PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
getkernel.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Licenced under Academic Free License version 2.0
7# Review ps2sdk README & LICENSE files for further details.
8*/
9
15#include <kernel.h>
16
17#ifdef F_GetSyscallHandler
18static u32 *g_pSyscallTable = NULL;
19
21static void InitSyscallTable(void)
22{
23 u32 oldintr, oldop;
24 u32 *pAddr;
25
26 oldintr = DIntr();
27 oldop = ee_set_opmode(0);
28 pAddr = (u32 *)0x800002f0;
29 g_pSyscallTable = (u32 *)((pAddr[0] << 16) | (pAddr[2] & 0xFFFF));
30 ee_set_opmode(oldop);
31 if (oldintr) {
32 EIntr();
33 }
34}
35
40void *GetSyscallHandler(int syscall_no)
41{
42 u32 oldintr, oldop;
43 u32 addr = 0;
44
45 if (g_pSyscallTable == NULL) {
46 InitSyscallTable();
47 }
48
49 if (g_pSyscallTable != NULL) {
50 oldintr = DIntr();
51 oldop = ee_set_opmode(0);
52 addr = g_pSyscallTable[syscall_no];
53 ee_set_opmode(oldop);
54 if (oldintr) {
55 EIntr();
56 }
57 }
58
59 return (void *)addr;
60}
61#endif
62
63#ifdef F_GetSyscall
68void *GetSyscall(int syscall_no) { return (GetSyscallHandler(syscall_no)); }
69#endif
70
71#ifdef F_GetExceptionHandler
72
73extern void *GetSyscallHandler(int syscall_no);
74
79void *GetExceptionHandler(int ex_cause_no)
80{
81 u32 oldintr, oldop;
82 u32 addr, table_addr;
83 u16 lo16, hi16;
84
85 if ((ex_cause_no < 1) || (ex_cause_no > 15)) {
86 return (NULL);
87 }
88
89 // get address of the syscall "SetVTLBRefillHandler"
90 addr = (u32)GetSyscallHandler(13);
91
92 // suspend interrupts and enter "kernel" operating mode.
93 oldintr = DIntr();
94 oldop = ee_set_opmode(0);
95
96 // harvest the address of the exception handler table.
97 lo16 = ((vu32 *)addr)[0x20 / 4];
98 hi16 = ((vu32 *)addr)[0x14 / 4];
99 table_addr = ((u32)(hi16 << 16) | lo16);
100
101 addr = ((u32 *)table_addr)[ex_cause_no];
102
103 // return to the old operating mode and resume interrupts.
104 ee_set_opmode(oldop);
105 if (oldintr) {
106 EIntr();
107 }
108
109 return ((void *)addr);
110}
111#endif
112
113#ifdef F_GetInterruptHandler
114
115extern void *GetSyscallHandler(int syscall_no);
116
121void *GetInterruptHandler(int intr_cause_no)
122{
123 u32 oldintr, oldop;
124 u32 addr;
125 u16 lo16, hi16;
126
127 // make sure intr_cause_no is between 0 and 7
128 if ((intr_cause_no < 0) || (intr_cause_no > 7)) {
129 return (NULL);
130 }
131
132 // get address of the syscall "SetVInterruptHandler"
133 addr = (u32)GetSyscallHandler(15);
134
135 // suspend interrupts and enter "kernel" operating mode.
136 oldintr = DIntr();
137 oldop = ee_set_opmode(0);
138
139 // harvest the address of the corresponding exception handler table.
140 hi16 = ((vu32 *)addr)[0x10 / 4];
141 lo16 = ((vu32 *)addr)[0x1C / 4];
142
143 addr = ((u32 *)((u32)(hi16 << 16) | lo16))[intr_cause_no];
144
145 // return to the old operating mode and resume interrupts.
146 ee_set_opmode(oldop);
147 if (oldintr) {
148 EIntr();
149 }
150
151 return (void *)addr;
152}
153#endif