mirror of https://github.com/PrimeDecomp/prime.git
Match and link OSInterrupt
This commit is contained in:
parent
63e08c42a2
commit
42555103a2
|
@ -45,7 +45,8 @@
|
|||
"trees.h": "c",
|
||||
"musyx.h": "c",
|
||||
"dsp_import.h": "c",
|
||||
"osinterrupt.h": "c"
|
||||
"osinterrupt.h": "c",
|
||||
"osmodule.h": "c"
|
||||
},
|
||||
"files.autoSave": "onFocusChange",
|
||||
"files.insertFinalNewline": true,
|
||||
|
|
|
@ -529,12 +529,12 @@ lbl_8037FFD8:
|
|||
/* 8038001C 0037CF7C 38 7F 02 88 */ addi r3, r31, 0x288
|
||||
/* 80380020 0037CF80 4B FF F9 8D */ bl OSReport
|
||||
lbl_80380024:
|
||||
/* 80380024 0037CF84 A8 8D AD 18 */ lha r4, lbl_805A98D8@sda21(r13)
|
||||
/* 80380024 0037CF84 A8 8D AD 18 */ lha r4, __OSLastInterrupt@sda21(r13)
|
||||
/* 80380028 0037CF88 38 7F 02 A4 */ addi r3, r31, 0x2a4
|
||||
/* 8038002C 0037CF8C 4C C6 31 82 */ crclr 6
|
||||
/* 80380030 0037CF90 80 AD AD 14 */ lwz r5, lbl_805A98D4@sda21(r13)
|
||||
/* 80380034 0037CF94 80 ED AD 20 */ lwz r7, lbl_805A98E0@sda21(r13)
|
||||
/* 80380038 0037CF98 81 0D AD 24 */ lwz r8, lbl_805A98E4@sda21(r13)
|
||||
/* 80380030 0037CF90 80 AD AD 14 */ lwz r5, __OSLastInterruptSrr0@sda21(r13)
|
||||
/* 80380034 0037CF94 80 ED AD 20 */ lwz r7, __OSLastInterruptTime@sda21(r13)
|
||||
/* 80380038 0037CF98 81 0D AD 24 */ lwz r8, __OSLastInterruptTime+4@sda21(r13)
|
||||
/* 8038003C 0037CF9C 4B FF F9 71 */ bl OSReport
|
||||
/* 80380040 0037CFA0 4B FE F7 D5 */ bl PPCHalt
|
||||
/* 80380044 0037CFA4 BA C1 00 18 */ lmw r22, 0x18(r1)
|
||||
|
|
|
@ -2,26 +2,24 @@
|
|||
|
||||
.section .sbss
|
||||
.balign 8
|
||||
.global lbl_805A98D0
|
||||
lbl_805A98D0:
|
||||
.global InterruptHandlerTable
|
||||
InterruptHandlerTable:
|
||||
.skip 0x4
|
||||
.global lbl_805A98D4
|
||||
lbl_805A98D4:
|
||||
.global __OSLastInterruptSrr0
|
||||
__OSLastInterruptSrr0:
|
||||
.skip 0x4
|
||||
.global lbl_805A98D8
|
||||
lbl_805A98D8:
|
||||
.global __OSLastInterrupt
|
||||
__OSLastInterrupt:
|
||||
.skip 0x2
|
||||
.skip 6
|
||||
.global __OSLastInterruptTime
|
||||
__OSLastInterruptTime:
|
||||
.skip 0x8
|
||||
.global lbl_805A98E0
|
||||
lbl_805A98E0:
|
||||
.skip 0x4
|
||||
.global lbl_805A98E4
|
||||
lbl_805A98E4:
|
||||
.skip 0x4
|
||||
|
||||
.section .data
|
||||
.balign 8
|
||||
.global lbl_803F2260
|
||||
lbl_803F2260:
|
||||
.global InterruptPrioTable
|
||||
InterruptPrioTable:
|
||||
.4byte 0x00000100
|
||||
.4byte 0x00000040
|
||||
.4byte 0xF8000000
|
||||
|
@ -74,7 +72,7 @@ lbl_803816A0:
|
|||
.global __OSSetInterruptHandler
|
||||
__OSSetInterruptHandler:
|
||||
/* 803816AC 0037E60C 7C 60 07 34 */ extsh r0, r3
|
||||
/* 803816B0 0037E610 80 6D AD 10 */ lwz r3, lbl_805A98D0@sda21(r13)
|
||||
/* 803816B0 0037E610 80 6D AD 10 */ lwz r3, InterruptHandlerTable@sda21(r13)
|
||||
/* 803816B4 0037E614 54 00 10 3A */ slwi r0, r0, 2
|
||||
/* 803816B8 0037E618 7C A3 02 14 */ add r5, r3, r0
|
||||
/* 803816BC 0037E61C 80 65 00 00 */ lwz r3, 0(r5)
|
||||
|
@ -84,7 +82,7 @@ __OSSetInterruptHandler:
|
|||
.global __OSGetInterruptHandler
|
||||
__OSGetInterruptHandler:
|
||||
/* 803816C8 0037E628 7C 60 07 34 */ extsh r0, r3
|
||||
/* 803816CC 0037E62C 80 6D AD 10 */ lwz r3, lbl_805A98D0@sda21(r13)
|
||||
/* 803816CC 0037E62C 80 6D AD 10 */ lwz r3, InterruptHandlerTable@sda21(r13)
|
||||
/* 803816D0 0037E630 54 00 10 3A */ slwi r0, r0, 2
|
||||
/* 803816D4 0037E634 7C 63 00 2E */ lwzx r3, r3, r0
|
||||
/* 803816D8 0037E638 4E 80 00 20 */ blr
|
||||
|
@ -97,10 +95,10 @@ __OSInterruptInit:
|
|||
/* 803816E8 0037E648 93 E1 00 0C */ stw r31, 0xc(r1)
|
||||
/* 803816EC 0037E64C 3F E0 80 00 */ lis r31, 0x80003040@ha
|
||||
/* 803816F0 0037E650 38 1F 30 40 */ addi r0, r31, 0x80003040@l
|
||||
/* 803816F4 0037E654 90 0D AD 10 */ stw r0, lbl_805A98D0@sda21(r13)
|
||||
/* 803816F4 0037E654 90 0D AD 10 */ stw r0, InterruptHandlerTable@sda21(r13)
|
||||
/* 803816F8 0037E658 38 80 00 00 */ li r4, 0
|
||||
/* 803816FC 0037E65C 38 A0 00 80 */ li r5, 0x80
|
||||
/* 80381700 0037E660 80 6D AD 10 */ lwz r3, lbl_805A98D0@sda21(r13)
|
||||
/* 80381700 0037E660 80 6D AD 10 */ lwz r3, InterruptHandlerTable@sda21(r13)
|
||||
/* 80381704 0037E664 4B C8 1C A5 */ bl memset
|
||||
/* 80381708 0037E668 38 00 00 00 */ li r0, 0
|
||||
/* 8038170C 0037E66C 90 1F 00 C4 */ stw r0, 0xc4(r31)
|
||||
|
@ -619,8 +617,8 @@ lbl_80381DA8:
|
|||
/* 80381DB8 0037ED18 7C 04 18 78 */ andc r4, r0, r3
|
||||
/* 80381DBC 0037ED1C 28 04 00 00 */ cmplwi r4, 0
|
||||
/* 80381DC0 0037ED20 41 82 00 98 */ beq lbl_80381E58
|
||||
/* 80381DC4 0037ED24 3C 60 80 3F */ lis r3, lbl_803F2260@ha
|
||||
/* 80381DC8 0037ED28 38 03 22 60 */ addi r0, r3, lbl_803F2260@l
|
||||
/* 80381DC4 0037ED24 3C 60 80 3F */ lis r3, InterruptPrioTable@ha
|
||||
/* 80381DC8 0037ED28 38 03 22 60 */ addi r0, r3, InterruptPrioTable@l
|
||||
/* 80381DCC 0037ED2C 7C 03 03 78 */ mr r3, r0
|
||||
/* 80381DD0 0037ED30 48 00 00 04 */ b lbl_80381DD4
|
||||
lbl_80381DD4:
|
||||
|
@ -637,19 +635,19 @@ lbl_80381DF4:
|
|||
/* 80381DF4 0037ED54 38 63 00 04 */ addi r3, r3, 4
|
||||
/* 80381DF8 0037ED58 4B FF FF E0 */ b lbl_80381DD8
|
||||
lbl_80381DFC:
|
||||
/* 80381DFC 0037ED5C 80 6D AD 10 */ lwz r3, lbl_805A98D0@sda21(r13)
|
||||
/* 80381DFC 0037ED5C 80 6D AD 10 */ lwz r3, InterruptHandlerTable@sda21(r13)
|
||||
/* 80381E00 0037ED60 57 A0 10 3A */ slwi r0, r29, 2
|
||||
/* 80381E04 0037ED64 7F E3 00 2E */ lwzx r31, r3, r0
|
||||
/* 80381E08 0037ED68 28 1F 00 00 */ cmplwi r31, 0
|
||||
/* 80381E0C 0037ED6C 41 82 00 4C */ beq lbl_80381E58
|
||||
/* 80381E10 0037ED70 2C 1D 00 04 */ cmpwi r29, 4
|
||||
/* 80381E14 0037ED74 40 81 00 1C */ ble lbl_80381E30
|
||||
/* 80381E18 0037ED78 B3 AD AD 18 */ sth r29, lbl_805A98D8@sda21(r13)
|
||||
/* 80381E18 0037ED78 B3 AD AD 18 */ sth r29, __OSLastInterrupt@sda21(r13)
|
||||
/* 80381E1C 0037ED7C 48 00 35 8D */ bl OSGetTime
|
||||
/* 80381E20 0037ED80 90 8D AD 24 */ stw r4, lbl_805A98E4@sda21(r13)
|
||||
/* 80381E24 0037ED84 90 6D AD 20 */ stw r3, lbl_805A98E0@sda21(r13)
|
||||
/* 80381E20 0037ED80 90 8D AD 24 */ stw r4, __OSLastInterruptTime+4@sda21(r13)
|
||||
/* 80381E24 0037ED84 90 6D AD 20 */ stw r3, __OSLastInterruptTime@sda21(r13)
|
||||
/* 80381E28 0037ED88 80 1E 01 98 */ lwz r0, 0x198(r30)
|
||||
/* 80381E2C 0037ED8C 90 0D AD 14 */ stw r0, lbl_805A98D4@sda21(r13)
|
||||
/* 80381E2C 0037ED8C 90 0D AD 14 */ stw r0, __OSLastInterruptSrr0@sda21(r13)
|
||||
lbl_80381E30:
|
||||
/* 80381E30 0037ED90 48 00 27 B1 */ bl OSDisableScheduler
|
||||
/* 80381E34 0037ED94 7F A3 EB 78 */ mr r3, r29
|
||||
|
@ -694,4 +692,3 @@ ExternalInterruptHandler:
|
|||
/* 80381EC0 0037EE20 90 04 01 C0 */ stw r0, 0x1c0(r4)
|
||||
/* 80381EC4 0037EE24 94 21 FF F8 */ stwu r1, -8(r1)
|
||||
/* 80381EC8 0037EE28 4B FF FC 70 */ b __OSDispatchInterrupt
|
||||
|
||||
|
|
|
@ -813,7 +813,7 @@ LIBS = [
|
|||
"Dolphin/os/OSError",
|
||||
"Dolphin/os/OSFatal",
|
||||
"Dolphin/os/OSFont",
|
||||
"Dolphin/os/OSInterrupt",
|
||||
["Dolphin/os/OSInterrupt", True],
|
||||
["Dolphin/os/OSLink", True],
|
||||
"Dolphin/os/OSMemory",
|
||||
["Dolphin/os/OSMutex", True],
|
||||
|
|
|
@ -0,0 +1,433 @@
|
|||
#include <dolphin/os.h>
|
||||
|
||||
static asm void ExternalInterruptHandler(register __OSException exception,
|
||||
register OSContext* context);
|
||||
|
||||
// TODO: Move these to a more appropriate location
|
||||
vu32 __PIRegs[12] : 0xCC003000;
|
||||
vu32 __EXIRegs[16] : 0xCC006800;
|
||||
vu16 __MEMRegs[64] : 0xCC004000;
|
||||
vu16 __DSPRegs[32] : 0xCC005000;
|
||||
vu32 __AIRegs[8] : 0xCC006C00;
|
||||
|
||||
extern void __RAS_OSDisableInterrupts_begin(void);
|
||||
extern void __RAS_OSDisableInterrupts_end(void);
|
||||
|
||||
static __OSInterruptHandler* InterruptHandlerTable;
|
||||
|
||||
static OSInterruptMask InterruptPrioTable[] = {
|
||||
OS_INTERRUPTMASK_PI_ERROR,
|
||||
OS_INTERRUPTMASK_PI_DEBUG,
|
||||
OS_INTERRUPTMASK_MEM,
|
||||
OS_INTERRUPTMASK_PI_RSW,
|
||||
OS_INTERRUPTMASK_PI_VI,
|
||||
OS_INTERRUPTMASK_PI_PE,
|
||||
OS_INTERRUPTMASK_PI_HSP,
|
||||
OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI |
|
||||
OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI,
|
||||
OS_INTERRUPTMASK_DSP_AI,
|
||||
OS_INTERRUPTMASK_PI_CP,
|
||||
0xFFFFFFFF,
|
||||
};
|
||||
|
||||
asm BOOL OSDisableInterrupts(void) {
|
||||
// clang-format off
|
||||
nofralloc
|
||||
entry __RAS_OSDisableInterrupts_begin
|
||||
mfmsr r3
|
||||
rlwinm r4, r3, 0, 17, 15
|
||||
mtmsr r4
|
||||
entry __RAS_OSDisableInterrupts_end
|
||||
rlwinm r3, r3, 17, 31, 31
|
||||
blr
|
||||
// clang-format on
|
||||
}
|
||||
asm BOOL OSEnableInterrupts(void) {
|
||||
// clang-format off
|
||||
nofralloc
|
||||
|
||||
mfmsr r3
|
||||
ori r4, r3, 0x8000
|
||||
mtmsr r4
|
||||
rlwinm r3, r3, 17, 31, 31
|
||||
blr
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
asm BOOL OSRestoreInterrupts(register BOOL level){
|
||||
// clang-format off
|
||||
|
||||
nofralloc
|
||||
|
||||
cmpwi level, 0
|
||||
mfmsr r4
|
||||
beq _disable
|
||||
ori r5, r4, 0x8000
|
||||
b _restore
|
||||
_disable:
|
||||
rlwinm r5, r4, 0, 17, 15
|
||||
_restore:
|
||||
mtmsr r5
|
||||
rlwinm r3, r4, 17, 31, 31
|
||||
blr
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
__OSInterruptHandler
|
||||
__OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) {
|
||||
__OSInterruptHandler oldHandler;
|
||||
|
||||
oldHandler = InterruptHandlerTable[interrupt];
|
||||
InterruptHandlerTable[interrupt] = handler;
|
||||
return oldHandler;
|
||||
}
|
||||
|
||||
__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) {
|
||||
return InterruptHandlerTable[interrupt];
|
||||
}
|
||||
|
||||
void __OSInterruptInit(void) {
|
||||
InterruptHandlerTable = OSPhysicalToCached(0x3040);
|
||||
memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler));
|
||||
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0;
|
||||
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0;
|
||||
|
||||
__PIRegs[1] = 0xf0;
|
||||
|
||||
__OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI |
|
||||
OS_INTERRUPTMASK_EXI | OS_INTERRUPTMASK_PI);
|
||||
|
||||
__OSSetExceptionHandler(4, ExternalInterruptHandler);
|
||||
}
|
||||
|
||||
u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) {
|
||||
u32 reg;
|
||||
|
||||
switch (__cntlzw(mask)) {
|
||||
case __OS_INTERRUPT_MEM_0:
|
||||
case __OS_INTERRUPT_MEM_1:
|
||||
case __OS_INTERRUPT_MEM_2:
|
||||
case __OS_INTERRUPT_MEM_3:
|
||||
case __OS_INTERRUPT_MEM_ADDRESS:
|
||||
reg = 0;
|
||||
if (!(current & OS_INTERRUPTMASK_MEM_0))
|
||||
reg |= 0x1;
|
||||
if (!(current & OS_INTERRUPTMASK_MEM_1))
|
||||
reg |= 0x2;
|
||||
if (!(current & OS_INTERRUPTMASK_MEM_2))
|
||||
reg |= 0x4;
|
||||
if (!(current & OS_INTERRUPTMASK_MEM_3))
|
||||
reg |= 0x8;
|
||||
if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS))
|
||||
reg |= 0x10;
|
||||
__MEMRegs[0x0000000e] = (u16)reg;
|
||||
mask &= ~OS_INTERRUPTMASK_MEM;
|
||||
break;
|
||||
case __OS_INTERRUPT_DSP_AI:
|
||||
case __OS_INTERRUPT_DSP_ARAM:
|
||||
case __OS_INTERRUPT_DSP_DSP:
|
||||
reg = __DSPRegs[0x00000005];
|
||||
reg &= ~0x1F8;
|
||||
if (!(current & OS_INTERRUPTMASK_DSP_AI))
|
||||
reg |= 0x10;
|
||||
if (!(current & OS_INTERRUPTMASK_DSP_ARAM))
|
||||
reg |= 0x40;
|
||||
if (!(current & OS_INTERRUPTMASK_DSP_DSP))
|
||||
reg |= 0x100;
|
||||
__DSPRegs[0x00000005] = (u16)reg;
|
||||
mask &= ~OS_INTERRUPTMASK_DSP;
|
||||
break;
|
||||
case __OS_INTERRUPT_AI_AI:
|
||||
reg = __AIRegs[0];
|
||||
reg &= ~0x2C;
|
||||
if (!(current & OS_INTERRUPTMASK_AI_AI))
|
||||
reg |= 0x4;
|
||||
__AIRegs[0] = reg;
|
||||
mask &= ~OS_INTERRUPTMASK_AI;
|
||||
break;
|
||||
case __OS_INTERRUPT_EXI_0_EXI:
|
||||
case __OS_INTERRUPT_EXI_0_TC:
|
||||
case __OS_INTERRUPT_EXI_0_EXT:
|
||||
reg = __EXIRegs[0];
|
||||
reg &= ~0x2C0F;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_0_EXI))
|
||||
reg |= 0x1;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_0_TC))
|
||||
reg |= 0x4;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_0_EXT))
|
||||
reg |= 0x400;
|
||||
__EXIRegs[0] = reg;
|
||||
mask &= ~OS_INTERRUPTMASK_EXI_0;
|
||||
break;
|
||||
case __OS_INTERRUPT_EXI_1_EXI:
|
||||
case __OS_INTERRUPT_EXI_1_TC:
|
||||
case __OS_INTERRUPT_EXI_1_EXT:
|
||||
reg = __EXIRegs[5];
|
||||
reg &= ~0xC0F;
|
||||
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_1_EXI))
|
||||
reg |= 0x1;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_1_TC))
|
||||
reg |= 0x4;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_1_EXT))
|
||||
reg |= 0x400;
|
||||
__EXIRegs[5] = reg;
|
||||
mask &= ~OS_INTERRUPTMASK_EXI_1;
|
||||
break;
|
||||
case __OS_INTERRUPT_EXI_2_EXI:
|
||||
case __OS_INTERRUPT_EXI_2_TC:
|
||||
reg = __EXIRegs[10];
|
||||
reg &= ~0xF;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_2_EXI))
|
||||
reg |= 0x1;
|
||||
if (!(current & OS_INTERRUPTMASK_EXI_2_TC))
|
||||
reg |= 0x4;
|
||||
|
||||
__EXIRegs[10] = reg;
|
||||
mask &= ~OS_INTERRUPTMASK_EXI_2;
|
||||
break;
|
||||
case __OS_INTERRUPT_PI_CP:
|
||||
case __OS_INTERRUPT_PI_SI:
|
||||
case __OS_INTERRUPT_PI_DI:
|
||||
case __OS_INTERRUPT_PI_RSW:
|
||||
case __OS_INTERRUPT_PI_ERROR:
|
||||
case __OS_INTERRUPT_PI_VI:
|
||||
case __OS_INTERRUPT_PI_DEBUG:
|
||||
case __OS_INTERRUPT_PI_PE_TOKEN:
|
||||
case __OS_INTERRUPT_PI_PE_FINISH:
|
||||
case __OS_INTERRUPT_PI_HSP:
|
||||
reg = 0xF0;
|
||||
|
||||
if (!(current & OS_INTERRUPTMASK_PI_CP)) {
|
||||
reg |= 0x800;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_SI)) {
|
||||
reg |= 0x8;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_DI)) {
|
||||
reg |= 0x4;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_RSW)) {
|
||||
reg |= 0x2;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_ERROR)) {
|
||||
reg |= 0x1;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_VI)) {
|
||||
reg |= 0x100;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) {
|
||||
reg |= 0x1000;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) {
|
||||
reg |= 0x200;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) {
|
||||
reg |= 0x400;
|
||||
}
|
||||
if (!(current & OS_INTERRUPTMASK_PI_HSP)) {
|
||||
reg |= 0x2000;
|
||||
}
|
||||
__PIRegs[1] = reg;
|
||||
mask &= ~OS_INTERRUPTMASK_PI;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
OSInterruptMask OSGetInterruptMask(void) { return *(OSInterruptMask*)OSPhysicalToCached(0x00C8); }
|
||||
|
||||
OSInterruptMask OSSetInterruptMask(OSInterruptMask local) {
|
||||
BOOL enabled;
|
||||
OSInterruptMask global;
|
||||
OSInterruptMask prev;
|
||||
OSInterruptMask mask;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
global = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
|
||||
prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
|
||||
mask = (global | prev) ^ local;
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C8) = local;
|
||||
while (mask) {
|
||||
mask = SetInterruptMask(mask, global | local);
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
|
||||
OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) {
|
||||
BOOL enabled;
|
||||
OSInterruptMask prev;
|
||||
OSInterruptMask local;
|
||||
OSInterruptMask mask;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
|
||||
local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
|
||||
mask = ~(prev | local) & global;
|
||||
global |= prev;
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global;
|
||||
while (mask) {
|
||||
mask = SetInterruptMask(mask, global | local);
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
|
||||
OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) {
|
||||
BOOL enabled;
|
||||
OSInterruptMask prev;
|
||||
OSInterruptMask local;
|
||||
OSInterruptMask mask;
|
||||
|
||||
enabled = OSDisableInterrupts();
|
||||
prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4);
|
||||
local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8);
|
||||
mask = (prev | local) & global;
|
||||
global = prev & ~global;
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global;
|
||||
while (mask) {
|
||||
mask = SetInterruptMask(mask, global | local);
|
||||
}
|
||||
OSRestoreInterrupts(enabled);
|
||||
return prev;
|
||||
}
|
||||
|
||||
volatile OSTime __OSLastInterruptTime;
|
||||
volatile __OSInterrupt __OSLastInterrupt;
|
||||
volatile u32 __OSLastInterruptSrr0;
|
||||
|
||||
void __OSDispatchInterrupt(__OSException exception, OSContext* context) {
|
||||
u32 intsr;
|
||||
u32 reg;
|
||||
OSInterruptMask cause;
|
||||
OSInterruptMask unmasked;
|
||||
OSInterruptMask* prio;
|
||||
__OSInterrupt interrupt;
|
||||
__OSInterruptHandler handler;
|
||||
intsr = __PIRegs[0];
|
||||
intsr &= ~0x00010000;
|
||||
|
||||
if (intsr == 0 || (intsr & __PIRegs[1]) == 0) {
|
||||
OSLoadContext(context);
|
||||
}
|
||||
|
||||
cause = 0;
|
||||
|
||||
if (intsr & 0x00000080) {
|
||||
reg = __MEMRegs[15];
|
||||
if (reg & 0x1)
|
||||
cause |= OS_INTERRUPTMASK_MEM_0;
|
||||
if (reg & 0x2)
|
||||
cause |= OS_INTERRUPTMASK_MEM_1;
|
||||
if (reg & 0x4)
|
||||
cause |= OS_INTERRUPTMASK_MEM_2;
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_MEM_3;
|
||||
if (reg & 0x10)
|
||||
cause |= OS_INTERRUPTMASK_MEM_ADDRESS;
|
||||
}
|
||||
|
||||
if (intsr & 0x00000040) {
|
||||
reg = __DSPRegs[5];
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_DSP_AI;
|
||||
if (reg & 0x20)
|
||||
cause |= OS_INTERRUPTMASK_DSP_ARAM;
|
||||
if (reg & 0x80)
|
||||
cause |= OS_INTERRUPTMASK_DSP_DSP;
|
||||
}
|
||||
|
||||
if (intsr & 0x00000020) {
|
||||
reg = __AIRegs[0];
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_AI_AI;
|
||||
}
|
||||
|
||||
if (intsr & 0x00000010) {
|
||||
reg = __EXIRegs[0];
|
||||
if (reg & 0x2)
|
||||
cause |= OS_INTERRUPTMASK_EXI_0_EXI;
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_EXI_0_TC;
|
||||
if (reg & 0x800)
|
||||
cause |= OS_INTERRUPTMASK_EXI_0_EXT;
|
||||
reg = __EXIRegs[5];
|
||||
if (reg & 0x2)
|
||||
cause |= OS_INTERRUPTMASK_EXI_1_EXI;
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_EXI_1_TC;
|
||||
if (reg & 0x800)
|
||||
cause |= OS_INTERRUPTMASK_EXI_1_EXT;
|
||||
reg = __EXIRegs[10];
|
||||
if (reg & 0x2)
|
||||
cause |= OS_INTERRUPTMASK_EXI_2_EXI;
|
||||
if (reg & 0x8)
|
||||
cause |= OS_INTERRUPTMASK_EXI_2_TC;
|
||||
}
|
||||
|
||||
if (intsr & 0x00002000)
|
||||
cause |= OS_INTERRUPTMASK_PI_HSP;
|
||||
if (intsr & 0x00001000)
|
||||
cause |= OS_INTERRUPTMASK_PI_DEBUG;
|
||||
if (intsr & 0x00000400)
|
||||
cause |= OS_INTERRUPTMASK_PI_PE_FINISH;
|
||||
if (intsr & 0x00000200)
|
||||
cause |= OS_INTERRUPTMASK_PI_PE_TOKEN;
|
||||
if (intsr & 0x00000100)
|
||||
cause |= OS_INTERRUPTMASK_PI_VI;
|
||||
if (intsr & 0x00000008)
|
||||
cause |= OS_INTERRUPTMASK_PI_SI;
|
||||
if (intsr & 0x00000004)
|
||||
cause |= OS_INTERRUPTMASK_PI_DI;
|
||||
if (intsr & 0x00000002)
|
||||
cause |= OS_INTERRUPTMASK_PI_RSW;
|
||||
if (intsr & 0x00000800)
|
||||
cause |= OS_INTERRUPTMASK_PI_CP;
|
||||
if (intsr & 0x00000001)
|
||||
cause |= OS_INTERRUPTMASK_PI_ERROR;
|
||||
|
||||
unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) |
|
||||
*(OSInterruptMask*)OSPhysicalToCached(0x00C8));
|
||||
if (unmasked) {
|
||||
for (prio = InterruptPrioTable;; ++prio) {
|
||||
if (unmasked & *prio) {
|
||||
interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
handler = __OSGetInterruptHandler(interrupt);
|
||||
if (handler) {
|
||||
if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) {
|
||||
__OSLastInterrupt = interrupt;
|
||||
__OSLastInterruptTime = OSGetTime();
|
||||
__OSLastInterruptSrr0 = context->srr0;
|
||||
}
|
||||
|
||||
OSDisableScheduler();
|
||||
handler(interrupt, context);
|
||||
OSEnableScheduler();
|
||||
__OSReschedule();
|
||||
OSLoadContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
OSLoadContext(context);
|
||||
}
|
||||
|
||||
static asm void ExternalInterruptHandler(register __OSException exception,
|
||||
register OSContext* context) {
|
||||
#pragma unused(exception)
|
||||
// clang-format off
|
||||
nofralloc
|
||||
OS_EXCEPTION_SAVE_GPRS(context)
|
||||
|
||||
stwu r1, -8(r1)
|
||||
b __OSDispatchInterrupt
|
||||
// clang-format on
|
||||
}
|
Loading…
Reference in New Issue