forked from olajep/esim-test-bins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
swi_nested.c
98 lines (81 loc) · 2.56 KB
/
swi_nested.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <stdio.h>
#include <stdint.h>
// e-server traps exception interrupt so use interrupt 8 for exception here
// after all, this is just for demonstrational purposes only.
void exception_isr() __attribute__ ((interrupt));
void user_isr() __attribute__ ((interrupt));
void exception_isr()
{
static int i = 0;
printf("exception_isr:\tbegin\n");
if (!i)
{
++i;
/* Trigger user interrupt with lower prio */
printf("exception_isr:\ttrigger user interrupt with swi.\n");
__asm__("movt r40, 0");
__asm__("mov r40, 0x200");
__asm__("movts ilatst, r40");
}
printf("exception_isr:\tend\n");
}
void user_isr()
{
static int i = 0;
float a = 1e38;
float b = 1e38;
float c;
printf("user_isr:\tbegin\n");
/* Make sure we trigger float exception only once, so we don't
* get an infinite loop.
*/
if (i) {
printf("user_isr:\tagain, will not trigger float exception\n");
goto out;
}
i = 1;
printf("user_isr:\tbefore float overflow\n");
/* Trigger software exception with higher prio */
__asm__("movt r40, 0");
__asm__("mov r40, 0x100");
__asm__("movts ilatst, r40");
// c = a*b;
printf("user_isr:\tafter float overflow\n");
out:
printf("user_isr:\tend\n");
}
int main()
{
register uint32_t r38 __asm__("r38"); // tmp for enabling fp exceptions
uint32_t *ivt_usr, *ivt_exception; // interrupt vector ptrs
uint32_t addr_usr, addr_exception; // relative branch addr
uint32_t br32_usr, br32_exception; // relative addr branch instruction
ivt_usr = (uint32_t *) 0x24;
addr_usr = (uint32_t) &user_isr;
addr_usr -= (uint32_t) ivt_usr; // Adjust for user interrupt branch addr
addr_usr = (addr_usr >> 1); // Lowest bit is skipped (alignment)
br32_usr = 0xe8;
br32_usr |= ((addr_usr & (0x00ffffff))) << 8;
*ivt_usr = br32_usr;
ivt_exception = (uint32_t *) 0x20;
addr_exception = (uint32_t) &exception_isr;
addr_exception -= (uint32_t) ivt_exception; // Adjust for user interrupt branch addr
addr_exception = (addr_exception >> 1); // Lowest bit is skipped (alignment)
br32_exception = 0xe8;
br32_exception |= ((addr_exception & (0x00ffffff))) << 8;
*ivt_exception = br32_exception;
// clear imask
__asm__("movt r40, 0");
__asm__("mov r40, 0");
__asm__("movts imask, r40");
// enable float exceptions
__asm__("movfs r38, config");
r38 |= 14;
__asm__("movts config, r38");
// Trigger user interrupt
printf("main:\t\ttrigger user interrupt with swi\n");
__asm__("movt r40, 0");
__asm__("mov r40, 0x200");
__asm__("movts ilatst, r40");
return 0;
}