Aviso:lo meto en spoiler ya que es bastante largo
Spoiler:
HSPRG
The hypervisor stores a pointer to some structure per LPAR in HSPRG0 register.
There are actually 2 HSPRG0 values: one for each thread of Cell CPU !!!
There is a HSPRG0 array at 0×8(-0x69A0(HSPRG0)) + 0×20.
LPAR
LPAR = Logical Partition
lpar1 starts at 0x, and its belived to be the memory space wherre lv1 stores its variables, flags and other data.
lpar2 starts at 0×80000000000 and it’s belived to be the memory space where lv2 stores its variables, flags and other data.
The pointer to active LPAR is stored at -0x67E8(HSPRG0).
vtable
0x0033CA40 (3.15)
Member variables
offset 0×38 – some pointer
offset 0×50 – LPAR id (8 bytes)
offset 0×70 – pointer to VAS id bitmap
offset 0×78 – power of 2 of word size from VAS id bitmap (4 bytes), equal to 6
offset 0x7C – number of 64-bit words in VAS id bitmap(4 bytes)
Interrupt handling
The pointer to the interrupt handler that is called e.g. when an external interrupt occurs is at -0x69F0(HSPRG0).
0×00001930 (3.15 and 2.60)
Interrupt vector tables
There are 2 interrupt vector tables. One for each thread. The pointer to these tables is at -0×6950(HSPRG0).
offset 0×8 – IIC memory base address (8 bytes)
offset 0×10 – thread register offset (8 bytes)
offset 0×18 – start of interrupt vector table (19 entries, each entry 32 bytes)
Interrupt vector table entry
offset 0×0 – pointer to interrupt handler
offset 0×8 – TOC
offset 0×10 – 0
offset 0×18 – parameter to interrupt handler
Interrupt handlers
Spurious interrupt handler
0x002BC174 (3.15)
RSX
0x00219A44 (3.15)
0x002176FC (2.60)
SB bus
0x002B9CC4 (3.15)
I/O address translation
0x002CD7D8 (3.15)
0x002C9214 (2.60)
Performance monitor
0x002F0584 (3.15)
0x002EB1B0 (2.60)
Token manager
0x002BBA9C (3.15)
0x002B754C (2.60)
HV call
The address of HV table is stored at -0x6FC8(HSPRG0).
The address of HV table size is stored at -0x6FD0(HSPRG0).
HV call
Name Description
lv1_undocumented_function_62 SPE (isolation, it updates a SLB entry, writes to SLB_Index, SLB_VSID, SLB_ESID and SLB_Invalidate_Entry registers)
lv1_undocumented_function_89 SPE (writes to MFC_TLB_Invalidate_Entry register)
lv1_undocumented_function_99 SPE (isolation, syscall 0×10043, syscall 0×10042, syscall 0x1004A)
lv1_undocumented_function_102 Returns current TB ticks
lv1_undocumented_function_137 SPE
lv1_undocumented_function_138 SPE
lv1_undocumented_function_167 SPE (isolation, reads from SPU_Out_Intr_Mbox and MFC_CNTL registers)
lv1_undocumented_function_168 SPE (isolation, writes to MFC_CNTL register)
lv1_undocumented_function_195 WLAN Gelic device
lv1_undocumented_function_196 WLAN Gelic device
lv1_undocumented_function_200 SPE (isolation)
lv1_undocumented_function_201 SPE (isolation)
lv1_undocumented_function_209 SPE (isolation)
lv1_undocumented_function_250 Storage device
lv1_undocumented_function_251 Storage device
lv1_undocumented_function_252 Storage device
lv1_undocumented_function_253 Storage device
Memory HV call
All memory HV calls branch to lv1_mm_call
lv1_mm_call has it’s own function table
Memory HV call number = HV call number
Memory HV call table
Each entry is a pointer to a function TOC entry.
table size = 256
0×00364208 (3.15)
Memory HV calls
lv1_map_htab – 0x002D595C (3.15)
lv1_unmap_htab – 0x002D56B8 (3.15)
lv1_allocate_memory – 0x002D72F0 (3.15)
lv1_release_memory – 0x002D66A4 (3.15)
lv1_query_logical_partition_address_region_info – 0x002C9B24 (3.15)
lv1_create_repository_node – 0x002DD014 (3.15)
lv1_get_repository_node_value – 0x002DD260 (3.15)
lv1_undocumented_function_231 – 0x0030B560 (3.15)
System call
HV Processes do not use HV calls. They use syscalls only.
System call handler
0x002974D8 (3.15)
0x00292F6C (2.60)
There are 2 system call tables in HV. The first one stores system calls 0 – 36. The second one stores system calls 0×10000 – 0x100FF.
System call table 0 – 36
0x0035FAE8 (3.15)
0x00358ED0 (2.60)
System call numbers
0×1 – getpid(void)
0×2 – getppid(void)
0×3 – fork(void)
0×4 – exit
0×5 – exec(filename)
0×6 – wait(status)
0×7 – open(filename)
0×8 – close(fd)
0×9 – read
0xA – write
0xB – seek
0xC – unlink(filename)
0xD – signal
0xE – kill(pid, signal type)
0xF – brk
0×10 – socket(af, type, protocol) (supports only address family 0x1F, type 0×0 and protocol 0×0)
0×11 – bind
0×12 – listen(fd, backlog)
0×13 – accept
0×14 – connect
0×15 – ?
0×16 – pause(void)
0×17 – sleep(seconds)
0×18 – mmap(addr, size, prot, flags, fd, offset)
0×19 – munmap
0x1A – some fs func for directories, perhaps readdir
0x1B – ?
0x1C – map_pages (used for alloc)
0x1D – unmap_pages (used for free)
0x1E – select
0x1F – getcwd
0×20 – ?
0×21 – alarm
0×22 – ioctl
0×23 – _map_pages
0×24 – _unmap_pages
System call table 0×10000 – 0x100FF
0x0035DE78 (3.15)
0×00357260 (2.60)
System call numbers
0×10000 – allocate_memory_region(LPAR id, size, log2 of page size, ?, ?)
0×10001 – lpar_query_address_region_info
0×10002 – lpar_memory_addr_to_phys_addr(LPAR id, LPAR address, physical addr)
0×10005 – construct_logical_pu
0×10007 – activate_logical_pu(LPAR id, PPE id)
0×10009 – construct_logical_partition(0, LPAR id, outlet)
0x1000E – release_memory_region(LPAR id, memory region address)
0x1001A – construct_event_receive_port
0×10024 – shutdown_logical_partition(LPAR id, shutdown command)
0×10025 – destruct_logical_partition(LPAR id)
0×10026 – get_logical_partition_info
0x1002C – construct_scheduling_table
0x1002D – set_scheduling_slot
0×10032 – accesses system console
0×10036 – accesses system console
0×10040 – construct_spe_type_1(SPE id, shaddow_addr)
0×10041 – destruct_spe(SPE id)
0×10042 – decrypt_lv2_self(spe id, LPAR auth id, SELF file image ptr, LPAR memory address)
0×10043 – load_spe_module(spe id, SCE module ptr, arg1, arg2, arg3, arg4)
0×10044 – disable_spe_execution
0×10045 – set_spe_interrupt_mask
0×10046 – read_spe_problem_state_register(spe id, register offset, value)
0×10047 – write_spe_problem_state_register(spe id, register offset, value)
0x1004B – disable_spe_loading
0×10053 – pmi_set_guest_os_mode
0×10081 – accesses system console
0×10084 – construct_virtual_uart(LPAR id, VUART id, VUART data buffer size)
0×10085 – destruct_virtual_uart(LPAR id, VUART id)
0×10088 – RSX_syscall_10088(LPAR id)
0×10089 – RSX_syscall_10089
0x1008A – RSX_syscall_1008A
0x100BE – lv1_ioctl
0x100C0 – create_repository_node(LPAR id)
0x100C1 – get_repository_node_value(LPAR id)
0x100C2 – modify_repository_node_value(LPAR id)
0x100C3 – remove_repository_node_value(LPAR id)
Process
Process table
HV supports only 32 processes simultaneously. The number of processes currently running in HV is stored at address 0x0035EA54 (3.15) and 0x00357E3C (2.60).
The process table is an array of 32 process table entries.
0x0035E850 (3.15)
0x00357C38 (2.60)
Process table entry
offset 0×0 – process status ? (8 bytes)
offset 0×8 – pointer to Process object
create_new_proc
This function creates a new Process object.
0x00298E2C (3.15)
0x002948BC (2.60)
Parameters
r3 – pointer to parent Process object
r4 – ?
copy_user_data
This function copies data to/from user space.
0×00299688 (3.15)
0×00295118 (2.60)
Parameters
r3 – pointer to Process object
r4 – some address in address space of Process
r5 – pointer to buffer in HV space
r6 – size to copy
r7 – ?
r8 – direction of copy (0 – copy from user space, != 0 – copy to user space)
r9 – ?
vtable
Processes have no vtables. That means they have no virtual functions.
Member variables
offset 0×0 – PID (4 bytes)
offset 0×8 – pointer to parent Process object
offset 0×10 – pointer to AddressSpace object
offset 0×30 – pointer to first PThread object of process
offset 0×38 – array of signal handlers (192 * 8 bytes)
offset 0×638 – pointer to pointer to ELF image
offset 0×640 – start of file table (20 * 24 bytes)
offset 0×820 – exit status (4 bytes)
offset 0×898 – pointer to Inode object of current directory
offset 0x8A8 – some pointer
Signals
A process can have upto 192 signal handlers. For example, signal 9 is SIGKILL. A signal handler for SIGKILL cannot be installed and it cannot be ignored.
A process does not have a signal mask. Every thread of a process has it’s own signal mask.
Signal constants
0×9 – SIGKILL
0xE – SIGALRM
0×20 – SIGSPUMB
0×21 – SIGSPUMB_SL
0×22 – SIGSPUSTOP
0×23 – SIGSPUSTOP_SL
0×24 – SIGSPUDMA
0×26 – SIGSPUTIMEOUT
0×27 – SIGSPUERR
0×41 – SIGSHUTDOWN
File table
The file table has 20 entries. So, a process can have at most 20 files opened simultaneously. Each entry is 24 bytes large.
offset 0×0 – entry valid or invalid (1 byte), 0 – invalid, 1 – valid
offset 0×8 – pointer to object with File interface
offset 0×10 – current file position (8 bytes)
Process_EA_to_RA
This function translates an effective process address to real address.
0x00297E08 (3.15)
Objects
Here are the addresses of Process objects i could identify in HV dump 3.15:
0x006BB0D0 (PID 0)
0x0012C010 (PID 3) – ss_server3.fself
0x000915D0 (PID 5) – ss_server2.fself
0x000E4D70 (PID 6) – ss_server1.fself
0x0012C8D0 (PID 9) – sysmgr_ss.fself
Here are the addresses of Process objects i could identify in HV dump 2.60:
0x006B7580 (PID 0)
0x00135F90 (PID 3)
0x000862D0 (PID 5)
0x000A9870 (PID 6)
0x00084B80 (PID 9)
PThread
All PThread objects of the same Process object are linked together in a list.
vtable
0x003556D8 (3.15)
0x0034ECC0 (2.60)
offset 0×60 – pointer to TOC entry of system call handler
Member variables
offset 0×10 – pointer to next PThread object of Process
offset 0×18 – Thread object
offset 0x2B8 – ? (4 bytes)
offset 0x2C0 – pointer to TOC of some function
offset 0x2C8 – pointer to TOC of some function
offset 0×348 – some conter (4 bytes)
offset 0x3C0 – pointer to Process object that owns PThread object
offset 0x3F8 – signal pending mask (3 * 8 bytes = 192 signals)
offset 0×440 – ConditionVariable object
Signals
A PThread has it’s own signal mask, independant of all other PThreads in the same process.
Methods
wait_for_my_turn(Pthread ptr, ?, sleep interruptible flag) = wakeup status – 0x00296FB0 (3.15)
Thread
get_current_thread
This function returns the pointer to current running thread.
0x0028B994 (3.15)
0x0028744C (2.60)
vtable
0×00355750 (3.15)
Member variables
offset 0×288 – some pointer
offset 0×290 – some pointer
AddressSpace
vtable
0x003549A0 (3.15)
0x0034DF88 (2.60)
Member variables
offset 0×8 – Mutex object
offset 0×40 – AddressProtectionDomain object
offset 0×50 – some pointer
offset 0xC0 – some counter (4 bytes)
AddressSpace_EA_to_RA
0x002874D0 (3.15)
AddressProtectionDomain
vtable
0×00354980 (3.15)
Member variables
offset 0×8 – pointer to previous AddressProtectionDomain object
offset 0×10 – pointer to next AddressProtectionDomain object
offset 0×18 – poiinter to pointer to SLB entries
offset 0×20 – pointer to AddressSpace object that owns this object
offset 0×34 – pointer to previous ProtectionPage
offset 0x3C – pointer to next ProtectionPage
offset 0×48 – Mutex object
ProtectionPage
vtable
none
Member variables
offset 0×0 – RA (8 bytes)
offset 0×8 – EA (4 bytes)
offset 0×10 – pointer to previous ProtectionPage (4 bytes)
offset 0×14 – pointer to next ProtectionPage (4 bytes)
Mutex
vtable
0x00354D08 (3.15)
0x0034E2F0 (2.60)
Member variables
offset 0×18 – ? (4 bytes)
offset 0x1C – ? (4 bytes)
ConditionVariable
vtable
0x003549C0 (3.15)
offset 0×20 – wait
Member variables
offset 0×20 – pointer to Mutex object
File interface
vtable
offset 0×8 – ?
offset 0×28 – open
offset 0×30 – close
offset 0×38 – read
offset 0×40 – write
offset 0×50 – mmap
offset 0×58 – ioctl
StorageRegionFile
Flash device file class.
vtable
0x003569F8 (3.15)
VUARTFile
VUART device file class.
vtable
0×00356458 (3.15)
STDLCFile
Console device file class.
vtable
0x003561F8 (3.15)
Member variables
offset 0×20 – reference counter (8 bytes)
offset 0×28 – free buffer space ? (8 bytes)
SocketFile
vtable
0x00355DB0 (3.15)
offset 0xB0 – bind
RegionManager
vtable
0x00355F80 (3.15)
Inode
DirectoryInode
vtable
0×00355788 (3.15)
offset 0×20 – link
offset 0×28 – unlink
get_root_inode
This function returns the pointer to the Inode object of the root directory.
0x0029C124 (3.15)
0x00297BB4 (2.60)
vtable
0x00334E50 (3.15)
offset 0×30 – lookup
File system
Console device file objects
Here is the list of console device file objects i found in HV dump 3.15:
console
vtable
0x003561F8 (3.15)
Flash device file objects
Here is the list of flash device file objects i found in HV dump 3.15:
/dev/eflash0
/dev/eflash1
/dev/rflash0
/dev/rflash1
/dev/rflash_1x
/dev/rflash_1xp
vtable
0x003569F8 (3.15)
IOIF device file objects
Here is the list of IOIF device file objects i found in HV dump 3.15:
/dev/ioif0
vtable
0×00356688 (3.15)
Member variables
0×360 = MMIO base address
SD detector device file objects
Here is the list of SD detector device file objects i found in HV dump 3.15:
/dev/sd_detector
vtable
0x00356B48 (3.15)
NET device file objects
Here is the list of NET device file objects i found in HV dump 3.15:
/dev/net0
vtable
0x00356DE8 (3.15)
INODES
INODE OBJECT
+0×04: previos inode
+0×08: next inodes
+ 0×38: path
+ 0×358: childer_inode
MFS_ROOT_INODE
(2.60) 0x3580B0
+ 0×60 = ROOT_INODE
SOME ADDRESSES IN 2.60
0x60C010: “/dev” inode
0x6AA580: “/proc” inode
using linked list you can follow all inodes
Repository
Each LPAR has it’s own node repository
Repository nodes are stored in a hash table which can have several sub-hash tables.
RepositoryNode
vtable
0x00357F58 (3.15)
Member variables
offset 0×30 – pointer to next RepositoryNode obj
offset 0×38 – 2nd hash value of name (4 bytes)
offset 0×40 – 1st field name (8 bytes)
offset 0×48 – 2nd field name (8 bytes)
offset 0×50 – 3rd field name (8 bytes)
offset 0×58 – 4th field name (8 bytes)
offset 0×60 – ? (4 bytes)
offset 0×68 – 1st field value (8 bytes)
offset 0×70 – 2nd field value (8 bytes)
Hash Function
The name of a repository node is hashed and 2 hash values (2 32bit values) are produced.
The 1st hash value is used to select a sub-hash table.
The 2nd hash value is used to find a sub-hash table bucket.
Repository nodes in a hash bucket are ordered by the 2nd hash value.
void hash(unsigned long long n1,
unsigned long long n2,
unsigned long long n3,
unsigned long long n4,
unsigned long *h1,
unsigned long *h2)
{
unsigned long long h;
unsigned long hl;
h = ((((n1 ^ n4) >> 32) ^ (n2 ^ n3)) ^ (((n2 ^ n3) >> 32) ^ (n1 ^ n4))) & ~0xC0000000ULL;
*h1 = h & 0xFFFFFFFFULL;
h = ((h & 0x55555555ULL) > 1);
h = ((h & 0x33333333ULL) > 2);
h = ((h & 0xF0F0F0FULL) > 4);
hl = (h > 24);
hl = (hl & ~0xFF000000UL) | ((h & 0xFFULL) 8)) & 0x0000FF00ULL);
hl |= 0×1;
*h2 = hl;
}
Repository nodes from HV 3.15
Dump of all repository nodes from HV 3.15
Buses
SB bus
type – 4
index – 1
num_devices – 4 (repository node says this but there are more devices !!!)
Storage bus
type – 5
index – 4
num_devices – 4
SB bus subsystem
vtable
0×00352600 (3.15)
Member variables
offset 0×10 – MMIO memory base address
offset 0×20 – array of 16 pointers to SB devices (0 – Gelic device, 1 – USB device)
Objects
0×00349528 – pointer to pointer to SB bus subsystem object
Memory base address
0×24000000000
All SB bus device MMIO addresses are relative to this memory address.
SB device MMIO/DMA memory region
vtable
0x000x352308 (3.15)
Member variables
offset 0×18 – pointer to previous bus memory region object
offset 0×20 – pointer to next bus memory region object
offset 0×30 – relative bus memory start address
offset 0×38 – size of bus memory region
SB bus device
vtable
0×00352620 (3.15)
Member variables
offset 0×18 – array of pointers to MMIO memory region objects owned by device (8 * 8 bytes)
offset 0×60 – pointer to first DMA region object
offset 0x6C – device opened flag (1 byte, 0 – not opened, 1 – already opened)
offset 0×70 – id of LPAR that opened this device
offset 0×90 – pointer to an object that contains the address of interrupt handler for this device and SB bus interrupt index
Gelic device (Network Interface)
device id = 0
interrupt index = 8
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0×2800 0×24000002800 0×200
1 0×3004000 0×24003004000 0×1000
2 – - -
3 – - -
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 – 0×8000
0xC0000000 – 0×10000000
SATA Controller 1 device
device id = 1
interrupt index = 49
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0×2000 0×24000002000 0×200
1 0×3000000 0×24003000000 0×1000
2 0×3800000 0×24003800000 0×1000
3 0×3802000 0×24003802000 0×1000
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 – 0×1000
0xA0001000 – 0×1000
0xA0002000 – 0×1000
SATA Controller 2 device
device id = 2
interrupt index = 13
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0×2200 0×24000002200 0×200
1 0×3001000 0×24003001000 0×1000
2 0×3801000 0×24003801000 0×1000
3 0×3803000 0×24003803000 0×1000
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 – 0×1000
0xA0001000 – 0×1000
0xA0002000 – 0×1000
USB Controller 1 device
device id = 3
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0×2400 0×24000002400 0×200
1 0×3010000 0×24003010000 0×10000
2 0×3810000 0×24003810000 0×10000
3 – - -
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0xC0000000 – 0×10000000
0xD0000000 – 0×10000000
USB Controller 2 device
device id = 4
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0×2600 0×24000002600 0×200
1 0×3020000 0×24003020000 0×10000
2 0×3820000 0×24003820000 0×10000
3 – - -
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0xC0000000 – 0×10000000
0xD0000000 – 0×10000000
ENCDEC device
device id = 7
interrupt index = 5
MMIO regions
Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2C00 0x24000002C00 0×200
1 0×3005000 0×24003005000 0×1000
2 0×3006000 0×24003006000 0×1000
3 – - -
4 – - -
5 – - -
6 – - -
7 – - -
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0×80010000 – 0×10000
0×80004000 – 0×4000
0×80001000 – 0×1000
0×80003000 – 0×1000
0×80008000 – 0×1000
0×80009000 – 0×1000
0×80040000 – 0×10000
0x8000A000 – 0×1000
0×90020000 – 0×20000
0xC0000000 – 0×10000
0xC0040000 – 0×40000
FLASH Controller device (StarShip – SS)
device id = 9
interrupt index = 41
MMIO regions
FLASH controller doesn’t have MMIO regions.
DMA regions
Relative Bus Start Address Absolute Bus Start Address Size
0×80000000 – 0×1000
0×80020000 – 0×20000
0×80002000 – 0×1000
0×90000000 – 0×20000
SB Bus Interrupt Handling
There is a table of interrupt handlers for SB devices
The size of table is 64
The main SB bus interrupt handler is at 0x002B9CC4 (3.15)
The main interrupt handler reads interrupt index and dispatches interrupts
Interrupt Index
The main SB bus interrupt handler reads 2 32-bit values from addresses 0×24000008100 and 0x0x24000008104
The interrupt index is calculated from these values
Interrupt Handler Table
Interrupt Description Address in HV
5 ENCDEC device 0x00275C60 (3.15)
6 EH EPCIC internal 0x0023B6B0 (3.15)
8 Gelic device 0×00245330 (3.15)
12 ATA interrupt handler 0x0026B984 (3.15)
13 ATA interrupt handler 0x0026B984 (3.15)
14 Spider SC 0x0020A68C (3.15)
29 SBERR 0x0023AA50 (3.15)
30 SBERR 0x0023AA50 (3.15)
41 EBUS (Flash StartShip) 0x002814EC (3.15)
49 ATA media interrupt handler 0x00268A8C (3.15)
50 Flash ? 0x00280B24 (3.15)
55 EH EPCIC SERR 0x0023B67C (3.15)
Storage bus subsystem
vtable
0x00353AC8 (3.15)
Member variables
offset 0xEE8 – table of pointers to storage device objects (7 * 8 bytes, max 7 devices)
Storage device class
Member variables
offset 0×8 – device id (8 bytes)
offset 0xD50 – device id (8 bytes)
offset 0xD60 – pointer to ENCDEC SB bus device object
Region
Each storage device can have at most 8 regions (0-7)
Each region can have ACL
Each region has a start sector that is an offset from the physical first sector of the storage device
and a number of sectors
The start sector passed to lv1 storage hvcalls is relative to the start sector of the region
passed to the lv1 storage hvcall
Region Access Protection
Before a storage region is accessed, HV checks access rights of the caller.
Repository node ss.laid (LPAR authentication id) is evaluated for this purpose.
If LPAR has a repository node ios.ata.region0.access (value doesn’t matter) then the access rights check never fails.
ALL storage accesses from LPAR 1 are allowed
If (flags & 0×100000002) != 0 then access rights check is skipped !!!.
I tested on HV 3.41 with flags 0×2 and got access to regions which were denied by policy (LV1_DENIED_BY_POLICY result).
Storage subsystem device
device id = -1
The storage subsystem is a storage device itself.
It’s a psuedo device used to notify a LPAR when storage devices become e.g. ready.
Linux implements a loop and reads from this device and process notifications (adds new devices dynamically).
Notification Events
List of supported notification events:
Notify Device Ready (0×1)
Notify Region Probe (0×2)
Notify Region Update (0×4)
RBD device
device id = 0
block size = 2048
/dev/rbd0
The RBD storage device uses ENCDEC device.
vtable
0×00354288 (3.15)
Regions
Index Start sector Number of sectors
0 0×0 0x7FFFFFFF
1 – -
2 – -
3 – -
4 – -
5 – -
6 – -
7 – -
Supported Device Commands
Here is the list of commands supported by RBD storage device.
The commands can be used with HV call lv1_storage_send_device_command.
However, before a command is executed HV does bit manipulation with it and checks it against the value of repository node ss.laid or also called LPAR authentication ID. If this test fails then the command is NOT executed.
Command Description
0×81 EdecKgen1
0×82 EdecKgen2
0×83 EdecKset
0×84 EdecKgenFlash
0×85 -
0×86 -
0×87 -
/dev/rbd0
This LPAR 1 device accesses RBD storage device.
A write to this device sends a device command to RBD storage device.
FLASH device
device id = 1
The FLASH device uses ENCDEC device.
vtable
0×00354450 (3.15)
Regions
Index Start sector Number of sectors
0 0×0 0×8000
1 0×8 0x77F8
2 0×7900 0×100
3 0x7A00 0×400
4 – -
5 – -
6 – -
7 – -
Supported Device Commands
Here is the list of commands supported by FLASH StarShip 2 storage device.
The commands can be used with HV call lv1_storage_send_device_command.
However, before a command is executed HV does bit manipulation with it and checks it against the value of repository node ss.laid or also called LPAR authentication ID. If this test fails then the command is NOT executed.
Command Description
0×31 -
0xA2 -
0xA3 -
0xA6 -
0xA8 -
0xAC -
0xAD -
/dev/eflash1 and /dev/rflash1
These LPAR 1 devices access region 0 of FLASH storage device.
/dev/rflash1 is 16MB large
There is no file system on /dev/rflash1
There is some sort of TOC (Table Of Contents) stored in it. It contains file names, offsets and sizes.
On /dev/rflash1 you will find lv0, lv1ldr, lv2_lernel.self and all the other important SELFs.
The files are encryted of course.
Content of /dev/rflash1 (FLASH storage device region 0, size 16 MB)
There is a main TOC which describes different regions on /dev/rflash1
It seems that TOC 0xC0000 and TOC 0x7C0000 contain the same files but from different SDK versions.
TOC 0xC0000 is SDK version 3.41 and TOC 0x7C0000 is SDK version 3.30 (look at the content of files sdk_version).
I guess it’s because when i bought my PS 3 Slim it had Firmware 3.30 and i updated it to 3.41 for PSGroove.
TOC on /dev/rflash1 is used by HV Processes to locate files and load them into memory, e.g. SPU modules. E.g. Process 6 loads spu_utoken_processor.self to decrypt and verify user tokens or SPL which runs in Process 5 loads spp_verifier.self from there in order to decrypt and verify profile files. And Update Manager stores e.g. there files.
TOC Entry
A TOC entry is 0×30 bytes large.
offset 0×0 – relative offset from this TOC to entry data
offset 0×8 – entry data size
offset 0×10 – entry name (max 32 characters)
Main TOC
Here is a list of regions/files stored on /dev/rflash1 i found in HV 3.41 and dumped with PSGroove:
Entry Name TOC Offset Entry TOC Index Entry Relative Offset Entry Absolute Offset Entry Size
asecure_loader 0×400 0 0×400 0×810 0x2E800
eEID 0×400 1 0x2EC00 0x2F010 0×10000
cISD 0×400 2 0x3EC00 0x3F010 0×800
cCSD 0×400 3 0x3F400 0x3F810 0×800
trvk_prg0 0×400 4 0x3FC00 0×40010 0×20000
trvk_prg1 0×400 5 0x5FC00 0×60010 0×20000
trvk_pkg0 0×400 6 0x7FC00 0×80010 0×20000
trvk_pkg1 0×400 7 0x9FC00 0xA0010 0×20000
ros0 0×400 8 0xBFC00 0xC0010 0×700000
ros1 0×400 9 0x7BFC00 0x7C0010 0×700000
cvtrm 0×400 10 0xEBFC00 0xEC0010 0×40000
asecure_loader Region TOC
Here is a list of files stored on /dev/rflash1 i found in HV 3.41 and dumped with PSGroove:
Entry Name TOC Offset Entry TOC Index Entry Relative Offset Entry Absolute Offset Entry Size
metldr 0×800 0 0×40 0×840 0xE920
ros1 Region TOC
Here is a list of files stored on /dev/rflash1 i found in HV 3.41 and dumped with PSGroove:
Entry Name TOC Offset Entry TOC Index Entry Relative Offset Entry Absolute Offset Entry Size
creserved_0 0xC0000 0 0×460 0xC0470 0×40000
sdk_version 0xC0000 1 0×40460 0×100470 0×8
lv1ldr 0xC0000 2 0×40480 0×100490 0x1E948
lv2ldr 0xC0000 3 0x5EE00 0x11EE10 0x16FF0
isoldr 0xC0000 4 0x75E00 0x135E10 0×13074
appldr 0xC0000 5 0x88E80 0x148E90 0x1E254
spu_pkg_rvk_verifier.self 0xC0000 6 0xA70D4 0x1670E4 0xFACC
spu_token_processor.self 0xC0000 7 0xB6BA0 0x176BB0 0x5C94
spu_utoken_processor.self 0xC0000 8 0xBC834 0x17C844 0x65D0
sc_iso.self 0xC0000 9 0xC2E04 0x182E14 0x1532C
aim_spu_module.self 0xC0000 10 0xD8130 0×198140 0×4498
spp_verifier.self 0xC0000 11 0xDC5C8 0x19C5D8 0xD7F0
mc_iso_spu_module.self 0xC0000 12 0xE9DB8 0x1A9DC8 0x808C
me_iso_spu_module.self 0xC0000 13 0xF1E44 0x1B1E54 0x88B8
sv_iso_spu_module.self 0xC0000 14 0xFA6FC 0x1BA70C 0xC078
sb_iso_spu_module.self 0xC0000 15 0×106774 0x1C6784 0x5DB0
default.spp 0xC0000 16 0x10C524 0x1CC534 0x22A0
lv1.self 0xC0000 17 0x10E800 0x1CE810 0x127DF0
lv0 0xC0000 18 0×236600 0x2F6610 0x3E678
lv2_kernel.self 0xC0000 19 0x274C78 0x334C88 0x171B88
eurus_fw.bin 0xC0000 20 0x3E6800 0x4A6810 0x70F94
emer_init.self 0xC0000 21 0×457794 0x5177A4 0x7CDB8
hdd_copy.self 0xC0000 22 0x4D454C 0x59455C 0x60D68
ros2 Region TOC
Here is a list of files stored on /dev/rflash1 i found in HV 3.41 and dumped with PSGroove:
Entry Name TOC Offset Entry TOC Index Entry Relative Offset Entry Absolute Offset Entry Size
creserved_0 0x7C0000 0 0×460 0x7C0470 0×40000
sdk_version 0x7C0000 1 0×40460 0×800470 0×8
lv1ldr 0x7C0000 2 0×40480 0×800490 0x1E64C
lv2ldr 0x7C0000 3 0x5EB00 0x81EB10 0x16E30
isoldr 0x7C0000 4 0×75980 0×835990 0x12EC4
appldr 0x7C0000 5 0×88880 0×848890 0x1DB64
spu_pkg_rvk_verifier.self 0x7C0000 6 0xA63E4 0x8663F4 0xFACC
spu_token_processor.self 0x7C0000 7 0xB5EB0 0x875EC0 0x5C94
spu_utoken_processor.self 0x7C0000 8 0xBBB44 0x87BB54 0x65D0
sc_iso.self 0x7C0000 9 0xC2114 0×882124 0x1532C
aim_spu_module.self 0x7C0000 10 0xD7440 0×897450 0×4498
spp_verifier.self 0x7C0000 11 0xDB8D8 0x89B8E8 0xD7F0
mc_iso_spu_module.self 0x7C0000 12 0xE90C8 0x8A90D8 0x808C
me_iso_spu_module.self 0x7C0000 13 0xF1154 0x8B1164 0x88B8
sv_iso_spu_module.self 0x7C0000 14 0xF9A0C 0x8B9A1C 0xC078
sb_iso_spu_module.self 0x7C0000 15 0x105A84 0x8C5A94 0x5DB0
default.spp 0x7C0000 16 0x10B834 0x8CB844 0x22A0
lv1.self 0x7C0000 17 0x10DB00 0x8CDB10 0×129040
lv0 0x7C0000 18 0x236B80 0x9F6B90 0x3E570
lv2_kernel.self 0x7C0000 19 0x2750F0 0xA35100 0x1712D0
eurus_fw.bin 0x7C0000 20 0x3E63C0 0xBA63D0 0x70F94
emer_init.self 0x7C0000 21 0×457354 0xC17364 0x7FBB8
hdd_copy.self 0x7C0000 22 0x4D6F0C 0xC96F1C 0×61518
HDD device
device id = 2
block size = 512
The HDD device uses ENCDEC device.
vtable
0x00353F48 (3.15)
Member variables
offset 0×1590 – LBA48 capability flag (4 bytes)
Regions
Index Start sector Number of sectors
0 0×0 0x950F8B0
1 0×8 0×80000
2 0×80018 0x7C8F898
3 0x7D0F8B8 0x3FFFF8
4 0x810F8B8 0x13FFFF8
5 – -
6 – -
7 – -
Supported Device Commands
Here is the list of commands supported by HDD storage device.
The commands can be used with HV call lv1_storage_send_device_command.
However, before a command is executed HV does bit manipulation with it and checks it against the value of repository node ss.laid or also called LPAR authentication ID. If this test fails then the command is NOT executed.
Command Description
0×2 LV1_STORAGE_SEND_ATA_COMMAND
0×10 -
0x1B ATA Set UltraDMA Mode
0x1C ATA Set Features PIO Flow Control Transfer Mode
0×21 -
0×22 ATA Identify Device
0×23 LV1_STORAGE_ATA_HDDOUT (ATA Flush Cache Ext)
0×26 ATA Read Alternative Status
0×27 ATA Read Error
0×28 -
0×31 ATA Flush Cache/ATA Flush Cache Ext
0×32 ATA Stanby Immediate
0×33 -
UNKNOWN device (redirected to HDD storage device)
device id = 3
block size = 512
It’s a psuedo device.
This storage device redirects all requests to the region 1 of HDD storage device !!!
vtable
0x00353D88 (3.15)
Member variables
offset 0xD60 – pointer to a storage device that all requests are redirected to
offset 0xD68 – region ID of the storage device that all requests are redirected to
Regions
Index Start sector Number of sectors
0 0×0 0×80000
1 0×8 0x75F8
2 0×7800 0x63E00
3 0x6B600 0×8000
4 0×73600 0×400
5 0x73A00 0×2000
6 0x77C00 0×200
7 – -
/dev/rflash1_1x and /dev/rflash_1xp
These LPAR 1 devices access region 5 of UNKNOWN storage device.
In region 5 of UNKNOWN storage device is e.g. LINUX image stored.
SATA/ATA/ATAPI
ATA Interrupt Handler
0x0026B984 (3.15)
ATA_SetDMA
0x00268ADC (3.15)
ATA_make_PRD_table
0x00267DB4 (3.15)
This function initializes a PRD (Physical Region Descriptor) table.
ClearPATACInterrupt
0x00267CAC (3.15)
EnablePATACInterrupt
0x00267D44 (3.15)
DisablePATACInterrupt
0x00267AF0 (3.15)
ATA_read_AltStatus_reg
0x00267C40 (3.15)
This function reads the ATA Alternate Status Register and returns it’s value.
ATA_write_DATA_reg
0x00268A10 (3.15)
This function writes a 16-bit value to the ATA Data Register.
ATA_read_DATA_reg
0x0026887C (3.15)
ATA_write_DATA
0x0026635C (3.15)
This function writes several 16-bit values to the ATA Data register.
ATA_write_CMD_reg
0x002688A0 (3.15)
ATA_read_Error_reg
0x00267BD4 (3.15)
ATA_write_Features_reg
0x002689F0 (3.15)
ATA_write_DevCtrl_reg
0x00267BB4 (3.15)
ATA_write_TaskFile_regs
0x00266BC8 (3.15) 0x002665A0 (3.15)
ATA_send_ATAPI_cmd
0x002655F4 (3.15)
ATA_send_cmd
0x0026580C (3.15)
ATA_send_ReadSectors_cmd
This function uses LBA28.
0x0025D2B4 (3.15)
ATA_send_WriteSectors_cmd
This function uses LBA28.
0x0025CEF4 (3.15)
ATA_send_ReadDMA_cmd
This function uses LBA28.
0x0025D380 (3.15)
ATA_send_WriteDMA_cmd
This function uses LBA28.
0x0025CFB8 (3.15)
ATA_send_ReadDMAExt_cmd
This function uses LBA48.
0x0025D74C (3.15)
ATA_send_WriteDMAExt_cmd
This function uses LBA48.
0x0025D664 (3.15)
ATA_send_IdentifyDevice_cmd
0x0025D4D8 (3.15)
ATA_send_IdentifyPacketDevice_cmd
0x0025D448 (3.15)
ATA_send_FlushCache_cmd
0x0025D5E8 (3.15)
ATA_send_FlushCacheExt_cmd
0x0025D568 (3.15)
ATA_send_StandbyImmediate_cmd
0x0025D07C (3.15)
ATA_send_SetFeatures_cmd
0x0025D208 (3.15)
ATA_send_SMARTEnable_cmd
0x0025D0F8 (3.15)
ATA_send_SMARTSaveAttributeValue_cmd
0x0025D180 (3.15)
ATA_SetUDMAMode
0x00260EE8 (3.15)
Parameters
r5 – UltraDMA mode (0-5)
High precision timers
These timers are used e.g. in SATA/ATA/ATAPI driver.
timer_add
0x002C3F2C (3.15)
timer_del
0x002C41AC (3.15)
timer_run_expired
This function is called from HDEC interrupt handler.
0x002C4020 (3.15)
timer_set_HDEC
0x002BCF80 (3.15)
SPE
There are 3 SPE classes.
The HV call lv1_construct_logical_spe can create LogicalSPE, SPEType1 and SPEType2 objects.
The syscall 0×10040 creates only SPEType1 objects.
The SPEType1 and SPEType2 objects cannot be created when isolation mode is disabled. The right most bit of repository node sys.lv1.iso_enbl is checked and when it’s not 1 then the SPEType1 and SPEType2 objects cannot be created. In LPAR 1, this check succeedes always. Only in LPARs different from 1, the repository node sys.lv1.iso_enbl is checked.
LogicalSPE
SPE type = 0
Objects of this class are used e.g. on Linux.
vtable
0×00358360 (3.15)
offset 0×20 – pointer to TOC entry of interrupt handler for SPE
Member variables
offset 0×38 – pointer to LPAR obj that owns this SPE obj
offset 0×78 – table of pointers to Outlet objects (3 * 8 bytes, one for each Class 0-2)
offset 0xB0 – pointer to VAS object
offset 0xC8 – pointer to Logical PPE object
offset 0xE0 – SPE id
offset 0x1A0 – pointer to MMIO Memory Region object
offset 0x1A8 – pointer to Shadow Registers Memory Region object
Objects
Here is the list of logical SPE objects i found in HV 3.15:
0x003A82E0 – SPE id 0
0x003A8660 – SPE id 1
0x003ABA00 – SPE id 2
0x003B4010 – SPE id 3
0x003B4D60 – SPE id 4
0x003B5970 – SPE id 5
SPEType1
SPE type = 1
vtable
0×00359750
Member Variables
offset 0×198 – pointer to MMIO Memory Region object
offset 0x1A0 – pointer to Shadow Registers Memory Region object
SPEType2
SPE type = 2
vtable
0×00359790
SPE Register Shadow Area
HV createas a SPE Register Shadow Area for each contstructed SPE.
The area is 1 4Kb page of physical memory.
When SPE state changes then HV updates data in this area.
The value of shadow_addr that is returned by lv1_construct_logical_spe is a LPAR start address of this area and it cannot be accessed until it’s mapped in the HTAB.
The SPE Register Shadow Area may be mapped only with read-only page protection or else HV call lv1_insert_htab_entry fails. I tested it with PSGroove and could map the whole memory range and read it after i constructed SPE of type 1 with lv1_construct_logical_spe.
The shadow_addr is also returned by syscall_10040 (that creates SPE of type 1) but it returns already mapped Process address so HV Processes do not have to map it in HTAB.
When an isoated SPU is done, HV Processes checks the value at offset 0×30 to determine if the SPU execution was successfull or not.
GameOS checks also the value at offset 0×30 in the SPE Shadow Area.
When GameOS creates SPE of type 1 then it maps only SPE Register Shadow Area into it’s address space.
SPE Register Shadow Area Offsets
0×30 – SPU_Status register value (4 bytes)
0xF10 – ?
0xF18 – ?
Stop Code
The high-order 16 bit of SPU_Status register value is a Stop Code.
Here is the list of Stop Codes i extracted from HV Processes which read the value at offset 0×30 when SPU is done:
Value Description
0xA Success
0xC Access Violation (LPAR auth id error)
0xE ?
0xF Revoked
0×12 Invalid Parameter
0×13 ?
0×17 Invalid Parameter
0×25 ?
SPU_send_MFC_cmd
0x002B09B0 (3.15)
This function programs a MFC.
SPU_write_MFC_cmd_status_reg
0x002AEE70 (3.15)
SPU_write_Sig_Notify1_reg
0x002AEF4C (3.15)
SPU_write_Sig_Notify2_reg
0x002AEF30 (3.15)
SPU_write_Sig_Notify1_and_Notify2
0x002B0A78 (3.15)
SPU_enable_iso_load_request
0x002AEDE0 (3.15)
SPU_iso_load_request
0x002AEED0 (3.15)
SPU_enable_runcntl
0x002AEB24 (3.15)
SPU_stop_request
0x002AEEF0 (3.15)
SPU_run_request
0x002AEF10 (3.15)
SPU_read_status_reg
0x002AE978 (3.15)
SPU_read_Mbox_Stat_reg
0x002AE998 (3.15)
lv1_undocumented_function_62
Updates SLB entry.
Parameters
%r3 – SPE id
%r4 – ? (valid values: 0 – 3)
%r5 – SLB entry index (valid values: 0 – 7)
%r6 – ESID
%r7 – VSID
spe_type1_interrupt_handler
0x0030E238 (3.15)
spe_type2_interrupt_handler
0x003103F8 (3.15)
spe_type3_interrupt_handler
0x002F36F4 (3.15)
Socket
The socket supports only one address family 0x1F, one socket type 0 and one protocol 0.
Socket address
Socket address is called port ID. Valid port IDs are 0-63. Port ID 0 is reserved.
Socket state
2 – LISTEN
Socket table
The socket table contains 64 entries, one for each port ID. Each entry is 16 bytes large.
The socket table is at 0x0035F6E8 (3.15).
Here is the list of opened sockets i found in HV 3.15:
0x00091FE0 (port ID 0×23, accepts connections)
0×00127850 (port ID 0×24, accepts connections)
0x0012F810 (port ID 0×25, accepts connections)
Socket table entry
offset 0×0 – pointer to Socket obj
offset 0×8 – socket accepts connections or not (0 – does not accept, 1 – accepts, 1 byte)
vtable
0x00355DB0 (3.15)
offset 0xB0 – bind
offset 0xB8 – listen
offset 0xC8 – connect
Member variables
offset 0×360 – socket state (4 bytes)
offset 0×368 – port ID (8 bytes)
offset 0×370 – max backlog queue size (8 bytes)
Virtual Address Space
VAS
vtable
0×00357958 (3.15)
Member variables
offset 0×18 – pointer to LPAR that owns this VAS object
offset 0×48 – VAS id (8 bytes)
offset 0×70 – number of page sizes (4 bytes)
offset 0×74 – log2 of HTAB size
offset 0×78 – pointer to HTAB object
Objects
Here is the list of the VAS objects i found in HV dump 3.15:
0x001C8050 (VAS id 2, LPAR 1)
0x003B4910 (VAS id 3, LPAR 2)
0x003BDB50 (VAS id 48, LPAR 2)
HTAB
0×38(-0x69A8(HSPRG0)) – pointer to the currently active HTAB in LPAR
vtable
0x003575B0 (3.15)
Member variables
offset 0×48 – pointer to first PTE
offset 0×60 – LPID (4 bytes)
offset 0×64 – log2 of HTAB size (4 bytes)
Objects
Here is the list of the HTAB objects i found in HV dump 3.15:
0x001C8270 (VAS id 2, LPAR 1)
* 0×00180000 – HTAB PTEs (HTAB size 256 kB)
0x003A8050 (VAS id 3, LPAR 2)
* 0×00500000 – HTAB PTEs (HTAB size 1 MB)
0x003BC510 (VAS id 48, LPAR 2)
* 0×00800000 – HTAB PTEs (HTAB size 1 MB)
LPAR_change_HTAB
This function changes currently active HTAB. It writes to SDR1 register where HTAB address and size is stored.
0x002BE5D4 (3.15)
Process SLB
Each HV process has 16 SLB entries.
Each SLB entry is 16 bytes large and is in format expected by opcode slbmte.
Most of the entries are zero (invalid).
Each process has 4 valid SLB entries: code, data, heap and stack.
Process 3
SLB entries
0x0012D1F0 (3.15)
Name ESID VSID
code 0×8 0×38
data 0xC 0x3C
heap 0xA 0x3A
stack 0xF 0x3F
Process 5
SLB entries
0×00093120 (3.15)
Name ESID VSID
code 0×8 0×48
data 0xC 0x4C
heap 0xA 0x4A
stack 0xF 0x4F
Process 6
SLB entries
0x000E6960 (3.15)
Name ESID VSID
code 0×8 0×58
data 0xC 0x5C
heap 0xA 0x5A
stack 0xF 0x5F
Process 9
SLB entries
0x00763E20 (3.15)
Name ESID VSID
code 0×8 0×8
data 0xC 0xC
heap 0xA 0xA
stack 0xF 0xF
VUART
VUART is a bi-directional communication link. A VUART object has a peer VUART object.
Data written to a VUART object is stored NOT in the data buffer of the VUART object but in the data buffer of the peer VUART object.
VUART table
Every LPAR has a VUART table. A VUART table has 256 entries. Each entry is a pointer to a VUART object that implements VUART interface.
0×00677218 (3.15) – address of VUART table of LPAR 1
Here is the list of all VUART objects in LPAR 1 i found in HV 3.15:
0x006ABD90 – VUART 0
0x006ABEB0 – VUART 1
0x006A3CB0 – VUART 2
0x006A3DD0 – VUART 3
0x000A3410 – VUART 5
0x000A3250 – VUART 6
VUART [0-3] are used by /dev/sc[0-3] respectively.
VUART [0-3] are linked to VUART objects of different type i could not yet identify. These unknown VUART objects use eieio opcode a lot. So i think, they communicate with hardware peripheral.
A write/read to/from /dev/sc[0-3] is a write/read to/from VUART.
0x00762AA8 (3.15) – address of VUART table of LPAR 2
Here is the list of all VUART objects in LPAR 2 i found in HV 3.15:
0×00126660 – VUART 0
0x000A3010 – VUART 2
VUART 0 and VUART 2 of LPAR 2 are created by Process 9 during LPAR construction.
VUART class
Member variables
offset 0×48 – pointer to peer VUART object
offset 0×58 – write pointer into data ring buffer
offset 0×60 – read pointer into data ring buffer
offset 0×68 – pointer to data ring buffer
offset 0×70 – size of data ring buffer (8 bytes)
offset 0×78 – size of data stored in data ring buffer currently (8 bytes)
offset 0×88 – tx trigger (8 bytes)
offset 0×90 – rx trigger (8 bytes)
offset 0×98 – interrupt mask (8 bytes)
offset 0xA8 – port number (4 bytes)
Methods
pmpi_read_virtual_uart(port, buf, size, nread) – 0x002EB30C (3.15)
pmpi_write_virtual_uart(port, buf, size, nwritten) – 0x002EB0EC (3.15)
VUART_read(pointer to VUART object, buf, size, nread) – 0x002E8654 (3.15)
VUART_write(pointer to VUART object, buf, size, nwritten) – 0x002E8428 (3.15)
Guest OS VUART 0 (AV Manager)
All data sent to VUART 0 in LPAR 2 is written into the data buffer of VUART 5 of LPAR 1.
VUART 5 of LPAR 1 is accessed by Process 9 in LPAR 1 through the file /proc/partitions/2/vuart/0.
Process 9 of LPAR 1 uses RSX syscalls to access RSX driver and memory mapped device access (/dev/ioif0).
Guest OS VUART 2 (System Manager)
All data sent to VUART 2 in LPAR 2 is written into the data buffer of VUART 6 of LPAR 1.
VUART 6 of LPAR 1 is accessed by Process 9 in LPAR 1 through the file /proc/partitions/2/vuart/2.
System manager supports 62 (0-61) service ids.
Process 9 has a SID table. SID table has 62 entries.
Each entry is a pointer to a function responsible for processing SID packets.
System Manager (SM)
System Manager (SM) is running in Process 9 of HV.
It communicates with Guest OS through /proc/partitions/2/vuart/2 file.
System Manager class
Member variables
offset 0×10 – LPAR state (8 bytes)
offset 0×68 – LPAR auth id
offset 0×70 – LPAR name
offset 0×90 – LPAR image path
offset 0x1C0 – LPAR ability (8 bytes)
Types of System Manager
There are 6 different SM types
When Process 9 starts it reads profile file, by default DEFAULT.SPP, by sending requests to SPL (Secure Profile Loader) and constructs System Managers listed in this profile file.
So, the profile file controls which System Manager types are available later.
Name LPAR name
SCE_CELLOS_PME -
SCE_CELLOS_SYSTEM_MGR PS3_LPAR
SCE_CELLOS_SYSTEM_MGR_PS2 PS2_LPAR
SCE_CELLOS_SYSTEM_MGR_PS2_SW PS2_SW_LPAR
SCE_CELLOS_SYSTEM_MGR_PS2_GX PS2_GX_LPAR
SCE_CELLOS_SYSTEM_MGR_LINUX LINUX_LPAR
Ability Bitmask
Index Name Ability Bitmask (Hex) Ability Bitmask (Binary)
0 SCE_CELLOS_PME 0×1 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001
1 SCE_CELLOS_SYSTEM_MGR 0x3BF7EF 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0011 1011 1111 0111 1110 1111
2 SCE_CELLOS_SYSTEM_MGR_PS2_SW 0x1226D 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0001 0010 0010 0110 1101
3 SCE_CELLOS_SYSTEM_MGR_LINUX 0×40012 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0000 0000 0001 0010
Bit Position (from right) SID Description
1 5 (SET_NEXT_OP) Shutdown or Reboot LPAR
2 5 (SET_NEXT_OP) Boot PS3 LPAR
3 5 (SET_NEXT_OP) Boot PS2_SW LPAR
4 5 (SET_NEXT_OP) Boot LINUX LPAR
5 12 (CONTROL_LED) Control LED
6 21 (RING_BUZZER) Ring Buzzer
7 19 (SET_CONFIG) Set Config
10 26 (REQUEST_ERROR_LOG) Request Error Log
10 28 (REQUEST_BE_COUNT) Request BE Count
10 32 (REQUEST_SYSTEM_EVENT_LOG) Request System Event Log
12 30 (REQUEST_SC_VERSION) Request SC Version
14 39 (SET_SHOP_DEMO_MODE) Set Shop Demo Mode
Service ID (SID)
SM supports 62 (0-61) SIDs.
The value of SM member variable ability controls which SIDs may be used by LPAR.
SID Name Description
0 – -
1 REQUEST -
2 RESPONSE -
3 COMMAND -
4 EXTERN_EVENT -
5 SET_NEXT_OP -
6 – -
7 – -
8 SET_ATTR -
9 GET_INTER_LPAR_PARAM -
10 SET_INTER_LPAR_PARAM -
11 – -
12 CONTROL_LED -
13 TEMPERATURE -
14 – -
15 – -
16 – -
17 – -
18 – -
19 SET_CONFIG -
20 – -
21 RING_BUZZER -
22 – -
23 – -
24 – -
25 FAN_POLICY -
26 REQUEST_ERROR_LOG -
27 – -
28 REQUEST_BE_COUNT -
29 – -
30 REQUEST_SC_VERSION -
31 – -
32 REQUEST_SYSTEM_EVENT_LOG -
33 – -
34 RTC_ALARM -
35 – -
36 RTC_ALARM -
37 – -
38 RTC_ALARM -
39 SET_SHOP_DEMO_MODE -
40 BOOT_PARAMETER -
41 – -
42 BOOT_PARAMETER -
43 – -
44 FACTORY_PROCESS_COMP -
45 – -
46 FACTORY_PROCESS_COMP -
47 – -
48 FACTORY_PROCESS_COMP -
49 – -
50 FAN_POLICY -
51 – -
52 – -
53 – -
54 – -
55 – -
56 – -
57 – -
58 – -
59 – -
60 – -
61 – -
12 – CONTROL_LED
I have tested this service with PSGroove and GameOS is allowed to use it
Packet Body
struct sysmgr_ctrl_led
{
u8 field0;
u8 field1;
u8 field2;
u8 res1;
u8 field4;
u8 field5;
u8 res2[10];
};
Parameters
I have tested the following parameters with this service:
field0 field1 field2 field4 field5 Description
0×1 0×0 0xFF 0xFF 0xFF Turns off the power button LED
0×1 0×1 0xFF 0xFF 0xFF Turns on the power button LED
21 – RING_BUZZER
I have tested this service with PSGroove and GameOS is allowed to use it
Packet Body
struct sysmgr_ring_buzzer
{
u8 res1;
u8 field1;
u8 field2;
u8 res2;
u32 field4;
};
Parameters
I have tested the following parameters with this service:
field1 field2 field4 Description
0×29 0×4 0×6 Makes a short single beep
0×29 0xA 0x1B6 Makes a double beep
0×29 0×7 0×36 -
0×29 0xA 0xFFF Makes a continuous beep
Active System Managers in HV dump 3.15
There are 4 active SMs in HV dump.
Index Name LPAR auth id LPAR image pathname Ability Bitmask (Hex)
0 SCE_CELLOS_PME 0×1070000001000001 /flh/os/this_is_dummy 0×1
1 SCE_CELLOS_SYSTEM_MGR 0×1070000002000001 /flh/os/lv2_kernel.self 0x3BF7EF
2 SCE_CELLOS_SYSTEM_MGR_PS2_SW 0×1020000003000001 /local_sys0/ps2emu/ps2_softemu.self 0x1226D
3 SCE_CELLOS_SYSTEM_MGR_LINUX 0×1080000004000001 /flh/lx/linux 0×40012
GameOS file image lv2_kernel.self is stored on /dev/rflash1
Linux file image is stored on /dev/rflash_1x or /dev/rflash_1xp
Booting Linux LPAR through System Manager
To boot Linux LPAR from GameOS when Linux support was not removed (Ability Mask of PS3 System Manager needs patching !!!):
Send SID packet SET_NEXT_OP with operation OP_LPAR_REBOOT and the index of Linux system manager to System Manager (VUART 2)
Send SID packet REQUEST with type SHUTDOWN to System Manager (VUART 2)
Execute lv1_panic HV call in GameOS
It should also work when Linux support was removed but Linux system manager was not removed from Process 9 and also assumed that a Linux kernel image is stored at the right place in /dev/rflash_1x.
It’s just a theory, nothing else, that i gathered during HV reversing. It needs a practical proof. Unfortunately, i don’t have access to Hypervisor.
AV Manager
All data sent to VUART 0 in LPAR 2 is written into the data buffer of VUART 5 of LPAR 1.
VUART 5 of LPAR 1 is accessed by Process 9 in LPAR 1 through the file /proc/partitions/2/vuart/0.
During initialization, AV Manager opens /dev/ioif0 device and maps different address ranges of the device into address space of Process 9
/dev/ioif0 is NOT opened and mapped if the value of repository node lv1.rsx.enable is less than 1
/dev/ioif0 is mapped with READ/WRITE protection
File descriptor of /dev/ioif0 in Process 9 is 4
AV Manager supports a lot more commands than used on Linux
Every command is implemented by a class
Mapped Address Ranges From /dev/ioif0
The base address of /dev/ioif0 is 0×28000000000. The device supports only mmap system call, it cannot be read or written. It also doesn’t support ioctl.
Index Absolute Address Range Size Mapped Address in Process 9 Address Space
0 0×28000000000 – 0×28000002000 0×2000 0xA0019000
1 0×28001800000 – 0×28001801000 0×1000 0xA0004000
2 0×28000600000 – 0×28000604000 0×4000 0xA001A000
3 0×28000680000 – 0×28000684000 0×4000 0xA0006000
4 0×28000080000 – 0×28000088000 0×8000 0xA000A000
5 0×28000088000 – 0×28000089000 0×1000 0xA000E000
6 0x2800000C000 – 0x2800000D000 0×1000 0xA0016000
7 0x2800008A000 – 0x2800008B000 0×1000 0xA0017000
8 0x2800008C000 – 0x2800008D000 0×1000 0xA0018000
Process socket services
Function ID and Packet ID
Processes 3, 5 and 6 provide services (functions) to other Processes through sockets (something like RPC).
A service is identified by a function ID.
Each process has a hash table which maps a function ID to socket port ID.
Services (functions) can be further differentiated by a packet ID.
To request a service, a Process sends a packet with specified function and packet ID to the Process that provides the service.
A process that provides a service (function) has a table of objects which handle different packet IDs.
Services are synchronous, a client sends a request and waits for a response.
If a Process requests a service that is located in the same Process then the service is called directly and sockets are not used !!! (e.g. SLL requests from DM creating VUART port during GameOS loading, SLL and DM are in the same Process, so SLL calls DM directly)
Port ID – Process ID mapping
Port ID Process ID
0×23 6
0×24 5
0×25 3
Function ID – Port ID mapping
Function ID Port ID Supported Packet IDs Function Description
0×2000 0×23 0×2001 – 0×2017 Virtual TRM Manager
0×3000 0×24 0×3001 – 0×3003 Secure RTC
0×5000 0×23 0×5001 – 0x500A Storage Manager
0×6000 0×23 0×6001 – 0×6011 Update Manager
0×9000 0×24 0×9001 – 0×9016 SC Manager
0×10000 0×23 – -
0×11000 0×25 0×11001 – 0×11002 SPM (Security Policy Manager)
0×14000 0×25 0×14004 – 0×14005 SLL (Secure LPAR Loader)
0×15000 0×24 0×15001, 0×15003, 0×15009 SPL (Secure Profile Loader)
0×17000 0×24 0×17001 – 0×17017 Indi Info Manager
0×18000 0×25 0×18001, 0×18002, 0×18004 Dispatcher Manager
0×19000 0×24 0×19002 – 0×19005 AIM
0×24000 0×23 0×24001 – 0×24002 USB Dongle Authenticator
0×25000 0×23 0×25001 – 0×25002 User Token Manager
SS Packet
SS means Secure Service ?
Processes send SS Packets to request a service or to reply to a service request.
Member variables
offset 0×8 – packet ID (8 bytes)
offset 0×10 – function ID (8 bytes)
offset 0×18 – return value (4 bytes)
offset 0×20 – subject ID (2 * 8 bytes)
Header
All services use a common header.
The header of a SS Packet is 0×28 bytes large.
struct ss_header
{
uint64_t packet_id;
uint64_t function_id;
uint32_t retval;
uint8_t res[4];
uint64_t laid; /* LPAR authority id */
uint64_t paid; /* Program authority id */
}
SS Service Return Values
Error Code Description
0×00000000 Success
0×00000005 Access Violation
0×00000006
Wiki Ingenieria inversa HV
Fuente