KBL Param

The KBL Param buffer (temporary name was sysroot buffer) is a  sized buffer passed to the Secure Kernel BootLoader in the scratch space and contains all sorts of flags and system parameters. This buffer is created in Second Loader copied to Secure Kernel, passed to the Secure and Non-Secure Kernel BootLoaders, and the non-secure kernel. It is used by many functions to check for features that are enabled for the system. The strategy in this buffer is to compute once for all the information that is often used, to share it between all security layers not to have to implement generator code many times, and to implement the generation code in the most secure layer: second_loader (excluding first_loader).

QA flags
In the following table bytes are counted from left to right and bits from left to right too (little-endian). However the OS uses bit masking for QA flags (unlike bit shifting for DIP Switches).

To check: Byte 0xF bit 7, byte 0xE bit 7, byte 0xE bit 6, byte 0xB bit 3: Revocation related.

The data below contains QA Flags captured (at 0x20 in sysroot buffer) from a System Debugger unit (SD DEM):

Boot flags

 * at 0x30: 0xFF - not update mode
 * at 0x33: 0xFF - not safe mode
 * at 0x35: FF on FAT - no internal storage or on PSTV or SLIM - internal storage enabled, FE on PSTV or SLIM - internal storage disabled

Hardware Info
Data returned by Ernie.

The following list is ordered by Ernie version, that should approximately match the hardware revision order.


 * 03 10 10 00: supports FW 0.931
 * 03 20 10 00: supports FW 0.931
 * 00 40 31 00: supports FW 0.931
 * 03 24 10 00: supports FW 0.931-1.691
 * 00 50 31 00: supports FW 0.931-1.691
 * 03 26 10 00: supports FW 0.940-3.68
 * 00 52 31 00: supports FW 0.940-1.691
 * 00 10 41 00: supports FW 0.990-1.691
 * 00 40 41 00: supports FW 0.990-1.691
 * 00 50 41 00: supports FW 0.996-1.691
 * 00 52 41 00: supports FW 0.996-3.68
 * 00 60 41 00: PDEL-10XX (IRT-002), supports FW 1.000-3.68
 * 00 40 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 41 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 44 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 46 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 48 40 00: unknown DEX model, supports FW 1.66-1.692
 * 00 50 40 00: unknown DEX model, supports FW 1.66-3.68
 * 00 52 40 00: unknown DEX model, supports FW 1.66-3.68
 * 00 60 40 00: PCH-10XX / PTEL-10XX (IRS-002 without 3G PCIe), supports FW 1.04-3.73
 * 02 60 40 00: PCH-11XX (IRS-002 with 3G PCIe), supports FW 1.04-3.73
 * 00 10 60 00: hybrid TOOL/DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 20 60 00: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 30 60 00: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 32 60 00: unknown DEX/CEX model, probably PCH-10XX / PCH-11XX (IRS-1001), supports FW 1.80-3.73
 * 30 30 70 00: VTE-10XX (DOL-1001), supports FW 2.50-3.73
 * 38 50 80 00: PCH-20XX / PTEL-20XX (USS-1001), supports FW 2.50-3.73
 * 30 30 72 00: VTE-10XX (DOL-1002), supports FW 3.30-3.73
 * 38 22 82 00: PCH-20XX (USS-1002), supports FW 3.50-3.73

Bytes meaning
Little-endian as usual.

First byte
This byte indicates the presence of some components:
 * 00 -> FAT WIFI
 * 02 -> 3G. This is what SceBbmc checks to know if 3G is supported.
 * 03 -> probably SD card reader
 * 30 -> PSTV (USB, ethernet)
 * 38 -> SLIM (micro USB)

Second byte
This byte indicates the motherboard minor version. It is relative to the motherboard main version which is indicated by third byte.

