ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
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
18 static u32* g_pSyscallTable = NULL;
19 
21 static 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) { EIntr(); }
32 }
33 
38 void *GetSyscallHandler(int syscall_no)
39 {
40  u32 oldintr, oldop;
41  u32 addr = 0;
42 
43  if(g_pSyscallTable == NULL)
44  {
45  InitSyscallTable();
46  }
47 
48  if(g_pSyscallTable != NULL)
49  {
50  oldintr = DIntr();
51  oldop = ee_set_opmode(0);
52  addr = g_pSyscallTable[syscall_no];
53  ee_set_opmode(oldop);
54  if(oldintr) { EIntr(); }
55  }
56 
57  return (void *) addr;
58 }
59 #endif
60 
61 #ifdef F_GetSyscall
66 void *GetSyscall(int syscall_no) { return(GetSyscallHandler(syscall_no)); }
67 #endif
68 
69 #ifdef F_GetExceptionHandler
70 
71 extern void *GetSyscallHandler(int syscall_no);
72 
77 void *GetExceptionHandler(int ex_cause_no)
78 {
79  u32 oldintr, oldop;
80  u32 addr, table_addr;
81  u16 lo16, hi16;
82 
83  if((ex_cause_no < 1) || (ex_cause_no > 15))
84  {
85  return(NULL);
86  }
87 
88  // get address of the syscall "SetVTLBRefillHandler"
89  addr = (u32)GetSyscallHandler(13);
90 
91  // suspend interrupts and enter "kernel" operating mode.
92  oldintr = DIntr();
93  oldop = ee_set_opmode(0);
94 
95  // harvest the address of the exception handler table.
96  lo16 = ((vu32 *) addr)[0x20 / 4];
97  hi16 = ((vu32 *) addr)[0x14 / 4];
98  table_addr = ((u32) (hi16 << 16) | lo16);
99 
100  addr = ((u32 *) table_addr)[ex_cause_no];
101 
102  // return to the old operating mode and resume interrupts.
103  ee_set_opmode(oldop);
104  if(oldintr) { EIntr(); }
105 
106  return((void *) addr);
107 }
108 #endif
109 
110 #ifdef F_GetInterruptHandler
111 
112 extern void *GetSyscallHandler(int syscall_no);
113 
118 void *GetInterruptHandler(int intr_cause_no)
119 {
120  u32 oldintr, oldop;
121  u32 addr;
122  u16 lo16, hi16;
123 
124  // make sure intr_cause_no is between 0 and 7
125  if((intr_cause_no < 0) || (intr_cause_no > 7))
126  {
127  return(NULL);
128  }
129 
130  // get address of the syscall "SetVInterruptHandler"
131  addr = (u32) GetSyscallHandler(15);
132 
133  // suspend interrupts and enter "kernel" operating mode.
134  oldintr = DIntr();
135  oldop = ee_set_opmode(0);
136 
137  // harvest the address of the corresponding exception handler table.
138  hi16 = ((vu32 *) addr)[0x10 / 4];
139  lo16 = ((vu32 *) addr)[0x1C / 4];
140 
141  addr = ((u32 *) ((u32) (hi16 << 16) | lo16))[intr_cause_no];
142 
143  // return to the old operating mode and resume interrupts.
144  ee_set_opmode(oldop);
145  if(oldintr) { EIntr(); }
146 
147  return (void *) addr;
148 }
149 #endif
150 
static int ee_set_opmode(u32 opmode)
Definition: kernel.h:163
void * GetSyscallHandler(int syscall_no)
void * GetInterruptHandler(int intr_no)
int DIntr(void)
void * GetExceptionHandler(int except_no)
int EIntr(void)
#define NULL
Definition: tamtypes.h:91
unsigned int u32
Definition: tamtypes.h:30
unsigned short u16
Definition: tamtypes.h:24
volatile u32 vu32
Definition: tamtypes.h:38