From f4f41cffc4bb71b5b14177f3f361228479415d9f Mon Sep 17 00:00:00 2001 From: Shwartsman Date: Tue, 21 Nov 2023 20:07:07 +0200 Subject: [PATCH] fix code duplication and optimize code --- bochs/cpu/apic.h | 12 +++++++----- bochs/cpu/cpu.h | 1 + bochs/cpu/vapic.cc | 45 ++++++++++++++++++++------------------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/bochs/cpu/apic.h b/bochs/cpu/apic.h index 88174e4b8..bb84edb77 100644 --- a/bochs/cpu/apic.h +++ b/bochs/cpu/apic.h @@ -218,14 +218,16 @@ class BOCHSAPI bx_local_apic_c : public logfunctions BX_CPU_C *cpu; - bool get_vector(Bit32u *reg, unsigned vector); - void set_vector(Bit32u *reg, unsigned vector); - void clear_vector(Bit32u *reg, unsigned vector); - public: - bool INTR; bx_local_apic_c(BX_CPU_C *cpu, unsigned id); ~bx_local_apic_c() { } + + static bool get_vector(Bit32u *reg, unsigned vector); + static void set_vector(Bit32u *reg, unsigned vector); + static void clear_vector(Bit32u *reg, unsigned vector); + + bool INTR; + void reset(unsigned type); bx_phy_address get_base(void) const { return base_addr; } void set_base(bx_phy_address newbase); diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 3354e999d..ed5de0d0a 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -4850,6 +4850,7 @@ public: // for now... BX_SMF void VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void *data); BX_SMF Bit32u VMX_Read_Virtual_APIC(unsigned offset); BX_SMF void VMX_Write_Virtual_APIC(unsigned offset, Bit32u val32); + BX_SMF void VMX_Write_Virtual_X2APIC(unsigned offset, Bit64u val64); BX_SMF void VMX_TPR_Virtualization(void); BX_SMF bool Virtualize_X2APIC_Write(unsigned msr, Bit64u val_64); BX_SMF void VMX_Virtual_Apic_Access_Trap(void); diff --git a/bochs/cpu/vapic.cc b/bochs/cpu/vapic.cc index 8137a5ba4..71462e397 100644 --- a/bochs/cpu/vapic.cc +++ b/bochs/cpu/vapic.cc @@ -81,6 +81,14 @@ void BX_CPU_C::VMX_Write_Virtual_APIC(unsigned offset, Bit32u val32) BX_NOTIFY_PHY_MEMORY_ACCESS(pAddr, 4, MEMTYPE(resolve_memtype(pAddr)), BX_WRITE, BX_VMX_VAPIC_ACCESS, (Bit8u*)(&val32)); } +void BX_CPU_C::VMX_Write_Virtual_X2APIC(unsigned offset, Bit64u val64) +{ + bx_phy_address pAddr = BX_CPU_THIS_PTR vmcs.virtual_apic_page_addr + offset; + // must avoid recursive call to the function when VMX APIC access page = VMX Virtual Apic Page + BX_MEM(0)->writePhysicalPage(BX_CPU_THIS, pAddr, 8, (Bit8u*)(&val64)); + BX_NOTIFY_PHY_MEMORY_ACCESS(pAddr, 8, MEMTYPE(resolve_memtype(pAddr)), BX_WRITE, BX_VMX_VAPIC_ACCESS, (Bit8u*)(&val64)); +} + bx_phy_address BX_CPU_C::VMX_Virtual_Apic_Read(bx_phy_address paddr, unsigned len, void *data) { BX_ASSERT(SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES)); @@ -238,42 +246,31 @@ void BX_CPU_C::VMX_Virtual_Apic_Write(bx_phy_address paddr, unsigned len, void * #if BX_SUPPORT_VMX >= 2 -BX_CPP_INLINE bool vapic_read_vector(Bit32u *arr, Bit8u vector) -{ - unsigned apic_reg = vector / 32; - - return arr[apic_reg] & (1 << (vector & 0x1f)); -} - BX_CPP_INLINE void BX_CPU_C::vapic_set_vector(unsigned arrbase, Bit8u vector) { unsigned reg = vector / 32; - Bit32u regval = VMX_Read_Virtual_APIC(arrbase + 0x10*reg); + Bit32u regval = VMX_Read_Virtual_APIC(arrbase + 16*reg); regval |= (1 << (vector & 0x1f)); - VMX_Write_Virtual_APIC(arrbase + 0x10*reg, regval); + VMX_Write_Virtual_APIC(arrbase + 16*reg, regval); } +#include "scalar_arith.h" // for lzcntd + BX_CPP_INLINE Bit8u BX_CPU_C::vapic_clear_and_find_highest_priority_int(unsigned arrbase, Bit8u vector) { Bit32u arr[8]; int n; for (n=0;n<8;n++) - arr[n] = VMX_Read_Virtual_APIC(arrbase + 0x10*n); + arr[n] = VMX_Read_Virtual_APIC(arrbase + 16*n); + bx_local_apic_c::clear_vector(arr, vector); unsigned reg = vector / 32; - arr[reg] &= ~(1 << (vector & 0x1f)); - - VMX_Write_Virtual_APIC(arrbase + 0x10*reg, arr[reg]); + VMX_Write_Virtual_APIC(arrbase + 16*reg, arr[reg]); for (n = 7; n >= 0; n--) { if (! arr[n]) continue; - - for (int bit = 31; bit >= 0; bit--) { - if (arr[n] & (1<eoi_exit_bitmap, vector)) { + bool bit_high = bx_local_apic_c::get_vector(vm->eoi_exit_bitmap, vector); + if (bit_high) { VMexit(VMX_VMEXIT_VIRTUALIZED_EOI, vector); // trap-like VMEXIT } else { @@ -465,8 +463,7 @@ bool BX_CPU_C::Virtualize_X2APIC_Write(unsigned msr, Bit64u val_64) if ((val_64 >> 8) != 0) exception(BX_GP_EXCEPTION, 0); - VMX_Write_Virtual_APIC(BX_LAPIC_TPR, val_64 & 0xff); - VMX_Write_Virtual_APIC(BX_LAPIC_TPR + 4, 0); + VMX_Write_Virtual_X2APIC(BX_LAPIC_TPR, val_64 & 0xff); VMX_TPR_Virtualization(); return true; @@ -480,7 +477,6 @@ bool BX_CPU_C::Virtualize_X2APIC_Write(unsigned msr, Bit64u val_64) exception(BX_GP_EXCEPTION, 0); VMX_EOI_Virtualization(); - return true; } @@ -491,8 +487,7 @@ bool BX_CPU_C::Virtualize_X2APIC_Write(unsigned msr, Bit64u val_64) Bit8u vector = val_64 & 0xff; if (vector < 16) { - VMX_Write_Virtual_APIC(BX_LAPIC_SELF_IPI, vector); - VMX_Write_Virtual_APIC(BX_LAPIC_SELF_IPI + 4, 0); + VMX_Write_Virtual_X2APIC(BX_LAPIC_SELF_IPI, vector); VMexit(VMX_VMEXIT_APIC_WRITE, BX_LAPIC_SELF_IPI); // trap-like vmexit } else {