Match and link OSMemory

Former-commit-id: 8c11873cf2
This commit is contained in:
Phillip Stephens 2022-12-18 10:32:00 -08:00
parent 758b61fc47
commit 7bd2b5f649
6 changed files with 259 additions and 11 deletions

View File

@ -2,8 +2,8 @@
.section .bss
.balign 8
.global lbl_80541250
lbl_80541250:
.global __OSErrorTable
__OSErrorTable:
.skip 0x48
.section .data
@ -206,9 +206,9 @@ OSSetErrorHandler:
/* 8037FB74 0037CAD4 93 81 00 20 */ stw r28, 0x20(r1)
/* 8037FB78 0037CAD8 3B 84 00 00 */ addi r28, r4, 0
/* 8037FB7C 0037CADC 48 00 1A E5 */ bl OSDisableInterrupts
/* 8037FB80 0037CAE0 3C 80 80 54 */ lis r4, lbl_80541250@ha
/* 8037FB80 0037CAE0 3C 80 80 54 */ lis r4, __OSErrorTable@ha
/* 8037FB84 0037CAE4 57 A5 13 BA */ rlwinm r5, r29, 2, 0xe, 0x1d
/* 8037FB88 0037CAE8 38 04 12 50 */ addi r0, r4, lbl_80541250@l
/* 8037FB88 0037CAE8 38 04 12 50 */ addi r0, r4, __OSErrorTable@l
/* 8037FB8C 0037CAEC 57 A6 04 3E */ clrlwi r6, r29, 0x10
/* 8037FB90 0037CAF0 7C 80 2A 14 */ add r4, r0, r5
/* 8037FB94 0037CAF4 83 C4 00 00 */ lwz r30, 0(r4)
@ -343,7 +343,7 @@ lbl_8037FD44:
.global __OSUnhandledException
__OSUnhandledException:
/* 8037FD70 0037CCD0 7C 08 02 A6 */ mflr r0
/* 8037FD74 0037CCD4 3D 00 80 54 */ lis r8, lbl_80541250@ha
/* 8037FD74 0037CCD4 3D 00 80 54 */ lis r8, __OSErrorTable@ha
/* 8037FD78 0037CCD8 90 01 00 04 */ stw r0, 4(r1)
/* 8037FD7C 0037CCDC 3C E0 80 3F */ lis r7, lbl_803F1430@ha
/* 8037FD80 0037CCE0 94 21 FF C0 */ stwu r1, -0x40(r1)
@ -352,7 +352,7 @@ __OSUnhandledException:
/* 8037FD8C 0037CCEC 3B 24 00 00 */ addi r25, r4, 0
/* 8037FD90 0037CCF0 3B 45 00 00 */ addi r26, r5, 0
/* 8037FD94 0037CCF4 3B 66 00 00 */ addi r27, r6, 0
/* 8037FD98 0037CCF8 3B C8 12 50 */ addi r30, r8, lbl_80541250@l
/* 8037FD98 0037CCF8 3B C8 12 50 */ addi r30, r8, __OSErrorTable@l
/* 8037FD9C 0037CCFC 3B E7 14 30 */ addi r31, r7, lbl_803F1430@l
/* 8037FDA0 0037CD00 48 00 56 09 */ bl OSGetTime
/* 8037FDA4 0037CD04 80 B9 01 9C */ lwz r5, 0x19c(r25)

View File

@ -38,9 +38,9 @@ MEMIntrruptHandler:
/* 80382A60 0037F9C0 38 00 00 00 */ li r0, 0
/* 80382A64 0037F9C4 94 21 FF F8 */ stwu r1, -8(r1)
/* 80382A68 0037F9C8 A0 E3 40 24 */ lhz r7, 0x4024(r3)
/* 80382A6C 0037F9CC 3C 60 80 54 */ lis r3, lbl_80541250@ha
/* 80382A6C 0037F9CC 3C 60 80 54 */ lis r3, __OSErrorTable@ha
/* 80382A70 0037F9D0 A0 C8 00 22 */ lhz r6, 0x22(r8)
/* 80382A74 0037F9D4 38 63 12 50 */ addi r3, r3, lbl_80541250@l
/* 80382A74 0037F9D4 38 63 12 50 */ addi r3, r3, __OSErrorTable@l
/* 80382A78 0037F9D8 A0 A8 00 1E */ lhz r5, 0x1e(r8)
/* 80382A7C 0037F9DC 50 E6 81 9E */ rlwimi r6, r7, 0x10, 6, 0xf
/* 80382A80 0037F9E0 B0 08 00 20 */ sth r0, 0x20(r8)

