Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107070196
D44454.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D44454.diff
View Options
Index: sys/amd64/amd64/apic_vector.S
===================================================================
--- sys/amd64/amd64/apic_vector.S
+++ sys/amd64/amd64/apic_vector.S
@@ -150,6 +150,15 @@
KMSAN_LEAVE
jmp doreti
+/*
+ * Local APIC thermal interrupt handler.
+ */
+ INTR_HANDLER thermalint
+ KMSAN_ENTER
+ call lapic_handle_thermal
+ KMSAN_LEAVE
+ jmp doreti
+
#ifdef XENHVM
/*
* Xen event channel upcall interrupt handler.
Index: sys/x86/include/apicvar.h
===================================================================
--- sys/x86/include/apicvar.h
+++ sys/x86/include/apicvar.h
@@ -178,12 +178,12 @@
inthand_t
IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(apic_isr6),
- IDTVEC(apic_isr7), IDTVEC(cmcint), IDTVEC(errorint),
- IDTVEC(spuriousint), IDTVEC(timerint),
+ IDTVEC(apic_isr7), IDTVEC(cmcint), IDTVEC(thermalint),
+ IDTVEC(errorint), IDTVEC(spuriousint), IDTVEC(timerint),
IDTVEC(apic_isr1_pti), IDTVEC(apic_isr2_pti), IDTVEC(apic_isr3_pti),
IDTVEC(apic_isr4_pti), IDTVEC(apic_isr5_pti), IDTVEC(apic_isr6_pti),
- IDTVEC(apic_isr7_pti), IDTVEC(cmcint_pti), IDTVEC(errorint_pti),
- IDTVEC(spuriousint_pti), IDTVEC(timerint_pti);
+ IDTVEC(apic_isr7_pti), IDTVEC(cmcint_pti), IDTVEC(thermalint_pti),
+ IDTVEC(errorint_pti), IDTVEC(spuriousint_pti), IDTVEC(timerint_pti);
extern vm_paddr_t lapic_paddr;
extern int *apic_cpuids;
@@ -224,6 +224,8 @@
void apic_disable_vector(u_int apic_id, u_int vector);
void apic_free_vector(u_int apic_id, u_int vector, u_int irq);
void lapic_calibrate_timer(void);
+void lapic_enable_thermal(void (* thermfunc)(int, void *), void *value);
+void lapic_disable_thermal(void);
int lapic_enable_pmc(void);
void lapic_disable_pmc(void);
void lapic_reenable_pmc(void);
@@ -248,6 +250,7 @@
int lapic_set_lvt_triggermode(u_int apic_id, u_int lvt,
enum intr_trigger trigger);
void lapic_handle_cmc(void);
+void lapic_handle_thermal(void);
void lapic_handle_error(void);
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(struct trapframe *frame);
Index: sys/x86/x86/local_apic.c
===================================================================
--- sys/x86/x86/local_apic.c
+++ sys/x86/x86/local_apic.c
@@ -206,6 +206,8 @@
static int __read_mostly lapic_ds_idle_timeout = 1000000;
#endif
unsigned int max_apic_id;
+static void *lapic_thermal_function_value = NULL;
+static void (* lapic_handle_thermal_function)(int, void *) = NULL;
SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"APIC options");
@@ -470,7 +472,9 @@
setidt(APIC_ERROR_INT, pti ? IDTVEC(errorint_pti) : IDTVEC(errorint),
SDT_APIC, SEL_KPL, GSEL_APIC);
- /* XXX: Thermal interrupt */
+ /* Thermal interrupt */
+ setidt(APIC_THERMAL_INT, pti ? IDTVEC(thermalint_pti) : IDTVEC(thermalint),
+ SDT_APIC, SEL_KPL, GSEL_APIC);
/* Local APIC CMCI. */
setidt(APIC_CMC_INT, pti ? IDTVEC(cmcint_pti) : IDTVEC(cmcint),
@@ -768,7 +772,9 @@
lapic_read32(LAPIC_LVT_ERROR)));
lapic_write32(LAPIC_ESR, 0);
- /* XXX: Thermal LVT */
+ /* Thermal LVT */
+ lapic_write32(LAPIC_LVT_THERMAL, lvt_mode(la, APIC_LVT_THERMAL,
+ lapic_read32(LAPIC_LVT_THERMAL)));
/* Program the CMCI LVT entry if present. */
if (maxlvt >= APIC_LVT_CMCI) {
@@ -1477,6 +1483,71 @@
return (APIC_ELVT_MCA);
}
+void
+lapic_handle_thermal(void)
+{
+ if(lapic_handle_thermal_function != NULL)
+ lapic_handle_thermal_function(PCPU_GET(cpuid), lapic_thermal_function_value);
+
+ lapic_eoi();
+}
+
+static void
+lapic_update_thermal(void *nouse)
+{
+ struct lapic *la;
+
+ la = &lapics[lapic_id()];
+ lapic_write32(LAPIC_LVT_THERMAL, lvt_mode(la, APIC_LVT_THERMAL,
+ lapic_read32(LAPIC_LVT_THERMAL)));
+}
+
+void
+lapic_enable_thermal(void (* thermfunc)(int, void *), void *value)
+{
+#ifdef DEV_ATPIC
+ if (!x2apic_mode && lapic_map == NULL)
+ return;
+#endif
+
+ lapic_handle_thermal_function = thermfunc;
+ lapic_thermal_function_value = value;
+
+ lvts[APIC_LVT_THERMAL].lvt_masked = 0;
+
+#ifdef EARLY_AP_STARTUP
+ MPASS(mp_ncpus == 1 || smp_started);
+ smp_rendezvous(NULL, lapic_update_thermal, NULL, NULL);
+#else
+#ifdef SMP
+ if (smp_started)
+ smp_rendezvous(NULL, lapic_update_thermal, NULL, NULL);
+ else
+#endif
+ lapic_update_thermal(NULL);
+#endif
+}
+
+void
+lapic_disable_thermal(void)
+{
+#ifdef DEV_ATPIC
+ /* Fail if the local APIC is not present. */
+ if (!x2apic_mode && lapic_map == NULL)
+ return;
+#endif
+
+ lvts[APIC_LVT_THERMAL].lvt_masked = 1;
+
+#ifdef SMP
+ KASSERT(mp_ncpus == 1 || smp_started, ("thermal driver unloaded too early"));
+#endif
+ smp_rendezvous(NULL, lapic_update_thermal, NULL, NULL);
+
+ lapic_handle_thermal_function = NULL;
+ lapic_thermal_function_value = NULL;
+}
+
void
lapic_handle_error(void)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 3:41 PM (14 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15743839
Default Alt Text
D44454.diff (4 KB)
Attached To
Mode
D44454: coredirector - Intel TD/HFI driver - Part2: Enable thermal interrupt handler for Local APIC's.
Attached
Detach File
Event Timeline
Log In to Comment