Syscon UART RPC

From Vita Development Wiki
Revision as of 00:51, 9 January 2024 by CelesteBlue (talk | contribs)
Jump to navigation Jump to search

The PlayStation Vita/TV's System Controller hosts a RPC server accessible from multiple interfaces, each of which has its own set of available commands.
One of the interfaces is UART, enabled by a special "jig" circuit that sets specific voltage levels on Syscon's voltage sense pins/probes.
This interface exposes around 100 RPC commands ranging from simple peripheral details retrieving to more complex procedures such as Syscon flash programming or alternative SoC boot modes.

Hardware

There need to be 2 digital pins (UART TX and RX) and at least 1 analog pin (Jig enable sense) accessible to the factory agent in order for Jig to work.

Model Interface location
IRT-001 Unknown
IRT-002 MultiConnector
IRS-* MultiConnector
DOL-* Service Connector (ffc)
USS-* microUSB

MultiConnector circuit

The UART interface is enabled if the *"Jig Sense 1"* probe is at 0.47v-0.738v during *"Jig Sense 2"* probe state change (float <-> gnd).

Type Location
Sense 1 Pin 11
Sense 2 Pin 12
Syscon RX Pin 6
Syscon TX Pin 7

Pins 11, 12, and 13 are routed directly to Syscon (seen through PCB delayering). They each have a 100K pull-up resistor to 1.8V.

Yellow = UDC pin 12, Cyan = UDC pin 11, Green = UDC pin 6 (Syscon UART RX), Magenta = UDC pin 7 (Syscon UART TX)

Since the test points for UDC pins 11 and 12 are close to the test points for Syscon UART, one (or both) of these pins could be used for voltage sensing.

Service Connector circuit

The UART interface is enabled if the *"Jig Sense 1"* probe is at 0.47v-0.738v during *"Jig Sense 2"* probe state change (float <-> gnd).

Type Location
Sense 1 Pin 4
Sense 2 Pin 6
Syscon RX Pin 20
Syscon TX Pin 19

MicroUSB circuit

The UART interface is enabled if the *"Jig Sense"* probe is at 1.017v-1.14v for at least 32000 Syscon clock cycles. When enabled, a "UUU" hello packet is sent over UART.

Type Location
Sense Pin 4 / ID
Syscon RX Pin 3 / D+
Syscon TX Pin 4 / D-

Example circuit

Tested circuit by SKGleba

Theoretical circuit with a 160K voltage divider by yifan lu

Software

Client

An example client implementation named Bert is provided by SKGleba.

The UART RPC interface protocol is a simple message -> reply packet interaction.

Packet Structure

Jig packets are ASCII-encoded hexadecimal strings (each raw byte is 2 ASCII bytes) and end in CRLF ("\r\n"). Each packet is converted to/from ASCII. Maximum packet size is 0x40 bytes (so 0x80 bytes in ASCII). Once decoded into raw bytes, the packet is structured as follows.

Offset Size Name
0x0 0x2 Command ID
0x2 0x1 Return status
0x3 0x2 Data size
0x5 Up to 0x39 Data
0x5 + Data size 0x2 Checksum

Commands

RPC Command ID Lock Description
0x100 0x0 nop
 - response: 0x00
0x101 0x0 get console info
 - response: 0x00
 - output: 3850800011050301030175008040327F
   - last 4 bytes are variable
0x102 0x0 communication settings
 - response: 0x00
 - input: 1byte protocol + 1byte baudrate + 2bytes unknown
   - protocol : 00 ascii, 01 ascii in/binary out
   - baudrate : 00 38400, 01 115200
0x103 0x0 unlock T1
 - response: 0x00
0x104 0x0 lock T1
 - response: 0x00
0x105 0x1 kermit power control
 - response: 0x00 if completed, 0x50 if bad current power state
 - input: requested new power state, 1byte
   - 00 : resp 0x00
     - power-off
   - 02 : resp 0x00
     - power-on
   - 03 : resp 0x00
     - powers on the SoC in SD boot mode, but does not reply to the challenge
     - this is used to talk with internal SoC subsystems via a SPI<->I2C interface
0x106 0x0 get power state
 - response: 0x00
 - output: current power state
   - 0400 : off
   - 0800 : suspended
   - 2000 : on
   - 0002 : unk
   - 0004 : unk. Maybe related to KBL_Param#Power_Info.
0x107 0x0 get TimeStamp
 - response: 0x00
 - output: 32303133313231333135353207000000000000000000000000000000
 - output hex2ascii : 201312131552
0x108 0x0 get ?some components serial numbers?
 - response: 0x00
 - output:
   - slim: 100001C20000000020008043000000003000A90016045300310020050208A90040FFFFFF00000000
   - pstv: 100001920000000020FFFFFF0000000030FFFFFFFFFFFFFF31FFFFFFFFFFFFFF40001ACA00000000
 - input: unknown, min size 2 bytes, only 0000 seems good
