[Main Page]

PS3 Hypervisor Reverse Engineering

From EurAsiaWiki

Main Page | Recent changes | View source | Page history | Log in / create account |

Printable version | Disclaimers | Privacy policy
Category: PS3

Source: graf_chokolo @ http://www.ps3devwiki.com/index.php?title=Hypervisor_Reverse_Engineering


Contents

Difference between Debug Firmware HV and Retail HV

There is no difference between debug firmware lv1.self and retail firmware lv1.self The differences reside on the repository nodes loaded because of policies/flags.

HSPRG

LPAR

LPAR = Logical Partition

lpar1 starts at 0x<unknown>, and its belived to be the memory space where lv1 stores its variables, flags and other data.

lpar2 starts at 0x80000000000 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 0x38 - some pointer

offset 0x50 - LPAR id (8 bytes)

offset 0x70 - pointer to VAS id bitmap

offset 0x78 - 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).

0x00001930 (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 -0x6950(HSPRG0).

offset 0x8 - IIC memory base address (8 bytes)

offset 0x10 - thread register offset (8 bytes)

offset 0x18 - start of interrupt vector table (19 entries, each entry 32 bytes)

Interrupt vector table entry

offset 0x0 - pointer to interrupt handler

offset 0x8 - TOC

offset 0x10 - 0

offset 0x18 - 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

HV call

Id Name Description
8 lv1_undocumented_function_8 Retruns current uptime of HV
62 lv1_undocumented_function_62 SPE (isolation, it updates a SLB entry, writes to SLB_Index, SLB_VSID, SLB_ESID and SLB_Invalidate_Entry registers)
89 lv1_undocumented_function_89 SPE (writes to MFC_TLB_Invalidate_Entry register)
99 lv1_authenticate_program_segment SPE (isolation, syscall 0x10043, syscall 0x10042, syscall 0x1004A)
102 lv1_undocumented_function_102 Returns current TB ticks
137 lv1_undocumented_function_137 SPE
138 lv1_undocumented_function_138 SPE
167 lv1_undocumented_function_167 SPE (isolation, reads from SPU_Out_Intr_Mbox and MFC_CNTL registers)
168 lv1_undocumented_function_168 SPE (isolation, writes to MFC_CNTL register)
195 lv1_undocumented_function_195 WLAN Gelic device
196 lv1_undocumented_function_196 WLAN Gelic device
200 lv1_undocumented_function_200 SPE (isolation)
201 lv1_undocumented_function_201 SPE (isolation)
209 lv1_undocumented_function_209 SPE (isolation)
250 lv1_undocumented_function_250 Storage device
251 lv1_undocumented_function_251 Storage device
252 lv1_undocumented_function_252 Storage device
253 lv1_undocumented_function_253 Storage device

Initializing HV Call Table

set_lv1_hvcall_table

0x002C02B4 (3.41)

0x002C1F04 (3.15)

0x002C2B4C (3.55)

This function sets pointer to HV Call Table and the size of HV Call Table in HSPRG context of a LPAR.

set_lv1_hvcall_table_entry_invalid

0x002C1F28 (3.15)

0x002C02D8 (3.41)

0x002C2B70 (3.55)

This function initializes an entry in HV Call Table to the Invalid HV Call function.

Memory HV call

Memory HV call table

0x00364208 (3.15)

0x00362308 (3.41)

0x00366088 (3.55)

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 0x10000 - 0x100FF.

System call table 0 - 36

0x0035FAE8 (3.15)

0x00358ED0 (2.60)

System call numbers

0x1 - getpid(void)

0x2 - getppid(void)

0x3 - fork(void)

0x4 - exit

0x5 - exec(filename)

0x6 - wait(status)

0x7 - open(filename)

0x8 - close(fd)

0x9 - read

0xA - write

0xB - seek

0xC - unlink(filename)

0xD - signal

0xE - kill(pid, signal type)

0xF - brk

0x10 - socket(af, type, protocol) (supports only address family 0x1F, type 0x0 and protocol 0x0)

0x11 - bind

0x12 - listen(fd, backlog)

0x13 - accept

0x14 - connect

0x15 - ?

0x16 - pause(void)

0x17 - sleep(seconds)

0x18 - mmap(addr, size, prot, flags, fd, offset)

0x19 - 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

0x20 - ?

0x21 - alarm

0x22 - ioctl

0x23 - _map_pages

0x24 - _unmap_pages

System call table 0x10000 - 0x100FF

0x0035DE78 (3.15)

0x00357260 (2.60)

System call numbers

0x10000 - allocate_memory_region(LPAR id, size, log2 of page size, ?, ?)

0x10001 - lpar_query_address_region_info

0x10002 - lpar_memory_addr_to_phys_addr(LPAR id, LPAR address, physical addr)

0x10005 - construct_logical_pu

0x10007 - activate_logical_pu(LPAR id, PPE id)

0x10009 - construct_logical_partition(0, LPAR id, outlet)

0x1000E - release_memory_region(LPAR id, memory region address)

0x1001A - construct_event_receive_port

0x10024 - shutdown_logical_partition(LPAR id, shutdown command)

0x10025 - destruct_logical_partition(LPAR id)

0x10026 - get_logical_partition_info

0x1002C - construct_scheduling_table

0x1002D - set_scheduling_slot

0x10032 - accesses system console

0x10036 - accesses system console

0x10040 - construct_spe_type_1(SPE id, shaddow_addr)

0x10041 - destruct_spe(SPE id)

0x10042 - decrypt_lv2_self(spe id, LPAR auth id, SELF file image ptr, LPAR memory address)

0x10043 - load_spe_module(spe id, SCE module ptr, arg1, arg2, arg3, arg4)

0x10044 - disable_spe_execution

0x10045 - set_spe_interrupt_mask

0x10046 - read_spe_problem_state_register(spe id, register offset, value)

0x10047 - write_spe_problem_state_register(spe id, register offset, value)

0x1004B - disable_spe_loading

0x10053 - pmi_set_guest_os_mode

0x10081 - accesses system console

0x10084 - construct_virtual_uart(LPAR id, VUART id, VUART data buffer size)

0x10085 - destruct_virtual_uart(LPAR id, VUART id)

0x10088 - RSX_syscall_10088(LPAR id)

0x10089 - 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.

0x0035F8D0 (3.55)

0x0035C550 (3.41)

0x0035E850 (3.15)

0x00357C38 (2.60)

Process table entry

offset 0x0 - process status ? (8 bytes)

offset 0x8 - 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.

0x00299688 (3.15)

0x00295118 (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 0x0 - PID (4 bytes)

offset 0x8 - pointer to parent Process object

offset 0x10 - pointer to AddressSpace object

offset 0x30 - pointer to first PThread object of process

offset 0x38 - array of signal handlers (192 * 8 bytes)

offset 0x638 - pointer to pointer to ELF image

offset 0x640 - start of file table (20 * 24 bytes)

offset 0x820 - exit status (4 bytes)

offset 0x898 - 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

0x9 - SIGKILL

0xE - SIGALRM

0x20 - SIGSPUMB

0x21 - SIGSPUMB_SL

0x22 - SIGSPUSTOP

0x23 - SIGSPUSTOP_SL

0x24 - SIGSPUDMA

0x26 - SIGSPUTIMEOUT

0x27 - SIGSPUERR

0x41 - 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 0x0 - entry valid or invalid (1 byte), 0 - invalid, 1 - valid

offset 0x8 - pointer to object with File interface

offset 0x10 - 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:

Here are the addresses of Process objects i could identify in HV dump 2.60:

PThread

All PThread objects of the same Process object are linked together in a list.

vtable

0x003556D8 (3.15)

0x0034ECC0 (2.60)

offset 0x60 - pointer to TOC entry of system call handler

Member variables

offset 0x10 - pointer to next PThread object of Process

offset 0x18 - Thread object

offset 0x2B8 - ? (4 bytes)

offset 0x2C0 - pointer to TOC of some function

offset 0x2C8 - pointer to TOC of some function

offset 0x348 - 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 0x440 - 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

0x00355750 (3.15)

Member variables

offset 0x288 - some pointer

offset 0x290 - some pointer

AddressSpace

vtable

0x003549A0 (3.15)

0x0034DF88 (2.60)

Member variables

offset 0x8 - Mutex object

offset 0x40 - AddressProtectionDomain object

offset 0x50 - some pointer

offset 0xC0 - some counter (4 bytes)

AddressSpace_EA_to_RA

0x002874D0 (3.15)

AddressProtectionDomain

vtable

0x00354980 (3.15)

Member variables

offset 0x8 - pointer to previous AddressProtectionDomain object

offset 0x10 - pointer to next AddressProtectionDomain object

offset 0x18 - poiinter to pointer to SLB entries

offset 0x20 - pointer to AddressSpace object that owns this object

offset 0x34 - pointer to previous ProtectionPage

offset 0x3C - pointer to next ProtectionPage

offset 0x48 - Mutex object

ProtectionPage

vtable

none

Member variables

offset 0x0 - RA (8 bytes)

offset 0x8 - EA (4 bytes)

offset 0x10 - pointer to previous ProtectionPage (4 bytes)

offset 0x14 - pointer to next ProtectionPage (4 bytes)

Mutex

vtable

0x00354D08 (3.15)

0x0034E2F0 (2.60)

Member variables

offset 0x18 - ? (4 bytes)

offset 0x1C - ? (4 bytes)

ConditionVariable

vtable

0x003549C0 (3.15)

offset 0x20 - wait

Member variables

offset 0x20 - pointer to Mutex object

File interface

vtable

offset 0x8 - ?

offset 0x28 - open

offset 0x30 - close

offset 0x38 - read

offset 0x40 - write

offset 0x50 - mmap

offset 0x58 - ioctl

StorageRegionFile

Flash device file class.

vtable

0x003569F8 (3.15)

VUARTFile

VUART device file class.

vtable

0x00356458 (3.15)

STDLCFile

Console device file class.

vtable

0x003561F8 (3.15)

Member variables

offset 0x20 - reference counter (8 bytes)

offset 0x28 - free buffer space ? (8 bytes)

SocketFile

vtable

0x00355DB0 (3.15)

offset 0xB0 - bind

RegionManager

vtable

0x00355F80 (3.15)

Inode

DirectoryInode

vtable

0x00355788 (3.15)

offset 0x20 - link

offset 0x28 - 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 0x30 - lookup

File system

Console device file objects

Here is the list of console device file objects i found in HV dump 3.15:

vtable

0x003561F8 (3.15)

Flash device file objects

Here is the list of flash device file objects i found in HV dump 3.15:

vtable

0x003569F8 (3.15)

IOIF device file objects

Here is the list of IOIF device file objects i found in HV dump 3.15:

vtable

0x00356688 (3.15)

Member variables

0x360 = 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:

vtable

0x00356B48 (3.15)

NET device file objects

Here is the list of NET device file objects i found in HV dump 3.15:

vtable

0x00356DE8 (3.15)

INODES

INODE OBJECT

+0x04: previos inode

+0x08: next inodes

+ 0x38:  path

+ 0x358: childer_inode


MFS_ROOT_INODE

(2.60) 0x3580B0

+ 0x60 = ROOT_INODE


SOME ADDRESSES IN 2.60

0x60C010: "/dev" inode

0x6AA580: "/proc" inode

using linked list you can follow all inodes

Repository

RepositoryNode

vtable

0x00357F58 (3.15)

Member variables

offset 0x30 - pointer to next RepositoryNode obj

offset 0x38 - 2nd hash value of name (4 bytes)

offset 0x40 - 1st field name (8 bytes)

offset 0x48 - 2nd field name (8 bytes)

offset 0x50 - 3rd field name (8 bytes)

offset 0x58 - 4th field name (8 bytes)

offset 0x60 - ? (4 bytes)

offset 0x68 - 1st field value (8 bytes)

offset 0x70 - 2nd field value (8 bytes)

Hash Function

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 & 0xAAAAAAAAULL) >> 1);

    h = ((h & 0x33333333ULL) << 2) | ((h & 0xCCCCCCCCULL) >> 2);

    h = ((h & 0xF0F0F0FULL) << 4) | ((h & 0xF0F0F0F0ULL) >> 4);

    hl = (h << 8) | ((h & 0xFF000000ULL) >> 24);

    hl = (hl & ~0xFF000000UL) | ((h & 0xFFULL) << 24);

    hl = (hl & ~0x0000FF00UL) | (((h << 24) | (h >> 8)) & 0x0000FF00ULL);

    hl |= 0x1; 

    *h2 = hl;
}

Repository nodes from HV 3.15

Dump of all repository nodes from HV 3.15

Repository nodes from HV 3.41 dump made from GameOS

Dump of all repository nodes from HV 3.41 dump made from GameOS

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

0x00352600 (3.15)

Member variables

offset 0x10 - MMIO memory base address

offset 0x20 - array of 16 pointers to SB devices (0 - Gelic device, 1 - USB device)

Objects

0x00349528 - pointer to pointer to SB bus subsystem object

Memory base address

0x24000000000

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 0x18 - pointer to previous bus memory region object

offset 0x20 - pointer to next bus memory region object

offset 0x30 - relative bus memory start address

offset 0x38 - size of bus memory region

SB bus device

vtable

0x00352620 (3.15)

Member variables

offset 0x18 - array of pointers to MMIO memory region objects owned by device (8 * 8 bytes)

offset 0x60 - pointer to first DMA region object

offset 0x6C - device opened flag (1 byte, 0 - not opened, 1 - already opened)

offset 0x70 - id of LPAR that opened this device

offset 0x90 - 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 0x2800 0x24000002800 0x200
1 0x3004000 0x24003004000 0x1000
2 - - -
3 - - -
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 - 0x8000
0xC0000000 - 0x10000000

SATA Controller 1 device

device id = 1

interrupt index = 49

MMIO regions

Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2000 0x24000002000 0x200
1 0x3000000 0x24003000000 0x1000
2 0x3800000 0x24003800000 0x1000
3 0x3802000 0x24003802000 0x1000
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 - 0x1000
0xA0001000 - 0x1000
0xA0002000 - 0x1000

SATA Controller 2 device

device id = 2

interrupt index = 13

MMIO regions

Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2200 0x24000002200 0x200
1 0x3001000 0x24003001000 0x1000
2 0x3801000 0x24003801000 0x1000
3 0x3803000 0x24003803000 0x1000
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0xA0000000 - 0x1000
0xA0001000 - 0x1000
0xA0002000 - 0x1000

USB Controller 1 device

device id = 3

MMIO regions

Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2400 0x24000002400 0x200
1 0x3010000 0x24003010000 0x10000
2 0x3810000 0x24003810000 0x10000
3 - - -
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0xC0000000 - 0x10000000
0xD0000000 - 0x10000000

USB Controller 2 device

device id = 4

MMIO regions

Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2600 0x24000002600 0x200
1 0x3020000 0x24003020000 0x10000
2 0x3820000 0x24003820000 0x10000
3 - - -
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0xC0000000 - 0x10000000
0xD0000000 - 0x10000000

ENCDEC device

device id = 7

interrupt index = 5

MMIO regions

Index Relative Bus Start Address Absolute Bus Start Address Size
0 0x2C00 0x24000002C00 0x200
1 0x3005000 0x24003005000 0x1000
2 0x3006000 0x24003006000 0x1000
3 - - -
4 - - -
5 - - -
6 - - -
7 - - -

DMA regions

Relative Bus Start Address Absolute Bus Start Address Size
0x80010000 - 0x10000
0x80004000 - 0x4000
0x80001000 - 0x1000
0x80003000 - 0x1000
0x80008000 - 0x1000
0x80009000 - 0x1000
0x80040000 - 0x10000
0x8000A000 - 0x1000
0x90020000 - 0x20000
0xC0000000 - 0x10000
0xC0040000 - 0x40000

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
0x80000000 - 0x1000
0x80020000 - 0x20000
0x80002000 - 0x1000
0x90000000 - 0x20000

SB Bus Interrupt Handling

Interrupt Index

Interrupt Handler Table

