arm7 OS_interrupt

This commit is contained in:
red031000 2020-06-14 21:47:39 +01:00
parent 30c442497e
commit c734347a8f
No known key found for this signature in database
GPG Key ID: A3C87CFF2DC536C2
19 changed files with 362 additions and 341 deletions

View File

@ -1,173 +0,0 @@
.include "asm/macros.inc"
.include "global.inc"
.section .bss
.global _03807744
_03807744: ;0x03807744
.space 0x03807748 - 0x03807744
.global _03807748
_03807748: ;0x03807748
.space 0x0380774C - 0x03807748
.global _0380774C
_0380774C: ;0x0380774C
.space 0x03807774 - 0x0380774C
.global _03807774
_03807774: ;0x03807774
.space 0x03807780 - 0x03807774
.section .text
arm_func_start OS_ResetRequestIrqMask
OS_ResetRequestIrqMask: ; 0x037F8824
ldr ip, _037F8850 ; =0x04000208
ldrh r3, [ip]
mov r1, #0
strh r1, [ip]
ldr r2, _037F8854 ; =0x04000214
ldr r1, [r2]
str r0, [r2]
ldrh r0, [ip]
strh r3, [ip]
mov r0, r1
bx lr
_037F8850: .word 0x04000208
_037F8854: .word 0x04000214
arm_func_start OS_DisableIrqMask
OS_DisableIrqMask: ; 0x037F8858
ldr ip, _037F888C ; =0x04000208
ldrh r3, [ip]
mov r1, #0
strh r1, [ip]
ldr r2, _037F8890 ; =0x04000210
ldr r1, [r2]
mvn r0, r0
and r0, r1, r0
str r0, [r2]
ldrh r0, [ip]
strh r3, [ip]
mov r0, r1
bx lr
_037F888C: .word 0x04000208
_037F8890: .word 0x04000210
arm_func_start OS_EnableIrqMask
OS_EnableIrqMask: ; 0x037F8894
ldr ip, _037F88C4 ; =0x04000208
ldrh r3, [ip]
mov r1, #0
strh r1, [ip]
ldr r2, _037F88C8 ; =0x04000210
ldr r1, [r2]
orr r0, r1, r0
str r0, [r2]
ldrh r0, [ip]
strh r3, [ip]
mov r0, r1
bx lr
_037F88C4: .word 0x04000208
_037F88C8: .word 0x04000210
arm_func_start OS_SetIrqMask
OS_SetIrqMask: ; 0x037F88CC
ldr ip, _037F88F8 ; =0x04000208
ldrh r3, [ip]
mov r1, #0
strh r1, [ip]
ldr r2, _037F88FC ; =0x04000210
ldr r1, [r2]
str r0, [r2]
ldrh r0, [ip]
strh r3, [ip]
mov r0, r1
bx lr
_037F88F8: .word 0x04000208
_037F88FC: .word 0x04000210
arm_func_start OSi_EnterTimerCallback
OSi_EnterTimerCallback: ; 0x037F8900
stmdb sp!, {r4, lr}
mov r3, #12
mul r4, r0, r3
ldr r3, _037F8940 ; =_03807744
str r1, [r3, r4]
ldr r1, _037F8944 ; =_0380774C
str r2, [r1, r4]
mov r1, #1
add r0, r0, #3
mov r0, r1, lsl r0
bl OS_EnableIrqMask
mov r1, #1
ldr r0, _037F8948 ; =_03807748
str r1, [r0, r4]
ldmia sp!, {r4, lr}
bx lr
_037F8940: .word _03807744
_037F8944: .word _0380774C
_037F8948: .word _03807748
arm_func_start OS_SetIrqFunction
OS_SetIrqFunction: ; 0x037F894C
stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
sub sp, sp, #4
mov r9, #0
mov r7, r9
ldr lr, _037F89E8 ; =OS_IRQTable
ldr r4, _037F89EC ; =_03807774
ldr r6, _037F89F0 ; =OSi_IrqCallbackInfo
mov ip, r9
mov r3, #1
mov r2, #12
_037F8974:
ands r5, r0, #1
beq _037F89CC
mov r8, r7
cmp r9, #8
blt _037F8998
cmp r9, #11
suble r5, r9, #8
mlale r8, r5, r2, r6
ble _037F89BC
_037F8998:
cmp r9, #3
blt _037F89B0
cmp r9, #6
addle r5, r9, #1
mlale r8, r5, r2, r6
ble _037F89BC
_037F89B0:
cmp r9, #0
moveq r8, r4
strne r1, [lr, r9, lsl #2]
_037F89BC:
cmp r8, #0
strne r1, [r8]
strne ip, [r8, #8]
strne r3, [r8, #4]
_037F89CC:
mov r0, r0, lsr #1
add r9, r9, #1
cmp r9, #25
blt _037F8974
add sp, sp, #4
ldmia sp!, {r4, r5, r6, r7, r8, r9, lr}
bx lr
_037F89E8: .word OS_IRQTable
_037F89EC: .word _03807774
_037F89F0: .word OSi_IrqCallbackInfo
arm_func_start OS_InitIrqTable
OS_InitIrqTable: ; 0x037F89F4
mov r1, #0
ldr r0, _037F8A10 ; =OSi_IrqThreadQueue
str r1, [r0, #4]
str r1, [r0]
ldr r0, _037F8A14 ; =0x027FFC3C
str r1, [r0]
bx lr
_037F8A10: .word OSi_IrqThreadQueue
_037F8A14: .word 0x027FFC3C

View File

@ -1,44 +1,6 @@
.include "asm/macros.inc"
.include "global.inc"
.section .data
.global _038075E4
_038075E4:
.word 0x00090008
.word 0x000B000A
.word 0x00040003
.word 0x00060005
.word 0x00000000
.global OS_IRQTable
OS_IRQTable:
.word OSi_IrqVBlank
.word OS_IrqDummy
.word OS_IrqDummy
.word OSi_IrqTimer0
.word OSi_IrqTimer1
.word OSi_IrqTimer2
.word OSi_IrqTimer3
.word OS_IrqDummy
.word OSi_IrqDma0
.word OSi_IrqDma1
.word OSi_IrqDma2
.word OSi_IrqDma3
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.section .text
arm_func_start OS_IrqHandler

View File

@ -1,6 +1,44 @@
.include "asm/macros.inc"
.include "global.inc"
.section .data
.global _038075E4
_038075E4:
.word 0x00090008
.word 0x000B000A
.word 0x00040003
.word 0x00060005
.word 0x00000000
.global OS_IRQTable
OS_IRQTable:
.word OSi_IrqVBlank
.word OS_IrqDummy
.word OS_IrqDummy
.word OSi_IrqTimer0
.word OSi_IrqTimer1
.word OSi_IrqTimer2
.word OSi_IrqTimer3
.word OS_IrqDummy
.word OSi_IrqDma0
.word OSi_IrqDma1
.word OSi_IrqDma2
.word OSi_IrqDma3
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.word OS_IrqDummy
.section .bss
.global OSi_IrqThreadQueue
@ -19,6 +57,22 @@ _03807718: ;0x03807718
_0380771C: ;0x0380771C
.space 0x03807744 - 0x0380771C
.global _03807744
_03807744: ;0x03807744
.space 0x03807748 - 0x03807744
.global _03807748
_03807748: ;0x03807748
.space 0x0380774C - 0x03807748
.global _0380774C
_0380774C: ;0x0380774C
.space 0x03807774 - 0x0380774C
.global _03807774
_03807774: ;0x03807774
.space 0x03807780 - 0x03807774
.section .text
arm_func_start OSi_IrqVBlank

View File

@ -0,0 +1,16 @@
#ifndef POKEDIAMOND_ARM7_OS_CONTEXT_H
#define POKEDIAMOND_ARM7_OS_CONTEXT_H
#include "nitro/types.h"
typedef struct OSContext
{
u32 cpsr;
u32 r[13];
u32 sp;
u32 lr;
u32 pc_plus4;
u32 sp_svc;
} OSContext;
#endif //POKEDIAMOND_ARM7_OS_CONTEXT_H

View File

@ -7,6 +7,9 @@
#include "OS_alloc.h"
#include "OS_reset.h"
#include "OS_terminate_proc.h"
#include "OS_spinLock.h"
#include "OS_context.h"
#include "OS_interrupt.h"
void OS_Init(void);

View File

@ -2,5 +2,22 @@
#define POKEDIAMOND_ARM7_OS_INTERRUPT_H
#include "nitro/OS_interrupt_shared.h"
#include "consts.h"
extern OSIrqFunction OS_IRQTable[];
extern OSIrqCallbackInfo OSi_IrqCallbackInfo[9];
static inline void OSi_SetVBlankCount(u32 count)
{
*(u32 *)HW_VBLANK_COUNT_BUF = count;
}
void OS_InitIrqTable(void);
void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function);
void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg);
OSIrqMask OS_SetIrqMask(OSIrqMask mask);
OSIrqMask OS_EnableIrqMask(OSIrqMask mask);
OSIrqMask OS_DisableIrqMask(OSIrqMask mask);
OSIrqMask OS_ResetRequestIrqMask(OSIrqMask mask);
#endif //POKEDIAMOND_ARM7_OS_INTERRUPT_H

View File

@ -0,0 +1,7 @@
#ifndef POKEDIAMOND_ARM7_OS_THREAD_H
#define POKEDIAMOND_ARM7_OS_THREAD_H
#include "OS_context.h"
#include "nitro/OS_thread_shared.h"
#endif //POKEDIAMOND_ARM7_OS_THREAD_H

View File

@ -3,5 +3,6 @@
#include "nitro/consts_shared.h"
#include "mmap.h"
#include "registers.h"
#endif //POKEDIAMOND_ARM7_CONSTS_H

View File

@ -23,6 +23,7 @@
#define HW_PRV_WRAM_SYSRV (HW_PRV_WRAM + HW_PRV_WRAM_SIZE - HW_PRV_WRAM_SYSRV_SIZE)
#define HW_VBLANK_COUNT_BUF (HW_MAIN_MEM + 0x007ffc3c)
#define HW_LOCK_ID_FLAG_SUB (HW_MAIN_MEM + 0x007fffb8)
#endif //POKEDIAMOND_ARM7_MMAP_H

View File

@ -0,0 +1,6 @@
#ifndef POKEDIAMOND_ARM7_REGISTERS_H
#define POKEDIAMOND_ARM7_REGISTERS_H
#include "nitro/registers_shared.h"
#endif //POKEDIAMOND_ARM7_REGISTERS_H

View File

@ -2,8 +2,6 @@
#include "OS_init.h"
extern void PXI_Init(void);
extern void OS_InitLock(void);
extern void OS_InitIrqTable(void);
extern void OS_InitTick(void);
extern void OS_InitAlarm(void);
extern void OS_InitThread(void);

106
arm7/lib/src/OS_interrupt.c Normal file
View File

@ -0,0 +1,106 @@
#include "function_target.h"
#include "consts.h"
#include "OS_interrupt.h"
#include "OS_thread.h"
extern OSThreadQueue OSi_IrqThreadQueue;
ARM_FUNC void OS_InitIrqTable(void)
{
OS_InitThreadQueue(&OSi_IrqThreadQueue);
OSi_SetVBlankCount(0);
}
ARM_FUNC void OS_SetIrqFunction(OSIrqMask intrBit, OSIrqFunction function)
{
s32 i;
OSIrqCallbackInfo *info;
for (i = 0; i < 25; i++)
{
if (intrBit & 1)
{
info = NULL;
if (8 <= i && i <= 11)
{
info = &OSi_IrqCallbackInfo[i - 8];
}
else if (3 <= i && i <= 6)
{
info = &OSi_IrqCallbackInfo[i - 3 + 4];
}
else if (0 == i)
{
info = &OSi_IrqCallbackInfo[8];
}
else
{
OS_IRQTable[i] = function;
}
if (info)
{
info->func = (void (*)(void *))function;
info->arg = 0;
info->enable = TRUE;
}
}
intrBit >>= 1;
}
}
ARM_FUNC void OSi_EnterTimerCallback(u32 timerNo, void (*callback) (void *), void *arg)
{
OSIrqMask mask = 1UL << (timerNo + 3);
OSi_IrqCallbackInfo[timerNo + 4].func = callback;
OSi_IrqCallbackInfo[timerNo + 4].arg = arg;
(void)OS_EnableIrqMask(mask);
OSi_IrqCallbackInfo[timerNo + 4].enable = TRUE;
}
ARM_FUNC OSIrqMask OS_SetIrqMask(OSIrqMask mask)
{
u16 regIme = reg_OS_IME;
reg_OS_IME = 0;
OSIrqMask regIe = reg_OS_IE;
reg_OS_IE = mask;
u16 unused = reg_OS_IME; //needed because otherwise it doesn't match
reg_OS_IME = regIme;
return regIe;
}
ARM_FUNC OSIrqMask OS_EnableIrqMask(OSIrqMask mask)
{
u16 regIme = reg_OS_IME;
reg_OS_IME = 0;
OSIrqMask regIe = reg_OS_IE;
reg_OS_IE = regIe | mask;
u16 unused = reg_OS_IME;
reg_OS_IME = regIme;
return regIe;
}
ARM_FUNC OSIrqMask OS_DisableIrqMask(OSIrqMask mask)
{
u16 regIme = reg_OS_IME;
reg_OS_IME = 0;
OSIrqMask regIe = reg_OS_IE;
reg_OS_IE = regIe & ~mask;
u16 unused = reg_OS_IME;
reg_OS_IME = regIme;
return regIe;
}
ARM_FUNC OSIrqMask OS_ResetRequestIrqMask(OSIrqMask mask)
{
u16 regIme = reg_OS_IME;
reg_OS_IME = 0;
OSIrqMask regIf = reg_OS_IF;
reg_OS_IF = mask;
u16 unused = reg_OS_IME;
reg_OS_IME = regIme;
return regIf;
}

View File

@ -6,15 +6,6 @@
#define OS_IE_TIMER0 (1UL << REG_OS_IE_T0_SHIFT)
typedef void (*OSIrqFunction) (void);
typedef struct
{
void (*func) (void *);
u32 enable;
void* arg;
} OSIrqCallbackInfo;
extern OSIrqFunction OS_IRQTable[];
extern OSIrqCallbackInfo OSi_IrqCallbackInfo[8];

View File

@ -1,89 +1,9 @@
#ifndef POKEDIAMOND_OS_THREAD_H
#define POKEDIAMOND_OS_THREAD_H
#ifndef POKEDIAMOND_ARM9_OS_THREAD_H
#define POKEDIAMOND_ARM9_OS_THREAD_H
#include "nitro/types.h"
#include "OS_context.h"
typedef struct OSiAlarm OSAlarm;
typedef struct _OSThread OSThread;
typedef struct _OSThreadQueue OSThreadQueue;
typedef struct _OSThreadLink OSThreadLink;
typedef struct _OSMutexQueue OSMutexQueue;
typedef struct _OSMutexLink OSMutexLink;
typedef struct OSMutex OSMutex;
struct _OSThreadQueue
{
OSThread *head;
OSThread *tail;
};
struct _OSThreadLink
{
OSThread *prev;
OSThread *next;
};
struct _OSMutexQueue
{
OSMutex *head;
OSMutex *tail;
};
struct _OSMutexLink
{
OSMutex *next;
OSMutex *prev;
};
typedef struct OSThreadInfo {
u16 isNeedRescheduling;
u16 irqDepth;
OSThread* current;
OSThread* list;
void* switchCallback; // type: OSSwitchThreadCallback
} OSThreadInfo;
typedef enum {
OS_THREAD_STATE_WAITING = 0,
OS_THREAD_STATE_READY = 1,
OS_THREAD_STATE_TERMINATED = 2
} OSThreadState;
typedef void (*OSSwitchThreadCallback) (OSThread *from, OSThread *to);
typedef void (*OSThreadDestructor) (void *);
struct _OSThread
{
OSContext context;
OSThreadState state;
OSThread *next;
u32 id;
u32 priority;
void *profiler;
OSThreadQueue *queue;
OSThreadLink link;
OSMutex *mutex;
OSMutexQueue mutexQueue;
u32 stackTop;
u32 stackBottom;
u32 stackWarningOffset;
OSThreadQueue joinQueue;
void *specific[3];
OSAlarm *alarmForSleep;
OSThreadDestructor destructor;
void *userParameter;
u32 systemErrno;
};
#include "nitro/OS_thread_shared.h"
static s32 OSi_GetUnusedThreadId(void);
static void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread);
@ -119,33 +39,4 @@ u32 OS_DisableScheduler(void);
u32 OS_EnableScheduler(void);
void OS_SetThreadDestructor(OSThread *thread, OSThreadDestructor dtor);
extern OSThreadInfo OSi_ThreadInfo;
static inline OSThreadInfo *OS_GetThreadInfo(void)
{
return &OSi_ThreadInfo;
}
static inline BOOL OS_IsThreadRunnable(const OSThread *thread)
{
return thread->state == OS_THREAD_STATE_READY;
}
static inline void OS_InitThreadQueue(OSThreadQueue * queue)
{
queue->head = queue->tail = NULL;
}
static inline OSThread *OS_GetCurrentThread(void)
{
return OS_GetThreadInfo()->current;
}
static inline void OS_SetCurrentThread(OSThread *thread)
{
OS_GetThreadInfo()->current = thread;
}
#define OSi_GetCurrentThread() (*OSi_CurrentThreadPtr)
#endif //POKEDIAMOND_OS_THREAD_H
#endif //POKEDIAMOND_ARM9_OS_THREAD_H

View File

@ -1,7 +1,8 @@
#ifndef POKEDIAMOND_REGISTERS_H
#define POKEDIAMOND_REGISTERS_H
#ifndef POKEDIAMOND_ARM9_REGISTERS_H
#define POKEDIAMOND_ARM9_REGISTERS_H
#include "nitro/types.h"
#include "nitro/registers_shared.h"
#define reg_GX_DISPCNT (*(REGType32v *)0x4000000)
#define reg_GX_DISPSTAT (*(REGType16v *)0x4000004)
@ -103,9 +104,6 @@
#define reg_MI_MCCMD1 (*(REGType32v *)0x40001ac)
#define reg_MI_EXMEMCNT (*(REGType16v *)0x4000204)
#define reg_OS_IME (*(REGType16v *)0x4000208)
#define reg_OS_IE (*(REGType32v *)0x4000210)
#define reg_OS_IF (*(REGType32v *)0x4000214)
#define reg_OS_PAUSE (*(REGType16v *)0x4000300)
#define reg_GX_VRAMCNT (*(REGType32v *)0x4000240)
@ -482,4 +480,4 @@
((u32)(a) << REG_PAD_KEYCNT_A_SHIFT))
#endif
#endif //POKEDIAMOND_REGISTERS_H
#endif //POKEDIAMOND_ARM9_REGISTERS_H