0x109 0x0 get task states
 - response: 0x00
 - input: mem buf idx ( 00 / 01 )
   - 00 : output:
     - slim: 0900040000000000320000000000000000000000000000000000000000000000
     - pstv: 0900080000000000510000000000000000000000000000000000000000000000
   - 01 : output:
     - slim: 0802020000000200610009020400000004003200000000000000000000000000
     - pstv: 0802200000002000090009020800000008005100000000000000000000000000
   - the buffers are updated by various tasks, from various states
0x110 0x1 unlock via handshake
 - response: 0x00
 - input: 3-step handshake, ascii size 80 bytes
   - keyset 0: start/enter SD boot mode
   - keyset 1: unlock T2
   - keyset 14: unlock T8
0x120 0x1 get VisibleId
 - response: 0x00
 - output: some serial (equivalent of PSP FuseID) read from fuses. Also stored in Cmep keyring 0x600
   - uses the SPI<->i2c interface in a special boot mode (command 0x105 mode 03)
   - keyring: C477BC5336570D60009F5118052CD5624441E0DD4A3A2E610186E87801010000
   - command: 53BC77C4600D573618519F0062D52C05DDE04144612E3A4A78E8860100000101
0x121 0x1 PervasiveMisc (SoC i2c device 0x40) read by offset
 - response: 0x00
 - input: 16bit offset (BE) for SoC i2c device 0x40
 - output: 32bit value read from offset
   - uses the SPI<->i2c interface in a special boot mode (command 0x105 mode 03)
   - example in=0004 -> out=94000115 (kermit rev)
   - example in=1060 -> out=00000029
   - blacklisted offsets 0x8-0x1000 in release syscon firmware
0x131 0x3 NVS read
 - auth level: T2
 - response: 0x00
 - input: 2byte offset + 1byte size
 - output: data read from given offset
0x132 0x3 NVS write
 - auth level: T2
 - response: 0x00
 - input: 2byte offset + 1byte size + sizeBytes data, min size 6 ascii bytes
 - output: data read from given offset
0x140 0x0 get ConfigStorageInfo
 - response: 0x00
 - output: 32bit values from the 0x10 field before both active and inactive ConfZZ
   - slim: 5800050058000400
   - pstv: 5000040050000300
     - whole buf 03B800: 43 6F 6E 66 5A 5A F0 03 50 00 03 00 E4 51 FF FF
     - whole buf 03BC00: 43 6F 6E 66 5A 5A F0 03 50 00 04 00 7E 52 FF FF
0x141 0x9 ConfZZ read-active
 - response: 0x00
 - input: 2byte offset + 1byte size, max offset 0x3EF, max size 0x20
 - output: ConfZZ data of size read from offset
0x142 0x9 ConfZZ write-to-inactive
 - response: 0x00
 - input: 2byte offset + 1byte size + sizeBytes data, max offset 0x3EF, max size 0x20
 - data is written to inactive ConfZZ
0x143 0x9 Unlock ConfZZ write-to-inactive (command 0x142)
 - response: 0x00
0x144 0x9 Lock ConfZZ write-to-inactive (command 0x142)
 - response: 0x00
0x145 0x9 Switch active ConfZZ?
 - response: 0x00
 - active ConfZZ is changed / ?inactive ConfZZ is written to active?
0x146 0x9 computes and checks some sha1, integrity checks?
 - response: 0x00 if all ok
 - input: unk, seems like 3 bytes followed by a sha1?
0x147 0x9 computes and checks some sha1, integrity checks?
 - response: 0x00 if all ok
 - input: unk, seems like 3 bytes followed by a sha1?
0x148 0x9 ??
0x150 0x1 ?
 - response: 0x00
 - output: some INVS flags preset?
   - slim: 0900001100000000
   - pstv: 100001AA00000000
0x151 0x1 Unlock INVS writes (0xAA)
 - response: 0x00
 - unlocks 0x155 & 0x156, writes 0xAA to INVS+1
0x152 0x9 Lock INVS writes
 - response: 0x00
 - locks 0x155 & 0x156, writes 0x00 to INVS+1
0x153 0x9 INVS read by id
 - response: 0x00
 - input: unknown, min ascii size 4 bytes, read data id?, max id 0x1D
   - 00 : output:
     - slim: 01AA0900
     - pstv: 01001000
   - 01 : output 6A000000
   - 02 : output 06000000
   - 03,06,07,0C-10,12,14,16,1A,1D : output 00
   - 04,19 : output 02
   - 05 : output 1400
   - 08,18 : output 01
   - 09,0A,0B,17 : output 0000
   - 11 : output 07
   - 13 : output 08
   - 15 : output 03
   - 1B : output 2800
   - 1C : output 29
