KBL Param

The KBL Param buffer (temporary name was sysroot buffer) is a  bytes 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 finally to 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 but that's because first_loader is not updatable and has minimum code).

QA flags
The steps to install QA flags are: Write Qaf token to NVS at offset 0x400 (0x80-bytes) (tied to Console ID). Write Qaf token RSA signature to NVS at offset 0x5A0 (0x100-bytes) (only required on firmware 1.80 and above). Write Qaf version to SNVS sector 0x15. Clear Qaf inhibit DIP switches 240 and 241 (maybe even more DIP switches inhibit QA flags). Write Qaf enable flag to NVS at offset 0x480. Set Qaf ON flag to SNVS mgmt sector.

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 contain QA Flags captured (at 0x20 in KBL Param and 0x10 in decrypted QA token) from multiple PS Vita System Debugger units (DEM-3000H, DEM-3000L, DEM-3000JEC and PDEL-1000 System Debuggers):

Boot flags
These Boot flags come from Ernie NVS.

On FW 3.60, second_loader generates the boot flags as following:
 * byte 0 = NVS 0x4A0
 * byte 1 = NVS 0x481
 * byte 2 = 0
 * byte 3 = NVS 0x483
 * byte 4 = NVS 0x487
 * byte 5 = NVS 0x486
 * byte 6-0xF = 0

Example: FF FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00


 * byte 0: 0xFF - not update mode
 * byte 1: 0xFF - extra UART not enabled
 * byte 3: 0xFF - not safe mode
 * byte 4: 0xFF - unknown, maybe not used on FWs <= 0.995
 * byte 5: 0xFF on FAT - no internal storage or on PSTV or SLIM - internal storage enabled, 0xFE on PSTV or SLIM - internal storage disabled, maybe not used on FWs <= 0.995

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.

Boot type indicator 1
We ignore the official name so we name it Boot type indicator 1.


 * 0x1: external boot mode. It is used in internal FWs to boot in external mode. It cannot be set in external (release) second_loader.
 * 0x2: seems to be never set in external (release) second_loader
 * 0x4: product mode. manufacturing mode (Mgmt bit 0)
 * 0x8: seems to be never set in external (release) second_loader. Required by FW 0.931 SKBL to perform memory tests.
 * 0x40: use special media type. Never set in external (release) second_loader. Used in NSKBL when loading modules from sd0:.
 * 0x10000: seems to be never set in external (release) second_loader, allows to bypass current fw check for module loading
 * 0x20000: on resume, no boot logo
 * 0x40000: manufacturing mode (Mgmt bit 0) and GCSD initialized (for mounting sd0:) by second_loader using Ernie command 0x888
 * 0x80000: ?sd mode? - (Mgmt bit 1)

Sleep Factor
This is a guessed name.

Used by SceSysmem.


 * 1 bsod reboot (or other serious factors)
 * 0x10 bsod poweroff
 * 0x400 usually
 * 0x20000 unknown

Wakeup Factor
Wakeup Factor is only 2 bytes but to preserve alignment, in KBL Param it is extended to 4 bytes.


 * 00 00 00 00 coldboot on a DEM-3000H
 * 01 XX XX XX unknown
 * 04 00 00 00 reboot
 * 0E XX XX XX related to USB Enum Wakeup(maybe devkit)
 * 0F 00 00 00 USB Enum Wakeup
 * 14 00 00 00 boot with power hold
 * 00 FF 00 00 maybe coldboot
 * 04 FF 00 00 reboot
 * 14 FF 00 00 boot with power hold
 * 16 FF 00 00 boot by charge cable
 * 17 XX 00 00 BSOD reboot
 * 80 00 00 00 after suspend

Deduction:
 * 1: Maybe do not show lock screen
 * 2: USB enum wakeup
 * 4: reboot
 * 0x8: BSOD
 * 0xB: goes to safe mode
 * 0x10: anormal boot
 * 0x1F: goes to safe mode
 * 0x20: unknown
 * 0x80: resume from suspend mode
 * 0xFF00: ?battery related?

Boot Controls Info
This information can be parsed the same way as in SceSysconControl.

Keys combo:
 * Enter Safe mode: Power + PS + R
 * Rebuild Database: Power + PS + R + (Square or Cross)
 * Set Production Mode On for Prototype: Power + PS + Square + Cross + Up + Left
 * Set Production Mode On: Power + PS + R + Square + Cross (not present on FW 0.931, present on FWs 0.940+)

