Skip to main content
PSL1GHT provides comprehensive memory management APIs for allocating and managing memory on the PlayStation 3, including direct allocation, memory mapping, and heap management.

Overview

Memory management is provided through:
  • sys/memory.h - Low-level memory allocation syscalls
  • lv2/memory.h - Memory mapping functions
  • sys/heap.h - Heap management utilities

Memory Types

typedef u32 sys_mem_id_t;        // Memory block ID
typedef u32 sys_mem_addr_t;      // Memory address
typedef u32 sys_mem_container_t; // Memory container ID

Direct Memory Allocation

Basic Allocation

LV2_SYSCALL sysMemoryAllocate(size_t size, u64 flags, 
                              sys_mem_addr_t *alloc_addr);
size
size_t
required
Size of memory to allocate in bytes
flags
u64
required
Memory allocation flags (page size and access rights)
alloc_addr
sys_mem_addr_t*
required
Pointer to receive the allocated memory address
return
s32
Returns 0 on success, non-zero error code on failure

Page Size Flags

ConstantDescription
SYS_MEMORY_PAGE_SIZE_1MUse 1MB pages (0x400)
SYS_MEMORY_PAGE_SIZE_64KUse 64KB pages (0x200)
Larger page sizes can improve performance but may waste memory if allocating small amounts.
ConstantDescription
SYS_MEMORY_ACCESS_RIGHT_PPU_THRPPU thread access (0x08)
SYS_MEMORY_ACCESS_RIGHT_HANDLERHandler access (0x04)
SYS_MEMORY_ACCESS_RIGHT_SPU_THRSPU thread access (0x02)
SYS_MEMORY_ACCESS_RIGHT_RAW_SPURaw SPU access (0x01)
SYS_MEMORY_ACCESS_RIGHT_ANYAll access rights (0x0F)
SYS_MEMORY_ACCESS_RIGHT_NONENo access (0xF0)
ConstantDescription
SYS_MEMORY_PROT_READ_ONLYRead-only access (0x80000)
SYS_MEMORY_PROT_READ_WRITERead-write access (0x40000)

Freeing Memory

LV2_SYSCALL sysMemoryFree(sys_mem_addr_t start_addr);

Memory Containers

Memory containers provide isolated memory pools for resource management.
LV2_SYSCALL sysMemContainerCreate(sys_mem_container_t *container, 
                                  size_t size);
LV2_SYSCALL sysMemContainerDestroy(sys_mem_container_t container);

Memory Mapper

The memory mapper provides advanced memory management with virtual address mapping.

Address Allocation

LV2_SYSCALL sysMMapperAllocateAddress(size_t size, u64 flags,
                                      size_t alignment,
                                      sys_mem_addr_t *alloc_addr);

Memory Allocation and Mapping

s32 sysMMapperAllocateMemory(size_t size, u64 flags, 
                             sys_mem_id_t *mem_id);
s32 sysMMapperMapMemory(sys_mem_addr_t start_addr, 
                        sys_mem_id_t mem_id, u64 flags);
s32 sysMMapperUnmapMemory(sys_mem_addr_t start_addr, 
                          sys_mem_id_t *mem_id);
s32 sysMMapperFreeMemory(sys_mem_id_t mem_id);

Search and Map

LV2_SYSCALL sysMMapperSearchAndMap(sys_mem_addr_t start_addr,
                                   sys_mem_id_t mem_id,
                                   u64 flags,
                                   sys_mem_addr_t *alloc_addr);

Heap Management

PSL1GHT provides a custom heap implementation for fine-grained memory control.

Heap Structure

typedef struct _heap_cntrl_t heap_cntrl;

struct _heap_cntrl_t {
    s32 lock;
    heap_block free_list;
    uintptr_t page_size;
    uintptr_t min_block_size;
    uintptr_t heap_begin;
    uintptr_t heap_end;
    heap_block *first_block;
    heap_block *last_block;
};

Heap Initialization

uintptr_t heapInit(heap_cntrl *theheap, void *start_addr, 
                   uintptr_t size);

Heap Allocation

void* heapAllocate(heap_cntrl *theheap, uintptr_t size);
void* heapAllocateAligned(heap_cntrl *theheap, uintptr_t size,
                          uintptr_t alignment);
bool heapFree(heap_cntrl *theheap, void *ptr);

Alignment Requirements

Many PS3 operations require specific memory alignment.
#include <ppu-types.h>

// SPU requires 128-byte alignment
#define SPU_ALIGNMENT      128
#define SPU_ALIGNSIZE(x)   (((x) + 127) & ~127)