Interrupt Description Address in HV
5 ENCDEC device 0x00275C60 (3.15)
6 EH EPCIC internal 0x0023B6B0 (3.15)
8 Gelic device 0x00245330 (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 0x8 - device id (8 bytes)

offset 0xD50 - device id (8 bytes)

offset 0xD60 - pointer to ENCDEC SB bus device object

Region Manager

Region

Region ACL

offset 0x0 - LPAR AUTH ID (8 bytes)

offset 0x8 - access rigths (8 bytes)

offset 0x10 - entry valid flag: 0 - invalid, 1 - valid (1 byte)

Region Access Protection
 I tested on HV 3.41 with flags 0x2 and got access to regions which were denied by policy (LV1_DENIED_BY_POLICY result).

Storage Device Partition Table

Methods

lv1_storage_create_region (lv1_undocumented_function_250) - 0x00301328 (3.15)

lv1_storage_delete_region (lv1_undocumented_function_251) - 0x003011E8 (3.15)

lv1_storage_set_region_acl (lv1_undocumented_function_252) - 0x00300F3C (3.15)

lv1_storage_get_region_acl (lv1_undocumented_function_253) - 0x00301090 (3.15)

storage_device_create_region - 0x00253988 (3.15)

storage_device_delete_region - 0x00253BE8 (3.15)

storage_device_region_set_acl - 0x00252C80 (3.15)

storage_device_region_get_acl - 0x00252710 (3.15)

storage_region_mgr_create_region - 0x0025A530 (3.15)

storage_region_mgr_delete_region - 0x0025BA64 (3.15)

storage_region_mgr_set_acl - 0x0025A140 (3.15)

storage_region_mgr_get_acl - 0x0025A298 (3.15)

storage_region_mgr_update_partition_table - 0x00259924 (3.15)

storage_region_acl_entry_reset - 0x0025C1A8 (3.15)

storage_region_acl_entry_check_laid - 0x0025C1FC (3.15)

storage_region_overlap - 0x0025C094 (3.15)

storage_region_check_access - 0x00259EC8 (3.15)

Storage subsystem device

device id = -1

Notification Events

List of supported notification events:

RBD device

device id = 0

block size = 2048

/dev/rbd0

vtable

0x00354288 (3.15)

Member variables

offset 0x1808 - request table (0x58 * 32 bytes)

Regions

Index Start sector Number of sectors
0 0x0 0x7FFFFFFF
1 - -
2 - -
3 - -
4 - -
5 - -
6 - -
7 - -

Supported Device Commands

Here is the list of commands supported by RBD storage device.

Command Description
0x1 LV1_STORAGE_SEND_ATAPI_COMMAND
0x10 ATAPI Read Capacity
0x11 ATAPI Get Configuration
0x13 ATAPI Read TOC
0x1A ATAPI Get Event

/dev/rbd0

ENCDEC Device

bus id = 4

device id = 0

Member variables

offset 0xDC0 - request table (0x58 * 32 bytes)

Methods

encdec_device_initialize - 0x00273524 (3.15)

InitializeENCDEC - 0x00277310 (3.15)

ENCDEC_ConnectBusDriver - 0x00275A98 (3.15)

encdec_interrupt_handler - 0x00275C60 (3.15)

encdec_process_interrupt - 0x0027526C (3.15)

encdec_device_enqueue_decsec_request - 0x00273738 (3.15)

encdec_device_do_request - 0x00273EA8 (3.15)

encdec_device_do_SS_request - 0x00274940 (3.15)

Encdec_KickDMA - 0x00277118 (3.15)

encdec_device_is_in_testmode - 0x002756E0 (3.15)

is_encdec_in_testmode - 0x002732D0 (3.15)

ENCDEC Device Commands

Command Description
0x81 EdecKgen1
0x82 EdecKgen2
0x83 EdecKset/EdecKset NG
0x84 EdecKgenFlash
0x85 Encrypts/decrypts sectors (This command cannot be executed through ioctl interface !!!)
0x86 Encdec decsec (This command cannot be executed through ioctl interface !!!)
0x87 EdecSBClear

EdecKgen1 Command (0x81)

Here is the data i sent to ENCDEC device:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   00 01 00 30 72 A7 88 EC  FC A4 06 71 4C B1 50 C9   ...0r§ˆìü¤.qL±PÉ
00000010   FB E0 06 C2 74 B5 84 C4  E6 BD 1E 55 4E 36 E9 C9   ûà.Âtµ„Äæ½.UN6éÉ
00000020   D6 09 BC B4 79 A6 BC DE  60 A5 B2 41 C7 15 68 68   Ö.¼´y¦¼Þ`¥²AÇ.hh
00000030   82 1D 8F D6 00 00 00 00  00 00 00 00 00 00 00 00   ‚.Ö............

Here is the data i received back from ENCDEC device:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   00 02 00 00 57 CF 06 AF  53 85 1B B8 49 37 06 28   ....WÏ.¯S….¸I7.(
00000010   51 8D 4E F9 EF 76 E2 C7  17 EF 41 14 FA 6C 96 A8   QNùïvâÇ.ïA.úl–¨
00000020   7E 41 43 96 15 9A 0D 71  A9 B6 A6 B0 F1 96 15 C5   ~AC–.š.q©¶¦°ñ–.Å
00000030   30 25 C3 8E 6F AC FB 7F  E7 2A FB E2 36 E1 85 92   0%ÃŽo¬ûç*ûâ6á…’
00000040   99 66 DB EC 00 00 00 00  00 00 00 00 00 00 00 00   ™fÛì............

Here is another data i received back from ENCDEC device by using the same command and data:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   00 02 00 00 57 CF 06 AF  53 85 1B B8 49 37 06 28   ....WÏ.¯S….¸I7.(
00000010   51 8D 4E F9 EF 76 E2 C7  17 EF 41 14 FA 6C 96 A8   QNùïvâÇ.ïA.úl–¨
00000020   7E 41 43 96 17 08 75 F6  66 2F 32 5A 9E 3E E7 FD   ~AC–..uöf/2Zž>çý
00000030   16 3E 18 CA B2 5E 90 84  29 7F 98 BC 73 36 0E 7B   .>.ʲ^„)˜¼s6.{
00000040   7D EC B6 37 00 00 00 00  00 00 00 00 00 00 00 00   }ì¶7............

EdecKgen2 Command (0x82)

EdecKset Command (0x83)

EdecKgenFlash Command (0x84)

Encdec decsec Command (0x86)

EdecSBClear Command (0x87)

Test Mode

ENCDEC Request

offset 0x34 - start sector (4 bytes)

offset 0x38 - sector count (4 bytes)

offset 0x3C - sector size (4 bytes)

offset 0x40 - key (4 bytes)

offset 0x44 - 0 = decrypt, 1 = encrypt (4 bytes)

Encrypting and Decrypting Sectors

ENCDEC User Buffer

offset 0x0 - start sector (4 bytes)

offset 0x4 - sector count (4 bytes)

offset 0x8 - sector size (4 bytes)

offset 0xC - key (4 bytes)

FLASH device

device id = 1

vtable

0x00354450 (3.15)

Member variables

offset 0x18F0 - request table (0x58 * 16 bytes)

Regions

Index Start sector Number of sectors
0 0x0 0x8000
1 0x8 0x77F8
2 0x7900 0x100
3 0x7A00 0x400
4 - -
5 - -
6 - -
7 - -

Supported Device Commands

Here is the list of commands supported by FLASH StarShip 2 storage device.

Command Description
0x31 Dummy (This command does nothing, returns success immediately)
0xA2 -
0xA3 -
0xA4 -
0xA6 SS2 HW Reset
0xAC -
0xAD TEST

/dev/eflash1 and /dev/rflash1

Content of /dev/rflash1 (FLASH storage device region 0, size 16 MB)

TOC Entry

A TOC entry is 0x30 bytes large.

offset 0x0 - relative offset from this TOC to entry data

offset 0x8 - entry data size

offset 0x10 - 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 0x400 0 0x400 0x810 0x2E800
eEID 0x400 1 0x2EC00 0x2F010 0x10000
cISD 0x400 2 0x3EC00 0x3F010 0x800
cCSD 0x400 3 0x3F400 0x3F810 0x800
trvk_prg0 0x400 4 0x3FC00 0x40010 0x20000
trvk_prg1 0x400 5 0x5FC00 0x60010 0x20000
trvk_pkg0 0x400 6 0x7FC00 0x80010 0x20000
trvk_pkg1 0x400 7 0x9FC00 0xA0010 0x20000
ros0 0x400 8 0xBFC00 0xC0010 0x700000
ros1 0x400 9 0x7BFC00 0x7C0010 0x700000
cvtrm 0x400 10 0xEBFC00 0xEC0010 0x40000
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 0x800 0 0x40 0x840 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 0x460 0xC0470 0x40000
sdk_version 0xC0000 1 0x40460 0x100470 0x8
lv1ldr 0xC0000 2 0x40480 0x100490 0x1E948
lv2ldr 0xC0000 3 0x5EE00 0x11EE10 0x16FF0
isoldr 0xC0000 4 0x75E00 0x135E10 0x13074
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 0x198140 0x4498
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 0x106774 0x1C6784 0x5DB0
default.spp 0xC0000 16 0x10C524 0x1CC534 0x22A0
lv1.self 0xC0000 17 0x10E800 0x1CE810 0x127DF0
lv0 0xC0000 18 0x236600 0x2F6610 0x3E678
lv2_kernel.self 0xC0000 19 0x274C78 0x334C88 0x171B88
eurus_fw.bin 0xC0000 20 0x3E6800 0x4A6810 0x70F94
emer_init.self 0xC0000 21 0x457794 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 0x460 0x7C0470 0x40000
sdk_version 0x7C0000 1 0x40460 0x800470 0x8
lv1ldr 0x7C0000 2 0x40480 0x800490 0x1E64C
lv2ldr 0x7C0000 3 0x5EB00 0x81EB10 0x16E30
isoldr 0x7C0000 4 0x75980 0x835990 0x12EC4
appldr 0x7C0000 5 0x88880 0x848890 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 0x882124 0x1532C
aim_spu_module.self 0x7C0000 10 0xD7440 0x897450 0x4498
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 0x129040
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 0x457354 0xC17364 0x7FBB8
hdd_copy.self 0x7C0000 22 0x4D6F0C 0xC96F1C 0x61518

Methods

initialize_starship - 0x0028298C (3.15)

SSOperation - 0x0027BFB0 (3.15)

SSTransfer - 0x0027BE68 (3.15)

FLASH_Memory_SS2_on_complete - 0x00278E48 (3.15)

_FLASH_read_data - 0x0022D89C (3.15)

_FLASH_write_data - 0x0022D8C8 (3.15)

FLASH_SS2_HW_Reset - 0x0027BD1C (3.15)

HDD device

device id = 2

block size = 512

vtable

0x00353F48 (3.15)

Member variables

offset 0x1590 - LBA48 capability flag (4 bytes)

offset 0x17E8 - request table (0x58 * 16 bytes)

offset 0x1DB8 - request timer active flag (1 byte)

Regions

Index Start sector Number of sectors
0 0x0 0x950F8B0
1 0x8 0x80000
2 0x80018 0x7C8F898
3 0x7D0F8B8 0x3FFFF8
4 0x810F8B8 0x13FFFF8
5 - -
6 - -
7 - -

Supported Device Commands

Here is the list of commands supported by HDD storage device.

Command Description
0x2 LV1_STORAGE_SEND_ATA_COMMAND
0x10 -
0x1B ATA Set UltraDMA Mode
0x1C ATA Set Features PIO Flow Control Transfer Mode
0x21 -
0x22 ATA Identify Device
0x23 LV1_STORAGE_ATA_HDDOUT (ATA Flush Cache Ext)
0x26 ATA Read Alternative Status
0x27 ATA Read Error
0x28 -
0x31 ATA Flush Cache/ATA Flush Cache Ext
0x32 ATA Stanby Immediate
0x33 -

Virtual FLASH device (VFLASH)

device id = 3 (on Linux)/ 4 (on GameOS)

block size = 512

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 0x0 0x80000
1 0x8 0x75F8
2 0x7800 0x63E00
3 0x6B600 0x8000
4 0x73600 0x400
5 0x73A00 0x2000
6 0x77C00 0x200
7 - -

Supported Device Commands

Here is the list of commands supported by VFLASH storage device.

Index Start sector Number of sectors
0x31 ATA Flush Cache/ATA Flush Cache Ext -

/dev/rflash1_1x and /dev/rflash_1xp

GameOS's dev_flash

Here is a snippet from raw dev_flash dump made with HV call lv1_storage_read (flags 0x4) from GameOS:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   E9 00 00 20 20 20 20 20  20 20 20 00 02 10 10 00   é..        .....
00000010   02 00 02 00 00 F8 70 00  00 00 00 00 00 00 00 00   .....øp.........
00000020   00 3E 06 00 00 00 29 00  00 00 00 4E 4F 20 4E 41   .>....)....NO NA
00000030   4D 45 20 20 20 20 46 41  54 31 36 20 20 20 00 00   ME    FAT16   ..
00000040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000060   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000070   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000080   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000100   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000110   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000130   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000140   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000150   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000160   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000170   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000180   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000190   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 AA   ..............Uª


Methods

initialize_virtual_flash - 0x00282954 (3.15)

Enqueueing and Scheduling of Storage Requests

Storage Device Request Table

Request Slot

offset 0x0 - state: 1 - free, 2 - ? (4 bytes)

offset 0x4 - type: 1 - Read/Write, 2 - Command, 0x86 - ENCDEC command (4 bytes)

offset 0x10 - request tag (8 bytes)

offset 0x20 - start sector (8 bytes)

offset 0x28 - sector count (4 bytes)

ENCDEC Storage Device

RBD Storage Device

FLASH Storage Device

HDD Storage Device

Methods

storage_device_HDD_enqueue_request - 0x0026E21C (3.15)

storage_device_HDD_do_device_command - 0x0026CED0 (3.15)

storage_device_HDD_do_request - 0x0026DED8 (3.15)

storage_device_HDD_request_complete - 0x0026E57C (3.15)

storage_device_FLASH_enqueue_request - 0x0027A518 (3.15)

storage_device_FLASH_do_request - 0x00278D1C (3.15)

storage_device_FLASH_do_device_command - 0x00279250 (3.15)

FLASH_Memory_SS2_on_complete - 0x00278E48 (3.15)

storage_device_async_request_complete - 0x00255184 (3.15)

storage_device_TransLparAddrToPhysAddr - 0x002533B4 (3.15)

storage_device_add_async_request_locked - 0x002527B8 (3.15)

storage_device_RBD_enqueue_request - 0x002723F0 (3.15)

storage_device_RBD_do_request - 0x0025EF70 (3.15)

storage_device_RBD_do_next_request - 0x00270994 (3.15)

storage_device_RBD_request_complete - 0x00271FD4 (3.15)

storage_device_rbd_do_request - 0x0025EE94 (3.41)

storage_device_rbd_do_device_command - 0x0027061C (3.41)

Encryption and Decryption of Storage Devices

HDD

UFS2

Here is the decrypted superblock of UFS2 filesystem:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00010000   00 00 00 00 00 00 00 00  00 00 00 28 00 00 00 30   ...........(...0
00010010   00 00 00 38 00 00 0B B8  00 00 00 00 00 00 00 00   ...8...¸........
00010020   00 00 00 00 00 00 00 00  00 00 78 10 00 00 01 5C   ..........x....\
00010030   00 00 40 00 00 00 08 00  00 00 00 08 00 00 00 08   ..@.............
00010040   00 00 00 00 00 00 00 00  FF FF C0 00 FF FF F8 00   ........ÿÿÀ.ÿÿø.
00010050   00 00 00 0E 00 00 00 0B  00 00 00 08 00 00 08 00   ................
00010060   00 00 00 03 00 00 00 02  00 00 08 00 00 00 00 00   ................
00010070   00 00 00 00 00 00 08 00  00 00 00 40 00 00 00 00   ...........@....
00010080   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010090   00 00 00 00 F5 35 BD 07  00 00 00 00 00 00 18 00   ....õ5½.........
000100A0   00 00 40 00 00 00 00 00  00 00 00 00 00 00 00 00   ..@.............
000100B0   00 00 00 00 00 00 00 00  00 00 5C 00 00 01 6F 70   ..........\...op
000100C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000100D0   00 00 00 80 2F 63 65 6C  6C 5F 6D 77 5F 63 66 73   ...€/cell_mw_cfs
000100E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000100F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010100   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010110   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010130   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010140   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010150   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010160   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010170   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010180   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010190   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000101F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010200   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010210   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010220   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010230   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010240   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010250   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010260   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010270   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010280   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010290   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000102A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000102B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000102C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000102D0   00 00 00 00 00 00 00 7C  00 00 00 00 00 00 00 00   .......|........
000102E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000102F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010300   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010310   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010320   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010330   00 00 00 00 00 00 00 00  80 00 00 00 00 55 FD 70   ........€....Uýp
00010340   80 00 00 00 00 55 E0 00  80 00 00 00 00 55 F8 00   €....Uà.€....Uø.
00010350   00 00 00 00 00 00 00 00  00 00 00 00 00 00 40 00   ..............@.
00010360   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010370   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010380   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010390   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000103A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000103B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000103C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000103D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000103E0   00 00 00 00 00 00 00 00  00 00 00 00 00 01 00 00   ................
000103F0   00 00 00 00 00 00 00 3C  00 00 00 00 00 3B D3 23   .......<.....;Ó#
00010400   00 00 00 00 00 7D 0F 82  00 00 00 00 00 00 00 9F   .....}.‚.......Ÿ
00010410   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010420   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010430   00 00 00 00 49 B0 5E 3B  00 00 00 00 01 F2 3E 26   ....I°^;.....ò>&
00010440   00 00 00 00 01 E2 86 3B  00 00 00 00 00 00 0B B8   .....â†;.......¸
00010450   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010460   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010470   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010480   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010490   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000104A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 40 00   ..............@.
000104B0   00 00 00 40 00 00 00 00  00 00 00 00 00 00 00 00   ...@............
000104C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000104D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000104E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000104F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010500   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010510   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00010520   00 00 00 03 00 00 00 08  00 00 00 78 00 00 00 00   ...........x....
00010530   00 00 80 10 02 02 FF FF  00 00 00 00 00 00 3F FF   ..€...ÿÿ......?ÿ
00010540   00 00 00 00 00 00 07 FF  00 00 00 00 00 00 00 00   .......ÿ........
00010550   00 00 00 00 00 00 00 00  00 00 00 00 19 54 01 19   .............T..

Other examples:

http://pastebin.com/3L241qu3
http://pastebin.com/WJv40nUQ
http://pastie.org/1529241
http://pastie.org/1588747

FLASH

RBD

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)

Booting a Bootloader from VFLASH

Coming soon !!!

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 0x10040 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

0x00358360 (3.15)

offset 0x20 - pointer to TOC entry of interrupt handler for SPE

Member variables

offset 0x38 - pointer to LPAR obj that owns this SPE obj

offset 0x78 - 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:

SPEType1

SPE type = 1

vtable

0x00359750

Member Variables

offset 0x198 - pointer to MMIO Memory Region object

offset 0x1A0 - pointer to Shadow Registers Memory Region object

SPEType2

SPE type = 2

vtable

0x00359790

SPE Register Shadow Area

SPE Register Shadow Area Offsets

0x30 - SPU_Status register value (4 bytes)

0xF10 - ?

0xF18 - ?

Stop Code

Here is the list of Stop Codes i extracted from HV Processes which read the value at offset 0x30 when SPU is done:

Value Description
0xA Success
0xC Access Violation (LPAR auth id error)
0xE  ?
0xF Revoked
0x12 Invalid Parameter
0x13  ?
0x17 Invalid Parameter
0x25  ?

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)

Isolation

Loaders Table

0x00010100 (3.15)

Loaders Table Entry

offset 0x0 - pointer to data in memory

offset 0x8 - size of data

Here are the contents of the Loaders Table from HV 3.15:

Index Name Address of Data in HV Dump Size of Data
0 - 0x0C150000 0x1E5CC
1 metldr 0x00011000 0xE8D0
2 lv2ldr 0x00020000 0x16DA0
3 isoldr 0x00055000 0x12E44
4 appldr 0x00037000 0x1DAE4
5 EID0 0x00068000 0x860
6 - 0x00069010 0x8
7 - 0x00069020 0x50
8 - 0x00069070 0x8

Methods

get_iso_loaders_tab - 0x002B0B70 (3.15)

iso_loaders_tab_get_entry - 0x002B0CB8 (3.15)

metldr

Loading metldr

Methods

SPE_load_request_metldr - 0x002B00A4 (3.15)

lv2ldr

Methods

SPE_load_request_lv2ldr_1 - 0x002AE82C (3.15)

SPE_load_request_lv2ldr_2 - 0x002AE8D8 (3.15)

Loading lv2ldr

isoldr

Revoke List For Programs

0x00361980 (3.15)

Methods

SPE_load_request_isoldr - 0x002B0394

Loading isoldr

appldr

Methods

SPE_load_request_appldr - 0x002AE900

Loading appldr

Decrypting SELFs with appldr and lv1_authenticate_program_segment

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:

Socket table entry

offset 0x0 - pointer to Socket obj

offset 0x8 - 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 0x360 - socket state (4 bytes)

offset 0x368 - port ID (8 bytes)

offset 0x370 - max backlog queue size (8 bytes)

Virtual Address Space

VAS

vtable

0x00357958 (3.15)

Member variables

offset 0x18 - pointer to LPAR that owns this VAS object

offset 0x48 - VAS id (8 bytes)

offset 0x70 - number of page sizes (4 bytes)

offset 0x74 - log2 of HTAB size

offset 0x78 - pointer to HTAB object

Objects

Here is the list of the VAS objects i found in HV dump 3.15:

HTAB

0x38(-0x69A8(HSPRG0)) - pointer to the currently active HTAB in LPAR

vtable

0x003575B0 (3.15)

Member variables

offset 0x48 - pointer to first PTE

offset 0x60 - LPID (4 bytes)

offset 0x64 - log2 of HTAB size (4 bytes)

Objects

Here is the list of the HTAB objects i found in HV dump 3.15:

 * 0x00180000 - HTAB PTEs (HTAB size 256 kB)
 * 0x00500000 - HTAB PTEs (HTAB size 1 MB)
 * 0x00800000 - 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 0x8 0x38
data 0xC 0x3C
heap 0xA 0x3A
stack 0xF 0x3F

Process 5

SLB entries

0x00093120 (3.15)

Name ESID VSID
code 0x8 0x48
data 0xC 0x4C
heap 0xA 0x4A
stack 0xF 0x4F

Process 6

SLB entries

0x000E6960 (3.15)

Name ESID VSID
code 0x8 0x58
data 0xC 0x5C
heap 0xA 0x5A
stack 0xF 0x5F

Process 9

SLB entries

0x00763E20 (3.15)

Name ESID VSID
code 0x8 0x8
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.

0x00677218 (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:

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:

VUART 0 and VUART 2 of LPAR 2 are created by Process 9 during LPAR construction.

VUART class

Member variables

offset 0x48 - pointer to peer VUART object

offset 0x58 - write pointer into data ring buffer

offset 0x60 - read pointer into data ring buffer

offset 0x68 - pointer to data ring buffer

offset 0x70 - size of data ring buffer (8 bytes)

offset 0x78 - size of data stored in data ring buffer currently (8 bytes)

offset 0x88 - tx trigger (8 bytes)

offset 0x90 - rx trigger (8 bytes)

offset 0x98 - 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.

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.

A/V Manager

System Manager (SM)

System Manager class

Member variables

offset 0x10 - LPAR state (8 bytes)

offset 0x68 - LPAR auth id

offset 0x70 - LPAR name

offset 0x90 - LPAR image path

offset 0x1C0 - LPAR ability (8 bytes)

Types of System Manager

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 0x1 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 0x40012 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
9 25 / 50 (FAN_POLICY) Fan Policy
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 Shares data with 25 -
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

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
0x1 0x0 0xFF 0xFF 0xFF Turns off the power button LED
0x1 0x1 0xFF 0xFF 0xFF Turns on the power button LED

21 - RING_BUZZER

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
0x29 0x4 0x6 Makes a short single beep
0x29 0xA 0x1B6 Makes a double beep
0x29 0x7 0x36 -
0x29 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 0x1070000001000001 /flh/os/this_is_dummy 0x1
1 SCE_CELLOS_SYSTEM_MGR 0x1070000002000001 /flh/os/lv2_kernel.self 0x3BF7EF
2 SCE_CELLOS_SYSTEM_MGR_PS2_SW 0x1020000003000001 /local_sys0/ps2emu/ps2_softemu.self 0x1226D
3 SCE_CELLOS_SYSTEM_MGR_LINUX 0x1080000004000001 /flh/lx/linux 0x40012

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 !!!):

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.

Booting modified and reencrypted lv2_kernel.self

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.

Mapped Address Ranges From /dev/ioif0

The base address of /dev/ioif0 is 0x28000000000. 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 0x28000000000 - 0x28000002000 0x2000 0xA0019000
1 0x28001800000 - 0x28001801000 0x1000 0xA0004000
2 0x28000600000 - 0x28000604000 0x4000 0xA001A000
3 0x28000680000 - 0x28000684000 0x4000 0xA0006000
4 0x28000080000 - 0x28000088000 0x8000 0xA000A000
5 0x28000088000 - 0x28000089000 0x1000 0xA000E000
6 0x2800000C000 - 0x2800000D000 0x1000 0xA0016000
7 0x2800008A000 - 0x2800008B000 0x1000 0xA0017000
8 0x2800008C000 - 0x2800008D000 0x1000 0xA0018000

Process socket services

Function ID and Packet ID

Port ID - Process ID mapping

Port ID Process ID
0x23 6
0x24 5
0x25 3

Function ID - Port ID mapping

Function ID Port ID Supported Packet IDs Function Description
0x2000 0x23 0x2001 - 0x2017 Virtual TRM Manager
0x3000 0x24 0x3001 - 0x3003 Secure RTC
0x5000 0x23 0x5001 - 0x500A Storage Manager
0x6000 0x23 0x6001 - 0x6011 Update Manager
0x9000 0x24 0x9001 - 0x9016 SC Manager
0x10000 0x23 - -
0x11000 0x25 0x11001 - 0x11002 SPM (Security Policy Manager)
0x14000 0x25 0x14004 - 0x14005 SLL (Secure LPAR Loader)
0x15000 0x24 0x15001, 0x15003, 0x15009 SPL (Secure Profile Loader)
0x17000 0x24 0x17001 - 0x17017 Indi Info Manager
0x18000 0x25 0x18001, 0x18002, 0x18004 Dispatcher Manager
0x19000 0x24 0x19002 - 0x19005 AIM
0x24000 0x23 0x24001 - 0x24002 USB Dongle Authenticator
0x25000 0x23 0x25001 - 0x25002 User Token Manager

SS Packet

Member variables

offset 0x8 - packet ID (8 bytes)

offset 0x10 - function ID (8 bytes)

offset 0x18 - return value (4 bytes)

offset 0x20 - subject ID (2 * 8 bytes)

Header

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
0x00000000 Success
0x00000005 Access Violation
0x00000006 No Entry ?
0x00000009 Invalid Parameter
0x0000000F Call Limit Exceeded ?

Body

0x2000 - Virtual TRM Manager

Packet ID Description
0x2001 Init
0x2002 Status
0x2003 Store
0x2004 Store
0x2005 Retrieve
0x2006 Free
0x200A Encrypt
0x200B Decrypt
0x200C Encrypt With Portability
0x200D Decrypt With Portability
0x200E Decrypt Master
0x2012 Backup Flash
0x2013 Restore Flash
0x2014 Backup SRK SRH
0x2015 Restore SRK SRH
0x2016 Flash Address Size
0x2017 Force Restart

0x200E - Decrypt Master

0x3000 - Secure RTC

Packet ID Description
0x3001 Set RTC
0x3002 Get Time
0x3003 Set Time

0x3001 - Set RTC

0x3002 - Get Time

0x3003 - Set Time

0x5000 - Storage Manager

Packet ID Description
0x5001 Set Encdec Key
0x5002 Set/Delete ATA (Encdec) Key
0x5003 Get Random Number
0x5004 Authenticate BD Drive
0x5005 Authenticate PS2 Disc
0x5006 Get Secure Firmware Version
0x5007 HW disc auth emu
0x5008 HW mc
0x5009 HW me auth header
0x500A HW me dec block

SB Isolation DMA Buffer Header

struct sb_iso_header
{
    u32 seqno;
    u32 mbmsg;
    u32 cmd;
    u32 cmd_size;
    u8 cmd_data[0];
}

0x5001 - Set Encdec Key

Per default, keys with index 0x0 - 0xB are not free. But we could patch it also.

0x5002 - Set/Delete ATA (Encdec) Key

Service Parameter Table

Service Parameter Description
0xC - 0xF Delete Encdec Key
0x10* Set ATA Key (index 1)
0x11* Delete ATA Key (index 1)

0x5003 - Get Random Number

0x5004 - Authenticate BD Drive

Service Parameter Table

Service Parameter Description
0x02 Used by SLL service 0x14004 during PS2EMU loading
0x1E Used by SLL service 0x14005 during PS2EMU unloading
0x29 Reset BD Drive
0x46 Authenticate BD Drive

0x5005 - PS2 Disc Authenticate

0x5006 - Get Version

0x5007 - Control BD Drive

Service Parameter Table

Service Parameter Description
0x41 -
0x46 -
0x51 -
0x52 -
0x53 -
0xA3 BD emu
0xA5 BD emu
0xA7 BD emu
0xAA BD emu

0x6000 - Update Manager

Packet ID Description
0x6001 Update Package Tophalf
0x6002 Inspect Package Tophalf
0x6003 Get Package Info
0x6004 Get Fix Instruction
0x6005 Extract Package Tophalf
0x6006 Get Extract Package
0x6009 Get Token Seed
0x600A Set Token
0x600B Read EPROM
0x600C Write EPROM
0x6010 Check Integrity
0x6011 Get Applicable Version

0x6001 - Update Package Tophalf

0x6002 - Inspect Package Tophalf

Inspect Package Tophalf Return Values

Error Code Description
0x00000000 Success
0x00000013 Same Version/Older Version
0x00000014 -

0x6003 - Get Package Info

Here are the versions of packages installed on my PS3:

Package Type Returned Version Description Package Name in PUP File
1 0x0003004100000000 Core OS Package CORE_OS_PACKAGE.pkg
2 0x0003004100000000 Revoke List Package for Program RL_FOR_PROGRAM.img
3 0x0002003000000000 Revoke List Package for Package RL_FOR_PACKAGE.img
4 0xDEADBEAFFACEBABE - -
5 0xDEADBEAFFACEBABE - -
6 0x0003004000000000 BD Firmware Package BDIT_FIRMWARE_PACKAGE.pkg, BDPT_FIRMWARE_PACKAGE_*.pkg
7 Invalid Parameter Bluetooth Firmware, dev_flash tarballs BLUETOOTH_FIRMWARE.pkg, dev_flash, dev_flash3
8 Invalid Parameter - -
9 Invalid Parameter SC Firmware Package SYS_CON_FIRMWARE_*.pkg

Decrypting and Extracting Packages with spu_pkg_rvk_verifier.self

RL_FOR_PROGRAM.img 3.41
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000200   00 00 00 04 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
00000210   00 00 00 06 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000220   00 00 00 03 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
00000230   00 00 00 00 00 00 00 02  FF FF FF FF FF FF FF FF   ........ÿÿÿÿÿÿÿÿ
00000240   00 00 00 04 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
00000250   10 70 00 05 FF 00 00 01  FF FF FF FF FF FF FF FF   .p..ÿ...ÿÿÿÿÿÿÿÿ
00000260   00 00 00 04 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
00000270   10 70 00 05 FE 00 00 01  FF FF FF FF FF FF FF FF   .p..þ...ÿÿÿÿÿÿÿÿ
00000280   00 00 00 04 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
00000290   10 70 00 05 FD 00 00 01  FF FF FF FF FF FF FF FF   .p..ý...ÿÿÿÿÿÿÿÿ
000002A0   00 00 00 04 00 00 00 01  00 03 00 41 00 00 00 00   ...........A....
000002B0   10 70 00 05 FC 00 00 01  FF FF FF FF FF FF FF FF   .p..ü...ÿÿÿÿÿÿÿÿ
000002C0   00 00 00 04 00 00 00 03  00 01 00 00 00 00 00 00   ................
000002D0   10 70 00 04 00 00 00 01  FF FF FF FF FF FF FF FF   .p......ÿÿÿÿÿÿÿÿ
RL_FOR_PROGRAM.img 3.50
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000200   00 00 00 04 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
00000210   00 00 00 06 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000220   00 00 00 03 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
00000230   00 00 00 00 00 00 00 02  FF FF FF FF FF FF FF FF   ........ÿÿÿÿÿÿÿÿ
00000240   00 00 00 04 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
00000250   10 70 00 05 FF 00 00 01  FF FF FF FF FF FF FF FF   .p..ÿ...ÿÿÿÿÿÿÿÿ
00000260   00 00 00 04 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
00000270   10 70 00 05 FE 00 00 01  FF FF FF FF FF FF FF FF   .p..þ...ÿÿÿÿÿÿÿÿ
00000280   00 00 00 04 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
00000290   10 70 00 05 FD 00 00 01  FF FF FF FF FF FF FF FF   .p..ý...ÿÿÿÿÿÿÿÿ
000002A0   00 00 00 04 00 00 00 01  00 03 00 50 00 00 00 00   ...........P....
000002B0   10 70 00 05 FC 00 00 01  FF FF FF FF FF FF FF FF   .p..ü...ÿÿÿÿÿÿÿÿ
000002C0   00 00 00 04 00 00 00 03  00 01 00 00 00 00 00 00   ................
000002D0   10 70 00 04 00 00 00 01  FF FF FF FF FF FF FF FF   .p......ÿÿÿÿÿÿÿÿ
RL_FOR_PACKAGE.img 3.41
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000200   00 00 00 03 00 00 00 02  00 01 00 00 00 00 00 00   ................
00000210   00 00 00 01 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000220   00 00 00 01 00 00 00 00  00 00 00 01 00 00 00 02   ................
00000230   00 00 00 08 00 05 00 00  00 00 00 00 00 00 00 00   ................
RL_FOR_PACKAGE.img 3.50
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000200   00 00 00 03 00 00 00 02  00 01 00 00 00 00 00 00   ................
00000210   00 00 00 01 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000220   00 00 00 01 00 00 00 00  00 00 00 01 00 00 00 02   ................
00000230   00 00 00 08 00 05 00 00  00 00 00 00 00 00 00 00   ................
CORE_OS_PACKAGE.pkg 3.15

Here is a piece of data from decrypted and decompressed package.

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   00 00 00 01 00 00 00 17  00 00 00 00 00 6F FF E0   .............oÿà
00000010   00 00 00 00 00 00 04 60  00 00 00 00 00 04 00 00   .......`........
00000020   63 72 65 73 65 72 76 65  64 5F 30 00 00 00 00 00   creserved_0.....
00000030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000040   00 00 00 00 00 04 04 60  00 00 00 00 00 00 00 08   .......`........
00000050   73 64 6B 5F 76 65 72 73  69 6F 6E 00 00 00 00 00   sdk_version.....
00000060   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000070   00 00 00 00 00 04 04 80  00 00 00 00 00 01 E5 CC   .......€......åÌ
00000080   6C 76 31 6C 64 72 00 00  00 00 00 00 00 00 00 00   lv1ldr..........
00000090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000A0   00 00 00 00 00 05 EA 80  00 00 00 00 00 01 6D A0   ......ê€......m 
000000B0   6C 76 32 6C 64 72 00 00  00 00 00 00 00 00 00 00   lv2ldr..........
000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000D0   00 00 00 00 00 07 58 80  00 00 00 00 00 01 2E 44   ......X€.......D
000000E0   69 73 6F 6C 64 72 00 00  00 00 00 00 00 00 00 00   isoldr..........
000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000100   00 00 00 00 00 08 87 00  00 00 00 00 00 01 DA E4   ......‡.......Úä
00000110   61 70 70 6C 64 72 00 00  00 00 00 00 00 00 00 00   appldr..........
00000120   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000130   00 00 00 00 00 0A 61 E4  00 00 00 00 00 00 FA CC   ......aä......úÌ
00000140   73 70 75 5F 70 6B 67 5F  72 76 6B 5F 76 65 72 69   spu_pkg_rvk_veri
00000150   66 69 65 72 2E 73 65 6C  66 00 00 00 00 00 00 00   fier.self.......
00000160   00 00 00 00 00 0B 5C B0  00 00 00 00 00 00 5C 94   ......\°......\”
00000170   73 70 75 5F 74 6F 6B 65  6E 5F 70 72 6F 63 65 73   spu_token_proces
00000180   73 6F 72 2E 73 65 6C 66  00 00 00 00 00 00 00 00   sor.self........
00000190   00 00 00 00 00 0B B9 44  00 00 00 00 00 00 65 D0   ......¹D......eÐ
000001A0   73 70 75 5F 75 74 6F 6B  65 6E 5F 70 72 6F 63 65   spu_utoken_proce
000001B0   73 73 6F 72 2E 73 65 6C  66 00 00 00 00 00 00 00   ssor.self.......
000001C0   00 00 00 00 00 0C 1F 14  00 00 00 00 00 01 53 2C   ..............S,
000001D0   73 63 5F 69 73 6F 2E 73  65 6C 66 00 00 00 00 00   sc_iso.self.....
000001E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000001F0   00 00 00 00 00 0D 72 40  00 00 00 00 00 00 44 98   ......r@......D˜
00000200   61 69 6D 5F 73 70 75 5F  6D 6F 64 75 6C 65 2E 73   aim_spu_module.s
00000210   65 6C 66 00 00 00 00 00  00 00 00 00 00 00 00 00   elf.............
00000220   00 00 00 00 00 0D B6 D8  00 00 00 00 00 00 D7 F0   ......¶Ø......×ð
00000230   73 70 70 5F 76 65 72 69  66 69 65 72 2E 73 65 6C   spp_verifier.sel
00000240   66 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   f...............
00000250   00 00 00 00 00 0E 8E C8  00 00 00 00 00 00 80 8C   ......ŽÈ......€Œ
00000260   6D 63 5F 69 73 6F 5F 73  70 75 5F 6D 6F 64 75 6C   mc_iso_spu_modul
00000270   65 2E 73 65 6C 66 00 00  00 00 00 00 00 00 00 00   e.self..........
00000280   00 00 00 00 00 0F 0F 54  00 00 00 00 00 00 88 B8   .......T......ˆ¸
00000290   6D 65 5F 69 73 6F 5F 73  70 75 5F 6D 6F 64 75 6C   me_iso_spu_modul
000002A0   65 2E 73 65 6C 66 00 00  00 00 00 00 00 00 00 00   e.self..........
000002B0   00 00 00 00 00 0F 98 0C  00 00 00 00 00 00 C0 78   ......˜.......Àx
000002C0   73 76 5F 69 73 6F 5F 73  70 75 5F 6D 6F 64 75 6C   sv_iso_spu_modul
000002D0   65 2E 73 65 6C 66 00 00  00 00 00 00 00 00 00 00   e.self..........
000002E0   00 00 00 00 00 10 58 84  00 00 00 00 00 00 5D B0   ......X„......]°
000002F0   73 62 5F 69 73 6F 5F 73  70 75 5F 6D 6F 64 75 6C   sb_iso_spu_modul
00000300   65 2E 73 65 6C 66 00 00  00 00 00 00 00 00 00 00   e.self..........
00000310   00 00 00 00 00 10 B6 34  00 00 00 00 00 00 22 A0   ......¶4......" 
00000320   64 65 66 61 75 6C 74 2E  73 70 70 00 00 00 00 00   default.spp.....
00000330   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000340   00 00 00 00 00 10 D9 00  00 00 00 00 00 12 B1 70   ......Ù.......±p
00000350   6C 76 31 2E 73 65 6C 66  00 00 00 00 00 00 00 00   lv1.self........
00000360   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000370   00 00 00 00 00 23 8A 80  00 00 00 00 00 03 E8 28   .....#Š€......è(
00000380   6C 76 30 00 00 00 00 00  00 00 00 00 00 00 00 00   lv0.............
00000390   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000003A0   00 00 00 00 00 27 72 A8  00 00 00 00 00 16 EE B8   .....'r¨......î¸
000003B0   6C 76 32 5F 6B 65 72 6E  65 6C 2E 73 65 6C 66 00   lv2_kernel.self.
000003C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000003D0   00 00 00 00 00 3E 61 60  00 00 00 00 00 07 0F 94   .....>a`.......”
000003E0   65 75 72 75 73 5F 66 77  2E 62 69 6E 00 00 00 00   eurus_fw.bin....
000003F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000400   00 00 00 00 00 45 70 F4  00 00 00 00 00 07 FC 48   .....Epô......üH
00000410   65 6D 65 72 5F 69 6E 69  74 2E 73 65 6C 66 00 00   emer_init.self..
00000420   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000430   00 00 00 00 00 4D 6D 3C  00 00 00 00 00 06 16 00   .....Mm<........
00000440   68 64 64 5F 63 6F 70 79  2E 73 65 6C 66 00 00 00   hdd_copy.self...
00000450   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................

00040460   33 31 35 2E 30 30 30 0A  00 00 00 00 00 00 00 00   315.000.........
00040470   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
BDIT_FIRMWARE_PACKAGE.pkg 3.50

Here is a piece of data from decrypted package.

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000300   43 6F 70 79 72 69 67 68  74 28 43 29 20 32 30 30   Copyright(C) 200
00000310   35 2D 32 30 30 36 2C 20  53 6F 6E 79 20 43 6F 6D   5-2006, Sony Com
00000320   70 75 74 65 72 20 45 6E  74 65 72 74 61 69 6E 6D   puter Entertainm
00000330   65 6E 74 20 49 6E 63 2E  1A 00 00 00 00 00 00 00   ent Inc.........
00000340   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000350   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000360   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000370   41 96 18 D3 2D 8F 0F 68  11 4D A7 09 E4 1F A7 6F   A–.Ó-.h.M§.ä.§o
00000380   EF 29 48 A0 E9 F2 A8 F0  CC 4B F3 4D E0 4A B0 17   ï)H éò¨ðÌKóMàJ°.
00000390   C2 DA 07 5F 96 B3 C8 8D  E1 06 2E 3A 1D A7 FD 20   ÂÚ._–³Èá..:.§ý 
BDPT_FIRMWARE_PACKAGE_301R.pkg 3.50

