HV Syscall Reference
HV Syscalls
lv1_allocate_memory
Create a memory region in the Hypervisor Virtual Address Space (vas)
Kernel Call
result = lv1_allocate_memory( /*IN*/ size, page_size_exp, 0, flags, /*OUT*/ &addr, &muid );
Parameters
Inputs | |
---|---|
Register | Description |
R3 | size - of the region to allocate, must be a multiple of page_size |
R4 | page_size_exp - where required page_size = 2 ^ page_size_exp |
R5 | 0 - Unknown, see notes |
R6 | flags - (from linux/include/asm-powerpc/lv1call.h) bit 63: transferability: TF_NO = 0×00, TF_YES = 0×01 |
Outputs | |
Register | Description |
R3 | Status - 0 = OK, LV1_RESOURCE_SHORTAGE (-2), LV1_NO_ENTRY (-6), LV1_DUPLICATE_ENTRY (-7) |
R4 | addr - LPAR Address of region |
R5 | muid - Unknown, unused by Kernel |
Notes:
page_size_exp takes values of 12 (page_size = 4K) to 21 (page_size = 2M) before LV1_RESOURCE_SHORTAGE (-2) is returned under a fully booted Linux OS. Higher values (24, page_size = 16M) can be found in the actual kernel source and can presumably be made before the OS has fully booted. page_size_exp values below 12 cause a return status of LV1_ILLEGAL_PARAMETER_VALUE (-17).
Input R5 was speculated to be the initialization value for the allocated region, but appears not to be the case. Values other than 0 or 1 appear to return a status of LV1_NO_ENTRY (-6), though a valid value of page_size_exp appears to be checked first (-17 is returned for invalid values of page_size_exp, regardless of the value of R5).
Allocations with flags = 0×00, 0×01, 0×02, 0×03 and 0×04 were successful though the effects of the flags could not be tested at this point. Allocations with flags >= 0×400 return LV1_ILLEGAL_PARAMETER_VALUE.
Initial tests allocating memory with flags = 0×08 (ADDR_0, presumably request physical address rather than logical partition address) result in a status of LV1_DUPLICATE_ENTRY (-7). This and the previous return value of -6 suggest an association with a database of some kind (repository values or memory maps?). It appears that some form of allocation may be taking place as LV1_ILLEGAL_PARAMETER_VALUE and LV1_RESOURCE_SHORTAGE are reported for invalid input parameters, rather than LV1_DUPLICATE_ENTRY.
For all successful allocations so far, output muid (R5) = 1
lv1_write_htab_entry
Write an entry to the hash page table.
Kernel Call
result = lv1_write_htab_entry( /*IN*/ vas_id, slot, va, pa );
Parameters
Inputs | |
---|---|
Register | Description |
R3 | vas_id - virtual address space id (0 for current) |
R4 | slot - table slot to write entry to |
R5 | va - first half of PTE |
R6 | pa - second half of PTE, except RPN is replaced with LPAR address |
Outputs | |
Register | Description |
R3 | Status - 0 = OK, Other values are unknown, but indicate failure. |
lv1_construct_virtual_address_space
Construct a PPE virtual address space.
Kernel Call
result = lv1_construct_virtual_address_space( /*IN*/ htab_size, number_of_sizes, page_sizes, /*OUT*/ &vas_id, &act_htab_size );
Parameters
Inputs | |
---|---|
Register | Description |
R3 | htab_size - must be 18, 19 or 20 (256KB, 512KB or 1MB) |
R4 | number_of_sizes - How many page sizes are specified in page_sizes |
R5 | page_sizes - see notes |
Outputs | |
Register | Description |
R3 | Status - 0 = OK, Other values are unknown, but indicate failure. |
R4 | vas_id - virtual address space id |
R5 | act_htab_size - actual hash table size? |
Notes:
Page sizes are specified as the power of two for the desired sizes. Each power of two is stored as an 8 bit field in page_sizes, starting from the MSB.
The “pages_sizes” parameter is set in “mm.c” using the following function:
page_sizes = make_page_sizes(PAGE_SHIFT_16M, PAGE_SHIFT_64K); static unsigned long make_page_sizes(unsigned long a, unsigned long b) { return (a << 56) | (b << 48); }
lv1_invalidate_htab_entries
Not used in current kernel.
Abstract Call
result = lv1_invalidate_htab_entries( /*IN*/ p1, p2, p3, p4, p5 );
Parameters
Inputs | |
---|---|
Register | Description |
R3 | p1 - Unknown |
R4 | p2 - Unknown |
R5 | p3 - Unknown |
R6 | p4 - Unknown |
R7 | p5 - Unknown |
Outputs | |
Register | Description |
R3 | Status? |
lv1_get_virtual_address_space_id_of_ppe
Returns the virtual address space id of the PPE.
Kernel Call
result = lv1_get_virtual_address_space_id_of_ppe( /*IN*/ ppe_id , /*OUT*/ &vas_id );
Parameters
Inputs | |
---|---|
Register | Description |
R3 | PPE id |
Outputs | |
Register | Description |
R3 | status: 0 = LV1_SUCCESS |
R4 | vas_id - virtual address space id of the PPE |
Notes:
Regardless of the ppe_id, when called from kernel module init function, vas_id always seems to be 11.
lv1_query_logical_partition_address_region_info
Retrieve address region information for the specified logical partition address region.
Kernel Call
result = lv1_query_logical_partition_address_region_info( /*IN*/ 0, /*OUT*/ &start_address, &size, &access_right, &max_page_size, &flags);
Parameters
Inputs | |
---|---|
Register | Description |
R3 | 0 - logical partition address region (lpar) |
Outputs | |
Register | Description |
R3 | status: 0 = LV1_SUCCESS |
R4 | start_address - start address of logical partition address region |
R5 | size - size of logical partition address region |
R6 | access_right - ? |
R7 | max_page_size - maximum page size of logical partition address region? or order of the allocation? |
R8 | flags - ? |
Notes:
Only the “max_page_size” parameter is currently used by the Kernel, in “mm.c”
Test Results
Register | Hex | Decimal | Comment |
---|---|---|---|
R3 | 0x00000000 | (0) | value does not seem to effect result |
Outputs | |||
R3 | 0×00000000 | (0) | LV1_SUCCESS |
R4 | 0×00000000 | (0) | start_address |
R5 | 0×08000000 | (134217728) | size - 128 Mb |
R6 | 0×00000003 | (3) | access_right |
R7 | 0x0000001b | (27) | max_page_size |
R8 | 0×00000008 | (8) | flags |
This suggests lpar 0 is a special lpar representing the first 128MB of RAM that are always available at boot time. In this case, max_page_size seems to correspond to the order of the allocation (2**27 = 128 MB). The meaning of access_right and flags is unknown.
Also works on a lpar obtained from lv1_allocate_memory, for example
lv1_allocate_memory(4096 /* size */, 12 /* page size */, 0, 0, &lpar, &muid); lv1_query_logical_partition_address_region_info(lpar, &start_address, &size, &access_right, &max_page_size, &flags);
returns:
Register | Hex | Decimal | Comment |
---|---|---|---|
R3 | 0x30000001f00 | (3298534891264) | lpar obtained from lv1_allocate_memory |
Outputs | |||
R3 | 0×00000000 | (0) | LV1_SUCCESS |
R4 | 0×30000001f00 | (0) | start_address (same as input lpar) |
R5 | 0×00001000 | (4096) | size - 4kB |
R6 | 0×00000003 | (3) | access_right |
R7 | 0x0000000c | (12) | max_page_size |
R8 | 0×00000000 | (0) | flags |