View File

@ -816,7 +816,7 @@ LIBS = [
["Dolphin/os/OSInterrupt", True],
["Dolphin/os/OSLink", True],
["Dolphin/os/OSMessage", True],
["Dolphin/os/OSMemory", False],
["Dolphin/os/OSMemory", True],
["Dolphin/os/OSMutex", True],
"Dolphin/os/OSReboot",
["Dolphin/os/OSReset", True],

View File

@ -158,6 +158,7 @@ void OSFatal(GXColor fg, GXColor bg, const char* msg);
#include <dolphin/os/OSFastCast.h>
#include <dolphin/os/OSFont.h>
#include <dolphin/os/OSInterrupt.h>
#include <dolphin/os/OSMemory.h>
#include <dolphin/os/OSMessage.h>
#include <dolphin/os/OSModule.h>
#include <dolphin/os/OSMutex.h>

View File

@ -28,9 +28,9 @@ extern "C" {
#define OS_ERROR_MAX (OS_ERROR_FPE + 1)
typedef u16 OSError;
typedef void OSErrorHandler(OSError, OSContext* context, ...);
typedef void (*OSErrorHandler)( OSError error, OSContext* context, ... );
void OSSetErrorHandler(OSError code, OSErrorHandler* handler);
void OSSetErrorHandler(OSError code, OSErrorHandler handler);
#ifdef __cplusplus
}

247
src/Dolphin/os/OSMemory.c Normal file
View File

@ -0,0 +1,247 @@
#include <dolphin/os.h>
#define TRUNC(n, a) (((u32)(n)) & ~((a)-1))
#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1))
vu16 __MEMRegs[64] : 0xCC004000;
extern OSErrorHandler __OSErrorTable[16];
static BOOL OnReset(BOOL final);
static OSResetFunctionInfo ResetFunctionInfo = {
OnReset,
127,
};
#if NONMATCHING
static BOOL OnReset(BOOL final) {
if (final != FALSE) {
__MEMRegs[8] = 0xFF;
__OSMaskInterrupts(0xf0000000);
}
return TRUE;
}
#else
/* clang-format off */
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
static asm BOOL OnReset(BOOL final) {
nofralloc
mflr r0
cmpwi r3, 0
stw r0, 4(r1)
stwu r1, -8(r1)
beq @1
lis r3, __MEMRegs+16@ha
li r0, 0xff
sth r0, __MEMRegs+16@l(r3)
lis r3, 0xf000
bl __OSMaskInterrupts
@1
li r3, 1
lwz r0, 0xc(r1)
addi r1, r1, 8
mtlr r0
blr
}
#pragma pop
/* clang-format on */
#endif
u32 OSGetPhysicalMemSize() { return *(u32*)(OSPhysicalToCached(0x0028)); }
u32 OSGetConsoleSimulatedMemSize() { return *(u32*)(OSPhysicalToCached(0x00F0)); }
static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) {
u32 addr;
u32 cause;
cause = __MEMRegs[0xf];
addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11];
__MEMRegs[0x10] = 0;
if (__OSErrorTable[OS_ERROR_PROTECTION]) {
__OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr);
return;
}
__OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr);
}
void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control) {
BOOL enabled;
u32 start;
u32 end;
u16 reg;
if (4 <= chan) {
return;
}
control &= OS_PROTECT_CONTROL_RDWR;
end = (u32)addr + nBytes;
start = TRUNC(addr, 1u << 10);
end = ROUND(end, 1u << 10);
DCFlushRange((void*)start, end - start);
enabled = OSDisableInterrupts();
__OSMaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan));
__MEMRegs[0 + 2 * chan] = (u16)(start >> 10);
__MEMRegs[1 + 2 * chan] = (u16)(end >> 10);
reg = __MEMRegs[8];
reg &= ~(OS_PROTECT_CONTROL_RDWR << 2 * chan);
reg |= control << 2 * chan;
__MEMRegs[8] = reg;
if (control != OS_PROTECT_CONTROL_RDWR) {
__OSUnmaskInterrupts(OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0 + chan));
}
OSRestoreInterrupts(enabled);
}
asm void Config24MB() {
// clang-format off
nofralloc
addi r7,r0,0
addis r4,r0,0x00000002@ha
addi r4,r4,0x00000002@l
addis r3,r0,0x800001ff@ha
addi r3,r3,0x800001ff@l
addis r6,r0,0x01000002@ha
addi r6,r6,0x01000002@l
addis r5,r0,0x810000ff@ha
addi r5,r5,0x810000ff@l
isync
mtspr dbat0u,r7
mtspr dbat0l,r4
mtspr dbat0u,r3
isync
mtspr ibat0u,r7
mtspr ibat0l,r4
mtspr ibat0u,r3
isync
mtspr dbat2u,r7
mtspr dbat2l,r6
mtspr dbat2u,r5
isync
mtspr ibat2u,r7
mtspr ibat2l,r6
mtspr ibat2u,r5
isync
mfmsr r3
ori r3, r3, 0x30
mtsrr1 r3
mflr r3
mtsrr0 r3
rfi
// clang-format on
}
asm void Config48MB() {
// clang-format off
nofralloc
addi r7,r0,0x0000
addis r4,r0,0x00000002@ha
addi r4,r4,0x00000002@l
addis r3,r0,0x800003ff@ha
addi r3,r3,0x800003ff@l
addis r6,r0,0x02000002@ha
addi r6,r6,0x02000002@l
addis r5,r0,0x820001ff@ha
addi r5,r5,0x820001ff@l
isync
mtspr dbat0u,r7
mtspr dbat0l,r4
mtspr dbat0u,r3
isync
mtspr ibat0u,r7
mtspr ibat0l,r4
mtspr ibat0u,r3
isync
mtspr dbat2u,r7
mtspr dbat2l,r6
mtspr dbat2u,r5
isync
mtspr ibat2u,r7
mtspr ibat2l,r6
mtspr ibat2u,r5
isync
mfmsr r3
ori r3, r3, 0x30
mtsrr1 r3
mflr r3
mtsrr0 r3
rfi
// clang-format on
}
asm void RealMode(register u32 addr) {
// clang-format off
nofralloc
clrlwi r3, r3, 2
mtsrr0 r3
mfmsr r3
rlwinm r3, r3, 0, 28, 25
mtsrr1 r3
rfi
// clang-format on
}
void __OSInitMemoryProtection() {
u32 padding[8];
u32 simulatedSize;
BOOL enabled;
simulatedSize = OSGetConsoleSimulatedMemSize();
enabled = OSDisableInterrupts();
if (simulatedSize <= 0x1800000) {
RealMode((u32)&Config24MB);
} else if (simulatedSize <= 0x3000000) {
RealMode((u32)&Config48MB);
}
__MEMRegs[16] = 0;
__MEMRegs[8] = 0xFF;
__OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 |
OS_INTERRUPTMASK_MEM_3);
__OSSetInterruptHandler(__OS_INTERRUPT_MEM_0, MEMIntrruptHandler);
__OSSetInterruptHandler(__OS_INTERRUPT_MEM_1, MEMIntrruptHandler);
__OSSetInterruptHandler(__OS_INTERRUPT_MEM_2, MEMIntrruptHandler);
__OSSetInterruptHandler(__OS_INTERRUPT_MEM_3, MEMIntrruptHandler);
__OSSetInterruptHandler(__OS_INTERRUPT_MEM_ADDRESS, MEMIntrruptHandler);
OSRegisterResetFunction(&ResetFunctionInfo);
if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() &&
OSGetConsoleSimulatedMemSize() == 0x1800000) {
__MEMRegs[20] = 2;
}
__OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS);
OSRestoreInterrupts(enabled);
}