Index: sys/arch/amd64/amd64/identcpu.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/identcpu.c,v retrieving revision 1.129 diff -u -p -u -p -r1.129 identcpu.c --- sys/arch/amd64/amd64/identcpu.c 22 Sep 2022 04:36:38 -0000 1.129 +++ sys/arch/amd64/amd64/identcpu.c 7 Nov 2022 17:58:50 -0000 @@ -221,7 +221,11 @@ const struct { { SEFF0EDX_SSBD, "SSBD" }, }, cpu_tpm_eaxfeatures[] = { { TPM_SENSOR, "SENSOR" }, + { TPM_TURBO, "TURBO" }, { TPM_ARAT, "ARAT" }, + { TPM_HWP, "HWP" }, +}, cpu_tpm_ecxfeatures[] = { + { TPM_EPB, "EPB" }, }, cpu_cpuid_perf_eax[] = { { CPUIDEAX_VERID, "PERF" }, }, cpu_cpuid_apmi_edx[] = { @@ -511,7 +515,7 @@ void identifycpu(struct cpu_info *ci) { uint64_t freq = 0; - u_int32_t dummy, val, cpu_tpm_ecxflags = 0; + u_int32_t dummy, val; char mycpu_model[48]; int i; char *brandstr_from, *brandstr_to; @@ -598,6 +602,8 @@ identifycpu(struct cpu_info *ci) if (cpu_apmi_edx & CPUIDEDX_ITSC) atomic_setbits_int(&ci->ci_flags, CPUF_INVAR_TSC); + tsc_timecounter_init(ci, freq); + tsc_identify(ci); } @@ -657,17 +663,21 @@ identifycpu(struct cpu_info *ci) } if (!strcmp(cpu_vendor, "GenuineIntel") && cpuid_level >= 0x06) { - CPUID(0x06, ci->ci_feature_tpmflags, dummy, cpu_tpm_ecxflags, - dummy); + CPUID(0x06, ci->ci_feature_tpmflags_eax, dummy, + ci->ci_feature_tpmflags_ecx, dummy); for (i = 0; i < nitems(cpu_tpm_eaxfeatures); i++) - if (ci->ci_feature_tpmflags & + if (ci->ci_feature_tpmflags_eax & cpu_tpm_eaxfeatures[i].bit) printf(",%s", cpu_tpm_eaxfeatures[i].str); + for (i = 0; i < nitems(cpu_tpm_eaxfeatures); i++) + if (ci->ci_feature_tpmflags_ecx & + cpu_tpm_ecxfeatures[i].bit) + printf(",%s", cpu_tpm_ecxfeatures[i].str); } else if (!strcmp(cpu_vendor, "AuthenticAMD")) { - CPUID(0x06, ci->ci_feature_tpmflags, dummy, cpu_tpm_ecxflags, + CPUID(0x06, ci->ci_feature_tpmflags_eax, dummy, ci->ci_feature_tpmflags_ecx, dummy); if (ci->ci_family >= 0x12) - ci->ci_feature_tpmflags |= TPM_ARAT; + ci->ci_feature_tpmflags_eax |= TPM_ARAT; } /* AMD speculation control features */ @@ -713,7 +723,9 @@ identifycpu(struct cpu_info *ci) setperf_setup = k1x_init; } - if (cpu_ecxfeature & CPUIDECX_EST) + if (ci->ci_feature_tpmflags_eax & TPM_HWP) + setperf_setup = pstate_init; + else if (cpu_ecxfeature & CPUIDECX_EST) setperf_setup = est_init; #endif @@ -736,7 +748,7 @@ identifycpu(struct cpu_info *ci) } #ifndef SMALL_KERNEL - if (CPU_IS_PRIMARY(ci) && (ci->ci_feature_tpmflags & TPM_SENSOR)) { + if (CPU_IS_PRIMARY(ci) && (ci->ci_feature_tpmflags_eax & TPM_SENSOR)) { ci->ci_sensor.type = SENSOR_TEMP; sensor_task_register(ci, intelcore_update_sensor, 5); sensor_attach(&ci->ci_sensordev, &ci->ci_sensor); @@ -762,15 +774,13 @@ identifycpu(struct cpu_info *ci) #endif } - tsc_timecounter_init(ci, freq); - cpu_topology(ci); #if NVMM > 0 cpu_check_vmm_cap(ci); #endif /* NVMM > 0 */ /* Check for effective frequency via MPERF, APERF */ - if ((cpu_tpm_ecxflags & TPM_EFFFREQ) && ci->ci_smt_id == 0) { + if ((ci->ci_feature_tpmflags_ecx & TPM_EFFFREQ) && ci->ci_smt_id == 0) { #ifndef SMALL_KERNEL ci->ci_hz_sensor.type = SENSOR_FREQ; sensor_task_register(ci, cpu_hz_update_sensor, 1); Index: sys/arch/amd64/amd64/machdep.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v retrieving revision 1.282 diff -u -p -u -p -r1.282 machdep.c --- sys/arch/amd64/amd64/machdep.c 30 Oct 2022 17:43:39 -0000 1.282 +++ sys/arch/amd64/amd64/machdep.c 7 Nov 2022 17:58:51 -0000 @@ -553,6 +553,9 @@ cpu_sysctl(int *name, u_int namelen, voi #endif case CPU_TSCFREQ: return (sysctl_rdquad(oldp, oldlenp, newp, tsc_frequency)); + case CPU_HWP: + return (pstate_hwp_sysctl(name + 1, namelen - 1, oldp, oldlenp, + newp, newlen, p)); default: return (sysctl_bounded_arr(cpuctl_vars, nitems(cpuctl_vars), name, namelen, oldp, oldlenp, newp, newlen)); Index: sys/arch/amd64/amd64/pstate.c =================================================================== RCS file: sys/arch/amd64/amd64/pstate.c diff -N sys/arch/amd64/amd64/pstate.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/amd64/amd64/pstate.c 7 Nov 2022 17:58:51 -0000 @@ -0,0 +1,303 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2020 joshua stein + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * "The default HWP control field values are expected to be suitable for many + * applications. The OS can enable autonomous HWP for these common cases by: + * + * Setting IA32_HWP_REQUEST.Desired Performance = 0 + * (hardware autonomous selection determines the performance target). + * + * Set IA32_HWP_REQUEST.Activity Window = 0 (enable HW dynamic selection of + * window size). + * + * To maximize HWP benefit for the common cases, the OS should set: + * IA32_HWP_REQUEST.Minimum_Performance = + * IA32_HWP_CAPABILITIES.Lowest_Performance and + * IA32_HWP_REQUEST.Maximum_Performance = + * IA32_HWP_CAPABILITIES.Highest_Performance." + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +extern int setperf_prio; +extern int perflevel; +#ifdef MULTIPROCESSOR +void mp_setperf(int); +#endif + +static int pstate_hwp = 0; +static int pstate_hwp_bias_style = -1; +enum { + PSTATE_HWP_BIAS_EPP, + PSTATE_HWP_BIAS_EPB, +}; + +/* IA32_HWP_REQUEST */ +union hwp_request { + uint64_t msr; + struct { + uint8_t min_perf; + uint8_t max_perf; + uint8_t desired_perf; + uint8_t epp; + uint16_t act_win : 10; + uint8_t package : 1; + uint32_t reserved : 21; + } __packed fields; +} pstate_hwp_req; + +uint64_t pstate_epb; + +/* IA32_HWP_CAPABILITIES */ +union hwp_capabilities { + uint64_t msr; + struct { + uint8_t highest_perf; + uint8_t guaranteed_perf; + uint8_t most_efficient; + uint8_t lowest_perf; + uint32_t reserved; + } __packed fields; +} pstate_hwp_cap; + +static struct { + int epb_min; + int epb_max; + int epp; + char *label; +} pstate_epp_labels[] = { + { 0x00, 0x03, 0x00, "performance" }, + { 0x04, 0x07, 0x80, "balance_performance" }, + { 0x08, 0x0b, 0xc0, "balance_powersave" }, + { 0x0c, 0x0f, 0xff, "powersave" }, +}; + +const char *pstate_hwp_bias_label(int); +void pstate_commit(void); + +void +pstate_init(struct cpu_info *ci) +{ + const char *cpu_device = ci->ci_dev->dv_xname; + union hwp_request hwp_req; + uint64_t msr; + int16_t eppepb; + + if (rdmsr_safe(MSR_PLATFORM_INFO, &msr) != 0) + return; + + /* power management must be enabled before reading capabilities */ + wrmsr(IA32_PM_ENABLE, 1); + if (rdmsr(IA32_PM_ENABLE) != 1) { + printf("%s: enabling HWP failed\n", cpu_device); + return; + } + + if (rdmsr_safe(IA32_HWP_CAPABILITIES, &pstate_hwp_cap.msr) != 0) { + printf("%s: no HWP capabilities\n", cpu_device); + /* XXX: what are we supposed to do now? */ + return; + } + + if (ci->ci_feature_tpmflags_eax & TPM_HWP_EPP) { + pstate_hwp_bias_style = PSTATE_HWP_BIAS_EPP; + pstate_hwp_req.msr = rdmsr(IA32_HWP_REQUEST); + eppepb = hwp_req.fields.epp; + } else if (ci->ci_feature_tpmflags_ecx & TPM_EPB) { + pstate_hwp_bias_style = PSTATE_HWP_BIAS_EPB; + eppepb = pstate_epb = rdmsr(IA32_ENERGY_PERF_BIAS) & 0x0f; + } else { + printf("%s: no energy bias control\n", cpu_device); + return; + } + + /* XXX: should we force epb to performance by default? */ + + pstate_hwp = 1; + setperf_prio = 1; + cpu_setperf = pstate_setperf; + + printf("%s: HWP enabled, bias %s, highest perf %d MHz, " + "guaranteed %d MHz, most efficient %d MHz, lowest perf %d MHz\n", + cpu_device, pstate_hwp_bias_label(eppepb), + pstate_hwp_cap.fields.highest_perf * 100, + pstate_hwp_cap.fields.guaranteed_perf * 100, + pstate_hwp_cap.fields.most_efficient * 100, + pstate_hwp_cap.fields.lowest_perf * 100); +} + +const char * +pstate_hwp_bias_label(int val) +{ + int i; + + for (i = 0; i < (sizeof(pstate_epp_labels) / + sizeof(pstate_epp_labels[0])); i++) { + if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPP) { + if (val == pstate_epp_labels[i].epp) + return pstate_epp_labels[i].label; + } else if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPB) { + if (val >= pstate_epp_labels[i].epb_min && + val <= pstate_epp_labels[i].epb_max) + return pstate_epp_labels[i].label; + } + } + + return "unknown"; +} + +void +pstate_setperf(int level) +{ + // printf("%s: %s(%d)\n", curcpu()->ci_dev->dv_xname, __func__, level); + + if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPP) + wrmsr(IA32_HWP_REQUEST, pstate_hwp_req.msr); + else if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPB) + wrmsr(IA32_ENERGY_PERF_BIAS, pstate_epb); +} + +void +pstate_commit(void) +{ +#ifdef MULTIPROCESSOR + /* + * This will broadcast X86_IPI_SETPERF to call pstate_setperf on each + * CPU, so we can wrmsr on each + */ + mp_setperf(perflevel); +#else + setperf(perflevel); +#endif +} + +/* TODO: update cpuspeed in response to hwp notifications */ + +int +pstate_hwp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen, struct proc *p) +{ + uint64_t epb = 0; + const char *bias; + char newbias[64]; + int newval, err, i, found = 0; + + if (namelen != 1) + return ENOTDIR; + + if (!pstate_hwp) + return EOPNOTSUPP; + + if (name[0] < 1 || name[0] >= HWP_MAXID) + return EOPNOTSUPP; + + pstate_hwp_req.msr = rdmsr(IA32_HWP_REQUEST); + + switch (name[0]) { + case HWP_MIN_PERF: + case HWP_MAX_PERF: + case HWP_DESIRED_PERF: + switch (name[0]) { + case HWP_MIN_PERF: + newval = pstate_hwp_req.fields.min_perf; + break; + case HWP_MAX_PERF: + newval = pstate_hwp_req.fields.max_perf; + break; + case HWP_DESIRED_PERF: + newval = pstate_hwp_req.fields.desired_perf; + break; + } + + if (newlen == 0) + return sysctl_rdint(oldp, oldlenp, newp, newval); + + err = sysctl_int(oldp, oldlenp, newp, newlen, &newval); + if (err) + return err; + + switch (name[0]) { + case HWP_MIN_PERF: + pstate_hwp_req.fields.min_perf = newval; + break; + case HWP_MAX_PERF: + pstate_hwp_req.fields.max_perf = newval; + break; + case HWP_DESIRED_PERF: + pstate_hwp_req.fields.desired_perf = newval; + break; + } + + printf("%s: name[0] %d, newval %d [%zu], writing hwpreq 0x%llx\n", + curcpu()->ci_dev->dv_xname, name[0], newval, newlen, + pstate_hwp_req.msr); + + pstate_commit(); + return 0; + + case HWP_EPP: + if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPP) + epb = pstate_hwp_req.fields.epp; + else if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPB) + pstate_epb = epb = rdmsr(IA32_ENERGY_PERF_BIAS) & 0x0f; + + bias = pstate_hwp_bias_label(epb); + + if (newlen == 0) + return sysctl_rdstring(oldp, oldlenp, newp, bias); + + memcpy(newbias, bias, sizeof(newbias)); + err = sysctl_string(oldp, oldlenp, newp, newlen, newbias, + sizeof(newbias)); + if (err) + return err; + + for (i = 0; i < (sizeof(pstate_epp_labels) / + sizeof(pstate_epp_labels[0])); i++) { + if (strcmp(pstate_epp_labels[i].label, newbias) != 0) + continue; + + if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPP) + pstate_hwp_req.fields.epp = + pstate_epp_labels[i].epp; + else if (pstate_hwp_bias_style == PSTATE_HWP_BIAS_EPB) + pstate_epb = pstate_epp_labels[i].epb_max; + + found = 1; + } + + if (!found) + return EINVAL; + + printf("%s: changing epp/epb bias to \"%s\" (0x%llx)\n", + curcpu()->ci_dev->dv_xname, newbias, pstate_hwp_req.msr); + + pstate_commit(); + return 0; + } + + return EOPNOTSUPP; +} Index: sys/arch/amd64/conf/files.amd64 =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v retrieving revision 1.106 diff -u -p -u -p -r1.106 files.amd64 --- sys/arch/amd64/conf/files.amd64 16 Oct 2022 15:03:39 -0000 1.106 +++ sys/arch/amd64/conf/files.amd64 7 Nov 2022 17:58:51 -0000 @@ -64,6 +64,7 @@ file arch/amd64/isa/clock.c file arch/amd64/amd64/powernow-k8.c !small_kernel file arch/amd64/amd64/est.c !small_kernel file arch/amd64/amd64/k1x-pstate.c !small_kernel +file arch/amd64/amd64/pstate.c !small_kernel include "dev/rasops/files.rasops" include "dev/wsfont/files.wsfont" Index: sys/arch/amd64/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/amd64/include/cpu.h,v retrieving revision 1.151 diff -u -p -u -p -r1.151 cpu.h --- sys/arch/amd64/include/cpu.h 20 Sep 2022 14:28:27 -0000 1.151 +++ sys/arch/amd64/include/cpu.h 7 Nov 2022 17:58:51 -0000 @@ -156,7 +156,8 @@ struct cpu_info { u_int32_t ci_feature_sefflags_ecx;/* [I] */ u_int32_t ci_feature_sefflags_edx;/* [I] */ u_int32_t ci_feature_amdspec_ebx; /* [I] */ - u_int32_t ci_feature_tpmflags; /* [I] */ + u_int32_t ci_feature_tpmflags_eax;/* [I] */ + u_int32_t ci_feature_tpmflags_ecx;/* [I] */ u_int32_t ci_pnfeatset; /* [I] */ u_int32_t ci_efeature_eax; /* [I] */ u_int32_t ci_efeature_ecx; /* [I] */ @@ -446,9 +447,16 @@ void k8_powernow_setperf(int); void k1x_init(struct cpu_info *); void k1x_setperf(int); +/* est.c */ void est_init(struct cpu_info *); void est_setperf(int); +/* pstate.c */ +void pstate_init(struct cpu_info *); +void pstate_setperf(int); +int pstate_hwp_sysctl(int *, u_int, void *, size_t *, void *, size_t, + struct proc *); + #ifdef MULTIPROCESSOR /* mp_setperf.c */ void mp_setperf_init(void); @@ -474,7 +482,8 @@ void mp_setperf_init(void); #define CPU_TSCFREQ 16 /* TSC frequency */ #define CPU_INVARIANTTSC 17 /* has invariant TSC */ #define CPU_PWRACTION 18 /* action caused by power button */ -#define CPU_MAXID 19 /* number of valid machdep ids */ +#define CPU_HWP 19 /* hardware p-state knobs */ +#define CPU_MAXID 20 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ @@ -496,6 +505,28 @@ void mp_setperf_init(void); { "tscfreq", CTLTYPE_QUAD }, \ { "invarianttsc", CTLTYPE_INT }, \ { "pwraction", CTLTYPE_INT }, \ + { "hwp", CTLTYPE_INT }, \ +} + +/* + * CTL_HWP definitions. + */ +#define HWP_MIN_PERF 1 +#define HWP_MIN_PERF_NAME "min_perf" +#define HWP_MAX_PERF 2 +#define HWP_MAX_PERF_NAME "max_perf" +#define HWP_DESIRED_PERF 3 +#define HWP_DESIRED_PERF_NAME "desired_perf" +#define HWP_EPP 4 +#define HWP_EPP_NAME "epp_bias" +#define HWP_MAXID 5 + +#define CTL_HWP_NAMES { \ + { 0, 0 }, \ + { HWP_MIN_PERF_NAME, CTLTYPE_INT }, \ + { HWP_MAX_PERF_NAME, CTLTYPE_INT }, \ + { HWP_DESIRED_PERF_NAME, CTLTYPE_INT }, \ + { HWP_EPP_NAME, CTLTYPE_STRING }, \ } #endif /* !_MACHINE_CPU_H_ */ Index: sys/arch/amd64/include/specialreg.h =================================================================== RCS file: /cvs/src/sys/arch/amd64/include/specialreg.h,v retrieving revision 1.95 diff -u -p -u -p -r1.95 specialreg.h --- sys/arch/amd64/include/specialreg.h 24 Oct 2022 00:56:33 -0000 1.95 +++ sys/arch/amd64/include/specialreg.h 7 Nov 2022 17:58:51 -0000 @@ -217,10 +217,20 @@ * Thermal and Power Management (CPUID function 0x6) EAX bits */ #define TPM_SENSOR 0x00000001 /* Digital temp sensor */ +#define TPM_TURBO 0x00000002 /* Turbo Boost available */ #define TPM_ARAT 0x00000004 /* APIC Timer Always Running */ +#define TPM_HWP 0x00000080 /* Hardware P-States supported */ +#define TPM_HWP_NOTIFY 0x00000100 /* HWP Notification */ +#define TPM_HWP_ACT_WIN 0x00000200 /* HWP Activity Window */ +#define TPM_HWP_EPP 0x00000400 /* HWP Energy Perf. Preference */ /* Thermal and Power Management (CPUID function 0x6) ECX bits */ #define TPM_EFFFREQ 0x00000001 /* APERF & MPERF MSR present */ +/* + * Thermal and Power Management (CPUID function 0x6) ECX bits + */ +#define TPM_EPB 0x00000008 /* IA32_ENERGY_PERF_BIAS supported */ + /* * "Architectural Performance Monitoring" bits (CPUID function 0x0a): * EAX bits, EBX bits, EDX bits. @@ -354,6 +364,7 @@ #define MSR_PERFCTR0 0x0c1 #define MSR_PERFCTR1 0x0c2 #define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ +#define MSR_PLATFORM_INFO 0x0ce #define MSR_MPERF 0x0e7 #define MSR_APERF 0x0e8 #define MSR_MTRRcap 0x0fe @@ -917,11 +928,28 @@ #define C3_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */ #define C3_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */ +/* Hardware-Controlled Performance States (HWP) */ +#define IA32_ENERGY_PERF_BIAS 0x1b0 +#define IA32_PM_ENABLE 0x770 +#define IA32_HWP_CAPABILITIES 0x771 +#define IA32_HWP_REQUEST_PKG 0x772 +#define IA32_HWP_INTERRUPT 0x773 +#define IA32_HWP_REQUEST 0x774 +#define IA32_HWP_STATUS 0x777 +#define MSR_PPERF 0x64e + /* Intel Silicon Debug */ #define IA32_DEBUG_INTERFACE 0xc80 #define IA32_DEBUG_INTERFACE_ENABLE 0x00000001 #define IA32_DEBUG_INTERFACE_LOCK 0x40000000 #define IA32_DEBUG_INTERFACE_MASK 0x80000000 + +/* Config TDP MSRs */ +#define MSR_CONFIG_TDP_NOMINAL 0x00000648 +#define MSR_CONFIG_TDP_LEVEL_1 0x00000649 +#define MSR_CONFIG_TDP_LEVEL_2 0x0000064A +#define MSR_CONFIG_TDP_CONTROL 0x0000064B +#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C /* * VMX Index: sbin/sysctl/sysctl.c =================================================================== RCS file: /cvs/src/sbin/sysctl/sysctl.c,v retrieving revision 1.258 diff -u -p -u -p -r1.258 sysctl.c --- sbin/sysctl/sysctl.c 12 Jul 2021 15:09:19 -0000 1.258 +++ sbin/sysctl/sysctl.c 7 Nov 2022 17:58:51 -0000 @@ -223,6 +223,7 @@ int sysctl_chipset(char *, char **, int int sysctl_audio(char *, char **, int *, int, int *); int sysctl_video(char *, char **, int *, int, int *); int sysctl_witness(char *, char **, int *, int, int *); +int sysctl_hwp(char *, char **, int *, int, int *); void vfsinit(void); char *equ = "="; @@ -771,6 +772,14 @@ parse(char *string, int flags) break; } #endif +#ifdef CPU_HWP + if (mib[1] == CPU_HWP) { + len = sysctl_hwp(string, &bufp, mib, flags, &type); + if (len < 0) + return; + break; + } +#endif break; case CTL_FS: @@ -2910,6 +2919,30 @@ sysctl_witness(char *string, char **bufp *typep = witnesslist.list[indx].ctl_type; return (3); } + +#ifdef CPU_HWP +/* + * handle machdep.hwp requests + */ +struct ctlname hwpname[] = CTL_HWP_NAMES; +struct list hwplist = { hwpname, HWP_MAXID }; + +int +sysctl_hwp(char *string, char **bufpp, int mib[], int flags, int *typep) +{ + int indx; + + if (*bufpp == NULL) { + listall(string, &hwplist); + return (-1); + } + if ((indx = findname(string, "third", bufpp, &hwplist)) == -1) + return (-1); + mib[2] = indx; + *typep = hwplist.list[indx].ctl_type; + return (3); +} +#endif /* * Scan a list of names searching for a particular name.