Note:
 * Set Production Mode On combos are not needed on genuine PSTV in Wakeup Factor flag 0x20 and are only checked when Wakeup Factor flags 0xB or 0x20 are set.
 * Set Production Mode On requires Jig connected else it fails with error 0x800F0A05 on set_pm STEP 8657.

Hardware Info
Hardware Info is got from Ernie.

It can be obtained using SceSyscon or SceSyscon. It can also be seen in the packet header in Syscon Update.

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


 * 0x00101003: supports FW 0.931
 * 0x00102003: supports FW 0.931
 * 0x00314000: supports FW 0.931
 * 0x00102403: supports FW 0.931-1.691
 * 0x00315000: certainly DEM-3000G (IRT-001), supports FW 0.931-1.691
 * 0x00102603: supports FW 0.940-3.68
 * 0x00315200: certainly DEM-3000H (IRT-001), supports FW 0.940-1.691
 * 0x00411000: supports FW 0.990-1.691, Product Sub Code 7, 9 or 0xA probably
 * 0x00414000: DEM-3000K (IRT-002), supports FW 0.990-1.691, Product Sub Code 9
 * 0x00415000: DEM-3000L (IRT-002), supports FW 0.996-1.691, Product Sub Code 0xB
 * 0x00415200: certainly DEM-3000P (IRT-002), supports FW 0.996-3.68, Product Sub Code 0xC probably
 * 0x00416000: PDEL-10XX, DEM-3000JEC third revision (IRT-002), supports FW 1.00-3.73, Product Sub Code 0xF, 0x10
 * 0x00404000: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 0x00404100: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 0x00404400: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 0x00404600: DEX model, CEM-3000NE2, supports FW 0.990-1.692
 * 0x00404800: unknown DEX model, supports FW 1.66-1.692
 * 0x00405000: unknown DEX model, supports FW 1.66-3.68
 * 0x00405200: unknown DEX model, supports FW 1.66-3.68
 * 0x00406000: PCH-10XX / PTEL-10XX (IRS-002 without 3G PCIe) -> supports FW 1.04-3.74, CEM-3000NP1 -> supports FW 1.00-3.74
 * 0x00406002: PCH-11XX (IRS-002 with 3G PCIe), supports FW 1.04-3.74
 * 0x0051XXXX: Prototype PS TV.
 * 0x00601000: unknown TOOL/DEX/CEX model (IRS-1001), supports FW 1.80-3.74
 * 0x00602000: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.74
 * 0x00603000: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.74
 * 0x00603200: PCH-10XX / PCH-11XX (IRS-1001), supports FW 1.80-3.74
 * 0x00703000: CEM-3000P01 (DOL-1001), supports FW 2.50-3.74
 * 0x00703030: VTE-10XX (DOL-1001), supports FW 2.50-3.74
 * 0x00805038: PCH-20XX / PTEL-20XX (USS-1001), supports FW 2.50-3.74
 * 0x00723030: VTE-10XX (DOL-1002), supports FW 3.30-3.74
 * 0x00822238: PCH-20XX (USS-1002), supports FW 3.50-3.74
 * 0x0090XXXX: Unknown prototype.

Bytes meaning
As PS Vita uses little-endian, we describe here in the same order, from the lowest to the highest.

First byte
This byte indicates the presence of some components. It works by bit flags:
 * 0x01: ?has SD card reader? (some DevKits and prototypes)
 * 0x02: has WWAN (3G modem). This is what SceBbmc checks to know if 3G modem is supported.
 * 0x04: unknown
 * 0x08: ?has microUSB? (Slim only)
 * 0x10: is MC emu capable (Slim and PS TV only). MC Emulation is done by partitionning the internal memory EMMC.
 * 0x20: has hw_info_2 (Slim and PS TV only)
 * 0x40: is Show mode
 * 0x80: is IDU mode

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 -> PS TV prototype motherboard
 * 60 -> IRS-1001
 * 70 -> DOL-1001
 * 72 -> DOL-1002
 * 80 -> USS-1001
 * 82 -> USS-1002
 * 90 -> unknown prototype motherboard

We can also guess that flag 1 means that the console has a Communication Processor.

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

Hardware flags

 * all zeroes on most cases
 * seen values:
 * ?0x0? on a Fat PS Vita with IRS-002
 * 0x7 on a Slim PS Vita with USS-1001
 * 0x247 on a Slim PS Vita with USS-1002