Hypervisor Reverse Engineering

From PS3 Developer wiki
Revision as of 06:37, 10 March 2011 by 74.67.180.165 (talk)
Jump to navigation Jump to search

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.