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