-
Notifications
You must be signed in to change notification settings - Fork 0
/
interrupts.cpp
107 lines (85 loc) · 2.94 KB
/
interrupts.cpp
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
99
100
101
102
103
104
105
106
#include <stdint.h>
#include <stdbool.h>
#include "interrupts.h"
#include "timer.h"
#include "system.h"
#include "Register.h"
static const uint32_t INTERRUPT_CONTROLLER_BASE = (System::getPeripheralBase() + 0xB200);
static Register IRQ_BASIC_PENDING (INTERRUPT_CONTROLLER_BASE + 0x00);
static Register IRQ_PENDING_1 (INTERRUPT_CONTROLLER_BASE + 0x04);
//IRQ_PENDING_2 = (INTERRUPT_CONTROLLER_BASE + 0x08),
//FIQ_CTRL = (INTERRUPT_CONTROLLER_BASE + 0x0C),
static Register ENABLE_IRQS_1 (INTERRUPT_CONTROLLER_BASE + 0x10);
//ENABLE_IRQS_2 = (INTERRUPT_CONTROLLER_BASE + 0x14),
static Register ENABLE_BASIC_IRQS (INTERRUPT_CONTROLLER_BASE + 0x18);
static Register DISABLE_IRQS_1 (INTERRUPT_CONTROLLER_BASE + 0x1C);
//DISABLE_IRQS_2 = (INTERRUPT_CONTROLLER_BASE + 0x20),
static Register DISABLE_BASIC_IRQS(INTERRUPT_CONTROLLER_BASE + 0x24);
static const uint32_t LOCAL_IRQ_BASE = (System::getLocalPeripheralBase() + 0x60);
static Register CORE0_IRQ_SOURCE (LOCAL_IRQ_BASE + 0x00);
namespace {
//BASIC IRQs
enum {
BASIC_ARM_TIMER_IRQ,
BASIC_ARM_MAILBOX_IRQ,
BASIC_ARM_DOORBELL_0_IRQ,
BASIC_ARM_DOORBELL_1_IRQ,
BASIC_GPU_0_HALTED_IRQ,
BASIC_GPU_1_HALTED_IRQ,
BASIC_ACCESS_ERROR_1_IRQ,
BASIC_ACCESS_ERROR_0_IRQ
};
const uint32_t CORE_TIMER_IRQCNTL_BASE = (System::getLocalPeripheralBase() + 0x40);
Register CORE0_TIMER_IRQCNTL (CORE_TIMER_IRQCNTL_BASE + 0x00);
Register CORE1_TIMER_IRQCNTL (CORE_TIMER_IRQCNTL_BASE + 0x04);
Register CORE2_TIMER_IRQCNTL (CORE_TIMER_IRQCNTL_BASE + 0x08);
Register CORE3_TIMER_IRQCNTL (CORE_TIMER_IRQCNTL_BASE + 0x0C);
//Core Timer interrupts
enum {
CNTPSIRQ,
CNTPNSIRQ,
CNTHPIRQ,
CNTVIRQ
};
}
namespace cpu {
namespace interrupt {
void enableArmTimer() {
ENABLE_BASIC_IRQS.set(BASIC_ARM_TIMER_IRQ);
}
void disableArmTimer() {
DISABLE_BASIC_IRQS.set(BASIC_ARM_TIMER_IRQ);
}
void enableSystemTimer(uint_fast8_t timerIdx) {
ENABLE_IRQS_1.set(timerIdx);
}
void disableSystemTimer(uint_fast8_t timerIdx) {
DISABLE_IRQS_1.set(timerIdx);
}
void enableCoreTimer() {
CORE0_TIMER_IRQCNTL.set(1);
}
void disableCoreTimer() {
CORE0_TIMER_IRQCNTL.clear(1); //?
}
void enable() {
asm volatile ("cpsie i");
}
void disable() {
asm volatile ("cpsid i");
}
}
}
extern "C"
void interruptHandler()
{
if(IRQ_BASIC_PENDING.get(BASIC_ARM_TIMER_IRQ)) {
System::armTimer().handleTimerInterrupt();
} else if(IRQ_PENDING_1.get(1)) {
System::systemTimer1().handleTimerInterrupt();
} else if(IRQ_PENDING_1.get(3)) {
System::systemTimer3().handleTimerInterrupt();
} else if(CORE0_IRQ_SOURCE.get(CNTPNSIRQ)) {
System::localTimer().handleTimerInterrupt();
}
}