GlobalTimer: add timer IRQ to experiment
gic: add disable individual interrupt support mpcore: refactor icdicer registers as array main: start timer with interrupt and add IRQ
This commit is contained in:
parent
535c162034
commit
1b714a8ca0
|
@ -7,6 +7,7 @@
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
|
use embedded_hal::blocking::delay::DelayUs;
|
||||||
use libasync::{
|
use libasync::{
|
||||||
delay,
|
delay,
|
||||||
smoltcp::{Sockets, TcpStream},
|
smoltcp::{Sockets, TcpStream},
|
||||||
|
@ -25,6 +26,7 @@ use libboard_zynq::{
|
||||||
wire::{EthernetAddress, IpAddress, IpCidr},
|
wire::{EthernetAddress, IpAddress, IpCidr},
|
||||||
},
|
},
|
||||||
time::Milliseconds,
|
time::Milliseconds,
|
||||||
|
timer::GlobalTimer,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "target_zc706")]
|
#[cfg(feature = "target_zc706")]
|
||||||
use libboard_zynq::print;
|
use libboard_zynq::print;
|
||||||
|
@ -61,10 +63,19 @@ interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, {
|
||||||
let id = gic.get_interrupt_id();
|
let id = gic.get_interrupt_id();
|
||||||
match MPIDR.read().cpu_id(){
|
match MPIDR.read().cpu_id(){
|
||||||
0 => {
|
0 => {
|
||||||
if id.0 == 0 {
|
match id.0 {
|
||||||
|
0 => {
|
||||||
println!("Interrupting core0...");
|
println!("Interrupting core0...");
|
||||||
gic.end_interrupt(id);
|
gic.end_interrupt(id);
|
||||||
return;
|
return;
|
||||||
|
},
|
||||||
|
27 => {
|
||||||
|
println!("GlobalTimer interrupting core0...");
|
||||||
|
GlobalTimer::clear_isr();
|
||||||
|
gic.end_interrupt(id);
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
1 => {
|
1 => {
|
||||||
|
@ -137,13 +148,24 @@ pub fn main_core0() {
|
||||||
clocks.cpu_1x()
|
clocks.cpu_1x()
|
||||||
);
|
);
|
||||||
|
|
||||||
let timer = libboard_zynq::timer::GlobalTimer::start();
|
let mut timer = GlobalTimer::start_with_interrupt(100_000);
|
||||||
|
|
||||||
let mut ddr = zynq::ddr::DdrRam::ddrram();
|
let mut ddr = zynq::ddr::DdrRam::ddrram();
|
||||||
#[cfg(not(feature = "target_zc706"))]
|
#[cfg(not(feature = "target_zc706"))]
|
||||||
ddr.memtest();
|
ddr.memtest();
|
||||||
ram::init_alloc_ddr(&mut ddr);
|
ram::init_alloc_ddr(&mut ddr);
|
||||||
|
|
||||||
|
info!("Enable GlobalTimer interrupt on core0");
|
||||||
|
interrupt_controller.enable(
|
||||||
|
gic::InterruptId(27),
|
||||||
|
gic::CPUCore::Core0,
|
||||||
|
gic::InterruptSensitivity::Edge,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
timer.delay_us(100_000);
|
||||||
|
interrupt_controller.disable(gic::InterruptId(27));
|
||||||
|
info!("Disable GlobalTimer interrupt");
|
||||||
|
|
||||||
info!("Send software interrupt to core0");
|
info!("Send software interrupt to core0");
|
||||||
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core0.into());
|
interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core0.into());
|
||||||
info!("Core0 returned from interrupt");
|
info!("Core0 returned from interrupt");
|
||||||
|
|
|
@ -95,6 +95,26 @@ impl InterruptController {
|
||||||
}.sgiintid(id.0).satt(false));
|
}.sgiintid(id.0).satt(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// disable the interrupt
|
||||||
|
pub fn disable(&mut self, id: InterruptId){
|
||||||
|
|
||||||
|
// disable
|
||||||
|
let m = (id.0 >> 5) as usize;
|
||||||
|
let n = (id.0 & 0x1F) as usize;
|
||||||
|
assert!(m < 3);
|
||||||
|
unsafe {
|
||||||
|
self.mpcore.icdicer[m].modify(|mut icdicer| *icdicer.set_bit(n, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove CPUs from interrupt
|
||||||
|
let m = (id.0 >> 2) as usize;
|
||||||
|
let n = (8 * (id.0 & 3)) as usize;
|
||||||
|
unsafe {
|
||||||
|
self.mpcore.icdiptr[m].modify(|mut icdiptr| *icdiptr.set_bits(n..=n+1, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// enable the interrupt *for this core*.
|
/// enable the interrupt *for this core*.
|
||||||
/// Not needed for SGI.
|
/// Not needed for SGI.
|
||||||
pub fn enable(&mut self, id: InterruptId, target_cpu: CPUCore, sensitivity: InterruptSensitivity, priority: u8) {
|
pub fn enable(&mut self, id: InterruptId, target_cpu: CPUCore, sensitivity: InterruptSensitivity, priority: u8) {
|
||||||
|
|
|
@ -96,12 +96,8 @@ pub struct RegisterBlock {
|
||||||
/// Interrupt Set-enable Registers
|
/// Interrupt Set-enable Registers
|
||||||
pub icdiser: [RW<u32>; 3],
|
pub icdiser: [RW<u32>; 3],
|
||||||
unused9: [u32; 29],
|
unused9: [u32; 29],
|
||||||
/// Interrupt Clear-Enable Register 0
|
/// Interrupt Clear-Enable Register
|
||||||
pub icdicer0: RW<u32>,
|
pub icdicer: [RW<u32>; 3],
|
||||||
/// Interrupt Clear-Enable Register 1
|
|
||||||
pub icdicer1: RW<u32>,
|
|
||||||
/// Interrupt Clear-Enable Register 2
|
|
||||||
pub icdicer2: RW<u32>,
|
|
||||||
unused10: [u32; 29],
|
unused10: [u32; 29],
|
||||||
/// Interrupt Set-pending Register
|
/// Interrupt Set-pending Register
|
||||||
pub icdispr0: RW<u32>,
|
pub icdispr0: RW<u32>,
|
||||||
|
|
Loading…
Reference in New Issue