Chameleon

Chameleon Commit Details

Date:2014-01-11 10:02:25 (5 years 10 months ago)
Author:Chuck Fry
Commit:2329
Parents: 2328
Message:Merged against trunk r2327
Changes:
M/branches/chucko/i386/libsaio/cache.c
M/branches/chucko
M/branches/chucko/i386/libsaio/gma.c
M/branches/chucko/i386/boot2/boot.c
M/branches/chucko/i386/boot2/boot2.s
M/branches/chucko/i386/libsaio/dram_controllers.c
M/branches/chucko/i386/libsa/printf.c
M/branches/chucko/i386/libsaio/ntfs.c
M/branches/chucko/i386/libsaio/nvidia.c
M/branches/chucko/i386/boot2/boot.h
M/branches/chucko/i386/boot2/modules.c
M/branches/chucko/i386/libsaio/pci.c
M/branches/chucko/i386/libsaio/bootstruct.h
M/branches/chucko/i386/libsa/string.c
M/branches/chucko/i386/libsaio/aml_generator.c
M/branches/chucko/i386/libsaio/pci.h
M/branches/chucko/i386/libsaio/acpi_patcher.c
M/branches/chucko/i386/libsaio/aml_generator.h
M/branches/chucko/i386/libsaio/allocate.c
M/branches/chucko/i386/libsaio/platform.c
M/branches/chucko/i386/libsaio/bootargs.h
M/branches/chucko/i386/libsaio/msdos.c
M/branches/chucko/i386/boot2/gui.c
M/branches/chucko/i386/libsaio/platform.h
M/branches/chucko/i386/libsaio/disk.c
M/branches/chucko/i386/libsaio/device_inject.c
M/branches/chucko/i386/libsaio/saio_internal.h
M/branches/chucko/i386/libsaio/smbios.c
M/branches/chucko/i386/boot2/ramdisk.c
M/branches/chucko/i386/boot2/options.c
M/branches/chucko/i386/libsaio/device_inject.h
M/branches/chucko/i386/libsaio/asm.s
M/branches/chucko/i386/libsaio/smbios.h
M/branches/chucko/i386/libsaio/bios.h
M/branches/chucko/i386/config/confdata.c
M/branches/chucko/i386/boot2/picopng.c
M/branches/chucko/i386/libsaio/console.c
M/branches/chucko/i386/boot2/graphics.c
M/branches/chucko/i386/libsaio/xml.h
M/branches/chucko/i386/libsaio/fdisk.h
M/branches/chucko/i386/libsaio/base64-decode.c
M/branches/chucko/i386/libsaio/efi.h
M/branches/chucko/i386/libsaio/pci_root.c
M/branches/chucko/i386/libsaio/device_tree.c
M/branches/chucko/i386/libsaio/befs.c
M/branches/chucko/i386/libsaio/hfs.c
M/branches/chucko/i386/libsaio/biosfn.c
M/branches/chucko/i386/boot2/drivers.c
M/branches/chucko/i386/libsaio/device_tree.h
M/branches/chucko/i386/libsaio/memvendors.h
M/branches/chucko/i386/libsaio/saio_types.h
M/branches/chucko/i386/libsaio/spd.c
M/branches/chucko/i386/libsaio/cpu.c
M/branches/chucko/i386/config/symbol.c
M/branches/chucko/i386/libsaio/fake_efi.c
M/branches/chucko/i386/libsaio/smbios_getters.c
M/branches/chucko/i386/libsaio/spd.h
M/branches/chucko/i386/libsaio/smbios_decode.c

File differences