Here is a piece of data from decrypted package.

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000300   43 6F 70 79 72 69 67 68  74 28 43 29 20 32 30 30   Copyright(C) 200
00000310   35 2D 32 30 30 39 2C 20  53 6F 6E 79 20 43 6F 6D   5-2009, Sony Com
00000320   70 75 74 65 72 20 45 6E  74 65 72 74 61 69 6E 6D   puter Entertainm
00000330   65 6E 74 20 49 6E 63 2E  1A 00 00 00 00 00 00 00   ent Inc.........
00000340   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000350   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000360   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000370   80 18 D2 E4 22 AA 2B D7  85 47 F4 40 53 9A 04 0C   €.Òä"ª+×…Gô@Sš..
00000380   D0 B8 A5 04 20 51 9E 90  09 4F 2E 78 BA 32 C0 EA   и¥. Qž.O.xº2Àê
00000390   E9 61 96 ED D8 2A 70 C0  59 68 4E B2 47 25 9C 97   éa–íØ*pÀYhN²G%œ—
BLUETOOTH_FIRMWARE.pkg 3.41
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   52 43 32 39 5F 66 69 72  6D 77 61 72 65 5F 66 6F   RC29_firmware_fo
00000010   6F 74 65 72 2E 64 66 75  00 00 00 00 00 00 00 00   oter.dfu........
00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000060   00 00 00 00 30 30 30 30  36 34 34 00 30 30 30 30   ....0000644.0000
00000070   30 30 30 00 30 30 30 30  30 30 30 00 30 30 30 30   000.0000000.0000
00000080   31 35 36 36 33 30 30 00  31 31 30 36 34 33 34 36   1566300.11064346
00000090   33 30 36 00 30 31 35 34  36 33 00 20 30 00 00 00   306.015463. 0...
000000A0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000B0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
000000F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000100   00 75 73 74 61 72 20 20  00 72 6F 6F 74 00 00 00   .ustar  .root...
00000110   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000120   00 00 00 00 00 00 00 00  00 72 6F 6F 74 00 00 00   .........root...
00000130   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
00000140   00 00 00 00 00 00 00 00  00 30 30 30 30 30 30 30   .........0000000
00000150   00 30 30 30 30 30 30 30  00 00 00 00 00 00 00 00   .0000000........


000A5950   84 1B 00 C0 94 04 00 00  74 06 00 00 45 75 72 75   „..À”...t...Euru
000A5960   73 5F 50 72 69 6D 61 72  79 5F 50 68 79 00 00 00   s_Primary_Phy...
000A5970   4D 61 72 76 65 6C 6C 5F  41 50 00 00 94 BB 01 C0   Marvell_AP..”».À


