git: 060ecf296664 - main - x86/local_apic.c: Factor out version read and max LVT slot computation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 10 Jul 2026 15:30:38 UTC
The branch main has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=060ecf296664fd150328ac6dcdc24764a427bc3a
commit 060ecf296664fd150328ac6dcdc24764a427bc3a
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-07-08 12:59:28 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-07-10 15:29:44 +0000
x86/local_apic.c: Factor out version read and max LVT slot computation
This makes the code slightly more compact and easier to read.
No functional change intended.
Reviewed by: bnovkov
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58110
---
sys/x86/x86/local_apic.c | 72 ++++++++++++++++++++++++------------------------
1 file changed, 36 insertions(+), 36 deletions(-)
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 9e1c1d70aea7..73ddf9115e4c 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -333,16 +333,6 @@ SYSCTL_INT(_hw_apic, OID_AUTO, ds_idle_timeout, CTLFLAG_RWTUN,
static void lapic_calibrate_initcount(struct lapic *la);
-/*
- * Calculate the max index of the present LVT entry from the value of
- * the LAPIC version register.
- */
-static int
-lapic_maxlvt(uint32_t version)
-{
- return ((version & APIC_VER_MAXLVT) >> MAXLVTSHIFT);
-}
-
/*
* Use __nosanitizethread to exempt the LAPIC I/O accessors from KCSan
* instrumentation. Otherwise, if x2APIC is not available, use of the global
@@ -390,6 +380,28 @@ lapic_write32_nofence(enum LAPIC_REGISTERS reg, uint32_t val)
}
}
+static inline uint32_t __pure2
+lapic_version(void)
+{
+ return (lapic_read32(LAPIC_VERSION));
+}
+
+/*
+ * Calculate the max index of the present LVT entry from the value of
+ * the LAPIC version register.
+ */
+static inline int __pure2
+lapic_version_maxlvt(uint32_t version)
+{
+ return ((version & APIC_VER_MAXLVT) >> MAXLVTSHIFT);
+}
+
+static inline int __pure2
+lapic_maxlvt(void)
+{
+ return (lapic_version_maxlvt(lapic_version()));
+}
+
#ifdef SMP
static uint64_t
lapic_read_icr_lo(void)
@@ -648,7 +660,7 @@ lapic_init(vm_paddr_t addr)
* It seems that at least some KVM versions report
* EOI_SUPPRESSION bit, but auto-EOI does not work.
*/
- ver = lapic_read32(LAPIC_VERSION);
+ ver = lapic_version();
if ((ver & APIC_VER_EOI_SUPPRESSION) != 0) {
lapic_eoi_suppression = 1;
if (vm_guest == VM_GUEST_KVM) {
@@ -755,7 +767,7 @@ amd_read_ext_features(void)
if (cpu_vendor_id != CPU_VENDOR_AMD &&
cpu_vendor_id != CPU_VENDOR_HYGON)
return (0);
- version = lapic_read32(LAPIC_VERSION);
+ version = lapic_version();
if ((version & APIC_VER_AMD_EXT_SPACE) != 0)
return (lapic_read32(LAPIC_EXT_FEATURES));
else
@@ -780,14 +792,12 @@ amd_read_elvt_count(void)
void
lapic_dump(const char* str)
{
- uint32_t version;
- uint32_t maxlvt;
+ const uint32_t version = lapic_version();
+ const int maxlvt = lapic_version_maxlvt(version);
uint32_t extf;
int elvt_count;
int i;
- version = lapic_read32(LAPIC_VERSION);
- maxlvt = lapic_maxlvt(version);
printf("cpu%d %s:\n", PCPU_GET(cpuid), str);
printf(" ID: 0x%08x VER: 0x%08x LDR: 0x%08x DFR: 0x%08x",
lapic_read32(LAPIC_ID), version,
@@ -844,10 +854,8 @@ static void
lapic_early_mask_vecs(void)
{
int elvt_count, lvts_count, i;
- uint32_t version;
- version = lapic_read32(LAPIC_VERSION);
- lvts_count = min(nitems(lvts), lapic_maxlvt(version) + 1);
+ lvts_count = min(nitems(lvts), lapic_maxlvt() + 1);
for (i = 0; i < lvts_count; i++)
lapic_early_mask_vec(&lvts[i]);
@@ -859,9 +867,9 @@ lapic_early_mask_vecs(void)
void
lapic_setup(int boot)
{
+ const uint32_t version = lapic_version();
+ const uint32_t maxlvt = lapic_version_maxlvt(version);
struct lapic *la;
- uint32_t version;
- uint32_t maxlvt;
register_t saveintr;
int elvt_count;
int i;
@@ -870,8 +878,6 @@ lapic_setup(int boot)
la = &lapics[lapic_id()];
KASSERT(la->la_present, ("missing APIC structure"));
- version = lapic_read32(LAPIC_VERSION);
- maxlvt = lapic_maxlvt(version);
/* Initialize the TPR to allow all interrupts. */
lapic_set_tpr(0);
@@ -1032,8 +1038,6 @@ lapic_calibrate_timer(void)
int
lapic_enable_pcint(void)
{
- u_int32_t maxlvt;
-
#ifdef DEV_ATPIC
/* Fail if the local APIC is not present. */
if (!x2apic_mode && lapic_map == NULL)
@@ -1041,8 +1045,7 @@ lapic_enable_pcint(void)
#endif
/* Fail if the PMC LVT is not present. */
- maxlvt = lapic_maxlvt(lapic_read32(LAPIC_VERSION));
- if (maxlvt < APIC_LVT_PMC)
+ if (lapic_maxlvt() < APIC_LVT_PMC)
return (0);
if (refcount_acquire(&pcint_refcnt) > 0)
return (1);
@@ -1059,8 +1062,6 @@ lapic_enable_pcint(void)
void
lapic_disable_pcint(void)
{
- u_int32_t maxlvt;
-
#ifdef DEV_ATPIC
/* Fail if the local APIC is not present. */
if (!x2apic_mode && lapic_map == NULL)
@@ -1068,8 +1069,7 @@ lapic_disable_pcint(void)
#endif
/* Fail if the PMC LVT is not present. */
- maxlvt = lapic_maxlvt(lapic_read32(LAPIC_VERSION));
- if (maxlvt < APIC_LVT_PMC)
+ if (lapic_maxlvt() < APIC_LVT_PMC)
return;
if (!refcount_release(&pcint_refcnt))
return;
@@ -1987,19 +1987,19 @@ DB_SHOW_COMMAND_FLAGS(lapic, db_show_lapic, DB_CMD_MEMSAFE)
{
const struct lvt *l;
int elvt_count, lvts_count, i;
- uint32_t v, vr;
+ const uint32_t v = lapic_version();
+ const int maxlvt = lapic_version_maxlvt(v);
+ const uint32_t vr = lapic_read32(LAPIC_SVR);
db_printf("lapic ID = %d\n", lapic_id());
- v = lapic_read32(LAPIC_VERSION);
db_printf("version = %d.%d (%#x) \n", (v & APIC_VER_VERSION) >> 4,
v & 0xf, v);
- db_printf("max LVT = %d\n", lapic_maxlvt(v));
- vr = lapic_read32(LAPIC_SVR);
+ db_printf("max LVT = %d\n", maxlvt);
db_printf("SVR = %02x (%s)\n", vr & APIC_SVR_VECTOR,
vr & APIC_SVR_ENABLE ? "enabled" : "disabled");
db_printf("TPR = %02x\n", lapic_read32(LAPIC_TPR));
- lvts_count = min(nitems(lvts), lapic_maxlvt(v) + 1);
+ lvts_count = min(nitems(lvts), maxlvt + 1);
for (i = 0; i < lvts_count; i++) {
l = &lvts[i];
db_printf("LVT%d (reg %#x %-5s) = %#010x\n", i, l->lvt_reg,