diff --git a/platform/aarch64/imx8mp/board.rs b/platform/aarch64/imx8mp/board.rs index 63a29473..5b9ea976 100644 --- a/platform/aarch64/imx8mp/board.rs +++ b/platform/aarch64/imx8mp/board.rs @@ -109,10 +109,10 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 8] = [ // }, // serial ]; -pub const ROOT_ZONE_IRQS: [u32; 28] = [ +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ 35, 36, 37, 38, 45, 52, 55, 56, 57, 59, 64, 67, 75, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 135, 150, 151, 152, 162, -]; +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/ok6254-c/board.rs b/platform/aarch64/ok6254-c/board.rs index a3b76054..85a49631 100644 --- a/platform/aarch64/ok6254-c/board.rs +++ b/platform/aarch64/ok6254-c/board.rs @@ -26,7 +26,6 @@ pub const BOARD_NAME: &str = "ok6254"; pub const BOARD_NCPUS: usize = 4; pub const BOARD_UART_BASE: u64 = 0x2800000; - #[rustfmt::skip] pub static BOARD_MPIDR_MAPPINGS: [u64; BOARD_NCPUS] = [ 0x0, // cpu0 @@ -127,9 +126,9 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 12] = [ }, // 0x10000000 ~ 0x80000000 ]; -pub const ROOT_ZONE_IRQS: [u32; 13] = [ +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ 64, 66, 114, 115, 118, 165, 194, 195, 210, 211, 228, 258, 266, -]; +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/phytium-pi/board.rs b/platform/aarch64/phytium-pi/board.rs index aa102509..ce969f87 100644 --- a/platform/aarch64/phytium-pi/board.rs +++ b/platform/aarch64/phytium-pi/board.rs @@ -131,8 +131,8 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 11] = [ }, ]; //46-usb2,54-mailbox 64-usb2,87-net,104、105-mmc,116-uart,133、138-i2c,191-spi -pub const ROOT_ZONE_IRQS: [u32; 14] = - [46, 54, 64, 65, 75, 76, 78, 87, 104, 105, 116, 133, 138, 191]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = + &get_irqs_bitmap(&[46, 54, 64, 65, 75, 76, 78, 87, 104, 105, 116, 133, 138, 191]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/qemu-gicv2/board.rs b/platform/aarch64/qemu-gicv2/board.rs index 98cae2b2..c8e09dca 100644 --- a/platform/aarch64/qemu-gicv2/board.rs +++ b/platform/aarch64/qemu-gicv2/board.rs @@ -14,7 +14,10 @@ // Authors: // use crate::{ - arch::{mmu::MemoryType, zone::{HvArchZoneConfig,GicConfig,Gicv2Config}}, + arch::{ + mmu::MemoryType, + zone::{GicConfig, Gicv2Config, HvArchZoneConfig}, + }, config::*, }; @@ -72,7 +75,7 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 3] = [ // 35 36 37 38 -> pcie intx# // 65 -> ivc -pub const ROOT_ZONE_IRQS: [u32; 9] = [33, 64, 77, 79, 35, 36, 37, 38, 65]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[33, 64, 77, 79, 35, 36, 37, 38, 65]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, @@ -89,7 +92,6 @@ pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { }), }; - pub const ROOT_PCI_CONFIG: HvPciConfig = HvPciConfig { ecam_base: 0x4010000000, ecam_size: 0x10000000, diff --git a/platform/aarch64/qemu-gicv3/board.rs b/platform/aarch64/qemu-gicv3/board.rs index 124b9dca..d60b4a8a 100644 --- a/platform/aarch64/qemu-gicv3/board.rs +++ b/platform/aarch64/qemu-gicv3/board.rs @@ -74,7 +74,8 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 3] = [ // 35 36 37 38 -> pcie intx# // 65 -> ivc -pub const ROOT_ZONE_IRQS: [u32; 9] = [33, 64, 77, 79, 35, 36, 37, 38, 65]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = + &get_irqs_bitmap(&[33, 64, 77, 79, 35, 36, 37, 38, 65]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/rk3568/board.rs b/platform/aarch64/rk3568/board.rs index 84f07a71..e590c189 100644 --- a/platform/aarch64/rk3568/board.rs +++ b/platform/aarch64/rk3568/board.rs @@ -46,10 +46,10 @@ pub const BOARD_PHYSMEM_LIST: &[(u64, u64, MemoryType)] = &[ ]; pub const ROOT_ZONE_DTB_ADDR: u64 = 0xa0000000; -pub const ROOT_ZONE_KERNEL_ADDR: u64 = 0x60080000 ; -pub const ROOT_ZONE_ENTRY: u64 = 0x60080000 ; +pub const ROOT_ZONE_KERNEL_ADDR: u64 = 0x60080000; +pub const ROOT_ZONE_ENTRY: u64 = 0x60080000; //pub const ROOT_ZONE_CPUS: u64 = (1 << 0) ; -pub const ROOT_ZONE_CPUS: u64 = (1 << 0)|(1 << 1); +pub const ROOT_ZONE_CPUS: u64 = (1 << 0) | (1 << 1); pub const ROOT_ZONE_NAME: &str = "root-linux"; pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 19] = [ @@ -187,8 +187,10 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 19] = [ }, //sdhci ]; -pub const ROOT_ZONE_IRQS: [u32; 20] = [ - 0x84, 0x98, 0x40, 0x104, 0x105, 0x106, 0x107, 0x2d, 0x2e, 0x2b, 0x2a, 0x29, 0x33, 0x96, 0x11c, 0x44, 0x43, 0x42, 0x41, 0x8d]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ + 0x84, 0x98, 0x40, 0x104, 0x105, 0x106, 0x107, 0x2d, 0x2e, 0x2b, 0x2a, 0x29, 0x33, 0x96, 0x11c, + 0x44, 0x43, 0x42, 0x41, 0x8d, +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/rk3588/board.rs b/platform/aarch64/rk3588/board.rs index b12c6ec1..8ac239c3 100644 --- a/platform/aarch64/rk3588/board.rs +++ b/platform/aarch64/rk3588/board.rs @@ -169,11 +169,11 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 9] = [ // } ]; -// pub const ROOT_ZONE_IRQS: [u32; 10] = [39, 64, 235, 237, 309, 312, 360, 365, 429, 455]; -pub const ROOT_ZONE_IRQS: [u32; 29] = [ +// pub const ROOT_ZONE_IRQS_BITMAP: [u32; 10] = [39, 64, 235, 237, 309, 312, 360, 365, 429, 455]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ 39, 41, 42, 43, 45, 46, 64, 120, 121, 235, 237, 247, 248, 250, 251, 252, 265, 266, 309, 312, 313, 355, 360, 365, 423, 424, 425, 429, 455, -]; +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { is_aarch32: 0, diff --git a/platform/aarch64/zcu102/board.rs b/platform/aarch64/zcu102/board.rs index b3527283..1ca5fe5b 100644 --- a/platform/aarch64/zcu102/board.rs +++ b/platform/aarch64/zcu102/board.rs @@ -15,7 +15,10 @@ // ForeverYolo <2572131118@qq.com> use crate::config::HvConfigMemoryRegion; use crate::{ - arch::{mmu::MemoryType, zone::{GicConfig, Gicv2Config, HvArchZoneConfig},}, + arch::{ + mmu::MemoryType, + zone::{GicConfig, Gicv2Config, HvArchZoneConfig}, + }, config::*, }; @@ -112,7 +115,8 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 9] = [ }, // gpio ]; -pub const ROOT_ZONE_IRQS: [u32; 11] = [53, 81, 175, 176, 177, 178, 64, 50, 48, 49, 95]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = + &get_irqs_bitmap(&[53, 81, 175, 176, 177, 178, 64, 50, 48, 49, 95]); // serial-mmc-pmu-pmu-pmu-pmu-(hvisor_virtio_device)-gpio-i2c(ff030000)-i2c(ff020000)-ethernet pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { diff --git a/platform/loongarch64/ls3a5000/board.rs b/platform/loongarch64/ls3a5000/board.rs index 184dc110..0ac53198 100644 --- a/platform/loongarch64/ls3a5000/board.rs +++ b/platform/loongarch64/ls3a5000/board.rs @@ -150,7 +150,7 @@ pub const ROOT_ZONE_MEMORY_REGIONS: &[HvConfigMemoryRegion] = &[ }, // SHARD_MEM ]; -pub const ROOT_ZONE_IRQS: [u32; 0] = []; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { dummy: 0 }; pub const ROOT_ZONE_IVC_CONFIG: [HvIvcConfig; 0] = []; diff --git a/platform/loongarch64/ls3a6000/board.rs b/platform/loongarch64/ls3a6000/board.rs index 184dc110..0ac53198 100644 --- a/platform/loongarch64/ls3a6000/board.rs +++ b/platform/loongarch64/ls3a6000/board.rs @@ -150,7 +150,7 @@ pub const ROOT_ZONE_MEMORY_REGIONS: &[HvConfigMemoryRegion] = &[ }, // SHARD_MEM ]; -pub const ROOT_ZONE_IRQS: [u32; 0] = []; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { dummy: 0 }; pub const ROOT_ZONE_IVC_CONFIG: [HvIvcConfig; 0] = []; diff --git a/platform/riscv64/hifive-premier-p550/board.rs b/platform/riscv64/hifive-premier-p550/board.rs index e7a3d179..9cf06504 100644 --- a/platform/riscv64/hifive-premier-p550/board.rs +++ b/platform/riscv64/hifive-premier-p550/board.rs @@ -146,7 +146,7 @@ pub const HW_IRQS: [u32; 21] = [ 0x1, 0x2, 0x3, 0x4, // cache controller 0x4f, // emmc 0x51, // sd-card - 0x64, // uart0 + 0x64, // uart0 0x164, 0x168, 0x165, 0x166, // iommu 0x183, // npu 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, 0x81, 0x83, // mailbox @@ -155,16 +155,15 @@ pub const HW_IRQS: [u32; 21] = [ ]; // irqs belong to the root zone. -pub const ROOT_ZONE_IRQS: [u32; 20] = [ +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ 0x1, 0x2, 0x3, 0x4, // cache controller 0x51, // sd-card - 0x64, // uart0 + 0x64, // uart0 0x164, 0x168, 0x165, 0x166, // iommu 0x183, // npu 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, 0x81, 0x83, // mailbox 0x123, // i2c - // 0x01, 0x03, 0x04, 0x02, // cache controller -]; +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { plic_base: 0xc000000, diff --git a/platform/riscv64/megrez/board.rs b/platform/riscv64/megrez/board.rs index bfe9abe6..e77374b0 100644 --- a/platform/riscv64/megrez/board.rs +++ b/platform/riscv64/megrez/board.rs @@ -198,11 +198,11 @@ pub const HW_IRQS: [u32; 8] = [ ]; // irqs belong to the root zone. -pub const ROOT_ZONE_IRQS: [u32; 3] = [ +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[ 0x51, // mmc@0x50460000 0x64, // serial@0x50900000 0x3d, // ethernet@50400000 -]; +]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { plic_base: 0xc000000, diff --git a/platform/riscv64/qemu-aia/board.rs b/platform/riscv64/qemu-aia/board.rs index 059b4d46..a23eae5b 100644 --- a/platform/riscv64/qemu-aia/board.rs +++ b/platform/riscv64/qemu-aia/board.rs @@ -98,7 +98,7 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 9] = [ ]; pub const HW_IRQS: [u32; 11] = [1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]; -pub const ROOT_ZONE_IRQS: [u32; 11] = [1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]; // ARCH= riscv .It doesn't matter temporarily. +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]); // ARCH= riscv .It doesn't matter temporarily. pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { plic_base: 0xc000000, diff --git a/platform/riscv64/qemu-plic/board.rs b/platform/riscv64/qemu-plic/board.rs index 094ef417..569cb327 100644 --- a/platform/riscv64/qemu-plic/board.rs +++ b/platform/riscv64/qemu-plic/board.rs @@ -100,7 +100,7 @@ pub const ROOT_ZONE_MEMORY_REGIONS: [HvConfigMemoryRegion; 9] = [ pub const HW_IRQS: [u32; 11] = [1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]; // irqs belong to the root zone. -pub const ROOT_ZONE_IRQS: [u32; 11] = [1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[1, 2, 3, 4, 5, 8, 10, 33, 34, 35, 36]); pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { plic_base: 0xc000000, diff --git a/platform/x86_64/nuc14mnk/board.rs b/platform/x86_64/nuc14mnk/board.rs index d5f001e9..cad0456c 100644 --- a/platform/x86_64/nuc14mnk/board.rs +++ b/platform/x86_64/nuc14mnk/board.rs @@ -128,7 +128,7 @@ const ROOT_ZONE_SETUP_ADDR: GuestPhysAddr = 0xa000; const ROOT_ZONE_VMLINUX_ENTRY_ADDR: GuestPhysAddr = 0x10_0000; const ROOT_ZONE_SCREEN_BASE_ADDR: GuestPhysAddr = 0x8000_0000; -pub const ROOT_ZONE_IRQS: [u32; 32] = [0; 32]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[0; 32]); pub const ROOT_ZONE_IOAPIC_BASE: usize = 0xfec0_0000; pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { ioapic_base: ROOT_ZONE_IOAPIC_BASE, diff --git a/platform/x86_64/qemu/board.rs b/platform/x86_64/qemu/board.rs index 342bac03..666ad306 100644 --- a/platform/x86_64/qemu/board.rs +++ b/platform/x86_64/qemu/board.rs @@ -92,7 +92,7 @@ const ROOT_ZONE_SETUP_ADDR: GuestPhysAddr = 0xa000; const ROOT_ZONE_VMLINUX_ENTRY_ADDR: GuestPhysAddr = 0x10_0000; const ROOT_ZONE_SCREEN_BASE_ADDR: GuestPhysAddr = 0x7000_0000; -pub const ROOT_ZONE_IRQS: [u32; 32] = [0; 32]; +pub const ROOT_ZONE_IRQS_BITMAP: &[BitmapWord] = &get_irqs_bitmap(&[0; 32]); pub const ROOT_ZONE_IOAPIC_BASE: usize = 0xfec0_0000; pub const ROOT_ARCH_ZONE_CONFIG: HvArchZoneConfig = HvArchZoneConfig { ioapic_base: ROOT_ZONE_IOAPIC_BASE, diff --git a/src/arch/loongarch64/zone.rs b/src/arch/loongarch64/zone.rs index 96ac8883..b9dd8b70 100644 --- a/src/arch/loongarch64/zone.rs +++ b/src/arch/loongarch64/zone.rs @@ -117,7 +117,7 @@ impl Zone { } Ok(()) } - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) {} + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[u32]) {} } pub fn disable_hwi_through() { diff --git a/src/arch/x86_64/zone.rs b/src/arch/x86_64/zone.rs index 75e7c43d..e4a55f82 100644 --- a/src/arch/x86_64/zone.rs +++ b/src/arch/x86_64/zone.rs @@ -96,7 +96,7 @@ impl Zone { Ok(()) } - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) {} + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[u32]) {} /// called after cpu_set is initialized pub fn arch_zone_pre_configuration(&mut self, config: &HvZoneConfig) -> HvResult { diff --git a/src/config.rs b/src/config.rs index 7d72f45d..e09876a3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -22,9 +22,13 @@ pub const MEM_TYPE_RAM: u32 = 0; pub const MEM_TYPE_IO: u32 = 1; pub const MEM_TYPE_VIRTIO: u32 = 2; -pub const CONFIG_MAGIC_VERSION: usize = 0x3; +pub const CONFIG_MAGIC_VERSION: usize = 0x4; pub const CONFIG_MAX_MEMORY_REGIONS: usize = 64; -pub const CONFIG_MAX_INTERRUPTS: usize = 32; + +pub type BitmapWord = u32; +pub const CONFIG_MAX_INTERRUPTS: usize = 1024; +pub const CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD: usize = 32; + pub const CONFIG_NAME_MAXLEN: usize = 32; pub const CONFIG_MAX_IVC_CONFIGS: usize = 2; pub const CONFIG_MAX_PCI_DEV: usize = 32; @@ -80,8 +84,7 @@ pub struct HvZoneConfig { cpus: u64, num_memory_regions: u32, memory_regions: [HvConfigMemoryRegion; CONFIG_MAX_MEMORY_REGIONS], - num_interrupts: u32, - interrupts: [u32; CONFIG_MAX_INTERRUPTS], + interrupts_bitmap: [BitmapWord; CONFIG_MAX_INTERRUPTS / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD], num_ivc_configs: u32, ivc_configs: [HvIvcConfig; CONFIG_MAX_IVC_CONFIGS], pub entry_point: u64, @@ -102,8 +105,8 @@ impl HvZoneConfig { cpus: u64, num_memory_regions: u32, memory_regions: [HvConfigMemoryRegion; CONFIG_MAX_MEMORY_REGIONS], - num_interrupts: u32, - interrupts: [u32; CONFIG_MAX_INTERRUPTS], + interrupts_bitmap: [BitmapWord; + CONFIG_MAX_INTERRUPTS / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD], num_ivc_configs: u32, ivc_configs: [HvIvcConfig; CONFIG_MAX_IVC_CONFIGS], entry_point: u64, @@ -122,8 +125,7 @@ impl HvZoneConfig { cpus, num_memory_regions, memory_regions, - num_interrupts, - interrupts, + interrupts_bitmap, num_ivc_configs, ivc_configs, entry_point, @@ -144,8 +146,8 @@ impl HvZoneConfig { &self.memory_regions[..self.num_memory_regions as usize] } - pub fn interrupts(&self) -> &[u32] { - &self.interrupts[..self.num_interrupts as usize] + pub fn interrupts_bitmap(&self) -> &[BitmapWord] { + &self.interrupts_bitmap } pub fn cpus(&self) -> Vec { @@ -192,3 +194,32 @@ pub struct HvIvcConfig { pub interrupt_num: u32, pub max_peers: u32, } + +pub const fn get_irqs_bitmap( + numbers: &[u32; N], +) -> [BitmapWord; CONFIG_MAX_INTERRUPTS / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD] { + assert!( + CONFIG_MAX_INTERRUPTS % CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD == 0, + "Configuration error: CONFIG_MAX_INTERRUPTS must be a multiple of 32 for a [u32] bitmap without rounding.", + ); + + let mut bitmap = [0; CONFIG_MAX_INTERRUPTS / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD]; + + let mut i = 0; + while i < N { + let num = numbers[i]; + + assert!( + (num as usize) < CONFIG_MAX_INTERRUPTS, + "Input IRQ number is out of bounds. It must be less than CONFIG_MAX_INTERRUPTS.", + ); + + let word_index = num as usize / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD; + let bit_index = num as usize & (CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD - 1); + + bitmap[word_index] |= (1 as BitmapWord) << bit_index; + i += 1; + } + + bitmap +} diff --git a/src/device/irqchip/aia/mod.rs b/src/device/irqchip/aia/mod.rs index fd1b89a4..9043dc85 100644 --- a/src/device/irqchip/aia/mod.rs +++ b/src/device/irqchip/aia/mod.rs @@ -22,7 +22,7 @@ pub mod vaplic; pub mod vimsic; use crate::arch::cpu::this_cpu_id; use crate::arch::zone::HvArchZoneConfig; -use crate::config::HvZoneConfig; +use crate::config::{BitmapWord, HvZoneConfig, CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD}; use crate::consts::{MAX_CPU_NUM, MAX_ZONE_NUM}; use crate::error::HvResult; use crate::memory::GuestPhysAddr; @@ -219,16 +219,23 @@ impl Zone { } /// irq_bitmap_init, and set these irqs' hw bit in vplic to true. - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) { + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[BitmapWord]) { // insert to zone.irq_bitmap - for irq in irqs { - let irq_id = *irq; - // They are hardware interrupts. - if HW_IRQS.iter().any(|&x| x == irq_id) { - self.get_vaplic().vaplic_set_hw(irq_id as usize, true); - info!("Set irq {} to hardware interrupt", irq_id); + for i in 0..irqs_bitmap.len() { + let word = irqs_bitmap[i]; + + for j in 0..CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD { + if ((word >> j) & 1) == 1 { + let irq_id = (i * CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD + j) as u32; + + // They are hardware interrupts. + if HW_IRQS.iter().any(|&x| x == irq_id) { + self.get_vaplic().vaplic_set_hw(irq_id as usize, true); + info!("Set irq {} to hardware interrupt", irq_id); + } + self.insert_irq_to_bitmap(irq_id); + } } - self.insert_irq_to_bitmap(irq_id); } // print irq_bitmap for (index, &word) in self.irq_bitmap.iter().enumerate() { diff --git a/src/device/irqchip/gicv2/vgic.rs b/src/device/irqchip/gicv2/vgic.rs index a3af2309..4490ef10 100644 --- a/src/device/irqchip/gicv2/vgic.rs +++ b/src/device/irqchip/gicv2/vgic.rs @@ -14,6 +14,7 @@ // Authors: // Hangqi Ren <2572131118@qq.com> use crate::arch::zone::{GicConfig, Gicv2Config, HvArchZoneConfig}; +use crate::config::{BitmapWord, CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD}; use crate::device::irqchip::gicv2::gicd::{ get_max_int_num, GICD, GICD_CTRL_REG_OFFSET, GICD_ICACTIVER_REG_OFFSET, GICD_ICENABLER_REG_OFFSET, GICD_ICFGR_REG_OFFSET, GICD_ICPENDR_REG_OFFSET, @@ -93,12 +94,21 @@ impl Zone { } // store the interrupt number in the irq_bitmap. - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) { + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[BitmapWord]) { // Enable each cpu's sgi and ppi access permission self.irq_bitmap[0] = 0xffff_ffff; - for irq in irqs { - self.insert_irq_to_bitmap(*irq); + + for i in 0..irqs_bitmap.len() { + let word = irqs_bitmap[i]; + + for j in 0..CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD { + if ((word >> j) & 1) == 1 { + let irq_id = (i * CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD + j) as u32; + self.insert_irq_to_bitmap(irq_id); + } + } } + for (index, &word) in self.irq_bitmap.iter().enumerate() { for bit_position in 0..32 { if word & (1 << bit_position) != 0 { diff --git a/src/device/irqchip/gicv3/vgic.rs b/src/device/irqchip/gicv3/vgic.rs index 7c52c26e..bd16002b 100644 --- a/src/device/irqchip/gicv3/vgic.rs +++ b/src/device/irqchip/gicv3/vgic.rs @@ -19,6 +19,7 @@ use super::{gicd::GICD_LOCK, is_spi}; use crate::platform::BOARD_MPIDR_MAPPINGS; use crate::{ arch::zone::{GicConfig, Gicv2Config, Gicv3Config, HvArchZoneConfig}, + config::{BitmapWord, CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD, CONFIG_MAX_INTERRUPTS}, consts::MAX_CPU_NUM, device::irqchip::gicv3::{ gicd::*, gicr::*, gits::*, host_gicd_base, host_gicr_base, host_gits_base, @@ -72,14 +73,23 @@ impl Zone { } } - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) { - for irq in irqs { - self.insert_irq_to_bitmap(*irq); + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[BitmapWord]) { + for i in 0..irqs_bitmap.len() { + let word = irqs_bitmap[i]; + + for j in 0..CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD { + if ((word >> j) & 1) == 1 { + let irq_id = (i * CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD + j) as u32; + self.insert_irq_to_bitmap(irq_id); + } + } } + for (index, &word) in self.irq_bitmap.iter().enumerate() { - for bit_position in 0..32 { + for bit_position in 0..CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD { if word & (1 << bit_position) != 0 { - let interrupt_number = index * 32 + bit_position; + let interrupt_number = + index * CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD + bit_position; info!( "Found interrupt in Zone {} irq_bitmap: {}", self.id, interrupt_number @@ -90,9 +100,9 @@ impl Zone { } fn insert_irq_to_bitmap(&mut self, irq: u32) { - assert!(irq < 1024); // 1024 is the maximum number of interrupts supported by GICv3 (GICD_TYPER.ITLinesNumber) - let irq_index = irq / 32; - let irq_bit = irq % 32; + assert!(irq < (CONFIG_MAX_INTERRUPTS as u32)); // CONFIG_MAX_INTERRUPTS is the maximum number of interrupts supported by GICv3 (GICD_TYPER.ITLinesNumber) + let irq_index = irq / (CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD as u32); + let irq_bit = irq % (CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD as u32); self.irq_bitmap[irq_index as usize] |= 1 << irq_bit; } } diff --git a/src/device/irqchip/plic/mod.rs b/src/device/irqchip/plic/mod.rs index 64a9163c..243580c8 100644 --- a/src/device/irqchip/plic/mod.rs +++ b/src/device/irqchip/plic/mod.rs @@ -22,6 +22,7 @@ use self::vplic::*; use crate::arch::zone::HvArchZoneConfig; use crate::config::root_zone_config; use crate::config::HvZoneConfig; +use crate::config::{BitmapWord, CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD}; use crate::consts::{MAX_CPU_NUM, MAX_ZONE_NUM}; use crate::error::HvResult; use crate::memory::mmio::MMIOAccess; @@ -256,17 +257,26 @@ impl Zone { } /// irq_bitmap_init, and set these irqs' hw bit in vplic to true. - pub fn irq_bitmap_init(&mut self, irqs: &[u32]) { + pub fn irq_bitmap_init(&mut self, irqs_bitmap: &[BitmapWord]) { // insert to zone.irq_bitmap - for irq in irqs { - let irq_id = *irq; - // They are hardware interrupts. - if HW_IRQS.iter().any(|&x| x == irq_id) { - self.get_vplic().vplic_set_hw(irq_id as usize, true); - info!("Set irq {} to hardware interrupt", irq_id); + for i in 0..irqs_bitmap.len() { + let word = irqs_bitmap[i]; + + for j in 0..CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD { + if ((word >> j) & 1) == 1 { + let irq_id = (i * CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD + j) as u32; + + // They are hardware interrupts. + if HW_IRQS.iter().any(|&x| x == irq_id) { + self.get_vplic().vplic_set_hw(irq_id as usize, true); + info!("Set irq {} to hardware interrupt", irq_id); + } + + self.insert_irq_to_bitmap(irq_id); + } } - self.insert_irq_to_bitmap(irq_id); } + // print irq_bitmap for (index, &word) in self.irq_bitmap.iter().enumerate() { for bit_position in 0..32 { diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 8dc1c493..d5241d9b 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -15,8 +15,9 @@ // use crate::{ config::{ - HvConfigMemoryRegion, HvIvcConfig, HvPciConfig, HvZoneConfig, CONFIG_MAX_INTERRUPTS, - CONFIG_MAX_IVC_CONFIGS, CONFIG_MAX_MEMORY_REGIONS, CONFIG_MAX_PCI_DEV, CONFIG_NAME_MAXLEN, + HvConfigMemoryRegion, HvIvcConfig, HvPciConfig, HvZoneConfig, + CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD, CONFIG_MAX_INTERRUPTS, CONFIG_MAX_IVC_CONFIGS, + CONFIG_MAX_MEMORY_REGIONS, CONFIG_MAX_PCI_DEV, CONFIG_NAME_MAXLEN, }, consts::INVALID_ADDRESS, }; @@ -59,13 +60,8 @@ pub fn platform_root_zone_config() -> HvZoneConfig { ivc_configs[.._num_ivc_configs].copy_from_slice(&ROOT_ZONE_IVC_CONFIG); } - let mut interrupts = [0; CONFIG_MAX_INTERRUPTS]; - check!( - ROOT_ZONE_IRQS.len(), - CONFIG_MAX_INTERRUPTS, - "ROOT_ZONE_IRQS" - ); - interrupts[..ROOT_ZONE_IRQS.len()].copy_from_slice(&ROOT_ZONE_IRQS); + let mut interrupts_bitmap = [0; CONFIG_MAX_INTERRUPTS / CONFIG_INTERRUPTS_BITMAP_BITS_PER_WORD]; + interrupts_bitmap[..ROOT_ZONE_IRQS_BITMAP.len()].copy_from_slice(&ROOT_ZONE_IRQS_BITMAP); let mut name = [0; CONFIG_NAME_MAXLEN]; check!(ROOT_ZONE_NAME.len(), CONFIG_NAME_MAXLEN, "ROOT_ZONE_NAME"); @@ -88,8 +84,7 @@ pub fn platform_root_zone_config() -> HvZoneConfig { ROOT_ZONE_CPUS, ROOT_ZONE_MEMORY_REGIONS.len() as u32, memory_regions, - ROOT_ZONE_IRQS.len() as u32, - interrupts, + interrupts_bitmap, _num_ivc_configs as _, ivc_configs, ROOT_ZONE_ENTRY, diff --git a/src/zone.rs b/src/zone.rs index 58bf6ec4..28c99a4a 100644 --- a/src/zone.rs +++ b/src/zone.rs @@ -256,7 +256,7 @@ pub fn zone_create(config: &HvZoneConfig) -> HvResult>> { // Initialize the virtual interrupt controller, it needs zone.cpu_num zone.virqc_init(config); - zone.irq_bitmap_init(config.interrupts()); + zone.irq_bitmap_init(config.interrupts_bitmap()); let mut dtb_ipa = INVALID_ADDRESS as u64; for region in config.memory_regions() {