000B7CC0   00 00 00 00 01 10 60 23  4D 61 72 76 65 6C 6C 20   ......`#Marvell 
000B7CD0   46 69 72 6D 77 61 72 65  20 53 44 4B 20 56 65 72   Firmware SDK Ver
000B7CE0   73 69 6F 6E 20 32 2E 33  2E 30 54 74 5D 04 02 2B   sion 2.3.0Tt]..+
000B7CF0   0F 14 E1 36 04 32 0A 1A  FD 08 32 1A 1A C1 08 02   ..á6.2..ý.2..Á..


000F42B0   44 6F 53 68 61 72 65 64  4B 65 79 53 65 71 31 3A   DoSharedKeySeq1:
000F42C0   20 45 6E 74 65 72 65 64  20 2D 2D 2D 20 72 73 70    Entered --- rsp
000F42D0   4D 61 63 20 3D 20 25 30  32 78 3A 25 30 32 78 3A   Mac = %02x:%02x:
000F42E0   25 30 32 78 3A 25 30 32  78 3A 25 30 32 78 3A 25   %02x:%02x:%02x:%
000F42F0   30 32 78 0A 00 00 00 00  6D 6C 6D 65 41 75 74 68   02x.....mlmeAuth
000F4300   44 6F 53 68 61 72 65 64  4B 65 79 53 65 71 31 3A   DoSharedKeySeq1:
000F4310   20 56 61 6C 69 64 61 74  69 6F 6E 20 66 61 69 6C    Validation fail
000F4320   65 64 20 2D 2D 2D 20 72  73 70 4D 61 63 20 3D 20   ed --- rspMac = 
000F4330   25 30 32 78 3A 25 30 32  78 3A 25 30 32 78 0A 00   %02x:%02x:%02x..
000F4340   6D 6C 6D 65 41 75 74 68  44 6F 53 68 61 72 65 64   mlmeAuthDoShared
000F4350   4B 65 79 53 65 71 33 3A  20 76 61 6C 69 64 61 74   KeySeq3: validat
000F4360   69 6F 6E 20 66 61 69 6C  65 64 21 20 2D 2D 2D 20   ion failed! --- 
000F4370   72 73 70 4D 61 63 20 3D  20 25 30 32 78 3A 25 30   rspMac = %02x:%0
000F4380   32 78 3A 25 30 32 78 0A  00 65 65 70 72 6F 6D 00   2x:%02x..eeprom.
000F4390   62 74 5F 68 63 69 00 62  74 5F 75 61 72 74 00 75   bt_hci.bt_uart.u
000F43A0   73 62 30 00 75 73 62 31  00 4F 53 41 00 77 6C 61   sb0.usb1.OSA.wla
000F43B0   F3 B8 E9 70 01 00 00 00  1C 6B 03 00 00 02 00 00   ó¸ép.....k......
SYS_CON_FIRMWARE_01050101.pkg 3.41
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000300   1B 2D 70 0F AB 5E B3 99  68 20 FE 3D E1 80 6A 1D   .-p.«^³™h þ=á€j.
00000310   B8 FD 37 CF CD 45 85 AB  51 F7 05 E3 EA 32 A5 EA   ¸ý7ÏÍE…«Q÷.ãê2¥ê
00000320   67 45 F9 48 00 00 00 00  00 10 00 00 C0 0F 00 00   gEùH........À...
00000330   8B 04 07 F9 9B A2 90 3A  75 89 F1 42 12 59 DA 0D   ‹..ù›¢:u‰ñB.YÚ.
00000340   21 7C A2 C3 5A E4 78 00  10 8D 4B F7 A2 73 9C 63   !|¢ÃZäx..K÷¢sœc
00000350   5D 8D 5D 49 16 C7 6F 2C  AD 33 FE 1F D3 6C A1 CA   ]]I.Ço,­3þ.Ól¡Ê
00000360   BA AD 2B FE 8F 33 71 D7  C5 E6 5C FF BF 77 6C 80   º­+þ3q×Åæ\ÿ¿wl€
00000370   F2 BE 11 BB 3C 52 52 DC  A9 68 E5 24 AD 4F F3 48   ò¾.»<RRÜ©hå$­OóH

0x6005 - Extract Package Tophalf

0x600B - Read EEPROM

EEPROM Offset Table

Here is the table of EEPROM offsets that can be accessed through Update Manager (3.15):

Offset Size Description
0x48C06 1 FSELF Control Flag
0x48C07 1 Product Mode (UM allows to read this offset, it can be also written but only when already in product mode)
0x48C0A 1 QA Flag
0x48C13 1 Device Type
0x48C30 1 SPE number Usally 0x06, can be set to 0x07 to enable the 8 SPE
0x48C42 1 HDD Copy Mode
0x48C50 0x10 Debug Support Flag
0x48C60 1 Update Status
0x48C61 1 Recover Mode Flag
0x48D3E 0x50 QA Token (UM doesn't allow access to this offset but SC Manager can read/write it)

0x600C - Write EEPROM

0x6010 - Check Integrity

0x6011 - Get Applicable Version

Here is the return value:

00 00 00 01 00 00 00 00 00 03 00 20 00 00 00 00 00 00 00 00 00 00 00 01
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01

BD Firmware Update

Detecting BD Drive Type, Generation and Revision

BD Drive Type Table

Here is the BD Drive Type Table extracted from HV Process 6 (3.15):

Index Vendor Identification String Drive Type
0
"SONY    EmerFlashROM"
0x2100000000000001
1
"SONY    PS-EMBOOT   300R"
0x2100000000000001
2
"SONY    BDRW AQUAM(BDIT)"
0x1100000000000001
3
"SONY    PS-SYSTEM   300R"
0x1100000000000001
4
"SONY    PS-SYSTEM   V300"
0x1100000000000001
5
"SCEI    EMER-FLASH-8"
0x2200000000000002
6
"SONY    PS-EMBOOT   301R"
0x2200000000000002
7
"SONY    PS-SYSTEM   301R"
0x1200000000000002
8
"SONY    PS-EMBOOT   302R"
0x2200000000000003
9
"SONY    PS-SYSTEM   302R"
0x1200000000000003
10
"SONY    PS-EMBOOT   303R"
0x2200000000000004
11
"SONY    PS-SYSTEM   303R"
0x1200000000000004
12
"SONY    PS-EMBOOT   304R"
0x2200000000000005
13
"SONY    PS-SYSTEM   304R"
0x1200000000000005
14
"SONY    PS-EMBOOT   306R"
0x2200000000000007
15
"SONY    PS-SYSTEM   306R"
0x1200000000000007

Methods (HV Process 6)

update_manager_update_bd_firmware - 0x800064BC (3.15)

bd_updater_prepare_drive - 0x80011A88 (3.15)

bd_updater_send_firmware - 0x80011544 (3.15)

bd_updater_disable_reqsense - 0x80010410 (3.15)

bd_updater_enable_reqsense - 0x800104D8 (3.15)

send_atp_command - 0x80023B10 (3.15)

0x9000 - SC Manager

Packet ID Description
0x9001 Get SRH
0x9002 Set SRH
0x9003 Encrypt
0x9004 Decrypt
0x9005 Init For VTRM
0x9006 Get Region Data
0x9007 Set Region Data
0x9008 Set RTC
0x9009 Get Time
0x900A Set Time
0x900B Read EPROM
0x900C Write EPROM
0x900D Init For Updater
0x900E Get SC Status
0x9011 SC Binary Patch
0x9012 SC RTC Factory
0x9013 Correct RTC Factory
0x9014 Set SC Status
0x9015 Backup Root Info
0x9016 Restore Root Info

0x9001 - SC Get SRH

struct ss_sc_mgr_get_srh
{
    u8 field0[20];
    u8 res1[4];
    u8 field18[20];
    u8 res2[4];
};

0x9003 - SC Encrypt

struct ss_sc_mgr_encrypt
{
    u32 type;               /* 1 - 5 */
    u8 res[4];
    u8 field8[16];
    u8 field18[16];
    u64 field28;
};

0x9004 - SC Decrypt

0x9006 - SC Get Region Data

struct ss_sc_mgr_get_region_data
{
    u64 id;
    u64 data_size;    /* max 0x30 bytes */
    u8 data[0];
};

Update Package Type - ID Mapping Table

Update Package Type ID
1 0
2 2
3 4
4 6
5 7
6 8

0x9007 - SC Set Region Data

struct ss_sc_mgr_set_region_data
{
    u64 id;
    u64 data_size;    /* max 0x30 bytes */
    u8 data[0];
};

0x900B - SC Read EPROM

struct ss_sc_mgr_read_eprom
{
    u32 offset;
    u8 res1[4];
    u32 nread;               /* max 0x100 bytes */
    u8 res2[4];
    u64 buf_size;
    u8 buf[0];
    /* here follows buf */
};

EPROM Offset - Block ID and Block Offset Mapping Table (NVS Service)

EPROM Offset Block ID Block Offset
0x48000 - 0x480FF 0x00 0x48000 - 0x480FF
0x48800 - 0x488FF 0x01 0x48800 - 0x488FF
0x48C00 - 0x48CFF 0x02 0x48C00 - 0x48CFF
0x48D00 - 0x48DFF 0x03 0x48D00 - 0x48DFF
0x2F00 - 0x2FFF 0x10 0x2F00 - 0x2FFF
0x3000 - 0x30FF 0x20 0x3000 - 0x30FF
All other offsets Invalid Invalid

0x900C - SC Write EPROM

struct ss_sc_mgr_write_eprom
{
    u32 offset;
    u8 res1[4];
    u32 nwrite;
    u8 res2[4];
    u64 buf_size;
    u8 buf[0];
    /* here follows buf */
};

0x900E - SC Get Status

Here is what the service returned on my fat PS3:

0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0xC0 0x00 0x00 0xFF 0x00 0x00 0x00 0x00

So, version is 0x00000003 and mode is 0xC00000FF.

struct ss_sc_mgr_get_sc_status
{
    u32 version;
    u8 res1[4];
    u32 mode;
    u8 res2[4];
};

0x9011 - SC Binary Patch

SC Isolation DMA Buffer Header

struct sc_iso_header
{
    u32 seqno;
    u32 mbmsg;
    u32 cmd;
    u32 cmd_size;
    u8 cmd_data[0];
};

0x11000 - SPM (Security Policy Manager)

Packet ID Description
0x11001 Request
0x11002 Load Additional Policy

0x14000 - SLL (Secure LPAR Loader)

Packet ID Description
0x14004 Load GOS
0x14005 Unload GOS

0x15000 - SPL (Secure Profile Loader)

Packet ID Description
0x15001 Get LPAR Parameter Size/Get LPAR Parameter
0x15003 Get Contents Size/Get Contents
0x15009 Get Component

SPP File

Here are the contents of DEFAULT.SPP from 3.41.

Here are the contents of DEFAULT.SPP 1.18 Debug from 1.18 Debug Firmware.

SPP Header

offset 0x2 - header format version (2 bytes)

offset 0x4 - header size (4 bytes)

offset 0x18 - number of segments (4 bytes)

Segments

Here is the list of profile segments from 3.41:

Name auth id/authority id
*SCE_CELLOS_PME 0x1070000001000001
*PS3_LPAR 0x1070000002000001
*PS2_LPAR 0x1020000003000001
*PS2_GX_LPAR 0x1020000003000001
*PS2_SW_LPAR 0x1020000003000001
*LINUX_LPAR 0x1080000004000001
*SCE_CELLOS_SYSTEM_MGR 0x107000001D000001
*SCE_CELLOS_SYSTEM_MGR_LINUX 0x107000001D000001
*SCE_CELLOS_SYSTEM_MGR_PS2 0x107000001D000001
*SCE_CELLOS_SYSTEM_MGR_PS2_SW 0x107000001D000001
*SCE_CELLOS_SYSTEM_MGR_PS2_GX 0x107000001D000001
*SCE_CELLOS_SS_SECURE_RTC 0x1070000033000001
*SCE_CELLOS_SS_INDI_INFO_EID
*SCE_CELLOS_SS_INIT_LV1_ACL 0x1070000017000001

0x15003 - Get Contents Size/Get Contents

0x17000 - Indi Info Manager

Packet ID Description
0x17001 Read EID Data Size By Index/Read metldr Size
0x17002 Read EID Data By Index/Read metldr
0x17004 Read System Data
0x17007 Read System Data From EEPROM
0x17013 Read eEID Size
0x17014 Write eEID/Write metldr
0x17015 Read cISD Size
0x17016 Read cISD
0x17017 Write cISD

0x17001 - Read EID Data Size By Index

Index Size Of Data Description
0 0x860 Used e.g. by Update Manager to decrypt update packages
4 0x30 Used e.g. by Storage Manager
0x1000 0xe960 metldr

0x17002 - Read EID Data By Index

0x17004 - Read System Data

0x17007 - Read System Data From EEPROM

Here is the list of possible EEPROM offsets from HV 3.15:

Index SC EEPROM Offset Size Of Data
0 0x48D20 6
1 0x48D28 6
2 0x48D30 6
3 0x48D38 6
4 0x48D00 4
5 0x48D04 4
6 0x48D08 4

0x17014 - Write eEID/Write metldr

0x17015 - Read cISD Size

0x17016 - Read cISD

0x17017 - Write cISD

0x18000 - DM (Dispatcher Manager)

Packet ID Description
0x18001 Construct Service Port
0x18002 Destruct Service Port

Dispatcher Manager Messages

Dispatcher Manager Header

struct dispmgr_header
{
    uint32_t request_id;
    uint32_t function_id;
    uint32_t request_size;         /* payload size of request */
    uint32_t response_size;        /* payload size of response */
}

Packet ID - SS ID Mapping

Here is the mapping table i extracted from HV Process 3 where SPM and DM run:

Packet ID SS ID
0x2001 0x34
0x2002 0x35
0x2003 0x36
0x2004 0x37
0x2005 0x38
0x2006 0x39
0x200A 0x3D
0x200B 0x3E
0x200C 0x3F
0x200D 0x40
0x200E 0x41
0x2012 0x7B
0x2013 0x7C
0x2014 0x7E
0x2015 0x7F
0x2016 0x7D
0x2017 0x80

0x19000 - AIM

Packet ID Description
0x19002 Get Device Type
0x19003 Get Device ID
0x19004 Get PS Code
0x19005 Get Open PS ID

0x19002 - Get Device Type

On my fat PS3 with HV 3.41 it returns:

0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x85
struct ss_aim_get_device_type
{
    u8 field0[16];
};

0x19003 - Get Device ID

struct ss_aim_get_device_id
{
    u8 field0[16];
};

0x19004 - Get PS Code

struct ss_aim_get_ps_code
{
    u8 field0[8];
};

0x19005 - Get Open PS ID

struct ss_aim_get_open_ps_id
{
    u8 field0[16];
};

0x24000 - USB Dongle Authenticator

Packet ID Description
0x24001 Generate Challenge
0x24002 Verify Response

0x24001 - Generate Challenge

Here are hexdumps of some challenge bodies i let 0x24001 service generate:

2E 02 01 72 3A 0A 76 BB 81 CB 29 BC E7 B5 D6 62 7C 0E EE 23 18 A9 1D
2E 02 01 F0 DA 78 D4 1D CB D7 C9 C7 F0 32 F4 2E 92 39 BD 3F 32 93 AA
2E 02 01 3B B2 9D FD A8 83 AF 9A C0 E9 13 BB AE D5 6C 8C 45 2E DE 13

0x24002 - Verify Response

USB Dongle Master Key

Here is the encrypted USB Dongle Master Key from HV 3.15:

0x22 0xD5 0xD1 0x8C 0xFF 0xE2 0x4F 0xAC 0xEC 0x72 0xA2 0x42 0xA7 0x18 0x98 0x10
0x25 0x33 0xE0 0x96 0xF2 0xC1 0x91 0x0D 0x15 0x23 0xD3 0x07 0x74 0xE7 0x2B 0x72
0xDF 0xA6 0xDD 0xE9 0x68 0x8B 0x76 0x2A 0x6A 0x87 0x51 0x7F 0x85 0x39 0x0B 0xD4
0x20 0x3F 0x46 0x89 0x04 0x82 0xB7 0x30 0x84 0x89 0x4B 0xCC 0x9D 0xB1 0x24 0x7C

This is the decrypted dongle master key:

0x46 0xDC 0xEA 0xD3 0x17 0xFE 0x45 0xD8 0x09 0x23
0xEB 0x97 0xE4 0x95 0x64 0x10 0xD4 0xCD 0xB2 0xC2

This is the decrypted dongle key for dongle ID 0xAAAA which works up to 3.55:

0x04 0x4E 0x61 0x1B 0xA6 0xA6 0xE3 0x9A 0x98 0xCF
0x35 0x81 0x2C 0x80 0x68 0xC7 0xFC 0x5F 0x7A 0xE8

Here is the USB Dongle Master Dummy Key from HV 3.15:

0xD1 0xFC 0x57 0x55 0xBF 0x20 0xFA 0xB2 0xD4 0xA5 0x4A 0x0A 0x0C 0x5D 0x52 0x8E
0xDF 0x66 0xCD 0x74

USB Dongle ID Revoke List

The following USB Dongle IDs are revoked in HV 3.15:

0, 2, 13, 32, 34, 176, 241

0x25000 - User Token Manager

Packet ID Description
0x25001 Encrypt User Token
0x25002 Decrypt User Token

User Token

User Token Format

stuct user_token_attr
{
    uint32_t type;                                 /* 0x00000001, value != 0x00000001 means attribute list ends here */
    uint32_t size;                                 /* 8 + sizeof(data) */
    /* data follows here, size of data may be 0 */
}

struct user_token
{
    uint32_t magic;                                /* 0x73757400 = "sut\0" */
    uint32_t format_version;                       /* 0x00000001 */
    uint64_t size;
    uint8_t idps[16];
    uint64_t expire_date;
    uint64_t capability;
    union
    {
        stuct user_token_attr attrs[0];
        uint8_t dummy[3072];
    } attrs;
    /* 0xC30 */
    uint8_t digest[20];
}

LPAR Memory Management

Memory Region class

This class is the base class for different memory region types.

vtable

0x003578B0 (3.15)

Member variables

offset 0x40 - pointer to LPAR object that owns this memory region

offset 0x48 - type of memory region (8 bytes)

offset 0x50 - LPAR start address of memory region

offset 0x58 - size of memory region (8 bytes)

offset 0x60 - flags (8 bytes)

offset 0xA0 - log2 of page size

Generating New LPAR Memory Region Addresses

generate_new_lpar_mem_region_address(?, memory region size, log2(page size), ?, ?) - 002C82E8 (3.15)

generate_new_lpar_mem_region_address - 002C6570 (3.41)

Encoding LPAR Memory Region Start Addresses and Sizes

LPAR Memory Region Start Address >> 42 = log2(LPAR Memory Region Size)
LPAR Memory Region Start Address = (log2(LPAR Memory Region Size) << 42) |
   (counter << log2(LPAR Memory Region Size))
LPAR Memory Region Address Counter

Physical Memory Region class

This type of memory region is created e.g. in lv1_allocate_memory HV call or in syscall 0x10000.

vtable

0x00357D08 (3.15)

Member variables

offset 0xB0 - pointer to object that stores a list of addresses of physical pages owned by this memory region

offset 0xB8 - pointer to LPAR object that owns this memory region

offset 0xC0 - reference counter (8 bytes)

Objects

Here is the list of physical memory region objects i found in HV 3.15.

Address in HV dump LPAR id LPAR Start Address Size Flags log2(Page Size) Physical Page Addresses
0x006B5510 1 0x300000001000 0x1000 0x0 0xC 0x672000
0x006B5E50 1 0x440000040000 0x20000 0x0 0x11 0x6C0000
0x006B6980 1 0x440000060000 0x20000 0x0 0x11 0x6E0000
0x006B7F00 1 0x400000040000 0x10000 0x0 0x10 0x100000
0x003A80F0 2 0x6C0058000000 0x7000000 0x4 0x18 0x1000000 - 0x7000000
0x003BE800 2 0x300000047000 0x1000 0x0 0xC 0x1FA000
0x006BDAA0 2 0x0 0x8000000 0x8 0x1B (single huge page) 0x8000000

So, Linux kernel should be located at physical address 0x8000000 and Linux syscall handler at 0x8000C00. Too bad that the HV dump is not large enough.

GameOS Physical Memory Regions

Here is the list of physical memory regions of GameOS i found in HV 3.41:

Start Address Size Access Right Max Page Size Flags Real Addresses
0x0 0x1000000 0x3 0x18 0x8 0x1000000 - 0x1FFF000
0x500000300000 0xA0000 0x3 0x10 0x8 0x380000 - 0x38F000, 0x3B0000 - 0x3BF000, 0x1E0000 - 0x1FF000, 0x3C0000 - 0x3FF000, 0xFF00000 - 0xFF1F000
0x700020000000 0xE900000 (huge memory region) 0x3 0x14 0x0 0x400000 - 0x5FF000, 0x800000 - 0xFFF000, 0x2000000 - 0xFEFF000

HTAB Memory Region class

This memory region is created when a HTAB is mapped into LPAR's address space. It's created in lv1_map_htab HV call.

vtable

0x00357C98 (3.15)

Member variables

offset 0xB0 - pointer to VAS object that owns the HTAB

Objects

Here is the list of HTAB memory region objects i found in HV 3.15.

Address in HV dump LPAR id VAS id LPAR Start Address Size Flags log2(Page Size)
0x001FE0F0 2 3 0x500000C00000 0x100000 0xC000000000000000 0x14
0x003BD850 2 3 0x500004300000 0x100000 0xC000000000000000 0x14
0x003BDEA0 2 3 0x500004500000 0x100000 0xC000000000000000 0x14

GameOS HTAB

GameOS SLB

Here is the dump of SLB entries from GameOS 3.41:

0x8000000008000000  0x0000000000000500
0x8000000208000000  0x0000000000020500
0x8000000300000000  0x0000000000030510
0x0000000000000000  0x0000000000000000
0x0000000080000000  0x0000000000038C00
0x00000000A0000000  0x000000000003AC00
0x00000000C0000000  0x000000000003CC00
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x0000000000000000  0x0000000000000000
0x8000000010057960  0x8000000000313E78
0x8000000010057940  0x0000000000000000
0x800000000001B698  0x0000000000000000
0x8000000010057930  0x8000000000490708
0x80000000002B6C68  0x80000000003DE928
0x8000000010057EC0  0x80000000003DE920
0x0000000000000000  0x8000000000309810
0x80000000004B3000  0x0000000000000000
0x8000000010057CC0  0x0000000000000000
0x80000000004AF000  0x80000000004E1F00
0x80000000100579C8  0x80000000100579C0
0x80000000100579E0  0x2400002200000000
0x80000000004CF5B0  0x8000000200012000
0x80000000100579F8  0x80000000100579F0
0x8000000010057A10  0x80000000004A3A00
0x80000000004CF5B0  0x80000000004C8D00
0x800000000001BF6C  0x80000000004CD400
0x800000000001B698  0x80000000004C8100
0x80000000100579D0  0x80000000004B48C0
0x0000000000001C08  0x0000000000000000
0x8000000010057A78  0x8000000010057A70
0x8000000010057A90  0x0000000000000000
0x80000000004CF90C  0x0000000000000000
0x0000000000000000  0x8000000010057A80
0x8000000010057A90  0x8000000000309810
0x80000000004CF62C  0x0000000000000000
0x8000000010057CC0  0x0000000000000000
0x80000000004AF000  0x80000000004B48C0
0x00004000001C0000  0x0000000000000001
0x00000000D0000000  0x0000A8E3EE7D10DA
0x0000000000000000  0x0000000000000000
0x80000000004D8088  0x80000000004D9000

SPE MMIO Memory Region class

This type of memory region represents MMIO memory region of a SPE. It's created e.g. in lv1_construct_logical_spe or in syscall 0x10040.

vtable

0x003583F8 (3.15)

Member variables

Objects

Here is the list of SPE memory region objects i found in HV 3.15.

Address in HV dump LPAR id SPE LPAR Start Address Size Physical Address Flags log2(Page Size)
0x003ABC20 2 1 0x4C0000880000 0x80000 0x20000080000 0xA000000000000000 0xC
0x003AAD70 2 2 0x4C0000980000 0x80000 0x20000100000 0xA000000000000000 0xC
0x003A8880 2 3 0x4C0000780000 0x80000 0x20000180000 0xA000000000000000 0xC
0x003B4F70 2 4 0x4C0000A80000 0x80000 0x20000200000 0xA000000000000000 0xC
0x003AB700 2 5 0x4C0000680000 0x80000 0x20000280000 0xA000000000000000 0xC
0x003B5BE0 2 6 0x4C0000B80000 0x80000 0x20000300000 0xA000000000000000 0xC

SPE Shadow Registers Memory Region class

This type of memory region represents shadow registers memory region of a SPE. It's created e.g. in lv1_construct_logical_spe or in syscall 0x10040.

vtable

0x00358448 (3.15)

Objects

Here is the list of SPE Shadow Registers memory region objects i found in HV 3.15.

Address in HV dump LPAR id SPE LPAR Start Address Size Physical Address Flags log2(Page Size)
0x003ABDA0 2 1 0x300000012000 0x1000 - 0xA000000000000000 0xC
0x003B4290 2 2 0x300000014000 0x1000 - 0xA000000000000000 0xC
0x003A8A00 2 3 0x300000010000 0x1000 - 0xA000000000000000 0xC
0x003B50F0 2 4 0x300000016000 0x1000 - 0xA000000000000000 0xC
0x001FFC90 2 5 0x30000000E000 0x1000 - 0xA000000000000000 0xC
0x003AE5B0 2 6 0x300000018000 0x1000 - 0xA000000000000000 0xC

Device MMIO Memory Region class

This type of memory region is created when a device MMIO region is mapped into LPAR address space, e.g. in lv1_map_device_mmio_region.

vtable

0x00352468 (3.15)

Member variables

offset 0xA8 - physical address where the device MMIO region is mapped to

Objects

Here is the list of Device MMIO memory region objects i found in HV 3.15.

Address in HV dump LPAR id LPAR Start Address Size Flags log2(Page Size) Physical Address Device
0x001FDF00 2 0x4000001D0000 0x10000 0x8000000000000000 0xC 0x24003010000 USB controller
0x003B3850 2 0x400000200000 0x10000 0x8000000000000000 0xC 0x24003020000 USB controller
0x003B6E50 2 0x4000001E0000 0x10000 0x8000000000000000 0xC 0x24003810000 USB controller
0x003B9950 2 0x4000001F0000 0x10000 0x8000000000000000 0xC 0x24003820000 USB controller

GPU Device Memory Region class

This type of memory region is created e.g. in lv1_gpu_open, lv1_gpu_device_map and lv1_undocumented_function_114.

vtable

0x00357C48 (3.15)

Member variables

offset 0xA8 - physical address

Objects

Here is the list of Device GPU memory region objects i found in HV 3.15.

Address in HV dump LPAR id LPAR Start Address Size Flags log2(Page Size) Physical Address
0x003AF380 2 0x700190000000 0xFE00000 0x8000000000000000 0x14 0x28080000000
0x003AF500 2 0x4000001A0000 0xC000 0x8000000000000000 0xC 0x3C0000
0x003AF680 2 0x4800006C0000 0x40000 0x8000000000000000 0xC 0x2808FE00000
0x003AFC30 2 0x440000380000 0x20000 0x8000000000000000 0xC 0x28000C00000
0x003BB420 2 0x3C0000108000 0x8000 0x8000000000000000 0xC 0x28000080100

Direct Map Memory Region class

This type of memory region is created in HV call lv1_undocumented_function_114. lv1_undocumented_function_114 allows you to map any memory address into LPAR's memory address.

vtable

0x00357C48 (3.15)

Member variables

offset 0xA8 - physical address

Exploiting HV with memory glitching and HV call lv1_undocumented_function_114

Here is a short description of the method i used to exploit HV from GameOS 3.15 and 3.41.

Methods

LPAR_get_memory_region_by_start_address - 0x002C7C40 (3.15)

LPAR_get_memory_region_by_address - 0x002C7DA8 (3.15)

LPAR_mem_addr_to_phys_addr(LPAR id, LPAR address, phys_addr) - 0x002FB8F0 (3.15)

LPAR_construct_direct_mapping_mem_region - 0x002D4D04 (3.15)

Network Devices

Ethernet Gelic Device

device id = 0

MAC Address: 00:1F:A7:C6:2A:C5

device memory base address = 0x24003004000 (size = 0x1000)

WLAN Gelic Device

device id = 0

MAC Address: 02:1F:A7:C6:2A:C5 (locally administered)

Net Manager

/dev/net0

The device supports 3 ioctl commands:

Methods

net_control_cmd_GELIC_LV1_POST_WLAN_CMD - 0x0024A55C (3.15)

net_control_wlan_cmd_GELIC_EURUS_CMD_ASSOC - 0x00246C78 (3.15)

net_control_wlan_cmd_GELIC_EURUS_CMD_START_SCAN - 0x00248A14 (3.15)

net_control_wlan_cmd_GELIC_EURUS_CMD_SET_WEP_CFG - 0x00249F24 (3.15)

net_control_wlan_cmd_GELIC_EURUS_CMD_SET_WPA_CFG - 0x002497B8 (3.15)

Event Notification

Outlet class

This is the base Outlet class. There are different types of Outlet and they derive from this base class.

vtable

0x00357DC0 (3.15)

Member variables

offset 0x30 - type (8 bytes)

offset 0x38 - pointer to LPAR that owns this Outlet object

offset 0x48 - outlet id (8 bytes)

offset 0x90 - VIRQ assigned to this Outlet object (4 bytes)

Event Receive Port class

vtable

0x00357E88

VUART Outlet

vtable

0x00357DC0

VUART IRQ Bitmap

Logical PPE

vtable

0x00357DF0 (3.15)

Member variables

offset 0x90 - pointer to an object that contains VIRQ-Outlet mapping table for thread 0

offset 0x98 - pointer to an object that contains VIRQ-Outlet mapping table for thread 1

Objects

Here is the list of Logical PPE objects i found in HV 3.15.

Address in HV dump LPAR id PPE id
0x0069C7F0 1 1
0x007A8900 2 1

Virtual IRQ - Outlet Mapping

LPAR 1 PPE 1 Thread 0

0x0069C990 (3.15) - address of VIRQ-Outlet table for LPAR 1 PPE 1 Thread 0 (not empty)

VIRQ Address of Outlet object in HV dump Description
58 0x00090D10 -
59 0x006BAC50 -
60 0x006B3ED0 FLASH storage device / Storage device notification for LPAR 1
61 0x00697E70 VUART interrupts
62 0x001C8F20 -

LPAR 1 PPE 1 Thread 1

0x0069D9B0 (3.15) - address of VIRQ-Outlet table for LPAR 1 PPE 1 Thread 1 (empty)

LPAR 2 PPE 1 Thread 0

0x000A06B0 (3.15) - address of VIRQ-Outlet table for LPAR 2 PPE 1 Thread 0 (not empty)

VIRQ Address of Outlet object in HV dump Description
20 0x003AA210 -
21 0x003AFEC0 -
22 0x001FC010 -
23 0x003A8E50 -
24 0x001FFED0 SPE 0 Class 0 Interrupt
25 0x003AE160 SPE 0 Class 1 Interrupt
26 0x003AE350 SPE 0 Class 2 Interrupt
27 0x003AB100 SPE 1 Class 0 Interrupt
28 0x003AB2F0 SPE 1 Class 1 Interrupt
29 0x003AB4E0 SPE 1 Class 2 Interrupt
30 0x003AA6A0 SPE 2 Class 0 Interrupt
31 0x003AA890 SPE 2 Class 1 Interrupt
32 0x003AAA80 SPE 2 Class 2 Interrupt
33 0x003B44A0 SPE 3 Class 0 Interrupt
34 0x003B4690 SPE 3 Class 1 Interrupt
35 0x003B4AD0 SPE 3 Class 2 Interrupt
36 0x003B5300 SPE 4 Class 0 Interrupt
37 0x003B54F0 SPE 4 Class 1 Interrupt
38 0x003B56E0 SPE 4 Class 2 Interrupt
39 0x003AE7C0 SPE 5 Class 0 Interrupt
40 0x003AE9B0 SPE 5 Class 1 Interrupt
41 0x003AEBA0 SPE 5 Class 2 Interrupt
42 0x003B2040 Storage device notification for LPAR 2
43 0x003AEE30 VUART interrupts
44 0x001FEAA0 -
45 0x001FEED0 HDD storage device
46 0x003B5E20 -
47 0x003B7040 -
48 0x003B9B40 -
49 0x003B3A40 -
50 0x003BACA0 Gelic device
51 0x003BAE10 UNKNOWN storage device
52 0x003B8350 -

LPAR 2 PPE 1 Thread 1

0x007A89E0 (3.15) - address of VIRQ-Outlet table for LPAR 2 PPE 1 Thread 1 (not empty)

VIRQ Address of Outlet object in HV dump Description
16 0x003B2480 -
17 0x003B2590 -
18 0x003B26A0 -
19 0x003B27B0 -

IRQ State Bitmap

0x8941FC0 - physical address of LPAR's IRQ State Bitmap for Thread 0 of LINUX LPAR

0x8948FC0 - physical address of LPAR's IRQ State Bitmap for Thread 1 of LINUX LPAR

System Controller (SC or SYSCON)

VUART Table

Here is the SC VUART table from HV 3.15:

Index Address of VUART object in HV dump Description
0 0x0060FD20 This VUART is connected with the VUART 0 (/dev/sc0) of LPAR 1
1 0x0060FE20 This VUART is connected with the VUART 1 (/dev/sc1) of LPAR 1
2 0x0060FF20 This VUART is not connected to some peer VUART but i guess that it should be connected to VUART 2 (/dev/sc2) of LPAR1
3 0x006124E0 This VUART is connected with the VUART 3 (/dev/sc3) of LPAR 1
4 0x00612DF0 lv1_get_rtc and syscall 0x10036 communicate with this VUART.

Interrupt Handling

spider_sc_interrupt_handler - 0x0020A68C (3.15)

Methods

sc_vuart_4_get_peer_vuart - 0x002ED384 (3.15)

sc_send - 0x0020A908 (3.15)

sc_receive - 0x0020A354 (3.15)

sc_vuart_rx_trigger_callback - 0x002ED470 (3.15)

lv1_get_rtc

SYSCON Protocol

Packet Header

struct sc_hdr
{
    uint8_t field0;
    uint8_t field1;          /* always 1 */
    uint8_t field2[4];
    uint16_t cksum;          /* header checksum */
    uint32_t index;          /* syscon index (0 - /dev/sc0, 1 - /dev/sc1, 2 - /dev/sc2, 3 - /dev/sc3) */
    uint16_t size1;          /* body size */
    uint16_t size2;          /* body size */
};

Calculating Packet Header Checksum

/* calculating SC packet header checksum */

/*
 * sc_hdr_cksum
 */
uint16_t sc_hdr_cksum(struct sc_hdr *sc_hdr)
{
    uint8_t *ptr;
    uint32_t sum;

    ptr = (uint8_t *) sc_hdr;
    sum = 0;

    for (i = 0; i < 6; i++)
        sum += *ptr++;

    sum += 0x8000;

    return sum & 0xffff;
}

struct sc_hdr sc_hdr;

memset(&sc_hdr, 0, sizeof(sc_hdr));

sc_hdr.cksum = sc_hdr_cksum(sc_hdr);

/* fill sc header here */

sc_hdr.cksum = sc_hdr_cksum(sc_hdr);

Packet Body

Reading SYSCON EPROM (NVS Service)

Here is a command which is sent to SYSCON to read 1 byte of EPROM at offset 0x48C07 (Product Mode):

0x14 0x01 0x00 0x00 0x00 0x00 0x80 0x15 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x04 0x20 0x02 0x07 0x01

And here is the response to the above request:

0x14 0x01 0x00 0x00 0x00 0x00 0x80 0x15 0x00 0x00 0x00 0x03 0x00 0x05 0x00 0x05 0x00 0x02 0x07 0x01 0xff

PCI Bus Power

PCI Bus Power On

Request to SC1:

0x10 0x01 0x00 0x00 0x00 0x00 0x80 0x11 0x00 0x00 0x00 0x00 0x00 0x02 0x00 0x02 0x31 0x01

PCI Bus Power Off

Request to SC1:

0x10 0x01 0x00 0x00 0x00 0x00 0x80 0x11 0x00 0x00 0x00 0x00 0x00 0x02 0x00 0x02 0x31 0x00

Ring Buzzer

Request:

0x16 0x01 0x00 0x00 0x00 0x00 0x80 0x17 0x00 0x00 0x00 0x00 0x00 0x08 0x00 0x08 0x20 0x00 0x00 0x00 0x00 0x00 0x00 0x00

SYSCON

Crossreference: gitbrew.org::SYSCON


SYSCON MMIO registers can be accessed on Linux with a driver using lv1_undocumented_function_114, e.g. ps3sbmmio. Use ps3sbmmio device driver carefully, an access at some addresses could shutdown your PS3.

Packet Header

struct sc_hdr {
    uint8_t service_id;
    uint8_t version;              /* must be 1 !!! */
    uint16_t transaction_id;      /* returned in response */
    uint8_t res[2];
    uint16_t cksum;               /* checksum of first 6 header bytes */
    uint32_t index;               /* SYSCON index: 0-4 */
    uint16_t payload_size[2];     /* body size */
};

Sending Packets

uint32_t cksum = 0;

for (i = 0; i < packet_size; i++)
    cksum -= packet[i];

cksum = cksum & 0xffff;
 
value = value + 1;
value &= 0xffff;
value = (value << 16) | value;

Receiving Packets

which gives us the possibility to communicate with SYSCON on Linux easily :)

Test

1. Before sending SYSCON packet:

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff4)) status=noxfer | hexdump -C

00000000  01 18 01 18                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  01 18 01 18                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff0)) status=noxfer | hexdump -C

00000000  01 24 01 24                                       |.$.$|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff4)) status=noxfer | hexdump -C

00000000  01 24 01 24                                       |.$.$|
00000004

2. SYSCON packet was sent by using ps3dm_scm read_eprom.

3. After sending SYSCON packet:

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff4)) status=noxfer | hexdump -C

00000000  01 19 01 19                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  01 19 01 19                                       |....|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8cff0)) status=noxfer | hexdump -C

00000000  01 25 01 25                                       |.%.%|
00000004

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff4)) status=noxfer | hexdump -C

00000000  01 25 01 25                                       |.%.%|
00000004

4. Received Header

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=16 skip=$((0x8c000)) status=noxfer | hexdump -C

00000000  14 01 00 00 00 00 80 15  00 00 00 03 00 05 00 05  |................|
00000010

5. Received Body

root@debian-hdd:~# dd if=/dev/ps3sbmmio bs=1 count=8 skip=$((0x8c010)) status=noxfer | hexdump -C

00000000  00 00 c7 01 ff 00 00 00                           |..Ç.ÿ...|
00000008

Examples

Get RTC

Request:

# write packet

# echo "0: 13 01 0000 0000 8014 00000004 0001 0001 33 00 00 00 0000ff1f" | xxd -c256 -r | \
       dd of=/dev/ps3sbmmio bs=1 seek=$((0x8d000)) status=noxfer

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c0 00 c0                                       |.À.À|
00000004

# increment packet counter

echo "0: 00c1 00c1" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8dff0)) status=noxfer

# kick packet

# echo "0: 00000001" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8e100)) status=noxfer

Response:

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c1 00 c1                                       |.Á.Á|
00000004

# dump response packet

# dd if=/dev/ps3sbmmio bs=1 count=24 skip=$((0x8c000)) status=noxfer | hexdump -C

00000000  13 01 00 00 00 00 80 14  00 00 00 04 00 08 00 08  |................|
00000010  00 00 00 00 15 af 47 6b                           |.....¯Gk|
00000018

Ring Buzzer

Request:

# write packet

# echo "0: 16 01 1620 0000 804d 00000001 0008 0008 20 29 0a 00 000001b6 0000fdcb" | xxd -c256 -r | \
       dd of=/dev/ps3sbmmio bs=1 seek=$((0x8d000)) status=noxfer

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c0 00 c0                                       |.À.À|
00000004

# increment packet counter

echo "0: 00c1 00c1" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8dff0)) status=noxfer

# kick packet

# echo "0: 00000001" | xxd -c256 -r | dd of=/dev/ps3sbmmio bs=1 seek=$((0x8e100)) status=noxfer

# you should hear a beep

Response:

# dump packet counter

# dd if=/dev/ps3sbmmio bs=1 count=4 skip=$((0x8dff0)) status=noxfer | hexdump -C

00000000  00 c1 00 c1                                       |.Á.Á|
00000004

# dump response packet

# dd if=/dev/ps3sbmmio bs=1 count=24 skip=$((0x8c000)) status=noxfer | hexdump -C
00000000  16 01 16 20 00 00 80 4d  00 00 00 01 00 01 00 01  |... ...M........|
00000010  00 00 00 00 00 00 fe e3                           |......þã|
00000018


Isolation

Crossreference: gitbrew.org::Isolation

Running Isolated SPE Modules On OtherOS++ Linux

root@debian-hdd:/home/glevand/spp_verifier# cat spp_verifier_355.self > /proc/spp_verifier/spu
root@debian-hdd:/home/glevand/spp_verifier# cat default_355.spp > /proc/spp_verifier/profile
root@debian-hdd:/home/glevand/spp_verifier# echo 1 > /proc/spp_verifier/run
root@debian-hdd:/home/glevand/spp_verifier# cat /proc/spp_verifier/debug 

PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x000000000000002b)
lv1_undocumented_function_209 (0x00000000)
shadow execution status (0x0000000000000002)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
sleep
shadow execution status (0x0000000000000002)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000001)
ea (0xc000000002920000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_undocumented_function_62 (0x00000000)
lv1_clear_spe_interrupt_status(1) (0x00000000)
lv1_undocumented_function_168 (0x00000000)
sleep
shadow execution status (0x0000000000000007)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
interrupt status 2 (0x0000000000000000)
out interrupt mbox (0x0000000000000002)
out interrupt mbox (0x0000000000000002)
lv1_undocumented_function_167 (0x00000000)
lv1_clear_spe_interrupt_status (0x00000000)
lv1_undocumented_function_200 (0x00000000)
sleep
shadow execution status (0x000000000000000b)
lv1_get_spe_interrupt_status(1) (0x00000000)
interrupt status 1 (0x0000000000000000)
shadow execution status (0x000000000000000b)
problem status (0x01000082)
lv1_destruct_logical_spe (0x00000000)

root@debian-hdd:/home/glevand/spp_verifier# hexdump -C /proc/spp_verifier/profile | less
...
...
00000200  00 02 00 05 00 00 20 a0  00 00 00 01 00 03 00 00  |......  ........|
00000210  00 00 00 00 00 00 00 01  00 00 00 0e 00 00 00 00  |................|
00000220  00 00 02 88 00 00 00 01  10 70 00 00 01 00 00 01  |.........p......|
00000230  00 00 00 00 00 00 00 00  53 43 45 5f 43 45 4c 4c  |........SCE_CELL|
00000240  4f 53 5f 50 4d 45 00 00  00 00 00 00 00 00 00 00  |OS_PME..........|
00000250  00 00 00 00 00 00 00 00  00 00 00 06 00 00 02 50  |...............P|
00000260  10 70 00 00 01 00 00 01  2f 66 6c 68 2f 6f 73 2f  |.p....../flh/os/|
00000270  74 68 69 73 5f 69 73 5f  64 75 6d 6d 79 00 00 00  |this_is_dummy...|
00000280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
...

Using metldr On OtherOS++ Linux

root@debian-hdd:/home/glevand/spp_verifier_direct# insmod ./spp_verifier_direct.ko
root@debian-hdd:/home/glevand/spp_verifier_direct# cat metldr > /proc/spp_verifier_direct/metldr
root@debian-hdd:/home/glevand/spp_verifier_direct# cat isoldr_355 > /proc/spp_verifier_direct/isoldr
root@debian-hdd:/home/glevand/spp_verifier_direct# cat RL_FOR_PROGRAM_355.img > /proc/spp_verifier_direct/rvkprg
root@debian-hdd:/home/glevand/spp_verifier_direct# cat EID0 > /proc/spp_verifier_direct/eid0
root@debian-hdd:/home/glevand/spp_verifier_direct# cat spp_verifier_355.self > /proc/spp_verifier_direct/spu
root@debian-hdd:/home/glevand/spp_verifier_direct# cat default_355.spp > /proc/spp_verifier_direct/profile
root@debian-hdd:/home/glevand/spp_verifier_direct# echo 1 > /proc/spp_verifier_direct/run
root@debian-hdd:/home/glevand/spp_verifier_direct# cat /proc/spp_verifier_direct/debug
 
PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x0000000000000033)
lv1_enable_logical_spe (0x00000000)
lv1_set_spe_interrupt_mask(0) (0x00000000)
lv1_set_spe_interrupt_mask(1) (0x00000000)
lv1_set_spe_interrupt_mask(2) (0x00000000)
lv1_set_spe_privilege_state_area_1_register (0x00000000)
ea (0xc000000002680000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000001)
lv1_clear_spe_interrupt_status(2) (0x00000000)
transferring EID0, ldr args and revoke list to LS
waiting until MFC transfers are finished
MFC transfers done
out mbox (0x00000001)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000002)
lv1_clear_spe_interrupt_status(2) (0x00000000)
out mbox (0x00000002)
lv1_clear_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
problem status (0x01000082)
lv1_destruct_logical_spe (0x00000000)

root@debian-hdd:/home/glevand/spp_verifier_direct# hexdump -C /proc/spp_verifier_direct/profile | less
...
...
00000200  00 02 00 05 00 00 20 a0  00 00 00 01 00 03 00 00  |......  ........|
00000210  00 00 00 00 00 00 00 01  00 00 00 0e 00 00 00 00  |................|
00000220  00 00 02 88 00 00 00 01  10 70 00 00 01 00 00 01  |.........p......|
00000230  00 00 00 00 00 00 00 00  53 43 45 5f 43 45 4c 4c  |........SCE_CELL|
00000240  4f 53 5f 50 4d 45 00 00  00 00 00 00 00 00 00 00  |OS_PME..........|
00000250  00 00 00 00 00 00 00 00  00 00 00 06 00 00 02 50  |...............P|
00000260  10 70 00 00 01 00 00 01  2f 66 6c 68 2f 6f 73 2f  |.p....../flh/os/|
00000270  74 68 69 73 5f 69 73 5f  64 75 6d 6d 79 00 00 00  |this_is_dummy...|
00000280  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
...

Gelic Device

Crossreference: gitbrew.org::Gelic Device

sys.hw.config

Note:old vs. new: Old == CECHA up to CECHK, New == CECHL and later

Control Interface

HV calls 195 and 196 are used by GameOS to send commands to Gelic device directly.

lv1_undocumented_function_196

Parameters

r3 - LPAR address of data buffer

r4 - size of data buffer

r5 - must be 0

lv1_undocumented_function_195

Parameters

r3 - command (16 bit value)

r4 - command data size

r5 - must be 0

Data Buffer

Command Data Buffer

Header

0x0 - command = request command + 1 (2 bytes)

0x4 - result, 0x1 - success ??? 0x2 - buffer too small ??? (2 bytes)

0x6 - body size (2 bytes)

Event Data Buffer

Header

offset 0x0 - GET index (4 bytes)

offset 0x4 - PUT index (4 bytes)

GameOS

Parameters

r3 - command (16 bits)

r4 - effective address of command data buffer

r5 - size of command data buffer

Commands

Unknown (0x1)

Get AP SSID (0x3)

offset 0xC - SSID (32 bytes)

Set AP SSID (0x5)

offset 0xC - SSID (32 bytes)

Get Channel (0xf)

offset 0x2F - active channel (2 bytes)

Set Channel (0x11)

offset 0xC - channel (1 byte)

Unknown (0x27)

Set Antenna (0x29)

offset 0xC - ??? (1 byte)

offset 0xD - ??? (1 byte)

Set AP WEP Configuration (0x5b)

offset 0xE - security mode: 0 - none, 1 - wep64, 2 - wep128 (1 byte)

offset 0x10 - WEP key (64 bytes)

Unknown (0x61)

Unknown (0x65)

Get Eurus Firmware Version (0x99)

Here is the response on my PS3 Slim:

00000000: 4a 55 50 49 54 45 52 2d 54 57 4f 2d 46 57 2d 32 |JUPITER-TWO-FW-2|
00000010: 30 2e 30 2e 31 32 2e 70 30 28 4a 61 6e 20 31 39 |0.0.12.p0(Jan 19|
00000020: 20 32 30 31 30 20 32 31 3a 32 30 3a 35 33 29 00 | 2010 21:20:53).|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00       |..............  |

Get AP Operating Mode (0xb7)

offset 0xC - opmode: 0 - 11b, 1 - 11g, 2 - 11bg (4 bytes)

Set AP Operating Mode (0xb9)

offset 0xC - opmode: 0 - 11b, 1 - 11g, 2 - 11bg (4 bytes)

Unknown (0xc5)

offset 0xC - ??? (4 bytes)

Unknown (0xc9)

Unknown (0xcf)

Set AP WPA PSK (0xd3)

offset 0xC - PSK (64 bytes)

Set AP WPA XXX Timeout (0xd5)

offset 0xC - timeout value (4 bytes)

Unknown (0x127)

Unknown (0x12b)

Unknown (0x17d)

Unknown (0x1bf)

Unknown (0x1d9)

Unknown (0x1dd)

Unknown (0x1ed)

Get Eurus HW Revision (0x1fb)

Associate (0x1001)

Get Common Configuration (0x1003)

Set Common Configuration (0x1005)

offset 0xE - opmode: 0 - 11b, 1 - 11g, 2 - 11bg (1 byte)

offset 0x10 - BSSID (6 bytes)

Get WEP Configuration (0x1013)

Set WEP Configuration (0x1015)

Get WPA Configuration (0x1017)

Set WPA Configuration (0x1019)

offset 0xE - security type: 0 - WPA, 1 - RSNA (1 byte)

offset 0xF - psk type: 0 - hex, 1 - bin (1 byte)

offset 0x10 - psk key: hex or bin (64 bytes)

offset 0x50 - group cipher suite: 0x0050f202 - WPA TKIP, 0x0050f204 - WPA AES, 0x000fac02 - RSNA TKIP, 0x000fac04 - RSNA CCMP (4 bytes)

offset 0x54 - pairwise cipher suite: 0x0050f202 - WPA TKIP, 0x0050f204 - WPA AES, 0x000fac02 - RSNA TKIP, 0x000fac04 - RSNA CCMP (4 bytes)

offset 0x58 - AKM suite: 0x0050f202 - WPA PSK, 0x000fac02 - RSNA PSK (4 bytes)

See IEEE 802.11 specification for more details about cipher/AKM suites

802.11 spec: [3]

Unknown (0x1025)

Unknown (0x1031)

Get Scan Results (0x1033)

Scan Results

offset 0x0 - number of scan entries (1 byte)

offset 0x1 - array of scan entries

Scan Entry

offset 0x0 - size of this entry in bytes, this field is NOT included (2 bytes)

offset 0x2 - BSSID (6 bytes)

offset 0x8 - RSSI (1 byte)

offset 0x9 - timestamp (8 bytes)

offset 0x11 - beacon period (2 bytes)

offset 0x13 - capability (2 bytes)

offset 0x15 - information elements (see 802.11 specification)

Start Scan (0x1035)

Diassociate (0x1037)

Get RSSI (0x103d)

offset 0x10 - MAC address of node (6 bytes)

offset 0x16 - RSSI (1 byte)

Get MAC Address (0x103f)

offset 0xD - MAC address (6 bytes)

Set MAC Address (0x1041)

Unknown (0x104d)

Unknown (0x1051)

Unknown (0x1053)

Unknown (0x1059)

Unknown (0x105f)

Get Zephyr HW Revision (0x1101)

Get MAC Address List (0x1117)

offset 0xC - number of MAC addresses (2 bytes)

offset 0xE - MAC addresses (6 * number of MAC addresses)

Unknown (0x1133)

Set WOL MAC Address Filter (0x1139)

Unknown (0x113b)

Set WOL Address Filter (0x113d)

Clear WOL MAC Address Filter (0x113f)

Unknown (0x1141)

Clear WOL Address Filter (0x1143)

Unknown (0x114b)

WOL Magic Packet Control (0x1155)

Unknown (0x1157)

Unknown (0x1159)

Set WOL Magic Packet Pattern (0x115b)

Unknown (0x115d)

Get WOL Magic Packet Pattern (0x115f)

Set Multicast Address Filter (0x1161)

Clear Multicast Address Filter (0x1163)

Get Multicast Address Filter (0x1165)

Unknown (0x1167)

Unknown (0x116d)

Unknown (0x116f)

Get Device Status (0xfffb)

Unknown (0xfffc)

Get Channel Information (0xfffd)

Set Response Timeout (0xfffe)

Unknown (0xffff)

Events

struct ps3_eurus_event_hdr {
	__le32 type;
	__le32 id;
	__le32 unknown1;            /* timestamp ??? */
	__le32 payload_length;
	__le32 unknown2;
} __packed;

struct ps3_eurus_event {
	struct ps3_eurus_event_hdr hdr;
	u8 payload[44];
} __packed;
Deauthentication Event
Connected Event
Device Ready Event

Enabling WLAN Gelic On FAT

Linux kernel doesn't use Gelic Device Control Interface like GameOS does it. To get WLAN working on Linux booted with GameOS rights, we have to disable Gelic Device Control Interface first because it's enabled for GameOS by default.

The value of repository node "ios.net.eurus.lpar" controls access to Gelic Device Control Interface. It's a bitmap. The position of a bit corresponds to LPAR id. During GameOS booting, HV process 9 (System Manager) sets bit at postion 2 to 1 which means enable Gelic Device Control Interface for LPAR 2.

To disable Gelic Device Control Interface on Linux, first unload Gelic device driver, then set value of repository node "ios.net.eurus.lpar" to 0 and load Gelic device driver again. After that WLAN should work again but only on FATs.

For PS3 Slim we need a new Linux Gelic device driver which uses Gelic Device Control Interface directly.


USB WLAN Interface (Codename Jupiter 2)

Endpoints

Bus 002 Device 002: ID 054c:036f Sony Corp. 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          224 Wireless
  bDeviceSubClass         1 Radio Frequency
  bDeviceProtocol         1 Bluetooth
  bMaxPacketSize0        64
  idVendor           0x054c Sony Corp.
  idProduct          0x036f 
  bcdDevice           20.12
  iManufacturer           1 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      1 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x4000  1x 0 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x05  EP 5 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x4000  1x 0 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        4
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      2 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x06  EP 6 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        5
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      2 
      bInterfaceProtocol      3 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x07  EP 7 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0002  1x 2 bytes
        bInterval             255

Device Initialization

Magic Data in Control Transfer

unsigned char ps3_usb_wlan_magic_data[] = {
	0x76, 0x4e, 0x4b, 0x07, 0x24, 0x42, 0x53, 0xfb, 0x5a, 0xc7, 0xcc, 0x1d, 0xae, 0x00, 0xc6, 0xd8,
	0x14, 0x40, 0x61, 0x8b, 0x13, 0x17, 0x4d, 0x7c, 0x3b, 0xb6, 0x90, 0xb8, 0x6e, 0x8b, 0xbb, 0x1d,
};

Initialization State Machine

State 1
State 2
State 3
State 4
State 5
State 6
State 7
State 8
State 9
State 10
State 11
State 12
State 13
State 14
State 15
State 16
State 17

Test Program

Source Code


/*
 * PS3 USB WLAN
 *
 * Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <unistd.h>
#include <pthread.h>

#include <libusb-1.0/libusb.h>

#define USB_VENDOR_ID				0x054c /* $ONY */
#define USB_PRODUCT_ID				0x036f
#define USB_IFACE_NUMBER			3

#define USB_INTR_TRANSFER_EP5_IN_BUF_SIZE	0x800
#define USB_INTR_TRANSFER_EP5_OUT_BUF_SIZE	0x800

struct wlan_cmd_pkt_hdr {
	uint8_t unknown1;
	uint8_t unknown2;
	uint8_t unknown3;
	uint8_t unknown4;
	uint16_t unknown5;
	uint8_t res1[2];
	uint16_t tag;
	uint8_t res2[14];
} __attribute__ ((packed));

struct wlan_cmd_hdr {
	uint16_t command;
	uint16_t tag;
	uint16_t status;
	uint16_t payload_size;
	uint8_t res[4];
} __attribute__ ((packed));

struct wlan_event_pkt_hdr {
	uint8_t unknown1;
	uint8_t unknown2;
	uint8_t unknown3;
	uint8_t event_count;
} __attribute__ ((packed));

static libusb_context *usb_ctx;
static libusb_device_handle *usb_dev_handle;

static struct libusb_transfer *usb_intr_transfer_ep5_in;
static unsigned char usb_intr_transfer_ep5_in_buf[USB_INTR_TRANSFER_EP5_IN_BUF_SIZE];

static unsigned char usb_intr_transfer_ep5_out_buf[USB_INTR_TRANSFER_EP5_OUT_BUF_SIZE];

static pthread_mutex_t usb_wlan_cmd_mutex;
static pthread_cond_t usb_wlan_cmd_cond;
static int volatile usb_wlan_cmd_busy;
static uint16_t usb_wlan_cmd;
static void *usb_wlan_cmd_data;

static int volatile usb_wlan_cmd_thread_done;

/*
 * WLAN won't work without this magic !!!
 */
static unsigned char usb_magic_data[] = {
	0x76, 0x4e, 0x4b, 0x07, 0x24, 0x42, 0x53, 0xfb, 0x5a, 0xc7, 0xcc, 0x1d, 0xae, 0x00, 0xc6, 0xd8,
	0x14, 0x40, 0x61, 0x8b, 0x13, 0x17, 0x4d, 0x7c, 0x3b, 0xb6, 0x90, 0xb8, 0x6e, 0x8b, 0xbb, 0x1d,
};

static unsigned char my_mac_addr[] = {
	0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
};

/*
 * hexdump
 */
static void hexdump(const unsigned char *data, unsigned int data_size)
{
	int i, j;

	for (i = 0; i < data_size; i += 16) {
		fprintf(stdout, "%08x:", i);

		for (j = 0; j < 16; j++) {
			if (i + j < data_size) {
				fprintf(stdout, " %02x", data[i + j]);
			} else {
				fprintf(stdout, "   ");
			}
		}

		fprintf(stdout, " |");

		for (j = 0; j < 16; j++) {
			if (i + j < data_size) {
				if (isprint(data[i + j]))
					fprintf(stdout, "%c", data[i + j]);
				else
					fprintf(stdout, ".");
			} else {
				fprintf(stdout, " ");
			}
		}

		fprintf(stdout, "|\n");
	}
}

/*
 * usb_handle_wlan_event
 */
static void usb_handle_wlan_event(struct wlan_event_pkt_hdr *wlan_event_pkt_hdr)
{
	fprintf(stdout, "%s:%d: === got WLAN event ===\n", __func__, __LINE__);

	/*
	fprintf(stdout, "%s:%d: event packet header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: unknown1 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown1);
	fprintf(stdout, "%s:%d: unknown2 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown2);
	fprintf(stdout, "%s:%d: unknown3 (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->unknown3);
	*/
	fprintf(stdout, "%s:%d: event_count (0x%02x)\n", __func__, __LINE__,
		wlan_event_pkt_hdr->event_count);

	hexdump((unsigned char *) (wlan_event_pkt_hdr + 1), wlan_event_pkt_hdr->event_count * 64);
}

/*
 * usb_handle_wlan_cmd_response
 */
static void usb_handle_wlan_cmd_response(struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr)
{
	struct wlan_cmd_hdr *wlan_cmd_hdr;
	uint8_t *wlan_cmd_payload;

	fprintf(stdout, "%s:%d: === got WLAN command response ===\n", __func__, __LINE__);

	wlan_cmd_hdr = (struct wlan_cmd_hdr *) (wlan_cmd_pkt_hdr + 1);
	wlan_cmd_payload = (uint8_t *) (wlan_cmd_hdr + 1);

	/* convert all header fields to big-endian byte order !!! */

	wlan_cmd_pkt_hdr->unknown5 = le16toh(wlan_cmd_pkt_hdr->unknown5);
	wlan_cmd_pkt_hdr->tag = le16toh(wlan_cmd_pkt_hdr->tag);			/* returned from request */

	wlan_cmd_hdr->command = le16toh(wlan_cmd_hdr->command);			/* request command + 1 */
	wlan_cmd_hdr->tag = le16toh(wlan_cmd_hdr->tag);				/* returned from request */
	wlan_cmd_hdr->status = le16toh(wlan_cmd_hdr->status);			/* 1 - success
										   2 - invalid parameters ???
										   3 - invalid command ??? */
	wlan_cmd_hdr->payload_size = le16toh(wlan_cmd_hdr->payload_size);	/* length of data that follows the header */

	/*
	fprintf(stdout, "%s:%d: command packet header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: unknown1 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown1);
	fprintf(stdout, "%s:%d: unknown2 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown2);
	fprintf(stdout, "%s:%d: unknown3 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown3);
	fprintf(stdout, "%s:%d: unknown4 (0x%02x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown4);
	fprintf(stdout, "%s:%d: unknown5 (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->unknown5);
	fprintf(stdout, "%s:%d: tag (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_pkt_hdr->tag);
	*/

	fprintf(stdout, "%s:%d: command header:\n", __func__, __LINE__);
	fprintf(stdout, "%s:%d: command (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->command);

	if ((usb_wlan_cmd + 1) != wlan_cmd_hdr->command)
		fprintf(stdout, "%s:%d: ==> command does not match, got (0x%04x) expected (0x%04x)\n",
			__func__, __LINE__, wlan_cmd_hdr->command, usb_wlan_cmd + 1);

	fprintf(stdout, "%s:%d: tag (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->tag);
	fprintf(stdout, "%s:%d: status (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->status);

	if (wlan_cmd_hdr->status != 0x1)
		fprintf(stdout, "%s:%d: ==> command status != 0x1\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: payload_size (0x%04x)\n", __func__, __LINE__,
		wlan_cmd_hdr->payload_size);

	fprintf(stdout, "%s:%d: command payload:\n", __func__, __LINE__);

	hexdump(wlan_cmd_payload, wlan_cmd_hdr->payload_size);

	memcpy(usb_wlan_cmd_data, wlan_cmd_payload, wlan_cmd_hdr->payload_size);

	pthread_mutex_lock(&usb_wlan_cmd_mutex);

	usb_wlan_cmd_busy = 0;

	pthread_cond_signal(&usb_wlan_cmd_cond);

	pthread_mutex_unlock(&usb_wlan_cmd_mutex);
}

/*
 * usb_intr_transfer_ep5_in_cb
 */
static void usb_intr_transfer_ep5_in_cb(struct libusb_transfer *transfer)
{
	struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr;
	int error;

	fprintf(stdout, "%s:%d: === got interrupt transfer ===\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: transfer status (%d) length (%d)\n",
		__func__, __LINE__, transfer->status, transfer->actual_length);

	wlan_cmd_pkt_hdr = (struct wlan_cmd_pkt_hdr *) transfer->buffer;

	if (wlan_cmd_pkt_hdr->unknown3 == 0x6)
		usb_handle_wlan_cmd_response(wlan_cmd_pkt_hdr);
	else if (wlan_cmd_pkt_hdr->unknown3 == 0x8)
		usb_handle_wlan_event((struct wlan_event_pkt_hdr *) transfer->buffer);
	else
		fprintf(stdout, "%s:%d: got unknown packet (0x%02x)\n",
			__func__, __LINE__, wlan_cmd_pkt_hdr->unknown3);

	memset(usb_intr_transfer_ep5_in_buf, 0, sizeof(usb_intr_transfer_ep5_in_buf));

	libusb_fill_interrupt_transfer(usb_intr_transfer_ep5_in, usb_dev_handle, LIBUSB_ENDPOINT_IN | 0x5,
		usb_intr_transfer_ep5_in_buf, sizeof(usb_intr_transfer_ep5_in_buf),
		usb_intr_transfer_ep5_in_cb, NULL, 0);

	error = libusb_submit_transfer(usb_intr_transfer_ep5_in);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}
}

/*
 * usb_intr_transfer_ep5_out_cb
 */
static void usb_intr_transfer_ep5_out_cb(struct libusb_transfer *transfer)
{
	/*
	fprintf(stdout, "%s:%d: sent interrupt transfer\n", __func__, __LINE__);

	fprintf(stdout, "%s:%d: transfer status (%d)\n", __func__, __LINE__, transfer->status);
	*/

	libusb_free_transfer(transfer);
}

/*
 * usb_wlan_cmd_send
 */
static int usb_wlan_cmd_send(uint16_t command, const uint8_t *data, unsigned int data_size)
{
	struct wlan_cmd_pkt_hdr *wlan_cmd_pkt_hdr;
	struct wlan_cmd_hdr *wlan_cmd_hdr;
	uint8_t *wlan_cmd_payload;
	struct libusb_transfer *transfer;
	int error;

	fprintf(stdout, "%s:%d: sending command (0x%04x) data size (0x%04x) command size (0x%04x)\n",
		__func__, __LINE__, command, data_size, data_size + sizeof(struct wlan_cmd_hdr));

	transfer = libusb_alloc_transfer(0);
	if (!transfer) {
		fprintf(stderr, "%s:%d: could not allocate transfer\n", __func__, __LINE__);
		error = -1;
		goto fail;
	}

	wlan_cmd_pkt_hdr = (struct wlan_cmd_pkt_hdr *) usb_intr_transfer_ep5_out_buf;
	wlan_cmd_hdr = (struct wlan_cmd_hdr *) (wlan_cmd_pkt_hdr + 1);
	wlan_cmd_payload = (uint8_t *) (wlan_cmd_hdr + 1);

	wlan_cmd_pkt_hdr->unknown1 = 0x1;
	wlan_cmd_pkt_hdr->unknown2 = 0x1;
	wlan_cmd_pkt_hdr->unknown3 = 0x6;
	wlan_cmd_pkt_hdr->unknown4 = 0x0;
	wlan_cmd_pkt_hdr->unknown5 = 0x1;
	wlan_cmd_pkt_hdr->tag = 0xf00d;		/* returned in response */

	wlan_cmd_hdr->command = command;
	wlan_cmd_hdr->tag = 0xcafe;		/* returned in response */
	wlan_cmd_hdr->status = 0xa;
	wlan_cmd_hdr->payload_size = data_size;

	memcpy(wlan_cmd_payload, data, data_size);

	usb_wlan_cmd = command;
	usb_wlan_cmd_data = (void *) data;

	libusb_fill_interrupt_transfer(transfer, usb_dev_handle, LIBUSB_ENDPOINT_OUT | 0x5,
		usb_intr_transfer_ep5_out_buf,
		sizeof(struct wlan_cmd_pkt_hdr) + sizeof(struct wlan_cmd_hdr) + wlan_cmd_hdr->payload_size,
		usb_intr_transfer_ep5_out_cb, NULL, 0);

	/* convert all header fields to little-endian byte order !!! */

	wlan_cmd_pkt_hdr->unknown5 = htole16(wlan_cmd_pkt_hdr->unknown5);
	wlan_cmd_pkt_hdr->tag = htole16(wlan_cmd_pkt_hdr->tag);

	wlan_cmd_hdr->command = htole16(wlan_cmd_hdr->command);
	wlan_cmd_hdr->tag = htole16(wlan_cmd_hdr->tag);
	wlan_cmd_hdr->status = htole16(wlan_cmd_hdr->status);
	wlan_cmd_hdr->payload_size = htole16(wlan_cmd_hdr->payload_size);

	error = libusb_submit_transfer(transfer);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		goto fail_free_transfer;
	}

	pthread_mutex_lock(&usb_wlan_cmd_mutex);

	usb_wlan_cmd_busy = 1;

	while (usb_wlan_cmd_busy)
		pthread_cond_wait(&usb_wlan_cmd_cond, &usb_wlan_cmd_mutex);

	pthread_mutex_unlock(&usb_wlan_cmd_mutex);

	return 0;

fail_free_transfer:

	libusb_free_transfer(transfer);

fail:

	return error;
}

/*
 * usb_wlan_cmd_start_scan
 */
static int usb_wlan_cmd_start_scan(void)
{
	unsigned char data[256], *ptr;
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	ptr = data;
	*ptr++ = 0x0;
	*ptr++ = 0x1;
	*ptr++ = 0x64;
	*ptr++ = 0x0;

	ptr = data + 0xa;
	*ptr++ = 0x3;

	*ptr++ = 13;	/* number of channels */
	*ptr++ = 1;	/* channels */
	*ptr++ = 2;
	*ptr++ = 3;
	*ptr++ = 4;
	*ptr++ = 5;
	*ptr++ = 6;
	*ptr++ = 7;
	*ptr++ = 8;
	*ptr++ = 9;
	*ptr++ = 10;
	*ptr++ = 11;
	*ptr++ = 12;
	*ptr++ = 13;

	data_size = ptr - data;

	return usb_wlan_cmd_send(0x1035, data, data_size);
}

/*
 * usb_wlan_cmd_get_scan_results
 */
static int usb_wlan_cmd_get_scan_results(void)
{
	unsigned char data[1456];
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	data_size = sizeof(data);

	return usb_wlan_cmd_send(0x1033, data, data_size);
}

/*
 * usb_wlan_cmd_0x99
 */
static int usb_wlan_cmd_0x99(void)
{
	unsigned char data[0x3e];
	unsigned int data_size;

	memset(data, 0, sizeof(data));

	data_size = sizeof(data);

	return usb_wlan_cmd_send(0x99, data, data_size);
}

/*
 * usb_wlan_init
 */
static int usb_wlan_init(void)
{
	unsigned char data[1456], *ptr;
	unsigned int data_size;
	int error;

	/* state 0x1 */

	memset(data, 0, sizeof(data));

	data_size = 0x518;

	error = usb_wlan_cmd_send(0x114f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x114f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x2 */

	memset(data, 0, sizeof(data));

	data_size = 0;

	error = usb_wlan_cmd_send(0x1171, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1171 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* wait for a WLAN event */

	/* state 0x4 */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x116f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x116f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x5 */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 0x4;
	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	data_size = 0x5e;

	error = usb_wlan_cmd_send(0x115b, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x115b (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0x6 */

	memset(data, 0, sizeof(data));

	ptr = data + 0x1c;

	*ptr++ = 0x20;

	data_size = 0x20;

	error = usb_wlan_cmd_send(0x1161, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1161 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data + 0xc;
	memset(ptr, 0xff, 7 * 4);

	data_size = 0x80;

	error = usb_wlan_cmd_send(0x110d, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x110d (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	data_size = 0x2;

	error = usb_wlan_cmd_send(0x1031, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1031 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;
	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	data_size = 0x6;

	error = usb_wlan_cmd_send(0x1041, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1041 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0xa */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x2;
	*ptr++ = 0x2;

	data_size = 0x2;

	error = usb_wlan_cmd_send(0x29, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x29 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 8;

	*ptr++ = 0x20;

	data_size = 0xc;

	error = usb_wlan_cmd_send(0x110b, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x110b (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	ptr = data + 0x4;

	*ptr++ = 0x15;
	*ptr++ = 0x27;

	*ptr++ = 0x12;
	*ptr++ = 0x0;

	*ptr++ = 0x6;
	*ptr++ = 0x0;

	ptr = data + 0xc;

	*ptr++ = 0x9;
	*ptr++ = 0x0;
	*ptr++ = 0x1;

	ptr = data + 0x10;

	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;
	*ptr++ = 0xff;

	data_size = 0x16;

	error = usb_wlan_cmd_send(0x1109, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x1109 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x1;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x207, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x207 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0x4;

	data_size = 0x4;

	error = usb_wlan_cmd_send(0x203, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x203 (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	sleep(2);

	/* state 0xf */

	memset(data, 0, sizeof(data));

	ptr = data;

	*ptr++ = 0xff;
	*ptr++ = 0x1f;

	memcpy(ptr, my_mac_addr, sizeof(my_mac_addr));

	ptr = data + 0x8;

	*ptr++ = 0x2;
	*ptr++ = 0x2;

	data_size = 0xa;

	error = usb_wlan_cmd_send(0x105f, data, data_size);
	if (error) {
		fprintf(stderr, "%s:%d: could not send command 0x105f (%d)\n",
			__func__, __LINE__, error);
		return error;
	}

	return 0;
}

/*
 * usb_wlan_cmd_thread
 */
static void *usb_wlan_cmd_thread(void *arg)
{
	int error;

	error = usb_wlan_init();
	if (error) {
		fprintf(stderr, "%s:%d: could not initialize device (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(5);

	error = usb_wlan_cmd_0x99();
	if (error) {
		fprintf(stderr, "%s:%d: could not start scanning (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	error = usb_wlan_cmd_start_scan();
	if (error) {
		fprintf(stderr, "%s:%d: could not start scanning (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(10);

	error = usb_wlan_cmd_get_scan_results();
	if (error) {
		fprintf(stderr, "%s:%d: could not get scan results (%d)\n",
			__func__, __LINE__, error);
		goto done;
	}

	sleep(10);

done:

	usb_wlan_cmd_thread_done = 1;

	return NULL;
}

/*
 * main
 */
int main(int argc, char **argv)
{
	unsigned char buf[256];
	pthread_t tid;
	struct timeval tv;
	int error;

	pthread_mutex_init(&usb_wlan_cmd_mutex, NULL);
	pthread_cond_init(&usb_wlan_cmd_cond, NULL);

	error = libusb_init(&usb_ctx);
	if (error) {
		fprintf(stderr, "%s:%d: libusb_init failed (%d)\n", __func__, __LINE__, error);
		exit(1);
	}

	libusb_set_debug(usb_ctx, 5);

	usb_dev_handle = libusb_open_device_with_vid_pid(usb_ctx, USB_VENDOR_ID, USB_PRODUCT_ID);
	if (!usb_dev_handle) {
		fprintf(stderr, "%s:%d: could not open device\n", __func__, __LINE__);
		exit(1);
	}

	if(libusb_kernel_driver_active(usb_dev_handle, USB_IFACE_NUMBER)) {
		fprintf(stdout, "%s:%d: kernel driver is attached\n", __func__, __LINE__);

		error = libusb_detach_kernel_driver(usb_dev_handle, USB_IFACE_NUMBER);
		if (error) {
			fprintf(stderr, "%s:%d: could not detach kernel driver (%d)\n",
				__func__, __LINE__, error);
			exit(1);
		}

		fprintf(stdout, "%s:%d: kernel driver dettached\n", __func__, __LINE__);
	}

	error = libusb_claim_interface(usb_dev_handle, USB_IFACE_NUMBER);
	if (error) {
		fprintf(stderr, "%s:%d: could not claim interface (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	error = libusb_control_transfer(usb_dev_handle, 0x40, 0x1, 0x9, 0x0,
		usb_magic_data, sizeof(usb_magic_data), 0);
	if (error < 0) {
		fprintf(stderr, "%s:%d: could not do control transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	fprintf(stdout, "%s:%d: number of bytes transferred (%d)\n", __func__, __LINE__, error);

	error = libusb_control_transfer(usb_dev_handle, 0xc0, 0x0, 0x2, 0x0, buf, 2, 0);
	if (error < 0) {
		fprintf(stderr, "%s:%d: could not do control transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	fprintf(stdout, "%s:%d: number of bytes received (%d)\n", __func__, __LINE__, error);

	fprintf(stdout, "%s:%d: 0x%02x 0x%02x\n", __func__, __LINE__, buf[0], buf[1]);

	usb_intr_transfer_ep5_in = libusb_alloc_transfer(0);
	if (!usb_intr_transfer_ep5_in) {
		fprintf(stderr, "%s:%d: could not allocate transfer\n", __func__, __LINE__);
		exit(1);
	}

	memset(usb_intr_transfer_ep5_in_buf, 0, sizeof(usb_intr_transfer_ep5_in_buf));

	libusb_fill_interrupt_transfer(usb_intr_transfer_ep5_in, usb_dev_handle, LIBUSB_ENDPOINT_IN | 0x5,
		usb_intr_transfer_ep5_in_buf, sizeof(usb_intr_transfer_ep5_in_buf),
		usb_intr_transfer_ep5_in_cb, NULL, 0);

	error = libusb_submit_transfer(usb_intr_transfer_ep5_in);
	if (error) {
		fprintf(stderr, "%s:%d: could not submit transfer (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	error = pthread_create(&tid, NULL, usb_wlan_cmd_thread, NULL);
	if (error) {
		fprintf(stderr, "%s:%d: could not create WLAN command thread (%d)\n",
			__func__, __LINE__, error);
		exit(1);
	}

	while (!usb_wlan_cmd_thread_done) {
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		error = libusb_handle_events_timeout(usb_ctx, &tv);
		if (error) {
			fprintf(stderr, "%s:%d: could not handle events (%d)\n",
				__func__, __LINE__, error);
			exit(1);
		}
	}

	libusb_free_transfer(usb_intr_transfer_ep5_in);

	error = libusb_release_interface(usb_dev_handle, USB_IFACE_NUMBER);
	if (error)
		fprintf(stderr, "%s:%d: could not release interface (%d)\n",
			__func__, __LINE__, error);

	libusb_close(usb_dev_handle);

	libusb_exit(usb_ctx);

	exit(0);
}

Output

glevand@debian-hdd:~/ps3_usb_wlan$ sudo ./ps3_usb_wlan 
sudo: unable to resolve host debian-hdd
main:824: number of bytes transferred (32)
main:833: number of bytes received (2)
main:835: 0x20 0x31
usb_wlan_cmd_send:288: sending command (0x114f) data size (0x0518) command size (0x0524)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1150)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0006)
usb_handle_wlan_cmd_response:205: ==> command status != 0x1
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1171) data size (0x0000) command size (0x000c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1172)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 00 04 00 00 10 00 00 00 3c 22 02 00 00 00 00 00 |........<"......|
00000010: fc 90 02 c0 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x116f) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1170)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x115b) data size (0x005e) command size (0x006a)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x115c)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1161) data size (0x0020) command size (0x002c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1162)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x110d) data size (0x0080) command size (0x008c)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110e)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_wlan_cmd_send:288: sending command (0x1031) data size (0x0002) command size (0x000e)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (38)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1032)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0002)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 00                                           |..              |
usb_wlan_cmd_send:288: sending command (0x1041) data size (0x0006) command size (0x0012)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (42)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1042)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0006)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 11 22 33 44 55                               |.."3DU          |
usb_wlan_cmd_send:288: sending command (0x0029) data size (0x0002) command size (0x000e)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (38)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x002a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0002)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 02 02                                           |..              |
usb_wlan_cmd_send:288: sending command (0x110b) data size (0x000c) command size (0x0018)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (48)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110c)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x000c)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00 00 00 00 00 20 00 00 00             |........ ...    |
usb_wlan_cmd_send:288: sending command (0x1109) data size (0x0016) command size (0x0022)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (58)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x110a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0016)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00 15 27 12 00 06 00 00 00 09 00 01 00 |.....'..........|
00000010: ff ff ff ff ff ff                               |......          |
usb_wlan_cmd_send:288: sending command (0x0207) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (40)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x0208)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0004)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 01 00 00 00                                     |....            |
usb_wlan_cmd_send:288: sending command (0x0203) data size (0x0004) command size (0x0010)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (40)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x0204)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0004)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 04 00 00 00                                     |....            |
usb_wlan_cmd_send:288: sending command (0x105f) data size (0x000a) command size (0x0016)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (36)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1060)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0000)
usb_handle_wlan_cmd_response:210: command payload:
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 80 00 00 00 00 10 00 00 9e 2b 02 00 04 00 00 00 |.........+......|
00000010: fc 90 02 c0 01 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x0099) data size (0x003e) command size (0x004a)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (98)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x009a)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x003e)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 4a 55 50 49 54 45 52 2d 54 57 4f 2d 46 57 2d 32 |JUPITER-TWO-FW-2|
00000010: 30 2e 30 2e 31 32 2e 70 30 28 4a 61 6e 20 31 39 |0.0.12.p0(Jan 19|
00000020: 20 32 30 31 30 20 32 31 3a 32 30 3a 35 33 29 00 | 2010 21:20:53).|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00       |..............  |
usb_wlan_cmd_send:288: sending command (0x1035) data size (0x0019) command size (0x0025)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (61)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1036)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0019)
usb_handle_wlan_cmd_response:210: command payload:
00000000: 00 01 64 00 00 00 00 00 00 00 03 0d 01 02 03 04 |..d.............|
00000010: 05 06 07 08 09 0a 0b 0c 0d                      |.........       |
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (68)
usb_handle_wlan_event:133: === got WLAN event ===
usb_handle_wlan_event:144: event_count (0x01)
00000000: 80 00 00 00 04 00 00 00 96 2e 02 00 01 00 00 00 |................|
00000010: fc 90 02 c0 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020: 13 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 |... ............|
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
usb_wlan_cmd_send:288: sending command (0x1033) data size (0x05b0) command size (0x05bc)
usb_intr_transfer_ep5_in_cb:233: === got interrupt transfer ===
usb_intr_transfer_ep5_in_cb:236: transfer status (0) length (1403)
usb_handle_wlan_cmd_response:158: === got WLAN command response ===
usb_handle_wlan_cmd_response:191: command header:
usb_handle_wlan_cmd_response:192: command (0x1034)
usb_handle_wlan_cmd_response:199: tag (0xcafe)
usb_handle_wlan_cmd_response:201: status (0x0001)
usb_handle_wlan_cmd_response:207: payload_size (0x0557)
usb_handle_wlan_cmd_response:210: command payload:
...
Here is scan output (removed by me)
...

Associate with AP

How to Associate with WPA AP

Packet Reception

Test with libusb

usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (98)
00000000: ff ff ff ff ff ff ?? ?? ?? ?? ?? ?? 08 00 45 00 |..............E.|
00000010: 00 54 00 00 40 00 40 01 b5 fe c0 a8 01 5b c0 a8 |.T..@.@......[..|
00000020: 01 ff 08 00 9c 69 0d 45 00 e2 4e 5d 34 26 00 07 |.....i.E..N]4&..|
00000030: df e1 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 |................|
00000040: 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 |.......... !"#$%|
00000050: 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 |&'()*+,-./012345|
00000060: 36 37                                           |67              |
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 |................|
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 |................|
usb_bulk_transfer_ep6_in_cb:318: === got data transfer ===
usb_bulk_transfer_ep6_in_cb:321: transfer status (0) length (16)
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 |................|

Multicast Address Filter

MAC Address Hash Function
unsigned char hash(unsigned char *data, unsigned int size)
{
        unsigned int hash;
        int i, j;

        /*XXX: reverse data bits */

        hash = 0xffffffff;

        for (i = 0; i < size; i++) {
                hash = (((unsigned int) data[i]) << 24) ^ hash;

                for (j = 0; j < 8; j++) {
                        if (((int) hash) >= 0) {
                                hash = hash << 1;
                        } else {
                                hash = (hash << 1) ^ 0x04c10000;
                                hash = hash ^ 0x00001db7;
                        }
                }
        }

        hash = ((hash >> 24) & 0xf8) | (hash & 0x7);

        return hash & 0xff;
}

h = hash(mac_addr, 6);
v = 1 << (h & 0x1f);    /* word value in filter */
p = h >> 5;             /* word position in filter */


For broadcast address:
------------------------

v = 0x20000000
p = 7

That's why 0x20 is used with command 0x1161 !!! Without it the device won't deliver broadcast traffic.
Learned it the hard way, after 2 days of trying to get packet reception working :)

LV2 Network Stack

LV2 Network Packet

RSX

Crossreference: gitbrew.org::RSX


HV Calls

lv1_gpu_context_attribute

Attribute 0x1

FIFO Command Buffer Setup
lv1_gpu_context_attribute(context handle, 0x1, PUT offset, GET offset, 0x0, 0x0)

Attribute 0x101

Set Flip Mode
lv1_gpu_attribute(0x2, ???, 0x0, 0x0)
lv1_gpu_context_attribute(context handle, 0x101, ???, sync mode, 0x0, 0x0)

Attribute 0x104

Set Display Buffer
lv1_gpu_context_attribute(context handle, 0x104, id, width << 32 | height, pitch << 32 | offset, 0x0)

Attribute 0x10a

Reset Flip Status
lv1_gpu_context_attribute(context handle, 0x10a, id, 0x7fffffff /* mask */, 0x0 /* value */, 0x0)

Attribute 0x300

Set Tile
Set Invalidate Tile
Bind Tile
Unbind Tile

Attribute 0x301

Set Zcull
Bind Zcull
Unbind Zcull

FIFO Command Buffer

FIFO Control Registers

Kicking FIFO Command Buffer

FIFO Setup Program of emer_init.self

0x42000
0x31337303

0xC2180
0x66604200
0xFEED0001
0xFEED0000

0x46000
0x313371C3

0xC6180
0x66604200
0xFEED0000
0xFEED0000

0x4A000
0x31337808

0x20A180
0x66604200
0x0
0x0
0x0
0x0
0x0
0x0
0x313371C3

0x8A2FC
0x3
0x4

0x88180
0x66604200
0xFEED0000

0x4C000
0x3137AF00

0x4C180
0x66604200

Example How to Use FIFO Command Buffer

Here is a small Linux kernel module which shows you how to use FIFO command buffer on Linux.

Download source code: [4]

Source Code

/*
 * PS3 RSX
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/delay.h>

#include <asm/abs_addr.h>
#include <asm/cell-regs.h>
#include <asm/lv1call.h>
#include <asm/ps3.h>

#define RSX_FIFO_CMD_BUF_SIZE	(1 * 1024 * 1024)

#define RSX_MEM_SIZE		(32 * 1024 * 1024)

#define RSX_GPU_IOIF		(0x0e000000ul)

#define RSX_FIFO_CTRL_SIZE	(4 * 1024)

struct rsx_fifo_ctrl {
	u8 res[0x40];
	u32 put;
	u32 get;
};

static u32 *rsx_fifo_cmd_buf;
static u64 rsx_fifo_cmd_buf_lpar;

static u64 rsx_mem_handle, rsx_mem_lpar;
static u64 rsx_ctx_handle;
static u64 rsx_fifo_ctrl_lpar;
static u64 rsx_drv_info_lpar;
static u64 rsx_reports_lpar, rsx_reports_size;

static struct rsx_fifo_ctrl *rsx_fifo_ctrl;

/*
 * FIFO program
 */
static u32 rsx_fifo_prg[] = {
	0x00000000, /* nop */
	0x00000000, /* nop */
	0x00000000, /* nop */
};

/*
 * ps3rsx_init
 */
static int __init ps3rsx_init(void)
{
	unsigned long timeout;
	int res;

	/* FIFO command buffer must be allocated in XDR memory */

	rsx_fifo_cmd_buf = kmalloc(RSX_FIFO_CMD_BUF_SIZE, GFP_KERNEL);
	if (!rsx_fifo_cmd_buf) {
		printk(KERN_INFO"could not allocate FIFO command buffer\n");
		res = -ENOMEM;
		goto fail;
	}

	res = lv1_gpu_memory_allocate(RSX_MEM_SIZE, 0, 0, 0, 0,
		&rsx_mem_handle, &rsx_mem_lpar);
	if (res) {
		printk(KERN_INFO"lv1_gpu_memory_allocate failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_fifo_cmd_buf_mem;
	}

	res = lv1_gpu_context_allocate(rsx_mem_handle, 0,
		&rsx_ctx_handle, &rsx_fifo_ctrl_lpar, &rsx_drv_info_lpar,
		&rsx_reports_lpar, &rsx_reports_size);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_allocate failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}
	
	/* map FIFO command buffer into RSX address space */

	rsx_fifo_cmd_buf_lpar = ps3_mm_phys_to_lpar(__pa(rsx_fifo_cmd_buf));

	res = lv1_gpu_context_iomap(rsx_ctx_handle,
		RSX_GPU_IOIF, rsx_fifo_cmd_buf_lpar, RSX_FIFO_CMD_BUF_SIZE,
		CBE_IOPTE_PP_W | CBE_IOPTE_PP_R | CBE_IOPTE_M);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_iomap failed (%d)\n", res);
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}

	/* map RSX FIFO control registers */

	rsx_fifo_ctrl = (struct rsx_fifo_ctrl *) ioremap(rsx_fifo_ctrl_lpar, RSX_FIFO_CTRL_SIZE);
	if (!rsx_fifo_ctrl) {
		printk(KERN_INFO"could not map FIFO control\n");
		res = -ENXIO;
		goto fail_free_gpu_mem;
	}

	/* PUT and GET offsets are in RSX address space */

	res = lv1_gpu_context_attribute(rsx_ctx_handle, 0x1,
		RSX_GPU_IOIF + 0x0 /* PUT offset */, RSX_GPU_IOIF + 0x0 /* GET offset */,
		0x0, 0x0);
	if (res) {
		printk(KERN_INFO"lv1_gpu_context_attribute(0x1) failed (%d)\n", res);
		res = -ENXIO;
		goto fail_unmap_fifo_ctrl;
	}

	/* copy FIFO commands to FIFO command buffer */

	memcpy(rsx_fifo_cmd_buf, rsx_fifo_prg, sizeof(rsx_fifo_prg));

	printk(KERN_INFO"GET offset (0x%08x) PUT offset (0x%08x)\n", rsx_fifo_ctrl->get, rsx_fifo_ctrl->put);

	/* kick FIFO */

	rsx_fifo_ctrl->put = RSX_GPU_IOIF + sizeof(rsx_fifo_prg);

	/* poll until RSX is done processing FIFO commands */

	timeout = 100;

	while (timeout--) {
		if (rsx_fifo_ctrl->get == rsx_fifo_ctrl->put)
			break;

		msleep(1);
	}

	printk(KERN_INFO"GET offset (0x%08x) PUT offset (0x%08x)\n", rsx_fifo_ctrl->get, rsx_fifo_ctrl->put);

	if (rsx_fifo_ctrl->get != rsx_fifo_ctrl->put) {
		printk(KERN_INFO"FIFO command buffer timeout\n");
		res = -ENXIO;
		goto fail_unmap_fifo_ctrl;
	}

	return 0;

fail_unmap_fifo_ctrl:

	iounmap(rsx_fifo_ctrl);


fail_free_gpu_mem:

	lv1_gpu_memory_free(rsx_mem_handle);

fail_free_fifo_cmd_buf_mem:

	kfree(rsx_fifo_cmd_buf);

fail:

	return res;
}

/*
 * ps3rsx_exit
 */
static void __exit ps3rsx_exit(void)
{
	iounmap(rsx_fifo_ctrl);

	lv1_gpu_context_iomap(rsx_ctx_handle, RSX_GPU_IOIF, rsx_fifo_cmd_buf_lpar,
		RSX_FIFO_CMD_BUF_SIZE, CBE_IOPTE_M);

	lv1_gpu_context_free(rsx_ctx_handle);

	lv1_gpu_memory_free(rsx_mem_handle);

	kfree(rsx_fifo_cmd_buf);
}

module_init(ps3rsx_init);
module_exit(ps3rsx_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PS3 RSX");
MODULE_AUTHOR("glevand");

Test

# insmod ./ps3rsx.ko
# dmesg

GET offset (0x0e000000) PUT offset (0x0e000000)  # GET and PUT offsets before kicking FIFO
GET offset (0x0e00000c) PUT offset (0x0e00000c)  # GET and PUT offsets after kicking FIFO

As you see, RSX processed our FIFO commands :)

BD Drive

Crossreference: gitbrew.org::HV#BD Drive


Profile

Profile Table

Profile Description
0x0 No Current Profile
0x2 Removable Disk
0x8 CD-ROM
0x9 CD-R
0xa CD-RW
0x10 DVD-ROM
0x11 DVD-R Sequential recording
0x12 DVD-RAM
0x13 DVD-RW Restricted Overwrite
0x14 DVD-RW Sequential recording
0x1a DVD+RW
0x1b DVD+R
0x40 BD-ROM
0x41 BD-R Sequential Recording(TBD)
0x42 BD-R Random Recording(TBD)
0x43 BD-RE
0x50 PS1 CD-ROM
0x60 PS2 CD-ROM
0x61 PS2 DVD-ROM
0x70 PS3 DVD-ROM
0x71 PS3 BD-ROM
0x10000 CD-DA
0x20000 SACD
0x100000 Dual Layer (Parallel)
0x200000 Dual Layer (else Parallel)

Buffer

Buffer Table

ID Size Description
0x0 0x8000 Used to transfer firmware to BD drive
0x1 0x800 Serial Flash
0x2 0x60 P-Block
0x3 0x670 S-Block
0x4 0x8000 Host Revocation List (HRL) Empty
0x5 0x8000 Host Revocation List (HRL) Current
0x6 0x670 S-Block
0x7 0x8000 Host Revocation List (HRL)

HRL Buffer

Device Commands

Get Profile (0x11)

Auto Request Sense Mode On/Off (0x30)

SCSI Commands

Get Configuration

Getting the profile of a BD movie disc:

# sg_raw -r 0x8 /dev/sr0 46 02 00 00 00 00 00 00 08 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 00 00 38 00 00 00 40                             ...8...@   

# 0x40 means BD-ROM

Getting the profile of a PS3 game disc:

# sg_raw -r 0x8 /dev/sr0 46 02 00 00 00 00 00 00 08 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 00 00 38 00 00 ff 71                             ...8...q 
 
# 0x71 means PS3 BD-ROM

Get SS Key

Test with PS3 game disc:

# sg_raw -r 8 /dev/sr0 a4 00 00 00 00 00 00 e0 00 08 03 00
SCSI Status: Good 

Sense Information:
sense buffer empty

Received 8 bytes of data:
 00     00 06 00 00 00 00 00 04                             ........        

Eject Media

sg_raw /dev/sr0 0x1b 00 00 00 02 00

Load Media

sg_raw /dev/sr0 0x1b 00 00 00 03 00

Mode Select 10

Enable Buffer Write

Test with sg3-utils which enables write to HRL buffer:

sg_raw /dev/sr0 55 10 00 00 00 00 00 00 10 00 00 0e 00 00 00 00 00 00 2d 06 04 00 00 00 00 00

Write Buffer

AACS

AACS SPU Module

Communication

Commands

Read 4 Bytes from XDR Buffer (0x2)
Set KCD (0x1e)
Init AES_H (0x34)
Calculate AES_H 1 (0x35)
Calculate AES_H 2 (0x36)
Generate Host Nonce (0x3c)
Get Host Nonce and Certificate (0x3d)
Set Drive Nonce and Certificate (0x3e)
Verify Drive Certificate (0x3f)
Set Drive Key (0x40)
Sign Host Key (0x44)
Get Host Key (0x45)
Calculate Bus Key (0x46)
Set Volume ID (0x47)
Calculate Volume ID MAC (0x48)
Verify Volume ID MAC (0x49)
Set PMSN (0x4a)
Calculate PMSN MAC (0x4b)
Verify PMSN (0x4c)
Set Media ID (0x4d)
Calculate Media ID MAC (0x4e)
Verify Media ID MAC (0x4f)
Unknown (0x54)
Verify Host/Drive Revocation (0x55)
Terminate Session (0xfefefeff)

Drive Revocation List (DRL)

Content Revocation List (CRL)

Host Revocation List (HRL)

Read HRL from BD Drive Flash

Empty HRL

# sg_read_buffer -m 2 -i 4 -o 0 -l $((0x40)) /dev/sr0 
 00     10 00 00 0c 00 03 10 03  00 00 00 01 21 00 00 34                    
 10     00 00 00 00 00 00 00 00  1b 0b f2 6d 47 9e 77 62                    
 20     3d 91 fc 78 b1 59 c9 52  ca a4 c7 41 85 24 96 64                    
 30     8d 1d 95 8e 9b 84 c6 fa  4a dd 43 9b 42 98 fe ff  

# byte 0x21 at offset 0xc means Record Type HRL

# as you see this HRL is empty

Current HRL

# sg_read_buffer -m 2 -i 5 -o 0 -l $((0x7c)) /dev/sr0 
 00     10 00 00 0c 00 04 10 03  00 00 00 09 21 00 00 6c                    
 10     00 00 00 07 00 00 00 07  00 09 ff ff 00 00 00 0b                    
 20     00 00 ff ff 00 00 00 16  00 08 ff ff 00 00 00 21                    
 30     00 03 ff ff 00 00 00 35  00 04 ff ff 00 00 00 4e                    
 40     00 03 ff ff 00 00 00 54  00 03 ff ff 00 00 00 5e                    
 50     80 93 3a 62 f5 5a 9c 8c  62 ce 7d b8 69 5d d7 b1                    
 60     c3 0f 36 ff 96 a2 3b 32  cb cd 58 d4 12 c9 fd bf                    
 70     f5 16 a6 4a 32 ba 60 f0  5d 71 74 10 

# the current HRL is NOT empty and is from MKBv9 because the only BD movie i played on my PS3 has MKBv9

PS3 BD Player Host Certificate

$ hexdump -C aacs_auth/ps3_host_cert.bin 
00000000  02 01 00 5c ff ff 80 00  00 39 00 00 65 ea c9 87  |...\ÿÿ...9..eêÉ.|
00000010  8b 85 ef f4 d7 7a 62 b1  d6 00 02 4a ce 68 dd 33  |..ïô×zb±Ö..JÎhÝ3|
00000020  66 88 0e 4f 84 4f 34 b7  7a 05 01 35 a2 0e 73 b6  |f..O.O4·z..5¢.s¶|
00000030  26 da ea 51 57 b3 2e b8  4b c6 e8 7b 0d ee 4d 83  |&ÚêQW³.žKÆè{.îM.|
00000040  3c ea da 86 12 01 51 00  2c 3c 66 d5 25 6f 71 cf  |<êÚ...Q.,<fÕ%oqÏ|
00000050  a6 8b 7e 55 ba 1b 35 1f  34 03 43 4e              |Š.~Uº.5.4.CN|
0000005c

# Host ID is 0xffff80000039

PS3 BD Player Host Private Key

$ hexdump -C aacs_auth/ps3_host_priv_key.bin 
00000000  00 66 8c 9a 75 ee fc 8d  a4 26 19 38 e2 71 28 50  |.f..u....&.8.q(P|
00000010  61 bb 09 f0 dd                                    |a....|

AACS Processing Keys

MKB v1

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v1.inf

=MKB=
type:
0x00031003
version:
0x00000001

MKB U masks and UVs: 514

=applying subset-difference=
index: 0
UV: 0x00000001
U mask: 0xff800000
V mask: 0xfffffffe

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 09 f9 11 02 9d 74 e3 5b d8 41 56 c5 63 56 88 c0 |.....t.[.AV.cV..|

C value:
00000000: cb 06 90 db e6 54 55 7b 12 62 aa d7 89 f4 9d 92 |.....TU{.b......|

media key:
00000000: b4 6c 48 5e f7 51 ae 29 ef 87 bc 58 28 f3 2a 8d |.lH^.Q.)...X(.*.|

=MKB verify media key data=
encrypted:
00000000: 46 32 5b 42 48 b4 86 5a fc ef 75 25 47 b1 b5 12 |F2[BH..Z..u%G...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 0d ac 14 b9 ee f4 bd cc |.#Eg............|

MKB v3

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v3.inf

=MKB=
type:
0x00031003
version:
0x00000003

MKB U masks and UVs: 528

=applying subset-difference=
index: 14
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 0a b7 33 82 85 62 91 d1 91 4a 95 9e 36 18 c7 a1 |..3..b...J..6...|

media key:
00000000: 6e da eb d4 88 aa 38 58 74 26 35 fd fd 36 66 d5 |n.....8Xt&5..6f.|

=MKB verify media key data=
encrypted:
00000000: 99 76 96 b0 6f 49 37 9b c4 b9 2b be 73 ce 96 1a |.v..oI7...+.s...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef fb 01 cc 85 eb e5 bf 0a |.#Eg............|

MKB v4

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v4.inf

=MKB=
type:
0x00031003
version:
0x00000004

MKB U masks and UVs: 526

=applying subset-difference=
index: 12
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: bf 71 0c 8b 46 a0 24 d8 f0 3a a1 26 37 9d fb fc |.q..F.$..:.&7...|

media key:
00000000: ef 18 c0 dd bf 02 32 a1 2f 57 f7 65 79 2c 1c 58 |......2./W.ey,.X|

=MKB verify media key data=
encrypted:
00000000: 54 85 08 a9 6a 70 2a c9 32 e3 74 a6 55 78 6c 01 |T...jp*.2.t.Uxl.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef da 90 cf 2a e5 b2 6c 45 |.#Eg.......*..lE|

MKB v7

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v7.inf

=MKB=
type:
0x00031003
version:
0x00000007

MKB U masks and UVs: 526

=applying subset-difference=
index: 7
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 21 fd c9 4b 3e 1a f3 fe 9e b4 7a e6 ef 01 75 1b |!..K>.....z...u.|

media key:
00000000: af cd e2 c8 67 12 a4 b6 a8 58 0c 15 ef 07 6e f8 |....g....X....n.|

=MKB verify media key data=
encrypted:
00000000: 4b 21 29 a5 0f db 96 bc bc 01 04 71 42 79 00 e5 |K!)........qBy..|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 4e f9 d2 05 6e 19 c1 79 |.#Eg....N...n..y|

MKB v8

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v8.inf

=MKB=
type:
0x00031003
version:
0x00000008

MKB U masks and UVs: 523

=applying subset-difference=
index: 4
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 73 2d 10 bd f8 b4 87 e2 86 a6 d5 3a 6d db 69 15 |s-.........:m.i.|

media key:
00000000: dd 46 d4 0d 26 54 5a ce 6c 59 0c 65 b7 2b 3a 9f |.F..&TZ.lY.e.+:.|

=MKB verify media key data=
encrypted:
00000000: c6 f6 f9 54 ce 90 e0 5e 2b 3b e4 1e 24 92 90 b2 |...T...^+;..$...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 97 e6 61 8b d1 69 3e a0 |.#Eg......a..i>.|

MKB v9

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v9.inf

=MKB=
type:
0x00031003
version:
0x00000009

MKB U masks and UVs: 520

=applying subset-difference=
index: 2
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: a4 5a c6 87 43 49 70 bb bf 0c 22 52 83 9e 2a f6 |.Z..CIp..."R..*.|

media key:
00000000: 37 02 bd fc 96 dc a2 18 2e 55 b0 79 6d ad 36 6b |7........U.ym.6k|

=MKB verify media key data=
encrypted:
00000000: 4d 5b 7b 9c 5d ee 55 a6 94 de e1 db 8d 08 c7 a2 |M[{.].U.........|
decrypted:
00000000: 01 23 45 67 89 ab cd ef cd 1d a8 8a 42 5a 10 43 |.#Eg........BZ.C|

MKB v10

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v10.inf

=MKB=
type:
0x00031003
version:
0x0000000a

MKB U masks and UVs: 522

=applying subset-difference=
index: 3
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: d4 77 dd 1a 8a 5c 6d d1 dd 31 2d af f7 d3 14 fa |.w...\m..1-.....|

media key:
00000000: 38 32 2b 3c 61 b0 35 b4 52 89 84 59 f4 7a 76 e6 |82+<a.5.R..Y.zv.|

=MKB verify media key data=
encrypted:
00000000: 3f d3 d5 fb 42 37 d9 05 b8 db 6b 03 a0 fe 2e 48 |?...B7....k....H|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 65 b1 87 8c eb 0d 60 0f |.#Eg....e.....`.|

