From cc54294dc0262b1f0e882c26855f73dbac7c0927 Mon Sep 17 00:00:00 2001 From: stl Date: Wed, 23 Sep 2026 10:34:31 +0800 Subject: [PATCH 1/4] feat(loongarch64): add 8-CPU support for LS3A6000 --- platform/loongarch64/ls3a6000/board.rs | 2 +- platform/loongarch64/ls3a6000/linker.ld | 2 +- src/arch/loongarch64/cpu.rs | 3 +- src/arch/loongarch64/ipi.rs | 26 +-- src/arch/loongarch64/zone.rs | 23 +- src/device/irqchip/ls7a2000/chip.rs | 297 ++++++++++++++---------- src/device/irqchip/ls7a2000/mod.rs | 6 +- 7 files changed, 192 insertions(+), 167 deletions(-) diff --git a/platform/loongarch64/ls3a6000/board.rs b/platform/loongarch64/ls3a6000/board.rs index 171c3ca9e..a65a12e02 100644 --- a/platform/loongarch64/ls3a6000/board.rs +++ b/platform/loongarch64/ls3a6000/board.rs @@ -19,7 +19,7 @@ use crate::{arch::zone::HvArchZoneConfig, config::*, pci::vpci_dev::VpciDevType} pub const BOARD_NAME: &str = "ls3a6000"; -pub const BOARD_NCPUS: usize = 4; +pub const BOARD_NCPUS: usize = 4; //supported max 8 cores pub const ROOT_ZONE_DTB_ADDR: u64 = 0x10000f000; pub const ROOT_ZONE_KERNEL_ADDR: u64 = 0x200000; diff --git a/platform/loongarch64/ls3a6000/linker.ld b/platform/loongarch64/ls3a6000/linker.ld index a226494f9..9b65e9a14 100644 --- a/platform/loongarch64/ls3a6000/linker.ld +++ b/platform/loongarch64/ls3a6000/linker.ld @@ -1,6 +1,6 @@ ENTRY(arch_entry) BASE_ADDRESS = 0x90000001f0000000; -CPU_NUM = 4; +CPU_NUM = 4; /* supported max 8 cores */ SECTIONS diff --git a/src/arch/loongarch64/cpu.rs b/src/arch/loongarch64/cpu.rs index 7281572ac..e2ccb568c 100644 --- a/src/arch/loongarch64/cpu.rs +++ b/src/arch/loongarch64/cpu.rs @@ -78,8 +78,9 @@ impl ArchCpu { .and_then(|zone| zone.read().phys_to_guest_cpu(physical_cpu)) .unwrap_or(0); info!( - "[[CPU virtualization]] CPU{} run@{:#x}", + "[[CPU virtualization]] CPU{} guest_cpuid={} run@{:#x}", self.get_cpuid(), + self.ctx.gcsr_cpuid, self.ctx.sepc ); debug!("loongarch64: @{:#x?}", self); diff --git a/src/arch/loongarch64/ipi.rs b/src/arch/loongarch64/ipi.rs index 35720de03..2d2d84e63 100644 --- a/src/arch/loongarch64/ipi.rs +++ b/src/arch/loongarch64/ipi.rs @@ -17,7 +17,7 @@ use crate::arch::cpu::this_cpu_id; use crate::consts::{IPI_EVENT_CLEAR_INJECT_IRQ, IPI_EVENT_SEND_IPI}; use core::arch::asm; -use core::ptr::write_volatile; +use loongArch64::iocsr::{iocsr_write_d, iocsr_write_w}; use loongArch64::register::ecfg::LineBasedInterrupt; use loongArch64::register::*; @@ -41,7 +41,6 @@ pub fn arch_notify_event(cpu_id: u64, sgi_num: u64, event_id: usize, queue_was_e } } -const MMIO_BASE: usize = 0x8000_0000_1fe0_0000; const IOCSR_IPI_STATUS: usize = 0x1000; const IOCSR_IPI_ENABLE: usize = 0x1004; const IOCSR_IPI_CLEAR: usize = 0x100c; @@ -101,20 +100,14 @@ pub fn mail_send_percore(data: usize, cpu_id: usize, mailbox_id: usize) { val |= cpu_id << 16; val |= high << 32; // debug!("(mail_send) sending high 32 bits, actual packed value: {:#x}", val); - unsafe { - // asm!("iocsrwr.d {}, {}", in(reg) val, in(reg) 0x1048); - write_volatile(IPI_MMIO_MAIL_SEND as *mut u64, val as u64); - } + iocsr_write_d(IOCSR_MBUF_SEND, val as u64); // send low 32 bits val = 1 << 31; val |= iocsr_mbuf_send_box_lo(mailbox_id) << 2; val |= cpu_id << 16; val |= low << 32; // debug!("(mail_send) sending low 32 bits, actual packed value: {:#x}", val); - unsafe { - // asm!("iocsrwr.d {}, {}", in(reg) val, in(reg) 0x1048); - write_volatile(IPI_MMIO_MAIL_SEND as *mut u64, val as u64); - } + iocsr_write_d(IOCSR_MBUF_SEND, val as u64); } fn ffs(a: usize) -> usize { @@ -132,8 +125,8 @@ fn ffs(a: usize) -> usize { i + 1 } -const IPI_MMIO_IPI_SEND: usize = MMIO_BASE + 0x1040; // 32 bits Write Only -const IPI_MMIO_MAIL_SEND: usize = MMIO_BASE + 0x1048; // 64 bits Write Only +const IOCSR_IPI_SEND: usize = 0x1040; // 32 bits Write Only +const IOCSR_MBUF_SEND: usize = 0x1048; // 64 bits Write Only #[allow(unused_assignments)] pub fn ipi_write_action_percore(cpu_id: usize, _action: usize) { @@ -152,13 +145,10 @@ pub fn ipi_write_action_percore(cpu_id: usize, _action: usize) { val |= irq - 1; val |= (cpu_id as u32) << 16; debug!( - "loongarch64::ipi_write_action writing value {:#x} to MMIO address: {:#x}", - val, IPI_MMIO_IPI_SEND + "loongarch64::ipi_write_action writing value {:#x} to IOCSR: {:#x}", + val, IOCSR_IPI_SEND ); - unsafe { - // asm!("iocsrwr.w {}, {}", in(reg) val, in(reg) 0x1040); - write_volatile(IPI_MMIO_IPI_SEND as *mut u32, val); - } + iocsr_write_w(IOCSR_IPI_SEND, val); debug!( "loongarch64::ipi_write_action sent irq: {} to cpu: {} !", irq, cpu_id diff --git a/src/arch/loongarch64/zone.rs b/src/arch/loongarch64/zone.rs index e692f672a..b6505b2e9 100644 --- a/src/arch/loongarch64/zone.rs +++ b/src/arch/loongarch64/zone.rs @@ -14,7 +14,7 @@ // Authors: // Yulong Han // -use crate::device::irqchip::ls7a2000::chip::get_extioi_sr; +use crate::device::irqchip::ls7a2000::chip::eio_core_isr_mmio_base; use crate::{ arch::{ cpu::this_cpu_id, ipi::SMP_BOOT_CPU, trap::GLOBAL_TRAP_CONTEXT_HELPER_PER_CPU, @@ -535,20 +535,13 @@ fn handle_uart_mmio(mmio: &mut MMIOAccess, base_addr: usize) -> HvResult { } fn handle_extioi_status_mmio(mmio: &mut MMIOAccess, base_addr: usize, size: usize) -> HvResult { - // first dump all 256 SR regs - let extioi_sr = get_extioi_sr(); - debug!("extioi_sr: {}", extioi_sr); - - // write 0 to clear, so all SR regs are RW - // since nonroot runs on cpu2(for example), but it still thinks it's on cpu0, and read SR regs from cpu0 - // we need to return the correct SR regs to nonroot according to this cpu id - let this_cpu_id = this_cpu_id(); - let target_cpu_sr_start = EXTIOI_SR_CORE_BASE + this_cpu_id * 0x100; - let guest_fake_cpu_id = (mmio.address - offset(EXTIOI_SR_CORE_BASE)) / 0x100; - let guest_cpu_sr_start = EXTIOI_SR_CORE_BASE + guest_fake_cpu_id * 0x100; - let compensation_offset = target_cpu_sr_start - guest_cpu_sr_start; - mmio.address += compensation_offset; // since inside each cpu's SR regs region, the "inner offset" should be retained! - mmio_perform_access(BASE_ADDR, mmio); // 1fe0_0000, do not use anything else - wheatfox + // IOCSR 0x1800 refers to the executing CPU's ISR. CPU4 starts at + // node1 + 0x1800 (0x1fe11800), not node0 + 0x1c00 (the route table). + let register_offset = (mmio.address - offset(EXTIOI_SR_CORE_BASE)) % 0x100; + let original_address = mmio.address; + mmio.address = register_offset; + mmio_perform_access(eio_core_isr_mmio_base(this_cpu_id()), mmio); + mmio.address = original_address; Ok(()) } diff --git a/src/device/irqchip/ls7a2000/chip.rs b/src/device/irqchip/ls7a2000/chip.rs index d7c567516..94d32d350 100644 --- a/src/device/irqchip/ls7a2000/chip.rs +++ b/src/device/irqchip/ls7a2000/chip.rs @@ -18,6 +18,7 @@ // wheatfox 2024.2.27 use crate::device::common::MMIODerefWrapper; +use crate::platform::BOARD_NCPUS; use alloc::string::String; use core::ptr::*; use tock_registers::fields::FieldValue; @@ -450,6 +451,68 @@ register_structs! { } } +/// Physical base of chip config space (node 0). 3A6000 on-chip node 1 is +0x10000 (0x1fe10000). +pub const CHIP_CFG_PHY_BASE: usize = 0x1fe0_0000; +/// Logical cores covered by one EIOINTC node (Linux: CORES_PER_EIO_NODE) +pub const CORES_PER_EIO_NODE: usize = 4; +/// Stride between adjacent on-chip node config spaces +pub const EIO_NODE_STRIDE: usize = 0x1_0000; + +/// Number of EIO nodes: 3A5000=1 (4 cores), 3A6000=2 (8 logical cores) +#[inline] +pub fn eio_num_nodes() -> usize { + (BOARD_NCPUS + CORES_PER_EIO_NODE - 1) / CORES_PER_EIO_NODE +} + +#[inline] +pub fn eio_cpu_to_node(cpu: usize) -> usize { + cpu / CORES_PER_EIO_NODE +} + +#[inline] +pub fn eio_cpu_to_local(cpu: usize) -> usize { + cpu % CORES_PER_EIO_NODE +} + +/// MMIO base of node `node` config space (with DMW uncached prefix) +#[inline] +pub fn eio_node_mmio_base(node: usize) -> usize { + PHY_TO_DMW_UNCACHED!(CHIP_CFG_PHY_BASE + node * EIO_NODE_STRIDE) +} + +/// COREn_EXT_IOIsr base for a logical CPU +#[inline] +pub fn eio_core_isr_mmio_base(cpu: usize) -> usize { + let node = eio_cpu_to_node(cpu); + let local = eio_cpu_to_local(cpu); + eio_node_mmio_base(node) + 0x1800 + local * 0x100 +} + +#[inline] +fn extioi_enable_regs(node: usize) -> MMIODerefWrapper { + unsafe { MMIODerefWrapper::new(eio_node_mmio_base(node) + 0x1600) } +} + +#[inline] +fn extioi_bounce_regs(node: usize) -> MMIODerefWrapper { + unsafe { MMIODerefWrapper::new(eio_node_mmio_base(node) + 0x1680) } +} + +#[inline] +fn extioi_status_regs(node: usize) -> MMIODerefWrapper { + unsafe { MMIODerefWrapper::new(eio_node_mmio_base(node) + 0x1700) } +} + +#[inline] +fn extioi_core_status_regs(cpu: usize) -> MMIODerefWrapper { + unsafe { MMIODerefWrapper::new(eio_core_isr_mmio_base(cpu)) } +} + +#[inline] +fn extioi_route_pin_regs(node: usize) -> MMIODerefWrapper { + unsafe { MMIODerefWrapper::new(eio_node_mmio_base(node) + 0x14c0) } +} + const MMIO_BASE: usize = PHY_TO_DMW_UNCACHED!(0x1fe0_0000); const CHIP_CONFIG_BASE: usize = MMIO_BASE + 0x0; const CHIP_OTHER_FUNCTION_BASE: usize = MMIO_BASE + 0x420; @@ -659,10 +722,13 @@ pub fn extioi_is_enabled() -> bool { } pub fn extioi_int_enable_all() { - CHIP_EXTIOI_ENABLE.extioi_en0.set(0xffff_ffff_ffff_ffff); - CHIP_EXTIOI_ENABLE.extioi_en1.set(0xffff_ffff_ffff_ffff); - CHIP_EXTIOI_ENABLE.extioi_en2.set(0xffff_ffff_ffff_ffff); - CHIP_EXTIOI_ENABLE.extioi_en3.set(0xffff_ffff_ffff_ffff); + for node in 0..eio_num_nodes() { + let regs = extioi_enable_regs(node); + regs.extioi_en0.set(u64::MAX); + regs.extioi_en1.set(u64::MAX); + regs.extioi_en2.set(u64::MAX); + regs.extioi_en3.set(u64::MAX); + } #[cfg(extioi_debug)] { // dump ht int vector and enable @@ -699,155 +765,128 @@ pub fn extioi_int_enable_all() { // rcore refenrence // https://github.com/Godones/rCoreloongArch/blob/master/kernel/src/loongarch/extioi.rs pub fn extioi_int_route_pin_all() { - csr_disable_new_codec(); // use legacy vector codec - let mask = 0b0000_0001u8; // INT1 - CHIP_EXTIOI_ROUTE.extioi_map0.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map1.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map2.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map3.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map4.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map5.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map6.set(mask); - CHIP_EXTIOI_ROUTE.extioi_map7.set(mask); + csr_disable_new_codec(); + // BIT(0) => IP0/INT0 + let mask = 0b0000_0001u8; + for node in 0..eio_num_nodes() { + let route = extioi_route_pin_regs(node); + route.extioi_map0.set(mask); + route.extioi_map1.set(mask); + route.extioi_map2.set(mask); + route.extioi_map3.set(mask); + route.extioi_map4.set(mask); + route.extioi_map5.set(mask); + route.extioi_map6.set(mask); + route.extioi_map7.set(mask); + } } -pub fn extioi_int_route_core_all() { - // first disable all extioi bounce - CHIP_EXTIOI_BOUNCE.extioi_bounce0.set(0); - CHIP_EXTIOI_BOUNCE.extioi_bounce1.set(0); - CHIP_EXTIOI_BOUNCE.extioi_bounce2.set(0); - CHIP_EXTIOI_BOUNCE.extioi_bounce3.set(0); - // write CHIP_EXTIOI_NODE_TYPE_BASE mmio (each with 2 bytes) - unsafe { - // set to 16'b0000_0000_0000_0001 - // which means only trigger node0 - core::ptr::write_volatile(CHIP_EXTIOI_NODE_TYPE_BASE as *mut u16, 0x0001); - } - // from CHIP_EXTIOI_ROUTE_CORE_BASE tp CHIP_EXTIOI_ROUTE_CORE_BASE + 0xff - // for each MMIO byte, set to cput core 0, data = 8'b0000_0001 - // which is [EXT_IOI_node_type0][CPU0 MASK] - let mask = 0b0000_0001u8; - for i in 0..256 { - let addr = CHIP_EXTIOI_ROUTE_CORE_BASE + i; +/// Program EXTIOI nodemap (0x14a0, 8 x u32) like Linux eiointc: +/// nodetype[k] gets bit k set, so route byte [7:4]=k selects destination node k. +fn extioi_init_nodemap(node_mmio_base: usize) { + // 256 vectors / 32 = 8 words; each word packs two u16 nodetype entries + for i in 0..8 { + let data = ((1u32 << (i * 2 + 1)) << 16) | (1u32 << (i * 2)); unsafe { - core::ptr::write_volatile(addr as *mut u8, mask); + write_volatile( + (node_mmio_base + 0x14a0 + i * 4) as *mut u32, + data, + ); } } } +pub fn extioi_int_route_core_all() { + for node in 0..eio_num_nodes() { + let base = eio_node_mmio_base(node); + let bounce = extioi_bounce_regs(node); + bounce.extioi_bounce0.set(0); + bounce.extioi_bounce1.set(0); + bounce.extioi_bounce2.set(0); + bounce.extioi_bounce3.set(0); + + extioi_init_nodemap(base); + + // [7:4]=nodetype index (= node id after nodemap init), [3:0]=local CPU bitmap + // Keep the initial destination on root CPU0. + let mask = 0b0000_0001u8; + for i in 0..256 { + let addr = base + 0x1c00 + i; + unsafe { + write_volatile(addr as *mut u8, mask); + } + } + } +} + +fn read_extioi_status_words(status: &ChipExtioiStatusRegs) -> (u64, u64, u64, u64) { + ( + status.extioi_sr0.get(), + status.extioi_sr1.get(), + status.extioi_sr2.get(), + status.extioi_sr3.get(), + ) +} + +/// Write-1-to-clear all pending bits (avoids RMW race of read-then-write). +fn clear_extioi_status_words(status: &ChipExtioiStatusRegs) { + const ALL: u64 = !0; + status.extioi_sr0.set(ALL); + status.extioi_sr1.set(ALL); + status.extioi_sr2.set(ALL); + status.extioi_sr3.set(ALL); +} + pub fn get_extioi_sr() -> String { let mut sr = String::new(); - // in one line, compact style - // core0: u64,u64,u64,u64; core1: u64,u64,u64,u64; core2: u64,u64,u64,u64; core3: u64,u64,u64,u64; - // so we need to read 4 * 4 = 16 u64 - for core_id in 0..4 { - let (sr0, sr1, sr2, sr3) = match core_id { - 0 => ( - CHIP_EXTIOI_CORE0_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr3.get(), - ), - 1 => ( - CHIP_EXTIOI_CORE1_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr3.get(), - ), - 2 => ( - CHIP_EXTIOI_CORE2_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr3.get(), - ), - 3 => ( - CHIP_EXTIOI_CORE3_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr3.get(), - ), - _ => panic!("get_extioi_sr: invalid core id: {}", core_id), - }; + for node in 0..eio_num_nodes() { + let (sr0, sr1, sr2, sr3) = read_extioi_status_words(&extioi_status_regs(node)); sr.push_str( format!( - "core{}: {:#x},{:#x},{:#x},{:#x}; ", - core_id, sr0, sr1, sr2, sr3 + "node{}-global: {:#x},{:#x},{:#x},{:#x}; ", + node, sr0, sr1, sr2, sr3 ) .as_str(), ); + for local in 0..CORES_PER_EIO_NODE { + let cpu = node * CORES_PER_EIO_NODE + local; + if cpu >= BOARD_NCPUS { + break; + } + let (c0, c1, c2, c3) = read_extioi_status_words(&extioi_core_status_regs(cpu)); + sr.push_str( + format!( + "cpu{}(n{}l{}): {:#x},{:#x},{:#x},{:#x}; ", + cpu, node, local, c0, c1, c2, c3 + ) + .as_str(), + ); + } } sr } +/// Clear only this CPU's pending vectors; used when resetting one zone. +pub fn clear_extioi_sr_for_cpu(cpu: usize) { + assert!(cpu < BOARD_NCPUS); + clear_extioi_status_words(&extioi_core_status_regs(cpu)); +} + pub fn clear_extioi_sr() { - warn!( - "clear_extioi_sr: clearing extioi SR regs, before: {}", - get_extioi_sr() - ); - // step one, for each sr reg, we read it and find any pending bit - for core_id in 0..4 { - let (sr0, sr1, sr2, sr3) = match core_id { - 0 => ( - CHIP_EXTIOI_CORE0_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE0_STATUS.extioi_sr3.get(), - ), - 1 => ( - CHIP_EXTIOI_CORE1_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE1_STATUS.extioi_sr3.get(), - ), - 2 => ( - CHIP_EXTIOI_CORE2_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE2_STATUS.extioi_sr3.get(), - ), - 3 => ( - CHIP_EXTIOI_CORE3_STATUS.extioi_sr0.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr1.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr2.get(), - CHIP_EXTIOI_CORE3_STATUS.extioi_sr3.get(), - ), - _ => panic!("clear_extioi_sr: invalid core id: {}", core_id), - }; - // then we directly write them back to clear the status - match core_id { - 0 => { - CHIP_EXTIOI_CORE0_STATUS.extioi_sr0.set(sr0); - CHIP_EXTIOI_CORE0_STATUS.extioi_sr1.set(sr1); - CHIP_EXTIOI_CORE0_STATUS.extioi_sr2.set(sr2); - CHIP_EXTIOI_CORE0_STATUS.extioi_sr3.set(sr3); + for node in 0..eio_num_nodes() { + clear_extioi_status_words(&extioi_status_regs(node)); + for local in 0..CORES_PER_EIO_NODE { + let cpu = node * CORES_PER_EIO_NODE + local; + if cpu >= BOARD_NCPUS { + break; } - 1 => { - CHIP_EXTIOI_CORE1_STATUS.extioi_sr0.set(sr0); - CHIP_EXTIOI_CORE1_STATUS.extioi_sr1.set(sr1); - CHIP_EXTIOI_CORE1_STATUS.extioi_sr2.set(sr2); - CHIP_EXTIOI_CORE1_STATUS.extioi_sr3.set(sr3); - } - 2 => { - CHIP_EXTIOI_CORE2_STATUS.extioi_sr0.set(sr0); - CHIP_EXTIOI_CORE2_STATUS.extioi_sr1.set(sr1); - CHIP_EXTIOI_CORE2_STATUS.extioi_sr2.set(sr2); - CHIP_EXTIOI_CORE2_STATUS.extioi_sr3.set(sr3); - } - 3 => { - CHIP_EXTIOI_CORE3_STATUS.extioi_sr0.set(sr0); - CHIP_EXTIOI_CORE3_STATUS.extioi_sr1.set(sr1); - CHIP_EXTIOI_CORE3_STATUS.extioi_sr2.set(sr2); - CHIP_EXTIOI_CORE3_STATUS.extioi_sr3.set(sr3); - } - _ => panic!("clear_extioi_sr: invalid core id: {}", core_id), + clear_extioi_status_words(&extioi_core_status_regs(cpu)); } } - warn!( - "clear_extioi_sr: clearing extioi SR regs, after: {}", - get_extioi_sr() - ); + debug!("clear_extioi_sr: done, status={}", get_extioi_sr()); } + /******************************************** */ /* PCI STUFFS :) */ /******************************************** */ diff --git a/src/device/irqchip/ls7a2000/mod.rs b/src/device/irqchip/ls7a2000/mod.rs index dea50912d..15dfe2337 100644 --- a/src/device/irqchip/ls7a2000/mod.rs +++ b/src/device/irqchip/ls7a2000/mod.rs @@ -221,8 +221,10 @@ pub fn clear_injected_irq(_irq: usize) { impl Zone { pub fn arch_irqchip_reset(&self) { - // clear all SR regs - clear_extioi_sr(); + // Other zones may still be running and must retain their pending IRQs. + for cpu in self.cpu_set().iter() { + clear_extioi_sr_for_cpu(cpu); + } let extioi_sr = get_extioi_sr(); info!( "loongarch64: irqchip: arch_irqchip_reset: extioi_sr: {}", From 4b6755513aa0181201224542c446d2a2e273e29d Mon Sep 17 00:00:00 2001 From: stl Date: Wed, 30 Sep 2026 15:11:39 +0800 Subject: [PATCH 2/4] style(loongarch64): fix rustfmt in LS7A2000 irqchip --- src/device/irqchip/ls7a2000/chip.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/device/irqchip/ls7a2000/chip.rs b/src/device/irqchip/ls7a2000/chip.rs index 94d32d350..736f83351 100644 --- a/src/device/irqchip/ls7a2000/chip.rs +++ b/src/device/irqchip/ls7a2000/chip.rs @@ -788,10 +788,7 @@ fn extioi_init_nodemap(node_mmio_base: usize) { for i in 0..8 { let data = ((1u32 << (i * 2 + 1)) << 16) | (1u32 << (i * 2)); unsafe { - write_volatile( - (node_mmio_base + 0x14a0 + i * 4) as *mut u32, - data, - ); + write_volatile((node_mmio_base + 0x14a0 + i * 4) as *mut u32, data); } } } @@ -886,7 +883,6 @@ pub fn clear_extioi_sr() { debug!("clear_extioi_sr: done, status={}", get_extioi_sr()); } - /******************************************** */ /* PCI STUFFS :) */ /******************************************** */ From 9076e2280b4ae548f54cb2027a0ee662598e98b7 Mon Sep 17 00:00:00 2001 From: Stl_ <108327818+weifenjihe@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:30:00 +0800 Subject: [PATCH 3/4] Update platform/loongarch64/ls3a6000/board.rs Co-authored-by: lxh --- platform/loongarch64/ls3a6000/board.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/loongarch64/ls3a6000/board.rs b/platform/loongarch64/ls3a6000/board.rs index a65a12e02..d489a1aca 100644 --- a/platform/loongarch64/ls3a6000/board.rs +++ b/platform/loongarch64/ls3a6000/board.rs @@ -19,7 +19,7 @@ use crate::{arch::zone::HvArchZoneConfig, config::*, pci::vpci_dev::VpciDevType} pub const BOARD_NAME: &str = "ls3a6000"; -pub const BOARD_NCPUS: usize = 4; //supported max 8 cores +pub const BOARD_NCPUS: usize = 8; pub const ROOT_ZONE_DTB_ADDR: u64 = 0x10000f000; pub const ROOT_ZONE_KERNEL_ADDR: u64 = 0x200000; From ad8b0365b28d1999262ecf2113f9d2818937c9dc Mon Sep 17 00:00:00 2001 From: Stl_ <108327818+weifenjihe@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:30:26 +0800 Subject: [PATCH 4/4] Update platform/loongarch64/ls3a6000/linker.ld Co-authored-by: lxh --- platform/loongarch64/ls3a6000/linker.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/loongarch64/ls3a6000/linker.ld b/platform/loongarch64/ls3a6000/linker.ld index 9b65e9a14..92652ddf5 100644 --- a/platform/loongarch64/ls3a6000/linker.ld +++ b/platform/loongarch64/ls3a6000/linker.ld @@ -1,6 +1,6 @@ ENTRY(arch_entry) BASE_ADDRESS = 0x90000001f0000000; -CPU_NUM = 4; /* supported max 8 cores */ +CPU_NUM = 8; SECTIONS