1 | /*␊ |
2 | * platform_env.c␊ |
3 | * ␊ |
4 | * Copyright 2012-2013 Cadet-petit Armel <armelcadetpetit@gmail.com>. All rights reserved.␊ |
5 | */␊ |
6 | ␊ |
7 | #include "libsaio.h"␊ |
8 | #include "bootstruct.h"␊ |
9 | #include "pci.h"␊ |
10 | #include "platform.h"␊ |
11 | #include "cpu.h"␊ |
12 | ␊ |
13 | #ifndef DEBUG_PLATFORM␊ |
14 | #define DEBUG_PLATFORM 0␊ |
15 | #endif␊ |
16 | ␊ |
17 | #if DEBUG_PLATFORM␊ |
18 | #define DBG(x...)␉printf(x)␊ |
19 | #else␊ |
20 | #define DBG(x...)␊ |
21 | #endif␊ |
22 | ␊ |
23 | #ifndef DEBUG_PLATFORM_CPU␊ |
24 | #define DEBUG_PLATFORM_CPU 0␊ |
25 | #endif␊ |
26 | ␊ |
27 | static char *gboardproduct = NULL;␊ |
28 | static char *gPlatformName = NULL;␊ |
29 | static char *gRootDevice = NULL;␊ |
30 | ␊ |
31 | void SetgRootDevice(const char * str)␊ |
32 | {␊ |
33 | gRootDevice = (char*)str;␊ |
34 | }␊ |
35 | void Setgboardproduct(const char * str)␊ |
36 | {␊ |
37 | gboardproduct = (char*)str;␊ |
38 | }␊ |
39 | void SetgPlatformName(const char * str)␊ |
40 | {␊ |
41 | gPlatformName = (char*)str;␊ |
42 | }␊ |
43 | ␊ |
44 | char * GetgPlatformName(void)␊ |
45 | {␊ |
46 | return gPlatformName ;␊ |
47 | }␊ |
48 | char * Getgboardproduct(void)␊ |
49 | {␊ |
50 | return gboardproduct;␊ |
51 | }␊ |
52 | char * GetgRootDevice(void)␊ |
53 | {␊ |
54 | return gRootDevice;␊ |
55 | }␊ |
56 | ␊ |
57 | #ifdef rootpath␊ |
58 | static char gRootPath[ROOT_PATH_LEN];␊ |
59 | void SetgRootPath(const char * str)␊ |
60 | {␊ |
61 | bzero(gRootPath,sizeof(gRootPath));␊ |
62 | memcpy(gRootPath,str, sizeof(gRootPath));␊ |
63 | }␊ |
64 | char * GetgRootPath(void)␊ |
65 | {␊ |
66 | return gRootPath ;␊ |
67 | }␊ |
68 | #endif␊ |
69 | ␊ |
70 | typedef enum envtype {␊ |
71 | kEnvPtr = 0,␊ |
72 | kEnvValue = 1␊ |
73 | } envtype;␊ |
74 | ␊ |
75 | struct env_struct {␊ |
76 | unsigned long long value; ␊ |
77 | char *name; ␊ |
78 | void * ptr;␊ |
79 | //int lock;␊ |
80 | enum envtype Type;␊ |
81 | UT_hash_handle hh; /* makes this structure hashable */␊ |
82 | };␊ |
83 | ␊ |
84 | static int SetVarPtr (struct env_struct *var, void* ptr, size_t size);␊ |
85 | static struct env_struct *find_env(const char *name);␊ |
86 | static void _re_set_env_ptr(struct env_struct *var , void* ptr,size_t size);␊ |
87 | struct env_struct *platform_env = NULL;␊ |
88 | ␊ |
89 | ␊ |
90 | static int SetVarPtr (struct env_struct *var, void* ptr, size_t size)␊ |
91 | {␊ |
92 | var->ptr = malloc(size);␊ |
93 | if (!var->ptr) {␊ |
94 | return 0;␊ |
95 | }␊ |
96 | ␉bzero(var->ptr,size);␊ |
97 | ␉if (ptr) ␊ |
98 | ␉␉memcpy(var->ptr, ptr, size);␊ |
99 | return 1;␊ |
100 | }␊ |
101 | ␊ |
102 | static struct env_struct *find_env(const char *name) {␊ |
103 | struct env_struct *var = NULL; ␊ |
104 | ␉CEXCEPTION_T e = CEXCEPTION_NONE;␊ |
105 | ␉␊ |
106 | ␉Try␊ |
107 | ␉{␊ |
108 | ␉␉HASH_FIND_STR( platform_env, name, var ); ␊ |
109 | ␉}␊ |
110 | ␉Catch(e)␊ |
111 | ␉{␊ |
112 | #if DEBUG_PLATFORM␊ |
113 | ␉␉printf("find_env: Unable to find environement variable\n"); ␊ |
114 | getc();␊ |
115 | #endif␊ |
116 | ␉}␊ |
117 | return var;␊ |
118 | }␊ |
119 | ␊ |
120 | static void _re_set_env_ptr(struct env_struct *var , void* ptr,size_t size) {␊ |
121 | ␊ |
122 | ␉if (var->Type == kEnvPtr) {␊ |
123 | ␉␉return ;␊ |
124 | ␉} ␊ |
125 | ␊ |
126 | if (var->ptr) {␊ |
127 | free(var->ptr);␊ |
128 | var->ptr = NULL;␊ |
129 | }␊ |
130 | ␊ |
131 | SetVarPtr(var, ptr, size);␊ |
132 | ␉␊ |
133 | ␉return; ␊ |
134 | }␊ |
135 | ␊ |
136 | void re_set_env_ptr(const char *name , void* ptr,size_t size) {␊ |
137 | ␉struct env_struct *var;␊ |
138 | ␊ |
139 | ␉var = find_env(name);␊ |
140 | ␉if (!var|| (var->Type == kEnvPtr)) {␊ |
141 | ␉␉printf("re_set_env_ptr: Unable to find environement variable %s\n",name);␊ |
142 | #if DEBUG_PLATFORM␊ |
143 | getc();␊ |
144 | #endif␊ |
145 | ␉␉return ;␊ |
146 | ␉} ␊ |
147 | ␊ |
148 | _re_set_env_ptr(var , ptr, size);␊ |
149 | ␉␊ |
150 | ␉return; ␊ |
151 | }␊ |
152 | ␊ |
153 | static void _set_env(const char *name, unsigned long long value, enum envtype Type, void* ptr, size_t size ) {␊ |
154 | struct env_struct *var;␊ |
155 | ␊ |
156 | var = (struct env_struct*)malloc(sizeof(struct env_struct));␊ |
157 | if (!var) {␊ |
158 | return;␊ |
159 | }␊ |
160 | ␉bzero(var,sizeof(struct env_struct));␊ |
161 | ␉␊ |
162 | if (Type == kEnvPtr) {␊ |
163 | if (!SetVarPtr( var, ptr, size)) ␊ |
164 | ␉␉{␊ |
165 | ␉␉␉free(var);␊ |
166 | ␉␉␉return;␊ |
167 | ␉␉}␊ |
168 | } ␊ |
169 | else if (Type == kEnvValue) ␊ |
170 | var->value = value;␊ |
171 | else␊ |
172 | ␉{␊ |
173 | ␉␉free(var);␊ |
174 | return;␊ |
175 | ␉}␊ |
176 | ␊ |
177 | var->Type = Type; ␊ |
178 | ␊ |
179 | var->name = newString(name);␊ |
180 | if (!var->name) { ␊ |
181 | ␉␉if (Type == kEnvPtr && var->ptr) free(var->ptr);␊ |
182 | free(var);␊ |
183 | return;␊ |
184 | }␊ |
185 | ␉␊ |
186 | ␉CEXCEPTION_T e = CEXCEPTION_NONE;␊ |
187 | ␉␊ |
188 | ␉Try␊ |
189 | ␉{␊ |
190 | ␉␉HASH_ADD_KEYPTR( hh, platform_env, name, strlen(var->name), var );␊ |
191 | ␉}␊ |
192 | ␉Catch(e)␊ |
193 | ␉{␊ |
194 | ␉␉printf("_set_env: Unable to set environement variable"); // don't try to acces to the string 'name', ␊ |
195 | ␉␉//'cause we just returned from the longjump, stack as already changed state.␊ |
196 | #if DEBUG_PLATFORM␊ |
197 | ␉␉getc();␊ |
198 | #endif␊ |
199 | ␉␉if (Type == kEnvPtr && var->ptr) free(var->ptr);␊ |
200 | ␉␉free(var->name);␊ |
201 | ␉␉free(var);␊ |
202 | ␉␉␊ |
203 | ␉}␉␊ |
204 | }␊ |
205 | ␊ |
206 | /* Warning: set_env will create a new variable each time it will be called, ␊ |
207 | * if you want to set again an existing variable, please use safe_set_env or re_set_env .␊ |
208 | * NOTE: If you set several times the "same variable" by using this function,␊ |
209 | * the HASH_COUNT will grow up, ␊ |
210 | * but hopefully find_env will return the last variable that you have set with the same name␊ |
211 | * ex: set_env("test",10);␊ |
212 | * set_env("test",20);␊ |
213 | *␊ |
214 | * HASH_COUNT will be equal to 2, get_env("test") will return 20␊ |
215 | *␊ |
216 | * safe_set_env("test",10);␊ |
217 | * safe_set_env("test",20);␊ |
218 | * ␊ |
219 | * HASH_COUNT will be equal to 1, get_env("test") will return 20␊ |
220 | *␊ |
221 | * set_env("test",10);␊ |
222 | * re_set_env("test",20);␊ |
223 | *␊ |
224 | * HASH_COUNT will be equal to 1, get_env("test") will return 20␊ |
225 | *␊ |
226 | */␊ |
227 | void set_env(const char *name, unsigned long long value ) {␊ |
228 | _set_env(name, value, kEnvValue,0,0);␊ |
229 | }␊ |
230 | ␊ |
231 | int set_env_ptr(const char *name, void * ptr, size_t size ) {␊ |
232 | _set_env(name, 0, kEnvPtr,ptr,size);␊ |
233 | ␉return 0;␊ |
234 | }␊ |
235 | ␊ |
236 | unsigned long long get_env_value(const char *name) {␊ |
237 | ␉struct env_struct *var;␊ |
238 | ␊ |
239 | ␉var = find_env(name);␊ |
240 | ␉if (!var) {␊ |
241 | #if DEBUG_PLATFORM␊ |
242 | ␉␉printf("get_env_value: Unable to find environement variable %s\n",name);␊ |
243 | getc();␊ |
244 | #endif␊ |
245 | ␉␉return 0;␊ |
246 | ␉}␊ |
247 | ␊ |
248 | if (var->Type != kEnvValue) {␊ |
249 | printf("get_env_value: Variable %s is not a value\n",name);␊ |
250 | #if DEBUG_PLATFORM␊ |
251 | getc();␊ |
252 | #endif␊ |
253 | return 0;␊ |
254 | }␊ |
255 | ␉␊ |
256 | ␉return var->value;␊ |
257 | ␊ |
258 | }␊ |
259 | ␊ |
260 | unsigned long long get_env(const char *name) {␉␊ |
261 | ␉␊ |
262 | ␉return get_env_value(name);␊ |
263 | ␊ |
264 | }␊ |
265 | ␊ |
266 | void * get_env_ptr(const char *name) {␊ |
267 | ␉struct env_struct *var;␊ |
268 | ␊ |
269 | ␉var = find_env(name);␊ |
270 | ␉if (!var) {␊ |
271 | #if DEBUG_PLATFORM␊ |
272 | ␉␉printf("get_env_ptr: Unable to get environement ptr variable %s\n",name);␊ |
273 | getc();␊ |
274 | #endif␊ |
275 | ␉␉return 0;␊ |
276 | ␉}␊ |
277 | ␊ |
278 | if (var->Type != kEnvPtr) {␊ |
279 | printf("get_env_ptr: Variable %s is not a ptr\n",name);␊ |
280 | #if DEBUG_PLATFORM␊ |
281 | getc();␊ |
282 | #endif␊ |
283 | return 0;␊ |
284 | }␊ |
285 | ␉␊ |
286 | ␉return var->ptr;␊ |
287 | ␊ |
288 | }␊ |
289 | ␊ |
290 | /* If no specified variable exist, safe_set_env will create one, else it only modify the value */␊ |
291 | static void _safe_set_env(const char *name, unsigned long long value, enum envtype Type, void* ptr, size_t size )␊ |
292 | {␊ |
293 | ␉struct env_struct *var;␊ |
294 | ␊ |
295 | ␉var = find_env(name);␊ |
296 | ␊ |
297 | if (!var) {␊ |
298 | if (Type == kEnvPtr) {␊ |
299 | _set_env(name, 0, kEnvPtr,ptr,size);␊ |
300 | } ␊ |
301 | else if (Type == kEnvValue) {␊ |
302 | _set_env(name, value, kEnvValue,0,0);␊ |
303 | }␊ |
304 | } ␊ |
305 | else if (var->Type != Type) {␊ |
306 | return; ␊ |
307 | ␉} ␊ |
308 | else {␊ |
309 | if (Type == kEnvValue) ␊ |
310 | var->value = value;␊ |
311 | else if (Type == kEnvPtr)␊ |
312 | _re_set_env_ptr(var,ptr,size); ␊ |
313 | }␊ |
314 | ␉␊ |
315 | ␉return; ␊ |
316 | }␊ |
317 | ␊ |
318 | int safe_set_env_ptr(const char *name , void * ptr, size_t size ) {␊ |
319 | ␊ |
320 | _safe_set_env(name, 0, kEnvPtr,ptr,size);␊ |
321 | ␉␊ |
322 | ␉return 0;␊ |
323 | }␊ |
324 | ␊ |
325 | void safe_set_env(const char *name , unsigned long long value) {␊ |
326 | ␊ |
327 | _safe_set_env(name, value, kEnvValue,0,0);␊ |
328 | ␉␊ |
329 | ␉return; ␊ |
330 | }␊ |
331 | ␊ |
332 | void re_set_env(const char *name , unsigned long long value) {␊ |
333 | ␉struct env_struct *var;␊ |
334 | ␊ |
335 | ␉var = find_env(name);␊ |
336 | ␉if (!var || (var->Type == kEnvValue)) {␊ |
337 | ␉␉printf("re_set_env: Unable to reset environement value variable %s\n",name);␊ |
338 | #if DEBUG_PLATFORM␊ |
339 | getc();␊ |
340 | #endif␊ |
341 | ␉␉return ;␊ |
342 | ␉} ␊ |
343 | ␊ |
344 | var->value = value;␊ |
345 | ␉␊ |
346 | ␉return; ␊ |
347 | }␊ |
348 | ␊ |
349 | static void delete_env(struct env_struct *var) {␉␊ |
350 | ␉␊ |
351 | ␉CEXCEPTION_T e = CEXCEPTION_NONE;␊ |
352 | ␉␊ |
353 | ␉Try␊ |
354 | ␉{␊ |
355 | ␉␉HASH_DEL( platform_env, var);␊ |
356 | if (var->name) free(var->name); ␊ |
357 | ␉␉if (var->Type == kEnvPtr && var->ptr) free(var->ptr);␊ |
358 | free(var);␊ |
359 | ␉}␊ |
360 | ␉Catch(e)␊ |
361 | ␉{␊ |
362 | ␉␉printf("delete_env: Unable to delete environement variable\n");␊ |
363 | #if DEBUG_PLATFORM␊ |
364 | getc();␉␊ |
365 | #endif␊ |
366 | ␉}␊ |
367 | }␊ |
368 | ␊ |
369 | void unset_env(const char *name) {␊ |
370 | struct env_struct *var;␊ |
371 | ␊ |
372 | if ((var = find_env(name))) {␊ |
373 | delete_env(var);␊ |
374 | } ␊ |
375 | }␊ |
376 | ␊ |
377 | void free_platform_env(void) {␊ |
378 | struct env_struct *current_var, *tmp; ␊ |
379 | ␉CEXCEPTION_T e = CEXCEPTION_NONE;␊ |
380 | ␉␊ |
381 | ␉Try␊ |
382 | ␉{␊ |
383 | ␉␉HASH_ITER(hh, platform_env, current_var, tmp) { ␊ |
384 | ␉␉␉HASH_DEL(platform_env,current_var);␊ |
385 | if (current_var->name) free(current_var->name);␊ |
386 | ␉␉␉if (current_var->Type == kEnvPtr && current_var->ptr) free(current_var->ptr);␊ |
387 | ␉␉␉␊ |
388 | ␉␉}␊ |
389 | ␉␉free(current_var);␊ |
390 | ␉}␊ |
391 | ␉Catch(e)␊ |
392 | ␉{␊ |
393 | ␉␉printf("free_platform_env: Unable to delete all environement variables\n"); ␊ |
394 | #if DEBUG_PLATFORM␊ |
395 | ␉␉getc();␊ |
396 | #endif␊ |
397 | ␉}␊ |
398 | }␊ |
399 | ␊ |
400 | #if DEBUG_PLATFORM␊ |
401 | void debug_platform_env(void)␊ |
402 | {␊ |
403 | struct env_struct *current_var;␊ |
404 | for(current_var=platform_env;current_var;current_var=(struct env_struct*)(current_var->hh.next)) ␊ |
405 | {␊ |
406 | #if DEBUG_PLATFORM >= 2␊ |
407 | if (current_var->Type == kEnvValue)␊ |
408 | printf(" Name = %s | Type = VALUE | Value = 0x%04x\n",current_var->name,(uint32_t)current_var->value);␊ |
409 | else if (current_var->Type == kEnvPtr )␊ |
410 | printf(" Name = %s | Type = PTR(Copy) | Value = 0x%x\n",current_var->name,(uint32_t)current_var->ptr);␊ |
411 | #else␊ |
412 | ␊ |
413 | if (current_var->Type == kEnvValue)␊ |
414 | printf("%s: 0x%04x\n",current_var->name,(uint32_t)current_var->value);␊ |
415 | else if (current_var->Type == kEnvPtr )␊ |
416 | printf("%s(ptr): 0x%x\n",current_var->name,(uint32_t)current_var->ptr);␊ |
417 | #endif␊ |
418 | ␊ |
419 | }␊ |
420 | getc();␊ |
421 | }␊ |
422 | #endif␊ |
423 | ␊ |
424 | void showError(void)␊ |
425 | {␊ |
426 | struct env_struct *current_var;␊ |
427 | for(current_var=platform_env;current_var;current_var=(struct env_struct*)(current_var->hh.next)) ␊ |
428 | {␊ |
429 | ␉␉if (strncmp(current_var->name, envConsoleErr, sizeof(envConsoleErr)) == 0) {␊ |
430 | ␉␉␉if (current_var->Type == kEnvPtr) {␊ |
431 | ␉␉␉␉printf("stderr: %s \n",(char*)(uint32_t)current_var->ptr);␊ |
432 | ␉␉␉}␊ |
433 | ␉␉} ␊ |
434 | }␊ |
435 | }␊ |
436 | ␊ |
437 | /** ␊ |
438 | Scan platform hardware information, called by the main entry point (common_boot() ) ␊ |
439 | _before_ bootConfig xml parsing settings are loaded␊ |
440 | */␊ |
441 | void scan_platform(void)␊ |
442 | {␉␊ |
443 | ␉build_pci_dt();␊ |
444 | ␉scan_cpu();␊ |
445 | ␊ |
446 | #if DEBUG_PLATFORM_CPU␊ |
447 | printf("CPU: %s\n", (char*)get_env_ptr(envBrandString));␊ |
448 | if (get_env(envVendor) == CPUID_VENDOR_AMD)␊ |
449 | printf("CPU: Vendor/Model/ExtModel: 0x%x/0x%x/0x%x\n", (uint32_t)get_env(envVendor), (uint32_t)get_env(envModel), (uint32_t)get_env(envExtModel));␊ |
450 | ␉printf("CPU: Family/ExtFamily: 0x%x/0x%x\n", (uint32_t)get_env(envFamily), (uint32_t)get_env(envExtFamily));␊ |
451 | if (get_env(envVendor) == CPUID_VENDOR_AMD) {␊ |
452 | printf("CPU (AMD): TSCFreq: %dMHz\n", (uint32_t)(get_env(envTSCFreq) / 1000000));␊ |
453 | printf("CPU (AMD): FSBFreq: %dMHz\n", (uint32_t)(get_env(envFSBFreq) / 1000000));␊ |
454 | printf("CPU (AMD): CPUFreq: %dMHz\n", (uint32_t)(get_env(envCPUFreq) / 1000000));␊ |
455 | printf("CPU (AMD): MaxCoef/CurrCoef: 0x%x/0x%x\n", (uint32_t)get_env(envMaxCoef), (uint32_t)get_env(envCurrCoef));␊ |
456 | printf("CPU (AMD): MaxDiv/CurrDiv: 0x%x/0x%x\n", (uint32_t)get_env(envMaxDiv), (uint32_t)get_env(envCurrDiv));␊ |
457 | } else if (get_env(envVendor) == CPUID_VENDOR_INTEL){␊ |
458 | printf("CPU: TSCFreq: %dMHz\n", (uint32_t)(get_env(envTSCFreq) / 1000000));␊ |
459 | printf("CPU: FSBFreq: %dMHz\n", (uint32_t)(get_env(envFSBFreq) / 1000000));␊ |
460 | printf("CPU: CPUFreq: %dMHz\n", (uint32_t)(get_env(envCPUFreq) / 1000000));␊ |
461 | printf("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", (uint32_t)(get_env(envMaxCoef)), (uint32_t)(get_env(envCurrCoef)));␊ |
462 | printf("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", (uint32_t)(get_env(envMaxDiv)), (uint32_t)(get_env(envCurrDiv)));␊ |
463 | }␉␉␉␊ |
464 | ␉␊ |
465 | ␉printf("CPU: NoCores/NoThreads: %d/%d\n", (uint32_t)(get_env(envNoCores)), (uint32_t)(get_env(envNoThreads)));␊ |
466 | ␉printf("CPU: Features: 0x%08x\n", (uint32_t)(get_env(envFeatures)));␊ |
467 | printf("CPU: ExtFeatures: 0x%08x\n", (uint32_t)(get_env(envExtFeatures)));␊ |
468 | #ifndef AMD_SUPPORT␊ |
469 | printf("CPU: MicrocodeVersion: %d\n", (uint32_t)(get_env(envMicrocodeVersion)));␊ |
470 | #endif␊ |
471 | pause();␊ |
472 | #endif␊ |
473 | } |