MKB v12

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v12.inf

=MKB=
type:
0x00031003
version:
0x0000000c

MKB U masks and UVs: 522

=applying subset-difference=
index: 3
UV: 0x00000080
U mask: 0xff800000
V mask: 0xffffff00

=applying device key=
index: 244
UV: 0x00000100
U mask: 0xff800000
V mask: 0xfffffe00
device key:
00000000: 81 08 27 a7 6e 5b 2c c1 68 5e 32 17 a2 3e 21 86 |..'.n[,.h^2..>!.|

processing key:
00000000: 97 39 40 bb 18 0e 83 26 62 31 ee 59 6c ef 65 b2 |.9@....&b1.Yl.e.|

C value:
00000000: 89 75 89 e6 6f 4a de 95 11 32 57 6a cb 99 dd 69 |.u..oJ...2Wj...i|

media key:
00000000: 4b dd 69 9d 32 98 d7 b0 ad 32 71 6b 3d 9c e3 c2 |K.i.2....2qk=...|

=MKB verify media key data=
encrypted:
00000000: 8d 43 fd f2 15 fa 58 78 64 db 25 46 62 ab 02 30 |.C....Xxd.%Fb..0|
decrypted:
00000000: 01 23 45 67 89 ab cd ef e6 1c bf 98 45 82 64 d9 |.#Eg........E.d.|

