diff options
Diffstat (limited to 'sys/i386/include/mptable.h')
-rw-r--r-- | sys/i386/include/mptable.h | 109 |
1 files changed, 88 insertions, 21 deletions
diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index 12d7578..954a7fd 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -26,7 +26,6 @@ */ #include "opt_cpu.h" -#include "opt_htt.h" #include "opt_kstack_pages.h" #ifdef SMP @@ -238,10 +237,9 @@ typedef struct BASETABLE_ENTRY { #define MP_ANNOUNCE_POST 0x19 -#ifdef HTT static int need_hyperthreading_fixup; static u_int logical_cpus; -#endif +static u_int logical_cpus_mask; /* used to hold the AP's until we are ready to release them */ static struct mtx ap_boot_mtx; @@ -318,9 +316,7 @@ static mpfps_t mpfps; static int search_for_sig(u_int32_t target, int count); static void mp_enable(u_int boot_addr); -#ifdef HTT static void mptable_hyperthread_fixup(u_int id_mask); -#endif static void mptable_pass1(void); static int mptable_pass2(void); static void default_mp_table(int type); @@ -791,9 +787,7 @@ mptable_pass1(void) void* position; int count; int type; -#ifdef HTT u_int id_mask; -#endif POSTCODE(MPTABLE_PASS1_POST); @@ -807,9 +801,7 @@ mptable_pass1(void) mp_nbusses = 0; mp_napics = 0; nintrs = 0; -#ifdef HTT id_mask = 0; -#endif /* check for use of 'default' configuration */ if (MPFPS_MPFB1 != 0) { @@ -844,10 +836,8 @@ mptable_pass1(void) & PROCENTRY_FLAG_EN) { ++mp_naps; mp_maxid++; -#ifdef HTT id_mask |= 1 << ((proc_entry_ptr)position)->apic_id; -#endif } break; case 1: /* bus_entry */ @@ -882,10 +872,8 @@ mptable_pass1(void) mp_naps = MAXCPU; } -#ifdef HTT /* See if we need to fixup HT logical CPUs. */ mptable_hyperthread_fixup(id_mask); -#endif /* * Count the BSP. @@ -911,9 +899,7 @@ mptable_pass1(void) static int mptable_pass2(void) { -#ifdef HTT struct PROCENTRY proc; -#endif int x; mpcth_t cth; int totalSize; @@ -926,12 +912,10 @@ mptable_pass2(void) POSTCODE(MPTABLE_PASS2_POST); -#ifdef HTT /* Initialize fake proc entry for use with HT fixup. */ bzero(&proc, sizeof(proc)); proc.type = 0; proc.cpu_flags = PROCENTRY_FLAG_EN; -#endif pgeflag = 0; /* XXX - Not used under SMP yet. */ @@ -1011,7 +995,6 @@ mptable_pass2(void) if (processor_entry(position, cpu)) ++cpu; -#ifdef HTT if (need_hyperthreading_fixup) { /* * Create fake mptable processor entries @@ -1022,10 +1005,10 @@ mptable_pass2(void) for (i = 1; i < logical_cpus; i++) { proc.apic_id++; (void)processor_entry(&proc, cpu); + logical_cpus_mask |= (1 << cpu); cpu++; } } -#endif break; case 1: if (bus_entry(position, bus)) @@ -1058,7 +1041,6 @@ mptable_pass2(void) return 0; } -#ifdef HTT /* * Check if we should perform a hyperthreading "fix-up" to * enumerate any logical CPU's that aren't already listed @@ -1108,7 +1090,6 @@ mptable_hyperthread_fixup(u_int id_mask) mp_maxid *= logical_cpus; mp_naps *= logical_cpus; } -#endif void assign_apic_irq(int apic, int intpin, int irq) @@ -2760,3 +2741,89 @@ release_aps(void *dummy __unused) } SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); + +static int hlt_cpus_mask; +static int hlt_logical_cpus = 1; +static struct sysctl_ctx_list logical_cpu_clist; + +static int +sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) +{ + u_int mask; + int error; + + mask = hlt_cpus_mask; + error = sysctl_handle_int(oidp, &mask, 0, req); + if (error || !req->newptr) + return (error); + + if (logical_cpus_mask != 0 && + (mask & logical_cpus_mask) == logical_cpus_mask) + hlt_logical_cpus = 1; + else + hlt_logical_cpus = 0; + + if ((mask & all_cpus) == all_cpus) + mask &= ~(1<<0); + hlt_cpus_mask = mask; + return (error); +} +SYSCTL_PROC(_machdep, OID_AUTO, hlt_cpus, CTLTYPE_INT|CTLFLAG_RW, + 0, 0, sysctl_hlt_cpus, "IU", ""); + +static int +sysctl_hlt_logical_cpus(SYSCTL_HANDLER_ARGS) +{ + int disable, error; + + disable = hlt_logical_cpus; + error = sysctl_handle_int(oidp, &disable, 0, req); + if (error || !req->newptr) + return (error); + + if (disable) + hlt_cpus_mask |= logical_cpus_mask; + else + hlt_cpus_mask &= ~logical_cpus_mask; + + if ((hlt_cpus_mask & all_cpus) == all_cpus) + hlt_cpus_mask &= ~(1<<0); + + hlt_logical_cpus = disable; + return (error); +} + +static void +cpu_hlt_setup(void *dummy __unused) +{ + + if (logical_cpus_mask != 0) { + TUNABLE_INT_FETCH("machdep.hlt_logical_cpus", + &hlt_logical_cpus); + sysctl_ctx_init(&logical_cpu_clist); + SYSCTL_ADD_PROC(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "hlt_logical_cpus", CTLTYPE_INT|CTLFLAG_RW, 0, 0, + sysctl_hlt_logical_cpus, "IU", ""); + SYSCTL_ADD_UINT(&logical_cpu_clist, + SYSCTL_STATIC_CHILDREN(_machdep), OID_AUTO, + "logical_cpus_mask", CTLTYPE_INT|CTLFLAG_RD, + &logical_cpus_mask, 0, ""); + + if (hlt_logical_cpus) + hlt_cpus_mask |= logical_cpus_mask; + } +} +SYSINIT(cpu_hlt, SI_SUB_SMP, SI_ORDER_ANY, cpu_hlt_setup, NULL); + +int +mp_grab_cpu_hlt(void) +{ + u_int mask = PCPU_GET(cpumask); + int retval; + + retval = mask & hlt_cpus_mask; + while (mask & hlt_cpus_mask) + __asm __volatile("sti; hlt" : : : "memory"); + return (retval); +} |