Pull irqchip from aarch64 code into more generic place

This commit is contained in:
Andrey Turkin
2024-10-21 19:55:00 +03:00
parent 6a731d0c84
commit 906259c024
19 changed files with 356 additions and 353 deletions
+9 -4
View File
@@ -2,15 +2,20 @@ use alloc::boxed::Box;
use log::info;
use crate::{
arch::device::irqchip::IRQ_CHIP, context, context::timeout,
device::cpu::registers::control_regs, dtb::DTB_BINARY, interrupt::irq::trigger, time,
context,
context::timeout,
device::cpu::registers::control_regs,
dtb::{
irqchip::{register_irq, InterruptHandler, IRQ_CHIP},
DTB_BINARY,
},
interrupt::irq::trigger,
time,
};
use alloc::vec::Vec;
use byteorder::{ByteOrder, BE};
use fdt::Fdt;
use super::irqchip::{register_irq, InterruptHandler};
bitflags! {
struct TimerCtrlFlags: u32 {
const ENABLE = 1 << 0;
+1 -2
View File
@@ -1,14 +1,13 @@
use core::ptr::{read_volatile, write_volatile};
use fdt::{node::FdtNode, Fdt};
use crate::dtb::irqchip::{InterruptController, IrqDesc};
use log::info;
use syscall::{
error::{Error, EINVAL},
Result,
};
use super::{InterruptController, IrqDesc};
static GICD_CTLR: u32 = 0x000;
static GICD_TYPER: u32 = 0x004;
static GICD_ISENABLER: u32 = 0x100;
+1 -2
View File
@@ -3,13 +3,12 @@ use core::arch::asm;
use fdt::{node::NodeProperty, Fdt};
use super::gic::GicDistIf;
use crate::dtb::irqchip::{InterruptController, IrqDesc};
use syscall::{
error::{Error, EINVAL},
Result,
};
use super::{InterruptController, IrqDesc};
#[derive(Debug)]
pub struct GicV3 {
gic_dist_if: GicDistIf,
@@ -1,19 +1,17 @@
use alloc::vec::Vec;
use core::ptr::{read_volatile, write_volatile};
use crate::arch::device::irqchip::IRQ_CHIP;
use byteorder::{ByteOrder, BE};
use fdt::{node::FdtNode, Fdt};
use log::{debug, error, info};
use crate::dtb::irqchip::{InterruptController, InterruptHandler, IrqDesc, IRQ_CHIP};
use syscall::{
error::{Error, EINVAL},
Result,
};
use super::{InterruptController, InterruptHandler, IrqDesc};
#[inline(always)]
fn ffs(num: u32) -> u32 {
let mut x = num;
@@ -4,14 +4,13 @@ use core::{
};
use fdt::{node::FdtNode, Fdt};
use crate::dtb::irqchip::{InterruptController, IrqDesc};
use log::{debug, info};
use syscall::{
error::{Error, EINVAL},
Result,
};
use super::{InterruptController, IrqDesc};
const LOCAL_CONTROL: u32 = 0x000;
const LOCAL_PRESCALER: u32 = 0x008;
const LOCAL_GPU_ROUTING: u32 = 0x00C;
+14 -259
View File
@@ -1,267 +1,22 @@
use alloc::{boxed::Box, vec::Vec};
use byteorder::{ByteOrder, BE};
use fdt::Fdt;
use syscall::Result;
use crate::init::device_tree::travel_interrupt_ctrl;
use log::{debug, error};
use crate::dtb::irqchip::InterruptController;
use alloc::boxed::Box;
mod gic;
mod gicv3;
mod irq_bcm2835;
mod irq_bcm2836;
pub trait InterruptController {
fn irq_init(
&mut self,
fdt: &Fdt,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<Option<usize>>;
fn irq_ack(&mut self) -> u32;
fn irq_eoi(&mut self, irq_num: u32);
fn irq_enable(&mut self, irq_num: u32);
#[allow(unused)]
fn irq_disable(&mut self, irq_num: u32);
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize>;
fn irq_to_virq(&mut self, hwirq: u32) -> Option<usize>;
fn irq_handler(&mut self, irq: u32);
}
pub trait InterruptHandler {
fn irq_handler(&mut self, irq: u32);
}
pub struct IrqChipItem {
pub phandle: u32,
pub parent_phandle: Option<u32>,
pub parent: Option<usize>, //parent idx in chiplist
pub childs: Vec<usize>, //child idx in chiplist
pub interrupts: Vec<u32>,
pub ic: Box<dyn InterruptController>,
}
pub struct IrqChipList {
pub chips: Vec<IrqChipItem>,
pub root_phandle: u32,
pub root_idx: usize,
}
pub struct IrqDescItem {
pub idx: usize,
pub ic_idx: usize, //ic idx in irq chip list
pub child_ic_idx: Option<usize>, //ic idx in irq chip list
pub ic_irq: u32, //hwirq in ic
pub used: bool,
}
pub struct IrqDesc {
pub basic: IrqDescItem,
pub handler: Option<Box<dyn InterruptHandler>>,
}
impl IrqChipList {
fn init_inner1(&mut self, fdt: &Fdt) {
let root_node = fdt.root();
let mut idx = 0;
let intr = root_node.property("interrupt-parent").unwrap();
let root_intr_parent = intr.as_usize().unwrap() as u32;
debug!("root parent = 0x{:08x}", root_intr_parent);
self.root_phandle = root_intr_parent;
for node in fdt.all_nodes() {
if node.property("interrupt-controller").is_some() {
let compatible = node.property("compatible").unwrap().as_str().unwrap();
let phandle = node.property("phandle").unwrap().as_usize().unwrap() as u32;
let intr_cells = node.interrupt_cells().unwrap();
let _intr = node.property("interrupt-parent");
let _intr_data = node.property("interrupts");
debug!(
"{}, compatible = {}, #interrupt-cells = 0x{:08x}, phandle = 0x{:08x}",
node.name, compatible, intr_cells, phandle
);
let mut item = IrqChipItem {
phandle,
parent_phandle: None,
parent: None,
childs: Vec::new(),
interrupts: Vec::new(),
ic: IrqChipCore::new_ic(compatible).unwrap(),
};
if let Some(intr) = _intr {
if let Some(intr_data) = _intr_data {
let intr = intr.as_usize().unwrap() as u32;
debug!("interrupt-parent = 0x{:08x}", intr);
item.parent_phandle = Some(intr);
debug!("interrupts begin:");
for chunk in intr_data.value.chunks(4) {
debug!("0x{:08x}, ", BE::read_u32(chunk));
item.interrupts.push(BE::read_u32(chunk));
}
debug!("interrupts end");
}
}
if item.phandle == root_intr_parent {
self.root_idx = idx as usize;
}
self.chips.push(item);
idx += 1;
}
}
}
fn init_inner2(&mut self) {
let mut x = 0;
while x < self.chips.len() {
let mut y = 0;
while y < self.chips.len() {
if x == y {
y += 1;
continue;
}
if let Some(pp) = self.chips[y].parent_phandle
&& pp == self.chips[x].phandle
{
self.chips[y].parent = Some(x);
self.chips[x].childs.push(y);
}
y += 1;
}
x += 1;
}
}
fn init_inner3(&mut self, fdt: &fdt::Fdt, irq_desc: &mut [IrqDesc; 1024]) {
//run init
let mut queue = Vec::new();
let mut irq_idx: usize = 0;
queue.push(self.root_idx);
while !queue.is_empty() {
let cur_idx = queue.pop().unwrap();
queue.extend_from_slice(&self.chips[cur_idx].childs);
let virq = self.chips[cur_idx]
.ic
.irq_init(fdt, irq_desc, cur_idx, &mut irq_idx);
if let Ok(Some(virq)) = virq {
irq_desc[virq].basic.child_ic_idx = Some(cur_idx);
}
}
}
}
pub struct IrqChipCore {
//TODO: support multi level interrupt constrollers
pub irq_chip_list: IrqChipList,
pub irq_desc: [IrqDesc; 1024],
}
impl IrqChipCore {
pub fn irq_ack(&mut self) -> u32 {
self.irq_chip_list.chips[self.irq_chip_list.root_idx]
.ic
.irq_ack()
}
pub fn irq_eoi(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_eoi(hwirq)
}
pub fn irq_enable(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_enable(hwirq)
}
#[allow(unused)]
pub fn irq_disable(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_disable(hwirq)
}
pub fn irq_to_virq(&mut self, hwirq: u32) -> Option<usize> {
self.irq_chip_list.chips[self.irq_chip_list.root_idx]
.ic
.irq_to_virq(hwirq)
}
pub fn init(&mut self, fdt: &Fdt) {
for i in 0..1024 {
self.irq_desc[i].basic.idx = i;
}
self.irq_chip_list.init_inner1(fdt);
self.irq_chip_list.init_inner2();
self.irq_chip_list.init_inner3(fdt, &mut self.irq_desc);
}
pub fn new_ic(ic_str: &str) -> Option<Box<dyn InterruptController>> {
if ic_str.contains("arm,gic-v3") {
Some(Box::new(gicv3::GicV3::new()))
} else if ic_str.contains("arm,cortex-a15-gic") {
Some(Box::new(gic::GenericInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-l1-intc") {
Some(Box::new(irq_bcm2836::Bcm2836ArmInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-armctrl-ic") {
Some(Box::new(irq_bcm2835::Bcm2835ArmInterruptController::new()))
} else {
log::warn!("no driver for interrupt controller {:?}", ic_str);
None
}
}
}
const INIT_HANDLER: Option<Box<dyn InterruptHandler>> = None;
const INIT_IRQ_DESC: IrqDesc = IrqDesc {
basic: IrqDescItem {
idx: 0,
ic_idx: 0,
ic_irq: 0,
child_ic_idx: None,
used: false,
},
handler: INIT_HANDLER,
};
pub static mut IRQ_CHIP: IrqChipCore = IrqChipCore {
irq_chip_list: IrqChipList {
chips: Vec::new(),
root_phandle: 0,
root_idx: 0,
},
irq_desc: [INIT_IRQ_DESC; 1024],
};
pub fn init(fdt: &Fdt) {
travel_interrupt_ctrl(fdt);
unsafe {
IRQ_CHIP.init(fdt);
}
}
pub fn register_irq(virq: u32, handler: Box<dyn InterruptHandler>) {
if virq >= 1024 {
error!("irq {} exceed 1024!!!", virq);
return;
}
unsafe {
if IRQ_CHIP.irq_desc[virq as usize].handler.is_some() {
error!("irq {} has already been registered!", virq);
return;
}
IRQ_CHIP.irq_desc[virq as usize].handler = Some(handler);
pub fn new_irqchip(ic_str: &str) -> Option<Box<dyn InterruptController>> {
if ic_str.contains("arm,gic-v3") {
Some(Box::new(gicv3::GicV3::new()))
} else if ic_str.contains("arm,cortex-a15-gic") {
Some(Box::new(gic::GenericInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-l1-intc") {
Some(Box::new(irq_bcm2836::Bcm2836ArmInterruptController::new()))
} else if ic_str.contains("brcm,bcm2836-armctrl-ic") {
Some(Box::new(irq_bcm2835::Bcm2835ArmInterruptController::new()))
} else {
log::warn!("no driver for interrupt controller {:?}", ic_str);
None
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
use crate::{dtb::DTB_BINARY, info};
use crate::{dtb, dtb::DTB_BINARY, info};
pub mod cpu;
pub mod generic_timer;
@@ -11,7 +11,7 @@ pub unsafe fn init() {
info!("IRQCHIP INIT");
let data = DTB_BINARY.get().unwrap();
let fdt = fdt::Fdt::new(data).unwrap();
irqchip::init(&fdt);
dtb::irqchip::init(&fdt);
info!("GIT INIT");
generic_timer::init();
}
+5 -2
View File
@@ -3,8 +3,11 @@ use spin::Mutex;
use crate::{device::uart_pl011::SerialPort, interrupt::irq::trigger};
use super::irqchip::{register_irq, InterruptHandler, IRQ_CHIP};
use crate::dtb::{diag_uart_range, DTB_BINARY};
use crate::dtb::{
diag_uart_range,
irqchip::{register_irq, InterruptHandler, IRQ_CHIP},
DTB_BINARY,
};
use alloc::vec::Vec;
use byteorder::{ByteOrder, BE};
use fdt::Fdt;
-38
View File
@@ -1,38 +0,0 @@
use byteorder::{ByteOrder, BE};
use fdt::{node::NodeProperty, Fdt};
use log::debug;
pub fn travel_interrupt_ctrl(fdt: &Fdt) {
let root_intr_parent = fdt
.root()
.property("interrupt-parent")
.and_then(NodeProperty::as_usize)
.unwrap();
debug!("root parent = 0x{:08x}", root_intr_parent);
for node in fdt.all_nodes() {
if node.property("interrupt-controller").is_some() {
let compatible = node.property("compatible").unwrap().as_str().unwrap();
let phandle = node.property("phandle").unwrap().as_usize().unwrap();
let intr_cells = node.interrupt_cells().unwrap();
let _intr = node
.property("interrupt-parent")
.and_then(NodeProperty::as_usize);
let _intr_data = node.property("interrupts");
debug!(
"{}, compatible = {}, #interrupt-cells = 0x{:08x}, phandle = 0x{:08x}",
node.name, compatible, intr_cells, phandle
);
if let Some(intr) = _intr {
if let Some(intr_data) = _intr_data {
debug!("interrupt-parent = 0x{:08x}", intr);
debug!("interrupts begin:");
for chunk in intr_data.value.chunks(4) {
debug!("0x{:08x}, ", BE::read_u32(chunk));
}
debug!("interrupts end");
}
}
}
}
}
-1
View File
@@ -1 +0,0 @@
pub mod device_tree;
+1 -5
View File
@@ -1,4 +1,4 @@
use crate::device::irqchip::IRQ_CHIP;
use crate::dtb::irqchip::IRQ_CHIP;
exception_stack!(irq_at_el0, |_stack| {
let irq = IRQ_CHIP.irq_ack();
@@ -44,10 +44,6 @@ pub unsafe fn trigger(irq: u32) {
IRQ_CHIP.irq_eoi(irq);
}
pub unsafe fn acknowledge(_irq: usize) {
// TODO
}
/*
pub unsafe fn irq_handler_gentimer(irq: u32) {
GENTIMER.clear_irq();
-15
View File
@@ -51,22 +51,7 @@ pub fn pause() {
unsafe { asm!("nop") };
}
pub fn available_irqs_iter(_cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
0..0
}
pub fn bsp_apic_id() -> Option<u32> {
//TODO
None
}
#[inline]
pub fn is_reserved(_cpu_id: LogicalCpuId, _index: u8) -> bool {
//TODO
true
}
#[inline]
pub fn set_reserved(_cpu_id: LogicalCpuId, _index: u8, _reserved: bool) {
//TODO
}
-3
View File
@@ -33,9 +33,6 @@ pub mod stop;
// Interrupt vectors
pub mod vectors;
/// Early init support
pub mod init;
pub mod time;
pub use ::rmm::AArch64Arch as CurrentRmmArch;
+6
View File
@@ -0,0 +1,6 @@
use crate::dtb::irqchip::InterruptController;
use alloc::boxed::Box;
pub fn new_irqchip(_ic_str: &str) -> Option<Box<dyn InterruptController>> {
None
}
+1
View File
@@ -5,6 +5,7 @@ use fdt::{
};
pub mod cpu;
pub mod irqchip;
pub mod serial;
fn string_property(name: &str) -> bool {
-10
View File
@@ -15,16 +15,6 @@ pub use handler::InterruptStack;
pub fn bsp_apic_id() -> Option<u32> {
Some(0)
}
pub fn available_irqs_iter(_cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
unimplemented!();
0..0
}
pub fn is_reserved(_cpu_id: LogicalCpuId, _index: u8) -> ! {
unimplemented!()
}
pub fn set_reserved(_cpu_id: LogicalCpuId, _index: u8, _reserved: bool) -> ! {
unimplemented!()
}
/// Clear interrupts
#[inline(always)]
+269
View File
@@ -0,0 +1,269 @@
use super::travel_interrupt_ctrl;
use crate::{
arch, arch::device::irqchip::new_irqchip, cpu_set::LogicalCpuId, scheme::irq::irq_trigger,
};
use alloc::{boxed::Box, vec::Vec};
use byteorder::{ByteOrder, BE};
use fdt::{node::NodeProperty, Fdt};
use log::{debug, error};
use syscall::{Error, Result, ENOENT};
pub trait InterruptHandler {
fn irq_handler(&mut self, irq: u32);
}
pub trait InterruptController {
fn irq_init(
&mut self,
fdt: &Fdt,
irq_desc: &mut [IrqDesc; 1024],
ic_idx: usize,
irq_idx: &mut usize,
) -> Result<Option<usize>>;
fn irq_ack(&mut self) -> u32;
fn irq_eoi(&mut self, irq_num: u32);
fn irq_enable(&mut self, irq_num: u32);
#[allow(unused)]
fn irq_disable(&mut self, irq_num: u32);
fn irq_xlate(&mut self, irq_data: &[u32], idx: usize) -> Result<usize>;
fn irq_to_virq(&mut self, hwirq: u32) -> Option<usize>;
fn irq_handler(&mut self, irq: u32);
}
pub struct IrqChipItem {
pub phandle: u32,
pub parent_phandle: Option<u32>,
pub parent: Option<usize>, //parent idx in chiplist
pub childs: Vec<usize>, //child idx in chiplist
pub interrupts: Vec<u32>,
pub ic: Box<dyn InterruptController>,
}
pub struct IrqChipList {
pub chips: Vec<IrqChipItem>,
pub root_phandle: u32,
pub root_idx: usize,
}
pub struct IrqDescItem {
pub idx: usize,
pub ic_idx: usize, //ic idx in irq chip list
pub child_ic_idx: Option<usize>, //ic idx in irq chip list
pub ic_irq: u32, //hwirq in ic
pub used: bool,
}
pub struct IrqDesc {
pub basic: IrqDescItem,
pub handler: Option<Box<dyn InterruptHandler>>,
}
impl IrqChipList {
fn init_inner1(&mut self, fdt: &Fdt) {
let root_node = fdt.root();
let mut idx = 0;
let intr = root_node.property("interrupt-parent").unwrap();
let root_intr_parent = intr.as_usize().unwrap() as u32;
debug!("root parent = 0x{:08x}", root_intr_parent);
self.root_phandle = root_intr_parent;
for node in fdt.all_nodes() {
if node.property("interrupt-controller").is_some() {
let compatible = node.property("compatible").unwrap().as_str().unwrap();
let phandle = node.property("phandle").unwrap().as_usize().unwrap() as u32;
let intr_cells = node.interrupt_cells().unwrap();
let _intr = node.property("interrupt-parent");
let _intr_data = node.property("interrupts");
debug!(
"{}, compatible = {}, #interrupt-cells = 0x{:08x}, phandle = 0x{:08x}",
node.name, compatible, intr_cells, phandle
);
let mut item = IrqChipItem {
phandle,
parent_phandle: None,
parent: None,
childs: Vec::new(),
interrupts: Vec::new(),
ic: new_irqchip(compatible).unwrap(),
};
if let Some(intr) = _intr {
if let Some(intr_data) = _intr_data {
let intr = intr.as_usize().unwrap() as u32;
debug!("interrupt-parent = 0x{:08x}", intr);
item.parent_phandle = Some(intr);
debug!("interrupts begin:");
for chunk in intr_data.value.chunks(4) {
debug!("0x{:08x}, ", BE::read_u32(chunk));
item.interrupts.push(BE::read_u32(chunk));
}
debug!("interrupts end");
}
}
if item.phandle == root_intr_parent {
self.root_idx = idx as usize;
}
self.chips.push(item);
idx += 1;
}
}
}
fn init_inner2(&mut self) {
let mut x = 0;
while x < self.chips.len() {
let mut y = 0;
while y < self.chips.len() {
if x == y {
y += 1;
continue;
}
if let Some(pp) = self.chips[y].parent_phandle
&& pp == self.chips[x].phandle
{
self.chips[y].parent = Some(x);
self.chips[x].childs.push(y);
}
y += 1;
}
x += 1;
}
}
fn init_inner3(&mut self, fdt: &fdt::Fdt, irq_desc: &mut [IrqDesc; 1024]) {
//run init
let mut queue = Vec::new();
let mut irq_idx: usize = 0;
queue.push(self.root_idx);
while !queue.is_empty() {
let cur_idx = queue.pop().unwrap();
queue.extend_from_slice(&self.chips[cur_idx].childs);
let virq = self.chips[cur_idx]
.ic
.irq_init(fdt, irq_desc, cur_idx, &mut irq_idx);
if let Ok(Some(virq)) = virq {
irq_desc[virq].basic.child_ic_idx = Some(cur_idx);
}
}
}
}
pub struct IrqChipCore {
//TODO: support multi level interrupt constrollers
pub irq_chip_list: IrqChipList,
pub irq_desc: [IrqDesc; 1024],
}
impl IrqChipCore {
pub fn irq_ack(&mut self) -> u32 {
self.irq_chip_list.chips[self.irq_chip_list.root_idx]
.ic
.irq_ack()
}
pub fn irq_eoi(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_eoi(hwirq)
}
pub fn irq_enable(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_enable(hwirq)
}
#[allow(unused)]
pub fn irq_disable(&mut self, virq: u32) {
let irq_desc = &self.irq_desc[virq as usize];
let ic_idx = irq_desc.basic.ic_idx;
let hwirq = irq_desc.basic.ic_irq;
self.irq_chip_list.chips[ic_idx].ic.irq_disable(hwirq)
}
pub fn irq_to_virq(&mut self, hwirq: u32) -> Option<usize> {
self.irq_chip_list.chips[self.irq_chip_list.root_idx]
.ic
.irq_to_virq(hwirq)
}
pub fn init(&mut self, fdt: &Fdt) {
for i in 0..1024 {
self.irq_desc[i].basic.idx = i;
}
self.irq_chip_list.init_inner1(fdt);
self.irq_chip_list.init_inner2();
self.irq_chip_list.init_inner3(fdt, &mut self.irq_desc);
}
}
pub unsafe fn acknowledge(_irq: usize) {
// TODO
}
const INIT_HANDLER: Option<Box<dyn InterruptHandler>> = None;
const INIT_IRQ_DESC: IrqDesc = IrqDesc {
basic: IrqDescItem {
idx: 0,
ic_idx: 0,
ic_irq: 0,
child_ic_idx: None,
used: false,
},
handler: INIT_HANDLER,
};
pub static mut IRQ_CHIP: IrqChipCore = IrqChipCore {
irq_chip_list: IrqChipList {
chips: Vec::new(),
root_phandle: 0,
root_idx: 0,
},
irq_desc: [INIT_IRQ_DESC; 1024],
};
pub fn init(fdt: &Fdt) {
travel_interrupt_ctrl(fdt);
unsafe {
IRQ_CHIP.init(fdt);
}
}
pub fn register_irq(virq: u32, handler: Box<dyn InterruptHandler>) {
if virq >= 1024 {
error!("irq {} exceed 1024!!!", virq);
return;
}
unsafe {
if IRQ_CHIP.irq_desc[virq as usize].handler.is_some() {
error!("irq {} has already been registered!", virq);
return;
}
IRQ_CHIP.irq_desc[virq as usize].handler = Some(handler);
}
}
#[inline]
pub fn is_reserved(_cpu_id: LogicalCpuId, _index: u8) -> bool {
//TODO
true
}
#[inline]
pub fn set_reserved(_cpu_id: LogicalCpuId, _index: u8, _reserved: bool) {
//TODO
}
pub fn available_irqs_iter(_cpu_id: LogicalCpuId) -> impl Iterator<Item = u8> + 'static {
error!("available_irqs_iter has been called");
0..0
}
+39
View File
@@ -1,7 +1,11 @@
pub mod irqchip;
use crate::startup::memory::{register_memory_region, BootloaderMemoryKind};
use alloc::vec::Vec;
use byteorder::{ByteOrder, BE};
use core::slice;
use fdt::{node::NodeProperty, Fdt};
use log::debug;
use spin::once::Once;
pub static DTB_BINARY: Once<Vec<u8>> = Once::new();
@@ -23,6 +27,41 @@ pub unsafe fn init(dtb: Option<(usize, usize)>) {
}
}
pub fn travel_interrupt_ctrl(fdt: &Fdt) {
let root_intr_parent = fdt
.root()
.property("interrupt-parent")
.and_then(NodeProperty::as_usize)
.unwrap();
debug!("root parent = 0x{:08x}", root_intr_parent);
for node in fdt.all_nodes() {
if node.property("interrupt-controller").is_some() {
let compatible = node.property("compatible").unwrap().as_str().unwrap();
let phandle = node.property("phandle").unwrap().as_usize().unwrap();
let intr_cells = node.interrupt_cells().unwrap();
let _intr = node
.property("interrupt-parent")
.and_then(NodeProperty::as_usize);
let _intr_data = node.property("interrupts");
debug!(
"{}, compatible = {}, #interrupt-cells = 0x{:08x}, phandle = 0x{:08x}",
node.name, compatible, intr_cells, phandle
);
if let Some(intr) = _intr {
if let Some(intr_data) = _intr_data {
debug!("interrupt-parent = 0x{:08x}", intr);
debug!("interrupts begin:");
for chunk in intr_data.value.chunks(4) {
debug!("0x{:08x}, ", BE::read_u32(chunk));
}
debug!("interrupts end");
}
}
}
}
}
#[allow(unused)]
pub fn register_memory_ranges(dt: &Fdt) {
for chunk in dt.memory().regions() {
+6 -5
View File
@@ -14,9 +14,13 @@ use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use crate::context::file::InternalFlags;
use crate::arch::interrupt::{available_irqs_iter, bsp_apic_id, is_reserved, set_reserved};
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
use crate::arch::interrupt::{available_irqs_iter, irq::acknowledge, is_reserved, set_reserved};
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
use crate::dtb::irqchip::{acknowledge, available_irqs_iter, is_reserved, set_reserved};
use crate::{
arch::interrupt::bsp_apic_id,
cpu_set::LogicalCpuId,
event,
syscall::{
@@ -27,9 +31,6 @@ use crate::{
},
};
#[cfg(not(target_arch = "riscv64"))]
use crate::interrupt::irq::acknowledge;
use super::{CallerCtx, GlobalSchemes, OpenResult};
/// IRQ queues
@@ -330,7 +331,7 @@ impl crate::scheme::KernelScheme for IrqScheme {
return Ok(0);
}
handle_ack.store(ack, Ordering::SeqCst);
#[cfg(not(target_arch = "riscv64"))]
unsafe {
acknowledge(handle_irq as usize);
}