GICv2ドライバの実装
まずはDTBから取得する
code:_
INFO init_gicv2 GICv2 GICD Base: 0x40041000, Size: 0x1000
INFO init_gicv2 GICC Base: 0x40042000, Size: 0x2000
GICD_TYPERレジスタから最大割り込み数などの情報を取得する
code:rs
/// bits4:0 ITLinesNumber: 最大割り込みID数 = (ITLinesNumber+1)*32
/// bits7:5 CPUNumber: 実装されているCPUインターフェース数 - 1
pub const GICD_TYPER: usize = 0x004;
pub fn dump_gicd_info(base: usize) {
let typer = unsafe {
mmio_read32(base, GICD_TYPER)
};
let it_lines_number = typer & 0x1F;
let max_interrupts = (it_lines_number + 1) * 32;
let cpu_number = (typer >> 5) & 0x7;
log_info!(
"GICD_TYPER: {:#010X} (max interrupts: {}, CPU interfaces: {})",
typer,
max_interrupts,
cpu_number + 1
);
}
試したんだけど、いまのアドレスからは0x0が入っていたので違いそう
GICv2に貼ってあるスライドを見ると0xff80_1000のほうを使うらしい
実機での検証結果
code:_
INFO init_gicv2 GICv2 GICD Base: 0xFF841000, Size: 0x1000
INFO init_gicv2 GICC Base: 0xFF842000, Size: 0x2000
INFO dump_gicd_info GICD_TYPER: 0x0000FC67 (max interrupts: 256, CPU interfaces: 4)
Software Generated InterruptによるIRQを発生させてテストを行う
code:rs
pub fn send_sgi_to_self(&self) {
unsafe {
mmio_write32(self.gicd_base, GICD_SGIR, SGIR_TARGET_SELF | SGI_ID);
}
}
DAIFのIが立っていたため割り込みを受け付けていなかったから直した
割り込みハンドラにはGICのベースアドレスの情報を伝えられない
構造体の静的変数として置くほどなのかな、ベースアドレスだけ置いてハンドラの中で構造体を作ってもいいかも
AtomicUsizeでベースアドレスだけ静的変数として置いた
なんか実機だと入力がリアルタイムじゃなくて何個か前に入力した文字が出てくる
空になるまでirqハンドラで回す
レジスタのクリア処理を追加する(たぶんこれが無かったのが原因)
#min1visor