0x154 0x9 INVS read
 - response: 0x00
 - input: 2byte offset + 1byte size, max offset 0x3F, max size 0x20
 - output: unknown data of size read from offset, seems to contain data from 0x153
0x155 0x9 ?
 - response: 0x00
 - input: unknown, min ascii size 4 bytes, ?write data?
0x156 0x9 ?
 - response: 0x00 (?apply data?)
0x157 0x1 Unlock INVS writes (0x11)
 - response: 0x00
 - unlocks 0x155 & 0x156, writes 0x11 to INVS+1
0x160 0x9 Depersonalize
 - response: 0x00
 - input: unknown, min size 2 ascii bytes
   - 01: long pause and no "UUU" message
   - 02: Formats NVS and SNVS
0x161 0x9 ?hard? reset syscon
 - response: 0x00
 - causes ?soft reset?, "UUU" message sent again, console shutdown
0x162 0x9 ?soft? reset syscon
 - response: 0x00
 - causes ?soft reset?, "UUU" message sent again, faster than 0x162
0x163 0x9 ?
 - response: 0x00
 - input: unknown, min size 2 ascii bytes
   - 5A: seems to shut down kermit and reset locks, no "UUU" message
0x168 0x1 ?
 - response: 0x00
 - output:
   - slim: 70033737
   - pstv: 70033535
0x170 0x9 ?
 - response: 0x00
 - output:
   - slim: 01420000250000001B0CFFFFF8000F00000000000018
   - pstv: 0102000100
0x171 0x9 ?
 - response: 0x00
 - output: 8040327FFFFF61EDF4
   - output is variable
0x172 0x9 ?
 - response: 0x00
 - output: CC640500FFFFFFFF00
   - output is variable
0x180 0x1 ?
 - response: 0x00
 - output:
   - slim: 8607B70FF200F70056000000
   - pstv: D007A00F2C012C0100000000
0x181 0x9 ?
 - response: 0x00
 - output:
   - slim: 110080016201000000000000
   - pstv: 000000000000000000000000
0x182 0x9 reset battery IC
 - response: 0x00
 - causes ?hard reset?, "UUU" message sent again after a longer period (~6 seconds)
   - nothing on PS TV -
0x183 0x9 ?
 - response: 0x00
 - unlocks 0x184,0x185,0x186,0x187,0x188,0x189
0x184 0x9 ?
 - response: 0x00
0x185 0x9 ?
 - response: 0x33
0x186 0x9 ?
 - response: 0x00
0x187 0x9 ?
 - response: 0x33
0x188 0x9 ?
 - response: 0x00
0x189 0x9 ?
 - response: 0x00
0x18A 0x9 ?
 - response: 0x00
 - output:
   - slim: 40000000
   - pstv: 00000000
0x18B 0x9 ?
 - response: 0x00
 - output: 01
0x18C 0x9 ?
 - response: 0x00
 - output:
   - slim: 0C
   - pstv: 09
0x18D 0x9 ?
 - response: 0x00
 - output:
   - slim: 00
   - pstv: 08
0x18E 0x9 ?
 - response: 0x00
 - output:
   - slim: 01
   - pstv: 0C
0x18F 0x9 ??
0x190 0x9 ?
 - response: 0x00
 - output: 0100000000010000
0x191 0x9 ??
0x192 0x9 ??
0x1A0 0x1 ?
 - response: 0x00
 - output: 0000000000000000000000000000000000000000
0x1A1 0x1 ?
 - response: 0x00
 - output: 808080808080808080808080
0x1B0 0x1 ?
 - response: 0x00
 - output: 0000000000000000
0x1B2 0x9 ??
0x1C0 0x1 ?
 - response: 0x00
 - output: 01550000
0x1C1 0x1 ?
 - response: 0x00
0x1C2 0x1 ?
 - response: 0x00
0x1C3 0x1 ?
 - response: 0x00
 - unlocks 0x1C1,0x1C4
0x1C4 0x1 ?
 - response: 0x00
 - output: 36300301FF000400
 - input: unknown, min ascii size 4 bytes, ?id?, max id 0x29
 - output: unknown, data read from id? for example id=01->data=A408020120000C0C
0x1D0 0x9 ?
 - response: 0x98
0x1D1 0x9 ?
 - response: 0x98
0x1D2 0x1 ?
 - response: 0x00
 - output: 0000000000010000
0x1D3 0x9 ??
0x1D4 0x1 ??
0x1D5 0x9 ??
0x1E0 0x1 ??
0x1E1 0x1 ??
0x1E2 0x1 ??
0x1E3 0x1 ??
0x300 0x0 write to shared jig-kermit buffer
 - response: 0x00
 - input: message to kermit, max ascii size 80 bytes
 - sets some key
