Skip to content
This repository was archived by the owner on Oct 24, 2023. It is now read-only.

Commit 7aaf252

Browse files
committed
Merge branch 'isr-refactor'
2 parents 2117d99 + 4e7a70e commit 7aaf252

File tree

14 files changed

+194
-381
lines changed

14 files changed

+194
-381
lines changed

examples/template/src/main.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
#include <seven/version.h>
21
#include <seven/hw/video/prelude.h>
32
#include <seven/hw/video/bg_bitmap.h>
43
#include <seven/hw/video/color_constants.h>
54

6-
libsevenEmitVersionString();
75

86
int main(void)
97
{

examples/vsync/src/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ int main(void)
1212
{
1313
// Set up the necessary interrupt handling
1414
irqInitDefault();
15-
irqEnableFull(IRQ_VBLANK);
15+
irqEnable(IRQ_VBLANK);
1616
irqHandlerSet(IRQ_VBLANK, vblank_callback);
1717

1818
// Clear the force-blank bit
1919
REG_DISPCNT = 0;
20+
REG_DISPSTAT = LCD_VBLANK_IRQ_ENABLE;
2021

2122
while (1)
2223
{

libseven/include/seven/attributes.h

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,26 @@
88

99
#include <seven/base.h>
1010

11-
#define _LIBSEVEN_SECCOUNT _LIBSEVEN_STR2(__COUNTER__)
11+
#define _LIBSEVEN_COUNTER _LIBSEVEN_STR2(__COUNTER__)
1212

13-
#define PACKED __attribute__((__packed__))
14-
#define ALIGN(n) __attribute__((__aligned__(n)))
15-
#define NORETURN __attribute__((__noreturn__))
16-
#define NOINLINE __attribute__((__noinline__))
17-
#define ARM_CODE __attribute__((__target__("arm"))) NOINLINE
18-
#define THUMB_CODE __attribute__((__target__("thumb"))) NOINLINE
13+
#define ALIGN(n) __attribute__((__aligned__(n)))
14+
#define ARM_CODE __attribute__((__target__("arm"))) NOINLINE
15+
#define NOINLINE __attribute__((__noinline__))
16+
#define NORETURN __attribute__((__noreturn__))
17+
#define PACKED __attribute__((__packed__))
18+
#define SECTION(name) __attribute__((__section__(name)))
19+
#define THUMB_CODE __attribute__((__target__("thumb"))) NOINLINE
1920

20-
#define SECTION(name) __attribute__((__section__(name)))
21+
#define IWRAM_CODE SECTION(".iwram.text." _LIBSEVEN_COUNTER) NOINLINE
22+
#define IWRAM_DATA SECTION(".iwram.data." _LIBSEVEN_COUNTER)
2123

22-
#define IWRAM_SECTION(suffix) SECTION(".iwram" suffix)
23-
#define IWRAM_OVERLAY(number) SECTION(".iwram" #number)
24+
#define EWRAM_CODE SECTION(".ewram.text." _LIBSEVEN_COUNTER) NOINLINE
25+
#define EWRAM_DATA SECTION(".ewram.data." _LIBSEVEN_COUNTER)
2426

25-
#define IWRAM_CODE IWRAM_SECTION(".text." _LIBSEVEN_SECCOUNT) NOINLINE
26-
#define IWRAM_DATA IWRAM_SECTION(".data." _LIBSEVEN_SECCOUNT)
27-
28-
#define EWRAM_SECTION(suffix) SECTION(".ewram" suffix)
29-
#define EWRAM_OVERLAY(number) SECTION(".ewram" #number)
30-
31-
#define EWRAM_CODE EWRAM_SECTION(".text." _LIBSEVEN_SECCOUNT) NOINLINE
32-
#define EWRAM_DATA EWRAM_SECTION(".data." _LIBSEVEN_SECCOUNT)
33-
34-
#ifndef _LIBSEVEN_NOCOMPATIBLE
35-
#define IWRAM_BSS SECTION(".bss." _LIBSEVEN_SECCOUNT)
36-
#define EWRAM_BSS SECTION(".sbss." _LIBSEVEN_SECCOUNT)
27+
#ifdef LIBSEVEN_COMPATIBLE
28+
#define IWRAM_BSS SECTION(".bss." _LIBSEVEN_COUNTER)
29+
#define EWRAM_BSS SECTION(".sbss." _LIBSEVEN_COUNTER)
3730
#else
38-
#define IWRAM_BSS SECTION(".iwram_bss." _LIBSEVEN_SECCOUNT)
39-
#define EWRAM_BSS SECTION(".ewram_bss." _LIBSEVEN_SECCOUNT)
40-
#endif /* !_LIBSEVEN_NOCOMPATIBLE */
31+
#define IWRAM_BSS SECTION(".iwram_bss." _LIBSEVEN_COUNTER)
32+
#define EWRAM_BSS SECTION(".ewram_bss." _LIBSEVEN_COUNTER)
33+
#endif /* LIBSEVEN_COMPATIBLE */

libseven/include/seven/base.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
#define _LIBSEVEN_STR(s) #s
2222
#define _LIBSEVEN_STR2(s) _LIBSEVEN_STR(s)
2323

24+
#define _LIBSEVEN_TARGET_ARM __attribute__((__target__("arm"), __noinline__))
25+
#define _LIBSEVEN_NOINLINE __attribute__((__noinline__))
2426
#define _LIBSEVEN_NORETURN __attribute__((__noreturn__))
25-
#define _LIBSEVEN_ALIGN4 __attribute__((__aligned__(4)))
27+
#define _LIBSEVEN_ALIGNED __attribute__((__aligned__(4)))
2628

2729
#define LIBSEVEN_VERSION_MAJOR 0
28-
#define LIBSEVEN_VERSION_MINOR 17
29-
#define LIBSEVEN_VERSION_PATCH 2
30+
#define LIBSEVEN_VERSION_MINOR 18
31+
#define LIBSEVEN_VERSION_PATCH 0
3032

3133
#define LIBSEVEN_VERSION \
3234
_LIBSEVEN_STR2(LIBSEVEN_VERSION_MAJOR) "." \

libseven/include/seven/hw/irq.h

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
_LIBSEVEN_EXTERN_C
1212

13-
// Attribute for compiling functions in a way that is suitable for ISRs.
14-
//
15-
#define ISR_FUNCTION IWRAM_CODE ARM_CODE
16-
1713
// Interrupt Enable
1814
//
1915
#define REG_IE VOLADDR(0x04000200, uint16_t)
@@ -28,11 +24,14 @@ _LIBSEVEN_EXTERN_C
2824

2925
// Interrupt Service Routine Function Pointer
3026
//
31-
#define MEM_ISR MEMADDR(0x03FFFFFC, IsrFn*)
27+
#define MEM_ISR VOLADDR(0x03FFFFFC, IsrFn*)
28+
29+
// Interrupt Flags used by BIOS
30+
#define MEM_IFBIOS VOLADDR(0x03FFFFF8, uint16_t)
3231

3332
// IRQ bitflags
3433
//
35-
enum IRQ
34+
enum IRQFlag
3635
{
3736
IRQ_VBLANK = BIT(0),
3837
IRQ_HBLANK = BIT(1),
@@ -57,7 +56,7 @@ enum IRQGroup
5756
IRQS_BLANK = IRQ_VBLANK | IRQ_HBLANK,
5857
IRQS_TIMER = IRQ_TIMER_0 | IRQ_TIMER_1 | IRQ_TIMER_2 | IRQ_TIMER_3,
5958
IRQS_DMA = IRQ_DMA_0 | IRQ_DMA_1 | IRQ_DMA_2 | IRQ_DMA_3,
60-
// IRQs in this group can wake up the GBA from a svcStop() call.
59+
// IRQs in this group can wake up the GBA from biosStop().
6160
IRQS_EXTERNAL = IRQ_SERIAL | IRQ_KEYPAD | IRQ_CARTRIDGE,
6261
IRQS_ALL = BITS(14),
6362
};
@@ -101,17 +100,13 @@ extern void irqInit(IsrFn *isr);
101100
// Initialize interrupt handling using a handler system.
102101
//
103102
// Used with the irqHandler* functions.
103+
// Supports nesting by calling irqUnmask() inside a handler.
104104
extern void irqInitDefault(void);
105105

106-
// Initialize interrupt handling using a single handler function.
106+
// Initialize interrupt handling using an optional, single handler function.
107107
//
108-
extern void irqInitSimple(IrqHandlerFn *fn);
109-
110-
// Initialize interrupt handling using a stub handler
111-
// that only acknowledges the IRQs and returns.
112-
//
113-
// This is enough for the BIOS interrupt wait functions to work.
114-
extern void irqInitStub(void);
108+
// Does not support nesting by default.
109+
extern void irqInitMinimal(IrqHandlerFn *fn);
115110

116111
// Set the handler associated with the specified irq.
117112
//
@@ -138,17 +133,16 @@ extern uint16_t irqEnable(uint16_t irqs);
138133
// Returns the old value of the IE register.
139134
extern uint16_t irqDisable(uint16_t irqs);
140135

141-
// Enable the specified IRQs and IRQ enable bits in the respective IO registers.
142-
//
143-
// Returns the old value of the IE register.
144-
extern uint16_t irqEnableFull(uint16_t irqs);
136+
// Calls a function with IRQs disabled, passing data as an argument.
137+
extern void irqFree(void (*f)(void *), void *arg);
145138

146-
// Disable the specified IRQs and IRQ enable bits in the respective IO registers.
147-
//
148-
// Returns the old value of the IE register.
149-
extern uint16_t irqDisableFull(uint16_t irqs);
139+
// Mask IRQs at the CPU level.
140+
extern void irqMask(void);
150141

151-
// Calls a function with IRQs disabled, passing data as an argument.
152-
extern void irqFree(void (*f)(void*), void *arg);
142+
// Unmask IRQs at the CPU level. Used for enabling nested interrupts.
143+
extern void irqUnmask(void);
144+
145+
// Returns whether IRQs are masked at the CPU level.
146+
extern bool irqMasked(void);
153147

154148
_LIBSEVEN_EXTERN_C_END

libseven/include/seven/hw/video/types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ struct Matrix
2323
int16_t vdx; // vertical shearing factor
2424
int16_t hdy; // horizontal shearing factor
2525
int16_t vdy; // vertical scaling factor
26-
} _LIBSEVEN_ALIGN4;
26+
} _LIBSEVEN_ALIGNED;
2727

2828
struct Object
2929
{
3030
uint16_t attr0;
3131
uint16_t attr1;
3232
uint16_t attr2;
3333
uint16_t _reserved;
34-
} _LIBSEVEN_ALIGN4;
34+
} _LIBSEVEN_ALIGNED;
3535

