summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-10-06 18:31:35 +0200
committerAmaury Pouly <amaury.pouly@gmail.com>2017-10-06 18:31:35 +0200
commit4382f8773eaa94c43dc6cc0f19591d2607a34f20 (patch)
tree8f4505cb16fdcdc3a14deb5b26ad21d20ed99c64
parent2f3801be3426c5cd743f237ec92b8feb9b5f0344 (diff)
downloadrockbox-4382f8773eaa94c43dc6cc0f19591d2607a34f20.tar.gz
rockbox-4382f8773eaa94c43dc6cc0f19591d2607a34f20.zip
cleanup linux cpuinfo code
sonynwz: quirk for cpufreq broken driver There was some redundancy between frequency_linux(cpu, true) and current_scaling_frequency(), also I see no reason to compile the cpuinfo stuff unconditionally and the scaling info only on DX since it was already printed some partial scaling info anyway. Thus compile all the code unconditionally and simplify the logic in the debug menu. Also avoid putting buffers of size PATH_MAX on stack since it can be quite big and we only requires 64 bytes for those paths. On Sony NWZ, the cpu driver reports frequency in MHz instead of kHz thus we need to make the cpuinfo code aware of that bug. Change-Id: I61af45ab5f179ecc909b4841b9137a915a60193a
-rw-r--r--apps/debug_menu.c16
-rw-r--r--firmware/target/hosted/cpuinfo-linux.c32
-rw-r--r--firmware/target/hosted/cpuinfo-linux.h8
3 files changed, 27 insertions, 29 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 5224dbe267..4947f30695 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -240,9 +240,13 @@ static const char* get_cpuinfo(int selected_item, void *data,
240 { 240 {
241 int cpu = (selected_item - 5) / (state_count + 1); 241 int cpu = (selected_item - 5) / (state_count + 1);
242 int cpu_line = (selected_item - 5) % (state_count + 1); 242 int cpu_line = (selected_item - 5) % (state_count + 1);
243#if defined(DX50) || defined(DX90) 243
244 /* scaling info */
244 int min_freq = min_scaling_frequency(cpu); 245 int min_freq = min_scaling_frequency(cpu);
245 int cur_freq = current_scaling_frequency(cpu); 246 int cur_freq = current_scaling_frequency(cpu);
247 /* fallback if scaling frequency is not available */
248 if(cur_freq <= 0)
249 cur_freq = frequency_linux(cpu);
246 int max_freq = max_scaling_frequency(cpu); 250 int max_freq = max_scaling_frequency(cpu);
247 char governor[20]; 251 char governor[20];
248 bool have_governor = current_scaling_governor(cpu, governor, sizeof(governor)); 252 bool have_governor = current_scaling_governor(cpu, governor, sizeof(governor));
@@ -256,16 +260,6 @@ static const char* get_cpuinfo(int selected_item, void *data,
256 cur_freq > 0 ? cur_freq/1000 : -1, 260 cur_freq > 0 ? cur_freq/1000 : -1,
257 max_freq > 0 ? max_freq/1000 : -1); 261 max_freq > 0 ? max_freq/1000 : -1);
258 } 262 }
259#else
260 int freq1 = frequency_linux(cpu, false);
261 int freq2 = frequency_linux(cpu, true);
262 if (cpu_line == 0)
263 {
264 sprintf(buffer, " CPU%d: Cur/Scal freq: %d/%d MHz", cpu,
265 freq1 > 0 ? freq1/1000 : -1,
266 freq2 > 0 ? freq2/1000 : -1);
267 }
268#endif
269 else 263 else
270 { 264 {
271 cpustatetimes_linux(cpu, states, ARRAYLEN(states)); 265 cpustatetimes_linux(cpu, states, ARRAYLEN(states));
diff --git a/firmware/target/hosted/cpuinfo-linux.c b/firmware/target/hosted/cpuinfo-linux.c
index 8158673349..c3669a9f5c 100644
--- a/firmware/target/hosted/cpuinfo-linux.c
+++ b/firmware/target/hosted/cpuinfo-linux.c
@@ -35,11 +35,9 @@
35#include "cpuinfo-linux.h" 35#include "cpuinfo-linux.h"
36#include "gcc_extensions.h" 36#include "gcc_extensions.h"
37 37
38#if defined(DX50) || defined(DX90)
39#include <limits.h> 38#include <limits.h>
40#include <string.h> 39#include <string.h>
41#include "debug.h" 40#include "debug.h"
42#endif
43 41
44#undef open /* want the *real* open here, not sim_open or the like */ 42#undef open /* want the *real* open here, not sim_open or the like */
45#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(DX50) || defined(DX90) 43#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(DX50) || defined(DX90)
@@ -51,6 +49,14 @@
51#define NUM_SAMPLES_MASK (NUM_SAMPLES-1) 49#define NUM_SAMPLES_MASK (NUM_SAMPLES-1)
52#define SAMPLE_RATE 4 50#define SAMPLE_RATE 4
53 51
52/* Some targets like the Sony NWZ have a broken cpu driver that reports frequencies in MHz instead
53 * of kHz */
54#if defined(SONY_NWZ_LINUX)
55#define FREQ_MULTIPLIER 1000
56#else
57#define FREQ_MULTIPLIER 1
58#endif
59
54struct cputime_sample { 60struct cputime_sample {
55 struct tms sample; 61 struct tms sample;
56 time_t time; 62 time_t time;
@@ -143,24 +149,21 @@ int cpucount_linux(void)
143 return get_nprocs(); 149 return get_nprocs();
144} 150}
145 151
146int frequency_linux(int cpu, bool scaling) 152int frequency_linux(int cpu)
147{ 153{
148 char path[64]; 154 char path[64];
149 char temp[10]; 155 char temp[10];
150 int cpu_dev, ret = -1; 156 int cpu_dev, ret = -1;
151 snprintf(path, sizeof(path), 157 snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_cur_freq", cpu);
152 "/sys/devices/system/cpu/cpu%d/cpufreq/%s_cur_freq",
153 cpu, scaling ? "scaling" : "cpuinfo");
154 cpu_dev = open(path, O_RDONLY); 158 cpu_dev = open(path, O_RDONLY);
155 if (cpu_dev < 0) 159 if (cpu_dev < 0)
156 return -1; 160 return -1;
157 if (read(cpu_dev, temp, sizeof(temp)) >= 0) 161 if (read(cpu_dev, temp, sizeof(temp)) >= 0)
158 ret = atoi(temp); 162 ret = atoi(temp) * FREQ_MULTIPLIER;
159 close(cpu_dev); 163 close(cpu_dev);
160 return ret; 164 return ret;
161} 165}
162 166
163#if defined(DX50) || defined(DX90)
164bool current_scaling_governor(int cpu, char* governor, int governor_size) 167bool current_scaling_governor(int cpu, char* governor, int governor_size)
165{ 168{
166 if((cpu < 0) || (governor == NULL) || (governor_size <= 0)) 169 if((cpu < 0) || (governor == NULL) || (governor_size <= 0))
@@ -168,7 +171,7 @@ bool current_scaling_governor(int cpu, char* governor, int governor_size)
168 return false; 171 return false;
169 } 172 }
170 173
171 char path[PATH_MAX]; 174 char path[64];
172 snprintf(path, 175 snprintf(path,
173 sizeof(path), 176 sizeof(path),
174 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", 177 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
@@ -212,13 +215,13 @@ static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
212 return -1; 215 return -1;
213 } 216 }
214 217
215 char path[PATH_MAX]; 218 char path[64];
216 switch(freqOpt) 219 switch(freqOpt)
217 { 220 {
218 case SCALING_MIN_FREQ: 221 case SCALING_MIN_FREQ:
219 { 222 {
220 snprintf(path, 223 snprintf(path,
221 PATH_MAX, 224 sizeof(path),
222 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", 225 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq",
223 cpu); 226 cpu);
224 break; 227 break;
@@ -227,7 +230,7 @@ static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
227 case SCALING_CUR_FREQ: 230 case SCALING_CUR_FREQ:
228 { 231 {
229 snprintf(path, 232 snprintf(path,
230 PATH_MAX, 233 sizeof(path),
231 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", 234 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq",
232 cpu); 235 cpu);
233 break; 236 break;
@@ -236,7 +239,7 @@ static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
236 case SCALING_MAX_FREQ: 239 case SCALING_MAX_FREQ:
237 { 240 {
238 snprintf(path, 241 snprintf(path,
239 PATH_MAX, 242 sizeof(path),
240 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", 243 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq",
241 cpu); 244 cpu);
242 break; 245 break;
@@ -264,7 +267,7 @@ static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
264 } 267 }
265 268
266 fclose(f); 269 fclose(f);
267 return(freq); 270 return freq * FREQ_MULTIPLIER;
268} 271}
269 272
270 273
@@ -284,7 +287,6 @@ int max_scaling_frequency(int cpu)
284{ 287{
285 return(read_cpu_frequency(cpu, SCALING_MAX_FREQ)); 288 return(read_cpu_frequency(cpu, SCALING_MAX_FREQ));
286} 289}
287#endif
288 290
289int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements) 291int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements)
290{ 292{
diff --git a/firmware/target/hosted/cpuinfo-linux.h b/firmware/target/hosted/cpuinfo-linux.h
index 0483a3a9aa..defbf2f374 100644
--- a/firmware/target/hosted/cpuinfo-linux.h
+++ b/firmware/target/hosted/cpuinfo-linux.h
@@ -39,9 +39,12 @@ struct time_state {
39}; 39};
40 40
41int cpuusage_linux(struct cpuusage* u); 41int cpuusage_linux(struct cpuusage* u);
42int frequency_linux(int cpu, bool scaling); 42/* Return the frequency of a CPU. Note that whenever CPU frequency scaling is supported by the
43 * driver, this frequency may not be accurate and may vaguely reflect the cpu mode. Use
44 * current_scaling_frequency() to get the actual frequency if scaling is supported.
45 * Return -1 on error. */
46int frequency_linux(int cpu);
43 47
44#if defined(DX50) || defined(DX90)
45/* 48/*
46 Get the current cpufreq scaling governor. 49 Get the current cpufreq scaling governor.
47 cpu [in]: The number of the cpu to query. 50 cpu [in]: The number of the cpu to query.
@@ -60,7 +63,6 @@ bool current_scaling_governor(int cpu, char* governor, int governor_size);
60int min_scaling_frequency(int cpu); 63int min_scaling_frequency(int cpu);
61int current_scaling_frequency(int cpu); 64int current_scaling_frequency(int cpu);
62int max_scaling_frequency(int cpu); 65int max_scaling_frequency(int cpu);
63#endif
64 66
65int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements); 67int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements);
66int cpucount_linux(void); 68int cpucount_linux(void);