Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151155402
D9612.id25216.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D9612.id25216.diff
View Options
Index: sys/x86/include/apicreg.h
===================================================================
--- sys/x86/include/apicreg.h
+++ sys/x86/include/apicreg.h
@@ -241,6 +241,18 @@
LAPIC_CCR_TIMER = 0x39,
LAPIC_DCR_TIMER = 0x3e,
LAPIC_SELF_IPI = 0x3f, /* Only in x2APIC */
+ LAPIC_EXT_FEATURES = 0x40, /* AMD */
+ LAPIC_EXT_CTRL = 0x41, /* AMD */
+ LAPIC_EXT_SEOI = 0x42, /* AMD */
+ LAPIC_EXT_IER0 = 0x48, /* AMD */
+ LAPIC_EXT_IER1 = 0x49, /* AMD */
+ LAPIC_EXT_IER2 = 0x4a, /* AMD */
+ LAPIC_EXT_IER3 = 0x4b, /* AMD */
+ LAPIC_EXT_IER4 = 0x4c, /* AMD */
+ LAPIC_EXT_IER5 = 0x4d, /* AMD */
+ LAPIC_EXT_IER6 = 0x4e, /* AMD */
+ LAPIC_EXT_IER7 = 0x4f, /* AMD */
+ LAPIC_EXT_LVT = 0x50, /* AMD */
};
/*
@@ -295,6 +307,7 @@
#define APIC_VER_MAXLVT 0x00ff0000
#define MAXLVTSHIFT 16
#define APIC_VER_EOI_SUPPRESSION 0x01000000
+#define APIC_VER_AMD_EXT_SPACE 0x80000000
/* fields in LDR */
#define APIC_LDR_RESERVED 0x00ffffff
@@ -418,6 +431,13 @@
#define APIC_TDCR_128 0x0a
#define APIC_TDCR_1 0x0b
+/* Constants related to AMD Extended APIC Features Register */
+#define APIC_EXTF_ELVT_MASK 0x00ff0000
+#define APIC_EXTF_ELVT_SHIFT 16
+#define APIC_EXTF_EXTID_CAP 0x00000004
+#define APIC_EXTF_SEIO_CAP 0x00000002
+#define APIC_EXTF_IER_CAP 0x00000001
+
/* LVT table indices */
#define APIC_LVT_LINT0 0
#define APIC_LVT_LINT1 1
@@ -428,6 +448,13 @@
#define APIC_LVT_CMCI 6
#define APIC_LVT_MAX APIC_LVT_CMCI
+/* Extended LVT constants, seem to be assigned by fiat */
+#define APIC_ELVT_IBS 0 /* Instruction based sampling */
+#define APIC_ELVT_MCA 1 /* MCE thresholding */
+#define APIC_ELVT_DEI 2 /* Deferred error interrupt */
+#define APIC_ELVT_3 3 /* Free */
+#define APIC_ELVT_MAX APIC_ELVT_3
+
/******************************************************************************
* I/O APIC defines
*/
Index: sys/x86/include/apicvar.h
===================================================================
--- sys/x86/include/apicvar.h
+++ sys/x86/include/apicvar.h
@@ -232,6 +232,9 @@
/* CMC */
void (*enable_cmc)(void);
+ /* AMD ELVT */
+ int (*enable_mca_elvt)(void);
+
/* IPI */
void (*ipi_raw)(register_t, u_int);
void (*ipi_vectored)(u_int, int);
@@ -396,6 +399,13 @@
apic_ops.enable_cmc();
}
+static inline int
+lapic_enable_mca_elvt(void)
+{
+
+ return (apic_ops.enable_mca_elvt());
+}
+
static inline void
lapic_ipi_raw(register_t icrlo, u_int dest)
{
Index: sys/x86/x86/local_apic.c
===================================================================
--- sys/x86/x86/local_apic.c
+++ sys/x86/x86/local_apic.c
@@ -319,6 +319,7 @@
static void native_lapic_disable_pmc(void);
static void native_lapic_reenable_pmc(void);
static void native_lapic_enable_cmc(void);
+static int native_lapic_enable_mca_elvt(void);
static int native_lapic_set_lvt_mask(u_int apic_id, u_int lvt,
u_char masked);
static int native_lapic_set_lvt_mode(u_int apic_id, u_int lvt,
@@ -357,6 +358,7 @@
.disable_pmc = native_lapic_disable_pmc,
.reenable_pmc = native_lapic_reenable_pmc,
.enable_cmc = native_lapic_enable_cmc,
+ .enable_mca_elvt = native_lapic_enable_mca_elvt,
#ifdef SMP
.ipi_raw = native_lapic_ipi_raw,
.ipi_vectored = native_lapic_ipi_vectored,
@@ -608,12 +610,14 @@
static void
native_lapic_dump(const char* str)
{
+ uint32_t version;
uint32_t maxlvt;
- maxlvt = (lapic_read32(LAPIC_VERSION) & APIC_VER_MAXLVT) >> MAXLVTSHIFT;
+ version = lapic_read32(LAPIC_VERSION);
+ maxlvt = (version & APIC_VER_MAXLVT) >> MAXLVTSHIFT;
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), lapic_read32(LAPIC_VERSION),
+ lapic_read32(LAPIC_ID), version,
lapic_read32(LAPIC_LDR), x2apic_mode ? 0 : lapic_read32(LAPIC_DFR));
if ((cpu_feature2 & CPUID2_X2APIC) != 0)
printf(" x2APIC: %d", x2apic_mode);
@@ -628,6 +632,20 @@
printf("\n");
if (maxlvt >= APIC_LVT_CMCI)
printf(" cmci: 0x%08x\n", lapic_read32(LAPIC_LVT_CMCI));
+ if (cpu_vendor_id == CPU_VENDOR_AMD &&
+ (version & APIC_VER_AMD_EXT_SPACE) != 0) {
+ uint32_t extf;
+ int elvt;
+ int i;
+
+ extf = lapic_read32(LAPIC_EXT_FEATURES);
+ printf(" AMD ext features: 0x%08x\n", extf);
+ elvt = (extf & APIC_EXTF_ELVT_MASK) >> APIC_EXTF_ELVT_SHIFT;
+ for (i = 0; i < elvt; i++) {
+ printf(" AMD elvt%d: 0x%08x\n", i,
+ lapic_read32(LAPIC_EXT_LVT + i));
+ }
+ }
}
static void
@@ -1311,6 +1329,38 @@
printf("lapic%u: CMCI unmasked\n", apic_id);
}
+static int
+native_lapic_enable_mca_elvt(void)
+{
+ uint32_t elvt;
+ uint32_t value;
+
+#ifdef DEV_ATPIC
+ if (!x2apic_mode && lapic_map == NULL)
+ return (-1);
+#endif
+
+ if (cpu_vendor_id != CPU_VENDOR_AMD ||
+ (lapic_read32(LAPIC_VERSION) & APIC_VER_AMD_EXT_SPACE) == 0) {
+ return (-1);
+ }
+ elvt = (lapic_read32(LAPIC_EXT_FEATURES) & APIC_EXTF_ELVT_MASK) >>
+ APIC_EXTF_ELVT_SHIFT;
+ if (elvt <= APIC_ELVT_MCA)
+ return (-1);
+
+ value = lapic_read32(LAPIC_EXT_LVT + APIC_ELVT_MCA);
+ if ((value & APIC_LVT_M) == 0) {
+ printf("AMD Extended LVT0 is already active\n");
+ return (-1);
+ }
+ value &= ~(APIC_LVT_M | APIC_LVT_DM | APIC_LVT_VECTOR);
+ value |= APIC_LVT_DM_FIXED;
+ value |= APIC_CMC_INT;
+ lapic_write32(LAPIC_EXT_LVT + APIC_ELVT_MCA, value);
+ return (APIC_ELVT_MCA);
+}
+
void
lapic_handle_error(void)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 11:42 AM (9 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31028480
Default Alt Text
D9612.id25216.diff (5 KB)
Attached To
Mode
D9612: Local APIC: add support for extended LVT entries found in AMD processors
Attached
Detach File
Event Timeline
Log In to Comment