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

Archive Download this file

Revision: 1887