Skip to content

Commit 021387a

Browse files
committed
Change GIC example to handle nested interrupts.
It can now handle a hi-prio SGI whilst in the middle of handling a low-prio SGI. This shows we got the asm interrupt handler's stacking code right (probably).
1 parent adab0e1 commit 021387a

File tree

1 file changed

+37
-8
lines changed
  • examples/mps3-an536/src/bin

1 file changed

+37
-8
lines changed

examples/mps3-an536/src/bin/gic.rs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ const GICD_BASE_OFFSET: usize = 0x0000_0000usize;
2323
/// Offset from PERIPHBASE for the first GIC Redistributor
2424
const GICR_BASE_OFFSET: usize = 0x0010_0000usize;
2525

26+
const SGI_INTID_LO: IntId = IntId::sgi(3);
27+
const SGI_INTID_HI: IntId = IntId::sgi(4);
28+
2629
/// The entry-point to the Rust application.
2730
///
2831
/// It is called by the start-up code in `cortex-r-rt`.
@@ -46,13 +49,17 @@ fn main() -> ! {
4649
SingleCoreGic::set_priority_mask(0x80);
4750

4851
// Configure a Software Generated Interrupt for Core 0
49-
println!("Configure SGI...");
50-
let sgi_intid = IntId::sgi(3);
51-
gic.set_interrupt_priority(sgi_intid, Some(0), 0x31);
52-
gic.set_group(sgi_intid, Some(0), Group::Group1NS);
52+
println!("Configure low-prio SGI...");
53+
gic.set_interrupt_priority(SGI_INTID_LO, Some(0), 0x31);
54+
gic.set_group(SGI_INTID_LO, Some(0), Group::Group1NS);
55+
56+
println!("Configure high-prio SGI...");
57+
gic.set_interrupt_priority(SGI_INTID_HI, Some(0), 0x10);
58+
gic.set_group(SGI_INTID_HI, Some(0), Group::Group1NS);
5359

5460
println!("gic.enable_interrupt()");
55-
gic.enable_interrupt(sgi_intid, Some(0), true);
61+
gic.enable_interrupt(SGI_INTID_LO, Some(0), true);
62+
gic.enable_interrupt(SGI_INTID_HI, Some(0), true);
5663

5764
println!("Enabling interrupts...");
5865
dump_cpsr();
@@ -62,9 +69,9 @@ fn main() -> ! {
6269
dump_cpsr();
6370

6471
// Send it
65-
println!("Send SGI");
72+
println!("Send lo-prio SGI");
6673
SingleCoreGic::send_sgi(
67-
sgi_intid,
74+
SGI_INTID_LO,
6875
SgiTarget::List {
6976
affinity3: 0,
7077
affinity2: 0,
@@ -89,7 +96,29 @@ fn dump_cpsr() {
8996
fn irq_handler() {
9097
println!("> IRQ");
9198
while let Some(int_id) = SingleCoreGic::get_and_acknowledge_interrupt() {
92-
println!("- IRQ handle {:?}", int_id);
99+
// let's go re-entrant
100+
unsafe {
101+
cortex_ar::interrupt::enable();
102+
}
103+
println!("- IRQ Handing {:?}", int_id);
104+
if int_id == SGI_INTID_LO {
105+
println!(
106+
"- IRQ got {:?}, sending hi-prio {:?}",
107+
SGI_INTID_LO, SGI_INTID_HI
108+
);
109+
SingleCoreGic::send_sgi(
110+
SGI_INTID_HI,
111+
SgiTarget::List {
112+
affinity3: 0,
113+
affinity2: 0,
114+
affinity1: 0,
115+
target_list: 0b1,
116+
},
117+
);
118+
println!("- IRQ finished sending hi-prio!");
119+
}
120+
// turn interrupts off again
121+
cortex_ar::interrupt::disable();
93122
SingleCoreGic::end_interrupt(int_id);
94123
}
95124
println!("< IRQ");

0 commit comments

Comments
 (0)