Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/platform.c

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
23static char *gboardproduct = NULL;
24static char *gPlatformName = NULL;
25static char *gRootDevice = NULL;
26
27void SetgRootDevice(const char * str)
28{
29 gRootDevice = (char*)str;
30}
31void Setgboardproduct(const char * str)
32{
33 gboardproduct = (char*)str;
34}
35void SetgPlatformName(const char * str)
36{
37 gPlatformName = (char*)str;
38}
39
40char * GetgPlatformName(void)
41{
42 return gPlatformName ;
43}
44char * Getgboardproduct(void)
45{
46 return gboardproduct;
47}
48char * GetgRootDevice(void)
49{
50 return gRootDevice;
51}
52
53#ifdef rootpath
54static char gRootPath[ROOT_PATH_LEN];
55void SetgRootPath(const char * str)
56{
57 bzero(gRootPath,sizeof(gRootPath));
58 memcpy(gRootPath,str, sizeof(gRootPath));
59}
60char * GetgRootPath(void)
61{
62 return gRootPath ;
63}
64#endif
65
66typedef enum envtype {
67 kEnvPtr = 0,
68 kEnvValue = 1
69} envtype;
70
71struct env_struct {
72 unsigned long long value;
73 char *name;
74 void * ptr;
75 //int lock;
76 enum envtype Type;
77 UT_hash_handle hh; /* makes this structure hashable */
78};
79
80static int CopyVarPtr (struct env_struct *var, void* ptr, size_t size);
81static struct env_struct *find_env(const char *name);
82static void _re_set_env_copy(struct env_struct *var , void* ptr,size_t size);
83struct env_struct *platform_env = NULL;
84
85
86static int CopyVarPtr (struct env_struct *var, void* ptr, size_t size)
87{
88 var->ptr = malloc(size);
89 if (!var->ptr) {
90 return 0;
91 }
92 memcpy(var->ptr, ptr, size);
93 return 1;
94}
95
96static struct env_struct *find_env(const char *name) {
97 struct env_struct *var;
98
99if (setjmp(h_buf_error) == -1) {
100#if DEBUG_PLATFORM
101printf("find_env: Unable to find environement variable\n");
102 getc();
103#endif
104return NULL;
105} else {
106HASH_FIND_STR( platform_env, name, var );
107}
108 return var;
109}
110
111static void _re_set_env_copy(struct env_struct *var , void* ptr,size_t size) {
112
113if (var->Type == kEnvPtr) {
114return ;
115}
116
117 if (var->ptr) {
118 free(var->ptr);
119 var->ptr = NULL;
120 }
121
122 CopyVarPtr(var, ptr, size);
123
124return;
125}
126
127void re_set_env_copy(const char *name , void* ptr,size_t size) {
128struct env_struct *var;
129
130var = find_env(name);
131if (!var|| (var->Type == kEnvPtr)) {
132printf("re_set_env_copy: Unable to find environement variable %s\n",name);
133#if DEBUG_PLATFORM
134 getc();
135#endif
136return ;
137}
138
139 _re_set_env_copy(var , ptr, size);
140
141return;
142}
143
144static void _set_env(const char *name, unsigned long long value, enum envtype Type, void* ptr, size_t size ) {
145 struct env_struct *var;
146
147 var = (struct env_struct*)malloc(sizeof(struct env_struct));
148 if (!var) {
149 return;
150 }
151 if (Type == kEnvPtr) {
152 if (!CopyVarPtr( var, ptr, size)) return;
153 }
154 else if (Type == kEnvValue)
155 var->value = value;
156 else
157 return;
158
159 var->Type = Type;
160
161 var->name = newString(name);
162 if (!var->name) {
163 free(var);
164 return;
165 }
166
167if (setjmp(h_buf_error) == -1) {
168printf("_set_env: Unable to set environement variable"); // don't try to acces to the string 'name',
169//'cause we just returned from the longjump, stack as already changed state.
170#if DEBUG_PLATFORM
171getc();
172#endif
173return;
174} else {
175 HASH_ADD_KEYPTR( hh, platform_env, name, strlen(var->name), var );
176}
177}
178
179/* Warning: set_env will create a new variable each time it will be called,
180 * if you want to set again an existing variable, please use safe_set_env or re_set_env .
181 * NOTE: If you set several times the "same variable" by using this function,
182 * the HASH_COUNT will grow up,
183 * but hopefully find_env will return the last variable that you have set with the same name
184 * ex: set_env("test",10);
185 * set_env("test",20);
186 *
187 * HASH_COUNT will be equal to 2, get_env("test") will return 20
188 *
189 * safe_set_env("test",10);
190 * safe_set_env("test",20);
191 *
192 * HASH_COUNT will be equal to 1, get_env("test") will return 20
193 *
194 * set_env("test",10);
195 * re_set_env("test",20);
196 *
197 * HASH_COUNT will be equal to 1, get_env("test") will return 20
198 *
199 */
200void set_env(const char *name, unsigned long long value ) {
201 _set_env(name, value, kEnvValue,0,0);
202}
203
204void set_env_copy(const char *name, void * ptr, size_t size ) {
205 _set_env(name, 0, kEnvPtr,ptr,size);
206}
207
208unsigned long long get_env_var(const char *name) {
209struct env_struct *var;
210
211var = find_env(name);
212if (!var) {
213#if DEBUG_PLATFORM
214printf("get_env_var: Unable to find environement variable %s\n",name);
215 getc();
216#endif
217return 0;
218}
219
220 if (var->Type != kEnvValue) {
221 printf("get_env_var: Variable %s is not a value\n",name);
222#if DEBUG_PLATFORM
223 getc();
224#endif
225 return 0;
226 }
227
228return var->value;
229
230}
231
232unsigned long long get_env(const char *name) {
233
234return get_env_var(name);;
235
236}
237
238void * get_env_ptr(const char *name) {
239struct env_struct *var;
240
241var = find_env(name);
242if (!var) {
243#if DEBUG_PLATFORM
244printf("get_env_ptr: Unable to get environement ptr variable %s\n",name);
245 getc();
246#endif
247return 0;
248}
249
250 if (var->Type != kEnvPtr) {
251 printf("get_env_ptr: Variable %s is not a ptr\n",name);
252#if DEBUG_PLATFORM
253 getc();
254#endif
255 return 0;
256 }
257
258return var->ptr;
259
260}
261
262/* If no specified variable exist, safe_set_env will create one, else it only modify the value */
263static void _safe_set_env(const char *name, unsigned long long value, enum envtype Type, void* ptr, size_t size )
264{
265struct env_struct *var;
266
267var = find_env(name);
268
269 if (!var) {
270 if (Type == kEnvPtr) {
271 _set_env(name, 0, kEnvPtr,ptr,size);
272 }
273 else if (Type == kEnvValue) {
274 _set_env(name, value, kEnvValue,0,0);
275 }
276 }
277 else if (var->Type != Type) {
278 return;
279}
280 else {
281 if (Type == kEnvValue)
282 var->value = value;
283 else if (Type == kEnvPtr)
284 _re_set_env_copy(var,ptr,size);
285 }
286
287return;
288}
289
290void safe_set_env_copy(const char *name , void * ptr, size_t size ) {
291
292 _safe_set_env(name, 0, kEnvPtr,ptr,size);
293
294return;
295}
296
297void safe_set_env(const char *name , unsigned long long value) {
298
299 _safe_set_env(name, value, kEnvValue,0,0);
300
301return;
302}
303
304void re_set_env(const char *name , unsigned long long value) {
305struct env_struct *var;
306
307var = find_env(name);
308if (!var || (var->Type == kEnvValue)) {
309printf("re_set_env: Unable to reset environement value variable %s\n",name);
310#if DEBUG_PLATFORM
311 getc();
312#endif
313return ;
314}
315
316 var->value = value;
317
318return;
319}
320
321static void delete_env(struct env_struct *var) {
322
323if (setjmp(h_buf_error) == -1) {
324printf("delete_env: Unable to delete environement variable\n");
325#if DEBUG_PLATFORM
326 getc();
327#endif
328return;
329} else {
330HASH_DEL( platform_env, var);
331 if (var->name) free(var->name);
332 free(var);
333
334}
335}
336
337void unset_env(const char *name) {
338 struct env_struct *var;
339
340 if ((var = find_env(name))) {
341 delete_env(var);
342 }
343}
344
345void free_platform_env(void) {
346 struct env_struct *current_var, *tmp;
347
348if (setjmp(h_buf_error) == -1) {
349printf("free_platform_env: Unable to delete all environement variables\n");
350#if DEBUG_PLATFORM
351getc();
352#endif
353return;
354} else {
355HASH_ITER(hh, platform_env, current_var, tmp) {
356HASH_DEL(platform_env,current_var);
357 if (current_var->name) free(current_var->name);
358free(current_var);
359}
360}
361}
362
363#if DEBUG_PLATFORM
364void debug_platform_env(void)
365{
366 struct env_struct *current_var = platform_env;
367 for(current_var=platform_env;current_var;current_var=(struct env_struct*)(current_var->hh.next))
368 {
369#if DEBUG_PLATFORM >= 2
370 if (current_var->Type == kEnvValue)
371 printf(" Name = %s | Type = VALUE | Value = 0x%04x\n",current_var->name,(uint32_t)current_var->value);
372 else if (current_var->Type == kEnvPtr )
373 printf(" Name = %s | Type = PTR(Copy) | Value = 0x%x\n",current_var->name,(uint32_t)current_var->ptr);
374#else
375
376 if (current_var->Type == kEnvValue)
377 printf("%s: 0x%04x\n",current_var->name,(uint32_t)current_var->value);
378 else if (current_var->Type == kEnvPtr )
379 printf("%s(ptr): 0x%x\n",current_var->name,(uint32_t)current_var->ptr);
380#endif
381
382 }
383 getc();
384}
385#endif
386
387/**
388 Scan platform hardware information, called by the main entry point (common_boot() )
389 _before_ bootConfig xml parsing settings are loaded
390 */
391void scan_platform(void)
392{
393//memset(&Platform, 0, sizeof(PlatformInfo_t));
394build_pci_dt();
395scan_cpu();
396
397#if DEBUG_PLATFORM
398 DBG("CPU: %s\n", (char*)get_env_ptr(envBrandString));
399 if (get_env(envVendor) == CPUID_VENDOR_AMD)
400 DBG("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));
401DBG("CPU: Family/ExtFamily: 0x%x/0x%x\n", (uint32_t)get_env(envFamily), (uint32_t)get_env(envExtFamily));
402 if (get_env(envVendor) == CPUID_VENDOR_AMD) {
403 DBG("CPU (AMD): TSCFreq: %dMHz\n", (uint32_t)(get_env(envTSCFreq) / 1000000));
404 DBG("CPU (AMD): FSBFreq: %dMHz\n", (uint32_t)(get_env(envFSBFreq) / 1000000));
405 DBG("CPU (AMD): CPUFreq: %dMHz\n", (uint32_t)(get_env(envCPUFreq) / 1000000));
406 DBG("CPU (AMD): MaxCoef/CurrCoef: 0x%x/0x%x\n", (uint32_t)get_env(envMaxCoef), (uint32_t)get_env(envCurrCoef));
407 DBG("CPU (AMD): MaxDiv/CurrDiv: 0x%x/0x%x\n", (uint32_t)get_env(envMaxDiv), (uint32_t)get_env(envCurrDiv));
408 } else if (get_env(envVendor) == CPUID_VENDOR_INTEL){
409 DBG("CPU: TSCFreq: %dMHz\n", (uint32_t)(get_env(envTSCFreq) / 1000000));
410 DBG("CPU: FSBFreq: %dMHz\n", (uint32_t)(get_env(envFSBFreq) / 1000000));
411 DBG("CPU: CPUFreq: %dMHz\n", (uint32_t)(get_env(envCPUFreq) / 1000000));
412 DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", (uint32_t)(get_env(envMaxCoef)), (uint32_t)(get_env(envCurrCoef)));
413 DBG("CPU: MaxDiv/CurrDiv: 0x%x/0x%x\n", (uint32_t)(get_env(envMaxDiv)), (uint32_t)(get_env(envCurrDiv)));
414 }
415
416DBG("CPU: NoCores/NoThreads: %d/%d\n", (uint32_t)(get_env(envNoCores)), (uint32_t)(get_env(envNoThreads)));
417DBG("CPU: Features: 0x%08x\n", (uint32_t)(get_env(envFeatures)));
418 DBG("CPU: ExtFeatures: 0x%08x\n", (uint32_t)(get_env(envExtFeatures)));
419#ifndef AMD_SUPPORT
420 DBG("CPU: MicrocodeVersion: %d\n", (uint32_t)(get_env(envMicrocodeVersion)));
421#endif
422 pause();
423#endif
424}
425
426#ifdef ShowCurrentDate
427
428// shamefully ripped to http://wiki.osdev.org/CMOS
429
430/*
431 * http://wiki.osdev.org/OSDev_Wiki:General_disclaimer
432 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
433 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
434 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
435 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
436 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
437 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
438 * THE SOFTWARE.
439 */
440
441#define CURRENT_YEAR 2012 // Change this each year!
442
443static int century_register = 0x00; // Set by ACPI table parsing code if possible(... in FADT table)
444
445enum {
446 cmos_address = 0x70,
447 cmos_data = 0x71
448};
449
450
451static int get_update_in_progress_flag() {
452 outb(cmos_address, 0x0A);
453 return (inb(cmos_data) & 0x80);
454}
455
456
457static unsigned char get_RTC_register(int reg) {
458 outb(cmos_address, reg);
459 return inb(cmos_data);
460}
461
462static void read_rtc(EFI_TIME *time) {
463 unsigned char century;
464 unsigned char last_second;
465 unsigned char last_minute;
466 unsigned char last_hour;
467 unsigned char last_day;
468 unsigned char last_month;
469 unsigned char last_year;
470 unsigned char last_century;
471 unsigned char registerB;
472
473 unsigned char second;
474 unsigned char minute;
475 unsigned char hour;
476 unsigned char day;
477 unsigned char month;
478 unsigned int year;
479 // Note: This uses the "read registers until you get the same values twice in a row" technique
480 // to avoid getting dodgy/inconsistent values due to RTC updates
481
482 while (get_update_in_progress_flag()); // Make sure an update isn't in progress
483 second = get_RTC_register(0x00);
484 minute = get_RTC_register(0x02);
485 hour = get_RTC_register(0x04);
486 day = get_RTC_register(0x07);
487 month = get_RTC_register(0x08);
488 year = get_RTC_register(0x09);
489 if(century_register != 0) {
490 century = get_RTC_register(century_register);
491 }
492
493 do {
494 last_second = second;
495 last_minute = minute;
496 last_hour = hour;
497 last_day = day;
498 last_month = month;
499 last_year = year;
500 last_century = century;
501
502 while (get_update_in_progress_flag()); // Make sure an update isn't in progress
503 second = get_RTC_register(0x00);
504 minute = get_RTC_register(0x02);
505 hour = get_RTC_register(0x04);
506 day = get_RTC_register(0x07);
507 month = get_RTC_register(0x08);
508 year = get_RTC_register(0x09);
509 if(century_register != 0) {
510 century = get_RTC_register(century_register);
511 }
512 } while( (last_second == second) && (last_minute == minute) && (last_hour == hour) &&
513 (last_day == day) && (last_month == month) && (last_year == year) &&
514 (last_century == century) );
515
516 registerB = get_RTC_register(0x0B);
517
518 // Convert BCD to binary values if necessary
519
520 if (!(registerB & 0x04)) {
521 second = (second & 0x0F) + ((second / 16) * 10);
522 minute = (minute & 0x0F) + ((minute / 16) * 10);
523 hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80);
524 day = (day & 0x0F) + ((day / 16) * 10);
525 month = (month & 0x0F) + ((month / 16) * 10);
526 year = (year & 0x0F) + ((year / 16) * 10);
527 if(century_register != 0) {
528 century = (century & 0x0F) + ((century / 16) * 10);
529 }
530 }
531
532 // Calculate the full (4-digit) year
533
534 if(century_register != 0) {
535 year += century * 100;
536 } else {
537 //year += (CURRENT_YEAR / 100) * 100;
538 //if(year < CURRENT_YEAR) year += 100;
539
540 if ((year += 1900) < 1970)
541 year += 100;
542 }
543
544 time->Second = second;
545 time->Minute = minute;
546 time->Hour = hour;
547 time->Day = day;
548 time->Month = month;
549 time->Year = year;
550}
551
552void rtc_time(EFI_TIME *time) {
553
554 read_rtc(time);
555
556 time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
557
558 return ;
559}
560
561char * Date(void)
562{
563 EFI_TIME rtctime;
564 rtc_time(&rtctime);
565
566 return newStringWithFormat("%02d/%02d/%04d %02d:%02d:%02d",rtctime.Month,rtctime.Day,rtctime.Year,
567 rtctime.Hour,rtctime.Minute,rtctime.Second);
568}
569#endif

Archive Download this file

Revision: 1919