Third byte
This byte indicates the motherboard main version:
 * 10 -> unknown prototype motherboard, has Syscon, maybe IRS-001
 * 31 -> IRT-001
 * 40 -> IRS-002
 * 41 -> IRT-002
 * 51 -> unknown prototype, maybe IRT-003
 * 60 -> IRS-1001
 * 70 -> DOL-1001
 * 72 -> DOL-1002
 * 80 -> USS-1001
 * 82 -> USS-1002
 * 90 -> unknown prototype, maybe PSP3

Fourth byte
This byte is reserved in case 3 bytes becomes not enough to handle all Hardware Info:
 * 00 -> default, unused

Experimental point of view
- No AC connected + No POWER Button pressed: 0x0 ex: rebooting by software PSVita when AC is not connected

- No AC connected + POWER Button pressed: 0x4 ex: booting PSVita by pressing POWER button when AC is not connected

- AC connected + No POWER Button pressed: 0x8 ex: rebooting by software PSVita when AC is connected ex: autobooting PSTV/IDU PSVita by pluging AC

- AC connected + POWER Button pressed: 0xC ex: powering off by software PSTV then booting it by pressing POWER button ex: booting PSVita by pressing POWER button when AC is connected

Wakeup factor

 * 14 FF 00 00
 * 04 FF 00 00 after normal reboot
 * 04 00 00 00
 * 00 FF 00 00
 * 80 after suspend

DIP Switches
DIP switches area embeds two parts: Communication Processor information as 32-bit integers, followed by DIP switches stored as bit flags.

DIP Switches bit flags resolving
Warning: DIP Switches bit flags actually start at offset 0x10 (before that is CP information), which implies the first bit flag number is 128 (bit_num = offset / 8).

DIP Switches bit flags follow little-endian logic, which makes it hard to visualize in commonly used big-endian hexadecimal:
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000001 (big-endian in hex) = 01 00 00 00 (little-endian in hex) = 10000000 00000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 128
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000002 (big-endian in hex) = 02 00 00 00 (little-endian in hex) = 01000000 00000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 129
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000100 (big-endian in hex) = 00 01 00 00 (little-endian in hex) = 00000000 10000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 136
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x80000000 (big-endian in hex) = 00 00 00 80 (little-endian in hex) = 00000000 00000000 00000000 00000001 (little-endian in base 2) <- the 1 corresponds to bit flag number 159

As you can see this way is not convenient to know in memory on which byte corresponds which bit flag, so instead we can use a formula to convert bit number to offset and bit:,. This is used for example in the following code:

CP Information
Bits  is a 32-bit integer of the current time on the CP clock. This is duplicated in bits.

Bits  is a 16-bit integer of the CP version and bits   is a 16-bit integer of the CP board ID. All integers are little-endian. On units that do not have a CP, these fields are zeroes.

Bits  is 32-bit integer ASLR seed that is randomized on each boot in second loader. It can be disabled by setting a specific DIP switch or QA flag byte 0xE mask 1.

Bits  are also manipulable as general purpose DIP Switches exposed with ,  , and   but these functions do not change anything in hardware (only cached values are overwritten in SceSysmem).

According to SDK only DIP Switches 0-63 are accessible from usermode, however:
 * On FW 0.990 (but not on FW 0.931 nor 3.60), DIP Switch number 237 is the only one out of range 0-63 that can be set from usermode.
 * Usermode SELFs can use DIP Switches number > 63 if they have a special attribute or capability in SELF Auth Info.

SDK (SCE) flags
Bits  are used for DevKit Boot Parameters.

Shell flags
Bits  are used for SceShell flags.

Debug control flags
Bits  are for various debug options.

System control flags
Bits  are used for various system options.

if ((System control flags & 1) != 0) { // not allow load QA flag } else { // allow load QA flag }

if ((System control flags & 2) != 0) { // clear qa flags // (SceQafMgrForDriver_382C71E8, SceQafMgrForDriver_52B4E164, sceSblQafMgrIsAllowHost0Access and sceSblQafMgrIsAllowDecryptedBootConfigLoad functions will return false) }

Hardware flags

 * all zeroes on most cases
 * 47 02, 07 00 on a Slim