Hypervisor Reverse Engineering
This is a copy of the page from 22nd of February 2011, right before ps3wiki.lan.st went down.
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)
- The function returns a new LPAR memory region address.
- This method is used e.g. in all HV calls which create any kind of memory regions, e.g. lv1_allocate_memory, lv1_map_htab, lv1_undocumented_function_114, lv1_construct_logical_spe, lv1_map_device_mmio_region or syscall 0x10040.
Encoding LPAR Memory Region Start Addresses and Sizes
- Size of LPAR memory region is encoded in the LPAR memory region start address.
- That is why e.g. the LPAR Memory Region Start Addresses of LPAR Memory Region of size 4096 byte begin with 0x300000000000, 0x300000000000 >> 42 = 0xC = log2(4096).
- Each LPAR has a counter (8 bytes) which is incremented by 1 every time a new LPAR Memory Region is created.
- Before incrementing, the counter is shifted left by log2(LPAR Memory Region Size) and ored with log2(LPAR Memory Region Size) << 42.
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
- LPAR Memory Region Address Counter is stored at address: 0x38(LPAR ptr) + 0x9E8
- LPAR1's Memory Region Address Counter is at address 0x00677A48 in HV dump 3.15
- LPAR2's Memory Region Address Counter is at address 0x007632D8 in HV dump 3.15
- LPAR1's Memory Region Address Counter is at address 0x00677A48 in HV dump 3.41
- LPAR2's Memory Region Address Counter is at address 0x00161E68 in HV dump 3.41
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
- GameOS allocates nearly all physical memory of PS3 for itself !!! That is why new HV calls lv1_allocate_memory with large memory region sizes will fail.
- So when someone wants a large piece of physical memory, he can borrow it from GameOS's LPAR memory region that starts at 0x700020000000. It can be used for example to send update packages to Update Manager which are very large.
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
- HTAB of GameOS is already mapped into address space of GameOS so that is why HV call lv1_map_htab will fail until you unmap it with lv1_unmap_htab
- Effective address of GameOS HTAB is 0x800000000F000000
- Virtual address of GameOS HTAB is 0xF000000
- Size of GameOS HTAB is 0x40000
- GameOS HTAB supports large pages of size 64K and 1M
- GameOS HTAB can be easily dumped by reading 0x40000 bytes at EA 0x800000000F000000
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.
- The HV call lv1_undocumented_function_115 destroys a memory region of this type.
- HV allows GameOS to create objects of this type of size 0 only !!! But it can be exploited with a dangling HTAB entry.
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.
- First i used the Geohot's method to create a dangling HTAB entry.
- Making memory glitch work on GameOS was the largest of my obstacles but i solved it and i'm able to create a dangling HTAB entry from GameOS within 1-3 minutes.
- Then i created many Direct Map Memory Region objects of size 0 with HV call lv1_undocumented_function_114 and checked if they are within the page to which the dangling HTAB entry points to.
- When i found one such Direct Map Memory Region object i patched the size of this object to 0x1000. Then i pointed this memory region object to the code of HV call lv1_undocumented_function_114 and patched 4 bytes in this HV call which allows me to create any Direct Map Memory Region objects without any restrictions.
- Function LPAR_construct_direct_mapping_mem_region which is used by HV call lv1_undocumented_function_114 has a parameter (register %r9) and when this parameter is not 0 then HV will allow you to create any Direct Map Memory Region objects without restrictions, but unfortunately the HV call lv1_undocumented_function_114 passes 0 in this parameter, so i just patched it.
- Then i mapped whole HV memory range with the patched HV call lv1_undocumented_function_114 into the address space of GameOS.
- And now you have read/write access to the whole HV.
- $ONY could fix this exploit by disallowing creating of Direct Map Memory Region objects of size 0, but i know tons of other HV C++ classes which will allow me to exploit the HV in a similar way, so it wouldn't bring $ONY anything :-) And they have to change member variable offsets in those objects to make sure that i cannot patch them easily :-)
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
- Net Manager runs in Process 9
- It sends commands to /dev/sc1 to reset WLAN Gelic device
- It opens /dev/net0, sets MAC address and writes device firmware eurus_fw.bin to WLAN device by using ioctl syscall
/dev/net0
The device supports 3 ioctl commands:
- 0 - 0x002AC10C (3.15)
- 1 - 0x002AC250 (3.15)
- 2 - EURUS_STAT 0x002AC320 (3.15)
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
- Event Notfication is used e.g. to notify a LPAR about some event, e.g. device interrupt or notify a LPAR about destruction of another LPAR.
- For example Process 9 is notified through Event Notification when LPAR 2 is destructed.
- During LPAR construction, Process 9 creates an Outlet object with syscall 0x1001A and then passes the outlet ID to the syscall 0x10009 that constructs the LINUX LPAR. In this way Process 9 is notified when LINUX LPAR is destructed.
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
- This type of Outlet is created e.g. in lv1_construct_event_receive_port and in syscall 0x1001A.
- HV calls lv1_connect_irq_plug and lv1_connect_irq_plug_ext assigns a VIRQ to Event Receive Port object.
vtable
0x00357E88
VUART Outlet
- HV supports only one VUART Outlet per LPAR
- lv1_configure_virtual_uart_irq constructs a VUART Outlet object and passes the address of LPAR's VUART IRQ Bitmap to HV
vtable
0x00357DC0
VUART IRQ Bitmap
- At address 0x38(LPAR ptr) + 0x158 is the VUART IRQ Bitmap owned by HV for LPAR (4 * 8 bytes = 256 bits)
- At address 0x38(LPAR ptr) + 0x150 is stored the physical address of LPAR's VUART IRQ Bitmap that was passed to lv1_configure_virtual_uart_irq
- When a VUART interrupt is generated by HV then first the VUART IRQ Bitmap owned by HV is updated and then this bitmap is copied to LPAR's VUART IRQ Bitmap, so VUART IRQ Bitmap is stored twice, once in HV and once in LPAR, just like IRQ State Bitmap.
- VUART IRQ Bitmap is not allowed to cross page boundary of LPAR memory region where it is stored. HV checks it and makes sure that it doesn't happen.
- GameOS 3.41 VUART IRQ bitmap is at address 0x80000000003556E8 and of size 32 bytes (256 bits, each bit corresponds to a VUART port).
- GameOS 3.15 VUART IRQ bitmap is at address 0x8000000000354768.
Logical PPE
- Logical PPE is used for interrupt management of LPAR.
- A Logical PPE object is created in syscall 0x10005. It' used e.g. in Process 9 during LPAR construction.
- syscall 0x10007 activates a Logical PPE object
- 0x67F0(HSPRG0) - pointer to currently active Logical PPE object (in HV dump it points to Linux PPE object naturally because the dump was made on Linux, so Linux LPAR was active at that time)
- E.g. lv1_get_logical_ppe_id, lv1_start_ppe_periodic_tracer and lv1_set_ppe_periodic_tracer_frequency grab the currently active Logical PPE object
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
- HV maintains 2 tables per PPE that map a VIRQ to an Outlet object.
- The table has 256 entries and is indexed by VIRQ.
- Each entry is a pointer to Outlet object.
- Each Logical PPE object has 2 tables, one for each thread of Cell CPU.
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
- There is one IRQ State Bitmap (256 bits = 32 bytes) per thread of Logical PPE
- HSPRG0 value is per thread, so there are 2 HSPRG0 values in HV dump !!!
- The IRQ State Bitmap of a thread is stored at -0x68E0(HSPRG0)
- When an Event or Interrupt happens then the bitmap at 0x68E0(HSPRG0) is updated
- The physical address of LPAR's IRQ State Bitmap of thread is stored at offset -0x68C0(HSPRG0)
- The address of LPAR's IRQ State Bitmap is passed to Hypervisor through HV call lv1_configure_irq_state_bitmap
- lv1_detect_pending_interrupts returns value of current IRQ State Bitmap.
- The IRQ State Bitmap is updated if an Outlet object is assigned to VIRQ and when Outlet generates an event
- After IRQ State Bitmap update, it's copied to LPAR's IRQ State Bitmap and a hardware interrupt is generated so that LPAR can read it's IRQ State Bitmap and handle interrupts.
- So, IRQ State Bitmap is stored twice, once in HV and once in LPAR, just like VUART IRQ Bitmap.
- GameOS IRQ state bitmap is stored at address SPRG0 + 0x1C0 and of size 64 bytes (256 bits state + 256 bits mask) per thread of Cell CPU. So there are 2 IRQ state bitmaps.
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)
- Data received from SC is sent to a VUART
- lv1_get_rtc and syscall 0x10036 communicate with SC VUART 4.
VUART Table
- Address of SC VUART Table - 0x00610410 (3.15).
- There are 5 VUARTs for SC in HV 3.15
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)
lv1_get_rtc
- lv1_get_rtc communicates with SC VUART 4.
- 20 bytes are written to the peer VUART of SC VUART 4.
- After a request is sent to SC VUART 4, lv1_get_rtc busy waits until SC VUART 4 receive data buffer is not empty.
- When SC VUART 4 receive data buffer is not empty, lv1_get_rtc reads 24 bytes from the VUART.