3636
_LIBSEVEN_EXTERN_C_END

libseven/include/seven/types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ typedef uintptr_t uptr;
6666
#define USIZE_BITS (CHAR_BIT * sizeof(usize))
6767
#define UPTR_BITS (CHAR_BIT * sizeof(uptr))
6868

69-
#ifndef _LIBSEVEN_NOCOMPATIBLE
69+
#ifdef LIBSEVEN_COMPATIBLE
7070

7171
typedef i8 s8;
7272
typedef i16 s16;
@@ -96,4 +96,4 @@ typedef iptr sptr;
9696
#define SSIZE_BITS ISIZE_BITS
9797
#define SPTR_BITS IPTR_BITS
9898

99-
#endif /* !_LIBSEVEN_NOCOMPATIBLE */
99+
#endif /* LIBSEVEN_COMPATIBLE */

libseven/include/seven/version.h

Lines changed: 0 additions & 18 deletions
This file was deleted.

libseven/src/hw/irq.c

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,18 @@
88
#include <seven/hw/irq.h>
99

1010
extern IsrFn isrDefault;
11-
extern IsrFn isrSimple;
12-
extern IsrFn isrStub;
13-
14-
extern IrqHandlerFn* ISR_SIMPLE_HANDLER;
15-
extern IrqHandlerFn* ISR_DEFAULT_HANDLERS[16];
11+
extern IsrFn isrMinimal;
12+
13+
// Mark these as volatile because LTO cannot verify that isrDefault/isrMinimal
14+
// is called because it's invoked indirectly through the hardware.
15+
//
16+
// This means LTO will consider calls to irqSetHandler and similar to be dead
17+
// accesses, and remove them entirely
18+
//
19+
// For our purposes, writing these does produce a side effect, so volatile is
20+
// actually the semantically correct option here.
21+
extern IrqHandlerFn * volatile ISR_MINIMAL_HANDLER;
22+
extern IrqHandlerFn * volatile ISR_DEFAULT_HANDLERS[16];
1623

