0x3F9 #2
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 1m14s
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 1m14s
This commit is contained in:
@@ -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)?;
|
||||||
|
|||||||
@@ -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(),
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user