0x301 0x0 read from jig-kermit shared buffer
 - response: 0x00
 - output: message from kermit, ascii size 80 bytes
0x900 0x0 unlock T4
 - response: 0x00
 - input: password, ascii size 32 bytes
0x901 0x0 lock T4
 - response: 0x00
0x910 0x4 ?
 - response: 0x33
0x911 0x4 ?
 - response: 0x33
0x912 0x4 ?
 - response: 0x33
0x913 0x4 ?
 - response: 0x33
0x914 0x4 ?
 - response: 0x33
0x915 0x4 ?
 - response: 0x33
0x916 0x4 ?
 - response: 0x00
 - output: 1B010600035402010100010000000000
0x917 0xC ?
 - response: 0x00
 - output: 2D3A0543
0x930 0x4 ?
 - response: 0x00
 - output:
   - slim: 01C2
   - pstv: 0192
0x931 0x4 ?
 - response: 0x00
 - output:
   - slim: 8043
   - pstv: FFFF
0x932 0x4 ?
 - response: 0x00
 - output:
   - slim: 2005A900160453000208A900
   - pstv: FFFFFFFFFFFFFFFFFFFFFFFF
0x940 0xC ?
 - response: 0x00
 - output: 0300
 - input: unknown
   - : output 05A9 resp 0x60
   - 00-03,08-0D,24,25,33-35,37,41,44,48 : output 0300
   - 04-07,0F-1F,36,38-3F : output 0400
   - 0E : output 0600
   - 20-22,40,43,46,47,49-4F : output 0200
   - 23,26-32,90-9F : output 0100
   - 42,71,72 : output 0004
   - 45 : output 0404
   - 50 : output 5541
   - 51,54 : output 4105
   - 52,55 : output 1000
   - 53 : output AA81
   - 56-5F,80,A0-A3,A5-A7,AA-B2,F0-FF : output 0000
   - 60-70 : output FFF0
   - 73 : output 0005
   - 74-7F : output 0101
   - 81 : output 1500
   - 82-85 : output 1700
   - 86-8F : output 0F00
   - B3-BF : output F000
   - A9,C0-CF : output 8000
   - D0-EF : output 01C2
0x941 0xC ?
 - response: 0x00
 - input: unknown, min ascii size 2 bytes
 - writes somewhere or sets some flag for 0x942
0x942 0xC ?
 - response: 0x00
 - input: unknown, min ascii size 2 bytes
 - output: 0000 unless written with 0x941, mashed with input
0x943 0xC ?
 - response: 0x00
 - input: unknown, min ascii size 2 bytes
0x944 0xC ?
 - response: 0x00
 - output: 9801
0x945 0xC ?
 - response: 0x00
 - input: unknown, min ascii size 2 bytes
0x952 0xC ?
 - response: 0x00
 - causes ?soft reset?, "UUU" message sent again after around 3 seconds
0x953 0x4 ?
 - response: 0x00
 - output: 1C000000A60BA30B
0x954 0x4 ??
0x955 0x4 ??
0x961 0x4 ?
 - response: 0x00
 - output: 8080808080808080
0x962 0x4 ?
 - response: 0x00
 - output: 0080008000800080
0x963 0x4 ?
 - response: 0x00
 - output: 00000000000000000000000000000000
0x964 0x4 ?
 - response: 0x00
 - output: 0080008000800000008000800080000000800080008000000080008000800000
0x965 0x4 ?
 - response: 0x00
 - output: 0000C0FF0000C0FF0000C0FF0000C0FF

Reply

The reply contains a command return status, currently the following common status IDs are known:

ID Description
0x0 "OK"
0x1 "UNK_CMD"
0x2 "BAD_LEN"
0x3 "BAD_CHKSUM"
0x4 "NO_CRLF"
0x5 "BAD_CMD_FORMAT"
0x10 "LOCKED_HANDSHAKE"
0x20 "LOCKED_T1"
0x32 "BAD_ARG_SIZE"
0x33 "BAD_ARG"
0x40 "WRONG_STATE"
0x50 "WRONG_POWER_STATE"

Locks

Some commands are locked behind "locks", global bits that can be set using other commands.
For example the power control command (RPC command 0x105) requires the T1 "lock" to be removed by calling command 0x103.
Some commands, such as NVS-read (0x131), might be locked behind multiple "locks" - here besides T1, the T8 lock needs to be removed/unlocked first by performing a 3-step keyset 1 handshake with cmd 0x110.

Bitmask Unlock RPC command ID Lock RPC command ID Usage
1 0x103 0x104 RPC command 0x105
2 0x110 with keyset 1 n/a
4 0x900 with password 0x901
8 0x110 with keyset 14 n/a Syscon command 0xD2 for SNVS read, RPC command 0x131 for NVS read