HV Syscall Reference

From PS3 Developer wiki
Revision as of 20:30, 18 May 2011 by MikeM6464 (talk | contribs) (Upto syscall 6 ported)
Jump to navigation Jump to search

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
bit 62: destruction_scheme: DS_NO_CONNECTIONS = 0×00, DS_ANYTIME = 0×02
bit 61: fail or alternative: FA_FAIL = 0×00, FA_ALTERNATIVE = 0×04
bit 60: need LPAR address 0: ADDR_ANY = 0×00, ADDR_0 = 0×08
function unknown.

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