1 // SPDX-License-Identifier: GPL-2.0-or-later
 
   3  * Copyright (C) 2022 Ash Logan <ash@heyquark.com>
 
   6 #include <coreinit/memorymap.h>
 
  10 #include "../memmap.h"
 
  12 #include "../psxmem.h"
 
  13 #include "../r3000a.h"
 
  17 void wiiu_clear_cache(void *start, void *end);
 
  19 static void* wiiu_mmap(uint32_t requested_va, size_t length, void* backing_mem) {
 
  20         if (length < OS_PAGE_SIZE) length = OS_PAGE_SIZE;
 
  22         uint32_t va = OSAllocVirtAddr(requested_va, length, 0);
 
  23         if (!va) return MAP_FAILED;
 
  25         BOOL mapped = OSMapMemory(va, OSEffectiveToPhysical((uint32_t)backing_mem),
 
  26                                   length, OS_MAP_MEMORY_READ_WRITE);
 
  28                 OSFreeVirtAddr(va, length);
 
  35 static void wiiu_unmap(void* va, size_t length) {
 
  36         if (va == MAP_FAILED) return;
 
  37         OSUnmapMemory((uint32_t)va, length);
 
  38         OSFreeVirtAddr((uint32_t)va, length);
 
  42 static void* psx_parallel;
 
  43 static void* psx_scratch;
 
  44 static void* psx_bios;
 
  46 int lightrec_init_mmap(void) {
 
  47         psx_mem      = memalign(OS_PAGE_SIZE, 0x200000);
 
  48         psx_parallel = memalign(OS_PAGE_SIZE, 0x10000);
 
  49         psx_scratch  = memalign(OS_PAGE_SIZE, 0x10000);
 
  50         psx_bios     = memalign(OS_PAGE_SIZE, 0x80000);
 
  51         if (!psx_mem || !psx_parallel || !psx_scratch || !psx_bios)
 
  52                 goto cleanup_allocations;
 
  55         uint32_t avail_va_size;
 
  56         OSGetMapVirtAddrRange(&avail_va, &avail_va_size);
 
  57         if (!avail_va || avail_va_size < 0x20000000)
 
  58                 goto cleanup_allocations;
 
  62         for (i = 0; i < 4; i++) {
 
  63                 void* ret = wiiu_mmap(avail_va + 0x200000 * i, 0x200000, psx_mem);
 
  64                 if (ret == MAP_FAILED) break;
 
  67                 for (int i = 0; i < 4; i++)
 
  68                         wiiu_unmap(avail_va + 0x200000 * i, 0x200000);
 
  69                 goto cleanup_allocations;
 
  71         psxM = (void*)avail_va;
 
  73         psxP = wiiu_mmap(avail_va + 0x1f000000, 0x10000, psx_parallel);
 
  74         psxH = wiiu_mmap(avail_va + 0x1f800000, 0x10000, psx_scratch);
 
  75         psxR = wiiu_mmap(avail_va + 0x1fc00000, 0x80000, psx_bios);
 
  77         if (psxP == MAP_FAILED || psxH == MAP_FAILED || psxR == MAP_FAILED) {
 
  78                 for (int i = 0; i < 4; i++)
 
  79                         wiiu_unmap(psxM + 0x200000 * i, 0x200000);
 
  80                 wiiu_unmap(psxP, 0x10000);
 
  81                 wiiu_unmap(psxH, 0x10000);
 
  82                 wiiu_unmap(psxR, 0x80000);
 
  83                 goto cleanup_allocations;
 
  86         code_buffer = WUP_RWX_MEM_BASE;
 
  98 void lightrec_free_mmap(void) {
 
  99         for (int i = 0; i < 4; i++)
 
 100                 wiiu_unmap(psxM + 0x200000 * i, 0x200000);
 
 101         wiiu_unmap(psxP, 0x10000);
 
 102         wiiu_unmap(psxH, 0x10000);
 
 103         wiiu_unmap(psxR, 0x80000);
 
 110 void lightrec_code_inv(void *ptr, uint32_t len)
 
 112         wiiu_clear_cache(ptr, (void *)((uintptr_t)ptr + len));