MKB v14

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v14.inf

=MKB=
type:
0x00031003
version:
0x0000000e

MKB U masks and UVs: 526

=applying subset-difference=
index: 6
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: 8c 7e 31 e8 15 17 7e c3 2c 67 b7 cc 87 e9 39 c3 |.~1...~.,g....9.|

media key:
00000000: 4b b1 31 d1 6e 0e 86 45 89 07 a2 68 91 c4 e5 38 |K.1.n..E...h...8|

=MKB verify media key data=
encrypted:
00000000: 20 03 8c 70 7d ab d0 6f ba 86 39 f0 31 26 86 5f | ..p}..o..9.1&._|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 27 9f e5 35 0b df 3d a5 |.#Eg....'..5..=.|

MKB v15

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v15.inf

=MKB=
type:
0x00031003
version:
0x0000000f

MKB U masks and UVs: 527

=applying subset-difference=
index: 6
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: 75 da 59 cf 0d c2 c0 95 86 fc 6b 8e 2e e9 cc 85 |u.Y.......k.....|

media key:
00000000: 28 46 25 38 3d cc 4f 1f 90 be 7d f7 8a ba 7b fd |(F%8=.O...}...{.|

=MKB verify media key data=
encrypted:
00000000: 8d d2 69 e0 b7 6a 44 53 03 ad ef 58 44 fc a7 d7 |..i..jDS...XD...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef ff 6a 7d c3 17 bb 19 11 |.#Eg.....j}.....|

MKB v16

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v16.inf

=MKB=
type:
0x00031003
version:
0x00000010

MKB U masks and UVs: 531

=applying subset-difference=
index: 5
UV: 0x00000248
U mask: 0xfffffe00
V mask: 0xfffffff0

=applying device key=
index: 28
UV: 0x00000280
U mask: 0xfffffe00
V mask: 0xffffff00
device key:
00000000: 44 14 5a 84 6f 19 d0 96 f2 c8 4a 2e 50 c5 c4 f5 |D.Z.o.....J.P...|

processing key:
00000000: 58 eb da df 88 dc c9 33 04 cb be db 9e e0 95 f6 |X......3........|

C value:
00000000: f8 49 9b d1 32 f9 6e 8d 33 98 35 a8 54 80 d9 fe |.I..2.n.3.5.T...|

media key:
00000000: 3a bf bf d7 7e b8 01 43 a9 3c 15 3f ba 47 8c e1 |:...~..C.<.?.G..|

=MKB verify media key data=
encrypted:
00000000: 8a 67 86 b6 9d 0d 22 dd 5d c2 88 1f 08 f3 ab b4 |.g....".].......|
decrypted:
00000000: 01 23 45 67 89 ab cd ef d6 32 1f 17 c4 2f e2 4a |.#Eg.....2.../.J|

MKB v17

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v17.inf

=MKB=
type:
0x00031003
version:
0x00000011

MKB U masks and UVs: 540

=applying subset-difference=
index: 14
UV: 0x00000308
U mask: 0xffffff00
V mask: 0xfffffff0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: 46 5f a8 be 82 85 09 01 4d 05 d2 fc ce ff 35 d2 |F_......M.....5.|

C value:
00000000: 01 f7 54 0b 34 e8 c1 ce 63 8d ea fa bc ce 6e 7b |..T.4...c.....n{|

media key:
00000000: ef 63 4e a8 ca 06 d1 6a c7 21 65 1b 18 b3 04 c6 |.cN....j.!e.....|

=MKB verify media key data=
encrypted:
00000000: d3 b9 d4 9c b6 94 47 d5 3d cc 42 fe 3e 47 40 04 |......G.=.B.>G@.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef f6 b4 c8 6a b7 b8 39 fc |.#Eg.......j..9.|

MKB v18

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v18.inf

=MKB=
type:
0x00031003
version:
0x00000012

MKB U masks and UVs: 543

=applying subset-difference=
index: 17
UV: 0x00000320
U mask: 0xffffff00
V mask: 0xffffffc0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: ad 5e 54 6c 46 d7 2d c0 83 ae b5 68 69 24 e1 b3 |.^TlF.-....hi$..|

C value:
00000000: 7a 8f 03 41 27 c4 86 58 05 37 3a 90 de f8 de 26 |z..A'..X.7:....&|

media key:
00000000: e3 ed cd b4 59 b4 12 d4 ae f9 4d 8e 78 7a cd 7d |....Y.....M.xz.}|

=MKB verify media key data=
encrypted:
00000000: ea 45 fa 35 65 70 56 6f 6a 86 65 ad 52 e7 71 a4 |.E.5epVoj.e.R.q.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef bd 36 f9 ce 60 54 80 3c |.#Eg.....6..`T.<|

MKB v19

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v19.inf

=MKB=
type:
0x00031003
version:
0x00000013

MKB U masks and UVs: 544

=applying subset-difference=
index: 17
UV: 0x00000320
U mask: 0xffffff00
V mask: 0xffffffc0

=applying device key=
index: 21
UV: 0x00000340
U mask: 0xffffff00
V mask: 0xffffff80
device key:
00000000: eb 55 a4 75 08 0f bc f1 85 34 ef a0 83 9a 73 73 |.U.u.....4....ss|

processing key:
00000000: ad 5e 54 6c 46 d7 2d c0 83 ae b5 68 69 24 e1 b3 |.^TlF.-....hi$..|

C value:
00000000: b9 0b 55 d1 18 3c cc 80 20 1c 9f 26 c3 58 27 18 |..U..<.. ..&.X'.|

media key:
00000000: 75 a9 79 9c 67 50 13 89 98 62 34 5b eb 54 34 dd |u.y.gP...b4[.T4.|

=MKB verify media key data=
encrypted:
00000000: c4 f0 ce 75 1b 12 b9 f0 22 2f 31 70 66 a9 6a b8 |...u...."/1pf.j.|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 66 5c 65 d3 c4 4c c7 b0 |.#Eg....f\e..L..|

MKB v20

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v20.inf

=MKB=
type:
0x00031003
version:
0x00000014

MKB U masks and UVs: 544

=applying subset-difference=
index: 19
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8

=applying device key=
index: 18
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8
device key:
00000000: fb 4a c3 90 09 e8 21 13 d4 5e cf 4b 7e ae a4 67 |.J....!..^.K~..g|

processing key:
00000000: 53 fc e7 8e cd 35 2d a5 0d 52 6b 5e e3 d3 d9 6b |S....5-..Rk^...k|

C value:
00000000: 10 9f f1 69 36 07 7d 7e ad 8f d2 1a 28 c5 09 ed |...i6.}~....(...|

media key:
00000000: dc 9f 08 f7 cb 1b f8 c4 cf 96 4e 96 df 23 56 58 |..........N..#VX|

=MKB verify media key data=
encrypted:
00000000: 18 ca f5 51 8f 36 ef 2f 7a 49 78 ff 54 40 a5 f1 |...Q.6./zIx.T@..|
decrypted:
00000000: 01 23 45 67 89 ab cd ef c5 5d 11 08 c3 26 db 48 |.#Eg.....]...&.H|

MKB v21

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v21.inf

=MKB=
type:
0x00031003
version:
0x00000015

MKB U masks and UVs: 552

=applying subset-difference=
index: 19
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8

=applying device key=
index: 18
UV: 0x00000384
U mask: 0xffffff80
V mask: 0xfffffff8
device key:
00000000: fb 4a c3 90 09 e8 21 13 d4 5e cf 4b 7e ae a4 67 |.J....!..^.K~..g|

processing key:
00000000: 53 fc e7 8e cd 35 2d a5 0d 52 6b 5e e3 d3 d9 6b |S....5-..Rk^...k|

C value:
00000000: c0 0c fa bf f0 fe f2 32 77 19 db c4 d8 f8 60 c9 |.......2w.....`.|

media key:
00000000: 55 83 aa 69 ff 52 16 83 c2 93 b3 48 03 2a 57 38 |U..i.R.....H.*W8|

=MKB verify media key data=
encrypted:
00000000: 12 5b f2 75 c8 f8 05 6b 4f 31 a5 ea 4a 12 9f a9 |.[.u...kO1..J...|
decrypted:
00000000: 01 23 45 67 89 ab cd ef dc 46 45 b4 79 8d 4f 68 |.#Eg.....FE.y.Oh|

MKB v23

glevand@debian-hdd:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v23.inf 

=MKB=
type:
0x00031003
version:
0x00000017

MKB U masks and UVs: 556

=applying subset-difference=
index: 17
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8

=applying device key=
index: 7
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8
device key:
00000000: 8b f4 fb d9 1a 7f b7 db 85 76 d1 e5 a1 5a 85 44 |.........v...Z.D|

processing key:
00000000: c3 22 38 97 6f f4 4a 51 e2 d3 35 53 cf e8 57 72 |."8.o.JQ..5S..Wr|

C value:
00000000: f0 81 d4 93 aa b5 01 1a a7 ff 8e 18 8a 48 8a 2d |.............H.-|

media key:
00000000: 02 04 59 d0 7c b5 54 94 bf 46 9b 98 91 1e 43 1f |..Y.|.T..F....C.|

=MKB verify media key data=
encrypted:
00000000: 24 a1 27 f9 30 70 25 67 07 2f 2a d4 13 89 0d aa |$.'.0p%g./*.....|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 21 00 20 84 c4 5f 36 78 |.#Eg....!. .._6x|

MKB v25

glevand@bastion:~/aacs_proc_key$ ./aacs_proc_key -n 0x389 -k ps3_device_keys -u ps3_device_key_u_masks_uvs mkbs/MKB_RW_v25.inf

=MKB=
type:
0x00031003
version:
0x00000019

MKB U masks and UVs: 564

=applying subset-difference=
index: 13
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8

=applying device key=
index: 7
UV: 0x00000384
U mask: 0xffffffe0
V mask: 0xfffffff8
device key:
00000000: 8b f4 fb d9 1a 7f b7 db 85 76 d1 e5 a1 5a 85 44 |.........v...Z.D|

processing key:
00000000: c3 22 38 97 6f f4 4a 51 e2 d3 35 53 cf e8 57 72 |."8.o.JQ..5S..Wr|

C value:
00000000: 19 62 23 7d 81 01 c2 55 2f 36 20 1b 3e 69 40 10 |.b#}...U/6 .>i@.|

media key:
00000000: 70 b5 9f 35 86 5d 18 73 bb 80 c3 2b f7 41 f6 14 |p..5.].s...+.A..|

=MKB verify media key data=
encrypted:
00000000: 89 be 1e 1e b1 93 4c f2 2d ac c3 ce ed 10 07 f0 |......L.-.......|
decrypted:
00000000: 01 23 45 67 89 ab cd ef 3f 5d 87 7a 88 09 db c4 |.#Eg....?].z....|

Documentation

CSS

CSS SPU Module

Commands

Generate Host Challenge Key (0x3)
Set Drive Key1 (0x4)
Set Drive Challenge Key (0x5)
Calculate Host Key2 (0x6)
Get Host Key2 (0x7)
Set Disc Key (0x8)
Decrypt Sector (0xc)

CSS Salt

Obfuscated:

71 ED 3F A3 DA FE E4 94  40 8C

Clear text:

F4  10  45  A3  E2

PS3 DVD Player Key Index

0x69

Documentation

CPRM

Commands

4C Secret Constant (S-Box)

Documentation

Remarrying BD Drive on OtherOS++

fdm_spu_module.self

Block types

Type Description BD Drive Buffer ID
0x1 P-Block 0x2
0x2 S-Block 0x3

Remarrying

Preparations

P-Block

Creating
Sending to BD Drive

S-Block

Creating
Sending to BD Drive

HRL

Empty HRL
Sending to BD Drive

VTRM

Crossreference: gitbrew.org::HV#VTRM

VTRM Services

Store With Update (0x2003)

Retrieve (0x2005)

DRL and CRL Hashes

Test with ps3dm-utils:

# mount dev_flash3

glevand@debian-hdd:~/ps3dm-utils$ sudo mount /dev/ps3vflashe /mnt

# DRL SHA1 hash

glevand@debian-hdd:~/ps3dm-utils$ sha1sum /mnt/data-revoke/drl/DRL1
8f0652bc6162a240362f90f1b2e5405bb82ee502  /mnt/data-revoke/drl/DRL1

# CRL SHA1 hash

glevand@debian-hdd:~/ps3dm-utils$ sha1sum /mnt/data-revoke/crl/CRL1 
96791f41f9a76f4d895dd5820db108ec03d19250  /mnt/data-revoke/crl/CRL1

# Retrieve DRL and CRL SHA1 hashes from VTRM
# DRL hash is first and then follows CRL hash

glevand@debian-hdd:~/ps3dm-utils$ sudo ./ps3dm_vtrm -l 0x0 -p 0x1070000034000001 /dev/ps3dmproxy retrieve 0
0x8f 0x06 0x52 0xbc 0x61 0x62 0xa2 0x40 0x36 0x2f 0x90 0xf1 0xb2 0xe5 0x40 0x5b 0xb8 0x2e 0xe5 0x02
0x96 0x79 0x1f 0x41 0xf9 0xa7 0x6f 0x4d 0x89 0x5d 0xd5 0x82 0x0d 0xb1 0x08 0xec 0x03 0xd1 0x92 0x50
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Backup Flash (0x2012)

Test with ps3dm-utils:

# enable product mode

# ps3dm_um /dev/ps3dmproxy write_eprom 0x48c07 0x0
/dev/ps3dmproxy: SS retval 0

# ps3dm_vtrm /dev/ps3dmproxy  backup_flash 0 0x200 | hexdump -C
00000000  53 43 45 49 ff ff ff ff  ff ff ff ff ff ff ff ff  |SCEIÿÿÿÿÿÿÿÿÿÿÿÿ|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
*
00000200

# dd if=/dev/ps3nflasha bs=1 count=$((0x100)) skip=$((0xec0000)) | hexdump -C
00000000  53 43 45 49 ff ff ff ff  ff ff ff ff ff ff ff ff  |SCEIÿÿÿÿÿÿÿÿÿÿÿÿ|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|
*

Flash Address Size (0x2016)

Test with ps3dm-utils:

# ps3dm_um /dev/ps3dmproxy read_eprom 0x48c07
0xff

# ps3dm_vtrm /dev/ps3dmproxy  flash_addr_size
/dev/ps3dmproxy: SS retval 5

# enable product mode

# ps3dm_um /dev/ps3dmproxy write_eprom 0x48c07 0x0
/dev/ps3dmproxy: SS retval 0

# ps3dm_um /dev/ps3dmproxy read_eprom 0x48c07
0x00

# ps3dm_vtrm /dev/ps3dmproxy  flash_addr_size
0x0000000000000000 0x0000000000040000


Revoke List

Crossreference: gitbrew::Revoke List

LPAR 1 System Call 0x1004A

rvk_list_verifier

root@debian-hdd:/home/glevand/rvk_list_verifier# cat /proc/rvk_list_verifier/debug 
PPE id (0x0000000000000001) VAS id (0x0000000000000002)
lv1_construct_logical_spe (0x00000000)
SPE id (0x0000000000000033)
lv1_enable_logical_spe (0x00000000)
lv1_set_spe_interrupt_mask(0) (0x00000000)
lv1_set_spe_interrupt_mask(1) (0x00000000)
lv1_set_spe_interrupt_mask(2) (0x00000000)
lv1_set_spe_privilege_state_area_1_register (0x00000000)
ea (0xc000000003f40000) esid (0xc000000008000000) vsid (0x0000408f92c94500)
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
out interrupt mbox (0x0000000000000001)
lv1_clear_spe_interrupt_status(2) (0x00000000)
transferring ldr args to LS
waiting until MFC transfers are finished
MFC transfers done
out mbox (0x00000001)
sleep
lv1_get_spe_interrupt_status(0) (0x00000000)
lv1_get_spe_interrupt_status(1) (0x00000000)
lv1_get_spe_interrupt_status(2) (0x00000000)
problem status (0x000b0082)
lv1_destruct_logical_spe (0x00000000)

Retrieved from "http://www.eurasia.nu/wiki/index.php/PS3_Hypervisor_Reverse_Engineering"

This page has been accessed 9,605 times. This page was last modified 04:22, 1 September 2011.