tartan_arch/arm/
interrupt.rs1use crate::{cp15_register_get, cp15_register_set};
4
5#[doc(hidden)]
7pub use paste::paste;
8
9
10#[macro_export]
37macro_rules! arm_exception_vector_table {
38 [$table:ident, $handler:path] => {
39 extern "C" {
40 #[no_mangle]
41 static $table: $crate::arm::interrupt::VectorTable;
42 }
43
44 core::arch::global_asm!(concat!("
45 .arm // Exception handlers always use 32-bit (Arm-mode) instructions
46 .balign 0x10
47 ", stringify!($table), ":
48
49 . = ", stringify!($table), " + 0x00
50 // Reset
51 ldr pc, ", stringify!($table), "_reset
52
53 . = ", stringify!($table), " + 0x04
54 // Undefined instruction
55 ldr pc, ", stringify!($table), "_undefined
56
57 . = ", stringify!($table), " + 0x08
58 // Software interrupt
59 ldr pc, ", stringify!($table), "_software
60
61 . = ", stringify!($table), " + 0x0c
62 // Prefetch abort
63 ldr pc, ", stringify!($table), "_prefetch
64
65 . = ", stringify!($table), " + 0x10
66 // Data abort
67 ldr pc, ", stringify!($table), "_data
68
69 . = ", stringify!($table), " + 0x18
70 // Hardware interrupt (IRQ)
71 ldr pc, ", stringify!($table), "_interrupt
72
73 . = ", stringify!($table), " + 0x1c
74 // Fast hardware interrupt (FIQ)
75 ldr pc, ", stringify!($table), "_fast_interrupt
76 "));
77
78 $crate::arm::interrupt::paste! {
79 #[no_mangle]
80 fn [< $table _reset >]() {
81 $handler($crate::arm::interrupt::Kind::Reset);
82 }
83
84 #[no_mangle]
85 fn [< $table _undefined >]() {
86 $handler($crate::arm::interrupt::Kind::UndefinedInstruction);
87 }
88
89 #[no_mangle]
90 fn [< $table _software >]() {
91 $handler($crate::arm::interrupt::Kind::SoftwareInterrupt);
92 }
93
94 #[no_mangle]
95 fn [< $table _prefetch >]() {
96 $handler($crate::arm::interrupt::Kind::PrefetchAbort);
97 }
98
99 #[no_mangle]
100 fn [< $table _data >]() {
101 $handler($crate::arm::interrupt::Kind::DataAbort);
102 }
103
104 #[no_mangle]
105 fn [< $table _interrupt >]() {
106 $handler($crate::arm::interrupt::Kind::HardwareInterrupt);
107 }
108
109 #[no_mangle]
110 fn [< $table _fast_interrupt >]() {
111 $handler($crate::arm::interrupt::Kind::FastHardwareInterrupt);
112 }
113 }
114 };
115}
116
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120#[allow(missing_docs)]
121pub enum Kind {
122 Reset,
123 UndefinedInstruction,
124 SoftwareInterrupt,
125 PrefetchAbort,
126 DataAbort,
127 HardwareInterrupt,
128 FastHardwareInterrupt,
129}
130
131
132#[repr(align(0x10))]
134#[allow(dead_code)]
135pub struct VectorTable([u8; 0x20]);
136
137
138pub enum VectorBaseAddressRegister {}
140
141impl VectorBaseAddressRegister {
142 pub fn get() -> *const VectorTable {
147 let usize_value = cp15_register_get!(0, "c12", "c0", 0);
148 usize_value as *const VectorTable
149 }
150
151 pub fn set(value: *const VectorTable) {
155 unsafe {
156 cp15_register_set!(0, "c12", "c0", 0, value as usize);
157 }
158 }
159}