0x3F9 #2
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 1m14s

This commit is contained in:
Masato Imai
2025-08-25 12:02:53 +00:00
parent 294e4f719d
commit a355e91c6e
2 changed files with 19 additions and 17 deletions

View File

@@ -23,7 +23,7 @@ pub fn vmm_interrupt_subscriber(vcpu_ptr: *mut core::ffi::c_void, context: &Inte
if 0x20 <= context.vector && context.vector <= 0x20 + 16 { if 0x20 <= context.vector && context.vector <= 0x20 + 16 {
let irq = context.vector - 0x20; let irq = context.vector - 0x20;
vcpu.pending_irq |= 1 << irq; vcpu.pic.pending_irq |= 1 << irq;
} }
} }
@@ -61,6 +61,7 @@ pub struct Pic {
pub primary_read_sel: ReadSel, pub primary_read_sel: ReadSel,
pub secondary_read_sel: ReadSel, pub secondary_read_sel: ReadSel,
pub serial: Serial, pub serial: Serial,
pub pending_irq: u16,
} }
impl Pic { impl Pic {
@@ -79,6 +80,7 @@ impl Pic {
primary_read_sel: ReadSel::Irr, primary_read_sel: ReadSel::Irr,
secondary_read_sel: ReadSel::Irr, secondary_read_sel: ReadSel::Irr,
serial: Serial::default(), serial: Serial::default(),
pending_irq: 0,
} }
} }
@@ -94,11 +96,8 @@ impl Pic {
} }
} }
pub fn inject_external_interrupt( pub fn inject_external_interrupt(&mut self) -> Result<bool, &'static str> {
&mut self, let pending = self.pending_irq;
pending_irq: &mut u16,
) -> Result<bool, &'static str> {
let pending = *pending_irq;
if pending == 0 { if pending == 0 {
return Ok(false); return Ok(false);
@@ -160,7 +159,7 @@ impl Pic {
u32::from(interrupt_info) as u64, u32::from(interrupt_info) as u64,
)?; )?;
*pending_irq &= !irq_bit; self.pending_irq &= !irq_bit;
return Ok(true); return Ok(true);
} }
@@ -234,9 +233,17 @@ impl Pic {
} }
fn handle_serial_out(&mut self, regs: &mut GuestRegisters, qual: QualIo) { fn handle_serial_out(&mut self, regs: &mut GuestRegisters, qual: QualIo) {
if matches!(qual.port(), 0x3F9 | 0x3FC) {
info!("Serial out: port={:#x}, value={:#x}", qual.port(), regs.rax);
}
match qual.port() { match qual.port() {
0x3F8 => serial::write_byte(regs.rax as u8), 0x3F8 => serial::write_byte(regs.rax as u8),
0x3F9 => self.serial.ier = regs.rax as u8, 0x3F9 => {
self.serial.ier = regs.rax as u8;
if regs.rax & 0x1 != 0 {
self.pending_irq |= 4;
}
}
0x3FA => {} 0x3FA => {}
0x3FB => {} 0x3FB => {}
0x3FC => self.serial.mcr = regs.rax as u8, 0x3FC => self.serial.mcr = regs.rax as u8,
@@ -370,7 +377,7 @@ impl IOBitmap {
} }
self.set_io_ports(0x0040..=0x0047); self.set_io_ports(0x0040..=0x0047);
self.set_io_ports(0x02F8..=0x03EF); //self.set_io_ports(0x02F8..=0x03EF);
vmwrite(vmcs::control::IO_BITMAP_A_ADDR_FULL, bitmap_a_addr as u64)?; vmwrite(vmcs::control::IO_BITMAP_A_ADDR_FULL, bitmap_a_addr as u64)?;
vmwrite(vmcs::control::IO_BITMAP_B_ADDR_FULL, bitmap_b_addr as u64)?; vmwrite(vmcs::control::IO_BITMAP_B_ADDR_FULL, bitmap_b_addr as u64)?;

View File

@@ -52,9 +52,8 @@ pub struct IntelVCpu {
pub host_msr: ShadowMsr, pub host_msr: ShadowMsr,
pub guest_msr: ShadowMsr, pub guest_msr: ShadowMsr,
pub ia32e_enabled: bool, pub ia32e_enabled: bool,
pic: super::io::Pic, pub pic: super::io::Pic,
io_bitmap: IOBitmap, io_bitmap: IOBitmap,
pub pending_irq: u16,
pub host_xcr0: u64, pub host_xcr0: u64,
pub guest_xcr0: XCR0, pub guest_xcr0: XCR0,
} }
@@ -87,10 +86,7 @@ impl IntelVCpu {
match exit_reason { match exit_reason {
VmxExitReason::HLT => { VmxExitReason::HLT => {
let injected = self let injected = self.pic.inject_external_interrupt().unwrap_or(false);
.pic
.inject_external_interrupt(&mut self.pending_irq)
.unwrap_or(false);
if !injected { if !injected {
unsafe { unsafe {
@@ -151,7 +147,7 @@ impl IntelVCpu {
asm!("cli"); asm!("cli");
} }
self.pic.inject_external_interrupt(&mut self.pending_irq)?; self.pic.inject_external_interrupt()?;
} }
VmxExitReason::EPT_VIOLATION => { VmxExitReason::EPT_VIOLATION => {
let guest_address = vmread(vmcs::ro::GUEST_PHYSICAL_ADDR_FULL)?; let guest_address = vmread(vmcs::ro::GUEST_PHYSICAL_ADDR_FULL)?;
@@ -916,7 +912,6 @@ impl VCpu for IntelVCpu {
ia32e_enabled: false, ia32e_enabled: false,
pic: super::io::Pic::new(), pic: super::io::Pic::new(),
io_bitmap: IOBitmap::new(frame_allocator), io_bitmap: IOBitmap::new(frame_allocator),
pending_irq: 0,
host_xcr0: 0, host_xcr0: 0,
guest_xcr0: XCR0::new(), guest_xcr0: XCR0::new(),
}) })