View File

@ -17,4 +17,13 @@
typedef u32 OSIrqMask;
typedef void (*OSIrqFunction) (void);
typedef struct
{
void (*func) (void *);
u32 enable;
void* arg;
} OSIrqCallbackInfo;
#endif //POKEDIAMOND_OS_INTERRUPT_SHARED_H

View File

@ -0,0 +1,116 @@
#ifndef POKEDIAMOND_OS_THREAD_SHARED_H
#define POKEDIAMOND_OS_THREAD_SHARED_H
#include "nitro/types.h"
typedef struct OSiAlarm OSAlarm;
typedef struct _OSThread OSThread;
typedef struct _OSThreadQueue OSThreadQueue;
typedef struct _OSThreadLink OSThreadLink;
typedef struct _OSMutexQueue OSMutexQueue;
typedef struct _OSMutexLink OSMutexLink;
typedef struct OSMutex OSMutex;
struct _OSThreadQueue
{
OSThread *head;
OSThread *tail;
};
struct _OSThreadLink
{
OSThread *prev;
OSThread *next;
};
struct _OSMutexQueue
{
OSMutex *head;
OSMutex *tail;
};
struct _OSMutexLink
{
OSMutex *next;
OSMutex *prev;
};
typedef struct OSThreadInfo {
u16 isNeedRescheduling;
u16 irqDepth;
OSThread* current;
OSThread* list;
void* switchCallback; // type: OSSwitchThreadCallback
} OSThreadInfo;
typedef enum {
OS_THREAD_STATE_WAITING = 0,
OS_THREAD_STATE_READY = 1,
OS_THREAD_STATE_TERMINATED = 2
} OSThreadState;
typedef void (*OSSwitchThreadCallback) (OSThread *from, OSThread *to);
typedef void (*OSThreadDestructor) (void *);
struct _OSThread
{
OSContext context;
OSThreadState state;
OSThread *next;
u32 id;
u32 priority;
void *profiler;
OSThreadQueue *queue;
OSThreadLink link;
OSMutex *mutex;
OSMutexQueue mutexQueue;
u32 stackTop;
u32 stackBottom;
u32 stackWarningOffset;
OSThreadQueue joinQueue;
void *specific[3];
OSAlarm *alarmForSleep;
OSThreadDestructor destructor;
void *userParameter;
u32 systemErrno;
};
extern OSThreadInfo OSi_ThreadInfo;
static inline OSThreadInfo *OS_GetThreadInfo(void)
{
return &OSi_ThreadInfo;
}
static inline BOOL OS_IsThreadRunnable(const OSThread *thread)
{
return thread->state == OS_THREAD_STATE_READY;
}
static inline void OS_InitThreadQueue(OSThreadQueue * queue)
{
queue->head = queue->tail = NULL;
}
static inline OSThread *OS_GetCurrentThread(void)
{
return OS_GetThreadInfo()->current;
}
static inline void OS_SetCurrentThread(OSThread *thread)
{
OS_GetThreadInfo()->current = thread;
}
#define OSi_GetCurrentThread() (*OSi_CurrentThreadPtr)
#endif //POKEDIAMOND_OS_THREAD_SHARED_H

View File

@ -15,6 +15,7 @@
#include "nitro/types.h"
#include "nitro/mmap_shared.h"
#include "nitro/registers_shared.h"
//Shared Consts

View File

@ -0,0 +1,17 @@
/*
* NOTE:
* This file is shared between ARM9 and ARM7
* DO NOT PUT PROC SPECIFIC CODE IN HERE
* Thank You!
*/
#ifndef POKEDIAMOND_REGISTERS_SHARED_H
#define POKEDIAMOND_REGISTERS_SHARED_H
#include "nitro/types.h"
#define reg_OS_IME (*(REGType16v *)0x4000208)
#define reg_OS_IE (*(REGType32v *)0x4000210)
#define reg_OS_IF (*(REGType32v *)0x4000214)
#endif //POKEDIAMOND_REGISTERS_SHARED_H