// Stack alignment helper
#define STACK_ALIGN(type, name, cnt, alignment) \
    u8 _al__##name[((sizeof(type)*(cnt)) + (alignment) + \
                    (((sizeof(type)*(cnt))%(alignment)) > 0 ? \
                     ((alignment) - ((sizeof(type)*(cnt))%(alignment))) : 0))]; \
    type *name = (type*)(((u64)(_al__##name)) + \
                 ((alignment) - (((u64)(_al__##name))&((alignment)-1))))
Critical Alignment Requirements:
  • SPU operations require 128-byte alignment
  • DMA transfers often require 16-byte alignment
  • Some syscalls require specific page alignment (64KB or 1MB)

Complete Memory Example

#include <stdio.h>
#include <string.h>
#include <sys/memory.h>
#include <sys/heap.h>

typedef struct {
    heap_cntrl heap;
    sys_mem_addr_t base_addr;
    size_t total_size;
} memory_manager_t;

int memory_init(memory_manager_t *mgr, size_t size) {
    s32 ret;
    u64 flags;
    
    // Allocate memory with 1MB pages
    flags = SYS_MEMORY_PAGE_SIZE_1M | 
            SYS_MEMORY_ACCESS_RIGHT_ANY |
            SYS_MEMORY_PROT_READ_WRITE;
    
    ret = sysMemoryAllocate(size, flags, &mgr->base_addr);
    if (ret != 0) {
        printf("Failed to allocate memory: %d\n", ret);
        return ret;
    }
    
    // Initialize heap
    void *heap_start = (void*)(uintptr_t)mgr->base_addr;
    uintptr_t usable = heapInit(&mgr->heap, heap_start, size);
    
    mgr->total_size = size;
    printf("Memory manager initialized: %zu bytes total, "
           "%lu bytes usable\n", size, usable);
    
    return 0;
}

void* memory_allocate(memory_manager_t *mgr, size_t size) {
    void *ptr = heapAllocate(&mgr->heap, size);
    if (ptr) {
        printf("Allocated %zu bytes at %p\n", size, ptr);
    }
    return ptr;
}

void* memory_allocate_aligned(memory_manager_t *mgr, 
                              size_t size, size_t alignment) {
    void *ptr = heapAllocateAligned(&mgr->heap, size, alignment);
    if (ptr) {
        printf("Allocated %zu bytes (aligned to %zu) at %p\n",
               size, alignment, ptr);
    }
    return ptr;
}

void memory_free(memory_manager_t *mgr, void *ptr) {
    if (heapFree(&mgr->heap, ptr)) {
        printf("Freed memory at %p\n", ptr);
    } else {
        printf("Failed to free memory at %p\n", ptr);
    }
}

void memory_shutdown(memory_manager_t *mgr) {
    sysMemoryFree(mgr->base_addr);
    printf("Memory manager shut down\n");
}

// Usage
int main() {
    memory_manager_t mgr;
    
    // Initialize with 4MB
    if (memory_init(&mgr, 4 * 1024 * 1024) != 0) {
        return 1;
    }
    
    // Allocate some memory
    void *buf1 = memory_allocate(&mgr, 1024);
    void *buf2 = memory_allocate_aligned(&mgr, 2048, 128);
    
    // Use the memory...
    memset(buf1, 0, 1024);
    memset(buf2, 0, 2048);
    
    // Free memory
    memory_free(&mgr, buf1);
    memory_free(&mgr, buf2);
    
    // Cleanup
    memory_shutdown(&mgr);
    
    return 0;
}

Memory Usage Tips

Choose Page Size Wisely

Use 1MB pages for large allocations, 64KB for smaller ones to reduce waste.

Always Free Memory

Prevent memory leaks by freeing all allocated memory when done.

Respect Alignment

Ensure proper alignment for SPU and DMA operations.

Use Containers

Isolate memory pools with containers for better resource management.
Memory Limits:The PS3 has limited RAM available to applications (typically around 256MB for games). Always be mindful of memory usage and implement proper cleanup.

Best Practices

  1. Check all allocations - Always verify memory allocation succeeded before use
  2. Use appropriate page sizes - Match page size to allocation size
  3. Align for hardware - Use required alignment for SPU and DMA
  4. Free in reverse order - Generally free memory in reverse of allocation order
  5. Container isolation - Use containers to limit resource usage
  6. Avoid fragmentation - Consider using custom heaps for many small allocations

See Also

Build docs developers (and LLMs) love