1724
extern void irqInit(IsrFn *isr)
1825
{
@@ -23,7 +30,6 @@ extern void irqInit(IsrFn *isr)
2330
MEM_ISR = isr;
2431

2532
REG_IME = 1;
26-
return;
2733
}
2834

2935
extern void irqInitDefault(void)
@@ -38,18 +44,13 @@ extern void irqInitDefault(void)
3844
irqInit(isrDefault);
3945
}
4046

41-
extern void irqInitSimple(IrqHandlerFn *handler)
47+
extern void irqInitMinimal(IrqHandlerFn *handler)
4248
{
4349
REG_IME = 0;
4450

45-
ISR_SIMPLE_HANDLER = handler;
46-
47-
irqInit(isrSimple);
48-
}
51+
ISR_MINIMAL_HANDLER = handler;
4952

50-
extern void irqInitStub(void)
51-
{
52-
irqInit(isrStub);
53+
irqInit(isrMinimal);
5354
}
5455

5556
extern bool irqHandlerSet(uint16_t irq, IrqHandlerFn *fn)
@@ -118,14 +119,49 @@ extern uint16_t irqDisable(uint16_t irqs)
118119
return old;
119120
}
120121

121-
extern void irqFree(void (*f)(void*), void *arg)
122+
extern void irqFree(void (*f)(void *), void *arg)
122123
{
123124
uint32_t ime = REG_IME;
124125
REG_IME = 0;
125126

126127
f(arg);
127128

128129
REG_IME = ime;
130+
}
131+
132+
_LIBSEVEN_TARGET_ARM extern void irqMask(void)
133+
{
134+
__asm__ volatile
135+
(
136+
"mrs r0, cpsr\n"
137+
"orr r0, r0, 0x80\n"
138+
"msr cpsr_c, r0\n"
139+
::: "r0"
140+
);
141+
}
142+
143+
_LIBSEVEN_TARGET_ARM extern void irqUnmask(void)
144+
{
145+
__asm__ volatile
146+
(
147+
"mrs r0, cpsr\n"
148+
"bic r0, r0, 0x80\n"
149+
"msr cpsr_c, r0\n"
150+
::: "r0"
151+
);
152+
}
153+
154+
_LIBSEVEN_TARGET_ARM extern bool irqMasked(void)
155+
{
156+
bool masked;
157+
158+
__asm__ volatile
159+
(
160+
"mrs %0, cpsr\n"
161+
"lsr %0, %0, 7\n"
162+
"and %0, %0, 1\n"
163+
: "=r"(masked)
164+
);
129165

130-
return;
166+
return masked;
131167
}

0 commit comments

Comments
 (0)