1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <stdio.h> 4 #include <errno.h> 5 #include <stdlib.h> 6 7 #include "helpers/helpers.h" 8 #include "helpers/sysfs.h" 9 10 #if defined(__i386__) || defined(__x86_64__) 11 12 #include "cpupower_intern.h" 13 14 #define MSR_AMD_HWCR 0xc0010015 15 16 int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, 17 int *states) 18 { 19 int ret; 20 unsigned long long val; 21 22 *support = *active = *states = 0; 23 24 if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) { 25 *support = 1; 26 27 /* AMD Family 0x17 does not utilize PCI D18F4 like prior 28 * families and has no fixed discrete boost states but 29 * has Hardware determined variable increments instead. 30 */ 31 32 if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB_MSR) { 33 if (!read_msr(cpu, MSR_AMD_HWCR, &val)) { 34 if (!(val & CPUPOWER_AMD_CPBDIS)) 35 *active = 1; 36 } 37 } else { 38 ret = amd_pci_get_num_boost_states(active, states); 39 if (ret) 40 return ret; 41 } 42 } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) 43 *support = *active = 1; 44 return 0; 45 } 46 47 int cpupower_intel_get_perf_bias(unsigned int cpu) 48 { 49 char linebuf[MAX_LINE_LEN]; 50 char path[SYSFS_PATH_MAX]; 51 unsigned long val; 52 char *endp; 53 54 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) 55 return -1; 56 57 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu); 58 59 if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) 60 return -1; 61 62 val = strtol(linebuf, &endp, 0); 63 if (endp == linebuf || errno == ERANGE) 64 return -1; 65 66 return val; 67 } 68 69 int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) 70 { 71 char path[SYSFS_PATH_MAX]; 72 char linebuf[3] = {}; 73 74 if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) 75 return -1; 76 77 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu); 78 snprintf(linebuf, sizeof(linebuf), "%d", val); 79 80 if (cpupower_write_sysfs(path, linebuf, 3) <= 0) 81 return -1; 82 83 return 0; 84 } 85 86 #endif /* #if defined(__i386__) || defined(__x86_64__) */ 87 88 /* get_cpustate 89 * 90 * Gather the information of all online CPUs into bitmask struct 91 */ 92 void get_cpustate(void) 93 { 94 unsigned int cpu = 0; 95 96 bitmask_clearall(online_cpus); 97 bitmask_clearall(offline_cpus); 98 99 for (cpu = bitmask_first(cpus_chosen); 100 cpu <= bitmask_last(cpus_chosen); cpu++) { 101 102 if (cpupower_is_cpu_online(cpu) == 1) 103 bitmask_setbit(online_cpus, cpu); 104 else 105 bitmask_setbit(offline_cpus, cpu); 106 107 continue; 108 } 109 } 110 111 /* print_online_cpus 112 * 113 * Print the CPU numbers of all CPUs that are online currently 114 */ 115 void print_online_cpus(void) 116 { 117 int str_len = 0; 118 char *online_cpus_str = NULL; 119 120 str_len = online_cpus->size * 5; 121 online_cpus_str = (void *)malloc(sizeof(char) * str_len); 122 123 if (!bitmask_isallclear(online_cpus)) { 124 bitmask_displaylist(online_cpus_str, str_len, online_cpus); 125 printf(_("Following CPUs are online:\n%s\n"), online_cpus_str); 126 } 127 } 128 129 /* print_offline_cpus 130 * 131 * Print the CPU numbers of all CPUs that are offline currently 132 */ 133 void print_offline_cpus(void) 134 { 135 int str_len = 0; 136 char *offline_cpus_str = NULL; 137 138 str_len = offline_cpus->size * 5; 139 offline_cpus_str = (void *)malloc(sizeof(char) * str_len); 140 141 if (!bitmask_isallclear(offline_cpus)) { 142 bitmask_displaylist(offline_cpus_str, str_len, offline_cpus); 143 printf(_("Following CPUs are offline:\n%s\n"), offline_cpus_str); 144 printf(_("cpupower set operation was not performed on them\n")); 145 } 146 } 147