Allocate GPU memory.
status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, &memory_handle, &ddr_lpar);
| Inputs | |
|---|---|
| Register | Description |
| R3 | ddr_size - amount of DDR to reserve? (see notes) |
| R4 | 0 - Unknown. Max value 512*1024. |
| R5 | 0 - Unknown. Max value 3075*1024. |
| R6 | 0 - Unknown. Max value 15. |
| R7 | 0 - Unknown. Max value 8. |
| Outputs | |
| Register | Description |
| R3 | status: 0 = LV1_SUCCESS, -17 = LV1_ILLEGAL_PARAMETER_VALUE |
| R4 | memory_handle - used by lv1_gpu_context_allocate and lv1_gpu_memory_free?? |
| R5 | ddr_lpar - remappable address of allocated video memory, unused by Kernel. |
Notes:
ddr_size accepts values (0..252) * 2^20 - values not divisible by 2^20 (1 MB) and above the range result in a return value of -17 (LV1_ILLEGAL_PARAMETER_VALUE). [Verified by Strontium Dog on an AU PS3 V1.5 firmware]
Bits 52-63 of ddr_size seem to be ignored or correspond to flags. The lower bits correspond to the amount of allocated video RAM. A call to lv1_gpu_context_allocate using the returned memory_handle will create a RSX DMA object handle 0xfeed0000 corresponding to the region of allocated memory. Multiple calls to lv1_gpu_memory_allocate with non-zero ddr_size will change the start of this region. The DMA object limit is set to ddr_size - 1. Before FW 2.1, a ddr_size of 0 was accepted, in which case a DMA object starting at zero and of limit 0xffffffff was created. Note that in this case, the start of this region is always zero even if previous calls to lv1_gpu_memory_allocate with non-zero ddr_size were performed. As of FW 2.1 and above, a zero ddr_size is not accepted anymore.
Parameters r4-r7 are unknown. Maximum values for these parameters are respectively 512kB, 3075kB, 15 and 8. They refer to shared scarce resources, as allocations are retained across multiple calls to lv1_gpu_memory_allocate. When attached to a context during lv1_gpu_context_allocate, the values of these parameters are reported in the lpar_driver_info structure of the context.
Cell separates multiple OS into Logical Partitions (lpar) described at http://research.scea.com/research/html/CellGDC05/13.html. PS3 GPU memory is referred to as DDR (or GDDR) whereas system memory is XDR. 256 MB of each are installed in PS3 though only XDR is currently available for use by OtherOS.
To make use of the allocated DDR ddr_lpar needs to be transformed into a usable address using:
ddr_address = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
Be aware that the memory that holds the physical GPU frame buffer is not allocated by the Kernel, just used. So on the first call to this, some or all of the memory you request (depending on now much you request) may be actually used as the frame buffer. You will know this, because your writes to memory will mysteriously disappear up to 20ms after you perform them. Note that direct access to video ram is very slow (~10MB/s).
| Register | Hex | Decimal | Comments |
|---|---|---|---|
| R3 | 0x000000000fc00000 | (264241152) | 252 MB |
| R4 | 0×0000000000000000 | (0) | |
| R5 | 0×0000000000000000 | (0) | |
| R6 | 0×0000000000000000 | (0) | |
| R7 | 0×0000000000000000 | (0) | |
| Outputs | |||
| R3 | 0×0000000000000000 | (0) | LV1_SUCCESS |
| R4 | 0x000000005a5a5a5b | (...) | memory handle |
| R5 | 0x00007001a0000000 | (...) | ddr logical partition address |