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 | ||
323bb280 AL |
17 | static void* wiiu_mmap(uint32_t requested_va, size_t length, void* backing_mem) { |
18 | if (length < OS_PAGE_SIZE) length = OS_PAGE_SIZE; | |
19 | ||
20 | uint32_t va = OSAllocVirtAddr(requested_va, length, 0); | |
21 | if (!va) return MAP_FAILED; | |
22 | ||
23 | BOOL mapped = OSMapMemory(va, OSEffectiveToPhysical((uint32_t)backing_mem), | |
24 | length, OS_MAP_MEMORY_READ_WRITE); | |
25 | if (!mapped) { | |
26 | OSFreeVirtAddr(va, length); | |
27 | return MAP_FAILED; | |
28 | } | |
29 | ||
30 | return (void*)va; | |
31 | } | |
32 | ||
33 | static void wiiu_unmap(void* va, size_t length) { | |
34 | if (va == MAP_FAILED) return; | |
35 | OSUnmapMemory((uint32_t)va, length); | |
36 | OSFreeVirtAddr((uint32_t)va, length); | |
37 | } | |
38 | ||
39 | static void* psx_mem; | |
40 | static void* psx_parallel; | |
41 | static void* psx_scratch; | |
42 | static void* psx_bios; | |
43 | ||
44 | int lightrec_init_mmap(void) { | |
45 | psx_mem = memalign(OS_PAGE_SIZE, 0x200000); | |
46 | psx_parallel = memalign(OS_PAGE_SIZE, 0x10000); | |
47 | psx_scratch = memalign(OS_PAGE_SIZE, 0x10000); | |
48 | psx_bios = memalign(OS_PAGE_SIZE, 0x80000); | |
49 | if (!psx_mem || !psx_parallel || !psx_scratch || !psx_bios) | |
50 | goto cleanup_allocations; | |
51 | ||
52 | uint32_t avail_va; | |
53 | uint32_t avail_va_size; | |
54 | OSGetMapVirtAddrRange(&avail_va, &avail_va_size); | |
55 | if (!avail_va || avail_va_size < 0x20000000) | |
56 | goto cleanup_allocations; | |
57 | ||
58 | // Map 4x ram mirrors | |
59 | int i; | |
60 | for (i = 0; i < 4; i++) { | |
61 | void* ret = wiiu_mmap(avail_va + 0x200000 * i, 0x200000, psx_mem); | |
62 | if (ret == MAP_FAILED) break; | |
63 | } | |
64 | if (i != 4) { | |
65 | for (int i = 0; i < 4; i++) | |
66 | wiiu_unmap(avail_va + 0x200000 * i, 0x200000); | |
67 | goto cleanup_allocations; | |
68 | } | |
69 | psxM = (void*)avail_va; | |
70 | ||
71 | psxP = wiiu_mmap(avail_va + 0x1f000000, 0x10000, psx_parallel); | |
72 | psxH = wiiu_mmap(avail_va + 0x1f800000, 0x10000, psx_scratch); | |
73 | psxR = wiiu_mmap(avail_va + 0x1fc00000, 0x80000, psx_bios); | |
74 | ||
75 | if (psxP == MAP_FAILED || psxH == MAP_FAILED || psxR == MAP_FAILED) { | |
76 | for (int i = 0; i < 4; i++) | |
77 | wiiu_unmap(psxM + 0x200000 * i, 0x200000); | |
78 | wiiu_unmap(psxP, 0x10000); | |
79 | wiiu_unmap(psxH, 0x10000); | |
80 | wiiu_unmap(psxR, 0x80000); | |
81 | goto cleanup_allocations; | |
82 | } | |
83 | ||
84 | code_buffer = WUP_RWX_MEM_BASE; | |
85 | ||
86 | return 0; | |
87 | ||
88 | cleanup_allocations: | |
89 | free(psx_mem); | |
90 | free(psx_parallel); | |
91 | free(psx_scratch); | |
92 | free(psx_bios); | |
93 | return -1; | |
94 | } | |
95 | ||
96 | void lightrec_free_mmap(void) { | |
97 | for (int i = 0; i < 4; i++) | |
98 | wiiu_unmap(psxM + 0x200000 * i, 0x200000); | |
99 | wiiu_unmap(psxP, 0x10000); | |
100 | wiiu_unmap(psxH, 0x10000); | |
101 | wiiu_unmap(psxR, 0x80000); | |
102 | free(psx_mem); | |
103 | free(psx_parallel); | |
104 | free(psx_scratch); | |
105 | free(psx_bios); | |
106 | } |