Commit | Line | Data |
---|---|---|
323bb280 AL |
1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* | |
3 | * Copyright (C) 2022 Ash Logan <ash@heyquark.com> | |
4 | */ | |
5 | ||
6 | #include <coreinit/memorymap.h> | |
7 | #include <malloc.h> | |
8 | #include <stdbool.h> | |
9 | ||
10 | #include "../memmap.h" | |
11 | #include "../psxhw.h" | |
12 | #include "../psxmem.h" | |
13 | #include "../r3000a.h" | |
14 | ||
15 | #include "mem.h" | |
16 | ||
17 | void* code_buffer; | |
18 | ||
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; | |
21 | ||
22 | uint32_t va = OSAllocVirtAddr(requested_va, length, 0); | |
23 | if (!va) return MAP_FAILED; | |
24 | ||
25 | BOOL mapped = OSMapMemory(va, OSEffectiveToPhysical((uint32_t)backing_mem), | |
26 | length, OS_MAP_MEMORY_READ_WRITE); | |
27 | if (!mapped) { | |
28 | OSFreeVirtAddr(va, length); | |
29 | return MAP_FAILED; | |
30 | } | |
31 | ||
32 | return (void*)va; | |
33 | } | |
34 | ||
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); | |
39 | } | |
40 | ||
41 | static void* psx_mem; | |
42 | static void* psx_parallel; | |
43 | static void* psx_scratch; | |
44 | static void* psx_bios; | |
45 | ||
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; | |
53 | ||
54 | uint32_t avail_va; | |
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; | |
59 | ||
60 | // Map 4x ram mirrors | |
61 | int i; | |
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; | |
65 | } | |
66 | if (i != 4) { | |
67 | for (int i = 0; i < 4; i++) | |
68 | wiiu_unmap(avail_va + 0x200000 * i, 0x200000); | |
69 | goto cleanup_allocations; | |
70 | } | |
71 | psxM = (void*)avail_va; | |
72 | ||
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); | |
76 | ||
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; | |
84 | } | |
85 | ||
86 | code_buffer = WUP_RWX_MEM_BASE; | |
87 | ||
88 | return 0; | |
89 | ||
90 | cleanup_allocations: | |
91 | free(psx_mem); | |
92 | free(psx_parallel); | |
93 | free(psx_scratch); | |
94 | free(psx_bios); | |
95 | return -1; | |
96 | } | |
97 | ||
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); | |
104 | free(psx_mem); | |
105 | free(psx_parallel); | |
106 | free(psx_scratch); | |
107 | free(psx_bios); | |
108 | } |