• PS3 Hacks , 17.11.2010

    Today graf_chokolo has made available to the PlayStation 3 Wiki (linked above) his PS3 hypervisor reverse-engineering work to date, as follows:

    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

    Source: Unforantly a mix of the EMO PS3 site and https://ps3wiki.lan.st/index.php/Hyp…se_Engineering

    Tags: ,

    Discuss in Forums (19)


  • 19 Comments

    1. CrystalWolf
      11-17-2010
      04:59 AM
      1

      What does this mean and what does this do ?????

    2. CaelThunderwing
      11-17-2010
      05:01 AM
      2

      Originally Posted by ultimathaker
      What does this mean and what does this do ?????
      this maynot be complete but its all the functions that have been documented of the PS3's Hypervisor

    3. rlme1
      11-17-2010
      05:15 AM
      3

      great job looking forward to what can come of this

    4. madshaun1984
      11-17-2010
      05:32 AM
      4

      If anyone here has a ps3 exploited with Geohots hardware mod, and on 3.15 still, please contact me via the irc/pm.

    5. BGsindikalac
      11-17-2010
      06:10 AM
      5

      omg this stuff may make your head explode :lol: That dude is really putting much effort into it. Great work.

    6. fanoh
      11-17-2010
      06:14 AM
      6

      Great effort

    7. lustimus
      11-17-2010
      08:37 AM
      7

      ..got to love the nerds

      thanks for all the hard work guys..

    8. michael903
      11-17-2010
      09:05 AM
      8

      Great work i see there is a TEMPERATURE command wonder if this tells how hot ps3 is running could be very good to help stop YLOD.Iwould love to no how hot it is running?Keep up the good work.

    9. PagaNz
      11-17-2010
      09:40 AM
      9

      flood of unneeded junk.

    10. Vampiror Nightstalker
      11-17-2010
      10:06 AM
      10

      I have no clue what any of this means!

      I saw about half way down about "region 0-7" is this refering to DVD region control? Didn't see anything about 0-3 for Bluray, Is bluray contolled on the drive itself?

      I hope this will lead to MR as I really want to multi region the PS3 DVD and Bluray

    11. jordanmoore
      11-17-2010
      10:11 AM
      11

      Originally Posted by PagaNz
      flood of unneeded junk.
      To you maybe. I imagine this is like porn to devs who know what to do with it.

    12. jblaze513
      11-17-2010
      10:19 AM
      12

      Originally Posted by PagaNz
      flood of unneeded junk.
      how do you call documented info on the hypervisor junk? unreal, this is above me but I can't wait until this gets to the right hands...

    13. ZanderCross
      11-17-2010
      10:24 AM
      13

      Originally Posted by PagaNz
      flood of unneeded junk.
      You guys don't get what PagaNz was getting at... He was saying that his own post was a flood of "unneeded junk"! This might be normal for him. Who knows!?

      Anyway thanks for the work guys!

    14. o0kilabot0o
      11-17-2010
      10:46 AM
      14

      or prolly Paganz needs attention?

    15. brakken
      11-17-2010
      12:39 PM
      15

      ||PagaNz
      ||flood of unneeded junk.

      |jblaze513 - 11-17-2010 10:19 AM
      |how do you call documented info on the hypervisor junk? unreal, this is above me but I can't wait until this gets to the right hands...

      "The right hands" most likely give two ****s about this site. I'm finally saying something. Most of this so called "news" is trivial garbage or not aimed at the target audience. It's either so boring and common sense, averagely entertaining or plain out over the heads of the readers.

      So stop posting non-sense bull**** (new clone this, new stupid SFO editor that). Stick to the good stuff and if you must post technical related material either take the time to explain what the hell you're posting, put the long **** in a comment/hidden/show box and if you don't know how to explain it yourself then don't post it.

      I sure as hell won't donate one US dollar to a site run like this.

      -brakken

    16. GregoryRasputin
      11-17-2010
      12:48 PM
      16

      Originally Posted by brakken
      ||PagaNz
      ||flood of unneeded junk.

      |jblaze513 - 11-17-2010 10:19 AM
      |how do you call documented info on the hypervisor junk? unreal, this is above me but I can't wait until this gets to the right hands...

      "The right hands" most likely give two ****s about this site. I'm finally saying something. Most of this so called "news" is trivial garbage or not aimed at the target audience. It's either so boring and common sense, averagely entertaining or plain out over the heads of the readers.

      So stop posting non-sense bull**** (new clone this, new stupid SFO editor that). Stick to the good stuff and if you must post technical related material either take the time to explain what the hell you're posting, put the long **** in a comment/hidden/show box and if you don't know how to explain it yourself then don't post it.

      I sure as hell won't donate one US dollar to a site run like this.

      -brakken

      Then go make your own site and dont post anything on the site, do stop crying like a little baby, its kinda pathetic, this site will continue to post what it wants, we aren't bothered by your dictating rants.

    17. advocatusdiaboli
      11-17-2010
      12:57 PM
      17

      Wow, finally some progress, kudos to you!

    18. vizard00
      11-17-2010
      01:42 PM
      18

      Originally Posted by ultimathaker
      What does this mean and what does this do ?????
      its a geohot poem

    19. ZanderCross
      11-17-2010
      02:45 PM
      19

      Originally Posted by brakken
      ||PagaNz
      ||flood of unneeded junk.

      |jblaze513 - 11-17-2010 10:19 AM
      |how do you call documented info on the hypervisor junk? unreal, this is above me but I can't wait until this gets to the right hands...

      "The right hands" most likely give two ****s about this site. I'm finally saying something. Most of this so called "news" is trivial garbage or not aimed at the target audience. It's either so boring and common sense, averagely entertaining or plain out over the heads of the readers.

      So stop posting non-sense bull**** (new clone this, new stupid SFO editor that). Stick to the good stuff and if you must post technical related material either take the time to explain what the hell you're posting, put the long **** in a comment/hidden/show box and if you don't know how to explain it yourself then don't post it.

      I sure as hell won't donate one US dollar to a site run like this.

      -brakken
      This is good stuff you idiot! Stop making accounts on news sites just to show them how dumb you are! That's obviously not "news" to anyone! Any progress is progress... Next time don't "finally say something" and keep your stupidity to yourself! Geez!