PS2SDK
PS2 Homebrew Libraries
sbusintr.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
16 #include "types.h"
17 #include "defs.h"
18 #include "irx.h"
19 
20 #include "loadcore.h"
21 #include "intrman.h"
22 #include "sifman.h"
23 #include "sbusintr.h"
24 
25 IRX_ID("sbusintr", 1, 1);
26 
27 static struct {
28  sbus_intr_handler_t handler;
29  void *arg;
30 } sbus_handler_table[32];
31 
32 extern struct irx_export_table _exp_sbusintr;
33 
34 int _start(int argc, char *argv[])
35 {
36  (void)argc;
37  (void)argv;
38 
39  if (RegisterLibraryEntries(&_exp_sbusintr) != 0)
40  return MODULE_NO_RESIDENT_END;
41 
42  return MODULE_RESIDENT_END;
43 }
44 
45 static int sbus_dispatch(void *arg)
46 {
47  u32 msflag, irq;
48 
49  (void)arg;
50 
51  if (!(msflag = sceSifGetMSFlag()))
52  return 1;
53 
54  for (irq = 0; msflag != 0 && irq < 32; irq++, msflag >>= 1) {
55  if (!(msflag & 1))
56  continue;
57 
58  /* "Acknowledge" the interrupt */
59  sceSifSetMSFlag(1 << irq);
60 
61  if (sbus_handler_table[irq].handler)
62  sbus_handler_table[irq].handler(irq,
63  sbus_handler_table[irq].arg);
64  }
65 
66  return 1;
67 }
68 
69 int sbus_intr_handler_add(u32 irq, sbus_intr_handler_t handler, void *arg)
70 {
71  int res = irq, state = 0;
72 
73  /* I hope this correct... */
74  CpuSuspendIntr(&state);
75 
76  if (irq > 31) {
77  res = -SBUS_E_ARG;
78  goto out;
79  }
80 
81  if (sbus_handler_table[irq].handler) {
82  res = -SBUS_E_IRQ;
83  goto out;
84  }
85 
86  sbus_handler_table[irq].handler = handler;
87  sbus_handler_table[irq].arg = arg;
88 out:
89  CpuResumeIntr(state);
90  return res;
91 }
92 
93 int sbus_intr_handler_del(u32 irq)
94 {
95  if (irq > 31)
96  return -SBUS_E_ARG;
97 
98  sbus_handler_table[irq].handler = NULL;
99  sbus_handler_table[irq].arg = NULL;
100 
101  return irq;
102 }
103 
104 void sbus_intr_main_interrupt(u32 irq)
105 {
106  u32 flag = 1 << irq;
107 
108  if (irq > 31 || (sceSifGetSMFlag() & flag))
109  return;
110 
111  sceSifSetSMFlag(flag);
112  sceSifIntrMain();
113 }
114 
115 static int initialized = 0;
116 
117 /*
118  * - Register SBUS handler
119  * - Clear handler table
120  */
121 int sbus_intr_init()
122 {
123  int i, state, res = 0;
124 
125  if (initialized)
126  return res;
127 
128  CpuSuspendIntr(&state);
129 
130  for (i = 0; i < 32; ++i) {
131  sbus_handler_table[i].handler = NULL;
132  sbus_handler_table[i].arg = NULL;
133  }
134 
135  if (RegisterIntrHandler(IOP_IRQ_SBUS, 1, sbus_dispatch, NULL) < 0) {
136  res = -SBUS_E_INIT;
137  goto out;
138  }
139  EnableIntr(IOP_IRQ_SBUS);
140  initialized = 1;
141 out:
142  CpuResumeIntr(state);
143  return res;
144 }
145 
146 void sbus_intr_exit()
147 {
148  DisableIntr(IOP_IRQ_SBUS, NULL);
149  ReleaseIntrHandler(IOP_IRQ_SBUS);
150  initialized = 0;
151 }
RegisterIntrHandler
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition: intrman.c:115
ReleaseIntrHandler
int ReleaseIntrHandler(int irq)
Definition: intrman.c:157
sifman.h
DisableIntr
int DisableIntr(int irq, int *res)
Definition: intrman.c:385
initialized
static int initialized
Definition: audsrv.c:53
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
loadcore.h
EnableIntr
int EnableIntr(int irq)
Definition: intrman.c:336
irx.h
SBUS_E_ARG
@ SBUS_E_ARG
Definition: sbusintr.h:29
SBUS_E_IRQ
@ SBUS_E_IRQ
Definition: sbusintr.h:31
irx_export_table
Definition: irx.h:90
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
defs.h
SBUS_E_INIT
@ SBUS_E_INIT
Definition: sbusintr.h:27
intrman.h
sbusintr.h