Chameleon

Chameleon Commit Details

Date:2010-03-18 13:38:54 (9 years 3 months ago)
Author:DieBuche
Commit:129
Parents: 128
Message:Patching my branch. Added typo fixes.
Changes:
M/branches/diebuche/i386/boot2/gui.c
M/branches/diebuche/i386/libsaio/915resolution.c

File differences

branches/diebuche/version
1
1
2.0-RC5pre9special
2.0-RC5pre11
branches/diebuche/CHANGES
1
12
23
34
- Implemented SPD memory automatic detection and injection,seems to work really great ...
- Factorized code to prepare a dynamic memory detection algorithm ...
- Optimized smbios table address search
- Optimized cursor spinout in textmode if no verbose mode is set
branches/diebuche/i386/libsaio/ATIresolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
/* Copied from 915 resolution created by steve tomljenovic
* This source code is into the public domain.
*
* Included to Chameleon RC3 by meklort
*
* Included to RC4 and edited by deviato to match more intel chipsets
*
*/
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#include "libsaio.h"
#include "ATIresolution.h"
char * chipset_type_names[] = {
"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
"946GZ", "G965", "Q965", "965GM", "G41", "G31", "G45", "GM45", "500"
};
char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
int freqs[] = { 60, 75, 85 };
UInt32 get_chipset_id(void) {
outl(0xcf8, 0x80000000);
return inl(0xcfc);
}
chipset_type get_chipset(UInt32 id) {
chipset_type type;
switch (id) {
case 0x35758086:
type = CT_830;
break;
case 0x25608086:
type = CT_845G;
break;
case 0x35808086:
type = CT_855GM;
break;
case 0x25708086:
type = CT_865G;
break;
case 0x25808086:
type = CT_915G;
break;
case 0x25908086:
type = CT_915GM;
break;
case 0x27708086:
type = CT_945G;
break;
case 0x27a08086:
type = CT_945GM;
break;
case 0x27ac8086:
type = CT_945GME;
break;
case 0x29708086:
type = CT_946GZ;
break;
case 0x29a08086:
type = CT_G965;
break;
case 0x29908086:
type = CT_Q965;
break;
case 0x2a008086:
type = CT_965GM;
break;
case 0x2a408086:
type = CT_GM45;
break;
case 0x2e308086:
type = CT_G41;
break;
case 0x29c08086:
type = CT_G31;
break;
case 0x2e208086:
type = CT_G45;
break;
case 0x81008086:
type = CT_500;
break;
default:
type = CT_UNKWN;
break;
}
return type;
}
vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
return ptr;
}
vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {
vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
return ptr;
}
char detect_bios_type(vbios_map * map, char modeline, int entry_size) {
UInt32 i;
UInt16 r1, r2;
r1 = r2 = 32000;
for (i=0; i < map->mode_table_size; i++) {
if (map->mode_table[i].resolution <= r1) {
r1 = map->mode_table[i].resolution;
}
else {
if (map->mode_table[i].resolution <= r2) {
r2 = map->mode_table[i].resolution;
}
}
/*printf("r1 = %d r2 = %d\n", r1, r2);*/
}
return (r2-r1-6) % entry_size == 0;
}
void close_vbios(vbios_map * map);
vbios_map * open_vbios(chipset_type forced_chipset) {
UInt32 z;
vbios_map * map = NEW(vbios_map);
for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
/*
* Determine chipset
*/
if (forced_chipset == CT_UNKWN) {
map->chipset_id = get_chipset_id();
map->chipset = get_chipset(map->chipset_id);
}
else if (forced_chipset != CT_UNKWN) {
map->chipset = forced_chipset;
}
else {
map->chipset = CT_915GM;
}
/*
* Map the video bios to memory
*/
map->bios_ptr=(char*)VBIOS_START;
/*
* check if we have ATI Radeon
if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
printf("ATI chipset detected. \n");
printf("Chipset Id: %x\n", map->chipset_id);
return 0;
}*/
/*
* check if we have NVIDIA
*/
/*
* check if we have Intel
*/
/*
* check for others
*/
if (map->chipset == CT_UNKWN) {
printf("Unknown chipset type and unrecognized bios.\n");
printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");
printf("Chipset Id: %x\n", map->chipset_id);
close_vbios(map);
return 0;
}
/*
* Figure out where the mode table is
*/
{
char* p = map->bios_ptr + 16;
char* limit = map->bios_ptr + VBIOS_SIZE;
while (p < limit && map->mode_table == 0) {
vbios_mode * mode_ptr = (vbios_mode *) p;
if ((mode_ptr[0].mode == 0x20) && (mode_ptr[1].mode == 0x03) &&
(mode_ptr[4].mode == 0x58) && (mode_ptr[5].mode == 0x02)) {
printf("We are onto something.\n");
map->mode_table = mode_ptr;
}
p++;
}
if (map->mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("Size: %d\n", sizeof(vbios_map));
close_vbios(map);
getc();
return 0;
}
}
/*
* Determine size of mode table
*/
{
vbios_mode * mode_ptr = map->mode_table;
while (mode_ptr->mode != 0xff) {
map->mode_table_size++;
mode_ptr++;
}
}
/*
* Figure out what type of bios we have
* order of detection is important
*/
if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
map->bios = BT_3;
}
else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
map->bios = BT_2;
}
else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
map->bios = BT_1;
}
else {
printf("Unable to determine bios type.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
printf("Mode Table Entries: %u\n", map->mode_table_size);
getc();
//THis is now
return 0;
}
return map;
}
void close_vbios(vbios_map * map) {
FREE(map);
}
void unlock_vbios(vbios_map * map) {
map->unlocked = TRUE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
map->b1 = inb(0xcfe);
outl(0xcf8, 0x8000005a);
outb(0xcfe, 0x33);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
map->b1 = inb(0xcfd);
map->b2 = inb(0xcfe);
outl(0xcf8, 0x80000090);
outb(0xcfd, 0x33);
outb(0xcfe, 0x33);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("unlock PAM: (0x%08x)\n", t);
}
#endif
}
void relock_vbios(vbios_map * map) {
map->unlocked = FALSE;
switch (map->chipset) {
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
outb(0xcfe, map->b1);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x8000005a);
outb(0xcfd, map->b1);
outb(0xcfe, map->b2);
break;
}
#if DEBUG
{
UInt32 t = inl(0xcfc);
printf("relock PAM: (0x%08x)\n", t);
}
#endif
}
void list_modes(vbios_map *map, UInt32 raw) {
UInt32 i, x, y;
for (i=0; i < map->mode_table_size; i++) {
switch(map->bios) {
case BT_1:
{
vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
x = ((((UInt32) res->x2) & 0xf0) << 4) | res->x1;
y = ((((UInt32) res->y2) & 0xf0) << 4) | res->y1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
if (raw)
{
printf("Mode %02x (raw) :\n\t%02x %02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
}
}
break;
case BT_2:
{
vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
x = res->modelines[0].x1+1;
y = res->modelines[0].y1+1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
}
break;
case BT_3:
{
vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
x = res->modelines[0].x1+1;
y = res->modelines[0].y1+1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
}
break;
case BT_UNKWN:
break;
}
}
}
static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
{
UInt32 hbl, vbl, vfreq;
vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
vfreq = vbl * freq;
hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
*vsyncstart = y;
*vsyncend = y + 3;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
*clock = (x + hbl) * vfreq / 1000;
}
void set_mode(vbios_map * map, /*UInt32 mode,*/ UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
UInt32 xprev, yprev;
UInt32 i = 0, j;// patch first available mode
//for (i=0; i < map->mode_table_size; i++) {
//if (map->mode_table[0].mode == mode) {
switch(map->bios) {
case BT_1:
{
vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
if (bp) {
map->mode_table[i].bits_per_pixel = bp;
}
res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
res->x1 = (x & 0xff);
res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
res->y1 = (y & 0xff);
if (htotal)
res->x_total = ((htotal-x) & 0xff);
if (vtotal)
res->y_total = ((vtotal-y) & 0xff);
}
break;
case BT_2:
{
vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
res->xchars = x / 8;
res->ychars = y / 16 - 1;
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for(j=0; j < 3; j++) {
vbios_modeline_type2 * modeline = &res->modelines[j];
if (modeline->x1 == xprev && modeline->y1 == yprev) {
modeline->x1 = modeline->x2 = x-1;
modeline->y1 = modeline->y2 = y-1;
gtf_timings(x, y, freqs[j], &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank);
if (htotal)
modeline->htotal = htotal;
else
modeline->htotal = modeline->hblank;
if (vtotal)
modeline->vtotal = vtotal;
else
modeline->vtotal = modeline->vblank;
}
}
}
break;
case BT_3:
{
vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
xprev = res->modelines[0].x1;
yprev = res->modelines[0].y1;
for (j=0; j < 3; j++) {
vbios_modeline_type3 * modeline = &res->modelines[j];
if (modeline->x1 == xprev && modeline->y1 == yprev) {
modeline->x1 = modeline->x2 = x-1;
modeline->y1 = modeline->y2 = y-1;
gtf_timings(x, y, freqs[j], &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank);
if (htotal)
modeline->htotal = htotal;
else
modeline->htotal = modeline->hblank;
if (vtotal)
modeline->vtotal = vtotal;
else
modeline->vtotal = modeline->vblank;
modeline->timing_h = y-1;
modeline->timing_v = x-1;
}
}
}
break;
case BT_UNKWN:
break;
}
//}
//}
}
void display_map_info(vbios_map * map) {
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("BIOS: %s\n", bios_type_names[map->bios]);
printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
printf("Mode Table Entries: %u\n", map->mode_table_size);
}
branches/diebuche/i386/libsaio/ATIresolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Copied from 915 resolution created by steve tomljenovic
* This source code is into the public domain.
*
* Included to Chameleon RC3 by meklort
*
* Included to RC4 and edited by deviato to match more intel chipsets
*
*/
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#ifndef __915_RESOLUTION_H
#define __915_RESOLUTION_H
#define NEW(a) ((a *)(malloc(sizeof(a))))
#define FREE(a) (free(a))
#define FALSE 0
#define TRUE 1
#define VBIOS_START 0x0
#define VBIOS_SIZE 0x10000
//#define MODE_TABLE_OFFSET_845G 617
#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
#define ATI_SIGNATURE2 "ATI Technologies Inc"
#define NVIDIA_SIGNATURE "NVIDIA Corp"
#define INTEL_SIGNATURE "Intel Corp"
typedef enum {
CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME,
CT_946GZ, CT_G965, CT_Q965, CT_965GM, CT_GM45, CT_G41, CT_G31, CT_G45, CT_500
} chipset_type;
typedef enum {
BT_UNKWN, BT_1, BT_2, BT_3
} bios_type;
typedef struct {
UInt8 mode;
UInt8 bits_per_pixel;
UInt16 resolution;
UInt8 unknown;
} __attribute__((packed)) vbios_mode;
typedef struct {
UInt8 unknow1[2];
UInt8 x1;
UInt8 x_total;
UInt8 x2;
UInt8 y1;
UInt8 y_total;
UInt8 y2;
} __attribute__((packed)) vbios_resolution_type1;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
} __attribute__((packed)) vbios_modeline_type2;
typedef struct {
UInt8 xchars;
UInt8 ychars;
UInt8 unknown[4];
vbios_modeline_type2 modelines[];
} __attribute__((packed)) vbios_resolution_type2;
typedef struct {
unsigned long clock;
UInt16 x1;
UInt16 htotal;
UInt16 x2;
UInt16 hblank;
UInt16 hsyncstart;
UInt16 hsyncend;
UInt16 y1;
UInt16 vtotal;
UInt16 y2;
UInt16 vblank;
UInt16 vsyncstart;
UInt16 vsyncend;
UInt16 timing_h;
UInt16 timing_v;
UInt8 unknown[6];
} __attribute__((packed)) vbios_modeline_type3;
typedef struct {
unsigned char unknown[6];
vbios_modeline_type3 modelines[];
} __attribute__((packed)) vbios_resolution_type3;
typedef struct {
UInt32 chipset_id;
chipset_type chipset;
bios_type bios;
UInt32 bios_fd;
char* bios_ptr;
vbios_mode * mode_table;
UInt32 mode_table_size;
UInt8 b1, b2;
UInt8 unlocked;
} vbios_map;
void display_map_info(vbios_map*);
vbios_map * open_vbios(chipset_type);
void close_vbios (vbios_map*);
void unlock_vbios(vbios_map*);
void relock_vbios(vbios_map*);
void set_mode(vbios_map*, UInt32, UInt32, UInt32, UInt32, UInt32);
void list_modes(vbios_map *map, UInt32 raw);
#endif
branches/diebuche/i386/libsaio/shortatombios.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/****************************************************************************/
/*Portion I: Definitions shared between VBIOS and Driver */
/****************************************************************************/
#ifndef _SHORT_ATOMBIOS_H
#define _SHORT_ATOMBIOS_H
#define ATOM_VERSION_MAJOR 0x00020000
#define ATOM_VERSION_MINOR 0x00000002
#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR)
typedef unsigned charBOOLEAN;
typedef signed charINT8;
typedef unsigned charUINT8;
typedef signed shortINT16;
typedef unsigned shortUINT16;
typedef signed longINT32;
typedef unsigned longUINT32;
typedef unsigned charCHAR8;
typedef unsigned shortCHAR16;
typedef unsigned shortUSHORT;
typedef unsigned charUCHAR;
typedefunsigned longULONG;
#pragma pack(1) /* BIOS data must use byte aligment */
/* Define offset to location of ROM header. */
#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER0x00000048L
#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L
typedef struct _ATOM_COMMON_TABLE_HEADER
{
USHORT usStructureSize;
UCHAR ucTableFormatRevision; /*Change it when the Parser is not backward compatible */
UCHAR ucTableContentRevision; /*Change it only when the table needs to change but the firmware */
/*Image can't be updated, while Driver needs to carry the new table! */
}ATOM_COMMON_TABLE_HEADER;
typedef struct _ATOM_ROM_HEADER
{
ATOM_COMMON_TABLE_HEADERsHeader;
UCHAR uaFirmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios,
atombios should init it as "ATOM", don't change the position */
USHORT usBiosRuntimeSegmentAddress;
USHORT usProtectedModeInfoOffset;
USHORT usConfigFilenameOffset;
USHORT usCRC_BlockOffset;
USHORT usBIOS_BootupMessageOffset;
USHORT usInt10Offset;
USHORT usPciBusDevInitCode;
USHORT usIoBaseAddress;
USHORT usSubsystemVendorID;
USHORT usSubsystemID;
USHORT usPCI_InfoOffset;
USHORT usMasterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */
USHORT usMasterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */
UCHAR ucExtendedFunctionCode;
UCHAR ucReserved;
}ATOM_ROM_HEADER;
/****************************************************************************/
// Structure used in Data.mtb
/****************************************************************************/
typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES
{
USHORT UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position!
USHORT MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios
USHORT MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios
USHORT StandardVESA_Timing; // Only used by Bios
USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4
USHORT DAC_Info; // Will be obsolete from R600
USHORT LVDS_Info; // Shared by various SW components,latest version 1.1
USHORT TMDS_Info; // Will be obsolete from R600
USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1
USHORT SupportedDevicesInfo; // Will be obsolete from R600
USHORT GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600
USHORT VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600
USHORT GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1
USHORT VESA_ToInternalModeLUT; // Only used by Bios
USHORT ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600
USHORT PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600
USHORT CompassionateData; // Will be obsolete from R600
USHORT SaveRestoreInfo; // Only used by Bios
USHORT PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info
USHORT OemInfo; // Defined and used by external SW, should be obsolete soon
USHORT XTMDS_Info; // Will be obsolete from R600
USHORT MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used
USHORT Object_Header; // Shared by various SW components,latest version 1.1
USHORT IndirectIOAccess; // Only used by Bios,this table position can't change at all!!
USHORT MC_InitParameter; // Only used by command table
USHORT ASIC_VDDC_Info;// Will be obsolete from R600
USHORT ASIC_InternalSS_Info;// New tabel name from R600, used to be called "ASIC_MVDDC_Info"
USHORT TV_VideoMode;// Only used by command table
USHORT VRAM_Info;// Only used by command table, latest version 1.3
USHORT MemoryTrainingInfo;// Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1
USHORT IntegratedSystemInfo;// Shared by various SW components
USHORT ASIC_ProfilingInfo;// New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600
USHORT VoltageObjectInfo;// Shared by various SW components, latest version 1.1
USHORTPowerSourceInfo;// Shared by various SW components, latest versoin 1.1
}ATOM_MASTER_LIST_OF_DATA_TABLES;
typedef struct _ATOM_MASTER_DATA_TABLE
{
ATOM_COMMON_TABLE_HEADER sHeader;
ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables;
}ATOM_MASTER_DATA_TABLE;
typedef union _ATOM_MODE_MISC_INFO_ACCESS
{
USHORT usAccess;
}ATOM_MODE_MISC_INFO_ACCESS;
/****************************************************************************/
// Structure used in StandardVESA_TimingTable
// AnalogTV_InfoTable
// ComponentVideoInfoTable
/****************************************************************************/
typedef struct _ATOM_MODE_TIMING
{
USHORT usCRTC_H_Total;
USHORT usCRTC_H_Disp;
USHORT usCRTC_H_SyncStart;
USHORT usCRTC_H_SyncWidth;
USHORT usCRTC_V_Total;
USHORT usCRTC_V_Disp;
USHORT usCRTC_V_SyncStart;
USHORT usCRTC_V_SyncWidth;
USHORT usPixelClock; //in 10Khz unit
ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
USHORT usCRTC_OverscanRight;
USHORT usCRTC_OverscanLeft;
USHORT usCRTC_OverscanBottom;
USHORT usCRTC_OverscanTop;
USHORT usReserve;
UCHAR ucInternalModeNumber;
UCHAR ucRefreshRate;
}ATOM_MODE_TIMING;
typedef struct _ATOM_DTD_FORMAT
{
USHORT usPixClk;
USHORT usHActive;
USHORT usHBlanking_Time;
USHORT usVActive;
USHORT usVBlanking_Time;
USHORT usHSyncOffset;
USHORT usHSyncWidth;
USHORT usVSyncOffset;
USHORT usVSyncWidth;
USHORT usImageHSize;
USHORT usImageVSize;
UCHAR ucHBorder;
UCHAR ucVBorder;
ATOM_MODE_MISC_INFO_ACCESS susModeMiscInfo;
UCHAR ucInternalModeNumber;
UCHAR ucRefreshRate;
}ATOM_DTD_FORMAT;
typedef struct _ATOM_LVDS_INFO_V12
{
ATOM_COMMON_TABLE_HEADER sHeader;
ATOM_DTD_FORMAT sLCDTiming;
USHORT usExtInfoTableOffset;
USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec.
USHORT usOffDelayInMs;
UCHAR ucPowerSequenceDigOntoDEin10Ms;
UCHAR ucPowerSequenceDEtoBLOnin10Ms;
UCHAR ucLVDS_Misc; // Bit0:{=0:single, =1:dual},Bit1 {=0:666RGB, =1:888RGB},Bit2:3:{Grey level}
// Bit4:{=0:LDI format for RGB888, =1 FPDI format for RGB888}
// Bit5:{=0:Spatial Dithering disabled;1 Spatial Dithering enabled}
// Bit6:{=0:Temporal Dithering disabled;1 Temporal Dithering enabled}
UCHAR ucPanelDefaultRefreshRate;
UCHAR ucPanelIdentification;
UCHAR ucSS_Id;
USHORT usLCDVenderID;
USHORT usLCDProductID;
UCHAR ucLCDPanel_SpecialHandlingCap;
UCHARucPanelInfoSize;// start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable
UCHAR ucReserved[2];
}ATOM_LVDS_INFO_V12;
typedef struct _ATOM_STANDARD_VESA_TIMING
{
ATOM_COMMON_TABLE_HEADER sHeader;
char * aModeTimings; // 16 is not the real array number, just for initial allocation
}ATOM_STANDARD_VESA_TIMING;
#endif
branches/diebuche/i386/libsaio/console.c
152152
153153
154154
155
156
157
158
159
160
161
halt();
while (1);
}
/** Print a "Press a key to continue..." message and wait for a key press. */
void pause()
{
printf("Press a key to continue...");
getc();
}
branches/diebuche/i386/libsaio/vbe.c
2727
2828
2929
30
3031
3132
3233
......
7475
7576
7677
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
9278
9379
9480
......
121107
122108
123109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
124126
125127
126128
*/
#include "libsaio.h"
#include "edid.h"
#include "vbe.h"
/*
return(bb.eax.r.h);
}
int getEDID( void * edidBlock, UInt8 block)
{
bzero(&bb, sizeof(bb));
bb.intno = 0x10;
bb.eax.rr = funcGetEDID;
bb.ebx.r.l= 0x01;
bb.edx.rr = block;
bb.es = SEG( edidBlock );
bb.edi.rr = OFF( edidBlock );
bios( &bb );
return(bb.eax.r.h);
}
int getVBEModeInfo( int mode, void * minfo_p )
{
bb.intno = 0x10;
}
/*
*EDID/DDC Readings
*/
int getEDID( void *ddcblock, uint8_t blocksleft )
{
bb.intno = 0x10;
bb.eax.rr = FUNC_GET_EDID;
bb.ebx.r.l = SERVICE_READ_EDID;
bb.es = SEG( ddcblock );
bb.edi.rr = OFF( ddcblock );
bb.edx.rr = blocksleft;
bios( &bb );
return( bb.eax.r.h );
}
/*
* Default GTF parameter values.
*/
#define kCellGranularity 8.0 // character cell granularity
branches/diebuche/i386/libsaio/vbe.h
6868
6969
7070
71
72
71
7372
7473
7574
......
273272
274273
275274
275
276
277
278
279
280
276281
277282
278283
funcGetSetPaletteFormat = 0x4F08,
funcGetSetPaletteData = 0x4F09,
funcGetProtModeInterdace = 0x4F0A,
funcGetSetPixelClock = 0x4F0B,
funcGetEDID = 0x4F15
funcGetSetPixelClock = 0x4F0B
};
enum {
extern int getVBEModeInfo(int mode, void *minfo_p);
extern int getVBEDACFormat(unsigned char *format);
extern int setVBEDACFormat(unsigned char format);
/*
* DDC
*/
extern int getEDID(void *ddcblock, uint8_t blocksleft);
extern int setVBEPalette(void *palette);
extern int getVBEPalette(void *palette);
extern int setVBEMode(unsigned short mode, const VBECRTCInfoBlock *timing);
branches/diebuche/i386/libsaio/spd.c
11
2
3
4
2
3
54
65
76
87
98
109
10
11
12
1113
1214
1315
......
1921
2022
2123
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
22344
23345
24
346
25347
/*
* Copyright 2010 AsereBLN. All rights reserved. <aserebln@googlemail.com>
*
* spd.c - obtain serial presene detect memory information
* spd.c - serial presence detect memory information
* (restored from pcefi10.5)
*/
#include "libsaio.h"
#include "pci.h"
#include "platform.h"
#include "spd.h"
#include "saio_internal.h"
#include "bootstruct.h"
#include "memvendors.h"
#ifndef DEBUG_SPD
#define DEBUG_SPD 0
#define DBG(x...)
#endif
static const char *spd_memory_types[] =
{
"RAM", /* 00h Undefined */
"FPM", /* 01h FPM */
"EDO", /* 02h EDO */
"",/* 03h PIPELINE NIBBLE */
"SDRAM", /* 04h SDRAM */
"",/* 05h MULTIPLEXED ROM */
"DDR SGRAM",/* 06h SGRAM DDR */
"DDR SDRAM",/* 07h SDRAM DDR */
"DDR2 SDRAM", /* 08h SDRAM DDR 2 */
"",/* 09h Undefined */
"",/* 0Ah Undefined */
"DDR3 SDRAM" /* 0Bh SDRAM DDR 3 */
};
#define UNKNOWN_MEM_TYPE 2
static uint8_t spd_mem_to_smbios[] =
{
UNKNOWN_MEM_TYPE, /* 00h Undefined */
UNKNOWN_MEM_TYPE, /* 01h FPM */
UNKNOWN_MEM_TYPE, /* 02h EDO */
UNKNOWN_MEM_TYPE, /* 03h PIPELINE NIBBLE */
SMB_MEM_TYPE_SDRAM, /* 04h SDRAM */
SMB_MEM_TYPE_ROM, /* 05h MULTIPLEXED ROM */
SMB_MEM_TYPE_SGRAM, /* 06h SGRAM DDR */
SMB_MEM_TYPE_DDR, /* 07h SDRAM DDR */
SMB_MEM_TYPE_DDR2, /* 08h SDRAM DDR 2 */
UNKNOWN_MEM_TYPE, /* 09h Undefined */
UNKNOWN_MEM_TYPE, /* 0Ah Undefined */
SMB_MEM_TYPE_DDR3 /* 0Bh SDRAM DDR 3 */
};
#define SPD_TO_SMBIOS_SIZE (sizeof(spd_mem_to_smbios)/sizeof(uint8_t))
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define SMBHSTSTS 0
#define SMBHSTCNT 2
#define SMBHSTCMD 3
#define SMBHSTADD 4
#define SMBHSTDAT 5
#define SBMBLKDAT 7
/** Read one byte from the intel i2c, used for reading SPD on intel chipsets only. */
unsigned char smb_read_byte_intel(uint32_t base, uint8_t adr, uint8_t cmd)
{
int l1, h1, l2, h2;
unsigned long long t;
outb(base + SMBHSTSTS, 0x1f);// reset SMBus Controller
outb(base + SMBHSTDAT, 0xff);
while( inb(base + SMBHSTSTS) & 0x01);// wait until ready
outb(base + SMBHSTCMD, cmd);
outb(base + SMBHSTADD, (adr << 1) | 0x01 );
outb(base + SMBHSTCNT, 0x48 );
rdtsc(l1, h1);
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 40);
if (t > 10)
break;// break after 10ms
}
return inb(base + SMBHSTDAT);
}
/** Get Vendor Name from spd, 2 cases handled DDR3 and DDR2,
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
const char * spd = slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = spd[0x75];
code = spd[0x76];
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
if(spd[0x40]==0x7f) {
for (i=0x40; i<0x48 && spd[i]==0x7f;i++) bank++;
code = spd[i];
} else {
code = spd[0x40];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
return vendorMap[i].name;
}
/* OK there is no vendor id here lets try to match the partnum if it exists */
if (strstr(slot->PartNo,"GU332") == slot->PartNo) // Unifosa fingerprint
return "Unifosa";
return "NoName";
}
/** Get Default Memory Module Speed (no overclocking handled) */
int getDDRspeedMhz(const char * spd)
{
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
switch(spd[12]) {
case 0x0f:
return 1066;
case 0x0c:
return 1333;
case 0x0a:
return 1600;
case 0x14:
default:
return 800;
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
switch(spd[9]) {
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
}
}
return 800; // default freq for unknown types
}
#define UIS(a) ((uint32_t)spd[a])
/** Get DDR3 or DDR2 serial number, 0 most of the times, always return a valid ptr */
const char *getDDRSerial(const char* spd)
{
static char asciiSerial[16];
static uint8_t serialnum=0;
uint32_t ret=0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {// DDR3
ret = UIS(122) | (UIS(123)<<8) | (UIS(124)<<16) | ((UIS(125)&0x7f)<<24);
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) { // DDR2 or DDR
ret = UIS(95) | (UIS(96)<<8) | (UIS(97)<<16) | ((UIS(98)&0x7f)<<24);
}
if (!ret) sprintf(asciiSerial, "10000000%d", serialnum++);
else sprintf(asciiSerial, "%d", ret);
return asciiSerial;
}
/** Get DDR3 or DDR2 Part Number, always return a valid ptr */
const char * getDDRPartNum(const char* spd)
{
const char * sPart = NULL;
int i;
bool bZero = false;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
sPart = &spd[128];
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2)
sPart = &spd[73];
if (sPart) { // Check that the spd part name is zero terminated and that it is ascii:
for (i=0; i<32; i++) {
if (sPart[i]==0) {
bZero = true;
break;
}
else if ( !isascii(sPart[i]) ) {
sPart = NULL;
break;
}
}
}
return ( sPart==NULL || !(*sPart) || !bZero ) ?
"N/A" : sPart;
}
int mapping []= {0,2,1,3,4,6,5,7,8,10,9,11};
/** Read from smbus the SPD content and interpret it for detecting memory attributes */
static void read_smb_intel(pci_dt_t *smbus_dev)
{
int i, x, speed;
uint8_t spd_size, spd_type;
uint32_t base;
bool dump = false;
RamSlotInfo_t* slot;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
DBG("Scanning smbus_dev <%04x, %04x> ...\n",smbus_dev->vendor_id, smbus_dev->device_id);
getBoolForKey("DumpSPD", &dump, &bootInfo->bootConfig);
bool fullBanks = // needed at least for laptops
Platform.DMI.MemoryModules == Platform.DMI.MaxMemorySlots;
// Search MAX_RAM_SLOTS slots
for (i = 0; i < MAX_RAM_SLOTS; i++){
slot = &Platform.RAM.DIMM[i];
spd_size = smb_read_byte_intel(base, 0x50 + i, 0);
// Check spd is present
if (spd_size && (spd_size != 0xff) ) {
slot->spd = malloc(spd_size);
if (slot->spd == NULL) continue;
slot->InUse = true;
bzero(slot->spd, spd_size);
// Copy spd data into buffer
for (x = 0; x < spd_size; x++)
slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x);
switch (slot->spd[SPD_MEMORY_TYPE]) {
case SPD_MEMORY_TYPE_SDRAM_DDR2:
slot->ModuleSize = ((1 << (slot->spd[SPD_NUM_ROWS] & 0x0f) + (slot->spd[SPD_NUM_COLUMNS] & 0x0f) - 17) *
((slot->spd[SPD_NUM_DIMM_BANKS] & 0x7) + 1) * slot->spd[SPD_NUM_BANKS_PER_SDRAM]);
break;
case SPD_MEMORY_TYPE_SDRAM_DDR3:
slot->ModuleSize = ((slot->spd[4] & 0x0f) + 28 ) + ((slot->spd[8] & 0x7) + 3 );
slot->ModuleSize -= (slot->spd[7] & 0x7) + 25;
slot->ModuleSize = ((1 << slot->ModuleSize) * (((slot->spd[7] >> 3) & 0x1f) + 1));
break;
}
spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
slot->Type = spd_mem_to_smbios[spd_type];
slot->PartNo = strdup(getDDRPartNum(slot->spd) );
slot->Vendor = strdup(getVendorName(slot) );
slot->SerialNo = strdup(getDDRSerial(slot->spd));
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (speed > slot->Frequency) slot->Frequency = speed; // just in case dmi wins on spd
if(dump) {
printf("Slot %d Type %d %dMB (%s) %dMHz Vendor=%s, PartNo=%s SerialNo=%s\n",
i,
(int)slot->Type,
slot->ModuleSize,
spd_memory_types[spd_type],
slot->Frequency,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
dumpPhysAddr("spd content: ",slot->spd, spd_size);
getc();
}
}
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform.DMI.DIMM[i]=
i>0 && Platform.RAM.DIMM[1].InUse==false && fullBanks && Platform.DMI.MaxMemorySlots==2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
if (slot->spd) {
free(slot->spd);
slot->spd = NULL;
}
} // for
}
static struct smbus_controllers_t smbus_controllers[] = {
{0x8086, 0x269B, "ESB2", read_smb_intel },
{0x8086, 0x25A4, "6300ESB", read_smb_intel },
{0x8086, 0x24C3, "ICH4", read_smb_intel },
{0x8086, 0x24D3, "ICH5", read_smb_intel },
{0x8086, 0x266A, "ICH6", read_smb_intel },
{0x8086, 0x27DA, "ICH7", read_smb_intel },
{0x8086, 0x283E, "ICH8", read_smb_intel },
{0x8086, 0x2930, "ICH9", read_smb_intel },
{0x8086, 0x3A30, "ICH10R", read_smb_intel },
{0x8086, 0x3A60, "ICH10B", read_smb_intel },
{0x8086, 0x3B30, "P55", read_smb_intel },
{0x8086, 0x5032, "EP80579", read_smb_intel }
};
// initial call : pci_dt = root_pci_dev;
// find_and_read_smbus_controller(root_pci_dev);
bool find_and_read_smbus_controller(pci_dt_t* pci_dt)
{
pci_dt_t*current = pci_dt;
int i;
while (current) {
#if DEBUG_SPD
printf("%02x:%02x.%x [%04x] [%04x:%04x] :: %s\n",
current->dev.bits.bus, current->dev.bits.dev, current->dev.bits.func,
current->class_id, current->vendor_id, current->device_id,
get_pci_dev_path(current));
#endif
for ( i = 0; i < sizeof(smbus_controllers) / sizeof(smbus_controllers[0]); i++ )
{
if (current->vendor_id == smbus_controllers[i].vendor &&
current->device_id == smbus_controllers[i].device)
{
smbus_controllers[i].read_smb(current); // read smb
return true;
}
}
find_and_read_smbus_controller(current->children);
current = current->next;
}
return false; // not found
}
void scan_spd(PlatformInfo_t *p)
{
/* NYI */
find_and_read_smbus_controller(root_pci_dev);
}
branches/diebuche/i386/libsaio/spd.h
88
99
1010
11
1112
12
13
1314
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
14158
#define __LIBSAIO_SPD_H
#include "platform.h"
#include "libsaio.h"
extern void scan_spd(PlatformInfo_t *p);
void scan_spd(PlatformInfo_t *p);
struct smbus_controllers_t {
uint32_tvendor;
uint32_tdevice;
char*name;
void (*read_smb)(pci_dt_t *smbus_dev);
};
/*
* Serial Presence Detect (SPD) data stored on SDRAM modules.
*
* Datasheet:
* - Name: PC SDRAM Serial Presence Detect (SPD) Specification
* Revision 1.2A, December, 1997
* - PDF: http://www.intel.com/design/chipsets/memory/spdsd12a.pdf
*
* Datasheet (alternative):
* - Name: SERIAL PRESENCE DETECT STANDARD, General Standard
* JEDEC Standard No. 21-C
* - PDF: http://www.jedec.org/download/search/4_01_02_00R9.PDF
*/
/* Byte numbers. */
#define SPD_NUM_MANUFACTURER_BYTES 0 /* Number of bytes used by module manufacturer */
#define SPD_TOTAL_SPD_MEMORY_SIZE 1 /* Total SPD memory size */
#define SPD_MEMORY_TYPE 2 /* (Fundamental) memory type */
#define SPD_NUM_ROWS 3 /* Number of row address bits */
#define SPD_NUM_COLUMNS 4 /* Number of column address bits */
#define SPD_NUM_DIMM_BANKS 5 /* Number of module rows (banks) */
#define SPD_MODULE_DATA_WIDTH_LSB 6 /* Module data width (LSB) */
#define SPD_MODULE_DATA_WIDTH_MSB 7 /* Module data width (MSB) */
#define SPD_MODULE_VOLTAGE 8 /* Module interface signal levels */
#define SPD_MIN_CYCLE_TIME_AT_CAS_MAX 9 /* SDRAM cycle time (highest CAS latency), RAS access time (tRAC) */
#define SPD_ACCESS_TIME_FROM_CLOCK 10 /* SDRAM access time from clock (highest CAS latency), CAS access time (Tac, tCAC) */
#define SPD_DIMM_CONFIG_TYPE 11 /* Module configuration type */
#define SPD_REFRESH 12 /* Refresh rate/type */
#define SPD_PRIMARY_SDRAM_WIDTH 13 /* SDRAM width (primary SDRAM) */
#define SPD_ERROR_CHECKING_SDRAM_WIDTH 14 /* Error checking SDRAM (data) width */
#define SPD_MIN_CLOCK_DELAY_B2B_RAND_COLUMN 15 /* SDRAM device attributes, minimum clock delay for back to back random column */
#define SPD_SUPPORTED_BURST_LENGTHS 16 /* SDRAM device attributes, burst lengths supported */
#define SPD_NUM_BANKS_PER_SDRAM 17 /* SDRAM device attributes, number of banks on SDRAM device */
#define SPD_ACCEPTABLE_CAS_LATENCIES 18 /* SDRAM device attributes, CAS latency */
#define SPD_CS_LATENCY 19 /* SDRAM device attributes, CS latency */
#define SPD_WE_LATENCY 20 /* SDRAM device attributes, WE latency */
#define SPD_MODULE_ATTRIBUTES 21 /* SDRAM module attributes */
#define SPD_DEVICE_ATTRIBUTES_GENERAL 22 /* SDRAM device attributes, general */
#define SPD_SDRAM_CYCLE_TIME_2ND 23 /* SDRAM cycle time (2nd highest CAS latency) */
#define SPD_ACCESS_TIME_FROM_CLOCK_2ND 24 /* SDRAM access from clock (2nd highest CAS latency) */
#define SPD_SDRAM_CYCLE_TIME_3RD 25 /* SDRAM cycle time (3rd highest CAS latency) */
#define SPD_ACCESS_TIME_FROM_CLOCK_3RD 26 /* SDRAM access from clock (3rd highest CAS latency) */
#define SPD_MIN_ROW_PRECHARGE_TIME 27 /* Minimum row precharge time (Trp) */
#define SPD_MIN_ROWACTIVE_TO_ROWACTIVE 28 /* Minimum row active to row active (Trrd) */
#define SPD_MIN_RAS_TO_CAS_DELAY 29 /* Minimum RAS to CAS delay (Trcd) */
#define SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY 30 /* Minimum RAS pulse width (Tras) */
#define SPD_DENSITY_OF_EACH_ROW_ON_MODULE 31 /* Density of each row on module */
#define SPD_CMD_SIGNAL_INPUT_SETUP_TIME 32 /* Command and address signal input setup time */
#define SPD_CMD_SIGNAL_INPUT_HOLD_TIME 33 /* Command and address signal input hold time */
#define SPD_DATA_SIGNAL_INPUT_SETUP_TIME 34 /* Data signal input setup time */
#define SPD_DATA_SIGNAL_INPUT_HOLD_TIME 35 /* Data signal input hold time */
#define SPD_WRITE_RECOVERY_TIME 36 /* Write recovery time (tWR) */
#define SPD_INT_WRITE_TO_READ_DELAY 37 /* Internal write to read command delay (tWTR) */
#define SPD_INT_READ_TO_PRECHARGE_DELAY 38 /* Internal read to precharge command delay (tRTP) */
#define SPD_MEM_ANALYSIS_PROBE_PARAMS 39 /* Memory analysis probe characteristics */
#define SPD_BYTE_41_42_EXTENSION 40 /* Extension of byte 41 (tRC) and byte 42 (tRFC) */
#define SPD_MIN_ACT_TO_ACT_AUTO_REFRESH 41 /* Minimum active to active auto refresh (tRCmin) */
#define SPD_MIN_AUTO_REFRESH_TO_ACT 42 /* Minimum auto refresh to active/auto refresh (tRFC) */
#define SPD_MAX_DEVICE_CYCLE_TIME 43 /* Maximum device cycle time (tCKmax) */
#define SPD_MAX_DQS_DQ_SKEW 44 /* Maximum skew between DQS and DQ (tDQSQ) */
#define SPD_MAX_READ_DATAHOLD_SKEW 45 /* Maximum read data-hold skew factor (tQHS) */
#define SPD_PLL_RELOCK_TIME 46 /* PLL relock time */
#define SPD_SPD_DATA_REVISION_CODE 62 /* SPD data revision code */
#define SPD_CHECKSUM_FOR_BYTES_0_TO_62 63 /* Checksum for bytes 0-62 */
#define SPD_MANUFACTURER_JEDEC_ID_CODE 64 /* Manufacturer's JEDEC ID code, per EIA/JEP106 (bytes 64-71) */
#define SPD_MANUFACTURING_LOCATION 72 /* Manufacturing location */
#define SPD_MANUFACTURER_PART_NUMBER 73 /* Manufacturer's part number, in 6-bit ASCII (bytes 73-90) */
#define SPD_REVISION_CODE 91 /* Revision code (bytes 91-92) */
#define SPD_MANUFACTURING_DATE 93 /* Manufacturing date (byte 93: year, byte 94: week) */
#define SPD_ASSEMBLY_SERIAL_NUMBER 95 /* Assembly serial number (bytes 95-98) */
#define SPD_MANUFACTURER_SPECIFIC_DATA 99 /* Manufacturer specific data (bytes 99-125) */
#define SPD_INTEL_SPEC_FOR_FREQUENCY 126 /* Intel specification for frequency */
#define SPD_INTEL_SPEC_100_MHZ 127 /* Intel specification details for 100MHz support */
/* DRAM specifications use the following naming conventions for SPD locations */
#define SPD_tRP SPD_MIN_ROW_PRECHARGE_TIME
#define SPD_tRRD SPD_MIN_ROWACTIVE_TO_ROWACTIVE
#define SPD_tRCD SPD_MIN_RAS_TO_CAS_DELAY
#define SPD_tRAS SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY
#define SPD_BANK_DENSITY SPD_DENSITY_OF_EACH_ROW_ON_MODULE
#define SPD_ADDRESS_CMD_HOLD SPD_CMD_SIGNAL_INPUT_HOLD_TIME
#define SPD_tRC41/* SDRAM Device Minimum Active to Active/Auto Refresh Time (tRC) */
#define SPD_tRFC42/* SDRAM Device Minimum Auto Refresh to Active/Auto Refresh (tRFC) */
/* SPD_MEMORY_TYPE values. */
#define SPD_MEMORY_TYPE_FPM_DRAM1
#define SPD_MEMORY_TYPE_EDO2
#define SPD_MEMORY_TYPE_PIPELINED_NIBBLE3
#define SPD_MEMORY_TYPE_SDRAM4
#define SPD_MEMORY_TYPE_MULTIPLEXED_ROM5
#define SPD_MEMORY_TYPE_SGRAM_DDR6
#define SPD_MEMORY_TYPE_SDRAM_DDR7
#define SPD_MEMORY_TYPE_SDRAM_DDR28
#define SPD_MEMORY_TYPE_SDRAM_DDR30xb
/* SPD_MODULE_VOLTAGE values. */
#define SPD_VOLTAGE_TTL0 /* 5.0 Volt/TTL */
#define SPD_VOLTAGE_LVTTL1 /* LVTTL */
#define SPD_VOLTAGE_HSTL2 /* HSTL 1.5 */
#define SPD_VOLTAGE_SSTL33 /* SSTL 3.3 */
#define SPD_VOLTAGE_SSTL24 /* SSTL 2.5 */
/* SPD_DIMM_CONFIG_TYPE values. */
#define ERROR_SCHEME_NONE0
#define ERROR_SCHEME_PARITY1
#define ERROR_SCHEME_ECC2
/* SPD_ACCEPTABLE_CAS_LATENCIES values. */
// TODO: Check values.
#define SPD_CAS_LATENCY_1_00x01
#define SPD_CAS_LATENCY_1_50x02
#define SPD_CAS_LATENCY_2_00x04
#define SPD_CAS_LATENCY_2_50x08
#define SPD_CAS_LATENCY_3_00x10
#define SPD_CAS_LATENCY_3_50x20
#define SPD_CAS_LATENCY_4_00x40
#define SPD_CAS_LATENCY_DDR2_3(1 << 3)
#define SPD_CAS_LATENCY_DDR2_4(1 << 4)
#define SPD_CAS_LATENCY_DDR2_5(1 << 5)
#define SPD_CAS_LATENCY_DDR2_6(1 << 6)
/* SPD_SUPPORTED_BURST_LENGTHS values. */
#define SPD_BURST_LENGTH_11
#define SPD_BURST_LENGTH_22
#define SPD_BURST_LENGTH_44
#define SPD_BURST_LENGTH_88
#define SPD_BURST_LENGTH_PAGE(1 << 7)
/* SPD_MODULE_ATTRIBUTES values. */
#define MODULE_BUFFERED1
#define MODULE_REGISTERED2
#endif /* !__LIBSAIO_SPD_H */
branches/diebuche/i386/libsaio/Makefile
4242
4343
4444
45
46
45
46
4747
4848
4949
cpu.o platform.o dsdt_patcher.o \
smbios_patcher.o fake_efi.o ext2fs.o \
hpet.o spd.o usb.o pci_setup.o \
device_inject.o nvidia.o ati.o ATIresolution.o edid.o pci_root.o \
convert.o mem.o
device_inject.o nvidia.o ati.o pci_root.o \
convert.o mem.o 915resolution.o edid.o
SAIO_EXTERN_OBJS = console.o
branches/diebuche/i386/libsaio/SMBIOS.h
112112
113113
114114
115
115116
116117
117118
SMBBytebankLocator;
SMBBytememoryType;
SMBWordtypeDetail;
SMBWord speed;
} __attribute__((packed));
#endif /* !_LIBSAIO_SMBIOS_H */
branches/diebuche/i386/libsaio/smbios_patcher.c
1010
1111
1212
13
1413
1514
16
15
1716
1817
1918
......
2221
2322
2423
24
25
26
27
2528
2629
27
30
2831
2932
3033
......
3942
4043
4144
42
45
4346
4447
4548
......
5457
5558
5659
57
60
5861
5962
6063
......
6972
7073
7174
72
75
7376
7477
7578
......
8487
8588
8689
87
90
8891
8992
9093
......
98101
99102
100103
101
104
102105
103106
104
107
105108
106109
107110
......
117120
118121
119122
120
121
122
123
124
125
123126
124127
125128
126129
127
130
128131
129132
130133
131134
132
135
133136
134137
135138
136139
137
140
138141
139142
140143
141144
142
145
143146
144147
145148
......
152155
153156
154157
155
158
156159
157160
158161
......
166169
167170
168171
169
172
170173
171
172
173
174
175
176
177
178
179
180
181
174182
183
175184
176185
177186
178
187
179188
180189
181190
......
189198
190199
191200
192
201
193202
194203
195204
196205
197206
198207
199
200
208
209
210
201211
202212
203213
204214
205215
206
216
207217
208218
209219
......
267277
268278
269279
270
271280
272281
273282
274283
275284
276285
277
278
279
280
281
282
286
287
288
289
290
291
292
293
283294
284295
285
296
286297
287298
288299
289
290
300
301
291302
292303
293304
......
318329
319330
320331
321
332
322333
323334
324335
......
329340
330341
331342
332
333
334
343
344
345
335346
336347
348
349
350
337351
338352
339353
......
379393
380394
381395
396
397
382398
383399
384400
......
426442
427443
428444
429
445
446
447
448
449
430450
431451
432452
......
437457
438458
439459
440
460
461
462
441463
442464
443465
......
453475
454476
455477
478
479
456480
457481
458482
......
461485
462486
463487
488
489
464490
465491
466492
467493
468494
495
496
469497
470498
471499
......
475503
476504
477505
506
507
478508
479
509
510
480511
481
512
482513
483514
515
516
484517
485518
486519
......
572605
573606
574607
608
609
575610
576611
577612
......
688723
689724
690725
726
727
691728
692729
693730
......
695732
696733
697734
698
699
700
701
735
736
737
738
739
702740
703
741
742
743
744
704745
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720746
721747
722748
723749
724
750
725751
726752
727
728753
729754
730755
731
756
757
732758
733
734
735
759
760
761
736762
737
738
739
763
764
765
766
767
740768
769
741770
742
771
743772
744773
745
746
747
748
749
774
775
776
777
778
779
780
781
782
783
784
750785
751
752
753
754
786
787
788
755789
756790
791
792
793
757794
758
759
760
761
762
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
#include "fake_efi.h"
#include "platform.h"
#include "smbios_patcher.h"
#include "SMBIOS.h"
#ifndef DEBUG_SMBIOS
#define DEBUG_SMBIOS 1
#define DEBUG_SMBIOS 0
#endif
#if DEBUG_SMBIOS
#define DBG(x...)
#endif
typedef struct {
const char* key;
const char* value;
} SMStrEntryPair;
// defaults for a MacBook
static char sm_macbook_defaults[][2][40]={
static const SMStrEntryPair const sm_macbook_defaults[]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MB41.88Z.0073.B00.0809221748"},
{"SMbiosdate","04/01/2008"},
};
// defaults for a MacBook Pro
static char sm_macbookpro_defaults[][2][40]={
static const SMStrEntryPair const sm_macbookpro_defaults[]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MBP41.88Z.0073.B00.0809221748"},
{"SMbiosdate","04/01/2008"},
};
// defaults for a Mac mini
static char sm_macmini_defaults[][2][40]={
static const SMStrEntryPair const sm_macmini_defaults[]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","MM21.88Z.009A.B00.0706281359"},
{"SMbiosdate","04/01/2008"},
};
// defaults for an iMac
static char sm_imac_defaults[][2][40]={
static const SMStrEntryPair const sm_imac_defaults[]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","IM81.88Z.00C1.B00.0802091538"},
{"SMbiosdate","04/01/2008"},
};
// defaults for a Mac Pro
static char sm_macpro_defaults[][2][40]={
static const SMStrEntryPair const sm_macpro_defaults[]={
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
{"SMbiosdate","04/01/2008"},
{ "",""}
};
static char *sm_get_defstr(char *name, int table_num)
static const char* sm_get_defstr(const char * key, int table_num)
{
inti;
char(*sm_defaults)[2][40];
const SMStrEntryPair*sm_defaults;
if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
if (Platform.CPU.NoCores > 1) {
}
}
for (i=0;sm_defaults[i][0][0];i++) {
if (!strcmp (sm_defaults[i][0],name)) {
return sm_defaults[i][1];
for (i=0; sm_defaults[i].key[0]; i++) {
if (!strcmp (sm_defaults[i].key, key)) {
return sm_defaults[i].value;
}
}
// Shouldn't happen
printf ("Error: no default for '%s' known\n", name);
printf ("Error: no default for '%s' known\n", key);
sleep (2);
return "";
}
static int sm_get_fsb(char *name, int table_num)
static int sm_get_fsb(const char *name, int table_num)
{
return Platform.CPU.FSBFrequency/1000000;
}
static int sm_get_cpu (char *name, int table_num)
static int sm_get_cpu (const char *name, int table_num)
{
return Platform.CPU.CPUFrequency/1000000;
}
static int sm_get_cputype (char *name, int table_num)
static int sm_get_cputype (const char *name, int table_num)
{
if (Platform.CPU.NoCores == 1) {
return 0x0101; // <01 01> Intel Core Solo?
}
}
static int sm_get_memtype (char *name, int table_num)
static int sm_get_memtype (const char *name, int table_num)
{
intmap;
return SMB_MEM_TYPE_DDR2;
}
static int sm_get_memspeed (char *name, int table_num)
static int sm_get_memspeed (const char *name, int table_num)
{
if (Platform.RAM.Frequency != 0) {
DBG("RAM Detected Freq = %d\n", Platform.RAM.Frequency/1000000);
return Platform.RAM.Frequency/1000000;
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Frequency != 0) {
DBG("RAM Detected Freq = %d Mhz\n", Platform.RAM.DIMM[map].Frequency);
return Platform.RAM.DIMM[map].Frequency;
}
}
return 800;
}
static char *sm_get_memvendor (char *name, int table_num)
static const char *sm_get_memvendor (const char *name, int table_num)
{
intmap;
return "N/A";
}
static char *sm_get_memserial (char *name, int table_num)
static const char *sm_get_memserial (const char *name, int table_num)
{
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) {
DBG("RAM Detected SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].SerialNo);
return Platform.RAM.DIMM[map].SerialNo;
DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "",
map, table_num, Platform.RAM.DIMM[map].SerialNo);
return Platform.RAM.DIMM[map].SerialNo;
}
}
return "N/A";
}
static char *sm_get_mempartno (char *name, int table_num)
static const char *sm_get_mempartno (const char *name, int table_num)
{
intmap;
static struct SMBEntryPoint *getAddressOfSmbiosTable(void)
{
struct SMBEntryPoint*smbios;
/*
* The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
* for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
*/
smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;
while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {
if (COMPARE_DWORD(smbios->anchor, SMTAG) && COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
{
return smbios;
}
smbios = (((void*) smbios) + 16);
if (COMPARE_DWORD(smbios->anchor, SMTAG) &&
COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
smbios->dmi.anchor[4]==DMITAG[4] &&
checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
{
return smbios;
}
smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );
}
printf("ERROR: Unable to find SMBIOS!\n");
sleep(5);
pause();
return NULL;
}
/* Compute necessary space requirements for new smbios */
struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
/** Compute necessary space requirements for new smbios */
static struct SMBEntryPoint *smbios_dry_run(struct SMBEntryPoint *origsmbios)
{
struct SMBEntryPoint*ret;
char*smbiostables;
ret->entryPointLength = sizeof(*ret);
ret->majorVersion = 2;
ret->minorVersion = 1;
ret->maxStructureSize = 0;
ret->maxStructureSize = 0; // will be calculated later in this function
ret->entryPointRevision = 0;
for (i=0;i<5;i++) {
ret->formattedArea[i] = 0;
ret->dmi.anchor[2] = 0x4d;
ret->dmi.anchor[3] = 0x49;
ret->dmi.anchor[4] = 0x5f;
ret->dmi.tableLength = 0;
ret->dmi.tableAddress = 0;
ret->dmi.structureCount = 0;
ret->dmi.tableLength = 0; // will be calculated later in this function
ret->dmi.tableAddress = 0; // will be initialized in smbios_real_run()
ret->dmi.structureCount = 0; // will be calculated later in this function
ret->dmi.bcdRevision = 0x21;
tablesptr = smbiostables;
// add stringlen of overrides to original stringlen, update maxStructure size adequately,
// update structure count and tablepresent[type] with count of type.
if (smbiostables) {
for (i=0; i<origsmbiosnum; i++) {
struct smbios_table_header*cur = (struct smbios_table_header *)tablesptr;
tablespresent[cur->type]++;
}
}
// Add eventually table types whose detected count would be < required count, and update ret header with:
// new stringlen addons, structure count, and tablepresent[type] count adequately
for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
intnumnec=-1;
charbuffer[40];
return ret;
}
void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
/** From the origsmbios detected by getAddressOfSmbiosTable() to newsmbios whose entrypoint
* struct has been created by smbios_dry_run, update each table struct content of new smbios
* int the new allocated table address of size newsmbios->tablelength.
*/
static void smbios_real_run(struct SMBEntryPoint * origsmbios, struct SMBEntryPoint * newsmbios)
{
char *smbiostables;
char *tablesptr, *newtablesptr;
int i, j;
int tablespresent[256];
bool do_auto=true;
extern void dumpPhysAddr(const char * title, void * a, int len);
bzero(tablespresent, sizeof(tablespresent));
bzero(handles, sizeof(handles));
}
tablesptr = smbiostables;
newtablesptr = (char *)newsmbios->dmi.tableAddress;
// if old smbios exists then update new smbios with old smbios original content first
if (smbiostables) {
for (i=0; i<origsmbiosnum; i++) {
struct smbios_table_header*oldcur = (struct smbios_table_header *) tablesptr;
intnstrings = 0;
handles[(oldcur->handle) / 8] |= 1 << ((oldcur->handle) % 8);
// copy table length from old table to new table but not the old strings
memcpy(newcur,oldcur, oldcur->length);
tablesptr += oldcur->length;
stringsptr = tablesptr;
newtablesptr += oldcur->length;
// calculate the number of strings in the old content
for (;tablesptr[0]!=0 || tablesptr[1]!=0; tablesptr++) {
if (tablesptr[0] == 0) {
nstrings++;
nstrings++;
}
tablesptr += 2;
// copy the old strings to new table
memcpy(newtablesptr, stringsptr, tablesptr-stringsptr);
//point to next possible space for a string
// point to next possible space for a string (deducting the second 0 char at the end)
newtablesptr += tablesptr - stringsptr - 1;
if (nstrings == 0) {
if (nstrings == 0) { // if no string was found rewind to the first 0 char of the 0,0 terminator
newtablesptr--;
}
// now for each property in the table update the overrides if any (auto or user)
for (j=0; j<sizeof(smbios_properties)/sizeof(smbios_properties[0]); j++) {
const char*str;
intsize;
tablespresent[newcur->type]++;
}
}
// for each eventual complementary table not present in the original smbios, do the overrides
for (i=0; i<sizeof(smbios_table_descriptions)/sizeof(smbios_table_descriptions[0]); i++) {
intnumnec = -1;
charbuffer[40];
tablespresent[smbios_table_descriptions[i].type]++;
}
}
// calculate new checksums
newsmbios->dmi.checksum = 0;
newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
newsmbios->checksum = 0;
verbose("Patched DMI Table\n");
}
struct SMBEntryPoint *getSmbios(int which)
{
static struct SMBEntryPoint *orig = NULL; // cached
static struct SMBEntryPoint *patched = NULL; // cached
#define MAX_DMI_TABLES 96
typedef struct DmiNumAssocTag {
struct DMIHeader * dmi;
uint8_t type;
} DmiNumAssoc;
if (orig == NULL) orig = getAddressOfSmbiosTable();
static DmiNumAssoc DmiTablePair[MAX_DMI_TABLES];
static int DmiTablePairCount = 0;
static int current_pos=0;
static bool ftTablePairInit = true;
switch (which) {
case SMBIOS_ORIGINAL:
return orig;
case SMBIOS_PATCHED:
if (patched == NULL) {
patched = smbios_dry_run(orig);
smbios_real_run(orig, patched);
}
return patched;
default:
printf("ERROR: invalid option for getSmbios() !!\n");
return NULL;
}
}
/**
* Get a table structure entry from a type specification and a smbios address
* return NULL if table is not found
*/
struct DMIHeader *getSmbiosTableStructure(struct SMBEntryPoint*smbios, int type, int min_length)
static void getSmbiosTableStructure(struct SMBEntryPoint *smbios)
{
struct DMIHeader * dmihdr=NULL;
bool found = false;
SMBByte* p;
int i;
if (smbios == NULL || type < 0 ) return NULL;
if (ftTablePairInit && smbios!=NULL) {
ftTablePairInit = false;
#if DEBUG_SMBIOS
printf(">>> SMBIOSAddr=0x%08x\n", smbios);
printf(">>> DMI: addr=0x%08x, len=0x%d, count=%d\n", smbios->dmi.tableAddress,
smbios->dmi.tableLength, smbios->dmi.structureCount);
printf(">>> SMBIOSAddr=0x%08x\n", smbios);
printf(">>> DMI: addr=0x%08x, len=%d, count=%d\n", smbios->dmi.tableAddress,
smbios->dmi.tableLength, smbios->dmi.structureCount);
#endif
p = (SMBByte *) smbios->dmi.tableAddress;
for (i=0; i < smbios->dmi.structureCount && p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; i++)
{
p = (SMBByte *) smbios->dmi.tableAddress;
for (i=0;
i < smbios->dmi.structureCount &&
p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength;
i++) {
dmihdr = (struct DMIHeader *) p;
#if DEBUG_SMBIOS
verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
// verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
#endif
if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
if (dmihdr->type == type) /* 3.3.2 System Information */
{
if (dmihdr->length >= min_length) found = true;
break;
}
if (DmiTablePairCount < MAX_DMI_TABLES) {
DmiTablePair[DmiTablePairCount].dmi = dmihdr;
DmiTablePair[DmiTablePairCount].type = dmihdr->type;
DmiTablePairCount++;
}
else {
printf("DMI table entries list is full! next entries won't be stored\n");
}
#if DEBUG_SMBIOS
printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);
#endif
p = p + dmihdr->length;
while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00))
{
p++;
}
while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) {
p++;
}
p += 2;
}
}
}
#if DEBUG_SMBIOS
printf("DMI header found for table type %d, length = %d\n", type, dmihdr->type, dmihdr->length);
#endif
return found ? dmihdr : NULL;
}
/** Get original or new smbios entry point, if sucessful, the adresses are cached for next time */
struct SMBEntryPoint *getSmbios(int which)
{
static struct SMBEntryPoint *orig = NULL; // cached
static struct SMBEntryPoint *patched = NULL; // cached
// whatever we are called with orig or new flag, initialize asap both structures
switch (which) {
case SMBIOS_ORIGINAL:
if (orig==NULL) {
orig = getAddressOfSmbiosTable();
getSmbiosTableStructure(orig); // generate tables entry list for fast table finding
}
return orig;
case SMBIOS_PATCHED:
if (orig==NULL && (orig = getAddressOfSmbiosTable())==NULL ) {
printf("Could not find original SMBIOS !!\n");
pause();
} else {
patched = smbios_dry_run(orig);
if(patched==NULL) {
printf("Could not create new SMBIOS !!\n");
pause();
}
else {
smbios_real_run(orig, patched);
}
}
return patched;
default:
printf("ERROR: invalid option for getSmbios() !!\n");
break;
}
return NULL;
}
/** Find first original dmi Table with a particular type */
struct DMIHeader* FindFirstDmiTableOfType(int type, int minlength)
{
current_pos = 0;
return FindNextDmiTableOfType(type, minlength);
};
/** Find next original dmi Table with a particular type */
struct DMIHeader* FindNextDmiTableOfType(int type, int minlength)
{
int i;
if (ftTablePairInit) getSmbios(SMBIOS_ORIGINAL);
for (i=current_pos; i < DmiTablePairCount; i++) {
if (type == DmiTablePair[i].type &&
DmiTablePair[i].dmi &&
DmiTablePair[i].dmi->length >= minlength ) {
current_pos = i+1;
return DmiTablePair[i].dmi;
}
}
return NULL; // not found
};
branches/diebuche/i386/libsaio/smbios_patcher.h
3030
3131
3232
33
33
3434
3535
3636
37
38
39
37
38
39
4040
4141
4242
......
4949
5050
5151
52
5352
53
54
55
5456
struct smbios_property
{
char*name;
const char*name;
uint8_ttable_type;
enum {SMSTRING, SMWORD, SMBYTE, SMOWORD} value_type;
intoffset;
int(*auto_int) (char *name, int table_num);
char*(*auto_str) (char *name, int table_num);
char*(*auto_oword) (char *name, int table_num);
int(*auto_int) (const char *name, int table_num);
const char*(*auto_str) (const char *name, int table_num);
const char*(*auto_oword) (const char *name, int table_num);
};
struct smbios_table_description
/** call with flag SMBIOS_ORIGINAL to get orig. entrypoint
or call with flag SMBIOS_PATCHED to get patched smbios entrypoint
*/
extern struct DMIHeader *getSmbiosTableStructure(struct SMBEntryPoint*smbios, int type, int min_length);
extern struct SMBEntryPoint*getSmbios(int);
extern struct DMIHeader* FindNextDmiTableOfType(int type, int minlen);
extern struct DMIHeader* FindFirstDmiTableOfType(int type, int minlen);
#endif /* !__LIBSAIO_SMBIOS_PATCHER_H */
branches/diebuche/i386/libsaio/mem.c
99
1010
1111
12
1213
1314
1415
......
2021
2122
2223
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
23103
24104
25
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
26141
#include "platform.h"
#include "cpu.h"
#include "mem.h"
#include "smbios_patcher.h"
#ifndef DEBUG_MEM
#define DEBUG_MEM 0
#define DBG(x...)
#endif
#define DC(c) (c >= 0x20 && c < 0x7f ? (char) c : '.')
#define STEP 16
void dumpPhysAddr(const char * title, void * a, int len)
{
int i,j;
u_int8_t* ad = (u_int8_t*) a;
char buffer[80];
char str[16];
if(ad==NULL) return;
printf("%s addr=0x%08x len=%04d\n",title ? title : "Dump of ", a, len);
printf("Ofs-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F ASCII\n");
i = (len/STEP)*STEP;
for (j=0; j < i; j+=STEP)
{
printf("%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
j,
ad[j], ad[j+1], ad[j+2], ad[j+3] , ad[j+4], ad[j+5], ad[j+6], ad[j+7],
ad[j+8], ad[j+9], ad[j+10], ad[j+11] , ad[j+12], ad[j+13], ad[j+14], ad[j+15],
DC(ad[j]), DC(ad[j+1]), DC(ad[j+2]), DC(ad[j+3]) , DC(ad[j+4]), DC(ad[j+5]), DC(ad[j+6]), DC(ad[j+7]),
DC(ad[j+8]), DC(ad[j+9]), DC(ad[j+10]), DC(ad[j+11]) , DC(ad[j+12]), DC(ad[j+13]), DC(ad[j+14]), DC(ad[j+15])
);
}
if (len%STEP==0) return;
sprintf(buffer,"%02x:", i);
for (j=0; j < STEP; j++) {
if (j<(len%STEP))
sprintf(str, " %02x", ad[i+j]);
else
strcpy(str, " " );
strncat(buffer, str, sizeof(buffer));
}
strncat(buffer," ", sizeof(buffer));
for (j=0; j < (len%STEP); j++) {
sprintf(str, "%c", DC(ad[i+j]));
strncat(buffer, str, sizeof(buffer));
}
printf("%s\n",buffer);
}
void dumpAllTablesOfType(int i)
{
char title[32];
struct DMIHeader * dmihdr;
for(dmihdr = FindFirstDmiTableOfType(i, 4);
dmihdr;
dmihdr = FindNextDmiTableOfType(i, 4)) {
sprintf(title,"Table (type %d) :" , i);
dumpPhysAddr(title, dmihdr, dmihdr->length+32);
}
}
const char * getDMIString(struct DMIHeader * dmihdr, uint8_t strNum)
{
const char * ret =NULL;
const char * startAddr = (const char *) dmihdr;
const char * limit = NULL;
if (!dmihdr || dmihdr->length<4 || strNum==0) return NULL;
startAddr += dmihdr->length;
limit = startAddr + 256;
for(; strNum; strNum--) {
if ((*startAddr)==0 && *(startAddr+1)==0) break;
if (*startAddr && strNum<=1) {
ret = startAddr; // current str
break;
}
while(*startAddr && startAddr<limit) startAddr++;
if (startAddr==limit) break; // no terminator found
else if((*startAddr==0) && *(startAddr+1)==0) break;
else startAddr++;
}
return ret;
}
void scan_memory(PlatformInfo_t *p)
{
/* NYI */
int i=0;
struct DMIHeader * dmihdr = NULL;
struct DMIMemoryModuleInfo* memInfo[MAX_RAM_SLOTS]; // 6
struct DMIPhysicalMemoryArray* physMemArray; // 16
struct DMIMemoryDevice* memDev[MAX_RAM_SLOTS]; //17
/* We mainly don't use obsolete tables 5,6 because most of computers don't handle it anymore */
Platform.DMI.MemoryModules = 0;
/* Now lets peek info rom table 16,17 as for some bios, table 5 & 6 are not used */
physMemArray = (struct DMIPhysicalMemoryArray*) FindFirstDmiTableOfType(16, 4);
Platform.DMI.MaxMemorySlots = physMemArray ? physMemArray->numberOfMemoryDevices : 0;
i = 0;
for(dmihdr = FindFirstDmiTableOfType(17, 4);
dmihdr;
dmihdr = FindNextDmiTableOfType(17, 4) ) {
memDev[i] = (struct DMIMemoryDevice*) dmihdr;
if (memDev[i]->size !=0 ) Platform.DMI.MemoryModules++;
if (memDev[i]->speed>0) Platform.RAM.DIMM[i].Frequency = memDev[i]->speed; // take it here for now but we'll check spd and dmi table 6 as well
i++;
}
// for table 6, we only have a look at the current speed
i = 0;
for(dmihdr = FindFirstDmiTableOfType(6, 4);
dmihdr;
dmihdr = FindNextDmiTableOfType(6, 4) ) {
memInfo[i] = (struct DMIMemoryModuleInfo*) dmihdr;
if (memInfo[i]->currentSpeed > Platform.RAM.DIMM[i].Frequency)
Platform.RAM.DIMM[i].Frequency = memInfo[i]->currentSpeed; // favor real overclocked speed if any
i++;
}
#if 0
dumpAllTablesOfType(17);
getc();
#endif
}
branches/diebuche/i386/libsaio/memvendors.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
/*
* Memory module vendors as published by JEDEC 106AA
*
* Special thanks to indi, memtest and theking for the table
*
*/
#ifndef __MEMVEN_H
#define __MEMVEN_H
typedef struct _vidTag {
uint8_t bank;
uint8_t code;
const char* name;
} VenIdName;
VenIdName vendorMap[] = {
{ 0, 0x01, "AMD"},
{ 0, 0x02, "AMI"},
{ 0, 0x83, "Fairchild"},
{ 0, 0x04, "Fujitsu"},
{ 0, 0x85, "GTE"},
{ 0, 0x86, "Harris"},
{ 0, 0x07, "Hitachi"},
{ 0, 0x08, "Inmos"},
{ 0, 0x89, "Intel"},
{ 0, 0x8a, "I.T.T."},
{ 0, 0x0b, "Intersil"},
{ 0, 0x8c, "Monolithic Memories"},
{ 0, 0x0d, "Mostek"},
{ 0, 0x0e, "Freescale (Motorola)"},
{ 0, 0x8f, "National"},
{ 0, 0x10, "NEC"},
{ 0, 0x91, "RCA"},
{ 0, 0x92, "Raytheon"},
{ 0, 0x13, "Conexant (Rockwell)"},
{ 0, 0x94, "Seeq"},
{ 0, 0x15, "NXP (Philips)"},
{ 0, 0x16, "Synertek"},
{ 0, 0x97, "Texas Instruments"},
{ 0, 0x98, "Toshiba"},
{ 0, 0x19, "Xicor"},
{ 0, 0x1a, "Zilog"},
{ 0, 0x9b, "Eurotechnique"},
{ 0, 0x1c, "Mitsubishi"},
{ 0, 0x9d, "Lucent (AT&T)"},
{ 0, 0x9e, "Exel"},
{ 0, 0x1f, "Atmel"},
{ 0, 0x20, "SGS/Thomson"},
{ 0, 0xa1, "Lattice Semi."},
{ 0, 0xa2, "NCR"},
{ 0, 0x23, "Wafer Scale Integration"},
{ 0, 0xa4, "IBM"},
{ 0, 0x25, "Tristar"},
{ 0, 0x26, "Visic"},
{ 0, 0xa7, "Intl. CMOS Technology"},
{ 0, 0xa8, "SSSI"},
{ 0, 0x29, "MicrochipTechnology"},
{ 0, 0x2a, "Ricoh"},
{ 0, 0xab, "VLSI"},
{ 0, 0x2c, "Micron Technology"},
{ 0, 0xad, "Hynix Semiconductor"},
{ 0, 0xae, "OKI Semiconductor"},
{ 0, 0x2f, "ACTEL"},
{ 0, 0xb0, "Sharp"},
{ 0, 0x31, "Catalyst"},
{ 0, 0x32, "Panasonic"},
{ 0, 0xb3, "IDT"},
{ 0, 0x34, "Cypress"},
{ 0, 0xb5, "DEC"},
{ 0, 0xb6, "LSI Logic"},
{ 0, 0x37, "Zarlink (Plessey)"},
{ 0, 0x38, "UTMC"},
{ 0, 0xb9, "Thinking Machine"},
{ 0, 0xba, "Thomson CSF"},
{ 0, 0x3b, "Integrated CMOS (Vertex)"},
{ 0, 0xbc, "Honeywell"},
{ 0, 0x3d, "Tektronix"},
{ 0, 0x3e, "Sun Microsystems"},
{ 0, 0xbf, "SST"},
{ 0, 0x40, "ProMos/Mosel Vitelic"},
{ 0, 0xc1, "Infineon (Siemens)"},
{ 0, 0xc2, "Macronix"},
{ 0, 0x43, "Xerox"},
{ 0, 0xc4, "Plus Logic"},
{ 0, 0x45, "SanDisk"},
{ 0, 0x46, "Elan Circuit Tech."},
{ 0, 0xc7, "European Silicon Str."},
{ 0, 0xc8, "Apple Computer"},
{ 0, 0x49, "Xilinx"},
{ 0, 0x4a, "Compaq"},
{ 0, 0xcb, "Protocol Engines"},
{ 0, 0x4c, "SCI"},
{ 0, 0xcd, "Seiko Instruments"},
{ 0, 0xce, "Samsung"},
{ 0, 0x4f, "I3 Design System"},
{ 0, 0xd0, "Klic"},
{ 0, 0x51, "Crosspoint Solutions"},
{ 0, 0x52, "Alliance Semiconductor"},
{ 0, 0xd3, "Tandem"},
{ 0, 0x54, "Hewlett-Packard"},
{ 0, 0xd5, "Intg. Silicon Solutions"},
{ 0, 0xd6, "Brooktree"},
{ 0, 0x57, "New Media"},
{ 0, 0x58, "MHS Electronic"},
{ 0, 0xd9, "Performance Semi."},
{ 0, 0xda, "Winbond Electronic"},
{ 0, 0x5b, "Kawasaki Steel"},
{ 0, 0xdc, "Bright Micro"},
{ 0, 0x5d, "TECMAR"},
{ 0, 0x5e, "Exar"},
{ 0, 0xdf, "PCMCIA"},
{ 0, 0xe0, "LG Semi (Goldstar)"},
{ 0, 0x61, "Northern Telecom"},
{ 0, 0x62, "Sanyo"},
{ 0, 0xe3, "Array Microsystems"},
{ 0, 0x64, "Crystal Semiconductor"},
{ 0, 0xe5, "Analog Devices"},
{ 0, 0xe6, "PMC-Sierra"},
{ 0, 0x67, "Asparix"},
{ 0, 0x68, "Convex Computer"},
{ 0, 0xe9, "Quality Semiconductor"},
{ 0, 0xea, "Nimbus Technology"},
{ 0, 0x6b, "Transwitch"},
{ 0, 0xec, "Micronas (ITT Intermetall)"},
{ 0, 0x6d, "Cannon"},
{ 0, 0x6e, "Altera"},
{ 0, 0xef, "NEXCOM"},
{ 0, 0x70, "QUALCOMM"},
{ 0, 0xf1, "Sony"},
{ 0, 0xf2, "Cray Research"},
{ 0, 0x73, "AMS(Austria Micro)"},
{ 0, 0xf4, "Vitesse"},
{ 0, 0x75, "Aster Electronics"},
{ 0, 0x76, "Bay Networks (Synoptic)"},
{ 0, 0xf7, "Zentrum/ZMD"},
{ 0, 0xf8, "TRW"},
{ 0, 0x79, "Thesys"},
{ 0, 0x7a, "Solbourne Computer"},
{ 0, 0xfb, "Allied-Signal"},
{ 0, 0x7c, "Dialog"},
{ 0, 0xfd, "Media Vision"},
{ 0, 0xfe, "Numonyx"},
{ 1, 0x01, "Cirrus Logic"},
{ 1, 0x02, "National Instruments"},
{ 1, 0x83, "ILC Data Device"},
{ 1, 0x04, "Alcatel Mietec"},
{ 1, 0x85, "Micro Linear"},
{ 1, 0x86, "Univ. of NC"},
{ 1, 0x07, "JTAG Technologies"},
{ 1, 0x08, "BAE Systems (Loral)"},
{ 1, 0x89, "Nchip"},
{ 1, 0x8a, "Galileo Tech"},
{ 1, 0x0b, "Bestlink Systems"},
{ 1, 0x8c, "Graychip"},
{ 1, 0x0d, "GENNUM"},
{ 1, 0x0e, "VideoLogic"},
{ 1, 0x8f, "Robert Bosch"},
{ 1, 0x10, "Chip Express"},
{ 1, 0x91, "DATARAM"},
{ 1, 0x92, "United Microelectronics Corp."},
{ 1, 0x13, "TCSI"},
{ 1, 0x94, "Smart Modular"},
{ 1, 0x15, "Hughes Aircraft"},
{ 1, 0x16, "Lanstar Semiconductor"},
{ 1, 0x97, "Qlogic"},
{ 1, 0x98, "Kingston"},
{ 1, 0x19, "Music Semi"},
{ 1, 0x1a, "Ericsson Components"},
{ 1, 0x9b, "SpaSE"},
{ 1, 0x1c, "Eon Silicon Devices"},
{ 1, 0x9d, "Programmable Micro Corp"},
{ 1, 0x9e, "DoD"},
{ 1, 0x1f, "Integ. Memories Tech."},
{ 1, 0x20, "Corollary"},
{ 1, 0xa1, "Dallas Semiconductor"},
{ 1, 0xa2, "Omnivision"},
{ 1, 0x23, "EIV(Switzerland)"},
{ 1, 0xa4, "Novatel Wireless"},
{ 1, 0x25, "Zarlink (Mitel)"},
{ 1, 0x26, "Clearpoint"},
{ 1, 0xa7, "Cabletron"},
{ 1, 0xa8, "STEC (Silicon Tech)"},
{ 1, 0x29, "Vanguard"},
{ 1, 0x2a, "Hagiwara Sys-Com"},
{ 1, 0xab, "Vantis"},
{ 1, 0x2c, "Celestica"},
{ 1, 0xad, "Century"},
{ 1, 0xae, "Hal Computers"},
{ 1, 0x2f, "Rohm Company"},
{ 1, 0xb0, "Juniper Networks"},
{ 1, 0x31, "Libit Signal Processing"},
{ 1, 0x32, "Mushkin Enhanced Memory"},
{ 1, 0xb3, "Tundra Semiconductor"},
{ 1, 0x34, "Adaptec"},
{ 1, 0xb5, "LightSpeed Semi."},
{ 1, 0xb6, "ZSP Corp."},
{ 1, 0x37, "AMIC Technology"},
{ 1, 0x38, "Adobe Systems"},
{ 1, 0xb9, "Dynachip"},
{ 1, 0xba, "PNY Electronics"},
{ 1, 0x3b, "Newport Digital"},
{ 1, 0xbc, "MMC Networks"},
{ 1, 0x3d, "T Square"},
{ 1, 0x3e, "Seiko Epson"},
{ 1, 0xbf, "Broadcom"},
{ 1, 0x40, "Viking Components"},
{ 1, 0xc1, "V3 Semiconductor"},
{ 1, 0xc2, "Flextronics (Orbit Semiconductor)"},
{ 1, 0x43, "Suwa Electronics"},
{ 1, 0xc4, "Transmeta"},
{ 1, 0x45, "Micron CMS"},
{ 1, 0x46, "American Computer & Digital Components"},
{ 1, 0xc7, "Enhance 3000"},
{ 1, 0xc8, "Tower Semiconductor"},
{ 1, 0x49, "CPU Design"},
{ 1, 0x4a, "Price Point"},
{ 1, 0xcb, "Maxim Integrated Product"},
{ 1, 0x4c, "Tellabs"},
{ 1, 0xcd, "Centaur Technology"},
{ 1, 0xce, "Unigen"},
{ 1, 0x4f, "Transcend Information"},
{ 1, 0xd0, "Memory Card Technology"},
{ 1, 0x51, "CKD"},
{ 1, 0x52, "Capital Instruments"},
{ 1, 0xd3, "Aica Kogyo"},
{ 1, 0x54, "Linvex Technology"},
{ 1, 0xd5, "MSC Vertriebs"},
{ 1, 0xd6, "AKM Company"},
{ 1, 0x57, "Dynamem"},
{ 1, 0x58, "NERA ASA"},
{ 1, 0xd9, "GSI Technology"},
{ 1, 0xda, "Dane-Elec (C Memory)"},
{ 1, 0x5b, "Acorn Computers"},
{ 1, 0xdc, "Lara Technology"},
{ 1, 0x5d, "Oak Technology"},
{ 1, 0x5e, "Itec Memory"},
{ 1, 0xdf, "Tanisys Technology"},
{ 1, 0xe0, "Truevision"},
{ 1, 0x61, "Wintec Industries"},
{ 1, 0x62, "Super PC Memory"},
{ 1, 0xe3, "MGV Memory"},
{ 1, 0x64, "Galvantech"},
{ 1, 0xe5, "Gadzoox Networks"},
{ 1, 0xe6, "Multi Dimensional Cons."},
{ 1, 0x67, "GateField"},
{ 1, 0x68, "Integrated Memory System"},
{ 1, 0xe9, "Triscend"},
{ 1, 0xea, "XaQti"},
{ 1, 0x6b, "Goldenram"},
{ 1, 0xec, "Clear Logic"},
{ 1, 0x6d, "Cimaron Communications"},
{ 1, 0x6e, "Nippon Steel Semi. Corp."},
{ 1, 0xef, "Advantage Memory"},
{ 1, 0x70, "AMCC"},
{ 1, 0xf1, "LeCroy"},
{ 1, 0xf2, "Yamaha"},
{ 1, 0x73, "Digital Microwave"},
{ 1, 0xf4, "NetLogic Microsystems"},
{ 1, 0x75, "MIMOS Semiconductor"},
{ 1, 0x76, "Advanced Fibre"},
{ 1, 0xf7, "BF Goodrich Data."},
{ 1, 0xf8, "Epigram"},
{ 1, 0x79, "Acbel Polytech"},
{ 1, 0x7a, "Apacer Technology"},
{ 1, 0xfb, "Admor Memory"},
{ 1, 0x7c, "FOXCONN"},
{ 1, 0xfd, "Quadratics Superconductor"},
{ 1, 0xfe, "3COM"},
{ 2, 0x01, "Camintonn"},
{ 2, 0x02, "ISOA"},
{ 2, 0x83, "Agate Semiconductor"},
{ 2, 0x04, "ADMtek"},
{ 2, 0x85, "HYPERTEC"},
{ 2, 0x86, "Adhoc Technologies"},
{ 2, 0x07, "MOSAID Technologies"},
{ 2, 0x08, "Ardent Technologies"},
{ 2, 0x89, "Switchcore"},
{ 2, 0x8a, "Cisco Systems"},
{ 2, 0x0b, "Allayer Technologies"},
{ 2, 0x8c, "WorkX AG (Wichman)"},
{ 2, 0x0d, "Oasis Semiconductor"},
{ 2, 0x0e, "Novanet Semiconductor"},
{ 2, 0x8f, "E-M Solutions"},
{ 2, 0x10, "Power General"},
{ 2, 0x91, "Advanced Hardware Arch."},
{ 2, 0x92, "Inova Semiconductors"},
{ 2, 0x13, "Telocity"},
{ 2, 0x94, "Delkin Devices"},
{ 2, 0x15, "Symagery Microsystems"},
{ 2, 0x16, "C-Port"},
{ 2, 0x97, "SiberCore Technologies"},
{ 2, 0x98, "Southland Microsystems"},
{ 2, 0x19, "Malleable Technologies"},
{ 2, 0x1a, "Kendin Communications"},
{ 2, 0x9b, "Great Technology Microcomputer"},
{ 2, 0x1c, "Sanmina"},
{ 2, 0x9d, "HADCO"},
{ 2, 0x9e, "Corsair"},
{ 2, 0x1f, "Actrans System"},
{ 2, 0x20, "ALPHA Technologies"},
{ 2, 0xa1, "Silicon Laboratories (Cygnal)"},
{ 2, 0xa2, "Artesyn Technologies"},
{ 2, 0x23, "Align Manufacturing"},
{ 2, 0xa4, "Peregrine Semiconductor"},
{ 2, 0x25, "Chameleon Systems"},
{ 2, 0x26, "Aplus Flash Technology"},
{ 2, 0xa7, "MIPS Technologies"},
{ 2, 0xa8, "Chrysalis ITS"},
{ 2, 0x29, "ADTEC"},
{ 2, 0x2a, "Kentron Technologies"},
{ 2, 0xab, "Win Technologies"},
{ 2, 0x2c, "Tachyon Semiconductor (ASIC)"},
{ 2, 0xad, "Extreme Packet Devices"},
{ 2, 0xae, "RF Micro Devices"},
{ 2, 0x2f, "Siemens AG"},
{ 2, 0xb0, "Sarnoff"},
{ 2, 0x31, "Itautec SA"},
{ 2, 0x32, "Radiata"},
{ 2, 0xb3, "Benchmark Elect. (AVEX)"},
{ 2, 0x34, "Legend"},
{ 2, 0xb5, "SpecTek"},
{ 2, 0xb6, "Hi/fn"},
{ 2, 0x37, "Enikia"},
{ 2, 0x38, "SwitchOn Networks"},
{ 2, 0xb9, "AANetcom"},
{ 2, 0xba, "Micro Memory Bank"},
{ 2, 0x3b, "ESS Technology"},
{ 2, 0xbc, "Virata"},
{ 2, 0x3d, "Excess Bandwidth"},
{ 2, 0x3e, "West Bay Semiconductor"},
{ 2, 0xbf, "DSP Group"},
{ 2, 0x40, "Newport Communications"},
{ 2, 0xc1, "Chip2Chip"},
{ 2, 0xc2, "Phobos"},
{ 2, 0x43, "Intellitech"},
{ 2, 0xc4, "Nordic VLSI ASA"},
{ 2, 0x45, "Ishoni Networks"},
{ 2, 0x46, "Silicon Spice"},
{ 2, 0xc7, "Alchemy Semiconductor"},
{ 2, 0xc8, "Agilent Technologies"},
{ 2, 0x49, "Centillium Communications"},
{ 2, 0x4a, "W.L. Gore"},
{ 2, 0xcb, "HanBit Electronics"},
{ 2, 0x4c, "GlobeSpan"},
{ 2, 0xcd, "Element 14"},
{ 2, 0xce, "Pycon"},
{ 2, 0x4f, "Saifun Semiconductors"},
{ 2, 0xd0, "Sibyte,"},
{ 2, 0x51, "MetaLink Technologies"},
{ 2, 0x52, "Feiya Technology"},
{ 2, 0xd3, "I & C Technology"},
{ 2, 0x54, "Shikatronics"},
{ 2, 0xd5, "Elektrobit"},
{ 2, 0xd6, "Megic"},
{ 2, 0x57, "Com-Tier"},
{ 2, 0x58, "Malaysia Micro Solutions"},
{ 2, 0xd9, "Hyperchip"},
{ 2, 0xda, "Gemstone Communications"},
{ 2, 0x5b, "Anadigm (Anadyne)"},
{ 2, 0xdc, "3ParData"},
{ 2, 0x5d, "Mellanox Technologies"},
{ 2, 0x5e, "Tenx Technologies"},
{ 2, 0xdf, "Helix AG"},
{ 2, 0xe0, "Domosys"},
{ 2, 0x61, "Skyup Technology"},
{ 2, 0x62, "HiNT"},
{ 2, 0xe3, "Chiaro"},
{ 2, 0x64, "MDT Technologies"},
{ 2, 0xe5, "Exbit Technology A/S"},
{ 2, 0xe6, "Integrated Technology Express"},
{ 2, 0x67, "AVED Memory"},
{ 2, 0x68, "Legerity"},
{ 2, 0xe9, "Jasmine Networks"},
{ 2, 0xea, "Caspian Networks"},
{ 2, 0x6b, "nCUBE"},
{ 2, 0xec, "Silicon Access Networks"},
{ 2, 0x6d, "FDK"},
{ 2, 0x6e, "High Bandwidth Access"},
{ 2, 0xef, "MultiLink Technology"},
{ 2, 0x70, "BRECIS"},
{ 2, 0xf1, "World Wide Packets"},
{ 2, 0xf2, "APW"},
{ 2, 0x73, "Chicory Systems"},
{ 2, 0xf4, "Xstream Logic"},
{ 2, 0x75, "Fast-Chip"},
{ 2, 0x76, "Zucotto Wireless"},
{ 2, 0xf7, "Realchip"},
{ 2, 0xf8, "Galaxy Power"},
{ 2, 0x79, "eSilicon"},
{ 2, 0x7a, "Morphics Technology"},
{ 2, 0xfb, "Accelerant Networks"},
{ 2, 0x7c, "Silicon Wave"},
{ 2, 0xfd, "SandCraft"},
{ 2, 0xfe, "Elpida"},
{ 3, 0x01, "Solectron"},
{ 3, 0x02, "Optosys Technologies"},
{ 3, 0x83, "Buffalo (Formerly Melco)"},
{ 3, 0x04, "TriMedia Technologies"},
{ 3, 0x85, "Cyan Technologies"},
{ 3, 0x86, "Global Locate"},
{ 3, 0x07, "Optillion"},
{ 3, 0x08, "Terago Communications"},
{ 3, 0x89, "Ikanos Communications"},
{ 3, 0x8a, "Preton Technology"},
{ 3, 0x0b, "Nanya Technology"},
{ 3, 0x8c, "Elite Flash Storage"},
{ 3, 0x0d, "Mysticom"},
{ 3, 0x0e, "LightSand Communications"},
{ 3, 0x8f, "ATI Technologies"},
{ 3, 0x10, "Agere Systems"},
{ 3, 0x91, "NeoMagic"},
{ 3, 0x92, "AuroraNetics"},
{ 3, 0x13, "Golden Empire"},
{ 3, 0x94, "Mushkin"},
{ 3, 0x15, "Tioga Technologies"},
{ 3, 0x16, "Netlist"},
{ 3, 0x97, "TeraLogic"},
{ 3, 0x98, "Cicada Semiconductor"},
{ 3, 0x19, "Centon Electronics"},
{ 3, 0x1a, "Tyco Electronics"},
{ 3, 0x9b, "Magis Works"},
{ 3, 0x1c, "Zettacom"},
{ 3, 0x9d, "Cogency Semiconductor"},
{ 3, 0x9e, "Chipcon AS"},
{ 3, 0x1f, "Aspex Technology"},
{ 3, 0x20, "F5 Networks"},
{ 3, 0xa1, "Programmable Silicon Solutions"},
{ 3, 0xa2, "ChipWrights"},
{ 3, 0x23, "Acorn Networks"},
{ 3, 0xa4, "Quicklogic"},
{ 3, 0x25, "Kingmax Semiconductor"},
{ 3, 0x26, "BOPS"},
{ 3, 0xa7, "Flasys"},
{ 3, 0xa8, "BitBlitz Communications"},
{ 3, 0x29, "eMemory Technology"},
{ 3, 0x2a, "Procket Networks"},
{ 3, 0xab, "Purple Ray"},
{ 3, 0x2c, "Trebia Networks"},
{ 3, 0xad, "Delta Electronics"},
{ 3, 0xae, "Onex Communications"},
{ 3, 0x2f, "Ample Communications"},
{ 3, 0xb0, "Memory Experts Intl"},
{ 3, 0x31, "Astute Networks"},
{ 3, 0x32, "Azanda Network Devices"},
{ 3, 0xb3, "Dibcom"},
{ 3, 0x34, "Tekmos"},
{ 3, 0xb5, "API NetWorks"},
{ 3, 0xb6, "Bay Microsystems"},
{ 3, 0x37, "Firecron"},
{ 3, 0x38, "Resonext Communications"},
{ 3, 0xb9, "Tachys Technologies"},
{ 3, 0xba, "Equator Technology"},
{ 3, 0x3b, "Concept Computer"},
{ 3, 0xbc, "SILCOM"},
{ 3, 0x3d, "3Dlabs"},
{ 3, 0x3e, "c?t Magazine"},
{ 3, 0xbf, "Sanera Systems"},
{ 3, 0x40, "Silicon Packets"},
{ 3, 0xc1, "Viasystems Group"},
{ 3, 0xc2, "Simtek"},
{ 3, 0x43, "Semicon Devices Singapore"},
{ 3, 0xc4, "Satron Handelsges"},
{ 3, 0x45, "Improv Systems"},
{ 3, 0x46, "INDUSYS"},
{ 3, 0xc7, "Corrent"},
{ 3, 0xc8, "Infrant Technologies"},
{ 3, 0x49, "Ritek Corp"},
{ 3, 0x4a, "empowerTel Networks"},
{ 3, 0xcb, "Hypertec"},
{ 3, 0x4c, "Cavium Networks"},
{ 3, 0xcd, "PLX Technology"},
{ 3, 0xce, "Massana Design"},
{ 3, 0x4f, "Intrinsity"},
{ 3, 0xd0, "Valence Semiconductor"},
{ 3, 0x51, "Terawave Communications"},
{ 3, 0x52, "IceFyre Semiconductor"},
{ 3, 0xd3, "Primarion"},
{ 3, 0x54, "Picochip Designs"},
{ 3, 0xd5, "Silverback Systems"},
{ 3, 0xd6, "Jade Star Technologies"},
{ 3, 0x57, "Pijnenburg Securealink"},
{ 3, 0x58, "takeMS International AG"},
{ 3, 0xd9, "Cambridge Silicon Radio"},
{ 3, 0xda, "Swissbit"},
{ 3, 0x5b, "Nazomi Communications"},
{ 3, 0xdc, "eWave System"},
{ 3, 0x5d, "Rockwell Collins"},
{ 3, 0x5e, "Picocel Co. (Paion)"},
{ 3, 0xdf, "Alphamosaic"},
{ 3, 0xe0, "Sandburst"},
{ 3, 0x61, "SiCon Video"},
{ 3, 0x62, "NanoAmp Solutions"},
{ 3, 0xe3, "Ericsson Technology"},
{ 3, 0x64, "PrairieComm"},
{ 3, 0xe5, "Mitac International"},
{ 3, 0xe6, "Layer N Networks"},
{ 3, 0x67, "MtekVision (Atsana)"},
{ 3, 0x68, "Allegro Networks"},
{ 3, 0xe9, "Marvell Semiconductors"},
{ 3, 0xea, "Netergy Microelectronic"},
{ 3, 0x6b, "NVIDIA"},
{ 3, 0xec, "Internet Machines"},
{ 3, 0x6d, "Peak Electronics"},
{ 3, 0x6e, "Litchfield Communication"},
{ 3, 0xef, "Accton Technology"},
{ 3, 0x70, "Teradiant Networks"},
{ 3, 0xf1, "Scaleo Chip"},
{ 3, 0xf2, "Cortina Systems"},
{ 3, 0x73, "RAM Components"},
{ 3, 0xf4, "Raqia Networks"},
{ 3, 0x75, "ClearSpeed"},
{ 3, 0x76, "Matsushita Battery"},
{ 3, 0xf7, "Xelerated"},
{ 3, 0xf8, "SimpleTech"},
{ 3, 0x79, "Utron Technology"},
{ 3, 0x7a, "Astec International"},
{ 3, 0xfb, "AVM"},
{ 3, 0x7c, "Redux Communications"},
{ 3, 0xfd, "Dot Hill Systems"},
{ 3, 0xfe, "TeraChip"},
{ 4, 0x01, "T-RAM"},
{ 4, 0x02, "Innovics Wireless"},
{ 4, 0x83, "Teknovus"},
{ 4, 0x04, "KeyEye Communications"},
{ 4, 0x85, "Runcom Technologies"},
{ 4, 0x86, "RedSwitch"},
{ 4, 0x07, "Dotcast"},
{ 4, 0x08, "Silicon Mountain Memory"},
{ 4, 0x89, "Signia Technologies"},
{ 4, 0x8a, "Pixim"},
{ 4, 0x0b, "Galazar Networks"},
{ 4, 0x8c, "White Electronic Designs"},
{ 4, 0x0d, "Patriot Scientific"},
{ 4, 0x0e, "Neoaxiom"},
{ 4, 0x8f, "3Y Power Technology"},
{ 4, 0x10, "Scaleo Chip"},
{ 4, 0x91, "Potentia Power Systems"},
{ 4, 0x92, "C-guys"},
{ 4, 0x13, "Digital Communications Technology"},
{ 4, 0x94, "Silicon-Based Technology"},
{ 4, 0x15, "Fulcrum Microsystems"},
{ 4, 0x16, "Positivo Informatica"},
{ 4, 0x97, "XIOtech"},
{ 4, 0x98, "PortalPlayer"},
{ 4, 0x19, "Zhiying Software"},
{ 4, 0x1a, "ParkerVision"},
{ 4, 0x9b, "Phonex Broadband"},
{ 4, 0x1c, "Skyworks Solutions"},
{ 4, 0x9d, "Entropic Communications"},
{ 4, 0x9e, "Pacific Force Technology"},
{ 4, 0x1f, "Zensys A/S"},
{ 4, 0x20, "Legend Silicon Corp."},
{ 4, 0xa1, "Sci-worx"},
{ 4, 0xa2, "SMSC (Standard Microsystems)"},
{ 4, 0x23, "Renesas Technology"},
{ 4, 0xa4, "Raza Microelectronics"},
{ 4, 0x25, "Phyworks"},
{ 4, 0x26, "MediaTek"},
{ 4, 0xa7, "Non-cents Productions"},
{ 4, 0xa8, "US Modular"},
{ 4, 0x29, "Wintegra"},
{ 4, 0x2a, "Mathstar"},
{ 4, 0xab, "StarCore"},
{ 4, 0x2c, "Oplus Technologies"},
{ 4, 0xad, "Mindspeed"},
{ 4, 0xae, "Just Young Computer"},
{ 4, 0x2f, "Radia Communications"},
{ 4, 0xb0, "OCZ"},
{ 4, 0x31, "Emuzed"},
{ 4, 0x32, "LOGIC Devices"},
{ 4, 0xb3, "Inphi"},
{ 4, 0x34, "Quake Technologies"},
{ 4, 0xb5, "Vixel"},
{ 4, 0xb6, "SolusTek"},
{ 4, 0x37, "Kongsberg Maritime"},
{ 4, 0x38, "Faraday Technology"},
{ 4, 0xb9, "Altium"},
{ 4, 0xba, "Insyte"},
{ 4, 0x3b, "ARM"},
{ 4, 0xbc, "DigiVision"},
{ 4, 0x3d, "Vativ Technologies"},
{ 4, 0x3e, "Endicott Interconnect Technologies"},
{ 4, 0xbf, "Pericom"},
{ 4, 0x40, "Bandspeed"},
{ 4, 0xc1, "LeWiz Communications"},
{ 4, 0xc2, "CPU Technology"},
{ 4, 0x43, "Ramaxel Technology"},
{ 4, 0xc4, "DSP Group"},
{ 4, 0x45, "Axis Communications"},
{ 4, 0x46, "Legacy Electronics"},
{ 4, 0xc7, "Chrontel"},
{ 4, 0xc8, "Powerchip Semiconductor"},
{ 4, 0x49, "MobilEye Technologies"},
{ 4, 0x4a, "Excel Semiconductor"},
{ 4, 0xcb, "A-DATA Technology"},
{ 4, 0x4c, "VirtualDigm"},
{ 4, 0xcd, "G Skill Intl"},
{ 4, 0xce, "Quanta Computer"},
{ 4, 0x4f, "Yield Microelectronics"},
{ 4, 0xd0, "Afa Technologies"},
{ 4, 0x51, "KINGBOX Technology Co."},
{ 4, 0x52, "Ceva"},
{ 4, 0xd3, "iStor Networks"},
{ 4, 0x54, "Advance Modules"},
{ 4, 0xd5, "Microsoft"},
{ 4, 0xd6, "Open-Silicon"},
{ 4, 0x57, "Goal Semiconductor"},
{ 4, 0x58, "ARC International"},
{ 4, 0xd9, "Simmtec"},
{ 4, 0xda, "Metanoia"},
{ 4, 0x5b, "Key Stream"},
{ 4, 0xdc, "Lowrance Electronics"},
{ 4, 0x5d, "Adimos"},
{ 4, 0x5e, "SiGe Semiconductor"},
{ 4, 0xdf, "Fodus Communications"},
{ 4, 0xe0, "Credence Systems Corp."},
{ 4, 0x61, "Genesis Microchip"},
{ 4, 0x62, "Vihana"},
{ 4, 0xe3, "WIS Technologies"},
{ 4, 0x64, "GateChange Technologies"},
{ 4, 0xe5, "High Density Devices AS"},
{ 4, 0xe6, "Synopsys"},
{ 4, 0x67, "Gigaram"},
{ 4, 0x68, "Enigma Semiconductor"},
{ 4, 0xe9, "Century Micro"},
{ 4, 0xea, "Icera Semiconductor"},
{ 4, 0x6b, "Mediaworks Integrated Systems"},
{ 4, 0xec, "O?Neil Product Development"},
{ 4, 0x6d, "Supreme Top Technology"},
{ 4, 0x6e, "MicroDisplay"},
{ 4, 0xef, "Team Group"},
{ 4, 0x70, "Sinett"},
{ 4, 0xf1, "Toshiba"},
{ 4, 0xf2, "Tensilica"},
{ 4, 0x73, "SiRF Technology"},
{ 4, 0xf4, "Bacoc"},
{ 4, 0x75, "SMaL Camera Technologies"},
{ 4, 0x76, "Thomson SC"},
{ 4, 0xf7, "Airgo Networks"},
{ 4, 0xf8, "Wisair"},
{ 4, 0x79, "SigmaTel"},
{ 4, 0x7a, "Arkados"},
{ 4, 0xfb, "Compete IT Co. KG"},
{ 4, 0x7c, "Eudar Technology"},
{ 4, 0xfd, "Focus Enhancements"},
{ 4, 0xfe, "Xyratex"},
{ 5, 0x01, "Specular Networks"},
{ 5, 0x02, "Patriot Memory (PDP Systems)"},
{ 5, 0x83, "U-Chip Technology Corp."},
{ 5, 0x04, "Silicon Optix"},
{ 5, 0x85, "Greenfield Networks"},
{ 5, 0x86, "CompuRAM"},
{ 5, 0x07, "Stargen"},
{ 5, 0x08, "NetCell"},
{ 5, 0x89, "Excalibrus Technologies"},
{ 5, 0x8a, "SCM Microsystems"},
{ 5, 0x0b, "Xsigo Systems"},
{ 5, 0x8c, "CHIPS & Systems"},
{ 5, 0x0d, "Tier"},
{ 5, 0x0e, "CWRL Labs"},
{ 5, 0x8f, "Teradici"},
{ 5, 0x10, "Gigaram"},
{ 5, 0x91, "g2 Microsystems"},
{ 5, 0x92, "PowerFlash Semiconductor"},
{ 5, 0x13, "P.A. Semi"},
{ 5, 0x94, "NovaTech Solutions, S.A."},
{ 5, 0x15, "c2 Microsystems"},
{ 5, 0x16, "Level5 Networks"},
{ 5, 0x97, "COS Memory AG"},
{ 5, 0x98, "Innovasic Semiconductor"},
{ 5, 0x19, "02IC Co."},
{ 5, 0x1a, "Tabula,"},
{ 5, 0x9b, "Crucial Technology"},
{ 5, 0x1c, "Chelsio Communications"},
{ 5, 0x9d, "Solarflare Communications"},
{ 5, 0x9e, "Xambala"},
{ 5, 0x1f, "EADS Astrium"},
{ 5, 0x20, "Terra Semiconductor"},
{ 5, 0xa1, "Imaging Works"},
{ 5, 0xa2, "Astute Networks"},
{ 5, 0x23, "Tzero"},
{ 5, 0xa4, "Emulex"},
{ 5, 0x25, "Power-One"},
{ 5, 0x26, "Pulse~LINK"},
{ 5, 0xa7, "Hon Hai Precision Industry"},
{ 5, 0xa8, "White Rock Networks"},
{ 5, 0x29, "Telegent Systems USA"},
{ 5, 0x2a, "Atrua Technologies"},
{ 5, 0xab, "Acbel Polytech"},
{ 5, 0x2c, "eRide"},
{ 5, 0xad, "ULi Electronics"},
{ 5, 0xae, "Magnum Semiconductor"},
{ 5, 0x2f, "neoOne Technology"},
{ 5, 0xb0, "Connex Technology"},
{ 5, 0x31, "Stream Processors"},
{ 5, 0x32, "Focus Enhancements"},
{ 5, 0xb3, "Telecis Wireless"},
{ 5, 0x34, "uNav Microelectronics"},
{ 5, 0xb5, "Tarari"},
{ 5, 0xb6, "Ambric"},
{ 5, 0x37, "Newport Media"},
{ 5, 0x38, "VMTS"},
{ 5, 0xb9, "Enuclia Semiconductor"},
{ 5, 0xba, "Virtium Technology"},
{ 5, 0x3b, "Solid State System Co."},
{ 5, 0xbc, "Kian Tech LLC"},
{ 5, 0x3d, "Artimi"},
{ 5, 0x3e, "Power Quotient International"},
{ 5, 0xbf, "Avago Technologies"},
{ 5, 0x40, "ADTechnology"},
{ 5, 0xc1, "Sigma Designs"},
{ 5, 0xc2, "SiCortex"},
{ 5, 0x43, "Ventura Technology Group"},
{ 5, 0xc4, "eASIC"},
{ 5, 0x45, "M.H.S. SAS"},
{ 5, 0x46, "Micro Star International"},
{ 5, 0xc7, "Rapport"},
{ 5, 0xc8, "Makway International"},
{ 5, 0x49, "Broad Reach Engineering Co."},
{ 5, 0x4a, "Semiconductor Mfg Intl Corp"},
{ 5, 0xcb, "SiConnect"},
{ 5, 0x4c, "FCI USA"},
{ 5, 0xcd, "Validity Sensors"},
{ 5, 0xce, "Coney Technology Co."},
{ 5, 0x4f, "Spans Logic"},
{ 5, 0xd0, "Neterion"},
{ 5, 0x51, "Qimonda"},
{ 5, 0x52, "New Japan Radio Co."},
{ 5, 0xd3, "Velogix"},
{ 5, 0x54, "Montalvo Systems"},
{ 5, 0xd5, "iVivity"},
{ 5, 0xd6, "Walton Chaintech"},
{ 5, 0x57, "AENEON"},
{ 5, 0x58, "Lorom Industrial Co."},
{ 5, 0xd9, "Radiospire Networks"},
{ 5, 0xda, "Sensio Technologies"},
{ 5, 0x5b, "Nethra Imaging"},
{ 5, 0xdc, "Hexon Technology Pte"},
{ 5, 0x5d, "CompuStocx (CSX)"},
{ 5, 0x5e, "Methode Electronics"},
{ 5, 0xdf, "Connect One"},
{ 5, 0xe0, "Opulan Technologies"},
{ 5, 0x61, "Septentrio NV"},
{ 5, 0x62, "Goldenmars Technology"},
{ 5, 0xe3, "Kreton"},
{ 5, 0x64, "Cochlear"},
{ 5, 0xe5, "Altair Semiconductor"},
{ 5, 0xe6, "NetEffect"},
{ 5, 0x67, "Spansion"},
{ 5, 0x68, "Taiwan Semiconductor Mfg"},
{ 5, 0xe9, "Emphany Systems"},
{ 5, 0xea, "ApaceWave Technologies"},
{ 5, 0x6b, "Mobilygen"},
{ 5, 0xec, "Tego"},
{ 5, 0x6d, "Cswitch"},
{ 5, 0x6e, "Haier (Beijing) IC Design Co."},
{ 5, 0xef, "MetaRAM"},
{ 5, 0x70, "Axel Electronics Co."},
{ 5, 0xf1, "Tilera"},
{ 5, 0xf2, "Aquantia"},
{ 5, 0x73, "Vivace Semiconductor"},
{ 5, 0xf4, "Redpine Signals"},
{ 5, 0x75, "Octalica"},
{ 5, 0x76, "InterDigital Communications"},
{ 5, 0xf7, "Avant Technology"},
{ 5, 0xf8, "Asrock"},
{ 5, 0x79, "Availink"},
{ 5, 0x7a, "Quartics"},
{ 5, 0xfb, "Element CXI"},
{ 5, 0x7c, "Innovaciones Microelectronicas"},
{ 5, 0xfd, "VeriSilicon Microelectronics"},
{ 5, 0xfe, "W5 Networks"},
{ 6, 0x01, "MOVEKING"},
{ 6, 0x02, "Mavrix Technology"},
{ 6, 0x83, "CellGuide"},
{ 6, 0x04, "Faraday Technology"},
{ 6, 0x85, "Diablo Technologies"},
{ 6, 0x86, "Jennic"},
{ 6, 0x07, "Octasic"},
{ 6, 0x08, "Molex"},
{ 6, 0x89, "3Leaf Networks"},
{ 6, 0x8a, "Bright Micron Technology"},
{ 6, 0x0b, "Netxen"},
{ 6, 0x8c, "NextWave Broadband"},
{ 6, 0x0d, "DisplayLink"},
{ 6, 0x0e, "ZMOS Technology"},
{ 6, 0x8f, "Tec-Hill"},
{ 6, 0x10, "Multigig"},
{ 6, 0x91, "Amimon"},
{ 6, 0x92, "Euphonic Technologies"},
{ 6, 0x13, "BRN Phoenix"},
{ 6, 0x94, "InSilica"},
{ 6, 0x15, "Ember"},
{ 6, 0x16, "Avexir Technologies"},
{ 6, 0x97, "Echelon"},
{ 6, 0x98, "Edgewater Computer Systems"},
{ 6, 0x19, "XMOS Semiconductor"},
{ 6, 0x1a, "GENUSION"},
{ 6, 0x9b, "Memory Corp NV"},
{ 6, 0x1c, "SiliconBlue Technologies"},
{ 6, 0x9d, "Rambus"},
{ 6, 0x9e, "Andes Technology"},
{ 6, 0x1f, "Coronis Systems"},
{ 6, 0x20, "Achronix Semiconductor"},
{ 6, 0xa1, "Siano Mobile Silicon"},
{ 6, 0xa2, "Semtech"},
{ 6, 0x23, "Pixelworks"},
{ 6, 0xa4, "Gaisler Research AB"},
{ 6, 0x25, "Teranetics"},
{ 6, 0x26, "Toppan Printing Co."},
{ 6, 0xa7, "Kingxcon"},
{ 6, 0xa8, "Silicon Integrated Systems"},
{ 6, 0x29, "I-O Data Device"},
{ 6, 0x2a, "NDS Americas"},
{ 6, 0xab, "Solomon Systech Limited"},
{ 6, 0x2c, "On Demand Microelectronics"},
{ 6, 0xad, "Amicus Wireless"},
{ 6, 0xae, "SMARDTV SNC"},
{ 6, 0x2f, "Comsys Communication"},
{ 6, 0xb0, "Movidia"},
{ 6, 0x31, "Javad GNSS"},
{ 6, 0x32, "Montage Technology Group"},
{ 6, 0xb3, "Trident Microsystems"},
{ 6, 0x34, "Super Talent"},
{ 6, 0xb5, "Optichron"},
{ 6, 0xb6, "Future Waves UK"},
{ 6, 0x37, "SiBEAM"},
{ 6, 0x38, "Inicore,"},
{ 6, 0xb9, "Virident Systems"},
{ 6, 0xba, "M2000"},
{ 6, 0x3b, "ZeroG Wireless"},
{ 6, 0xbc, "Gingle Technology Co."},
{ 6, 0x3d, "Space Micro"},
{ 6, 0x3e, "Wilocity"},
{ 6, 0xbf, "Novafora, Ic."},
{ 6, 0x40, "iKoa"},
{ 6, 0xc1, "ASint Technology"},
{ 6, 0xc2, "Ramtron"},
{ 6, 0x43, "Plato Networks"},
{ 6, 0xc4, "IPtronics AS"},
{ 6, 0x45, "Infinite-Memories"},
{ 6, 0x46, "Parade Technologies"},
{ 6, 0xc7, "Dune Networks"},
{ 6, 0xc8, "GigaDevice Semiconductor"},
{ 6, 0x49, "Modu"},
{ 6, 0x4a, "CEITEC"},
{ 6, 0xcb, "Northrop Grumman"},
{ 6, 0x4c, "XRONET"},
{ 6, 0xcd, "Sicon Semiconductor AB"},
{ 6, 0xce, "Atla Electronics Co."},
{ 6, 0x4f, "TOPRAM Technology"},
{ 6, 0xd0, "Silego Technology"},
{ 6, 0x51, "Kinglife"},
{ 6, 0x52, "Ability Industries"},
{ 6, 0xd3, "Silicon Power Computer & Communications"},
{ 6, 0x54, "Augusta Technology"},
{ 6, 0xd5, "Nantronics Semiconductors"},
{ 6, 0xd6, "Hilscher Gesellschaft"},
{ 6, 0x57, "Quixant"},
{ 6, 0x58, "Percello"},
{ 6, 0xd9, "NextIO"},
{ 6, 0xda, "Scanimetrics"},
{ 6, 0x5b, "FS-Semi Company"},
{ 6, 0xdc, "Infinera"},
{ 6, 0x5d, "SandForce"},
{ 6, 0x5e, "Lexar Media"},
{ 6, 0xdf, "Teradyne"},
{ 6, 0xe0, "Memory Exchange Corp."},
{ 6, 0x61, "Suzhou Smartek Electronics"},
{ 6, 0x62, "Avantium"},
{ 6, 0xe3, "ATP Electronics"},
{ 6, 0x64, "Valens Semiconductor"},
{ 6, 0xe5, "Agate Logic"},
{ 6, 0xe6, "Netronome"},
{ 6, 0x67, "Zenverge"},
{ 6, 0x68, "N-trig"},
{ 6, 0xe9, "SanMax Technologies"},
{ 6, 0xea, "Contour Semiconductor"},
{ 6, 0x6b, "TwinMOS"},
{ 6, 0xec, "Silicon Systems"},
{ 6, 0x6d, "V-Color Technology"},
{ 6, 0x6e, "Certicom"},
{ 6, 0xef, "JSC ICC Milandr"},
{ 6, 0x70, "PhotoFast Global"},
{ 6, 0xf1, "InnoDisk"},
{ 6, 0xf2, "Muscle Power"},
{ 6, 0x73, "Energy Micro"},
{ 6, 0xf4, "Innofidei"},
{ 9, 0xff, ""}
};
#define VEN_MAP_SIZE (sizeof(vendorMap)/sizeof(VenIdName))
#endif
branches/diebuche/i386/libsaio/platform.c
2525
2626
2727
28
2829
2930
3031
......
3435
3536
3637
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
3753
3854
55
3956
4057
4158
42
43
44
59
60
61
4562
PlatformInfo_t Platform;
/** Return if a CPU feature specified by feature is activated (true) or not (false) */
bool platformCPUFeature(uint32_t feature)
{
if (Platform.CPU.Features & feature) {
}
}
/** scan mem for memory autodection purpose */
void scan_mem() {
bool useAutodetection = false;
getBoolForKey(kUseMemDetect, &useAutodetection, &bootInfo->bootConfig);
if (useAutodetection) {
scan_memory(&Platform);
scan_spd(&Platform);
}
}
/**
Scan platform hardware information, called by the main entry point (common_boot() )
_before_ bootConfig xml parsing settings are loaded
*/
void scan_platform(void)
{
memset(&Platform, 0, sizeof(Platform));
build_pci_dt();
scan_cpu(&Platform);
scan_memory(&Platform);
scan_spd(&Platform);
// disabled for now as options can't be read yet here:
// scan_mem();
}
branches/diebuche/i386/libsaio/cpu.c
369369
370370
371371
372
373
372
374373
375374
DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
printf("(Press a key to continue...)\n");
getc();
pause();
#endif
}
branches/diebuche/i386/libsaio/platform.h
1111
1212
1313
14
1415
1516
1617
......
6465
6566
6667
67
68
6869
6970
7071
......
7475
7576
7677
77
78
79
80
81
78
79
80
81
82
83
84
85
86
87
88
8289
8390
8491
......
104111
105112
106113
107
108114
109115
110116
extern bool platformCPUFeature(uint32_t);
extern void scan_platform(void);
extern void dumpPhysAddr(const char * title, void * a, int len);
/* CPUID index into cpuid_raw */
#define CPUID_00
#define SMB_MEM_CHANNEL_TRIPLE3
/* Maximum number of ram slots */
#define MAX_RAM_SLOTS12
#define MAX_RAM_SLOTS8
#define RAM_SLOT_ENUMERATOR{0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11}
/* Maximum number of SPD bytes */
#define UUID_LEN16
typedef struct _RamSlotInfo_t {
boolInUse;
uint8_tType;
charVendor[64];
charPartNo[64];
charSerialNo[16];
uint32_t ModuleSize;// Size of Module in MB
uint32_t Frequency; // in Mhz
const char*Vendor;
const char*PartNo;
const char*SerialNo;
char*spd;// SPD Dump
boolInUse;
uint8_tType;
uint8_t BankConnections; // table type 6, see (3.3.7)
uint8_t BankConnCnt;
} RamSlotInfo_t;
typedef struct _PlatformInfo_t {
struct RAM {
RamSlotInfo_tDIMM[MAX_RAM_SLOTS];// Information about each slot
uint64_tFrequency;// Ram Frequency
} RAM;
struct DMI {
branches/diebuche/i386/libsaio/915resolution.c
1
2
3
4
5
6
7
8
91
102
113
......
2416
2517
2618
19
2720
2821
2922
30
23
24
3125
3226
3327
3428
3529
30
3631
3732
3833
......
7065
7166
7267
68
69
70
71
72
73
74
75
7376
7477
7578
......
9598
9699
97100
101
102
103
104
98105
99106
100107
101
108
109
110
111
112
113
114
115
116
117
102118
103119
104120
105
121
106122
107123
108124
109
110
125
126
111127
112128
113
129
114130
115131
116132
117133
118
119134
120135
121136
......
154169
155170
156171
157
172
158173
159174
160175
161176
162177
178
179
180
181
163182
164183
165184
166185
167186
168187
169
170188
171189
172
190
173191
174192
175193
......
186204
187205
188206
189
207
190208
191209
192210
193211
194
212
213
214
215
216
217
218
219
220
221
195222
196
223
197224
198
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
199240
200241
201242
202243
203
204
205
244
245
206246
247
248
249
250
251
252
253
254
255
256
257
258
207259
208260
261
209262
210263
211264
......
217270
218271
219272
273
220274
221
222
275
276
223277
224278
225279
......
241295
242296
243297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
244317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
245372
246373
247374
248375
249376
250
377
251378
252379
253380
......
260387
261388
262389
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
281407
282
283
284
408
409
410
285411
286412
287413
......
314440
315441
316442
443
317444
318445
319446
447
448
449
450
451
452
320453
321454
322455
323456
324457
458
325459
326460
327461
328
329462
330463
331464
......
360493
361494
362495
496
363497
364498
365499
500
501
502
503
504
505
366506
367507
368508
369509
370510
371
511
512
372513
373514
374515
......
381522
382523
383524
384
385525
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
526
527
528
529
437530
438531
532
533
534
535
536
537
538
439539
440540
441541
442542
443543
444544
445
446
545
546
547
447548
448
449
450
549
550
551
451552
452553
453
454
455
456
554
555
556
557
457558
458559
459560
460
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
461611
462612
463613
......
551701
552702
553703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
554930
555931
556932
......
558934
559935
560936
561
562
563
564
565
566
567
/* Copied from 915 resolution created by steve tomljenovic
* This source code is into the public domain.
*
* Included to Chameleon RC3 by meklort
*
* Included to RC4 and edited by deviato to match more intel chipsets
*
*/
/* Copied from 915 resolution created by steve tomljenovic
*
#include "libsaio.h"
#include "915resolution.h"
#include "../boot2/graphics.h"
char * chipset_type_names[] = {
"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
"946GZ", "G965", "Q965", "965GM", "G41", "G31", "G45", "GM45", "500"
"946GZ", "955X", "G965", "Q965", "965GM", "975X",
"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
};
char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
int freqs[] = { 60, 75, 85 };
UInt32 get_chipset_id(void) {
outl(0xcf8, 0x80000000);
case 0x27708086:
type = CT_945G;
break;
case 0x27748086:
type = CT_955X;
break;
case 0x277c8086:
type = CT_975X;
break;
case 0x27a08086:
type = CT_945GM;
type = CT_965GM;
break;
case 0x29e08086:
type = CT_X48;
break;
case 0x2a408086:
type = CT_GM45;
break;
case 0x2e108086:
case 0X2e908086:
type = CT_B43;
break;
case 0x2e208086:
type = CT_P45;
break;
case 0x2e308086:
type = CT_G41;
break;
case 0x29c08086:
type = CT_G31;
break;
case 0x2e208086:
case 0x29208086:
type = CT_G45;
break;
case 0x81008086:
type = CT_500;
break;
default:
type = CT_UNKWN;
break;
}
}
/*printf("r1 = %d r2 = %d\n", r1, r2);*/
/* printf("r1 = %d r2 = %d\n", r1, r2); */
}
return (r2-r1-6) % entry_size == 0;
}
char detect_ati_bios_type(vbios_map * map) {
return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;
}
void close_vbios(vbios_map * map);
vbios_map * open_vbios(chipset_type forced_chipset) {
UInt32 z;
vbios_map * map = NEW(vbios_map);
for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
/*
* Determine chipset
*/
*/
if (forced_chipset == CT_UNKWN) {
map->chipset_id = get_chipset_id();
* Map the video bios to memory
*/
map->bios_ptr=(char*)VBIOS_START;
map->bios_ptr = (unsigned char *)VBIOS_START;
/*
* check if we have ATI Radeon
*/
map->ati_tables.base = map->bios_ptr;
map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") != 0) {
printf("Not an AtomBios Card\n");
} else {
map->bios = BT_ATI_1;
}
/*
* check if we have NVIDIA
* check if we have NVidia
*/
if (map->bios != BT_ATI_1) {
int i = 0;
while (i < 512) { // we don't need to look through the whole bios, just the first 512 bytes
if ((map->bios_ptr[i] == 'N')
&& (map->bios_ptr[i+1] == 'V')
&& (map->bios_ptr[i+2] == 'I')
&& (map->bios_ptr[i+3] == 'D'))
{
map->bios = BT_NVDA;
break;
}
i++;
}
}
/*
* check if we have Intel
*/
/*
* check for others
*/
/*if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");
printf("Chipset Id: %x\n", map->chipset_id);
printf("Please report this problem to stomljen@yahoo.com\n");
close_vbios(map);
return 0;
}*/
/*
* check for others
*/
if (map->chipset == CT_UNKWN) {
printf("Unknown chipset type and unrecognized bios.\n");
printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");
printf("Chipset Id: %x\n", map->chipset_id);
* Figure out where the mode table is
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))
{
char* p = map->bios_ptr + 16;
char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
unsigned char* p = map->bios_ptr + 16;
unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
while (p < limit && map->mode_table == 0) {
vbios_mode * mode_ptr = (vbios_mode *) p;
close_vbios(map);
return 0;
}
}
else if (map->bios == BT_ATI_1)
{
map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;
unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing;
ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);
map->ati_mode_table = (char *) &std_vesa->aModeTimings;
if (map->ati_mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
close_vbios(map);
return 0;
}
map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);
if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;
}
else if (map->bios == BT_NVDA)
{
unsigned short nv_data_table_offset = 0;
unsigned short nv_modeline_2_offset = 0;
unsigned short * nv_data_table;
NV_VESA_TABLE * std_vesa;
int i = 0;
while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only
if ((map->bios_ptr[i] == 0x44)
&& (map->bios_ptr[i+1] == 0x01)
&& (map->bios_ptr[i+2] == 0x04)
&& (map->bios_ptr[i+3] == 0x00)) {
nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
break;
}
i++;
}
while (i < VBIOS_SIZE) { //We don't know how to locate it other way
if ((map->bios_ptr[i] == 0x00) && (map->bios_ptr[i+1] == 0x04) //this is the first 1024 modeline.
&& (map->bios_ptr[i+2] == 0x00) && (map->bios_ptr[i+3] == 0x03)
&& (map->bios_ptr[i+4] == 0x80)
&& (map->bios_ptr[i+5] == 0x2F)
&& (map->bios_ptr[i+6] == 0x10)
&& (map->bios_ptr[i+7] == 0x10)
&& (map->bios_ptr[i+8] == 0x05)) {
nv_modeline_2_offset = (unsigned short) i;
break;
}
i++;
}
nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
map->nv_mode_table = (char *) std_vesa->sModelines;
if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {
map->nv_mode_table_2 = NULL;
} else {
map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;
}
if (map->nv_mode_table == 0) {
printf("Unable to locate the mode table.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
close_vbios(map);
return 0;
}
map->mode_table_size = std_vesa->sHeader.usTable_Size;
}
/*
* Determine size of mode table
*/
{
if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
vbios_mode * mode_ptr = map->mode_table;
while (mode_ptr->mode != 0xff) {
* Figure out what type of bios we have
* order of detection is important
*/
if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
map->bios = BT_3;
}
else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
map->bios = BT_2;
}
else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
map->bios = BT_1;
}
else {
printf("Unable to determine bios type.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
printf("Mode Table Entries: %u\n", map->mode_table_size);
if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
map->bios = BT_3;
}
else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
map->bios = BT_2;
}
else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
map->bios = BT_1;
}
else {
printf("Unable to determine bios type.\n");
printf("Please run the program 'dump_bios' as root and\n");
printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
printf("Chipset: %s\n", chipset_type_names[map->chipset]);
printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
//THis is now
return 0;
printf("Mode Table Entries: %u\n", map->mode_table_size);
return 0;
}
}
return map;
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
map->b1 = inb(0xcfd);
map->b2 = inb(0xcfe);
outl(0xcf8, 0x80000090);
outb(0xcfd, 0x33);
outb(0xcfe, 0x33);
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x8000005a);
outl(0xcf8, 0x80000090);
outb(0xcfd, map->b1);
outb(0xcfe, map->b2);
break;
}
#endif
}
void list_modes(vbios_map *map, UInt32 raw) {
UInt32 i, x, y;
for (i=0; i < map->mode_table_size; i++) {
switch(map->bios) {
case BT_1:
{
vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
x = ((((UInt32) res->x2) & 0xf0) << 4) | res->x1;
y = ((((UInt32) res->y2) & 0xf0) << 4) | res->y1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
if (raw)
{
printf("Mode %02x (raw) :\n\t%02x %02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
}
}
break;
case BT_2:
{
vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
x = res->modelines[0].x1+1;
y = res->modelines[0].y1+1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
}
break;
case BT_3:
{
vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
x = res->modelines[0].x1+1;
y = res->modelines[0].y1+1;
if (x != 0 && y != 0) {
printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
}
}
break;
case BT_UNKWN:
break;
}
}
void save_vbios(vbios_map * map)
{
map->bios_backup_ptr = malloc(VBIOS_SIZE);
bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);
}
void restore_vbios(vbios_map * map)
{
bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);
}
static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
{
UInt32 hbl, vbl, vfreq;
vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
vfreq = vbl * freq;
hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
+ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
+ (70 + 300000 / vfreq) / 16 + 0);
*vsyncstart = y;
*vsyncend = y + 3;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
*clock = (x + hbl) * vfreq / 1000;
}
void set_mode(vbios_map * map, /*UInt32 mode,*/ UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
unsigned long *clock,
UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)
{
UInt32 hbl, hbp, vbl, vsync, hperiod;
if (!(y % 3) && ((y * 4 / 3) == x))
vsync = 4;
else if (!(y % 9) && ((y * 16 / 9) == x))
vsync = 5;
else if (!(y % 10) && ((y * 16 / 10) == x))
vsync = 6;
else if (!(y % 4) && ((y * 5 / 4) == x))
vsync = 7;
else if (!(y % 9) && ((y * 15 / 9) == x))
vsync = 7;
else /* Custom */
vsync = 10;
if (!reduced) {
hperiod = (1000000/freq - 550) / (y + 3);
vbl = y + (550/hperiod) + 3;
hbp = 30 - ((300*hperiod)/1000);
hbl = (x * hbp) / (100 - hbp);
*vsyncstart = y + 6;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
} else {
hperiod = (1000000/freq - 460) / y;
vbl = y + 460/hperiod + 1;
hbl = 160;
*vsyncstart = y + 3;
*vsyncend = *vsyncstart + vsync;
*vblank = vbl - 1;
*hsyncstart = x + hbl / 2 - 32;
*hsyncend = x + hbl / 2 - 1;
*hblank = x + hbl - 1;
}
*clock = (x + hbl) * 1000 / hperiod;
}
void set_mode(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
UInt32 xprev, yprev;
UInt32 i = 0, j;// patch first available mode
}
}
break;
case BT_ATI_1:
{
edid_mode mode;
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table;
mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
if ( mode_n == modeEndOfList )
{
minfo.XResolution = 1024;
minfo.YResolution = 768;
}
int m_status = getMode(&mode);
if (m_status || (mode.h_active != x)) {
vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
bzero(modeline, sizeof(vbios_modeline_type2));
cvt_timings(x, y, 60, &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank, FALSE);
mode.pixel_clock = modeline->clock /10;
mode.h_active = x;
mode.h_sync_offset = modeline->hsyncstart - x;
mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
mode.h_blanking = modeline->hblank - x;
mode.v_active = y;
mode.v_sync_offset = modeline->vsyncstart - y;
mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
mode.v_blanking = modeline->vblank - y;
free(modeline);
m_status = 0;
}
if (!m_status) {
while (i < (map->mode_table_size / sizeof(ATOM_MODE_TIMING)))
{
if (mode_timing[i].usCRTC_H_Disp == minfo.XResolution) {
mode_timing[i].usCRTC_H_Total = mode.h_active + mode.h_blanking;
mode_timing[i].usCRTC_H_Disp = mode.h_active;
mode_timing[i].usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset;
mode_timing[i].usCRTC_H_SyncWidth = mode.h_sync_width;
mode_timing[i].usCRTC_V_Total = mode.v_active + mode.v_blanking;
mode_timing[i].usCRTC_V_Disp = mode.v_active;
mode_timing[i].usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset;
mode_timing[i].usCRTC_V_SyncWidth = mode.v_sync_width;
mode_timing[i].usPixelClock = mode.pixel_clock;
}
i++;
}
}
}
break;
case BT_ATI_2:
{
edid_mode mode;
VBEModeInfoBlock minfo;
unsigned short mode_n;
unsigned short vesaVersion;
ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table;
mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
if ( mode_n == modeEndOfList )
{
minfo.XResolution = 1024;
minfo.YResolution = 768;
}
int m_status = getMode(&mode);
if (m_status || (mode.h_active != x)) {
vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
bzero(modeline, sizeof(vbios_modeline_type2));
cvt_timings(x, y, 60, &modeline->clock,
&modeline->hsyncstart, &modeline->hsyncend,
&modeline->hblank, &modeline->vsyncstart,
&modeline->vsyncend, &modeline->vblank, FALSE);
mode.pixel_clock = modeline->clock /10;
mode.h_active = x;
mode.h_sync_offset = modeline->hsyncstart - x;
mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
mode.h_blanking = modeline->hblank - x;
mode.v_active = y;
mode.v_sync_offset = modeline->vsyncstart - y;
mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
mode.v_blanking = modeline->vblank - y;
free(modeline);
m_status = 0;
}
if (!m_status) {
while (i < (map->mode_table_size / sizeof(ATOM_DTD_FORMAT)))
{