branches/chucko/i386/libsaio/asm.s
8282
8383
8484
85
85
8686
8787
8888
......
348348
349349
350350
351
351
352352
353353
354354
* New boot0 (boot1 has been deprecated). Booter must now reside in its own partition, no disk label required.
*
* Revision 1.1.1.2 1999/08/04 21:16:57 wsanchez
* Impoort of boot-66
* Import of boot-66
*
* Revision 1.3 1999/08/04 21:12:12 wsanchez
* Update APSL
push %ebp
mov %esp, %ebp
mov 0xc(%ebp), %eax // argument to program
mov 0xc(%ebp), %eax // argument to program - bootargs to mach_kernel
mov 0x8(%ebp), %ecx // entry offset
mov $0x28, %ebx // segment
push %ebx
branches/chucko/i386/libsaio/console.c
5050
5151
5252
53
54
53
54
5555
5656
5757
......
6969
7070
7171
72
73
72
73
7474
7575
7676
......
8383
8484
8585
86
86
8787
8888
8989
......
9999
100100
101101
102
102
103103
104
104105
105
106
106107
108
107109
108110
109111
......
115117
116118
117119
118
120
119121
122
120123
121124
122125
......
129132
130133
131134
132
133
135
134136
135137
136138
137139
138
139
140
140141
141
142
142143
143144
144145
145
146
146147
147148
148149
149150
150
151
151152
152
153
154
155
153
154
155
156
157
156158
157159
158160
......
165167
166168
167169
168
170
169171
170172
171173
172174
173175
174
176
175177
176
178
177179
178
180
179181
182
180183
181184
182185
183186
184187
185
188
186189
190
187191
188
192
189193
194
190195
191196
192197
......
194199
195200
196201
197
202
198203
199204
200205
201206
202
207
203208
204209
205
206
207
210
211
208212
209
213
210214
211
215
216
212217
213218
214219
215220
216221
217
222
218223
224
219225
220
226
221227
228
222229
223230
224231
225232
226233
227234
228
229
235
236
230237
231238
232239
233240
234
235
236
237
241
242
243
244
238245
239
246
240247
248
241249
242
250
243251
244252
245253
extern intvprf(const char * fmt, va_list ap);
bool gVerboseMode;
bool gErrors;
bool gVerboseMode = false;
bool gErrors = false;
/*
* Azi: Doubled available log size; this seems to fix some hangs and instant reboots caused by
struct putc_info //Azi: exists on gui.c & printf.c
{
char * str;
char * last_str;
char * str;
char * last_str;
};
static int
return 0;
}
*(pi->str)++ = c;
return c;
return c;
}
void initBooterLog(void)
va_list ap;
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return;
}
va_start(ap, fmt);
pi.str = cursor;
void setupBooterLog(void)
{
if (!msgbuf)
if (!msgbuf) {
return;
}
Node *node = DT__FindNode("/", false);
if (node)
*/
int putchar(int c)
{
if ( c == '\t' )
{
if ( c == '\t' ) {
for (c = 0; c < 8; c++) bios_putchar(' ');
return c;
}
if ( c == '\n' )
{
if ( c == '\n' ) {
bios_putchar('\r');
}
}
bios_putchar(c);
return c;
return c;
}
int getc()
{
int c = bgetc();
int c = bgetc();
if ((c & 0xff) == 0)
return c;
else
return (c & 0xff);
if ((c & 0xff) == 0) {
return c;
} else {
return (c & 0xff);
}
}
// Read and echo a character from console. This doesn't echo backspace
//if ( c == '\r' ) c = '\n';
//if ( c >= ' ' && c < 0x7f) putchar(c);
return (c);
}
int printf(const char * fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
{
// Kabyl: BooterLog
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return 0;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return 0;
}
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
}
va_end(ap);
return 0;
return 0;
}
int verbose(const char * fmt, ...)
{
va_list ap;
va_list ap;
va_start(ap, fmt);
if (gVerboseMode)
{
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
if (gVerboseMode) {
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
}
}
{
// Kabyl: BooterLog
struct putc_info pi;
if (!msgbuf)
if (!msgbuf) {
return 0;
}
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE))) {
return 0;
}
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
cursor += strlen((char *)cursor);
}
va_end(ap);
return(0);
va_end(ap);
return(0);
}
int error(const char * fmt, ...)
{
va_list ap;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
va_list ap;
gErrors = true;
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
prf(fmt, ap, putchar, 0);
else
} else {
vprf(fmt, ap);
}
va_end(ap);
return(0);
return(0);
}
void stop(const char * fmt, ...)
branches/chucko/i386/libsaio/xml.h
2626
2727
2828
29
30
31
32
33
34
35
36
37
38
29
30
31
32
33
34
35
36
37
38
3939
4040
4141
......
4848
4949
5050
51
52
53
54
55
56
57
58
59
60
51
52
53
54
55
56
57
58
59
60
61
62
63
64
6165
62
63
64
6566
6667
6768
......
7172
7273
7374
74
75
76
77
75
76
77
78
7879
7980
8081
#define __LIBSAIO_XML_H
enum xmltype {
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
kTagTypeNone = 0,
kTagTypeDict,
kTagTypeKey,
kTagTypeString,
kTagTypeInteger,
kTagTypeData,
kTagTypeDate,
kTagTypeFalse,
kTagTypeTrue,
kTagTypeArray
};
struct string_ref
extern string_ref* ref_strings;
#define kXMLTagPList "plist "
#define kXMLTagDict "dict"
#define kXMLTagKey "key"
#define kXMLTagString "string"
#define kXMLTagInteger "integer"
#define kXMLTagData "data"
#define kXMLTagDate "date"
#define kXMLTagFalse "false/"
#define kXMLTagTrue "true/"
#define kXMLTagArray "array"
#define kXMLTagPList "plist "
#define kXMLTagDict "dict"
#define kXMLTagKey "key"
#define kXMLTagString "string"
#define kXMLTagInteger "integer"
#define kXMLTagData "data"
#define kXMLTagDate "date"
#define kXMLTagFalse "false/"
#define kXMLTagTrue "true/"
#define kXMLTagArray "array"
// for back-references used by libkern serializer
#define kXMLTagReference "reference"
#define kXMLStringID "ID="
#define kXMLStringIDRef "IDREF="
#define kXMLStringID"ID="
#define kXMLStringIDRef "IDREF="
#define kPropCFBundleIdentifier ("CFBundleIdentifier")
#define kPropCFBundleExecutable ("CFBundleExecutable")
#define kPropOSBundleRequired ("OSBundleRequired")
/*
struct Tag {
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
long type;
char *string;
struct Tag *tag;
struct Tag *tagNext;
};
typedef struct Tag Tag, *TagPtr;
*/
branches/chucko/i386/libsaio/efi.h
7171
7272
7373
74
7574
76
75
7776
7877
7978
......
8281
8382
8483
85
8684
87
8885
8986
9087
......
118115
119116
120117
118
119
120
121
121122
122123
123124
124125
125126
127
126128
127129
128130
......
141143
142144
143145
144
146
145147
146148
147149
......
160162
161163
162164
163
164
165
166
167
168
169
170
171
172
173
165
166
167
168
169
170
171
172
173
174
175
174176
175177
176
178
177179
178
180
179181
180182
181183
182
184
183185
184
186
185187
186188
187189
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
203205
204206
205207
206
207
208
209
210
208
209
210
211
212
211213
212214
213
214215
215
216
216217
217218
218219
219220
220221
221222
222
223
223224
224
225
225226
226227
227228
228229
229
230
230231
231
232
232233
233234
234235
......
236237
237238
238239
239
240
241
242
243
244
240
241
242
243
244
245
245246
246247
247248
......
263264
264265
265266
266
267
267268
268
269
269270
270271
271272
......
302303
303304
304305
305
306
306307
307
308
308309
309
310
311
310
311
312
312313
313314
314315
......
371372
372373
373374
374
375375
376
377
378
379
380
381
382
376
377
378
379
380
383381
384
385
382
386383
387384
388385
......
404401
405402
406403
407
404
408405
409
410
411
412
413
414
415
406
407
408
409
410
416411
417
418
419
420
421
412
422413
423
424
425
426
427
428
414
415
429416
430
431
432
433
434
435417
418
419
420
421
422
423
424
425
426
436427
437
438
439
440
441
442
428
429
430
431
432
433
443434
444435
445436
446437
447438
448
439
449440
450
451
452
453
454
455
456
457441
458
459
460
461
462
442
463443
464
465
466
467
468
469
444
445
446
447
470448
471
472
473
474
475
449
476450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
477465
478
479
480
481
482
483
466
467
468
469
470
471
484472
485473
486474
......
489477
490478
491479
492
493
480
481
494482
495483
496484
497
498
485
486
499487
500488
501
489
502490
503
491
504492
505493
506494
......
508496
509497
510498
511
499
512500
513
514
501
502
515503
516
517
504
505
518506
519
520
507
508
521509
522
523
510
511
524512
525
526
513
514
527515
528
529
516
517
530518
531519
532520
533521
534
522
535523
536
537
524
525
538526
539
527
528
529
540530
541
542
531
532
543533
544
545
534
535
546536
547
548
537
538
549539
550
551
552
553
554
555
540
541
556542
557543
558544
*/
//
// Modifiers for EFI Runtime and Boot Services
//
#define EFI_RUNTIMESERVICE
#define EFIAPI
#define IN
#define EFI_MAX_BIT 0x80000000
//
// Set the upper bit to indicate EFI Error.
//
#define EFIERR(a) (EFI_MAX_BIT | (a))
#define EFIWARN(a) (a)
#define EFI_INCOMPATIBLE_VERSION EFIERR (25)
#define EFI_SECURITY_VIOLATION EFIERR (26)
#define EFI_CRC_ERROR EFIERR (27)
#define EFI_END_OF_MEDIA EFIERR (28)
#define EFI_END_OF_FILE EFIERR (31)
#define EFI_INVALID_LANGUAGE EFIERR (32)
#define EFI_COMPROMISED_DATA EFIERR (33)
#define EFI_WARN_UNKNOWN_GLYPH EFIWARN (1)
#define EFI_WARN_DELETE_FAILURE EFIWARN (2)
#define EFI_WARN_WRITE_FAILURE EFIWARN (3)
#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN (4)
#define EFI_WARN_STALE_DATA EFIWARN (5)
//
// EFI Specification Revision information
{0xAC39C713, 0x7E50, 0x423D, {0x88, 0x9D, 0x27,0x8F, 0xCC, 0x34, 0x22, 0xB6} }
#define EFI_GLOBAL_VARIABLE_GUID \
{0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
{0x8BE4DF61, 0x93CA, 0x11D2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} }
typedef union {
EFI_GUID Guid;
// TimeZone: -1440 to 1440 or 2047
//
typedef struct {
EFI_UINT16 Year;
EFI_UINT8 Month;
EFI_UINT8 Day;
EFI_UINT8 Hour;
EFI_UINT8 Minute;
EFI_UINT8 Second;
EFI_UINT8 Pad1;
EFI_UINT32 Nanosecond;
EFI_INT16 TimeZone;
EFI_UINT8 Daylight;
EFI_UINT8 Pad2;
EFI_UINT16 Year;
EFI_UINT8 Month;
EFI_UINT8 Day;
EFI_UINT8 Hour;
EFI_UINT8 Minute;
EFI_UINT8 Second;
EFI_UINT8 Pad1;
EFI_UINT32 Nanosecond;
EFI_INT16 TimeZone;
EFI_UINT8 Daylight;
EFI_UINT8 Pad2;
} EFI_TIME;
//
// Bit definitions for EFI_TIME.Daylight
//
#define EFI_TIME_ADJUST_DAYLIGHT 0x01
#define EFI_TIME_IN_DAYLIGHT 0x02
//
// Value definition for EFI_TIME.TimeZone
//
#define EFI_UNSPECIFIED_TIMEZONE 0x07FF
typedef enum {
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiMaxMemoryType
EfiReservedMemoryType,
EfiLoaderCode,
EfiLoaderData,
EfiBootServicesCode,
EfiBootServicesData,
EfiRuntimeServicesCode,
EfiRuntimeServicesData,
EfiConventionalMemory,
EfiUnusableMemory,
EfiACPIReclaimMemory,
EfiACPIMemoryNVS,
EfiMemoryMappedIO,
EfiMemoryMappedIOPortSpace,
EfiPalCode,
EfiMaxMemoryType
} EFI_MEMORY_TYPE;
typedef struct {
EFI_UINT64 Signature;
EFI_UINT32 Revision;
EFI_UINT32 HeaderSize;
EFI_UINT32 CRC32;
EFI_UINT32 Reserved;
EFI_UINT64Signature;
EFI_UINT32Revision;
EFI_UINT32HeaderSize;
EFI_UINT32CRC32;
EFI_UINT32Reserved;
} __attribute__((aligned(8))) EFI_TABLE_HEADER;
//
// possible caching types for the memory range
//
#define EFI_MEMORY_UC 0x0000000000000001ULL
#define EFI_MEMORY_WC 0x0000000000000002ULL
#define EFI_MEMORY_WT 0x0000000000000004ULL
#define EFI_MEMORY_WB 0x0000000000000008ULL
#define EFI_MEMORY_UCE 0x0000000000000010ULL
//
// physical memory protection on range
//
#define EFI_MEMORY_WP 0x0000000000001000ULL
#define EFI_MEMORY_RP 0x0000000000002000ULL
#define EFI_MEMORY_XP 0x0000000000004000ULL
//
// range requires a runtime mapping
//
#define EFI_MEMORY_RUNTIME 0x8000000000000000ULL
typedef EFI_UINT64 EFI_PHYSICAL_ADDRESS;
#define EFI_MEMORY_DESCRIPTOR_VERSION 1
typedef struct {
EFI_UINT32 Type;
EFI_UINT32 Pad;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
EFI_UINT64 NumberOfPages;
EFI_UINT64 Attribute;
EFI_UINT32 Type;
EFI_UINT32 Pad;
EFI_PHYSICAL_ADDRESS PhysicalStart;
EFI_VIRTUAL_ADDRESS VirtualStart;
EFI_UINT64 NumberOfPages;
EFI_UINT64 Attribute;
} __attribute__((aligned(8))) EFI_MEMORY_DESCRIPTOR;
IN OUT VOID **Address
) __attribute__((regparm(0)));
//
// Variable attributes
//
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
IN VOID * Data
) __attribute__((regparm(0)));
//
// EFI Time
//
typedef struct {
EFI_UINT32 Resolution;
EFI_UINT32 Accuracy;
EFI_BOOLEAN SetsToZero;
EFI_UINT32 Resolution;
EFI_UINT32 Accuracy;
EFI_BOOLEAN SetsToZero;
} __attribute__((aligned(4))) EFI_TIME_CAPABILITIES;
typedef
OUT EFI_UINT32 * HighCount
) __attribute__((regparm(0)));
//
// Definition of Status Code extended data header
//
// HeaderSize The size of the architecture. This is specified to enable
// the future expansion
//
// Size The size of the data in bytes. This does not include the size
// of the header structure.
//
// HeaderSize The size of the architecture. This is specified to enable the future expansion
// Size The size of the data in bytes. This does not include the size of the header structure.
// Type A GUID defining the type of the data
//
//
#ifdef TIANO_EXTENSION_FLAG
typedef
#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION))
typedef struct {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADERHdr;
//
// Time services
//
EFI_PTR32 GetTime;
EFI_PTR32 SetTime;
EFI_PTR32 GetWakeupTime;
EFI_PTR32 SetWakeupTime;
// Time Services
EFI_PTR32GetTime;
EFI_PTR32SetTime;
EFI_PTR32GetWakeupTime;
EFI_PTR32SetWakeupTime;
//
// Virtual memory services
//
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
// Virtual Memory Services
//
// Variable services
//
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
EFI_PTR32 SetVirtualAddressMap;
EFI_PTR32 ConvertPointer;
//
// Misc
//
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
// Variable Services
EFI_PTR32 GetVariable;
EFI_PTR32 GetNextVariableName;
EFI_PTR32 SetVariable;
// Miscellaneous Services
EFI_PTR32 GetNextHighMonotonicCount;
EFI_PTR32 ResetSystem;
#ifdef TIANO_EXTENSION_FLAG
//
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
//
EFI_PTR32 ReportStatusCode;
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
EFI_PTR32 ReportStatusCode;
#endif
} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_32;
typedef struct {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
//
// Time services
//
EFI_PTR64 GetTime;
EFI_PTR64 SetTime;
EFI_PTR64 GetWakeupTime;
EFI_PTR64 SetWakeupTime;
//
// Virtual memory services
//
EFI_PTR64 SetVirtualAddressMap;
EFI_PTR64 ConvertPointer;
// Time services
//
// Variable services
//
EFI_PTR64 GetVariable;
EFI_PTR64 GetNextVariableName;
EFI_PTR64 SetVariable;
EFI_PTR64 GetTime;
EFI_PTR64 SetTime;
EFI_PTR64 GetWakeupTime;
EFI_PTR64 SetWakeupTime;
//
// Misc
//
EFI_PTR64 GetNextHighMonotonicCount;
EFI_PTR64 ResetSystem;
// Virtual memory services
EFI_PTR64 SetVirtualAddressMap;
EFI_PTR64 ConvertPointer;
// Variable services
EFI_PTR64 GetVariable;
EFI_PTR64 GetNextVariableName;
EFI_PTR64 SetVariable;
// Misc
EFI_PTR64 GetNextHighMonotonicCount;
EFI_PTR64 ResetSystem;
#ifdef TIANO_EXTENSION_FLAG
//
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
//
EFI_PTR64 ReportStatusCode;
// ////////////////////////////////////////////////////
// Extended EFI Services
//////////////////////////////////////////////////////
EFI_PTR64 ReportStatusCode;
#endif
} __attribute__((aligned(8))) EFI_RUNTIME_SERVICES_64;
// EFI Configuration Table
//
typedef struct {
EFI_GUID VendorGuid;
EFI_PTR32 VendorTable;
EFI_GUID VendorGuid;
EFI_PTR32 VendorTable;
} EFI_CONFIGURATION_TABLE_32;
typedef struct {
EFI_GUID VendorGuid;
EFI_PTR64 VendorTable;
EFI_GUID VendorGuid;
EFI_PTR64 VendorTable;
} __attribute__((aligned(8))) EFI_CONFIGURATION_TABLE_64;
//
// EFI System Table
//
#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249ULL
#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION << 16) | (EFI_SPECIFICATION_MINOR_REVISION))
#define EFI_2_00_SYSTEM_TABLE_REVISION ((2 << 16) | 00)
#define EFI_1_10_SYSTEM_TABLE_REVISION ((1 << 16) | 10)
typedef struct EFI_SYSTEM_TABLE_32 {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR32 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleInHandle;
EFI_PTR32 ConIn;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 ConsoleOutHandle;
EFI_PTR32 ConOut;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_HANDLE32 StandardErrorHandle;
EFI_PTR32 StdErr;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_PTR32 RuntimeServices;
EFI_PTR32 BootServices;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
EFI_UINT32 NumberOfTableEntries;
EFI_PTR32 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_32;
typedef struct EFI_SYSTEM_TABLE_64 {
EFI_TABLE_HEADER Hdr;
EFI_TABLE_HEADER Hdr;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_PTR64 FirmwareVendor;
EFI_UINT32 FirmwareRevision;
EFI_UINT32 __pad;
EFI_UINT32 __pad;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleInHandle;
EFI_PTR64 ConIn;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 ConsoleOutHandle;
EFI_PTR64 ConOut;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_HANDLE64 StandardErrorHandle;
EFI_PTR64 StdErr;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_PTR64 RuntimeServices;
EFI_PTR64 BootServices;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
EFI_UINT64 NumberOfTableEntries;
EFI_PTR64 ConfigurationTable;
} __attribute__((aligned(8))) EFI_SYSTEM_TABLE_64;
#endif /* _PEXPERT_I386_EFI_H */
branches/chucko/i386/libsaio/bootstruct.h
4444
4545
4646
47
4847
4948
5049
......
7574
7675
7776
78
79
80
77
78
79
8180
8281
8382
......
9190
9291
9392
94
95
96
97
93
94
95
96
9897
99
98
10099
101100
102101
......
108107
109108
110109
111
112
110
111
113112
114
113
115114
116
115
117116
118
119
117
118
120119
121
120
122121
123122
124
123
125124
126
127
125
126
128127
129
130
131
132
133
134
128
129
130
131
132
133
135134
136135
137136
//#define FB_TEXT_MODE 2
/*
* Maximum number of boot drivers that can be loaded.
*/
} PCI_bus_info_t;
typedef struct {
unsigned long address; // address where driver was loaded
unsigned long size; // number of bytes
unsigned long type; // driver type
unsigned long address; // address where driver was loaded
unsigned long size; // number of bytes
unsigned long type; // driver type
} driver_config_t;
/*
* ACPI defined memory range types.
*/
enum {
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
/* Undefined types should be treated as kMemoryRangeReserved */
/* Undefined types should be treated as kMemoryRangeReserved */
};
/*!
to the kernel and are thus located in bootArgs although with different field names.
*/
typedef struct PrivateBootInfo {
int convmem; // conventional memory
int extmem; // extended memory
int convmem; // conventional memory
int extmem; // extended memory
#if 0
int numBootDrivers; // number of drivers loaded
int numBootDrivers; // number of drivers loaded
#endif
char bootFile[128]; // kernel file name
char bootFile[128]; // kernel file name
unsigned long memoryMapCount;
MemoryRange memoryMap[kMemoryMapCountMax];
unsigned long memoryMapCount;
MemoryRange memoryMap[kMemoryMapCountMax];
PCI_bus_info_t pciInfo;
PCI_bus_info_t pciInfo;
#if 0
driver_config_t driverConfig[NDRIVERS];
driver_config_t driverConfig[NDRIVERS];
#endif
char * configEnd; // pointer to end of config files
char config[CONFIG_SIZE];
char * configEnd;// pointer to end of config files
char config[CONFIG_SIZE];
config_file_t bootConfig; // com.apple.Boot.plist
config_file_t chameleonConfig; // org.chameleon.Boot.plist which can override bootConfig keys
config_file_t themeConfig; // theme.plist
config_file_t smbiosConfig; // smbios.plist
config_file_t helperConfig; // boot helper partition's boot.plist
config_file_t ramdiskConfig; // RAMDisk.plist
config_file_t bootConfig;// com.apple.Boot.plist
config_file_t chameleonConfig;// org.chameleon.Boot.plist which can override bootConfig keys
config_file_t themeConfig;// theme.plist
config_file_t smbiosConfig;// smbios.plist
config_file_t helperConfig;// boot helper partition's boot.plist
config_file_t ramdiskConfig;// RAMDisk.plist
bool memDetect;
} PrivateBootInfo_t;
branches/chucko/i386/libsaio/device_tree.c
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
320
421
522
623
7
24
825
926
1027
1128
1229
1330
14
15
31
32
1633
1734
1835
1936
2037
21
22
38
39
2340
2441
2542
2643
2744
28
45
46
2947
3048
3149
......
4967
5068
5169
52
53
54
70
71
72
5573
5674
5775
......
6179
6280
6381
82
83
84
6485
6586
6687
67
88
6889
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
90
9291
93
94
95
92
93
94
9695
97
98
99
100
101
102
103
104
96
10597
106
107
108
109
98
99
100
110101
111
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
112141
113142
143
144
145
114146
115147
116148
117
149
118150
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
151
152
153
144154
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
155204
156205
206
207
208
157209
158210
159211
160
161
212
213
162214
215
216
217
163218
164219
165220
......
167222
168223
169224
225
226
170227
171228
172229
173
174
175
176
177
178
179
180
181
182
183
184
185
230
231
232
233
234
235
236
237
238
239
240
241
242
186243
187244
245
188246
189
190
247
191248
192249
193250
194251
195
196
252
253
197254
198
199
200
201
202
203
255
204256
205
206
207
208
209
210
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
211273
212
213
214
215
216
274
275
276
277
217278
218279
280
281
219282
220283
221284
222
223
224
225
285
286
287
288
226289
227
290
291
292
228293
229
230
294
295
231296
232
233
234
235
236
237
238
239
240
297
298
299
300
301
302
303
304
305
241306
242
243
244
245
307
246308
247
309
310
311
312
313
314
315
316
248317
249318
250
251
252
319
320
321
253322
254323
255324
......
258327
259328
260329
261
262
330
331
263332
264
333
334
265335
266
336
337
338
267339
268340
269
270
271
341
342
343
272344
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
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
291376
292377
378
379
293380
294381
295382
296
383
297384
298
299
300
301
302
303
304
305
306
307
385
386
387
388
389
390
391
392
393
394
395
396
397
308398
309399
400
401
310402
311403
312404
313
314
315
316
405
406
407
408
317409
318
410
319411
320
321
322
412
413
323414
324
325
326
415
327416
328
329
417
418
419
420
421
422
423
330424
331
332
333
334
335
425
426
427
428
336429
337
338
339
340
341
342
343
344
345
346
347
430
348431
349
350
351
352
353
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
354465
355466
356467
357468
469
470
358471
359472
360473
361
362
474
475
363476
364
365
366
477
478
479
480
367481
368
369
370
371
372
373
374
375
376
377
378
379
380
381
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
382505
383506
507
508
384509
385510
386511
387
388
389
390
512
513
514
515
516
517
518
519
391520
392521
522
523
393524
394525
395526
396
397
527
528
398529
399530
531
532
400533
401534
402535
403
404
405
406
407
536
537
538
539
540
408541
409
410
411
542
543
544
412545
413
414
415
416
417
418
419
420
421
422
423
546
547
548
549
550
551
552
553
554
555
556
557
558
424559
425
560
426561
427562
563
564
428565
429566
430567
431
568
432569
433
570
434571
435
436
437
438
439
440
441
442
443
572
573
574
575
576
577
578
579
580
581
582
444583
445584
585
586
446587
447588
448589
449
590
450591
451592
593
452594
453595
454596
455597
456
457
458
459
460
461
462
463
598
599
600
601
602
603
604
605
464606
465
607
466608
467
468
469
470
609
610
611
612
471613
472
473
474
475
614
615
616
617
476618
477
478
479
480
619
620
621
622
481623
482
483
624
625
484626
485
627
486628
487
629
488630
489
631
490632
491
633
492634
493
635
494636
495
637
496638
497
639
498640
499
641
500642
501
502
503
504
643
644
645
646
647
648
649
650
651
652
653
505654
506
507
508
509
510
511
512
655
656
513657
514
515
516
517
518
519
658
659
660
661
662
663
664
665
520666
521
522
523
524
525
526
527
528
529
530
531
532
533
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
534682
535683
536
684
537685
538686
539687
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
*/
#if 1
/*
Structures for a Flattened Device Tree
*/
#define kPropNameLength 32
typedef struct DeviceTreeNodeProperty {
char name[kPropNameLength]; // NUL terminated property name
unsigned long length; // Length (bytes) of folloing prop value
char name[kPropNameLength]; // NUL terminated property name
unsigned long length; // Length (bytes) of folloing prop value
// unsigned long value[1]; // Variable length value of property
// Padded to a multiple of a longword?
} DeviceTreeNodeProperty;
typedef struct OpaqueDTEntry {
unsigned long nProperties; // Number of props[] elements (0 => end)
unsigned long nChildren; // Number of children[] elements
unsigned long nProperties; // Number of props[] elements (0 => end)
unsigned long nChildren; // Number of children[] elements
// DeviceTreeNodeProperty props[];// array size == nProperties
// DeviceTreeNode children[]; // array size == nChildren
} DeviceTreeNode;
typedef char DTPropertyNameBuf[32];
/* Entry Name Definitions (Entry Names are C-Strings)*/
// Entry Name Definitions (Entry Names are C-Strings).
enum {
kDTMaxEntryNameLength = 31 /* Max length of a C-String Entry Name (terminator not included) */
};
#define RoundToLong(x)(((x) + 3) & ~3)
static struct _DTSizeInfo {
uint32_t numNodes;
uint32_t numProperties;
uint32_t totalPropertySize;
uint32_tnumNodes;
uint32_tnumProperties;
uint32_ttotalPropertySize;
} DTInfo;
#define kAllocSize 4096
static Node *freeNodes, *allocedNodes;
static Property *freeProperties, *allocedProperties;
//==============================================================================
Property *
DT__AddProperty(Node *node, const char *name, uint32_t length, void *value)
{
Property *prop;
Property *prop;
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
if (freeProperties == NULL) {
void *buf = malloc(kAllocSize);
int i;
DPRINTF("Allocating more free properties\n");
if (buf == 0) return 0;
bzero(buf, kAllocSize);
// Use the first property to record the allocated buffer
// for later freeing.
prop = (Property *)buf;
prop->next = allocedProperties;
allocedProperties = prop;
prop->value = buf;
prop++;
for (i=1; i<(kAllocSize / sizeof(Property)); i++) {
prop->next = freeProperties;
freeProperties = prop;
prop++;
}
}
prop = freeProperties;
freeProperties = prop->next;
DPRINTF("DT__AddProperty([Node '%s'], '%s', %d, 0x%x)\n", DT__GetName(node), name, length, value);
prop->name = name;
prop->length = length;
prop->value = value;
if (freeProperties == NULL) {
void *buf = malloc(kAllocSize);
int i;
// Always add to end of list
if (node->properties == 0) {
node->properties = prop;
} else {
node->last_prop->next = prop;
}
node->last_prop = prop;
prop->next = 0;
DPRINTF("Allocating more free properties\n");
DPRINTF("Done [0x%x]\n", prop);
DTInfo.numProperties++;
DTInfo.totalPropertySize += RoundToLong(length);
if (buf == 0) {
return 0;
}
return prop;
bzero(buf, kAllocSize);
// Use the first property to record the allocated buffer
// for later freeing.
prop = (Property *)buf;
prop->next = allocedProperties;
allocedProperties = prop;
prop->value = buf;
prop++;
for (i = 1; i < (kAllocSize / sizeof(Property)); i++) {
prop->next = freeProperties;
freeProperties = prop;
prop++;
}
}
prop = freeProperties;
freeProperties = prop->next;
prop->name = name;
prop->length = length;
prop->value = value;
// Always add to end of list
if (node->properties == 0) {
node->properties = prop;
} else {
node->last_prop->next = prop;
}
node->last_prop = prop;
prop->next = 0;
DPRINTF("Done [0x%x]\n", prop);
DTInfo.numProperties++;
DTInfo.totalPropertySize += RoundToLong(length);
return prop;
}
//==============================================================================
Node *
DT__AddChild(Node *parent, const char *name)
{
Node *node;
Node *node;
if (freeNodes == NULL) {
void *buf = malloc(kAllocSize);
int i;
DPRINTF("Allocating more free nodes\n");
if (buf == 0) return 0;
bzero(buf, kAllocSize);
node = (Node *)buf;
// Use the first node to record the allocated buffer
// for later freeing.
node->next = allocedNodes;
allocedNodes = node;
node->children = (Node *)buf;
node++;
for (i=1; i<(kAllocSize / sizeof(Node)); i++) {
node->next = freeNodes;
freeNodes = node;
node++;
}
}
DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);
node = freeNodes;
freeNodes = node->next;
DPRINTF("Got free node 0x%x\n", node);
DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);
if (freeNodes == NULL)
{
void *buf = malloc(kAllocSize);
if (parent == NULL) {
rootNode = node;
node->next = 0;
} else {
node->next = parent->children;
parent->children = node;
}
DTInfo.numNodes++;
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
return node;
if (buf == 0)
{
return 0;
}
int i;
DPRINTF("Allocating more free nodes\n");
bzero(buf, kAllocSize);
node = (Node *)buf;
// Use the first node to record the allocated buffer for later freeing.
node->next = allocedNodes;
allocedNodes = node;
node->children = (Node *)buf;
node++;
for (i = 1; i < (kAllocSize / sizeof(Node)); i++)
{
node->next = freeNodes;
freeNodes = node;
node++;
}
}
DPRINTF("DT__AddChild(0x%x, '%s')\n", parent, name);
node = freeNodes;
freeNodes = node->next;
DPRINTF("Got free node 0x%x\n", node);
DPRINTF("prop = 0x%x, children = 0x%x, next = 0x%x\n", node->properties, node->children, node->next);
if (parent == NULL)
{
rootNode = node;
node->next = 0;
}
else
{
node->next = parent->children;
parent->children = node;
}
DTInfo.numNodes++;
DT__AddProperty(node, "name", strlen(name) + 1, (void *) name);
return node;
}
//==============================================================================
void
DT__FreeProperty(Property *prop)
{
prop->next = freeProperties;
freeProperties = prop;
prop->next = freeProperties;
freeProperties = prop;
}
//==============================================================================
void
DT__FreeNode(Node *node)
{
freeNodes = node;
}
//==============================================================================
void
DT__Initialize(void)
{
DPRINTF("DT__Initialize\n");
freeNodes = 0;
allocedNodes = 0;
freeProperties = 0;
allocedProperties = 0;
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
rootNode = DT__AddChild(NULL, "/");
DPRINTF("DT__Initialize done\n");
DPRINTF("DT__Initialize\n");
freeNodes = 0;
allocedNodes = 0;
freeProperties = 0;
allocedProperties = 0;
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
rootNode = DT__AddChild(NULL, "/");
DPRINTF("DT__Initialize done\n");
}
//==============================================================================
/*
* Free up memory used by in-memory representation
* of device tree.
* Free up memory used by in-memory representation of device tree.
*/
void
DT__Finalize(void)
{
Node *node;
Property *prop;
Node *node;
Property *prop;
DPRINTF("DT__Finalize\n");
for (prop = allocedProperties; prop != NULL; prop = prop->next) {
free(prop->value);
}
allocedProperties = NULL;
freeProperties = NULL;
DPRINTF("DT__Finalize\n");
for (node = allocedNodes; node != NULL; node = node->next) {
free((void *)node->children);
}
allocedNodes = NULL;
freeNodes = NULL;
rootNode = NULL;
for (prop = allocedProperties; prop != NULL; prop = prop->next)
{
free(prop->value);
}
allocedProperties = NULL;
freeProperties = NULL;
for (node = allocedNodes; node != NULL; node = node->next)
{
free((void *)node->children);
}
allocedNodes = NULL;
freeNodes = NULL;
rootNode = NULL;
// XXX leaks any created strings
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
// XXX leaks any created strings
DTInfo.numNodes = 0;
DTInfo.numProperties = 0;
DTInfo.totalPropertySize = 0;
}
//==============================================================================
static void *
FlattenNodes(Node *node, void *buffer)
{
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
Property *prop;
DeviceTreeNode *flatNode;
DeviceTreeNodeProperty *flatProp;
int count;
if (node == 0) return buffer;
if (node == 0) {
return buffer;
}
flatNode = (DeviceTreeNode *)buffer;
buffer += sizeof(DeviceTreeNode);
flatNode = (DeviceTreeNode *)buffer;
buffer += sizeof(DeviceTreeNode);
for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next) {
flatProp = (DeviceTreeNodeProperty *)buffer;
strcpy(flatProp->name, prop->name);
flatProp->length = prop->length;
buffer += sizeof(DeviceTreeNodeProperty);
bcopy(prop->value, buffer, prop->length);
buffer += RoundToLong(prop->length);
}
flatNode->nProperties = count;
for (count = 0, prop = node->properties; prop != 0; count++, prop = prop->next)
{
flatProp = (DeviceTreeNodeProperty *)buffer;
strcpy(flatProp->name, prop->name);
flatProp->length = prop->length;
buffer += sizeof(DeviceTreeNodeProperty);
bcopy(prop->value, buffer, prop->length);
buffer += RoundToLong(prop->length);
}
for (count = 0, node = node->children; node != 0; count++, node = node->next) {
buffer = FlattenNodes(node, buffer);
}
flatNode->nChildren = count;
flatNode->nProperties = count;
return buffer;
for (count = 0, node = node->children; node != 0; count++, node = node->next)
{
buffer = FlattenNodes(node, buffer);
}
flatNode->nChildren = count;
return buffer;
}
/*
* Flatten the in-memory representation of the device tree
* into a binary DT block.
/*==============================================================================
* Flatten the in-memory representation of the device tree into a binary DT block.
* To get the buffer size needed, call with result = 0.
* To have a buffer allocated for you, call with *result = 0.
* To use your own buffer, call with *result = &buffer.
void
DT__FlattenDeviceTree(void **buffer_p, uint32_t *length)
{
uint32_t totalSize;
void *buf;
uint32_t totalSize;
void * buf;
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
DPRINTF("DT__FlattenDeviceTree(0x%x, 0x%x)\n", buffer_p, length);
#if DEBUG
if (buffer_p) DT__PrintTree(rootNode);
if (buffer_p) {
DT__PrintTree(rootNode);
}
#endif
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
DTInfo.totalPropertySize;
totalSize = DTInfo.numNodes * sizeof(DeviceTreeNode) +
DTInfo.numProperties * sizeof(DeviceTreeNodeProperty) +
DTInfo.totalPropertySize;
DPRINTF("Total size 0x%x\n", totalSize);
if (buffer_p != 0) {
if (totalSize == 0) {
buf = 0;
} else {
if (*buffer_p == 0) {
buf = malloc(totalSize);
} else {
buf = *buffer_p;
}
bzero(buf, totalSize);
FlattenNodes(rootNode, buf);
}
*buffer_p = buf;
}
if (length)
*length = totalSize;
DPRINTF("Total size 0x%x\n", totalSize);
if (buffer_p != 0)
{
if (totalSize == 0)
{
buf = 0;
}
else
{
if (*buffer_p == 0)
{
buf = malloc(totalSize);
}
else
{
buf = *buffer_p;
}
bzero(buf, totalSize);
FlattenNodes(rootNode, buf);
}
*buffer_p = buf;
}
if (length)
{
*length = totalSize;
}
}
//==============================================================================
char *
DT__GetName(Node *node)
{
Property *prop;
Property *prop;
//DPRINTF("DT__GetName(0x%x)\n", node);
//DPRINTF("Node properties = 0x%x\n", node->properties);
for (prop = node->properties; prop; prop = prop->next) {
//DPRINTF("Prop '%s'\n", prop->name);
if (strcmp(prop->name, "name") == 0) {
return prop->value;
}
}
//DPRINTF("DT__GetName returns 0\n");
return "(null)";
//DPRINTF("DT__GetName(0x%x)\n", node);
//DPRINTF("Node properties = 0x%x\n", node->properties);
for (prop = node->properties; prop; prop = prop->next)
{
//DPRINTF("Prop '%s'\n", prop->name);
if (strcmp(prop->name, "name") == 0)
{
return prop->value;
}
}
//DPRINTF("DT__GetName returns 0\n");
return "(null)";
}
//==============================================================================
Node *
DT__FindNode(const char *path, bool createIfMissing)
{
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
Node *node, *child;
DTPropertyNameBuf nameBuf;
char *bp;
int i;
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
// Start at root
node = rootNode;
DPRINTF("root = 0x%x\n", rootNode);
// Start at root
node = rootNode;
while (node) {
// Skip leading slash
while (*path == '/') path++;
DPRINTF("root = 0x%x\n", rootNode);
for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;
*bp = '\0';
while (node)
{
// Skip leading slash
while (*path == '/')
{
path++;
}
if (nameBuf[0] == '\0') {
// last path entry
break;
}
DPRINTF("Node '%s'\n", nameBuf);
for (i = 0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++)
{
*bp = *path;
}
for (child = node->children; child != 0; child = child->next) {
DPRINTF("Child 0x%x\n", child);
if (strcmp(DT__GetName(child), nameBuf) == 0) {
break;
}
}
if (child == 0 && createIfMissing) {
DPRINTF("Creating node\n");
char *str = malloc(strlen(nameBuf) + 1);
// XXX this will leak
strcpy(str, nameBuf);
*bp = '\0';
child = DT__AddChild(node, str);
}
node = child;
}
return node;
if (nameBuf[0] == '\0')
{
// last path entry
break;
}
DPRINTF("Node '%s'\n", nameBuf);
for (child = node->children; child != 0; child = child->next)
{
DPRINTF("Child 0x%x\n", child);
if (strcmp(DT__GetName(child), nameBuf) == 0)
{
break;
}
}
if (child == 0 && createIfMissing)
{
DPRINTF("Creating node\n");
char *str = malloc(strlen(nameBuf) + 1);
// XXX this will leak
strcpy(str, nameBuf);
child = DT__AddChild(node, str);
}
node = child;
}
return node;
}
#if DEBUG
//==============================================================================
void
DT__PrintNode(Node *node, int level)
{
char spaces[10], *cp = spaces;
Property *prop;
char spaces[10], *cp = spaces;
Property *prop;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9)
{
level = 9;
}
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next) {
char c = *((char *)prop->value);
if (prop->length < 64 && (
strcmp(prop->name, "name") == 0 ||
(c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') || c == '_')) {
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
} else {
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
while (level--)
{
*cp++ = ' ';
}
*cp = '\0';
printf("%s===Node===\n", spaces);
for (prop = node->properties; prop; prop = prop->next)
{
char c = *((char *)prop->value);
if (prop->length < 64 && (strcmp(prop->name, "name") == 0 || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'))
{
printf("%s Property '%s' [%d] = '%s'\n", spaces, prop->name, prop->length, prop->value);
}
else
{
printf("%s Property '%s' [%d] = (data)\n", spaces, prop->name, prop->length);
}
}
printf("%s==========\n", spaces);
}
//==============================================================================
static void
_PrintTree(Node *node, int level)
{
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
_PrintTree(node, level);
DT__PrintNode(node, level);
level++;
for (node = node->children; node; node = node->next)
{
_PrintTree(node, level);
}
}
//==============================================================================
void
DT__PrintTree(Node *node)
{
if (node == 0) node = rootNode;
_PrintTree(node, 0);
if (node == 0) node = rootNode;
_PrintTree(node, 0);
}
//==============================================================================
void
DT__PrintFlattenedNode(DTEntry entry, int level)
{
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
char spaces[10], *cp = spaces;
DTPropertyIterator propIter;
char *name;
void *prop;
int propSize;
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
if (level > 9) level = 9;
while (level--) *cp++ = ' ';
*cp = '\0';
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter)) {
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s===Entry %p===\n", spaces, entry);
if (kSuccess != DTCreatePropertyIterator(entry, &propIter))
{
printf("Couldn't create property iterator\n");
return;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( entry, name, &prop, &propSize ))
continue;
printf("%s Property %s = %s\n", spaces, name, prop);
}
DTDisposePropertyIterator(propIter);
printf("%s==========\n", spaces);
printf("%s==========\n", spaces);
}
//==============================================================================
static void
_PrintFlattenedTree(DTEntry entry, int level)
{
DTEntryIterator entryIter;
DTEntryIterator entryIter;
PrintFlattenedNode(entry, level);
PrintFlattenedNode(entry, level);
if (kSuccess != DTCreateEntryIterator(entry, &entryIter)) {
printf("Couldn't create entry iterator\n");
return;
}
level++;
while (kSuccess == DTIterateEntries( entryIter, &entry )) {
_PrintFlattenedTree(entry, level);
}
DTDisposeEntryIterator(entryIter);
if (kSuccess != DTCreateEntryIterator(entry, &entryIter))
{
printf("Couldn't create entry iterator\n");
return;
}
level++;
while (kSuccess == DTIterateEntries( entryIter, &entry ))
{
_PrintFlattenedTree(entry, level);
}
DTDisposeEntryIterator(entryIter);
}
//==============================================================================
void
DT__PrintFlattenedTree(DTEntry entry)
{
_PrintFlattenedTree(entry, 0);
_PrintFlattenedTree(entry, 0);
}
//==============================================================================
int
main(int argc, char **argv)
{
DTEntry dtEntry;
DTPropertyIterator propIter;
DTEntryIterator entryIter;
void*prop;
intpropSize;
char*name;
void *flatTree;
uint32_t flatSize;
DTEntrydtEntry;
DTPropertyIteratorpropIter;
DTEntryIteratorentryIter;
void*prop;
intpropSize;
char*name;
void*flatTree;
uint32_tflatSize;
Node *node;
Node *node;
node = AddChild(NULL, "device-tree");
AddProperty(node, "potato", 4, "foo");
AddProperty(node, "chemistry", 4, "bar");
AddProperty(node, "physics", 4, "baz");
node = AddChild(NULL, "device-tree");
AddProperty(node, "potato", 4, "foo");
AddProperty(node, "chemistry", 4, "bar");
AddProperty(node, "physics", 4, "baz");
node = AddChild(node, "dev");
AddProperty(node, "one", 4, "one");
AddProperty(node, "two", 4, "two");
AddProperty(node, "three", 6, "three");
node = AddChild(node, "dev");
AddProperty(node, "one", 4, "one");
AddProperty(node, "two", 4, "two");
AddProperty(node, "three", 6, "three");
node = AddChild(rootNode, "foo");
AddProperty(node, "aaa", 4, "aab");
AddProperty(node, "bbb", 4, "bbc");
AddProperty(node, "cccc", 6, "ccccd");
node = AddChild(rootNode, "foo");
AddProperty(node, "aaa", 4, "aab");
AddProperty(node, "bbb", 4, "bbc");
AddProperty(node, "cccc", 6, "ccccd");
node = FindNode("/this/is/a/test", 1);
AddProperty(node, "dddd", 12, "abcdefghijk");
node = FindNode("/this/is/a/test", 1);
AddProperty(node, "dddd", 12, "abcdefghijk");
printf("In-memory tree:\n\n");
printf("In-memory tree:\n\n");
PrintTree(rootNode);
PrintTree(rootNode);
FlattenDeviceTree(&flatTree, &flatSize);
FlattenDeviceTree(&flatTree, &flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
printf("Flat tree = %p, size %d\n", flatTree, flatSize);
dtEntry = (DTEntry)flatTree;
dtEntry = (DTEntry)flatTree;
printf("\n\nPrinting flat tree\n\n");
printf("\n\nPrinting flat tree\n\n");
DTInit(dtEntry);
DTInit(dtEntry);
PrintFlattenedTree((DTEntry)flatTree);
PrintFlattenedTree((DTEntry)flatTree);
#if 0
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
printf("Couldn't create property iterator\n");
return 1;
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
{
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
DTDisposePropertyIterator(propIter);
printf("========\n");
if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter)) {
printf("Couldn't create entry iterator\n");
return 1;
}
while (kSuccess == DTIterateEntries( entryIter, &dtEntry )) {
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreateEntryIterator(dtEntry, &entryIter))
{
printf("Couldn't create entry iterator\n");
return 1;
}
while (kSuccess == DTIterateEntries( entryIter, &dtEntry ))
{
printf("=== Entry %p ===\n", dtEntry);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter)) {
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name)) {
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
}
DTDisposeEntryIterator(entryIter);
if (kSuccess != DTCreatePropertyIterator(dtEntry, &propIter))
{
printf("Couldn't create property iterator\n");
return 1;
}
while( kSuccess == DTIterateProperties( propIter, &name))
{
if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize ))
continue;
printf(" Property %s = %s\n", name, prop);
}
DTDisposePropertyIterator(propIter);
printf("========\n");
}
DTDisposeEntryIterator(entryIter);
#endif
return 0;
return 0;
}
#endif
branches/chucko/i386/libsaio/hfs.c
109109
110110
111111
112
113
112114
113115
114
115
116
117
116
117
118
119
118120
119121
122
123
124
120125
121126
122
123
124
127
128
129
130
125131
126132
133
134
135
127136
128137
129138
130139
131
132
140
141
133142
134
143
135144
136
137
145
146
147
138148
149
139150
140151
141152
153
154
155
142156
143157
144
145
158
159
146160
147
161
162
148163
149
164
150165
151
152
166
167
153168
154169
155
156
157
158
159
160
161
162
163
164
165
166
167
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
168196
169197
170
171
172
173
174
198
199
200
201
202
175203
176
177
178
204
205
206
179207
180
181
208
209
210
182211
183
184
185
186
187
188
212
213
214
215
216
217
218
189219
190
191
220
221
192222
193
194
195
196
197
198
223
224
225
226
227
199228
200
201
229
202230
203
204
205
206
207
231
232
233
234
235
236
208237
209
210
238
239
211240
212
213
241
242
214243
215
244
216245
217
218
219
246
247
248
220249
221
222
223
224
225
226
227
250
251
252
253
254
255
256
228257
229
230
231
232
258
259
260
261
233262
234263
235
236
237
238264
239
240
241
242
265
266
243267
244
245
268
269
270
271
246272
247
248
273
249274
250
251
252
253
254
275
255276
256
277
278
279
280
281
282
283
284
257285
258286
287
288
289
259290
260291
261
292
262293
263294
264295
......
267298
268299
269300
270
271
272
273
274
275
276
277
278
301
302
279303
280
281
282
283
284
304
285305
286
287
288
289
306
307
308
309
310
311
312
313
314
315
316
317
318
319
290320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
291339
292
293
294
340
341
342
343
344
345
295346
296347
297
298
299
300
348
349
350
351
352
301353
302
303
304
305
306
354
355
356
357
358
307359
308360
309361
......
10301082
10311083
10321084
1033
1085
10341086
10351087
1036
1088
10371089
1038
1039
1090
1091
10401092
10411093
10421094
u_int16_t *uniStr2, u_int32_t len2);
//==============================================================================
static void SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
{
dst->fdType = SWAP_BE32(src->fdType);
dst->fdCreator = SWAP_BE32(src->fdCreator);
dst->fdFlags = SWAP_BE16(src->fdFlags);
// Don't bother with location
dst->fdType = SWAP_BE32(src->fdType);
dst->fdCreator = SWAP_BE32(src->fdCreator);
dst->fdFlags = SWAP_BE16(src->fdFlags);
// Don't bother with location
}
//==============================================================================
void HFSFree(CICell ih)
{
if(gCurrentIH == ih)
gCurrentIH = 0;
free(ih);
if(gCurrentIH == ih) {
gCurrentIH = 0;
}
free(ih);
}
//==============================================================================
bool HFSProbe (const void *buf)
{
const HFSMasterDirectoryBlock *mdb;
const HFSPlusVolumeHeader *header;
mdb=(const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset);
header=(const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
mdb = (const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset);
header = (const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord )
if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord ) {
return true;
if (SWAP_BE16(header->signature) != kHFSPlusSigWord &&
SWAP_BE16(header->signature) != kHFSXSigWord)
}
if (SWAP_BE16(header->signature) != kHFSPlusSigWord && SWAP_BE16(header->signature) != kHFSXSigWord) {
return false;
}
return true;
}
//==============================================================================
long HFSInitPartition(CICell ih)
{
long extentSize, extentFile, nodeSize;
void *extent;
long extentSize, extentFile, nodeSize;
void *extent;
if (ih == gCurrentIH) {
if (ih == gCurrentIH)
{
#ifdef __i386__
CacheInit(ih, gCacheBlockSize);
CacheInit(ih, gCacheBlockSize);
#endif
return 0;
}
return 0;
}
#ifdef __i386__
if (!gTempStr) gTempStr = (char *)malloc(4096);
if (!gLinkTemp) gLinkTemp = (char *)malloc(64);
if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512);
if (!gHFSMdbVib) {
gHFSMdbVib = (char *)malloc(kBlockSize);
gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
}
if (!gHFSPlusHeader) {
gHFSPlusHeader = (char *)malloc(kBlockSize);
gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
}
if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer ||
!gHFSMdbVib || !gHFSPlusHeader) return -1;
if (!gTempStr)
{
gTempStr = (char *)malloc(4096);
}
if (!gLinkTemp)
{
gLinkTemp = (char *)malloc(64);
}
if (!gBTreeHeaderBuffer)
{
gBTreeHeaderBuffer = (char *)malloc(512);
}
if (!gHFSMdbVib)
{
gHFSMdbVib = (char *)malloc(kBlockSize);
gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
}
if (!gHFSPlusHeader)
{
gHFSPlusHeader = (char *)malloc(kBlockSize);
gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
}
if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer || !gHFSMdbVib || !gHFSPlusHeader)
{
return -1;
}
#endif /* __i386__ */
gAllocationOffset = 0;
gIsHFSPlus = 0;
gCaseSensitive = 0;
gBTHeaders[0] = 0;
gBTHeaders[1] = 0;
gAllocationOffset = 0;
gIsHFSPlus = 0;
gCaseSensitive = 0;
gBTHeaders[0] = 0;
gBTHeaders[1] = 0;
// Look for the HFS MDB
Seek(ih, kMDBBaseOffset);
Read(ih, (long)gHFSMdbVib, kBlockSize);
// Look for the HFS MDB
Seek(ih, kMDBBaseOffset);
Read(ih, (long)gHFSMdbVib, kBlockSize);
if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) {
gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;
if (SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord)
{
gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;
// See if it is HFSPlus
if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) {
// Normal HFS;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
// See if it is HFSPlus
if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord)
{
// Normal HFS;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
// grab the 64 bit volume ID
bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8);
// grab the 64 bit volume ID
bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8);
// Get the Catalog BTree node size.
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
extentFile = kHFSCatalogFileID;
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// Get the Catalog BTree node size.
extent = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
extentFile = kHFSCatalogFileID;
ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
sizeof(BTNodeDescriptor)))->nodeSize);
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize);
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize) {
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
}
return 0;
}
// Calculate the offset to the embeded HFSPlus volume.
gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
// Calculate the offset to the embeded HFSPlus volume.
gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
SWAP_BE32(gHFSMDB->drAlBlkSiz);
}
}
// Look for the HFSPlus Header
Seek(ih, gAllocationOffset + kMDBBaseOffset);
Read(ih, (long)gHFSPlusHeader, kBlockSize);
// Look for the HFSPlus Header
Seek(ih, gAllocationOffset + kMDBBaseOffset);
Read(ih, (long)gHFSPlusHeader, kBlockSize);
// Not a HFS+ or HFSX volume.
if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord &&
SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) {
verbose("HFS signature was not present.\n");
gCurrentIH = 0;
return -1;
}
// Not a HFS+ or HFSX volume.
if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord && SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord)
{
verbose("HFS signature was not present.\n");
gCurrentIH = 0;
return -1;
}
gIsHFSPlus = 1;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
gIsHFSPlus = 1;
gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
CacheInit(ih, gCacheBlockSize);
gCurrentIH = ih;
ih->modTime = SWAP_BE32(gHFSPlus->modifyDate) - 2082844800;
// grab the 64 bit volume ID
bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8);
// Get the Catalog BTree node size.
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
extentFile = kHFSCatalogFileID;
// grab the 64 bit volume ID
bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8);
ReadExtent(extent, extentSize, extentFile, 0, 256,
gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// Get the Catalog BTree node size.
extent = &gHFSPlus->catalogFile.extents;
extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
extentFile = kHFSCatalogFileID;
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
sizeof(BTNodeDescriptor)))->nodeSize);
ReadExtent(extent, extentSize, extentFile, 0, 256, gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize) {
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + sizeof(BTNodeDescriptor)))->nodeSize);
return 0;
// If the BTree node size is larger than the block size, reset the cache.
if (nodeSize > gBlockSize)
{
gCacheBlockSize = nodeSize;
CacheInit(ih, gCacheBlockSize);
}
return 0;
}
//==============================================================================
long HFSLoadFile(CICell ih, char * filePath)
{
return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
return HFSReadFile(ih, filePath, (void *)gFSLoadAddress, 0, 0);
}
long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length)
char devStr[12];
long dirID, result, flags;
if (HFSInitPartition(ih) == -1) return -1;
dirID = kHFSRootFolderID;
// Skip a lead '\'. Start in the system folder if there are two.
if (filePath[0] == '/') {
if (filePath[1] == '/') {
if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
if (dirID == 0) {
if (HFSInitPartition(ih) == -1)
{
return -1;
}
filePath++;
}
filePath++;
}
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
return -1;
}
dirID = kHFSRootFolderID;
// Skip a lead '\'. Start in the system folder if there are two.
if (filePath[0] == '/')
{
if (filePath[1] == '/')
{
if (gIsHFSPlus)
{
dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
}
else
{
dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
}
if (dirID == 0)
{
return -1;
}
filePath++;
}
filePath++;
}
result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat))
{
return -1;
}
#if UNUSED
// Not yet for Intel. System.config/Default.table will fail this check.
// Check file owner and permissions.
if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1;
// Not yet for Intel. System.config/Default.table will fail this check.
// Check file owner and permissions.
if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite))
{
return -1;
}
#endif
result = ReadFile(entry, &length, base, offset);
if (result == -1) {
return -1;
}
result = ReadFile(entry, &length, base, offset);
if (result == -1)
{
return -1;
}
getDeviceDescription(ih, devStr);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",
(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
return length;
getDeviceDescription(ih, devStr);
verbose("Read HFS%s file: [%s/%s] %d bytes.\n",
(gIsHFSPlus ? "+" : ""), devStr, filePath, (uint32_t)length);
return length;
}
long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name,
{
HFSPlusExtentKey *searchKey, *trialKey;
long result;
searchKey = key;
trialKey = testKey;
// assume searchKey < trialKey
result = -1;
result = -1;
if (searchKey->fileID == trialKey->fileID) {
// FileNum's are equal; compare fork types
if (searchKey->forkType == trialKey->forkType) {
branches/chucko/i386/libsaio/acpi_patcher.c
103103
104104
105105
106
107
108
109
110
106
107
108
109
111110
112
113
114
115
116
117
118
111
112
113
114
115
116
119117
120118
121119
......
273271
274272
275273
276
274
277275
278
279
280
276
277
278
281279
282280
283
281
284282
285283
286284
......
288286
289287
290288
291
292
293
289
290
291
294292
295293
296294
......
303301
304302
305303
306
307
308
304
305
306
309307
310308
311309
......
317315
318316
319317
320
321
322
318
319
320
323321
324322
325323
......
330328
331329
332330
333
334
331
332
335333
336334
337335
......
340338
341339
342340
343
344
341
342
345343
346344
347345
......
351349
352350
353351
354
355
352
353
356354
357355
358356
......
361359
362360
363361
364
365
362
363
366364
367365
368366
......
370368
371369
372370
373
374
371
372
375373
376374
377375
......
638636
639637
640638
641
639
642640
643641
644
645
646
642
643
644
647645
648646
649647
650
648
651649
652650
653651
......
862860
863861
864862
865
863
866864
867865
868866
869867
868
870869
871870
872871
......
894893
895894
896895
897
896
898897
899898
900899
901
900
902901
903902
904903
......
912911
913912
914913
915
914
916915
917916
918917
......
974973
975974
976975
976
977977
978978
979979
980980
981981
982982
983
983
984984
985985
986986
......
10941094
10951095
10961096
1097
10971098
10981099
10991100
......
11601161
11611162
11621163
1163
1164
11641165
11651166
11661167
// Start searching any potential location for ACPI Table
snprintf(dirSpec, sizeof(dirSpec), "%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
snprintf(dirSpec, sizeof(dirSpec), "/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
if (fd < 0) {
snprintf(dirSpec, sizeof(dirSpec), "/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
snprintf(dirSpec, sizeof(dirSpec), "bt(0,0)/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
// NOT FOUND:
verbose("ACPI Table not found: %s\n", filename);
*dirSpec = '\0';
snprintf(dirSpec, sizeof(dirSpec), "bt(0,0)/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0) {
// NOT FOUND:
verbose("ACPI Table not found: %s\n", filename);
*dirSpec = '\0';
}
}
}
unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);
struct aml_chunk* root = aml_create_node(NULL);
AML_CHUNK* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "CST_");
struct aml_chunk* pack = aml_add_package(name);
AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
AML_CHUNK* name = aml_add_name(scop, "CST_");
AML_CHUNK* pack = aml_add_package(name);
aml_add_byte(pack, cstates_count);
struct aml_chunk* tmpl = aml_add_package(pack);
AML_CHUNK* tmpl = aml_add_package(pack);
if (cst_using_systemio)
{
// C1
resource_template_register_fixedhw[9] = 0x00;
resource_template_register_fixedhw[18] = 0x00;
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x01); // C1
aml_add_word(tmpl, 0x0001); // Latency
aml_add_dword(tmpl, 0x000003e8); // Power
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_dword(tmpl, 0x000003e8);// Power
uint8_t p_blk_lo, p_blk_hi;
resource_template_register_systemio[11] = p_blk_lo; // C2
resource_template_register_systemio[12] = p_blk_hi; // C2
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x02); // C2
aml_add_word(tmpl, 0x0040); // Latency
aml_add_dword(tmpl, 0x000001f4); // Power
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_dword(tmpl, 0x000001f4);// Power
}
if (c4_enabled) // C4
resource_template_register_systemio[11] = p_blk_lo; // C4
resource_template_register_systemio[12] = p_blk_hi; // C4
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x04); // C4
aml_add_word(tmpl, 0x0080); // Latency
aml_add_dword(tmpl, 0x000000C8); // Power
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_dword(tmpl, 0x000000C8);// Power
}
else if (c3_enabled) // C3
{
resource_template_register_systemio[11] = p_blk_lo; // C3
resource_template_register_systemio[12] = p_blk_hi; // C3
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_dword(tmpl, 0x0000015e);// Power
}
}
// C1
resource_template_register_fixedhw[11] = 0x00; // C1
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_byte(tmpl, 0x01);// C1
aml_add_word(tmpl, 0x0001);// Latency
aml_add_dword(tmpl, 0x000003e8);// Power
resource_template_register_fixedhw[18] = 0x03;
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x10; // C2
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_byte(tmpl, 0x02);// C2
aml_add_word(tmpl, 0x0040);// Latency
aml_add_dword(tmpl, 0x000001f4);// Power
}
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x30; // C4
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_byte(tmpl, 0x04);// C4
aml_add_word(tmpl, 0x0080);// Latency
aml_add_dword(tmpl, 0x000000C8);// Power
}
else if (c3_enabled)
tmpl = aml_add_package(pack);
resource_template_register_fixedhw[11] = 0x20; // C3
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_byte(tmpl, 0x03);// C3
aml_add_word(tmpl, 0x0060);// Latency
aml_add_dword(tmpl, 0x0000015e);// Power
}
}
{
int i;
struct aml_chunk* root = aml_create_node(NULL);
AML_CHUNK* root = aml_create_node(NULL);
aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header
struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");
struct aml_chunk* name = aml_add_name(scop, "PSS_");
struct aml_chunk* pack = aml_add_package(name);
AML_CHUNK* scop = aml_add_scope(root, "\\_PR_");
AML_CHUNK* name = aml_add_name(scop, "PSS_");
AML_CHUNK* pack = aml_add_package(name);
for (i = 0; i < p_states_count; i++)
{
struct aml_chunk* pstt = aml_add_package(pack);
AML_CHUNK* pstt = aml_add_package(pack);
aml_add_dword(pstt, p_states[i].Frequency);
aml_add_dword(pstt, 0x00000000); // Power
/* Try using the file specified with the DSDT option */
if (getValueForKey(kDSDT, &filename, &len, &bootInfo->chameleonConfig))
{
snprintf(dirSpec, sizeof(dirSpec), filename);
snprintf(dirSpec, sizeof(dirSpec), filename);
}
else
{
sprintf(dirSpec, "DSDT.aml");
//verbose("dirSpec, DSDT.aml");
}
// Load replacement DSDT
{
int i;
for (i=0; i<30; i++)
for (i = 0; i < 30; i++)
{
char filename[512];
sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i);
sprintf(filename, i > 0?"SSDT-%d.aml":"SSDT.aml", i);
if ( (new_ssdt[ssdt_count] = loadACPITable(filename)) )
{
}
// Do the same procedure for both versions of ACPI
for (version=0; version<2; version++) {
for (version = 0; version < 2; version++) {
struct acpi_2_rsdp *rsdp, *rsdp_mod;
struct acpi_2_rsdt *rsdt, *rsdt_mod;
int rsdplength;
if (drop_ssdt && tableSign(table, "SSDT"))
{
verbose("OEM SSDT tables was dropped\n");
dropoffset++;
continue;
}
if (tableSign(table, "DSDT"))
{
DBG("DSDT found\n");
verbose("Custom DSDT table was found\n");
if(new_dsdt)
{
rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
if (drop_ssdt && tableSign(table, "SSDT"))
{
verbose("OEM SSDT tables was dropped\n");
dropoffset++;
continue;
}
xsdt_entries=(uint64_t *)(xsdt_mod+1);
// Mozodojo: Insert additional SSDTs into XSDT
if(ssdt_count>0)
if(ssdt_count > 0)
{
int j;
branches/chucko/i386/libsaio/device_tree.h
11
2
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
323
424
525
......
828
929
1030
31
32
33
1134
12
13
14
15
16
35
36
37
38
1739
1840
41
42
43
1944
20
21
22
23
24
25
45
46
47
48
2649
2750
2851
......
4770
4871
4972
50
51
52
53
73
74
75
5476
5577
5678
/*
* Copyright (c) 2005 Apple Computer, Inc. All Rights Reserved.
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef __DEVICE_TREE_H
#include <stdbool.h>
#include <stdint.h>
//==============================================================================
typedef struct _Property {
const char * name;
uint32_t length;
void * value;
struct _Property * next;
const char *name;
uint32_tlength;
void *value;
struct _Property *next;
} Property;
//==============================================================================
typedef struct _Node {
struct _Property * properties;
struct _Property * last_prop;
struct _Node * children;
struct _Node * next;
struct _Property *properties;
struct _Property *last_prop;
struct _Node *children;
struct _Node *next;
} Node;
void
DT__Initialize(void);
/*
* Free up memory used by in-memory representation
* of device tree.
*/
// Free up memory used by in-memory representation of device tree.
extern void
DT__Finalize(void);
branches/chucko/i386/libsaio/allocate.c
3333
3434
3535
36
37
3638
3739
3840
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
5864
5965
66
67
68
6069
61
70
6271
63
72
6473
65
66
67
68
69
70
74
75
76
77
78
7179
72
73
74
75
76
80
81
82
7783
78
84
85
86
7987
#define RoundPage(x) ((((unsigned)(x)) + kPageSize - 1) & ~(kPageSize - 1))
//==============================================================================
long
AllocateMemoryRange(char * rangeName, long start, long length, long type)
{
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) return -1;
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) {
free(nameBuf);
return -1;
}
strcpy(nameBuf, rangeName);
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
char *nameBuf;
uint32_t *buffer;
nameBuf = malloc(strlen(rangeName) + 1);
if (nameBuf == 0) {
return -1;
}
buffer = malloc(2 * sizeof(uint32_t));
if (buffer == 0) {
free(nameBuf);
return -1;
}
strcpy(nameBuf, rangeName);
buffer[0] = start;
buffer[1] = length;
DT__AddProperty(gMemoryMapNode, nameBuf, 2 * sizeof(uint32_t), (char *)buffer);
return 0;
}
//==============================================================================
long
AllocateKernelMemory( long inSize )
AllocateKernelMemory(long inSize)
{
long addr;
long addr;
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage( bootArgs->kaddr +
bootArgs->ksize );
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if (gImageLastKernelAddr == 0) {
gImageLastKernelAddr = RoundPage(bootArgs->kaddr + bootArgs->ksize);
}
addr = gImageLastKernelAddr;
gImageLastKernelAddr += RoundPage(inSize);
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
if ( gImageLastKernelAddr >= (KERNEL_ADDR + KERNEL_LEN) ) {
stop ("AllocateKernelMemory error");
}
return addr;
bootArgs->ksize = gImageLastKernelAddr - bootArgs->kaddr;
return addr;
}
branches/chucko/i386/libsaio/bootargs.h
4545
4646
4747
48
49
48
49
5050
5151
5252
......
5757
5858
5959
60
60
6161
6262
6363
......
9393
9494
9595
96
97
96
97
9898
9999
100100
101101
102102
103
104
103
104
105105
106106
107107
......
109109
110110
111111
112
113
112
113
114114
115115
116116
117117
118
118
119119
120120
121121
122
122
123123
124
124
125125
126126
127127
128128
129
129
130130
131
131
132132
133133
134
134
135135
136136
137
137
138138
139139
140140
141
141
142142
143143
144
144
145145
146146
147
147
148148
149149
150150
......
152152
153153
154154
155
155
156156
157157
158158
159159
160160
161
161
162162
163
163
164164
165165
166166
167167
168
168
169169
170
170
171171
172172
173
173
174174
175175
176
176
177177
178178
179179
180
180
181181
182182
183183
......
185185
186186
187187
188
188
189189
190190
191191
enum {
kEfiReservedMemoryType= 0,
kEfiLoaderCode= 1,
kEfiLoaderData= 2,
kEfiLoaderCode= 1,
kEfiLoaderData= 2,
kEfiBootServicesCode= 3,
kEfiBootServicesData= 4,
kEfiRuntimeServicesCode= 5,
kEfiACPIMemoryNVS= 10,
kEfiMemoryMappedIO= 11,
kEfiMemoryMappedIOPortSpace = 12,
kEfiPalCode= 13,
kEfiPalCode= 13,
kEfiMaxMemoryType= 14
};
/* Values for v_display */
#define GRAPHICS_MODE1
#define FB_TEXT_MODE2
#define GRAPHICS_MODE1
#define FB_TEXT_MODE2
/* Boot argument structure - passed into Mach kernel at boot time.
* "Revision" can be incremented for compatible changes
*/
// Lion
#define kBootArgsRevision0
#define kBootArgsVersion2
#define kBootArgsRevision0
#define kBootArgsVersion2
// Snow Leopard and older
#define kBootArgsPreLionRevision6
/* Snapshot constants of previous revisions that are supported */
#define kBootArgsEfiMode3232
#define kBootArgsEfiMode6464
#define kBootArgsEfiMode3232
#define kBootArgsEfiMode6464
typedef struct boot_args {
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */
uint8_t debugMode; /* Bit field with behavior changes */
uint8_t __reserved1[2];
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t MemoryMapSize;
uint32_t MemoryMapDescriptorSize;
uint32_t MemoryMapDescriptorVersion;
Boot_VideoVideo;/* Video Information */
uint32_t deviceTreeP; /* Physical address of flattened device tree */
uint32_t deviceTreeLength; /* Length of flattened tree */
uint32_t kaddr; /* Physical address of beginning of kernel text */
uint32_t ksize; /* Size of combined kernel text+data+efi */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
uint32_t efiRuntimeServicesPageCount;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint32_t __reserved2;
uint32_t performanceDataStart; /* physical address of log */
uint32_t performanceDataSize;
uint32_t keyStoreDataStart; /* physical address of key store data */
uint32_t keyStoreDataSize;
uint64_tbootMemStart;
uint64_t PhysicalMemorySize;
uint64_t FSBFrequency;
uint32_t __reserved4[734];
} boot_args;
typedef struct boot_args_pre_lion {
uint16_t Revision;/* Revision of boot_args structure */
uint16_t Version;/* Version of boot_args structure */
char CommandLine[BOOT_LINE_LENGTH];/* Passed in command line */
uint32_t MemoryMap; /* Physical address of memory map */
uint32_t MemoryMapSize;
uint32_t MemoryMapDescriptorSize;
uint32_t MemoryMapDescriptorVersion;
Boot_VideoVideo;/* Video Information */
uint32_t deviceTreeP; /* Physical address of flattened device tree */
uint32_t deviceTreeLength; /* Length of flattened tree */
uint32_t kaddr; /* Physical address of beginning of kernel text */
uint32_t ksize; /* Size of combined kernel text+data+efi */
uint32_t efiRuntimeServicesPageStart; /* physical address of defragmented runtime pages */
uint32_t efiRuntimeServicesPageCount;
uint32_t efiSystemTable; /* physical address of system table in runtime area */
uint8_t efiMode; /* 32 = 32-bit, 64 = 64-bit */
uint8_t __reserved1[3];
uint32_t __reserved2[1];
uint32_t performanceDataSize;
uint64_t efiRuntimeServicesVirtualPageStart; /* virtual address of defragmented runtime pages */
uint32_t __reserved3[2];
} boot_args_pre_lion;
extern char gMacOSVersion[8];
branches/chucko/i386/libsaio/spd.c
6969
7070
7171
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
10972
11073
11174
......
11982
12083
12184
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
122128
123129
124130
......
132138
133139
134140
135
136
137
138
141
142
143
144
139145
140
141
142
143
144
145
146
147
148
149
150
151
146
147
148
149
150
151
152
153
154
152155
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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
167189
168190
169
191
170192
171193
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
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
199227
200228
201229
202230
203231
204
232
205233
206234
207
235
208236
209
210
211
212
213
214
215
216
237
238
239
240
241
242
243
244
245
246
217247
218
248
219249
220250
221
251
222252
223253
224254
225255
226256
227
257
258
228259
229260
230
261
262
231263
232264
233265
234
235
266
267
236268
237
269
270
238271
239272
240
273
274
275
241276
277
242278
279
243280
281
244282
245283
246284
......
249287
250288
251289
252
290
253291
254292
255
256
257
258
259
293
294
295
296
297
260298
261299
262300
263301
264302
265303
266
304
267305
268
269
306
307
270308
271
272
309
310
273311
274
312
275313
276314
277
278
279
280
281
282
283
284
315
316
317
318
319
320
321
322
323
324
285325
286326
287
327
328
288329
289
290
291
292
330
331
332
333
293334
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
335
317336
318
319
320
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
321378
322379
323
380
381
324382
325383
326384
327
385
386
328387
329388
330389
......
342401
343402
344403
345
346
404
405
406
347407
348
349
350
351
352
353
354
355
356
408
409
410
411
357412
358413
359
414
360415
361416
362417
418
363419
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
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
381445
382446
383447
......
385449
386450
387451
388
389
452
453
390454
391
455
456
392457
393
394
395
396
458
459
460
461
397462
398
399
400
401
402
403
404
405
406
407
408
409
410
463
464
465
466
467
468
469
470
471
472
473
474
411475
412476
413477
414478
415
479
416480
417481
#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);
rdtsc(l1, h1);
while ( inb(base + SMBHSTSTS) & 0x01) // wait until read
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
return 0xFF; // break
}
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 / 100);
if (t > 5)
break;// break after 5ms
}
return inb(base + SMBHSTDAT);
}
/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */
#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x)
int spd_indexes[] = {
SPD_MEMORY_TYPE,
SPD_DDR3_MEMORY_BANK,
};
#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int))
/** 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);
rdtsc(l1, h1);
while ( inb(base + SMBHSTSTS) & 0x01) // wait until read
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
if (t > 5)
{
return 0xFF;// break
}
}
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 / 100);
if (t > 5)
{
break;// break after 5ms
}
}
return inb(base + SMBHSTDAT);
}
/* SPD i2c read optimization: prefetch only what we need, read non prefetcheable bytes on the fly */
#define READ_SPD(spd, base, slot, x) spd[x] = smb_read_byte_intel(base, 0x50 + slot, x)
/** Read from spd *used* values only*/
static void init_spd(char * spd, uint32_t base, int slot)
{
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
uint8_t * spd = (uint8_t *) slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
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[64]==0x7f) {
for (i=64; i<72 && spd[i]==0x7f;i++) {
bank++;
READ_SPD(spd, base, slot_num,i+1); // prefetch next spd byte to read for next loop
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{ // DDR3
bank = (spd[SPD_DDR3_MEMORY_BANK] & 0x07f); // constructors like Patriot use b7=1
code = spd[SPD_DDR3_MEMORY_CODE];
for (i=0; i < VEN_MAP_SIZE; i++)
{
if (bank==vendorMap[i].bank && code==vendorMap[i].code)
{
return vendorMap[i].name;
}
READ_SPD(spd, base, slot_num,i);
code = spd[i];
} else {
code = spd[64];
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";
}
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
if(spd[64]==0x7f)
{
for (i=64; i<72 && spd[i]==0x7f;i++)
{
bank++;
READ_SPD(spd, base, slot_num, (uint8_t)(i+1)); // prefetch next spd byte to read for next loop
}
READ_SPD(spd, base, slot_num,(uint8_t)i);
code = spd[i];
}
else
{
code = spd[64];
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) */
/* 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
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 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
switch(spd[9])
{
case 0x50:
return 400;
case 0x3d:
return 533;
case 0x30:
return 667;
case 0x25:
default:
return 800;
case 0x1E:
return 1066;
}
}
return 800; // default freq for unknown types
}
#define SMST(a) ((uint8_t)((spd[a] & 0xf0) >> 4))
#define SLST(a) ((uint8_t)(spd[a] & 0x0f))
/** Get DDR3 or DDR2 serial number, 0 most of the times, always return a valid ptr */
/* 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 char asciiSerial[16];
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
}
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) // DDR3
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(122) /*& 0x7*/, SLST(122), SMST(123), SLST(123), SMST(124), SLST(124), SMST(125), SLST(125));
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR) // DDR2 or DDR
{
sprintf(asciiSerial, "%X%X%X%X%X%X%X%X", SMST(95) /*& 0x7*/, SLST(95), SMST(96), SLST(96), SMST(97), SLST(97), SMST(98), SLST(98));
} else {
sprintf(asciiSerial, "0000000000000000");
}
return strdup(asciiSerial);
return strdup(asciiSerial);
}
/** Get DDR3 or DDR2 Part Number, always return a valid ptr */
/* Get DDR3 or DDR2 Part Number, always return a valid ptr */
const char * getDDRPartNum(char* spd, uint32_t base, int slot)
{
static char asciiPartNo[32];
int i, start=0, index = 0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
{
start = 128;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR)
{
start = 73;
}
// Check that the spd part name is zero terminated and that it is ascii:
bzero(asciiPartNo, sizeof(asciiPartNo));
// Check that the spd part name is zero terminated and that it is ascii:
bzero(asciiPartNo, sizeof(asciiPartNo));
char c;
for (i=start; i < start + sizeof(asciiPartNo); i++) {
for (i=start; i < start + sizeof(asciiPartNo); i++)
{
READ_SPD(spd, base, slot, i); // only read once the corresponding model part (ddr3 or ddr2)
c = spd[i];
if (isalpha(c) || isdigit(c) || ispunct(c)) // It seems that System Profiler likes only letters and digits...
if (isalpha(c) || isdigit(c) || ispunct(c))
{
// It seems that System Profiler likes only letters and digits...
asciiPartNo[index++] = c;
}
else if (!isascii(c))
{
break;
}
}
return strdup(asciiPartNo);
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 */
/* 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, speed;
uint8_t spd_size, spd_type;
uint32_t base, mmio, hostc;
// bool dump = false;
RamSlotInfo_t* slot;
uint16_t speed;
uint8_t i, spd_size, spd_type;
uint32_t base, mmio, hostc;
//bool dump = false;
RamSlotInfo_t* slot;
uint16_t cmd = pci_config_read16(smbus_dev->dev.addr, 0x04);
DBG("SMBus CmdReg: 0x%x\n", cmd);
pci_config_write16(smbus_dev->dev.addr, 0x04, cmd | 1);
mmio = pci_config_read32(smbus_dev->dev.addr, 0x10);// & ~0x0f;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
base = pci_config_read16(smbus_dev->dev.addr, 0x20) & 0xFFFE;
hostc = pci_config_read8(smbus_dev->dev.addr, 0x40);
verbose("Scanning SMBus [%04x:%04x], mmio: 0x%x, ioport: 0x%x, hostc: 0x%x\n",
smbus_dev->vendor_id, smbus_dev->device_id, mmio, base, hostc);
verbose("Scanning SMBus [%04x:%04x], mmio: 0x%x, ioport: 0x%x, hostc: 0x%x\n",
smbus_dev->vendor_id, smbus_dev->device_id, mmio, base, hostc);
//Azi: no use for this!
// getBoolForKey("DumpSPD", &dump, &bootInfo->chameleonConfig);
//Azi: no use for this!
// getBoolForKey("DumpSPD", &dump, &bootInfo->chameleonConfig);
// needed at least for laptops
bool fullBanks = Platform.DMI.MemoryModules == Platform.DMI.CntMemorySlots;
bool fullBanks = Platform.DMI.MemoryModules == Platform.DMI.CntMemorySlots;
char spdbuf[MAX_SPD_SIZE];
// 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);
DBG("SPD[0] (size): %d @0x%x\n", spd_size, 0x50 + i);
// Check spd is present
if (spd_size && (spd_size != 0xff))
{
// 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);
DBG("SPD[0] (size): 0x%02x @0x%x\n", spd_size, 0x50 + i);
// Check spd is present
if (spd_size && (spd_size != 0xff))
{
slot->spd = spdbuf;
slot->InUse = true;
// -----
slot->InUse = true;
bzero(slot->spd, spd_size);
// Copy spd data into buffer
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);
init_spd(slot->spd, base, i);
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 = getDDRPartNum(slot->spd, base, i);
slot->Vendor = getVendorName(slot, base, i);
slot->SerialNo = getDDRSerial(slot->spd);
init_spd(slot->spd, base, i);
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (slot->Frequency<speed) slot->Frequency = speed;
switch (slot->spd[SPD_MEMORY_TYPE])
{
case SPD_MEMORY_TYPE_SDRAM_DDR:
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])/3)*2;
break;
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];
if (slot->Type == UNKNOWN_MEM_TYPE)
{
continue;
}
slot->PartNo = getDDRPartNum(slot->spd, base, i);
slot->Vendor = getVendorName(slot, base, i);
slot->SerialNo = getDDRSerial(slot->spd);
// determine spd speed
speed = getDDRspeedMhz(slot->spd);
if (slot->Frequency<speed)
{
slot->Frequency = speed;
}
// pci memory controller if available, is more reliable
if (Platform.RAM.Frequency > 0) {
if (Platform.RAM.Frequency > 0)
{
uint32_t freq = (uint32_t)Platform.RAM.Frequency / 500000;
// now round off special cases
uint32_t fmod100 = freq %100;
switch(fmod100) {
switch(fmod100)
{
case 1:freq--;break;
case 32:freq++;break;
case 65:freq++; break;
slot->Frequency,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
slot->SerialNo);
slot->InUse = true;
}
}
// 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.CntMemorySlots == 2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform.DMI.DIMM[i]=
(uint32_t)((i>0 && Platform.RAM.DIMM[1].InUse==false && !fullBanks && Platform.DMI.CntMemorySlots == 2) ?
mapping[i] : i); // for laptops case, mapping setup would need to be more generic than this
slot->spd = NULL;
} // for
} // for
}
static struct smbus_controllers_t smbus_controllers[] = {
// Info from here: http://cateee.net/lkddb/web-lkddb/I2C_I801.html
{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, "5 Series",read_smb_intel },
{0x8086, 0x1C22, "6 Series",read_smb_intel },
{0x8086, 0x1D22, "C600/X79 Series",read_smb_intel },
{0x8086, 0x1E22, "7 Series",read_smb_intel },
{0x8086, 0x5032, "EP80579",read_smb_intel },
{0x8086, 0x8C22, "8 Series",read_smb_intel },
{0x8086, 0x9C22, "Lynx Point-LP", read_smb_intel }
{0x8086, 0x1C22, "6 Series", read_smb_intel },
{0x8086, 0x1D22, "C600/X79 Series", read_smb_intel },
{0x8086, 0x1D70, "C600/X79 Series", read_smb_intel },
{0x8086, 0x1D71, "C608/C606/X79 Series", read_smb_intel },
{0x8086, 0x1D72, "C608", read_smb_intel },
{0x8086, 0x1E22, "7 Series/C210 Series", read_smb_intel },
{0x8086, 0x2330, "DH89xxCC", read_smb_intel },
{0x8086, 0x2413, "82801AA", read_smb_intel },
{0x8086, 0x2423, "82801BA/BAM", read_smb_intel },
{0x8086, 0x2443, "82801BA/BAM", read_smb_intel },
{0x8086, 0x2483, "82801CA/CAM", read_smb_intel },
{0x8086, 0x24C3, "82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M)", read_smb_intel },
{0x8086, 0x24D3, "82801EB/ER (ICH5/ICH5R)", read_smb_intel },
{0x8086, 0x25A4, "6300ESB", read_smb_intel },
{0x8086, 0x266A, "82801FB/FBM/FR/FW/FRW (ICH6 Family)", read_smb_intel },
{0x8086, 0x269B, "631xESB/632xESB/3100", read_smb_intel },
{0x8086, 0x27DA, "N10/ICH 7 Family", read_smb_intel },
{0x8086, 0x283E, "82801H (ICH8 Family) ", read_smb_intel },
{0x8086, 0x2930, "82801I (ICH9 Family)", read_smb_intel },
{0x8086, 0x3A30, "82801JI (ICH10 Family)", read_smb_intel },
{0x8086, 0x3A60, "82801JD/DO (ICH10 Family)", read_smb_intel },
{0x8086, 0x3B30, "5 Series/3400 Series", read_smb_intel },
{0x8086, 0x5032, "EP80579", read_smb_intel },
{0x8086, 0x8C22, "8 Series/C220", read_smb_intel },
{0x8086, 0x9C22, "Lynx Point-LP", read_smb_intel }
};
// 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;
pci_dt_t*current = pci_dt;
int i;
while (current) {
while (current)
{
#if 0
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));
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
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)
{
find_and_read_smbus_controller(root_pci_dev);
find_and_read_smbus_controller(root_pci_dev);
}
branches/chucko/i386/libsaio/spd.h
1616
1717
1818
19
19
2020
2121
2222
......
3838
3939
4040
41
4142
4243
4344
......
130131
131132
132133
134
135
136
133137
134138
135139
......
141145
142146
143147
148
144149
145150
146151
uint32_tvendor;
uint32_tdevice;
char*name;
void (*read_smb)(pci_dt_t *smbus_dev);
void (*read_smb)(pci_dt_t *smbus_dev);
};
/* 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 */
// (Essentially) common to DDR & DDR2
#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 ERROR_SCHEME_NONE0
#define ERROR_SCHEME_PARITY1
#define ERROR_SCHEME_ECC2
#define DDR2_DATA_PARITY(1<<0)
#define DDR2_DATA_ECC(1<<1)
#define DDR2_ADDRESS_PARITY(1<<2)
/* SPD_ACCEPTABLE_CAS_LATENCIES values. */
// TODO: Check values.
#define SPD_CAS_LATENCY_3_50x20
#define SPD_CAS_LATENCY_4_00x40
#define SPD_CAS_LATENCY_DDR2_2(1 << 2)
#define SPD_CAS_LATENCY_DDR2_3(1 << 3)
#define SPD_CAS_LATENCY_DDR2_4(1 << 4)
#define SPD_CAS_LATENCY_DDR2_5(1 << 5)
branches/chucko/i386/libsaio/bios.h
3232
3333
3434
35
36
37
38
39
40
35
36
37
38
39
40
4141
4242
4343
44
45
46
47
48
49
50
51
52
53
54
55
56
57
44
45
46
47
48
49
50
51
52
53
54
55
56
57
5858
5959
6060
61
62
63
64
65
66
67
68
69
70
71
72
61
62
63
64
65
66
67
68
69
70
71
72
7373
7474
75
76
77
75
76
77
7878
79
79
8080
8181
8282
8383
8484
8585
86
87
88
89
86
87
88
89
9090
91
91
9292
9393
9494
......
9696
9797
9898
99
100
101
102
99
100
101
102
103103
104104
105105
#include "bootargs.h"
typedef union {
unsigned int rx;
unsigned short rr;
struct {
unsigned char l;
unsigned char h;
} r;
unsigned int rx;
unsigned short rr;
struct {
unsigned char l;
unsigned char h;
} r;
} machineRegister_t;
typedef struct {
unsigned short cf :1;
unsigned short :1;
unsigned short pf :1;
unsigned short :1;
unsigned short af :1;
unsigned short :1;
unsigned short zf :1;
unsigned short sf :1;
unsigned short tf :1;
unsigned short _if :1;
unsigned short df :1;
unsigned short of :1;
unsigned short iopl:2;
unsigned short nt :1;
unsigned short cf :1;
unsigned short :1;
unsigned short pf :1;
unsigned short :1;
unsigned short af :1;
unsigned short :1;
unsigned short zf :1;
unsigned short sf :1;
unsigned short tf :1;
unsigned short _if :1;
unsigned short df :1;
unsigned short of :1;
unsigned short iopl:2;
unsigned short nt :1;
} machineFlags_t;
typedef struct {
unsigned int intno;
machineRegister_t eax;
machineRegister_t ebx;
machineRegister_t ecx;
machineRegister_t edx;
machineRegister_t edi;
machineRegister_t esi;
machineRegister_t ebp;
unsigned short cs;
unsigned short ds;
unsigned short es;
machineFlags_t flags;
unsigned int intno;
machineRegister_t eax;
machineRegister_t ebx;
machineRegister_t ecx;
machineRegister_t edx;
machineRegister_t edi;
machineRegister_t esi;
machineRegister_t ebp;
unsigned short cs;
unsigned short ds;
unsigned short es;
machineFlags_t flags;
} biosBuf_t;
#define EBIOS_FIXED_DISK_ACCESS 0x01
#define EBIOS_LOCKING_ACCESS 0x02
#define EBIOS_ENHANCED_DRIVE_INFO 0x04
#define EBIOS_FIXED_DISK_ACCESS0x01
#define EBIOS_LOCKING_ACCESS0x02
#define EBIOS_ENHANCED_DRIVE_INFO0x04
#define BASE_HD_DRIVE 0x80
#define BASE_HD_DRIVE0x80
#if 0
/*
* ACPI defined memory range types.
*/
enum {
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
kMemoryRangeUsable = 1, // RAM usable by the OS.
kMemoryRangeReserved = 2, // Reserved. (Do not use)
kMemoryRangeACPI = 3, // ACPI tables. Can be reclaimed.
kMemoryRangeNVS = 4, // ACPI NVS memory. (Do not use)
/* Undefined types should be treated as kMemoryRangeReserved */
/* Undefined types should be treated as kMemoryRangeReserved */
};
#endif
* Memory range descriptor.
*/
typedef struct MemoryRange {
unsigned long long base; // 64-bit base address
unsigned long long length; // 64-bit length in bytes
unsigned long type; // type of memory range
unsigned long reserved;
unsigned long long base; // 64-bit base address
unsigned long long length; // 64-bit length in bytes
unsigned long type; // type of memory range
unsigned long reserved;
} MemoryRange;
#endif /* !__LIBSAIO_BIOS_H */
branches/chucko/i386/libsaio/gma.c
354354
355355
356356
357
357
358358
359359
360360
......
388388
389389
390390
391
392
391
393392
394393
395394
396395
397
398
396
399397
400398
401399
{
if (intel_gfx_chipsets[i].model == ((device_id << 16) | vendor_id))
{
snprintf(desc, sizeof(desc), "%s %s", INTEL_NAME, intel_gfx_chipsets[i].label_info);
snprintf(desc, sizeof(desc), "%s %s", INTEL_NAME, intel_gfx_chipsets[i].label_info);
return desc;
}
}
verbose("Class code: [%04x]\n%s [%04x:%04x] (rev %02x)\nSubsystem: [%04x:%04x] :: %s\n",
gma_dev->class_id, model, gma_dev->vendor_id, gma_dev->device_id, gma_dev->revision_id, gma_dev->subsys_id.subsys.vendor_id, gma_dev->subsys_id.subsys.device_id, devicepath);
if (!string)
{
if (!string) {
string = devprop_create_string();
}
struct DevPropDevice *device = devprop_add_device(string, devicepath);
if (!device)
{
if (!device) {
printf("Failed initializing dev-prop string dev-entry.\n");
pause();
return false;
branches/chucko/i386/libsaio/pci_root.c
7979
8080
8181
82
82
8383
8484
8585
......
105105
106106
107107
108
108
109109
110110
111111
// Try using the file specified with the DSDT option
if (getValueForKey(kDSDT, &dsdt_filename, &len, &bootInfo->chameleonConfig))
{
snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);
snprintf(dsdt_dirSpec, sizeof(dsdt_dirSpec), dsdt_filename);
}
else
{
}
if (read (fd, new_dsdt, fsize) != fsize) {
verbose("[ERROR] read %s failed\n", dsdt_filename);
free(new_dsdt);
free(new_dsdt);
close (fd);
goto out;
}
branches/chucko/i386/libsaio/aml_generator.c
55
66
77
8
89
910
1011
1112
12
13
1314
1415
1516
......
2425
2526
2627
27
28
28
2929
3030
3131
......
3535
3636
3737
38
38
3939
40
41
40
41
4242
43
43
4444
4545
4646
......
4949
5050
5151
52
52
5353
54
54
5555
5656
5757
5858
5959
6060
61
61
6262
6363
64
64
6565
6666
6767
68
68
6969
70
70
7171
72
72
7373
7474
7575
7676
7777
7878
79
79
8080
81
8182
8283
8384
8485
85
86
8687
87
88
8889
89
90
90
9191
92
92
9393
9494
9595
......
9797
9898
9999
100
100
101101
102
102
103103
104
105
104
106105
107
108106
109107
110108
111109
112
113110
114111
115112
116
113
117114
118
115
119116
120
121
117
122118
123119
124120
125121
126122
127123
128
129124
130125
131126
132
127
133128
134
129
135130
136
137
131
138132
139133
140134
......
143137
144138
145139
146
147140
148141
149142
150
143
151144
152
145
153146
154
155
147
156148
157149
158150
......
165157
166158
167159
168
169160
170161
171162
172
163
173164
174
175
165
176166
177167
178168
179
180169
181170
182171
183172
184
173
185174
186
175
176
177
178
187179
180
188181
189
182
183
184
190185
191
192
186
193187
194188
195189
196
197
198190
199
191
200192
201
202
203
204
205
193
194
195
196
197
206198
207
199
200
208201
209202
210
211
203
212204
213
205
214206
215207
216208
217
209
210
218211
219212
220
221
213
214
222215
223216
224
217
225218
226
227
219
220
228221
229222
230
223
231224
232
225
233226
234
235
227
236228
237229
238230
239231
240
241232
242233
243234
244
235
245236
246
237
247238
248
249
239
250240
251241
252242
253243
244
245
254246
247
248
249
250
251
252
253
254
255
256
257
258
255259
256260
257261
258
262
259263
260
264
261265
262
263
266
264267
265268
266269
267270
268271
269
270272
271273
272274
273
275
274276
275
277
276278
277
278
279
279280
280281
281282
......
287288
288289
289290
290
291
291292
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
292417
293418
294
419
295420
296
421
297422
298423
299
424
300425
301426
302
427
303428
304
305
306
307
429
308430
309
310
431
432
311433
312
313
434
435
314436
315437
316
438
317439
318440
319441
320442
321
322
443
323444
445
446
324447
325448
449
450
326451
452
327453
328454
329455
456
457
458
459
460
461
330462
331463
332464
......
334466
335467
336468
337
338
469
339470
340
341
342
471
343472
344473
345
346474
347475
348476
......
350478
351479
352480
481
482
353483
354484
355485
356
357486
358487
359
360488
361489
362490
363
491
364492
365493
366494
367495
368496
369497
370
498
371499
372500
373501
......
375503
376504
377505
378
506
379507
380508
381509
......
385513
386514
387515
388
516
389517
390518
391519
......
399527
400528
401529
402
530
403531
404
405
532
406533
407534
408535
409536
410537
411538
412
539
413540
414
415
416
417
418
419
420
421
422
423
424
425
426
541
542
543
544
545
546
547
548
427549
428
429
430
431
432
550
551
552
433553
434554
435555
......
437557
438558
439559
440
560
441561
442
443
444
562
563
564
445565
446
447
566
448567
449568
450569
451570
571
572
573
574
575
576
577
578
579
580
581
582
452583
584
453585
586
454587
455588
456589
457590
458591
459592
460
461
593
462594
463
464
465
595
466596
467597
468598
......
473603
474604
475605
606
607
476608
477609
478610
......
481613
482614
483615
484
616
617
485618
486
487
488
489
490619
491620
492621
493
494
622
623
624
625
495626
496627
497628
498629
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
* Created by Mozodojo on 20/07/10.
* Copyright 2010 mozo. All rights reserved.
*
* additions and corrections by Slice and pcj, 2012.
*/
#include "aml_generator.h"
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
bool aml_add_to_parent(AML_CHUNK* parent, AML_CHUNK* node)
{
if (parent && node)
{
verbose("aml_add_to_parent: Node doesn't support child nodes!\n");
return false;
case AML_CHUNK_NAME:
if (parent->First)
{
if (parent->First) {
verbose("aml_add_to_parent: Name node supports only one child node!\n");
return false;
}
break;
}
if (!parent->First)
if (!parent->First) {
parent->First = node;
if (parent->Last)
}
if (parent->Last) {
parent->Last->Next = node;
}
parent->Last = node;
return true;
return false;
}
struct aml_chunk* aml_create_node(struct aml_chunk* parent)
AML_CHUNK* aml_create_node(AML_CHUNK* parent)
{
struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));
AML_CHUNK* node = (AML_CHUNK*)malloc(sizeof(AML_CHUNK));
aml_add_to_parent(parent, node);
return node;
}
void aml_destroy_node(struct aml_chunk* node)
void aml_destroy_node(AML_CHUNK* node)
{
// Delete child nodes
struct aml_chunk* child = node->First;
AML_CHUNK* child = node->First;
while (child)
{
struct aml_chunk* next = child->Next;
AML_CHUNK* next = child->Next;
if (child->Buffer)
if (child->Buffer) {
free(child->Buffer);
}
free(child);
child = next;
}
// Free node
if (node->Buffer)
if (node->Buffer) {
free(node->Buffer);
}
free(node);
}
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
AML_CHUNK* aml_add_buffer(AML_CHUNK* parent, char* buffer, uint32_t size)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_NONE;
node->Length = size;
node->Length = (uint16_t)size;
node->Buffer = malloc(node->Length);
memcpy(node->Buffer, buffer, node->Length);
}
return node;
}
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value)
AML_CHUNK* aml_add_byte(AML_CHUNK* parent, uint8_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_BYTE;
node->Length = 1;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value;
}
return node;
}
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value)
AML_CHUNK* aml_add_word(AML_CHUNK* parent, uint16_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_WORD;
node->Length = 2;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value & 0xff;
node->Buffer[1] = value >> 8;
}
return node;
}
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value)
AML_CHUNK* aml_add_dword(AML_CHUNK* parent, uint32_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_DWORD;
node->Length = 4;
node->Buffer = malloc(node->Length);
node->Buffer[2] = (value >> 16) & 0xff;
node->Buffer[3] = (value >> 24) & 0xff;
}
return node;
}
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value)
AML_CHUNK* aml_add_qword(AML_CHUNK* parent, uint64_t value)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_QWORD;
node->Length = 8;
node->Buffer = malloc(node->Length);
node->Buffer[6] = (value >> 48) & 0xff;
node->Buffer[7] = (value >> 56) & 0xff;
}
return node;
}
unsigned int aml_fill_simple_name(char* buffer, const char* name)
uint32_t aml_fill_simple_name(char* buffer, char* name)
{
if (strlen(name) < 4)
{
if (strlen(name) < 4) {
verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4.\n", name);
return 0;
}
memcpy(buffer, name, 4);
return 4;
}
unsigned int aml_fill_name(struct aml_chunk* node, const char* name)
uint32_t aml_fill_name(AML_CHUNK* node, char* name)
{
if (!node)
int len, offset, count;
uint32_t root = 0;
if (!node) {
return 0;
}
int len = strlen(name), offset = 0, count = len / 4;
len = strlen(name);
offset = 0;
count = len >> 2;
if ((len % 4) > 1 || count == 0)
{
if ((len % 4) > 1 || count == 0) {
verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16, etc...\n", name);
return 0;
}
unsigned int root = 0;
if ((len % 4) == 1 && name[0] == '\\')
if (((len % 4) == 1) && (name[0] == '\\')) {
root++;
if (count == 1)
{
node->Length = 4 + root;
node->Buffer = malloc(node->Length);
}
if (count == 1) {
node->Length = (uint16_t)(4 + root);
node->Buffer = malloc(node->Length+4);
memcpy(node->Buffer, name, 4 + root);
return node->Length;
offset += 4 + root;
return (uint32_t)offset;
}
if (count == 2)
{
if (count == 2) {
node->Length = 2 + 8;
node->Buffer = malloc(node->Length);
node->Buffer = malloc(node->Length+4);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2e; // Double name
memcpy(node->Buffer+offset, name + root, 8);
return node->Length;
offset += 8;
return (uint32_t)offset;
}
node->Length = 3 + count*4;
node->Buffer = malloc(node->Length);
node->Length = (uint16_t)(3 + (count << 2));
node->Buffer = malloc(node->Length+4);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2f; // Multi name
node->Buffer[offset++] = count; // Names count
node->Buffer[offset++] = (char)count; // Names count
memcpy(node->Buffer+offset, name + root, count*4);
return node->Length;
offset += count*4;
return (uint32_t)offset;
}
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)
AML_CHUNK* aml_add_scope(AML_CHUNK* parent, char* name)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_SCOPE;
aml_fill_name(node, name);
}
return node;
}
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name)
AML_CHUNK* aml_add_name(AML_CHUNK* parent, char* name)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_NAME;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_method(AML_CHUNK* parent, char* name, uint8_t args)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
unsigned int offset = aml_fill_name(node, name);
node->Type = AML_CHUNK_METHOD;
node->Length++;
node->Buffer[offset] = args;
}
return node;
}
struct aml_chunk* aml_add_package(struct aml_chunk* parent)
AML_CHUNK* aml_add_package(AML_CHUNK* parent)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_PACKAGE;
node->Length = 1;
node->Buffer = malloc(node->Length);
}
return node;
}
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2)
AML_CHUNK* aml_add_alias(AML_CHUNK* parent, char* name1, char* name2)
{
struct aml_chunk* node = aml_create_node(parent);
AML_CHUNK* node = aml_create_node(parent);
if (node)
{
if (node) {
node->Type = AML_CHUNK_ALIAS;
node->Length = 8;
return node;
}
unsigned char aml_get_size_length(unsigned int size)
AML_CHUNK* aml_add_return_name(AML_CHUNK* parent, char* name)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_return_byte(AML_CHUNK* parent, uint8_t value)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
aml_add_byte(node, value);
}
return node;
}
AML_CHUNK* aml_add_device(AML_CHUNK* parent, char* name)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_DEVICE;
aml_fill_name(node, name);
}
return node;
}
AML_CHUNK* aml_add_local0(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_LOCAL0;
node->Length = 1;
}
return node;
}
AML_CHUNK* aml_add_store(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_STORE_OP;
node->Length = 1;
}
return node;
}
AML_CHUNK* aml_add_byte_buffer(AML_CHUNK* parent, char* data, uint32_t size)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
int offset = 0;
node->Type = AML_CHUNK_BUFFER;
node->Length = (uint8_t)(size + 2);
node->Buffer = malloc (node->Length);
node->Buffer[offset++] = AML_CHUNK_BYTE; //0x0A
node->Buffer[offset++] = (char)size;
memcpy(node->Buffer+offset,data, node->Length);
}
return node;
}
AML_CHUNK* aml_add_string_buffer(AML_CHUNK* parent, char* StringBuf)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
unsigned int offset = 0;
unsigned int len = strlen(StringBuf)+1;
node->Type = AML_CHUNK_BUFFER;
node->Length = (uint8_t)(len + 3);
node->Buffer = malloc (node->Length);
node->Buffer[offset++] = AML_CHUNK_BYTE;
node->Buffer[offset++] = (char)len;
memcpy(node->Buffer+offset, StringBuf, len);
node->Buffer[offset+len] = '\0';
}
return node;
}
AML_CHUNK* aml_add_string(AML_CHUNK* parent, char* StringBuf)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
int len = strlen(StringBuf);
node->Type = AML_CHUNK_STRING;
node->Length = (uint8_t)(len + 1);
node->Buffer = malloc (len);
memcpy(node->Buffer, StringBuf, len);
node->Buffer[len] = '\0';
}
return node;
}
AML_CHUNK* aml_add_return(AML_CHUNK* parent)
{
AML_CHUNK* node = aml_create_node(parent);
if (node) {
node->Type = AML_CHUNK_RETURN;
//aml_add_byte(node, value);
}
return node;
}
uint8_t aml_get_size_length(uint32_t size)
{
if (size + 1 <= 0x3f)
return 1;
else if (size + 2 <= 0x3fff)
else if (size + 2 <= 0xfff) /* Encode in 4 bits and 1 byte */
return 2;
else if (size + 3 <= 0x3fffff)
else if (size + 3 <= 0xfffff) /* Encode in 4 bits and 2 bytes */
return 3;
return 4;
return 4; /* Encode 0xfffffff in 4 bits and 2 bytes */
}
unsigned int aml_calculate_size(struct aml_chunk* node)
uint32_t aml_calculate_size(AML_CHUNK* node)
{
if (node)
{
node->Size = 0;
if (node) {
// Calculate child nodes size
struct aml_chunk* child = node->First;
unsigned char child_count = 0;
AML_CHUNK* child = node->First;
uint8_t child_count = 0;
while (child)
{
node->Size = 0;
while (child) {
child_count++;
node->Size += aml_calculate_size(child);
node->Size += (uint16_t)aml_calculate_size(child);
child = child->Next;
}
switch (node->Type)
{
switch (node->Type) {
case AML_CHUNK_NONE:
case AML_STORE_OP:
case AML_CHUNK_LOCAL0:
node->Size += node->Length;
break;
case AML_CHUNK_METHOD:
case AML_CHUNK_SCOPE:
case AML_CHUNK_BUFFER:
node->Size += 1 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_DEVICE:
node->Size += 2 + node->Length;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_PACKAGE:
node->Buffer[0] = child_count;
node->Size += 1 + node->Length;
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) {
node->Size += node->Length;
}
else
{
} else {
node->Size += 1 + node->Length;
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
case AML_CHUNK_RETURN:
case AML_CHUNK_STRING:
node->Size += 1 + node->Length;
break;
}
return node->Size;
}
return 0;
}
unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)
uint32_t aml_write_byte(uint8_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value;
return offset;
}
unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)
uint32_t aml_write_word(uint16_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = value >> 8;
return offset;
}
unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)
uint32_t aml_write_dword(uint32_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
return offset;
}
unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)
uint32_t aml_write_qword(uint64_t value, char* buffer, uint32_t offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
return offset;
}
unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)
uint32_t aml_write_buffer(const char* value, uint32_t size, char* buffer, uint32_t offset)
{
if (size > 0)
{
if (size > 0) {
memcpy(buffer + offset, value, size);
}
return offset + size;
}
unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset)
uint32_t aml_write_size(uint32_t size, char* buffer, uint32_t offset)
{
if (size <= 0x3f)
{
buffer[offset++] = size;
}
else if (size <= 0x3fff)
{
buffer[offset++] = 0x40 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
}
else if (size <= 0x3fffff)
{
buffer[offset++] = 0x80 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
if (size <= 0x3f) { /* simple 1 byte length in 6 bits */
buffer[offset++] = (char)size;
} else if (size <= 0xfff) {
buffer[offset++] = 0x40 | (size & 0xf); /* 0x40 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +1 bytes for rest length */
} else if (size <= 0xfffff) {
buffer[offset++] = 0x80 | (size & 0xf); /* 0x80 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +2 bytes for rest length */
buffer[offset++] = (size >> 12) & 0xff;
}
else
{
buffer[offset++] = 0xc0 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
} else {
buffer[offset++] = 0xc0 | (size & 0xf); /* 0xC0 is type, 0x0X is first nibble of length */
buffer[offset++] = (size >> 4) & 0xff; /* +3 bytes for rest length */
buffer[offset++] = (size >> 12) & 0xff;
buffer[offset++] = (size >> 20) & 0xff;
}
return offset;
}
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset)
uint32_t aml_write_node(AML_CHUNK* node, char* buffer, uint32_t offset)
{
if (node && buffer)
{
unsigned int old = offset;
if (node && buffer) {
uint32_t old = offset;
AML_CHUNK* child = node->First;
switch (node->Type)
{
switch (node->Type) {
case AML_CHUNK_NONE:
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_LOCAL0:
case AML_STORE_OP:
offset = aml_write_byte(node->Type, buffer, offset);
break;
case AML_CHUNK_DEVICE:
offset = aml_write_byte(AML_CHUNK_OP, buffer, offset);
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_size(node->Size-3, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_SCOPE:
case AML_CHUNK_METHOD:
case AML_CHUNK_PACKAGE:
case AML_CHUNK_BUFFER:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_size(node->Size-1, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1) {
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
else
{
} else {
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
case AML_CHUNK_RETURN:
case AML_CHUNK_STRING:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
break;
}
struct aml_chunk* child = node->First;
while (child) {
offset = aml_write_node(child, buffer, offset);
while (child)
{
offset = aml_write_node(child, buffer, offset);
child = child->Next;
}
if (offset - old != node->Size)
verbose("Node size incorrect: 0x%x\n", node->Type);
if (offset - old != node->Size) {
verbose("Node size incorrect: type=0x%x size=%x offset=%x\n",
node->Type, node->Size, (offset - old));
}
}
return offset;
}
//the procedure can find array char sizeof N inside part of large array "dsdt" size of len
int32_t FindBin (uint8_t *dsdt, uint32_t len, uint8_t *bin, unsigned int N)
{
uint32_t i, j;
bool eq;
for (i=0; i<len-N; i++) {
eq = true;
for (j=0; j<N; j++) {
if (dsdt[i+j] != bin[j]) {
eq = false;
break;
}
}
if (eq) {
return i;
}
}
return 0;
}
uint32_t get_size(uint8_t* Buffer, uint32_t adr)
{
uint32_t temp;
temp = Buffer[adr] & 0xF0; //keep bits 0x30 to check if this is valid size field
if(temp <= 0x30) { // 0
temp = Buffer[adr];
} else if(temp == 0x40){// 4
temp = (Buffer[adr] - 0x40) << 0|
Buffer[adr+1] << 4;
} else if(temp == 0x80){// 8
temp = (Buffer[adr] - 0x80) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12;
} else if(temp == 0xC0){// C
temp = (Buffer[adr] - 0xC0) << 0|
Buffer[adr+1] << 4|
Buffer[adr+2] << 12|
Buffer[adr+3] << 20;
} else {
verbose("wrong pointer to size field at %x\n", adr);
return 0; //this means wrong pointer to size field
}
return temp;
}
branches/chucko/i386/libsaio/befs.c
2020
2121
2222
23
23
2424
2525
2626
......
2828
2929
3030
31
31
3232
33
3334
3435
3536
/* Find BeFS signature */
bool BeFSProbe (const void *buf)
{
return (OSReadLittleInt32(buf+0x220,0)==SUPER_BLOCK_MAGIC1);
return (OSReadLittleInt32(buf+0x220,0) == SUPER_BLOCK_MAGIC1);
}
/* Find BeFS volume label */