Chameleon

Chameleon Commit Details

Date:2010-09-08 05:24:46 (13 years 7 months ago)
Author:Evan Lojewski
Commit:505
Parents: 504
Message:Sync with trunk, untested
Changes:
D/branches/meklort/efisysinst.sh
D/branches/meklort/i386/libsaio/dsdt_patcher.c
D/branches/meklort/i386/libsaio/dsdt_patcher.h
D/branches/meklort/i386/boot1/boot1.asm
C/trunk/MEMTEST86_LICENSE → /branches/meklort/MEMTEST86_LICENSE
C/trunk/i386/libsaio/acpi_patcher.c → /branches/meklort/i386/libsaio/acpi_patcher.c
C/trunk/i386/libsaio/acpi_patcher.h → /branches/meklort/i386/libsaio/acpi_patcher.h
C/trunk/i386/libsaio/aml_generator.c → /branches/meklort/i386/libsaio/aml_generator.c
C/trunk/i386/libsaio/aml_generator.h → /branches/meklort/i386/libsaio/aml_generator.h
C/trunk/i386/boot1/boot1f32-install.sh → /branches/meklort/i386/boot1/boot1f32-install.sh
C/trunk/i386/libsaio/dram_controllers.c → /branches/meklort/i386/libsaio/dram_controllers.c
C/trunk/i386/libsaio/dram_controllers.h → /branches/meklort/i386/libsaio/dram_controllers.h
C/trunk/i386/util/bdmesg.c → /branches/meklort/i386/util/bdmesg.c
C/trunk/i386/libsaio/disk.h → /branches/meklort/i386/libsaio/disk.h
C/trunk/README → /branches/meklort/README
C/trunk/GPL_V2_LICENSE → /branches/meklort/GPL_V2_LICENSE
M/branches/meklort/i386/libsaio/console.c
M/branches/meklort/i386/libsaio/xml.h
M/branches/meklort/i386/libsaio/ntfs_private.h
M/branches/meklort/i386/libsa/string.c
M/branches/meklort/i386/libsaio/hfs.c
M/branches/meklort/i386/boot2/drivers.c
M/branches/meklort/i386/libsaio/hfs.h
M/branches/meklort/i386/libsaio/spd.c
M/branches/meklort/i386/libsaio/spd.h
M/branches/meklort/i386/libsaio/Makefile
M/branches/meklort/i386/libsaio/ufs.c
M/branches/meklort/i386/libsaio/ufs.h
M/branches/meklort/i386/libsaio/smbios_patcher.c
M/branches/meklort/i386/boot2/graphics.c
M/branches/meklort/doc/README
M/branches/meklort/i386/boot1/boot1.s
M/branches/meklort/i386/libsa/libsa.h
M/branches/meklort/i386/boot1/boot1f32.s
M/branches/meklort/i386/libsaio/memvendors.h
M/branches/meklort/i386/boot2/gui.c
M/branches/meklort/i386/libsaio/usb.c
M/branches/meklort/i386/boot2/gui.h
M/branches/meklort/i386/boot2/ramdisk.c
M/branches/meklort/i386/boot2/Makefile
M/branches/meklort/doc/BootHelp.txt
M/branches/meklort
M/branches/meklort/i386/boot2/boot.c
M/branches/meklort/i386/libsaio/ntfs.c
M/branches/meklort/i386/libsaio/nvidia.c
M/branches/meklort/i386/boot2/boot.h
M/branches/meklort/i386/libsaio/sys.c
M/branches/meklort/i386/libsaio/nbp.c
M/branches/meklort/i386/libsaio/ntfs.h
M/branches/meklort/i386/libsaio/nvidia.h
M/branches/meklort/Makefile
M/branches/meklort/i386/libsaio/acpi.h
M/branches/meklort/i386/cdboot/cdboot.s
M/branches/meklort/i386/libsaio/platform.c
M/branches/meklort/i386/libsaio/cpu.c
M/branches/meklort/i386/libsaio/platform.h
M/branches/meklort/i386/libsaio/disk.c
M/branches/meklort/i386/libsaio/pci_setup.c
M/branches/meklort/i386/libsaio/cpu.h
M/branches/meklort/CREDITS
M/branches/meklort/i386/libsaio/cache.c
M/branches/meklort/i386/boot0/boot0.s
M/branches/meklort/CHANGES
M/branches/meklort/i386/boot1/boot1he.s
M/branches/meklort/i386/libsaio/saio_types.h
M/branches/meklort/i386/libsa/memory.h
M/branches/meklort/i386/libsaio/msdos.c
M/branches/meklort/i386/util/Makefile
M/branches/meklort/version
M/branches/meklort/i386/libsaio/fake_efi.c
M/branches/meklort/i386/libsaio/msdos.h
M/branches/meklort/i386/libsaio/saio_internal.h
M/branches/meklort/i386/libsaio/fake_efi.h
M/branches/meklort/i386/boot2/options.c
M/branches/meklort/i386/libsaio/xml.c

File differences

branches/meklort/efisysinst.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/sh
# efisysinst.sh
#
#
# Created by mackerintel on 2/2/09.
# Copyright 2009 mackerintel. All rights reserved.
if [[ x$1 == x ]]; then
echo Usage: $0 disknumber;
exit 0;
fi
if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then
echo "/dev/disk${1}s1" "isn't" a FAT32 partition;
exit 1;
fi
if [ ! -f boot1f32 ]; then
echo "boot1f32 not found";
exit 1;
fi
if [ ! -f boot0 ]; then
echo "boot0 not found";
exit 1;
fi
dd if=/dev/disk${1}s1 count=1 bs=512 of=/tmp/origbs
cp boot1f32 /tmp/newbs
dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc
dd of=/dev/disk${1}s1 count=1 bs=512 if=/tmp/newbs
dd if=boot0 of=/dev/disk${1} count=430 bs=1
branches/meklort/doc/BootHelp.txt
1414
1515
1616
17
18
17
18
19
1920
2021
2122
......
4748
4849
4950
50
51
52
53
5154
52
55
56
57
58
59
60
61
5362
54
55
56
5763
5864
5965
......
7076
7177
7278
73
79
7480
7581
82
83
7684
7785
7886
......
8290
8391
8492
85
93
8694
87
88
89
95
96
9097
9198
9299
......
100107
101108
102109
110
111
kernel: kernel name (e.g. "mach_kernel" - must be in "/" )
flags: -v (verbose) -s (single user mode),
-x (safe mode) -F (ignore boot configuration file)
flags: -v (verbose) -s (single user mode)
-x (safe mode) -f (ignore caches)
-F (ignore "Kernel Flags" specified in boot configuration file)
"Graphics Mode"="WIDTHxHEIGHTxDEPTH" (e.g. "1024x768x32")
"Instant Menu"=Yes Force displaying the partition selection menu.
"Default Partition" Sets the default boot partition,
=hd(x,y) where 'x' & 'y' are the disk and partition numbers.
=hd(x,y)|UUID|"Label" Specified as a disk/partition pair, an UUID, or a
label enclosed in quotes.
"Hide Partition" Remove unwanted partition(s) from the boot menu.
=hd(x,y) [hd(m,n)] only non mac osx boot partitions can be hidden.
=partition Specified, possibly multiple times, as hd(x,y), an
[;partition2 ...] UUID or label enclosed in quotes.
"Rename Partition" Rename partition(s) for the boot menu.
=partition <alias> Where partition is hd(x,y), UUID or label enclosed
[;partition2 <alias2> in quotes. The alias can optionally be quoted too.
...]
"Rename Partition" Rename partition(s) for the boot menu.
=hd(x,y) <alias> [;hd(m,n) <alias2> ...]
GUI=No Disable the GUI (enabled by default).
"Boot Banner"=Yes|No Show boot banner in GUI mode (enabled by default).
"Legacy Logo"=Yes|No Use the legacy grey apple logo (disabled by default).
EthernetBuiltIn=Yes|No Automatic "built-in"=yes device-properties generation
for ethernet interfaces.
USBBusFix=Yes Enable the EHCI and UHCI fixes (disabled by default).
USBBusFix=Yes Enable all USB fixes below:
EHCIacquire=Yes Enable the EHCI fix (disabled by default).
UHCIreset=Yes Enable the UHCI fix (disabled by default).
USBLegacyOff=Yes Enable the USB Legacy fix (disabled by default).
ForceHPET=Yes|No Force Enable HPET.
Wake=No Disable wake up after hibernation (default: enabled).
DropSSDT=Yes Skip the SSDT tables while relocating the ACPI tables.
DSDT=<file> Use an alternate DSDT.aml file
(default path: /DSDT.aml /Extra/DSDT.aml).
(default path: /DSDT.aml /Extra/DSDT.aml bt(0,0)/Extra/DSDT.aml).
SMBIOS=<file> Use an alternate smbios.plist file
(default path: /smbios.plist /Extra/smbios.plist
bt(0,0)/Extra/smbios.plist).
SMBIOS=<file> Use an alternate SMBIOS.plist file
(default path: /Extra/SMBIOS.plist bt(0,0)/Extra/SMBIOS.plist).
SMBIOSdefaults=No Don't use the Default values for SMBIOS overriding
if smbios.plist doesn't exist, factory
SMUUID in smbios config (reserved field) isn't used.
SystemType=<n> Set the system type where n is between 0..6
(default =1 (Desktop)
md0=<file> Load raw img file into memory for use as XNU's md0
ramdisk. /Extra/Postboot.img is used otherwise.
branches/meklort/doc/README
1818
1919
2020
21
22
21
2322
2423
2524
......
3130
3231
3332
34
33
3534
3635
3736
......
5251
5352
5453
55
56
54
55
5756
5857
5958
......
6665
6766
6867
69
70
71
72
73
74
7568
76
7769
7870
7971
......
9385
9486
9587
96
97
- automatic FSB detection code even for recent AMD CPUs.
- Apple Software RAID support.
- stage2 loader (boot) can be placed as a regular file in the boot
partition's root folder. It has precedence over the embedded
startupfile.
partition's root folder.
Installation
Suppose that your installation is on /dev/disk0s2
- Install boot0 to the MBR:
sudo fdisk -f boot0 -u -y /dev/rdisk0
sudo ./fdisk440 -f boot0 -u -y /dev/rdisk0
- Install boot1h to the partition's bootsector:
sudo dd if=boot1h of=/dev/rdisk0s2
namely /dev/disk0s3 and /dev/disk1s3
- Install boot0 to the MBR of both disks:
sudo fdisk -f boot0 -u -y /dev/rdisk0
sudo fdisk -f boot0 -u -y /dev/rdisk1
sudo ./fdisk440 -f boot0 -u -y /dev/rdisk0
sudo ./fdisk440 -f boot0 -u -y /dev/rdisk1
- Install boot1h to the bootsector of each boot partition:
sudo dd if=boot1h of=/dev/rdisk0s3
diskutil mount disk1s3
cp boot /Volumes/Boot\ OSX
diskutil unmount disk1s3
- Add "rd=uuid boot-uuid=506D8F03-0596-32D8-BE0B-E3A4E7D5C72A" to your kernel flags
(replace with your root volume's UUID; find out using "Disk Utility.app", right
click on your root volume, then Get Info"):
nano /Library/Preferences/SystemConfiguration/com.apple.Boot.plist
touch /System/Library/Extensions
Support:
--------
Chameleon is released under the terms and conditions of
Apple Public Source License (see APPLE_LICENSE).
To use "Chameleon" for commercial purposes please contact us at:
http://chameleon.osx86.hu/contact
branches/meklort/version
1
1
2.0-RC5pre11
2.0-RC5
branches/meklort/CHANGES
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1018
1119
1220
- Added module hooks + callback system. Main code still needs ot be populated with hooks
- Added module support
- Fixed lapic_init patch. Fixed _cpuid_set_info patch to work on the 10.6.0 / 10.6.1 kernel (patches cpumodel)
- Added USB Legacy Off patch. Modified to run immediately *before* the kernel is executed, that
way no files need to be loaded after the usb device is reset.
- Backup original dsdt to /dsdt/originaldsdt in the IORegistery
- Added kernel patcher, removes the CPUID check panic in the kernel. Forces _cpuid_set_info to
return Penryn / cpuid model 23
- Added Booter Log Dump Tool
- Added Booter message Logging (":/boot-log" ioreg property)
- Removed obsolete -f option, use -x instead
- Removed -x32 option, use arch=i386 instead
- Added automatic SMBusspeed detection for lga1156 core i5/7 cpus
- Added new iMac11,1 sbios default model for lga1156 core i5/17 mobos
- md0 code. Notified xnu when an md ramdisk is specified
- Added rollover image support for selected device icons.
Use device_<type>_o.png in theme folder. Credits goes to Blackosx.
- Revisited theme resource embedding. Using the device_<type> icons are optional with
the exception of device_generic.
- Optimized memory detection speed
- Added displaying source device and partition number for file read operations.
- Increased boot2's maximum size from 383.5k to 447.5k.
Updated stage 1 loaders for handling the new size limit.
- Added alternate format for setting the default partition. The user can specify the selected
volume UUID for the "Default Partition" key.
- Implemented SPD memory automatic detection and injection,seems to work really great ...
- Factorized code to prepare a dynamic memory detection algorithm ...
- Optimized smbios table address search
branches/meklort/i386/libsaio/dsdt_patcher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
/*
* Copyright 2008 mackerintel
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "acpi.h"
#include "efi_tables.h"
#include "fake_efi.h"
#include "dsdt_patcher.h"
#include "platform.h"
#ifndef DEBUG_DSDT
#define DEBUG_DSDT 0
#endif
#if DEBUG_DSDT==2
#define DBG(x...) {printf(x); sleep(1);}
#elif DEBUG_DSDT==1
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
/* Gets the ACPI 1.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpiTable()
{
/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
void *acpi_addr = (void*)ACPI_RANGE_START;
for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
{
if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
{
uint8_t csum = checksum8(acpi_addr, 20);
if(csum == 0)
{
// Only return the table if it is a true version 1.0 table (Revision 0)
if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)
return acpi_addr;
}
}
}
return NULL;
}
/* Gets the ACPI 2.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpi20Table()
{
/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
void *acpi_addr = (void*)ACPI_RANGE_START;
for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
{
if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
{
uint8_t csum = checksum8(acpi_addr, 20);
/* Only assume this is a 2.0 or better table if the revision is greater than 0
* NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
* and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
*/
if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0))
{
uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp));
if(csum2 == 0)
return acpi_addr;
}
}
}
return NULL;
}
/** The folowing ACPI Table search algo. should be reused anywhere needed:*/
int search_and_get_acpi_fd(const char * filename, const char ** outDirspec)
{
int fd=0;
const char * overriden_pathname=NULL;
static char dirspec[512]="";
static bool first_time =true;
int len=0;
/// Take in accound user overriding if it's DSDT only
if (strstr(filename, "DSDT") &&
getValueForKey(kDSDT, &overriden_pathname, &len,
&bootInfo->bootConfig))
{
sprintf(dirspec, "%s", overriden_pathname);
fd=open (dirspec,0);
if (fd>=0) goto success_fd;
}
// Check that dirspec is not already assigned with a path
if (!first_time && *dirspec)
{ // it is so start searching this cached patch first
//extract path
for (len=strlen(dirspec)-1; len; len--)
if (dirspec[len]=='/' || len==0)
{
dirspec[len]='\0';
break;
}
// now concat with the filename
strncat(dirspec, "/", sizeof(dirspec));
strncat(dirspec, filename, sizeof(dirspec));
// and test to see if we don't have our big boy here:
fd=open (dirspec,0);
if (fd>=0)
{
// printf("ACPI file search cache hit: file found at %s\n", dirspec);
goto success_fd;
}
}
// Start searching any potential location for ACPI Table
// search the Extra folders first
sprintf(dirspec,"/Extra/%s",filename);
fd=open (dirspec,0);
if (fd>=0) goto success_fd;
sprintf(dirspec,"bt(0,0)/Extra/%s",filename);
fd=open (dirspec,0);
if (fd>=0) goto success_fd;
sprintf(dirspec, "%s", filename); // search current dir
fd=open (dirspec,0);
if (fd>=0) goto success_fd;
sprintf(dirspec, "/%s", filename); // search root
fd=open (dirspec,0);
if (fd>=0) goto success_fd;
// NOT FOUND:
verbose("ACPI Table not found: %s\n", filename);
if (outDirspec) *outDirspec = "";
first_time = false;
return -1;
// FOUND
success_fd:
first_time = false;
if (outDirspec) *outDirspec = dirspec;
return fd;
}
void *loadACPITable (const char * filename)
{
void *tableAddr;
const char * dirspec=NULL;
int fd = search_and_get_acpi_fd(filename, &dirspec);
if (fd>=0)
{
tableAddr=(void*)AllocateKernelMemory(file_size (fd));
if (tableAddr)
{
if (read (fd, tableAddr, file_size (fd))!=file_size (fd))
{
printf("Couldn't read table %s\n",dirspec);
free (tableAddr);
close (fd);
return NULL;
}
DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);
close (fd);
return tableAddr;
}
close (fd);
printf("Couldn't allocate memory for table \n", dirspec);
}
printf("Couldn't find table %s\n", filename);
return NULL;
}
struct acpi_2_fadt *
patch_fadt(struct acpi_2_fadt *fadt, void *new_dsdt)
{
extern void setupSystemType();
struct acpi_2_fadt *fadt_mod;
bool fadt_rev2_needed = false;
bool fix_restart;
const char * value;
// Restart Fix
if (Platform.CPU.Vendor == 0x756E6547) {/* Intel */
fix_restart = true;
getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);
} else {
verbose ("Not an Intel platform: Restart Fix not applied !!!\n");
fix_restart = false;
}
if (fix_restart) fadt_rev2_needed = true;
// Allocate new fadt table
if (fadt->Length < 0x84 && fadt_rev2_needed)
{
fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);
memcpy(fadt_mod, fadt, fadt->Length);
fadt_mod->Length = 0x84;
fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)
}
else
{
fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
}
// Determine system type / PM_Model
if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL)
{
if (Platform.Type > 6)
{
if(fadt_mod->PM_Profile<=6)
Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct
else
Platform.Type = 1;/* Set a fixed value (Desktop) */
verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type);
}
else
Platform.Type = (unsigned char) strtoul(value, NULL, 10);
}
// Set PM_Profile from System-type if only if user wanted this value to be forced
if (fadt_mod->PM_Profile != Platform.Type)
{
if (value)
{ // user has overriden the SystemType so take care of it in FACP
verbose("FADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type);
fadt_mod->PM_Profile = Platform.Type;
}
else
{ // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs
Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1;
}
}
// We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()
// because we need to take care of facp original content, if it is correct.
setupSystemType();
// Patch FADT to fix restart
if (fix_restart)
{
fadt_mod->Flags|= 0x400;
fadt_mod->Reset_SpaceID= 0x01; // System I/O
fadt_mod->Reset_BitWidth= 0x08; // 1 byte
fadt_mod->Reset_BitOffset= 0x00; // Offset 0
fadt_mod->Reset_AccessWidth= 0x01; // Byte access
fadt_mod->Reset_Address= 0x0cf9; // Address of the register
fadt_mod->Reset_Value= 0x06; // Value to write to reset the system
verbose("FADT: Restart Fix applied !\n");
}
// Save old DSDT to the IORegistery
Node* node = DT__FindNode("/", false);
if(node != NULL)
{
node = DT__AddChild(node, "dsdt");
struct acpi_2_dsdt *dsdt;
dsdt = (struct acpi_2_dsdt*) (fadt_mod->DSDT);
DT__AddProperty(node, "originaldsdt", (dsdt->Length + sizeof(struct acpi_2_dsdt) - 1), (void*)dsdt);/// Insert old dsdt. Length is header length (36) + dsdt length
}
// Patch DSDT Address
DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT);
fadt_mod->DSDT=(uint32_t)new_dsdt;
if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
fadt_mod->X_DSDT=(uint32_t)new_dsdt;
DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
// Correct the checksum
fadt_mod->Checksum=0;
fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);
return fadt_mod;
}
/* Setup ACPI without replacing DSDT. */
int setupAcpiNoMod()
{
//addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI");
//addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20");
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)getAddressOfAcpiTable();
acpi20_p = (uint32_t)getAddressOfAcpi20Table();
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
return 1;
}
/* Setup ACPI. Replace DSDT if DSDT.aml is found */
int setupAcpi(void)
{
int version;
void *new_dsdt;
bool drop_ssdt;
// Load replacement DSDT
new_dsdt=loadACPITable("DSDT.aml");
if (!new_dsdt)
{
return setupAcpiNoMod();
}
DBG("New DSDT Loaded in memory\n");
{
bool tmp;
drop_ssdt=getBoolForKey(kDropSSDT, &tmp, &bootInfo->bootConfig)&&tmp;
}
// Do the same procedure for both versions of ACPI
for (version=0; version<2; version++) {
struct acpi_2_rsdp *rsdp, *rsdp_mod;
struct acpi_2_rsdt *rsdt, *rsdt_mod;
int rsdplength;
// Find original rsdp
rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable());
if (!rsdp)
{
DBG("No ACPI version %d found. Ignoring\n", version+1);
if (version)
addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");
else
addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
continue;
}
rsdplength=version?rsdp->Length:20;
DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);
/* FIXME: no check that memory allocation succeeded
* Copy and patch RSDP,RSDT, XSDT and FADT
* For more info see ACPI Specification pages 110 and following
*/
rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);
memcpy(rsdp_mod, rsdp, rsdplength);
rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);
DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);
if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)
{
uint32_t *rsdt_entries;
int rsdt_entries_num;
int dropoffset=0, i;
rsdt_mod=(struct acpi_2_rsdt *)AllocateKernelMemory(rsdt->Length);
memcpy (rsdt_mod, rsdt, rsdt->Length);
rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;
rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;
rsdt_entries=(uint32_t *)(rsdt_mod+1);
for (i=0;i<rsdt_entries_num;i++)
{
char *table=(char *)(rsdt_entries[i]);
if (!table)
continue;
DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);
rsdt_entries[i-dropoffset]=rsdt_entries[i];
if (drop_ssdt && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T')
{
dropoffset++;
continue;
}
if (table[0]=='D' && table[1]=='S' && table[2]=='D' && table[3]=='T')
{
DBG("DSDT found\n");
rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
continue;
}
if (table[0]=='F' && table[1]=='A' && table[2]=='C' && table[3]=='P')
{
struct acpi_2_fadt *fadt, *fadt_mod;
fadt=(struct acpi_2_fadt *)rsdt_entries[i];
DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);
if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
{
printf("FADT incorrect. Not modified\n");
continue;
}
fadt_mod = patch_fadt(fadt, new_dsdt);
rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
continue;
}
}
DBG("\n");
// Correct the checksum of RSDT
rsdt_mod->Length-=4*dropoffset;
DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);
rsdt_mod->Checksum=0;
rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);
DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
}
else
{
rsdp_mod->RsdtAddress=0;
printf("RSDT not found or RSDT incorrect\n");
}
if (version)
{
struct acpi_2_xsdt *xsdt, *xsdt_mod;
// FIXME: handle 64-bit address correctly
xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,
xsdt->Length);
if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
{
uint64_t *xsdt_entries;
int xsdt_entries_num, i;
int dropoffset=0;
xsdt_mod=(struct acpi_2_xsdt*)AllocateKernelMemory(xsdt->Length);
memcpy(xsdt_mod, xsdt, xsdt->Length);
rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;
xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;
xsdt_entries=(uint64_t *)(xsdt_mod+1);
for (i=0;i<xsdt_entries_num;i++)
{
char *table=(char *)((uint32_t)(xsdt_entries[i]));
if (!table)
continue;
xsdt_entries[i-dropoffset]=xsdt_entries[i];
if (drop_ssdt && table[0]=='S' && table[1]=='S' && table[2]=='D' && table[3]=='T')
{
dropoffset++;
continue;
}
if (table[0]=='D' && table[1]=='S' && table[2]=='D' && table[3]=='T')
{
DBG("DSDT found\n");
xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
continue;
}
if (table[0]=='F' && table[1]=='A' && table[2]=='C' && table[3]=='P')
{
struct acpi_2_fadt *fadt, *fadt_mod;
fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
fadt->Length);
if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
{
verbose("FADT incorrect or after 4GB. Dropping XSDT\n");
goto drop_xsdt;
}
fadt_mod = patch_fadt(fadt, new_dsdt);
xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
continue;
}
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
}
// Correct the checksum of XSDT
xsdt_mod->Length-=8*dropoffset;
xsdt_mod->Checksum=0;
xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);
}
else
{
drop_xsdt:
DBG("About to drop XSDT\n");
/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
* A Better strategy would be to generate
*/
rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
verbose("XSDT not found or XSDT incorrect\n");
}
}
// Correct the checksum of RSDP
DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);
rsdp_mod->Checksum=0;
rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);
DBG("New checksum %d\n", rsdp_mod->Checksum);
if (version)
{
DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);
rsdp_mod->ExtendedChecksum=0;
rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);
DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);
}
verbose("Patched ACPI version %d DSDT\n", version+1);
if (version)
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi20_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
}
else
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
}
}
#if DEBUG_DSDT
printf("Press a key to continue... (DEBUG_DSDT)\n");
getc();
#endif
return 1;
}
branches/meklort/i386/libsaio/dsdt_patcher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* Copyright 2008 mackerintel
*/
#ifndef __LIBSAIO_DSDT_PATCHER_H
#define __LIBSAIO_DSDT_PATCHER_H
#include "libsaio.h"
uint64_t acpi10_p;
uint64_t acpi20_p;
uint64_t smbios_p;
extern int setupAcpi();
extern EFI_STATUS addConfigurationTable();
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
#endif /* !__LIBSAIO_DSDT_PATCHER_H */
branches/meklort/i386/libsaio/fake_efi.h
88
99
1010
11
12
11
1312
1413
/* Set up space for up to 10 configuration table entries */
#define MAX_CONFIGURATION_TABLE_ENTRIES 10
extern void
setupFakeEfi(void);
extern void setupFakeEfi(void);
#endif /* !__LIBSAIO_FAKE_EFI_H */
branches/meklort/i386/libsaio/xml.c
110110
111111
112112
113
113114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
114171
115172
116173
return 0;
}
/* Function for basic XML character entities parsing */
char*
XMLDecode(const char* src)
{
typedef const struct XMLEntity {
const char* name;
size_t nameLen;
char value;
} XMLEntity;
/* This is ugly, but better than specifying the lengths by hand */
#define _e(str,c) {str,sizeof(str)-1,c}
const XMLEntity ents[] = {
_e("quot;",'"'), _e("apos;",'\''),
_e("lt;", '<'), _e("gt;", '>'),
_e("amp;", '&')
};
size_t len;
const char *s;
char *out, *o;
if ( !src || !(len = strlen(src)) || !(out = malloc(len+1)) )
return 0;
o = out;
s = src;
while (s <= src+len) /* Make sure the terminator is also copied */
{
if ( *s == '&' )
{
bool entFound = false;
int i;
s++;
for ( i = 0; i < sizeof(ents); i++)
{
if ( strncmp(s, ents[i].name, ents[i].nameLen) == 0 )
{
entFound = true;
break;
}
}
if ( entFound )
{
*o++ = ents[i].value;
s += ents[i].nameLen;
continue;
}
}
*o++ = *s++;
}
return out;
}
#if UNUSED
//==========================================================================
// XMLParseFile
branches/meklort/i386/libsaio/console.c
5252
5353
5454
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
55116
56117
57118
......
103164
104165
105166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
106183
107184
108185
......
111188
112189
113190
191
114192
115193
116
117194
118195
119196
120197
121
122198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
123216
124217
125218
bool gVerboseMode;
bool gErrors;
/* Kabyl: BooterLog */
#define BOOTER_LOG_SIZE(64 * 1024)
#define SAFE_LOG_SIZE80
char *msgbuf = 0;
char *cursor = 0;
struct putc_info {
char * str;
char * last_str;
};
static void sputc(int c, struct putc_info * pi)
{
if (pi->last_str)
if (pi->str == pi->last_str)
{
*(pi->str) = '\0';
return;
}
*(pi->str)++ = c;
}
void initBooterLog(void)
{
msgbuf = malloc(BOOTER_LOG_SIZE);
bzero(msgbuf, BOOTER_LOG_SIZE);
cursor = msgbuf;
}
void msglog(const char * fmt, ...)
{
va_list ap;
struct putc_info pi;
if (!msgbuf)
return;
if (((cursor - msgbuf) > (BOOTER_LOG_SIZE - SAFE_LOG_SIZE)))
return;
va_start(ap, fmt);
pi.str = cursor;
pi.last_str = 0;
prf(fmt, ap, sputc, &pi);
va_end(ap);
cursor += strlen((char *)cursor);
}
void setupBooterLog(void)
{
if (!msgbuf)
return;
Node *node = DT__FindNode("/", false);
if (node)
DT__AddProperty(node, "boot-log", strlen((char *)msgbuf) + 1, msgbuf);
}
/* Kabyl: !BooterLog */
/*
* write one character to console
*/
prf(fmt, ap, putchar, 0);
else
vprf(fmt, ap);
{
/* Kabyl: BooterLog */
struct putc_info pi;
if (!msgbuf)
return 0;
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_list ap;
va_start(ap, fmt);
if (gVerboseMode)
{
va_start(ap, fmt);
if (bootArgs->Video.v_display == VGA_TEXT_MODE)
prf(fmt, ap, putchar, 0);
else
vprf(fmt, ap);
va_end(ap);
}
{
/* Kabyl: BooterLog */
struct putc_info pi;
if (!msgbuf)
return 0;
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);
}
branches/meklort/i386/libsaio/xml.h
7373
7474
7575
76
7677
7778
7879
TagPtr XMLGetProperty( TagPtr dict, const char * key );
long XMLParseNextTag(char *buffer, TagPtr *tag);
void XMLFreeTag(TagPtr tag);
char* XMLDecode(const char *in);
//==========================================================================
// XMLParseFile
// Expects to see one dictionary in the XML file.
branches/meklort/i386/libsaio/ntfs_private.h
275275
276276
277277
278
279
278
279
280
281
280282
281283
282284
cn_t bf_mftmirrcn;/* $MFTMirr cn */
u_int8_t bf_mftrecsz;/* MFT record size (clust) */
/* 0xF6 inducates 1/4 */
u_int32_t bf_ibsz;/* index buffer size */
u_int32_t bf_volsn;/* volume ser. num. */
u_int8_t reserved5[3];
u_int8_t bf_ibsz;/* index buffer size */
u_int8_t reserved6[3];
u_int64_t bf_volsn;/* volume ser. num. */
};
/*
branches/meklort/i386/libsaio/hfs.c
8080
8181
8282
83
83
8484
85
85
8686
8787
8888
89
89
9090
9191
92
92
9393
9494
9595
......
264264
265265
266266
267
267268
268269
269270
270
271
271272
272273
273274
......
298299
299300
300301
301
302
302
303
304
303305
304306
305307
306308
307
309
308310
309311
310312
......
346348
347349
348350
349
351
350352
351353
352354
......
360362
361363
362364
363
365
364366
365367
366368
......
526528
527529
528530
529
531
530532
531533
532
534
535
533536
534537
535538
......
576579
577580
578581
579
582
580583
581584
582585
......
597600
598601
599602
600
601
603
604
602605
603606
604607
605
608
606609
607610
608611
......
626629
627630
628631
629
632
630633
631634
632635
......
634637
635638
636639
637
640
638641
639642
640643
......
680683
681684
682685
683
686
684687
685688
686689
......
732735
733736
734737
735
738
736739
737740
738741
......
800803
801804
802805
803
806
804807
805808
806809
static long GetCatalogEntryInfo(void *entry, long *flags, long *time,
FinderInfo *finderInfo, long *infoValid);
static long ResolvePathToCatalogEntry(char *filePath, long *flags,
void *entry, long dirID, long *dirIndex);
void *entry, long dirID, long long *dirIndex);
static long GetCatalogEntry(long *dirIndex, char **name,
static long GetCatalogEntry(long long *dirIndex, char **name,
long *flags, long *time,
FinderInfo *finderInfo, long *infoValid);
static long ReadCatalogEntry(char *fileName, long dirID, void *entry,
long *dirIndex);
long long *dirIndex);
static long ReadExtentsEntry(long fileID, long startBlock, void *entry);
static long ReadBTreeEntry(long btree, void *key, char *entry, long *dirIndex);
static long ReadBTreeEntry(long btree, void *key, char *entry, long long *dirIndex);
static void GetBTreeRecord(long index, char *nodeBuffer, long nodeSize,
char **key, char **data);
long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length)
{
char entry[512];
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] == '/') {
return -1;
}
verbose("Loaded HFS%s file: [%s] %d bytes from %x.\n",
(gIsHFSPlus ? "+" : ""), filePath, (uint32_t)length, ih);
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 * dirIndex, char ** name,
long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex, char ** name,
long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
{
UInt16 nodeSize;
UInt32 firstLeafNode;
long dirIndex;
long long dirIndex;
char *name;
long flags, time;
nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);
dirIndex = firstLeafNode * nodeSize;
dirIndex = (long long) firstLeafNode * nodeSize;
GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
}
static long ResolvePathToCatalogEntry(char * filePath, long * flags,
void * entry, long dirID, long * dirIndex)
void * entry, long dirID, long long * dirIndex)
{
char *restPath;
long result, cnt, subFolderID = 0, tmpDirIndex;
long result, cnt, subFolderID = 0;
long long tmpDirIndex;
HFSPlusCatalogFile *hfsPlusFile;
// Copy the file name to gTempStr
return result;
}
static long GetCatalogEntry(long * dirIndex, char ** name,
static long GetCatalogEntry(long long * dirIndex, char ** name,
long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
{
nodeBuf = (char *)malloc(nodeSize);
node = (BTNodeDescriptor *)nodeBuf;
index = *dirIndex % nodeSize;
curNode = *dirIndex / nodeSize;
index = (long) (*dirIndex % nodeSize);
curNode = (long) (*dirIndex / nodeSize);
// Read the BTree node and get the record for index.
ReadExtent(extent, extentSize, kHFSCatalogFileID,
(long long)curNode * nodeSize, nodeSize, nodeBuf, 1);
(long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = curNode * nodeSize + index;
*dirIndex = (long long) curNode * nodeSize + index;
free(nodeBuf);
}
static long ReadCatalogEntry(char * fileName, long dirID,
void * entry, long * dirIndex)
void * entry, long long * dirIndex)
{
long length;
char key[sizeof(HFSPlusCatalogKey)];
return ReadBTreeEntry(kBTreeExtents, &key, entry, 0);
}
static long ReadBTreeEntry(long btree, void * key, char * entry, long * dirIndex)
static long ReadBTreeEntry(long btree, void * key, char * entry, long long * dirIndex)
{
long extentSize;
void *extent;
while (1) {
// Read the current node.
ReadExtent(extent, extentSize, extentFile,
(long long)curNode * nodeSize, nodeSize, nodeBuf, 1);
(long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
// Find the matching key.
lowerBound = 0;
index = 0;
curNode = SWAP_BE32(node->fLink);
}
*dirIndex = curNode * nodeSize + index;
*dirIndex = (long long) curNode * nodeSize + index;
}
free(nodeBuf);
branches/meklort/i386/libsaio/acpi_patcher.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
/*
* Copyright 2008 mackerintel
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "acpi.h"
#include "efi_tables.h"
#include "fake_efi.h"
#include "acpi_patcher.h"
#include "platform.h"
#include "cpu.h"
#include "aml_generator.h"
#ifndef DEBUG_ACPI
#define DEBUG_ACPI 0
#endif
#if DEBUG_ACPI==2
#define DBG(x...) {printf(x); sleep(1);}
#elif DEBUG_ACPI==1
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
// Slice: New signature compare function
boolean_t tableSign(char *table, const char *sgn)
{
int i;
for (i=0; i<4; i++) {
if ((table[i] &~0x20) != (sgn[i] &~0x20)) {
return false;
}
}
return true;
}
/* Gets the ACPI 1.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpiTable()
{
/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
void *acpi_addr = (void*)ACPI_RANGE_START;
for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
{
if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
{
uint8_t csum = checksum8(acpi_addr, 20);
if(csum == 0)
{
// Only return the table if it is a true version 1.0 table (Revision 0)
if(((struct acpi_2_rsdp*)acpi_addr)->Revision == 0)
return acpi_addr;
}
}
}
return NULL;
}
/* Gets the ACPI 2.0 RSDP address */
static struct acpi_2_rsdp* getAddressOfAcpi20Table()
{
/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
void *acpi_addr = (void*)ACPI_RANGE_START;
for(; acpi_addr <= (void*)ACPI_RANGE_END; acpi_addr += 16)
{
if(*(uint64_t *)acpi_addr == ACPI_SIGNATURE_UINT64_LE)
{
uint8_t csum = checksum8(acpi_addr, 20);
/* Only assume this is a 2.0 or better table if the revision is greater than 0
* NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
* and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
*/
if(csum == 0 && (((struct acpi_2_rsdp*)acpi_addr)->Revision > 0))
{
uint8_t csum2 = checksum8(acpi_addr, sizeof(struct acpi_2_rsdp));
if(csum2 == 0)
return acpi_addr;
}
}
}
return NULL;
}
/** The folowing ACPI Table search algo. should be reused anywhere needed:*/
int search_and_get_acpi_fd(const char * filename, const char ** outDirspec)
{
int fd = 0;
char dirSpec[512] = "";
// Try finding 'filename' in the usual places
// Start searching any potential location for ACPI Table
sprintf(dirSpec, "%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
sprintf(dirSpec, "/Extra/%s", filename);
fd = open(dirSpec, 0);
if (fd < 0)
{
sprintf(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';
}
if (outDirspec) *outDirspec = dirSpec;
return fd;
}
void *loadACPITable (const char * filename)
{
void *tableAddr;
const char * dirspec=NULL;
int fd = search_and_get_acpi_fd(filename, &dirspec);
if (fd>=0)
{
tableAddr=(void*)AllocateKernelMemory(file_size (fd));
if (tableAddr)
{
if (read (fd, tableAddr, file_size (fd))!=file_size (fd))
{
printf("Couldn't read table %s\n",dirspec);
free (tableAddr);
close (fd);
return NULL;
}
DBG("Table %s read and stored at: %x\n", dirspec, tableAddr);
close (fd);
return tableAddr;
}
close (fd);
printf("Couldn't allocate memory for table \n", dirspec);
}
//printf("Couldn't find table %s\n", filename);
return NULL;
}
uint8_tacpi_cpu_count = 0;
char* acpi_cpu_name[32];
void get_acpi_cpu_names(unsigned char* dsdt, uint32_t length)
{
uint32_t i;
for (i=0; i<length-7; i++)
{
if (dsdt[i] == 0x5B && dsdt[i+1] == 0x83) // ProcessorOP
{
uint32_t offset = i + 3 + (dsdt[i+2] >> 6);
bool add_name = true;
uint8_t j;
for (j=0; j<4; j++)
{
char c = dsdt[offset+j];
if (!aml_isvalidchar(c))
{
add_name = false;
verbose("Invalid character found in ProcessorOP 0x%x!\n", c);
break;
}
}
if (add_name)
{
acpi_cpu_name[acpi_cpu_count] = malloc(4);
memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);
i = offset + 5;
verbose("Found ACPI CPU: %c%c%c%c\n", acpi_cpu_name[acpi_cpu_count][0], acpi_cpu_name[acpi_cpu_count][1], acpi_cpu_name[acpi_cpu_count][2], acpi_cpu_name[acpi_cpu_count][3]);
if (++acpi_cpu_count == 32) return;
}
}
}
}
struct acpi_2_ssdt *generate_cst_ssdt(struct acpi_2_fadt* fadt)
{
char ssdt_header[] =
{
0x53, 0x53, 0x44, 0x54, 0xE7, 0x00, 0x00, 0x00, /* SSDT.... */
0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */
0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */
0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */
0x31, 0x03, 0x10, 0x20 /* 1.._*/
};
char cstate_resource_template[] =
{
0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,
0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x79, 0x00
};
if (Platform.CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: C-States will not be generated !!!\n");
return NULL;
}
if (fadt == NULL) {
verbose ("FACP not exists: C-States will not be generated !!!\n");
return NULL;
}
struct acpi_2_dsdt* dsdt = (void*)fadt->DSDT;
if (dsdt == NULL) {
verbose ("DSDT not found: C-States will not be generated !!!\n");
return NULL;
}
if (acpi_cpu_count == 0)
get_acpi_cpu_names((void*)dsdt, dsdt->Length);
if (acpi_cpu_count > 0)
{
bool c2_enabled = fadt->C2_Latency < 100;
bool c3_enabled = fadt->C3_Latency < 1000;
bool c4_enabled = false;
getBoolForKey(kEnableC4States, &c4_enabled, &bootInfo->bootConfig);
unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);
struct 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_add_byte(pack, cstates_count);
struct aml_chunk* tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x00; // C1
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x01); // C1
aml_add_byte(tmpl, 0x01); // Latency
aml_add_word(tmpl, 0x03e8); // Power
// C2
if (c2_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x10; // C2
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x02); // C2
aml_add_byte(tmpl, fadt->C2_Latency);
aml_add_word(tmpl, 0x01f4); // Power
}
// C4
if (c4_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x30; // C4
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x04); // C4
aml_add_word(tmpl, fadt->C3_Latency / 2); // TODO: right latency for C4
aml_add_byte(tmpl, 0xfa); // Power
}
else
// C3
if (c3_enabled)
{
tmpl = aml_add_package(pack);
cstate_resource_template[11] = 0x20; // C3
aml_add_buffer(tmpl, cstate_resource_template, sizeof(cstate_resource_template));
aml_add_byte(tmpl, 0x03); // C3
aml_add_word(tmpl, fadt->C3_Latency);
aml_add_word(tmpl, 0x015e); // Power
}
// Aliaces
int i;
for (i = 0; i < acpi_cpu_count; i++)
{
char name[9];
sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);
scop = aml_add_scope(root, name);
aml_add_alias(scop, "CST_", "_CST");
}
aml_calculate_size(root);
struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
aml_write_node(root, (void*)ssdt, 0);
ssdt->Length = root->Size;
ssdt->Checksum = 0;
ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
aml_destroy_node(root);
//dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);
verbose ("SSDT with CPU C-States generated successfully\n");
return ssdt;
}
else
{
verbose ("ACPI CPUs not found: C-States not generated !!!\n");
}
return NULL;
}
struct acpi_2_ssdt *generate_pss_ssdt(struct acpi_2_dsdt* dsdt)
{
char ssdt_header[] =
{
0x53, 0x53, 0x44, 0x54, 0x7E, 0x00, 0x00, 0x00, /* SSDT.... */
0x01, 0x6A, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x00, /* ..PmRef. */
0x43, 0x70, 0x75, 0x50, 0x6D, 0x00, 0x00, 0x00, /* CpuPm... */
0x00, 0x30, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* .0..INTL */
0x31, 0x03, 0x10, 0x20,/* 1.._*/
};
if (Platform.CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: P-States will not be generated !!!\n");
return NULL;
}
if (!(Platform.CPU.Features & CPU_FEATURE_MSR)) {
verbose ("Unsupported CPU: P-States will not be generated !!!\n");
return NULL;
}
if (acpi_cpu_count == 0)
get_acpi_cpu_names((void*)dsdt, dsdt->Length);
if (acpi_cpu_count > 0)
{
struct p_state initial, maximum, minimum, p_states[32];
uint8_t p_states_count = 0;
// Retrieving P-States, ported from code by superhai (c)
switch (Platform.CPU.Family) {
case 0x06:
{
switch (Platform.CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH: // Yonah
case CPU_MODEL_MEROM: // Merom
case CPU_MODEL_PENRYN: // Penryn
case CPU_MODEL_ATOM: // Intel Atom (45nm)
{
bool cpu_dynamic_fsb = false;
if (rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 27))
{
wrmsr64(MSR_IA32_EXT_CONFIG, (rdmsr64(MSR_IA32_EXT_CONFIG) | (1 << 28)));
delay(1);
cpu_dynamic_fsb = rdmsr64(MSR_IA32_EXT_CONFIG) & (1 << 28);
}
bool cpu_noninteger_bus_ratio = (rdmsr64(MSR_IA32_PERF_STATUS) & (1ULL << 46));
initial.Control = rdmsr64(MSR_IA32_PERF_STATUS);
maximum.Control = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 32) & 0x1F3F) | (0x4000 * cpu_noninteger_bus_ratio);
maximum.CID = ((maximum.FID & 0x1F) << 1) | cpu_noninteger_bus_ratio;
minimum.FID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 24) & 0x1F) | (0x80 * cpu_dynamic_fsb);
minimum.VID = ((rdmsr64(MSR_IA32_PERF_STATUS) >> 48) & 0x3F);
if (minimum.FID == 0)
{
uint64_t msr;
uint8_t i;
// Probe for lowest fid
for (i = maximum.FID; i >= 0x6; i--)
{
msr = rdmsr64(MSR_IA32_PERF_CONTROL);
wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (i << 8) | minimum.VID);
intel_waitforsts();
minimum.FID = (rdmsr64(MSR_IA32_PERF_STATUS) >> 8) & 0x1F;
delay(1);
}
msr = rdmsr64(MSR_IA32_PERF_CONTROL);
wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
intel_waitforsts();
}
if (minimum.VID == maximum.VID)
{
uint64_t msr;
uint8_t i;
// Probe for lowest vid
for (i = maximum.VID; i > 0xA; i--)
{
msr = rdmsr64(MSR_IA32_PERF_CONTROL);
wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (minimum.FID << 8) | i);
intel_waitforsts();
minimum.VID = rdmsr64(MSR_IA32_PERF_STATUS) & 0x3F;
delay(1);
}
msr = rdmsr64(MSR_IA32_PERF_CONTROL);
wrmsr64(MSR_IA32_PERF_CONTROL, (msr & 0xFFFFFFFFFFFF0000ULL) | (maximum.FID << 8) | maximum.VID);
intel_waitforsts();
}
minimum.CID = ((minimum.FID & 0x1F) << 1) >> cpu_dynamic_fsb;
// Sanity check
if (maximum.CID < minimum.CID)
{
DBG("Insane FID values!");
p_states_count = 1;
}
else
{
// Finalize P-States
// Find how many P-States machine supports
p_states_count = maximum.CID - minimum.CID + 1;
if (p_states_count > 32)
p_states_count = 32;
uint8_t vidstep;
uint8_t i = 0, u, invalid = 0;
vidstep = ((maximum.VID << 2) - (minimum.VID << 2)) / (p_states_count - 1);
for (u = 0; u < p_states_count; u++)
{
i = u - invalid;
p_states[i].CID = maximum.CID - u;
p_states[i].FID = (p_states[i].CID >> 1);
if (p_states[i].FID < 0x6)
{
if (cpu_dynamic_fsb)
p_states[i].FID = (p_states[i].FID << 1) | 0x80;
}
else if (cpu_noninteger_bus_ratio)
{
p_states[i].FID = p_states[i].FID | (0x40 * (p_states[i].CID & 0x1));
}
if (i && p_states[i].FID == p_states[i-1].FID)
invalid++;
p_states[i].VID = ((maximum.VID << 2) - (vidstep * u)) >> 2;
uint32_t multiplier = p_states[i].FID & 0x1f;// = 0x08
bool half = p_states[i].FID & 0x40;// = 0x01
bool dfsb = p_states[i].FID & 0x80;// = 0x00
uint32_t fsb = Platform.CPU.FSBFrequency / 1000000; // = 400
uint32_t halffsb = (fsb + 1) >> 1;// = 200
uint32_t frequency = (multiplier * fsb);// = 3200
p_states[i].Frequency = (frequency + (half * halffsb)) >> dfsb;// = 3200 + 200 = 3400
}
p_states_count -= invalid;
}
} break;
case CPU_MODEL_FIELDS:
case CPU_MODEL_DALES:
case CPU_MODEL_DALES_32NM:
case CPU_MODEL_NEHALEM:
case CPU_MODEL_NEHALEM_EX:
case CPU_MODEL_WESTMERE:
case CPU_MODEL_WESTMERE_EX:
default:
verbose ("Unsupported CPU: P-States not generated !!!\n");
break;
}
}
}
// Generating SSDT
if (p_states_count > 0)
{
int i;
struct 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);
for (i = 0; i < p_states_count; i++)
{
struct aml_chunk* pstt = aml_add_package(pack);
aml_add_dword(pstt, p_states[i].Frequency);
aml_add_dword(pstt, 0x00000000); // Power
aml_add_dword(pstt, 0x0000000A); // Latency
aml_add_dword(pstt, 0x0000000A); // Latency
aml_add_dword(pstt, p_states[i].Control);
aml_add_dword(pstt, i+1); // Status
}
// Add aliaces
for (i = 0; i < acpi_cpu_count; i++)
{
char name[9];
sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);
scop = aml_add_scope(root, name);
aml_add_alias(scop, "PSS_", "_PSS");
}
aml_calculate_size(root);
struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);
aml_write_node(root, (void*)ssdt, 0);
ssdt->Length = root->Size;
ssdt->Checksum = 0;
ssdt->Checksum = 256 - checksum8(ssdt, ssdt->Length);
aml_destroy_node(root);
//dumpPhysAddr("P-States SSDT content: ", ssdt, ssdt->Length);
verbose ("SSDT with CPU P-States generated successfully\n");
return ssdt;
}
}
else
{
verbose ("ACPI CPUs not found: P-States not generated !!!\n");
}
return NULL;
}
struct acpi_2_fadt *patch_fadt(struct acpi_2_fadt *fadt, struct acpi_2_dsdt *new_dsdt)
{
extern void setupSystemType();
struct acpi_2_fadt *fadt_mod;
bool fadt_rev2_needed = false;
bool fix_restart;
const char * value;
// Restart Fix
if (Platform.CPU.Vendor == 0x756E6547) {/* Intel */
fix_restart = true;
getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);
} else {
verbose ("Not an Intel platform: Restart Fix not applied !!!\n");
fix_restart = false;
}
if (fix_restart) fadt_rev2_needed = true;
// Allocate new fadt table
if (fadt->Length < 0x84 && fadt_rev2_needed)
{
fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(0x84);
memcpy(fadt_mod, fadt, fadt->Length);
fadt_mod->Length = 0x84;
fadt_mod->Revision = 0x02; // FADT rev 2 (ACPI 1.0B MS extensions)
}
else
{
fadt_mod=(struct acpi_2_fadt *)AllocateKernelMemory(fadt->Length);
memcpy(fadt_mod, fadt, fadt->Length);
}
// Determine system type / PM_Model
if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL)
{
if (Platform.Type > 6)
{
if(fadt_mod->PM_Profile<=6)
Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct
else
Platform.Type = 1;/* Set a fixed value (Desktop) */
verbose("Error: system-type must be 0..6. Defaulting to %d !\n", Platform.Type);
}
else
Platform.Type = (unsigned char) strtoul(value, NULL, 10);
}
// Set PM_Profile from System-type if only user wanted this value to be forced
if (fadt_mod->PM_Profile != Platform.Type)
{
if (value)
{ // user has overriden the SystemType so take care of it in FACP
verbose("FADT: changing PM_Profile from 0x%02x to 0x%02x\n", fadt_mod->PM_Profile, Platform.Type);
fadt_mod->PM_Profile = Platform.Type;
}
else
{ // PM_Profile has a different value and no override has been set, so reflect the user value to ioregs
Platform.Type = fadt_mod->PM_Profile <= 6 ? fadt_mod->PM_Profile : 1;
}
}
// We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()
// because we need to take care of facp original content, if it is correct.
setupSystemType();
// Patch FADT to fix restart
if (fix_restart)
{
fadt_mod->Flags|= 0x400;
fadt_mod->Reset_SpaceID= 0x01; // System I/O
fadt_mod->Reset_BitWidth= 0x08; // 1 byte
fadt_mod->Reset_BitOffset= 0x00; // Offset 0
fadt_mod->Reset_AccessWidth= 0x01; // Byte access
fadt_mod->Reset_Address= 0x0cf9; // Address of the register
fadt_mod->Reset_Value= 0x06; // Value to write to reset the system
verbose("FADT: Restart Fix applied!\n");
}
// Patch DSDT Address if we have loaded DSDT.aml
if(new_dsdt)
{
DBG("DSDT: Old @%x,%x, ",fadt_mod->DSDT,fadt_mod->X_DSDT);
fadt_mod->DSDT=(uint32_t)new_dsdt;
if ((uint32_t)(&(fadt_mod->X_DSDT))-(uint32_t)fadt_mod+8<=fadt_mod->Length)
fadt_mod->X_DSDT=(uint32_t)new_dsdt;
DBG("New @%x,%x\n",fadt_mod->DSDT,fadt_mod->X_DSDT);
verbose("FADT: Using custom DSDT!\n");
}
// Correct the checksum
fadt_mod->Checksum=0;
fadt_mod->Checksum=256-checksum8(fadt_mod,fadt_mod->Length);
return fadt_mod;
}
/* Setup ACPI without replacing DSDT. */
int setupAcpiNoMod()
{
//addConfigurationTable(&gEfiAcpiTableGuid, getAddressOfAcpiTable(), "ACPI");
//addConfigurationTable(&gEfiAcpi20TableGuid, getAddressOfAcpi20Table(), "ACPI_20");
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)getAddressOfAcpiTable();
acpi20_p = (uint32_t)getAddressOfAcpi20Table();
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
if(acpi20_p) addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
return 1;
}
/* Setup ACPI. Replace DSDT if DSDT.aml is found */
int setupAcpi(void)
{
int version;
void *new_dsdt;
const char *filename;
char dirSpec[128];
int len = 0;
// Try using the file specified with the DSDT option
if (getValueForKey(kDSDT, &filename, &len, &bootInfo->bootConfig))
{
sprintf(dirSpec, filename);
}
else
{
sprintf(dirSpec, "DSDT.aml");
}
// Load replacement DSDT
new_dsdt = loadACPITable(dirSpec);
// Mozodojo: going to patch FACP and load SSDT's even if DSDT.aml is not present
/*if (!new_dsdt)
{
return setupAcpiNoMod();
}*/
// Mozodojo: Load additional SSDTs
struct acpi_2_ssdt *new_ssdt[32]; // 30 + 2 additional tables for pss & cst
int ssdt_count=0;
// SSDT Options
bool drop_ssdt=false, generate_pstates=false, generate_cstates=false;
getBoolForKey(kDropSSDT, &drop_ssdt, &bootInfo->bootConfig);
getBoolForKey(kGeneratePStates, &generate_pstates, &bootInfo->bootConfig);
getBoolForKey(kGenerateCStates, &generate_cstates, &bootInfo->bootConfig);
{
int i;
for (i=0; i<30; i++)
{
char filename[512];
sprintf(filename, i>0?"SSDT-%d.aml":"SSDT.aml", i);
if(new_ssdt[ssdt_count] = loadACPITable(filename))
{
ssdt_count++;
}
else
{
break;
}
}
}
// Do the same procedure for both versions of ACPI
for (version=0; version<2; version++) {
struct acpi_2_rsdp *rsdp, *rsdp_mod;
struct acpi_2_rsdt *rsdt, *rsdt_mod;
int rsdplength;
// Find original rsdp
rsdp=(struct acpi_2_rsdp *)(version?getAddressOfAcpi20Table():getAddressOfAcpiTable());
if (!rsdp)
{
DBG("No ACPI version %d found. Ignoring\n", version+1);
if (version)
addConfigurationTable(&gEfiAcpi20TableGuid, NULL, "ACPI_20");
else
addConfigurationTable(&gEfiAcpiTableGuid, NULL, "ACPI");
continue;
}
rsdplength=version?rsdp->Length:20;
DBG("RSDP version %d found @%x. Length=%d\n",version+1,rsdp,rsdplength);
/* FIXME: no check that memory allocation succeeded
* Copy and patch RSDP,RSDT, XSDT and FADT
* For more info see ACPI Specification pages 110 and following
*/
rsdp_mod=(struct acpi_2_rsdp *) AllocateKernelMemory(rsdplength);
memcpy(rsdp_mod, rsdp, rsdplength);
rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);
DBG("RSDT @%x, Length %d\n",rsdt, rsdt->Length);
if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)
{
uint32_t *rsdt_entries;
int rsdt_entries_num;
int dropoffset=0, i;
// mozo: using malloc cos I didn't found how to free already allocated kernel memory
rsdt_mod=(struct acpi_2_rsdt *)malloc(rsdt->Length);
memcpy (rsdt_mod, rsdt, rsdt->Length);
rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;
rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;
rsdt_entries=(uint32_t *)(rsdt_mod+1);
for (i=0;i<rsdt_entries_num;i++)
{
char *table=(char *)(rsdt_entries[i]);
if (!table)
continue;
DBG("TABLE %c%c%c%c,",table[0],table[1],table[2],table[3]);
rsdt_entries[i-dropoffset]=rsdt_entries[i];
if (drop_ssdt && tableSign(table, "SSDT"))
{
dropoffset++;
continue;
}
if (tableSign(table, "DSDT"))
{
DBG("DSDT found\n");
if(new_dsdt)
rsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
continue;
}
if (tableSign(table, "FACP"))
{
struct acpi_2_fadt *fadt, *fadt_mod;
fadt=(struct acpi_2_fadt *)rsdt_entries[i];
DBG("FADT found @%x, Length %d\n",fadt, fadt->Length);
if (!fadt || (uint32_t)fadt == 0xffffffff || fadt->Length>0x10000)
{
printf("FADT incorrect. Not modified\n");
continue;
}
fadt_mod = patch_fadt(fadt, new_dsdt);
rsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
// Generate _CST SSDT
if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
{
generate_cstates = false; // Generate SSDT only once!
ssdt_count++;
}
// Generating _PSS SSDT
if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
{
generate_pstates = false; // Generate SSDT only once!
ssdt_count++;
}
continue;
}
}
DBG("\n");
// Allocate rsdt in Kernel memory area
rsdt_mod->Length += 4*ssdt_count - 4*dropoffset;
struct acpi_2_rsdt *rsdt_copy = (struct acpi_2_rsdt *)AllocateKernelMemory(rsdt_mod->Length);
memcpy (rsdt_copy, rsdt_mod, rsdt_mod->Length);
free(rsdt_mod); rsdt_mod = rsdt_copy;
rsdp_mod->RsdtAddress=(uint32_t)rsdt_mod;
rsdt_entries_num=(rsdt_mod->Length-sizeof(struct acpi_2_rsdt))/4;
rsdt_entries=(uint32_t *)(rsdt_mod+1);
// Mozodojo: Insert additional SSDTs into RSDT
if(ssdt_count>0)
{
int j;
for (j=0; j<ssdt_count; j++)
rsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];
verbose("RSDT: Added %d SSDT table(s)\n", ssdt_count);
}
// Correct the checksum of RSDT
DBG("RSDT: Original checksum %d, ", rsdt_mod->Checksum);
rsdt_mod->Checksum=0;
rsdt_mod->Checksum=256-checksum8(rsdt_mod,rsdt_mod->Length);
DBG("New checksum %d at %x\n", rsdt_mod->Checksum,rsdt_mod);
}
else
{
rsdp_mod->RsdtAddress=0;
printf("RSDT not found or RSDT incorrect\n");
}
if (version)
{
struct acpi_2_xsdt *xsdt, *xsdt_mod;
// FIXME: handle 64-bit address correctly
xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
DBG("XSDT @%x;%x, Length=%d\n", (uint32_t)(rsdp->XsdtAddress>>32),(uint32_t)rsdp->XsdtAddress,
xsdt->Length);
if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
{
uint64_t *xsdt_entries;
int xsdt_entries_num, i;
int dropoffset=0;
// mozo: using malloc cos I didn't found how to free already allocated kernel memory
xsdt_mod=(struct acpi_2_xsdt*)malloc(xsdt->Length);
memcpy(xsdt_mod, xsdt, xsdt->Length);
rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;
xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;
xsdt_entries=(uint64_t *)(xsdt_mod+1);
for (i=0;i<xsdt_entries_num;i++)
{
char *table=(char *)((uint32_t)(xsdt_entries[i]));
if (!table)
continue;
xsdt_entries[i-dropoffset]=xsdt_entries[i];
if (drop_ssdt && tableSign(table, "SSDT"))
{
dropoffset++;
continue;
}
if (tableSign(table, "DSDT"))
{
DBG("DSDT found\n");
if (new_dsdt)
xsdt_entries[i-dropoffset]=(uint32_t)new_dsdt;
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
continue;
}
if (tableSign(table, "FACP"))
{
struct acpi_2_fadt *fadt, *fadt_mod;
fadt=(struct acpi_2_fadt *)(uint32_t)xsdt_entries[i];
DBG("FADT found @%x,%x, Length %d\n",(uint32_t)(xsdt_entries[i]>>32),fadt,
fadt->Length);
if (!fadt || (uint64_t)xsdt_entries[i] >= 0xffffffff || fadt->Length>0x10000)
{
verbose("FADT incorrect or after 4GB. Dropping XSDT\n");
goto drop_xsdt;
}
fadt_mod = patch_fadt(fadt, new_dsdt);
xsdt_entries[i-dropoffset]=(uint32_t)fadt_mod;
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
// Generate _CST SSDT
if (generate_cstates && (new_ssdt[ssdt_count] = generate_cst_ssdt(fadt_mod)))
{
generate_cstates = false; // Generate SSDT only once!
ssdt_count++;
}
// Generating _PSS SSDT
if (generate_pstates && (new_ssdt[ssdt_count] = generate_pss_ssdt((void*)fadt_mod->DSDT)))
{
generate_pstates = false; // Generate SSDT only once!
ssdt_count++;
}
continue;
}
DBG("TABLE %c%c%c%c@%x,",table[0],table[1],table[2],table[3],xsdt_entries[i]);
}
// Allocate xsdt in Kernel memory area
xsdt_mod->Length += 8*ssdt_count - 8*dropoffset;
struct acpi_2_xsdt *xsdt_copy = (struct acpi_2_xsdt *)AllocateKernelMemory(xsdt_mod->Length);
memcpy(xsdt_copy, xsdt_mod, xsdt_mod->Length);
free(xsdt_mod); xsdt_mod = xsdt_copy;
rsdp_mod->XsdtAddress=(uint32_t)xsdt_mod;
xsdt_entries_num=(xsdt_mod->Length-sizeof(struct acpi_2_xsdt))/8;
xsdt_entries=(uint64_t *)(xsdt_mod+1);
// Mozodojo: Insert additional SSDTs into XSDT
if(ssdt_count>0)
{
int j;
for (j=0; j<ssdt_count; j++)
xsdt_entries[i-dropoffset+j]=(uint32_t)new_ssdt[j];
verbose("Added %d SSDT table(s) into XSDT\n", ssdt_count);
}
// Correct the checksum of XSDT
xsdt_mod->Checksum=0;
xsdt_mod->Checksum=256-checksum8(xsdt_mod,xsdt_mod->Length);
}
else
{
drop_xsdt:
DBG("About to drop XSDT\n");
/*FIXME: Now we just hope that if MacOS doesn't find XSDT it reverts to RSDT.
* A Better strategy would be to generate
*/
rsdp_mod->XsdtAddress=0xffffffffffffffffLL;
verbose("XSDT not found or XSDT incorrect\n");
}
}
// Correct the checksum of RSDP
DBG("RSDP: Original checksum %d, ", rsdp_mod->Checksum);
rsdp_mod->Checksum=0;
rsdp_mod->Checksum=256-checksum8(rsdp_mod,20);
DBG("New checksum %d\n", rsdp_mod->Checksum);
if (version)
{
DBG("RSDP: Original extended checksum %d", rsdp_mod->ExtendedChecksum);
rsdp_mod->ExtendedChecksum=0;
rsdp_mod->ExtendedChecksum=256-checksum8(rsdp_mod,rsdp_mod->Length);
DBG("New extended checksum %d\n", rsdp_mod->ExtendedChecksum);
}
//verbose("Patched ACPI version %d DSDT\n", version+1);
if (version)
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi20_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpi20TableGuid, &acpi20_p, "ACPI_20");
}
else
{
/* XXX aserebln why uint32 cast if pointer is uint64 ? */
acpi10_p = (uint32_t)rsdp_mod;
addConfigurationTable(&gEfiAcpiTableGuid, &acpi10_p, "ACPI");
}
}
#if DEBUG_ACPI
printf("Press a key to continue... (DEBUG_ACPI)\n");
getc();
#endif
return 1;
}
branches/meklort/i386/libsaio/hfs.h
2323
2424
2525
26
26
2727
2828
2929
extern long HFSInitPartition(CICell ih);
extern long HFSLoadFile(CICell ih, char * filePath);
extern long HFSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length);
extern long HFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
extern long HFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid);
extern void HFSGetDescription(CICell ih, char *str, long strMaxLen);
branches/meklort/i386/libsaio/spd.c
11
22
3
3
4
5
6
47
58
69
......
8588
8689
8790
88
89
90
91
92
93
9194
9295
9396
9497
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
95123
96124
97
125
98126
99127
100128
101129
102
130
103131
104132
105
106
133
134
107135
108136
109137
110138
111139
112
113
140
141
142
143
144
145
114146
115147
116
148
117149
118150
119151
......
158190
159191
160192
161
193
194
162195
163196
164197
165198
166199
167
168
169
170
171
200
201
202
203
172204
173
174
205
206
207
175208
176209
177
178
179
180
210
181211
182212
183213
184
214
185215
186
187
188
216
217
189218
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
208240
209241
210242
211243
244
212245
213246
214247
215
248
216249
217250
218251
......
225258
226259
227260
261
262
228263
229264
230265
231
232266
233267
234
235
236268
269
237270
238271
239272
240273
241274
242
243
244275
276
277
278
245279
246280
247281
......
260294
261295
262296
263
264
265
297
298
299
266300
267301
268302
269
270
271
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
272321
273322
274323
......
277326
278327
279328
280
329
330
281331
282332
283333
......
287337
288338
289339
290
291
292
293
340
294341
295342
296343
......
320367
321368
322369
323
370
324371
325372
326373
/*
* spd.c - serial presence detect memory information
* (restored from pcefi10.5)
*
* Originally restored from pcefi10.5
* Dynamic mem detection original impl. by Rekursor
* System profiler fix and other fixes by Mozodojo.
*/
#include "libsaio.h"
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 40);
if (t > 10)
break;// break after 10ms
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,
SPD_DDR3_MEMORY_CODE,
SPD_NUM_ROWS,
SPD_NUM_COLUMNS,
SPD_NUM_DIMM_BANKS,
SPD_NUM_BANKS_PER_SDRAM,
4,7,8,9,12,64, /* TODO: give names to these values */
95,96,97,98, 122,123,124,125 /* UIS */
};
#define SPD_INDEXES_SIZE (sizeof(spd_indexes) / sizeof(int))
/** Read from spd *used* values only*/
static void init_spd(char * spd, uint32_t base, int slot)
{
int i;
for (i=0; i< SPD_INDEXES_SIZE; i++) {
READ_SPD(spd, base, slot, spd_indexes[i]);
}
}
/** Get Vendor Name from spd, 2 cases handled DDR3 and DDR2,
have different formats, always return a valid ptr.*/
const char * getVendorName(RamSlotInfo_t* slot)
const char * getVendorName(RamSlotInfo_t* slot, uint32_t base, int slot_num)
{
uint8_t bank = 0;
uint8_t code = 0;
int i = 0;
const char * spd = slot->spd;
uint8_t * spd = (uint8_t *) slot->spd;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3
bank = spd[0x75];
code = spd[0x76];
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[0x40]==0x7f) {
for (i=0x40; i<0x48 && spd[i]==0x7f;i++) bank++;
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
}
READ_SPD(spd, base, slot_num,i);
code = spd[i];
} else {
code = spd[0x40];
code = spd[64];
bank = 0;
}
for (i=0; i < VEN_MAP_SIZE; i++)
return 800; // default freq for unknown types
}
#define UIS(a) ((uint32_t)spd[a])
#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 */
const char *getDDRSerial(const char* spd)
{
static char asciiSerial[16];
static uint8_t serialnum=0;
uint32_t ret=0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {// DDR3
ret = UIS(122) | (UIS(123)<<8) | (UIS(124)<<16) | ((UIS(125)&0x7f)<<24);
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
ret = UIS(95) | (UIS(96)<<8) | (UIS(97)<<16) | ((UIS(98)&0x7f)<<24);
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 (!ret) sprintf(asciiSerial, "10000000%d", serialnum++);
else sprintf(asciiSerial, "%d", ret);
return asciiSerial;
return strdup(asciiSerial);
}
/** Get DDR3 or DDR2 Part Number, always return a valid ptr */
const char * getDDRPartNum(const char* spd)
const char * getDDRPartNum(char* spd, uint32_t base, int slot)
{
const char * sPart = NULL;
int i;
bool bZero = false;
static char asciiPartNo[32];
int i, start=0, index = 0;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3)
sPart = &spd[128];
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2)
sPart = &spd[73];
if (sPart) { // Check that the spd part name is zero terminated and that it is ascii:
for (i=0; i<32; i++) {
if (sPart[i]==0) {
bZero = true;
break;
}
else if ( !isascii(sPart[i]) ) {
sPart = NULL;
break;
}
}
}
return ( sPart==NULL || !(*sPart) || !bZero ) ?
"N/A" : sPart;
if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) {
start = 128;
}
else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2) {
start = 73;
}
// 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++) {
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...
asciiPartNo[index++] = c;
else if (!isascii(c))
break;
}
return strdup(asciiPartNo);
return NULL;
}
int mapping []= {0,2,1,3,4,6,5,7,8,10,9,11};
/** Read from smbus the SPD content and interpret it for detecting memory attributes */
static void read_smb_intel(pci_dt_t *smbus_dev)
{
int i, x, speed;
int i, speed;
uint8_t spd_size, spd_type;
uint32_t base;
bool dump = false;
bool fullBanks = // needed at least for laptops
Platform.DMI.MemoryModules == Platform.DMI.MaxMemorySlots;
// Search MAX_RAM_SLOTS slots
char spdbuf[256];
for (i = 0; i < MAX_RAM_SLOTS; i++){
slot = &Platform.RAM.DIMM[i];
spd_size = smb_read_byte_intel(base, 0x50 + i, 0);
// Check spd is present
if (spd_size && (spd_size != 0xff) ) {
slot->spd = malloc(spd_size);
if (slot->spd == NULL) continue;
slot->spd = spdbuf;
slot->InUse = true;
bzero(slot->spd, spd_size);
// Copy spd data into buffer
for (x = 0; x < spd_size; x++)
slot->spd[x] = smb_read_byte_intel(base, 0x50 + i, x);
//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:
spd_type = (slot->spd[SPD_MEMORY_TYPE] < ((char) 12) ? slot->spd[SPD_MEMORY_TYPE] : 0);
slot->Type = spd_mem_to_smbios[spd_type];
slot->PartNo = strdup(getDDRPartNum(slot->spd) );
slot->Vendor = strdup(getVendorName(slot) );
slot->SerialNo = strdup(getDDRSerial(slot->spd));
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 (speed > slot->Frequency) slot->Frequency = speed; // just in case dmi wins on spd
if(dump) {
printf("Slot %d Type %d %dMB (%s) %dMHz Vendor=%s, PartNo=%s SerialNo=%s\n",
if (slot->Frequency<speed) slot->Frequency = speed;
// pci memory controller if available, is more reliable
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) {
case 1:freq--;break;
case 32:freq++;break;
case 65:freq++; break;
case 98:freq+=2;break;
case 99:freq++; break;
}
slot->Frequency = freq;
}
verbose("Slot: %d Type %d %dMB (%s) %dMHz Vendor=%s\n PartNo=%s SerialNo=%s\n",
i,
(int)slot->Type,
slot->ModuleSize,
slot->Vendor,
slot->PartNo,
slot->SerialNo);
dumpPhysAddr("spd content: ",slot->spd, spd_size);
if(DEBUG_SPD) {
dumpPhysAddr("spd content: ",slot->spd, spd_size);
getc();
}
}
i>0 && Platform.RAM.DIMM[1].InUse==false && fullBanks && Platform.DMI.MaxMemorySlots==2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
if (slot->spd) {
free(slot->spd);
slot->spd = NULL;
}
slot->spd = NULL;
} // for
}
int i;
while (current) {
#if DEBUG_SPD
#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,
branches/meklort/i386/libsaio/acpi_patcher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
* Copyright 2008 mackerintel
*/
#ifndef __LIBSAIO_ACPI_PATCHER_H
#define __LIBSAIO_ACPI_PATCHER_H
#include "libsaio.h"
uint64_t acpi10_p;
uint64_t acpi20_p;
uint64_t smbios_p;
extern int setupAcpi();
extern EFI_STATUS addConfigurationTable();
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
struct p_state
{
union
{
uint16_t Control;
struct
{
uint8_t VID;// Voltage ID
uint8_t FID;// Frequency ID
};
};
uint8_tCID;// Compare ID
uint32_tFrequency;
};
#endif /* !__LIBSAIO_ACPI_PATCHER_H */
branches/meklort/i386/libsaio/spd.h
9494
9595
9696
97
98
9799
98100
99101
#define SPD_MANUFACTURER_SPECIFIC_DATA 99 /* Manufacturer specific data (bytes 99-125) */
#define SPD_INTEL_SPEC_FOR_FREQUENCY 126 /* Intel specification for frequency */
#define SPD_INTEL_SPEC_100_MHZ 127 /* Intel specification details for 100MHz support */
#define SPD_DDR3_MEMORY_BANK 0x75
#define SPD_DDR3_MEMORY_CODE 0x76
/* DRAM specifications use the following naming conventions for SPD locations */
#define SPD_tRP SPD_MIN_ROW_PRECHARGE_TIME
branches/meklort/i386/libsaio/Makefile
3939
4040
4141
42
42
4343
44
44
4545
46
46
4747
4848
4949
ufs.o ufs_byteorder.o \
vbe.o nbp.o hfs.o hfs_compare.o \
xml.o ntfs.o msdos.o md5c.o device_tree.o \
cpu.o platform.o dsdt_patcher.o \
cpu.o platform.o acpi_patcher.o \
smbios_patcher.o fake_efi.o ext2fs.o \
hpet.o spd.o usb.o pci_setup.o \
hpet.o dram_controllers.o spd.o usb.o pci_setup.o \
device_inject.o nvidia.o ati.o pci_root.o \
convert.o mem.o edid.o resolution.o
convert.o mem.o aml_generator.o resolution.o edid.o
SAIO_EXTERN_OBJS = console.o
branches/meklort/i386/libsaio/ufs.c
4646
4747
4848
49
49
5050
5151
5252
......
223223
224224
225225
226
226
227227
228228
229229
......
383383
384384
385385
386
386
387387
388388
389389
390
390
391391
392392
393393
394394
395395
396
397
396
397
398398
399399
400400
......
418418
419419
420420
421
421
422
422423
423424
424425
static long ResolvePathToInode(char *filePath, long *flags,
InodePtr fileInode, InodePtr dirInode);
static long ReadDirEntry(InodePtr dirInode, long *fileInodeNum,
long *dirIndex, char **name);
long long *dirIndex, char **name);
static long FindFileInDir(char *fileName, long *flags,
InodePtr fileInode, InodePtr dirInode);
static char *ReadFileBlock(InodePtr fileInode, long fragNum, long blockOffset,
#ifndef BOOT1
long UFSGetDirEntry( CICell ih, char * dirPath, long * dirIndex,
long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
{
}
static long ReadDirEntry( InodePtr dirInode, long * fileInodeNum,
long * dirIndex, char ** name )
long long * dirIndex, char ** name )
{
struct direct *dir;
char *buffer;
long index;
long long index;
long dirBlockNum, dirBlockOffset;
while (1) {
index = *dirIndex;
dirBlockOffset = index % DIRBLKSIZ;
dirBlockNum = index / DIRBLKSIZ;
dirBlockOffset = (long) (index % DIRBLKSIZ);
dirBlockNum = (long) (index / DIRBLKSIZ);
buffer = ReadFileBlock(dirInode, dirBlockNum, 0, DIRBLKSIZ, 0, 1);
if (buffer == 0) return -1;
static long FindFileInDir( char * fileName, long * flags,
InodePtr fileInode, InodePtr dirInode )
{
long ret, inodeNum, index = 0;
long ret, inodeNum;
long long index = 0;
char *name;
while (1) {
branches/meklort/i386/libsaio/ufs.h
2323
2424
2525
26
26
2727
2828
2929
extern long UFSInitPartition(CICell ih);
extern long UFSLoadFile(CICell ih, char * filePath);
extern long UFSReadFile( CICell ih, char * filePath, void * base, uint64_t offset, uint64_t length );
extern long UFSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
extern long UFSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid);
extern void UFSGetDescription(CICell ih, char *str, long strMaxLen);
branches/meklort/i386/libsaio/smbios_patcher.c
1010
1111
1212
13
1314
1415
1516
......
8889
8990
9091
91
92
93
94
95
96
97
98
99
100
92
93
94
95
96
97
98
99
100
101
101102
102103
103104
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
104135
105136
106137
......
113144
114145
115146
116
117
118
119
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
120187
121188
122
189
123190
124191
125192
......
142209
143210
144211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
145302
146303
147
148
149
150
151
152
153
154
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
155355
356
357
156358
157359
158360
......
166368
167369
168370
371
169372
170373
171374
......
255458
256459
257460
258
461
259462
260463
261464
......
457660
458661
459662
460
461
663
664
462665
666
667
463668
464669
465670
......
729934
730935
731936
732
937
938
939
940
941
733942
734943
735944
......
777986
778987
779988
780
989
781990
782991
783992
#include "fake_efi.h"
#include "platform.h"
#include "smbios_patcher.h"
#include "pci.h"
#ifndef DEBUG_SMBIOS
#define DEBUG_SMBIOS 0
// defaults for a Mac Pro
static const SMStrEntryPair const sm_macpro_defaults[]={
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Computer, Inc."},
{"SMproductname","MacPro3,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacPro"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F4208DC8"},
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosversion","MP31.88Z.006C.B05.0802291410"},
{"SMbiosdate","04/01/2008"},
{"SMmanufacter","Apple Computer, Inc."},
{"SMproductname","MacPro3,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacPro"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F4208DC8"},
{ "",""}
};
// defaults for an iMac11,1 core i3/i5/i7
static const SMStrEntryPair const sm_imac_core_defaults[]={
{"SMbiosvendor","Apple Inc."},
{"SMbiosversion","IM111.88Z.0034.B00.0802091538"},
{"SMbiosdate","06/01/2009"},
{"SMmanufacter","Apple Inc."},
{"SMproductname","iMac11,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","iMac"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F2268DAE"},
{ "",""}
};
// defaults for a Mac Pro 4,1 core i7/Xeon
static const SMStrEntryPair const sm_macpro_core_defaults[]={
{"SMbiosvendor","Apple Computer, Inc."},
{"SMbiosversion","MP41.88Z.0081.B04.0903051113"},
{"SMbiosdate","11/06/2009"},
{"SMmanufacter","Apple Computer, Inc."},
{"SMproductname","MacPro4,1"},
{"SMsystemversion","1.0"},
{"SMserial","SOMESRLNMBR"},
{"SMfamily","MacPro"},
{"SMboardmanufacter","Apple Computer, Inc."},
{"SMboardproduct","Mac-F4208DC8"},
{ "",""}
};
static const char* sm_get_defstr(const char * key, int table_num)
{
inti;
sm_defaults=sm_macbook_defaults;
}
} else {
switch (Platform.CPU.NoCores) {
case 1: sm_defaults=sm_macmini_defaults; break;
case 2: sm_defaults=sm_imac_defaults; break;
default: sm_defaults=sm_macpro_defaults; break;
switch (Platform.CPU.NoCores)
{
case 1:
sm_defaults=sm_macmini_defaults;
break;
case 2:
sm_defaults=sm_imac_defaults;
break;
default:
{
switch (Platform.CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
{
case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)
case 0x19: // Intel Core i5 650 @3.20 Ghz
sm_defaults=sm_imac_core_defaults;
break;
case CPU_MODEL_NEHALEM:
case CPU_MODEL_NEHALEM_EX:
case CPU_MODEL_WESTMERE:
case CPU_MODEL_WESTMERE_EX:
sm_defaults=sm_macpro_core_defaults;
break;
default:
sm_defaults=sm_macpro_defaults;
break;
}
break;
}
default:
sm_defaults=sm_macpro_defaults;
break;
}
break;
}
}
}
for (i=0; sm_defaults[i].key[0]; i++) {
if (!strcmp (sm_defaults[i].key, key)) {
return sm_defaults[i].value;
return Platform.CPU.CPUFrequency/1000000;
}
static int sm_get_bus_speed (const char *name, int table_num)
{
if (Platform.CPU.Vendor == 0x756E6547) // Intel
{
switch (Platform.CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH:// Yonah0x0E
case CPU_MODEL_MEROM:// Merom0x0F
case CPU_MODEL_PENRYN:// Penryn0x17
case CPU_MODEL_ATOM:// Atom 45nm0x1C
return 0; // TODO: populate bus speed for these processors
//case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
//if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
//return 2500; // Core i5
//return 4800; // Core i7
//case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
//case CPU_MODEL_NEHALEM_EX:
//case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
//return 4800; // GT/s / 1000
//
case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
return 0; // TODO: populate bus speed for these processors
//case 0x19: // Intel Core i5 650 @3.20 Ghz
//return 2500; // why? Intel spec says 2.5GT/s
case 0x19: // Intel Core i5 650 @3.20 Ghz
case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm)
case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core
case CPU_MODEL_NEHALEM_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
{ // thanks to dgobe for i3/i5/i7 bus speed detection
int nhm_bus = 0x3F;
static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};
unsigned long did, vid;
int i;
// Nehalem supports Scrubbing
// First, locate the PCI bus where the MCH is located
for(i = 0; i < sizeof(possible_nhm_bus); i++)
{
vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);
did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);
vid &= 0xFFFF;
did &= 0xFF00;
if(vid == 0x8086 && did >= 0x2C00)
nhm_bus = possible_nhm_bus[i];
}
unsigned long qpimult, qpibusspeed;
qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);
qpimult &= 0x7F;
DBG("qpimult %d\n", qpimult);
qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000));
// Rek: rounding decimals to match original mac profile info
if (qpibusspeed%100 != 0)qpibusspeed = ((qpibusspeed+50)/100)*100;
DBG("qpibusspeed %d\n", qpibusspeed);
return qpibusspeed;
}
}
}
}
}
return 0;
}
static int sm_get_simplecputype()
{
if (Platform.CPU.NoCores >= 4)
{
return 0x0501; // Quad-Core Xeon
}
else if (Platform.CPU.NoCores == 1)
{
return 0x0201; // Core Solo
};
return 0x0301; // Core 2 Duo
}
static int sm_get_cputype (const char *name, int table_num)
{
if (Platform.CPU.NoCores == 1) {
return 0x0101; // <01 01> Intel Core Solo?
} else if (Platform.CPU.NoCores == 2) {
return 0x0301; // <01 03> Intel Core 2 Duo
} else if (Platform.CPU.NoCores >= 4) {
return 0x0501; // <01 05> Quad-Core Intel Xeon
} else {
return 0x0301; // Default to Core 2 Duo
static bool done = false;
if (Platform.CPU.Vendor == 0x756E6547) // Intel
{
if (!done) {
verbose("CPU is %s, family 0x%x, model 0x%x\n", Platform.CPU.BrandString, Platform.CPU.Family, Platform.CPU.Model);
done = true;
}
switch (Platform.CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH: // Yonah
case CPU_MODEL_MEROM: // Merom
case CPU_MODEL_PENRYN: // Penryn
case CPU_MODEL_ATOM: // Intel Atom (45nm)
return sm_get_simplecputype();
case CPU_MODEL_NEHALEM: // Intel Core i7 LGA1366 (45nm)
return 0x0701; // Core i7
case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
return 0x601; // Core i5
return 0x701; // Core i7
case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) (Havendale, Auburndale)
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
return 0x601; // Core i5
return 0x0701; // Core i7
case CPU_MODEL_DALES_32NM: // Intel Core i3, i5, i7 LGA1156 (32nm) (Clarkdale, Arrandale)
if (strstr(Platform.CPU.BrandString, "Core(TM) i3"))
return 0x901; // Core i3
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
return 0x601; // Core i5
return 0x0701; // Core i7
case CPU_MODEL_WESTMERE: // Intel Core i7 LGA1366 (32nm) 6 Core (Gulftown, Westmere-EP, Westmere-WS)
case CPU_MODEL_WESTMERE_EX: // Intel Core i7 LGA1366 (45nm) 6 Core ???
return 0x0701; // Core i7
case 0x19: // Intel Core i5 650 @3.20 Ghz
return 0x601; // Core i5
}
}
}
}
return sm_get_simplecputype();
}
static int sm_get_memtype (const char *name, int table_num)
return Platform.RAM.DIMM[map].Type;
}
}
return SMB_MEM_TYPE_DDR2;
}
{.name="SMmemserial",.table_type=17,.value_type=SMSTRING,.offset=0x18,.auto_str=sm_get_memserial},
{.name="SMmempart",.table_type=17,.value_type=SMSTRING,.offset=0x1A,.auto_str=sm_get_mempartno},
{.name="SMcputype",.table_type=131,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_cputype},
{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_str=0}
{.name="SMbusspeed",.table_type=132,.value_type=SMWORD,.offset=0x04,.auto_int=sm_get_bus_speed}
};
struct smbios_table_description smbios_table_descriptions[]=
int i, j;
int tablespresent[256];
bool do_auto=true;
extern void dumpPhysAddr(const char * title, void * a, int len);
static bool done = false; // IMPROVEME: called twice via getSmbios(), but only the second call can get all necessary info !
extern void dumpPhysAddr(const char * title, void * a, int len);
bzero(tablespresent, sizeof(tablespresent));
bzero(handles, sizeof(handles));
newsmbios->dmi.checksum = 256 - checksum8(&newsmbios->dmi, sizeof(newsmbios->dmi));
newsmbios->checksum = 0;
newsmbios->checksum = 256 - checksum8(newsmbios, sizeof(*newsmbios));
verbose("Patched DMI Table\n");
if (!done) {
verbose("Patched DMI Table\n");
done=true;
}
}
#define MAX_DMI_TABLES 96
DmiTablePairCount++;
}
else {
printf("DMI table entries list is full! next entries won't be stored\n");
printf("DMI table entries list is full! Next entries won't be stored.\n");
}
#if DEBUG_SMBIOS
printf("DMI header found for table type %d, length = %d\n", dmihdr->type, dmihdr->length);
branches/meklort/i386/libsaio/aml_generator.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
/*
* aml_generator.c
* Chameleon
*
* Created by Mozodojo on 20/07/10.
* Copyright 2010 mozo. All rights reserved.
*
*/
#include "aml_generator.h"
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
{
if (parent && node)
{
switch (parent->Type)
{
case AML_CHUNK_NONE:
case AML_CHUNK_BYTE:
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
verbose("aml_add_to_parent: Node isn't supports child nodes!");
return FALSE;
case AML_CHUNK_NAME:
if (parent->First)
{
verbose("aml_add_to_parent: Name node could have only one child node!");
return FALSE;
}
break;
default:
break;
}
if (!parent->First)
parent->First = node;
if (parent->Last)
parent->Last->Next = node;
parent->Last = node;
return TRUE;
}
return FALSE;
}
struct aml_chunk* aml_create_node(struct aml_chunk* parent)
{
struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));
aml_add_to_parent(parent, node);
return node;
}
void aml_destroy_node(struct aml_chunk* node)
{
// Delete child nodes
struct aml_chunk* child = node->First;
while (child)
{
struct aml_chunk* next = child->Next;
if (child->Buffer)
free(child->Buffer);
free(child);
child = next;
}
// Free node
if (node->Buffer)
free(node->Buffer);
free(node);
}
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_NONE;
node->Length = 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)
{
struct aml_chunk* node = aml_create_node(parent);
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)
{
struct aml_chunk* node = aml_create_node(parent);
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)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_DWORD;
node->Length = 4;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value & 0xff;
node->Buffer[1] = (value >> 8) & 0xff;
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)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_QWORD;
node->Length = 8;
node->Buffer = malloc(node->Length);
node->Buffer[0] = value & 0xff;
node->Buffer[1] = (value >> 8) & 0xff;
node->Buffer[2] = (value >> 16) & 0xff;
node->Buffer[3] = (value >> 24) & 0xff;
node->Buffer[4] = (value >> 32) & 0xff;
node->Buffer[5] = (value >> 40) & 0xff;
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)
{
if (strlen(name) < 4)
{
verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4", name);
return 0;
}
memcpy(buffer, name, 4);
return 4;
}
unsigned int aml_fill_name(struct aml_chunk* node, const char* name)
{
if (!node)
return 0;
int len = strlen(name), offset = 0, count = len / 4;
if ((len % 4) > 1 || count == 0)
{
verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16 etc.", name);
return 0;
}
unsigned int root = 0;
if ((len % 4) == 1 && name[0] == '\\')
root++;
if (count == 1)
{
node->Length = 4 + root;
node->Buffer = malloc(node->Length);
memcpy(node->Buffer, name, 4 + root);
return node->Length;
}
if (count == 2)
{
node->Length = 2 + 8;
node->Buffer = malloc(node->Length);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2e; // Double name
memcpy(node->Buffer+offset, name + root, 8);
return node->Length;
}
node->Length = 3 + count*4;
node->Buffer = malloc(node->Length);
node->Buffer[offset++] = 0x5c; // Root Char
node->Buffer[offset++] = 0x2f; // Multi name
node->Buffer[offset++] = count; // Names count
memcpy(node->Buffer+offset, name + root, count*4);
return node->Length;
}
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)
{
struct aml_chunk* node = aml_create_node(parent);
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)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_NAME;
aml_fill_name(node, name);
}
return node;
}
struct aml_chunk* aml_add_package(struct aml_chunk* parent)
{
struct aml_chunk* node = aml_create_node(parent);
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)
{
struct aml_chunk* node = aml_create_node(parent);
if (node)
{
node->Type = AML_CHUNK_ALIAS;
node->Length = 8;
node->Buffer = malloc(node->Length);
aml_fill_simple_name(node->Buffer, name1);
aml_fill_simple_name(node->Buffer+4, name2);
}
return node;
}
unsigned char aml_get_size_length(unsigned int size)
{
if (size + 1 <= 0x3f)
return 1;
else if (size + 2 <= 0x3fff)
return 2;
else if (size + 3 <= 0x3fffff)
return 3;
return 4;
}
unsigned int aml_calculate_size(struct aml_chunk* node)
{
if (node)
{
node->Size = 0;
// Calculate child nodes size
struct aml_chunk* child = node->First;
unsigned char child_count = 0;
while (child)
{
child_count++;
node->Size += aml_calculate_size(child);
child = child->Next;
}
switch (node->Type)
{
case AML_CHUNK_NONE:
node->Size += node->Length;
break;
case AML_CHUNK_SCOPE:
node->Size += 1 + 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;
node->Size += aml_get_size_length(node->Size);
break;
case AML_CHUNK_BYTE:
if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
{
node->Size += node->Length;
}
else
{
node->Size += 1 + node->Length;
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
node->Size += 1 + node->Length;
break;
}
return node->Size;
}
return 0;
}
unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)
{
buffer[offset++] = value;
return offset;
}
unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = value >> 8;
return offset;
}
unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
buffer[offset++] = (value >> 16) & 0xff;
buffer[offset++] = (value >> 24) & 0xff;
return offset;
}
unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)
{
buffer[offset++] = value & 0xff;
buffer[offset++] = (value >> 8) & 0xff;
buffer[offset++] = (value >> 16) & 0xff;
buffer[offset++] = (value >> 24) & 0xff;
buffer[offset++] = (value >> 32) & 0xff;
buffer[offset++] = (value >> 40) & 0xff;
buffer[offset++] = (value >> 48) & 0xff;
buffer[offset++] = (value >> 56) & 0xff;
return offset;
}
unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)
{
if (size > 0)
{
memcpy(buffer + offset, value, size);
}
return offset + size;
}
unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int 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;
buffer[offset++] = (size >> 12) & 0xff;
}
else
{
buffer[offset++] = 0xc0 | (size & 0xf);
buffer[offset++] = (size >> 4) & 0xff;
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)
{
if (node && buffer)
{
unsigned int old = offset;
switch (node->Type)
{
case AML_CHUNK_NONE:
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
case AML_CHUNK_SCOPE:
case AML_CHUNK_PACKAGE:
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)
{
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
else
{
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
}
break;
case AML_CHUNK_WORD:
case AML_CHUNK_DWORD:
case AML_CHUNK_QWORD:
case AML_CHUNK_ALIAS:
case AML_CHUNK_NAME:
offset = aml_write_byte(node->Type, buffer, offset);
offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
break;
default:
break;
}
struct aml_chunk* child = node->First;
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);
}
return offset;
}
branches/meklort/i386/libsaio/aml_generator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
* aml_generator.h
* Chameleon
*
* Created by Mozodojo on 20/07/10.
* Copyright 2010 mozo. All rights reserved.
*
*/
#ifndef __LIBSAIO_AML_GENERATOR_H
#define __LIBSAIO_AML_GENERATOR_H
#include "libsaio.h"
#defineAML_CHUNK_NONE0xff
#defineAML_CHUNK_ZERO0x00
#defineAML_CHUNK_ONE0x01
#defineAML_CHUNK_ALIAS0x06
#defineAML_CHUNK_NAME0x08
#defineAML_CHUNK_BYTE0x0A
#defineAML_CHUNK_WORD0x0B
#defineAML_CHUNK_DWORD0x0C
#defineAML_CHUNK_STRING0x0D
#defineAML_CHUNK_QWORD0x0E
#defineAML_CHUNK_SCOPE0x10
#defineAML_CHUNK_PACKAGE0x12
struct aml_chunk
{
unsigned charType;
unsigned intLength;
char*Buffer;
unsigned intSize;
struct aml_chunk*Next;
struct aml_chunk*First;
struct aml_chunk*Last;
};
static inline bool aml_isvalidchar(char c)
{
return isupper(c) || isdigit(c) || c == '_';
};
bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node);
struct aml_chunk* aml_create_node(struct aml_chunk* parent);
void aml_destroy_node(struct aml_chunk* node);
struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size);
struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value);
struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value);
struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value);
struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value);
struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name);
struct aml_chunk* aml_add_package(struct aml_chunk* parent);
struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2);
unsigned int aml_calculate_size(struct aml_chunk* node);
unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset);
#endif /* !__LIBSAIO_AML_GENERATOR_H */
branches/meklort/i386/libsaio/memvendors.h
410410
411411
412412
413
413
414414
415415
416416
......
645645
646646
647647
648
648
649649
650650
651651
{ 3, 0x10, "Agere Systems"},
{ 3, 0x91, "NeoMagic"},
{ 3, 0x92, "AuroraNetics"},
{ 3, 0x13, "Golden Empire"},
{ 3, 0x13, "Geil"},
{ 3, 0x94, "Mushkin"},
{ 3, 0x15, "Tioga Technologies"},
{ 3, 0x16, "Netlist"},
{ 4, 0xfd, "Focus Enhancements"},
{ 4, 0xfe, "Xyratex"},
{ 5, 0x01, "Specular Networks"},
{ 5, 0x02, "Patriot Memory (PDP Systems)"},
{ 5, 0x02, "PDP Systems"},
{ 5, 0x83, "U-Chip Technology Corp."},
{ 5, 0x04, "Silicon Optix"},
{ 5, 0x85, "Greenfield Networks"},
branches/meklort/i386/libsaio/usb.c
6666
6767
6868
69
69
7070
71
72
7371
7472
75
73
7674
7775
7876
......
8179
8280
8381
84
8582
8683
87
84
8885
8986
9087
......
9895
9996
10097
98
10199
102100
103101
......
200198
201199
202200
203
204
205201
206202
207203
{
int retVal = 1;
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy = true;
fix_ehci = fix_uhci = fix_usb = fix_legacy = false;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig))
{
fix_ehci = fix_uhci = fix_legacy = fix_usb;// Enable all if none set
fix_ehci = fix_uhci = fix_legacy = fix_usb;// Disable all if none set
}
else
{
getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig);
}
struct pciList* current = usbList;
while(current && current->next)
while(current)
{
switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG))
{
// UHCI
case 0x00:
if (fix_uhci) retVal &= uhci_reset(current->pciDev);
break;
}
return 1;
}
int ehci_acquire (pci_dt_t *pci_dev)
{
intj, k;
branches/meklort/i386/libsaio/dram_controllers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
/*
* dram controller access and scan from the pci host controller
* Integrated and adapted for chameleon 2.0 RC5 by Rekursor from bs0d work
* original source comes from:
*
* memtest86
*
* Released under version 2 of the Gnu Public License.
* By Chris Brady, cbrady@sgi.com
* ----------------------------------------------------
* MemTest86+ V4.00 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.canardpc.com - http://www.memtest.org
*/
#include "libsaio.h"
#include "bootstruct.h"
#include "pci.h"
#include "platform.h"
#include "dram_controllers.h"
#ifndef DEBUG_DRAM
#define DEBUG_DRAM 0
#endif
#if DEBUG_DRAM
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
/*
* Initialise memory controller functions
*/
// Setup P35 Memory Controller
static void setup_p35(pci_dt_t *dram_dev)
{
uint32_t dev0;
// Activate MMR I/O
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
if (!(dev0 & 0x1))
pci_config_write8(dram_dev->dev.addr, 0x48, (dev0 | 1));
}
int nhm_bus = 0x3F;
// Setup Nehalem Integrated Memory Controller
static void setup_nhm(pci_dt_t *dram_dev)
{
static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};
unsigned long did, vid;
int i;
// Nehalem supports Scrubbing
// First, locate the PCI bus where the MCH is located
for(i = 0; i < sizeof(possible_nhm_bus); i++)
{
vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);
did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);
vid &= 0xFFFF;
did &= 0xFF00;
if(vid == 0x8086 && did >= 0x2C00)
nhm_bus = possible_nhm_bus[i];
}
}
/*
* Retrieve memory controller fsb functions
*/
// Get i965 Memory Speed
static void get_fsb_i965(pci_dt_t *dram_dev)
{
uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;
long *ptr;
// Find Ratio
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0xC00);
mch_cfg = *ptr & 0xFFFF;
mch_ratio = 100000;
switch (mch_cfg & 7)
{
case 0: mch_fsb = 1066; break;
case 1: mch_fsb = 533; break;
default:
case 2: mch_fsb = 800; break;
case 3: mch_fsb = 667; break;
case 4: mch_fsb = 1333; break;
case 6: mch_fsb = 1600; break;
}
DBG("mch_fsb %d\n", mch_fsb);
switch (mch_fsb)
{
case 533:
switch ((mch_cfg >> 4) & 7)
{
case 1:mch_ratio = 200000; break;
case 2:mch_ratio = 250000; break;
case 3:mch_ratio = 300000; break;
}
break;
default:
case 800:
switch ((mch_cfg >> 4) & 7)
{
case 0:mch_ratio = 100000; break;
case 1:mch_ratio = 125000; break;
case 2:mch_ratio = 166667; break; // 1.666666667
case 3:mch_ratio = 200000; break;
case 4:mch_ratio = 266667; break; // 2.666666667
case 5:mch_ratio = 333333; break; // 3.333333333
}
break;
case 1066:
switch ((mch_cfg >> 4) & 7)
{
case 1:mch_ratio = 100000; break;
case 2:mch_ratio = 125000; break;
case 3:mch_ratio = 150000; break;
case 4:mch_ratio = 200000; break;
case 5:mch_ratio = 250000; break;
}
break;
case 1333:
switch ((mch_cfg >> 4) & 7)
{
case 2:mch_ratio = 100000; break;
case 3:mch_ratio = 120000; break;
case 4:mch_ratio = 160000; break;
case 5:mch_ratio = 200000; break;
}
break;
case 1600:
switch ((mch_cfg >> 4) & 7)
{
case 3:mch_ratio = 100000; break;
case 4:mch_ratio = 133333; break; // 1.333333333
case 5:mch_ratio = 150000; break;
case 6:mch_ratio = 200000; break;
}
break;
}
DBG("mch_ratio %d\n", mch_ratio);
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
DBG("ram_fsb %d\n", Platform.RAM.Frequency);
}
// Get i965m Memory Speed
static void get_fsb_im965(pci_dt_t *dram_dev)
{
uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;
long *ptr;
// Find Ratio
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0xC00);
mch_cfg = *ptr & 0xFFFF;
mch_ratio = 100000;
switch (mch_cfg & 7)
{
case 1: mch_fsb = 533; break;
default:
case 2:mch_fsb = 800; break;
case 3:mch_fsb = 667; break;
case 6:mch_fsb = 1066; break;
}
switch (mch_fsb)
{
case 533:
switch ((mch_cfg >> 4) & 7)
{
case 1:mch_ratio = 125000; break;
case 2:mch_ratio = 150000; break;
case 3:mch_ratio = 200000; break;
}
break;
case 667:
switch ((mch_cfg >> 4)& 7)
{
case 1:mch_ratio = 100000; break;
case 2:mch_ratio = 120000; break;
case 3:mch_ratio = 160000; break;
case 4:mch_ratio = 200000; break;
case 5:mch_ratio = 240000; break;
}
break;
default:
case 800:
switch ((mch_cfg >> 4) & 7)
{
case 1:mch_ratio = 83333; break; // 0.833333333
case 2:mch_ratio = 100000; break;
case 3:mch_ratio = 133333; break; // 1.333333333
case 4:mch_ratio = 166667; break; // 1.666666667
case 5:mch_ratio = 200000; break;
}
break;
case 1066:
switch ((mch_cfg >> 4)&7) {
case 5:mch_ratio = 150000; break;
case 6:mch_ratio = 200000; break;
}
}
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
}
// Get iCore7 Memory Speed
static void get_fsb_nhm(pci_dt_t *dram_dev)
{
uint32_t mch_ratio, mc_dimm_clk_ratio;
// Get the clock ratio
mc_dimm_clk_ratio = pci_config_read16(PCIADDR(nhm_bus, 3, 4), 0x54 );
mch_ratio = (mc_dimm_clk_ratio & 0x1F);
// Compute RAM Frequency
Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2;
}
/*
* Retrieve memory controller info functions
*/
// Get i965 Memory Timings
static void get_timings_i965(pci_dt_t *dram_dev)
{
// Thanks for CDH optis
uint32_t dev0, c0ckectrl, c1ckectrl, offset;
uint32_t ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;
long *ptr;
// Read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x260);
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x660);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);
ptr = (long*)(dev0 + offset + 0x29C);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x250);
Precharge_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x252);
ACT_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x258);
Read_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x244);
Misc_Register = *ptr & 0xFFFFFFFF;
// 965 Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 16) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 11) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get im965 Memory Timings
static void get_timings_im965(pci_dt_t *dram_dev)
{
// Thanks for CDH optis
uint32_t dev0, c0ckectrl, c1ckectrl, offset, ODT_Control_Register, Precharge_Register;
long *ptr;
// Read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x1200);
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x1300);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x100);
ptr = (long*)(dev0 + offset + 0x121C);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x1214);
Precharge_Register = *ptr & 0xFFFFFFFF;
// Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = ((Precharge_Register >> 5) & 7) + 2;
// RAS Precharge (tRP)
Platform.RAM.TRP= (Precharge_Register & 7) + 2;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 21) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get P35 Memory Timings
static void get_timings_p35(pci_dt_t *dram_dev)
{
// Thanks for CDH optis
unsigned long dev0, Memory_Check, c0ckectrl, c1ckectrl, offset;
unsigned long ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;
long *ptr;
//Device_ID = pci_config_read16(dram_dev->dev.addr, 0x02);
//Device_ID &= 0xFFFF;
// Now, read MMR Base Address
dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);
dev0 &= 0xFFFFC000;
ptr = (long*)(dev0 + 0x260);
c0ckectrl = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + 0x660);
c1ckectrl = *ptr & 0xFFFFFFFF;
// If DIMM 0 not populated, check DIMM 1
((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);
ptr = (long*)(dev0 + offset + 0x265);
ODT_Control_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x25D);
Precharge_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x252);
ACT_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x258);
Read_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x244);
Misc_Register = *ptr & 0xFFFFFFFF;
ptr = (long*)(dev0 + offset + 0x1E8);
Memory_Check = *ptr & 0xFFFFFFFF;
// On P45, check 1A8
if(dram_dev->device_id > 0x2E00) {
ptr = (long*)(dev0 + offset + 0x1A8);
Memory_Check = *ptr & 0xFFFFFFFF;
Memory_Check >>= 2;
Memory_Check &= 1;
Memory_Check = !Memory_Check;
} else {
ptr = (long*)(dev0 + offset + 0x1E8);
Memory_Check = *ptr & 0xFFFFFFFF;
}
// Determine DDR-II or DDR-III
if (Memory_Check & 1)
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
else
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
// CAS Latency (tCAS)
if(dram_dev->device_id > 0x2E00)
Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 6;
else
Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 17) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = Precharge_Register & 0x3F;
// Channel configuration
if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get Nehalem Memory Timings
static void get_timings_nhm(pci_dt_t *dram_dev)
{
unsigned long mc_channel_bank_timing, mc_control, mc_channel_mrs_value;
int fvc_bn = 4;
// Find which channels are populated
mc_control = pci_config_read16(PCIADDR(nhm_bus, 3, 0), 0x48);
mc_control = (mc_control >> 8) & 0x7;
// DDR-III
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
// Get the first valid channel
if(mc_control & 1)
fvc_bn = 4;
else if(mc_control & 2)
fvc_bn = 5;
else if(mc_control & 7)
fvc_bn = 6;
// Now, detect timings
mc_channel_bank_timing = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x88);
mc_channel_mrs_value = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x70);
// CAS Latency (tCAS)
Platform.RAM.CAS = ((mc_channel_mrs_value >> 4) & 0xF ) + 4;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.CAS = (mc_channel_bank_timing >> 4) & 0x1F;
// RAS Active to precharge (tRAS)
Platform.RAM.TRP = mc_channel_bank_timing & 0xF;
// Single , Dual or Triple Channels
if (mc_control == 1 || mc_control == 2 || mc_control == 4 )
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
else if (mc_control == 7)
Platform.RAM.Channels = SMB_MEM_CHANNEL_TRIPLE;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
}
static struct mem_controller_t dram_controllers[] = {
// Default unknown chipset
{ 0, 0, "",NULL, NULL, NULL },
// Intel
{ 0x8086, 0x7190, "VMWare",NULL, NULL, NULL },
{ 0x8086, 0x1A30, "i845",NULL, NULL, NULL },
{ 0x8086, 0x2970, "i946PL/GZ",setup_p35, get_fsb_i965, get_timings_i965 },
{ 0x8086, 0x2990, "Q963/Q965",setup_p35, get_fsb_i965, get_timings_i965 },
{ 0x8086, 0x29A0, "P965/G965",setup_p35, get_fsb_i965, get_timings_i965 },
{ 0x8086, 0x2A00, "GM965/GL960",setup_p35, get_fsb_im965, get_timings_im965 },
{ 0x8086, 0x2A10, "GME965/GLE960",setup_p35, get_fsb_im965, get_timings_im965 },
{ 0x8086, 0x2A40, "PM/GM45/47",setup_p35, get_fsb_im965, get_timings_im965 },
{ 0x8086, 0x29B0, "Q35",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x29C0, "P35/G33",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x29D0, "Q33",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x29E0, "X38/X48",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x2E00, "Eaglelake",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x2E10, "Q45/Q43",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x2E20, "P45/G45",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0x2E30, "G41",setup_p35, get_fsb_i965, get_timings_p35 },
{ 0x8086, 0xD131, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0xD132, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3400, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3401, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3402, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3403, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3404, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3405, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3406, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
{ 0x8086, 0x3407, "NHM IMC",setup_nhm, get_fsb_nhm, get_timings_nhm },
};
static const char *memory_channel_types[] =
{
"Unknown", "Single", "Dual", "Triple"
};
void scan_dram_controller(pci_dt_t *dram_dev)
{
int i;
for(i = 1; i < sizeof(dram_controllers) / sizeof(dram_controllers[0]); i++)
if ((dram_controllers[i].vendor == dram_dev->vendor_id)
&& (dram_controllers[i].device == dram_dev->device_id))
{
verbose("%s%s DRAM Controller [%4x:%4x] at %02x:%02x.%x\n",
(dram_dev->vendor_id == 0x8086) ? "Intel " : "" ,
dram_controllers[i].name, dram_dev->vendor_id, dram_dev->device_id,
dram_dev->dev.bits.bus, dram_dev->dev.bits.dev, dram_dev->dev.bits.func);
if (dram_controllers[i].initialise != NULL)
dram_controllers[i].initialise(dram_dev);
if (dram_controllers[i].poll_timings != NULL)
dram_controllers[i].poll_timings(dram_dev);
if (dram_controllers[i].poll_speed != NULL)
dram_controllers[i].poll_speed(dram_dev);
verbose("Frequency detected: %d MHz (%d) %s Channel %d-%d-%d-%d\n",
(uint32_t)Platform.RAM.Frequency / 1000000,
(uint32_t)Platform.RAM.Frequency / 500000,
memory_channel_types[Platform.RAM.Channels],
Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS
);
}
}
branches/meklort/i386/libsaio/ntfs.c
295295
296296
297297
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
298333
299334
300335
......
307342
308343
309344
310
311
return;
}
long NTFSGetUUID(CICell ih, char *uuidStr)
{
bool NTFSProbe(const void*);
struct bootfile *boot;
void *buf = malloc(MAX_BLOCK_SIZE);
if ( !buf )
return -1;
/*
* Read the boot sector, check signatures, and do some minimal
* sanity checking. NOTE: the size of the read below is intended
* to be a multiple of all supported block sizes, so we don't
* have to determine or change the device's block size.
*/
Seek(ih, 0);
Read(ih, (long)buf, MAX_BLOCK_SIZE);
boot = (struct bootfile *) buf;
// Check for NTFS signature
if ( memcmp((void*)boot->bf_sysid, NTFS_BBID, NTFS_BBIDLEN) != 0 )
return -1;
// Check for non-null volume serial number
if( !boot->bf_volsn )
return -1;
// Use UUID like the one you get on Windows
sprintf(uuidStr, "%04X-%04X",(unsigned short)(boot->bf_volsn >> 16) & 0xFFFF,
(unsigned short)boot->bf_volsn & 0xFFFF);
return 0;
}
bool NTFSProbe(const void * buffer)
{
bool result = false;
return result;
}
branches/meklort/i386/libsaio/nvidia.c
267267
268268
269269
270
270271
271272
272273
273274
274
275
275276
276277
277278
......
290291
291292
292293
293
294
294295
295296
296297
......
322323
323324
324325
326
327
328
329
325330
326331
327332
......
336341
337342
338343
339
340
344
345
346
341347
342348
349
343350
344351
345352
......
351358
352359
353360
354
361
362
363
364
365
366
367
368
355369
356370
357371
......
650664
651665
652666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
653689
654690
655691
656
692
657693
658
694
659695
660696
661
697
698
662699
663700
664701
665
666
702
703
667704
668705
669706
......
674711
675712
676713
714
715
716
717
718
677719
678720
679
721
680722
681
723
682724
683
684
685
725
726
727
686728
687729
688730
......
768810
769811
770812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
771847
772
773
774
775848
776849
777850
{ 0x10DE05E2, "GeForce GTX 260" },
{ 0x10DE05E3, "GeForce GTX 285" },
{ 0x10DE05E6, "GeForce GTX 275" },
{ 0x10DE05EA, "GeForce GTX 260" },
{ 0x10DE05EB, "GeForce GTX 295" },
{ 0x10DE05F9, "Quadro CX" },
{ 0x10DE05FD, "Quadro FX 5800" },
{ 0x10DE05FE, "Quadro FX 4800" },
{ 0x10DE0600, "GeForce 8800 GTS 512" },
{ 0x10DE0600, "GeForce 8800 GTS 512" },
{ 0x10DE0602, "GeForce 8800 GT" },
{ 0x10DE0604, "GeForce 9800 GX2" },
{ 0x10DE0605, "GeForce 9800 GT" },
{ 0x10DE0614, "GeForce 9800 GT" },
{ 0x10DE0615, "GeForce GTS 250" },
{ 0x10DE0617, "GeForce 9800M GTX" },
{ 0x10DE0618, "GeForce GTX 260M" },
{ 0x10DE0618, "GeForce GTX 260M" },
{ 0x10DE061A, "Quadro FX 3700" },
{ 0x10DE061C, "Quadro FX 3600M" },
{ 0x10DE061D, "Quadro FX 2800M" },
{ 0x10DE065A, "Quadro FX 1700M" },
{ 0x10DE065B, "GeForce 9400 GT" },
{ 0x10DE065C, "Quadro FX 770M" },
{ 0x10DE06C0, "GeForce GTX 480" },
{ 0x10DE06C4, "GeForce GTX 465" },
{ 0x10DE06CA, "GeForce GTX 480M" },
{ 0x10DE06CD, "GeForce GTX 470" },
{ 0x10DE06E0, "GeForce 9300 GE" },
{ 0x10DE06E1, "GeForce 9300 GS" },
{ 0x10DE06E4, "GeForce 8400 GS" },
{ 0x10DE06F9, "Quadro FX 370 LP" },
{ 0x10DE06FA, "Quadro NVS 450" },
{ 0x10DE06FD, "Quadro NVS 295" },
{ 0x10DE087D, "ION 9400M" },
{ 0x10DE087E, "ION LE" },
{ 0x10DE086C, "GeForce 9300/nForce 730i" },
{ 0x10DE087D, "ION 9400M" },
{ 0x10DE087E, "ION LE" },
{ 0x10DE0A20, "GeForce GT220" },
{ 0x10DE0A23, "GeForce 210" },
{ 0x10DE0A28, "GeForce GT 230M" },
{ 0x10DE0A2A, "GeForce GT 230M" },
{ 0x10DE0A34, "GeForce GT 240M" },
{ 0x10DE0A60, "GeForce G210" },
{ 0x10DE0A78, "Quadro FX 380 LP" },
{ 0x10DE0CA3, "GeForce GT 240" },
{ 0x10DE0CA8, "GeForce GTS 260M" },
{ 0x10DE0CA9, "GeForce GTS 250M" }
{ 0x10DE0CA9, "GeForce GTS 250M" },
{ 0x10DE0CA3, "GeForce GT240" },
{ 0x10DE0E22, "GeForce GTX 460" },
{ 0x10DE0E24, "GeForce GTX 460" },
{ 0x10DE06D1, "Tesla C2050" },// TODO: sub-device id: 0x0771
{ 0x10DE06D1, "Tesla C2070" },// TODO: sub-device id: 0x0772
{ 0x10DE06DE, "Tesla M2050" },// TODO: sub-device id: 0x0846
{ 0x10DE06DE, "Tesla M2070" }// TODO: sub-device id: ?
};
static uint16_t swap16(uint16_t x)
return 0;
}
unsigned long long mem_detect(volatile uint8_t *regs, uint8_t nvCardType, pci_dt_t *nvda_dev)
{
unsigned long long vram_size = 0;
if (nvCardType < NV_ARCH_50) {
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
}
else if (nvCardType >= NV_ARCH_C0) {
vram_size = REG32(NVC0_MEM_CTRLR_COUNT);
vram_size *= REG32(NVC0_MEM_CTRLR_RAM_AMOUNT);
vram_size <<= 20;
}
else {
vram_size = REG32(NV04_PFB_FIFO_DATA);
vram_size |= (vram_size & 0xff) << 32;
vram_size &= 0xffffffff00ll;
}
return vram_size;
}
bool setup_nvidia_devprop(pci_dt_t *nvda_dev)
{
struct DevPropDevice*device;
char*devicepath;
char*devicepath;
struct pci_rom_pci_header_t*rom_pci_header;
volatile uint8_t*regs;
volatile uint8_t*regs;
uint8_t*rom;
uint8_t*nvRom;
uint32_tvideoRam;
uint8_tnvCardType;
unsigned long longvideoRam;
uint32_tnvBiosOveride;
uint32_tbar[7];
uint32_tboot_display;
intnvPatch;
intlen;
intnvPatch;
intlen;
charbiosVersion[32];
charnvFilename[32];
charkNVCAP[12];
devicepath = get_pci_dev_path(nvda_dev);
bar[0] = pci_config_read32(nvda_dev->dev.addr, 0x10 );
regs = (uint8_t *) (bar[0] & ~0x0f);
delay(50);
// get card type
nvCardType = (REG32(0) >> 20) & 0x1ff;
// Amount of VRAM in kilobytes
videoRam = (REG32(0x10020c) & 0xfff00000) >> 10;
videoRam = mem_detect(regs, nvCardType, nvda_dev);
model = get_nvidia_model((nvda_dev->vendor_id << 16) | nvda_dev->device_id);
verbose("nVidia %s %dMB NV%02x [%04x:%04x] :: %s\n",
model, (videoRam / 1024),
(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
devicepath);
model, (uint32_t)(videoRam / 1024 / 1024),
(REG32(0) >> 20) & 0x1ff, nvda_dev->vendor_id, nvda_dev->device_id,
devicepath);
rom = malloc(NVIDIA_ROM_SIZE);
sprintf(nvFilename, "/Extra/%04x_%04x.rom", (uint16_t)nvda_dev->vendor_id, (uint16_t)nvda_dev->device_id);
uint8_t built_in = 0x01;
devprop_add_value(device, "@0,built-in", &built_in, 1);
}
// get bios version
const int MAX_BIOS_VERSION_LENGTH = 32;
char* version_str = (char*)malloc(MAX_BIOS_VERSION_LENGTH);
memset(version_str, 0, MAX_BIOS_VERSION_LENGTH);
int i, version_start;
int crlf_count = 0;
// only search the first 384 bytes
for(i = 0; i < 0x180; i++) {
if(rom[i] == 0x0D && rom[i+1] == 0x0A) {
crlf_count++;
// second 0x0D0A was found, extract bios version
if(crlf_count == 2) {
if(rom[i-1] == 0x20) i--; // strip last " "
for(version_start = i; version_start > (i-MAX_BIOS_VERSION_LENGTH); version_start--) {
// find start
if(rom[version_start] == 0x00) {
version_start++;
// strip "Version "
if(strncmp((const char*)rom+version_start, "Version ", 8) == 0) {
version_start += 8;
}
strncpy(version_str, (const char*)rom+version_start, i-version_start);
break;
}
}
break;
}
}
}
sprintf(biosVersion, "%s", (nvBiosOveride > 0) ? nvFilename : version_str);
videoRam *= 1024;
sprintf(biosVersion, "xx.xx.xx - %s", (nvBiosOveride > 0) ? nvFilename : "internal");
sprintf(kNVCAP, "NVCAP_%04x", nvda_dev->device_id);
if (getValueForKey(kNVCAP, &value, &len, &bootInfo->bootConfig) && len == NVCAP_LEN * 2) {
uint8_tnew_NVCAP[NVCAP_LEN];
branches/meklort/i386/libsaio/sys.c
6363
6464
6565
66
6667
68
6769
6870
6971
......
8789
8890
8991
92
9093
9194
92
93
94
95
95
96
9697
9798
9899
99100
100101
102
103
104
105
106
107
101108
102109
103110
......
111118
112119
113120
114
115
116
117
118121
119122
120123
......
294297
295298
296299
297
300
298301
299302
300303
......
322325
323326
324327
325
328
326329
327330
328331
......
403406
404407
405408
406
407409
408410
409411
......
425427
426428
427429
428
429430
430431
431432
......
516517
517518
518519
519
520
521
522
523
524
525
526
527
528
529
520
530521
531522
532523
......
602593
603594
604595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
605652
606653
607654
......
762809
763810
764811
765
812
766813
767
814
768815
769816
770817
......
774821
775822
776823
777
824
778825
779826
780827
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
828
829
830
831
832
833
834
835
836
797837
798
799
838
800839
801840
802841
803842
804843
805844
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
825864
826865
827866
......
832871
833872
834873
835
836
837
838
839
840
874
875
876
877
878
879
841880
842881
843882
......
957996
958997
959998
999
9601000
961
962
963
964
965
966
967
968
969
970
971
972
973
974
9751001
9761002
9771003
......
9941020
9951021
9961022
997
9981023
9991024
10001025
10011026
1002
1027
10031028
1004
1029
10051030
1006
1007
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
10081047
1009
1048
1049
10101050
1011
1012
1013
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
10141073
1015
1016
1017
1074
10181075
1019
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
10201088
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "disk.h"
#include "ramdisk.h"
#include "xml.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
# include <Kernel/libkern/crypto/md5.h>
#else
int type;
};
// Device entries must be ordered by bios device numbers.
static struct devsw devsw[] =
{
{ "sd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_SD */
{ "hd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_HD */
{ "fd", 0x00, kBIOSDevTypeFloppy }, /* DEV_FD */
{ "en", 0xE0, kBIOSDevTypeNetwork }, /* DEV_EN */
{ "hd", 0x80, kBIOSDevTypeHardDrive }, /* DEV_HD */
{ "en", 0xE0, kBIOSDevTypeNetwork }, /* DEV_EN */
{ "rd", 0x100, kBIOSDevTypeHardDrive },
{ "bt", 0x101, kBIOSDevTypeHardDrive }, // turbo - type for booter partition
{ 0, 0 }
};
// Pseudo BIOS devices
enum {
kPseudoBIOSDevRAMDisk = 0x100,
kPseudoBIOSDevBooter = 0x101
};
/*
* Max number of file descriptors.
*/
BVRef gBIOSBootVolume = NULL;
BVRef gBootVolume;
// zef - ramdisk variables
//extern BVRef gRAMDiskVolume;
//extern bool gRAMDiskBTAliased;
//static BVRef getBootVolumeRef( const char * path, const char ** outPath );
static BVRef newBootVolumeRef( int biosdev, int partno );
// GetDirEntry - LOW-LEVEL FILESYSTEM FUNCTION.
// Fetch the next directory entry for the given directory.
long GetDirEntry(const char * dirSpec, long * dirIndex, const char ** name,
long GetDirEntry(const char * dirSpec, long long * dirIndex, const char ** name,
long * flags, long * time)
{
const char * dirPath;
long GetFileInfo(const char * dirSpec, const char * name,
long * flags, long * time)
{
long index = 0;
long long index = 0;
const char * entryName;
if (gMakeDirSpec == 0)
return io;
}
#if UNUSED
//==========================================================================
// openmem()
return fdesc;
}
#endif
//==========================================================================
// open() - Open the file specified by 'path' for reading.
}
}
}
// turbo - bt(0,0) hook
if ((dp->biosdev + unit) == 0x101) {
// zef - use the ramdisk if available and the alias is active.
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased) {
bvr = gRAMDiskVolume;
} else {
bvr = gBIOSBootVolume;
}
} else {
bvr = newBootVolumeRef(dp->biosdev + unit, partition);
}
bvr = newBootVolumeRef(dp->biosdev + unit, partition);
return open_bvr(bvr, path, flags);
}
}
}
//==========================================================================
// write() - Write up to 'count' bytes of data to the file descriptor
// from the buffer pointed to by buf.
int write(int fdesc, const char * buf, int count)
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
if ((io->i_offset + count) > (unsigned int)io->i_filesize)
count = io->i_filesize - io->i_offset;
if (count <= 0)
return 0; // end of file
bcopy(buf, io->i_buf + io->i_offset, count);
io->i_offset += count;
return count;
}
int writebyte(int fdesc, char value)
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
if ((io->i_offset + 1) > (unsigned int)io->i_filesize)
return 0; // end of file
io->i_buf[io->i_offset++] = value;
return 1;
}
int writeint(int fdesc, int value)
{
struct iob * io;
if ((io = iob_from_fdesc(fdesc)) == NULL)
return (-1);
if ((io->i_offset + 4) > (unsigned int)io->i_filesize)
return 0; // end of file
bcopy(&value, io->i_buf + io->i_offset, 4);
io->i_offset += 4;
return 4;
}
//==========================================================================
// file_size() - Returns the size of the file described by the file
// descriptor.
BVRef selectBootVolume( BVRef chain )
{
bool filteredChain = false;
bool filteredChain = false;
bool foundPrimary = false;
BVRef bvr, bvr1 = 0, bvr2 = 0;
BVRef bvr, bvr1 = 0, bvr2 = 0;
if (chain->filtered) filteredChain = true;
return bvr;
/*
* Checking "Default Partition" key in system configuration - use format: hd(x,y) -
* Checking "Default Partition" key in system configuration - use format: hd(x,y), the volume UUID or label -
* to override the default selection.
* We accept only kBVFlagSystemVolume or kBVFlagForeignBoot volumes.
*/
const char * val;
char testStr[64];
int cnt;
if (getValueForKey(kDefaultPartition, &val, &cnt, &bootInfo->bootConfig) && cnt >= 7 && filteredChain)
{
for ( bvr = chain; bvr; bvr = bvr->next )
{
*testStr = '\0';
if ( bvr->biosdev >= 0x80 && bvr->biosdev < 0x100
&& ( bvr->flags & ( kBVFlagSystemVolume|kBVFlagForeignBoot ) ) )
{
sprintf(testStr, "hd(%d,%d)", bvr->biosdev - 0x80, bvr->part_no);
if (strcmp(testStr, val) == 0)
return bvr;
}
char *val = XMLDecode(getStringForKey(kDefaultPartition, &bootInfo->bootConfig));
if (val) {
for ( bvr = chain; bvr; bvr = bvr->next ) {
if (matchVolumeToString(bvr, val, false)) {
free(val);
return bvr;
}
}
free(val);
}
}
/*
* Scannig the volume chain backwards and trying to find
* a HFS+ volume with valid boot record signature.
* If not found any active partition then we will
* select this volume as the boot volume.
*/
for ( bvr = chain; bvr; bvr = bvr->next )
{
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) foundPrimary = true;
// zhell -- Undo a regression that was introduced from r491 to 492.
// if gBIOSBootVolume is set already, no change is required
if ( bvr->flags & (kBVFlagBootable|kBVFlagSystemVolume)
&& gBIOSBootVolume
&& (!filteredChain || (filteredChain && bvr->visible))
&& bvr->biosdev == gBIOSDev )
bvr2 = bvr;
// zhell -- if gBIOSBootVolume is NOT set, we use the "if" statement
// from r491,
if ( bvr->flags & kBVFlagBootable
&& ! gBIOSBootVolume
&& bvr->biosdev == gBIOSDev )
bvr2 = bvr;
}
for ( bvr = chain; bvr; bvr = bvr->next )
{
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) foundPrimary = true;
// zhell -- Undo a regression that was introduced from r491 to 492.
// if gBIOSBootVolume is set already, no change is required
if ( bvr->flags & (kBVFlagBootable|kBVFlagSystemVolume)
&& gBIOSBootVolume
&& (!filteredChain || (filteredChain && bvr->visible))
&& bvr->biosdev == gBIOSDev )
bvr2 = bvr;
// zhell -- if gBIOSBootVolume is NOT set, we use the "if" statement
// from r491,
if ( bvr->flags & kBVFlagBootable
&& ! gBIOSBootVolume
&& bvr->biosdev == gBIOSDev )
bvr2 = bvr;
}
/*
* Use the standrad method for selecting the boot volume.
*/
if ( bvr->flags & kBVFlagNativeBoot && bvr->biosdev == gBIOSDev ) bvr1 = bvr;
if ( bvr->flags & kBVFlagPrimary && bvr->biosdev == gBIOSDev ) bvr2 = bvr;
}
}
bvr = bvr2 ? bvr2 :
bvr1 ? bvr1 : chain;
return bvr;
}
bvr = bvr2 ? bvr2 :
bvr1 ? bvr1 : chain;
return bvr;
}
//==========================================================================
if (*cp == RP) cp++;
biosdev = dp->biosdev + unit;
bvr = newBootVolumeRef(biosdev, part);
// turbo - bt(0,0) hook
if (biosdev == 0x101)
{
// zef - use the ramdisk if available and the alias is active.
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased)
bvr = gRAMDiskVolume;
else
bvr = gBIOSBootVolume;
}
else
{
bvr = newBootVolumeRef(biosdev, part);
}
if(bvr == NULL)
return NULL;
}
}
//==========================================================================
// Function name is a misnomer as scanBootVolumes usually calls diskScanBootVolumes
// which caches the information. So it's only allocated on the first run.
static BVRef newBootVolumeRef( int biosdev, int partno )
{
BVRef bvr, bvr1, bvrChain;
BVRef bvr, bvr1, bvrChain;
// Fetch the volume list from the device.
bvr = bvr1 = NULL;
scanBootVolumes( biosdev, NULL );
bvrChain = getBVChainForBIOSDev(biosdev);
// Try resolving "rd" and "bt" devices first.
if (biosdev == kPseudoBIOSDevRAMDisk)
{
if (gRAMDiskVolume)
bvr1 = gRAMDiskVolume;
}
else if (biosdev == kPseudoBIOSDevBooter)
{
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased)
bvr1 = gRAMDiskVolume;
else
bvr1 = gBIOSBootVolume;
}
else
{
// Fetch the volume list from the device.
// Look for a perfect match based on device and partition number.
scanBootVolumes( biosdev, NULL );
bvrChain = getBVChainForBIOSDev(biosdev);
for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next )
{
if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) continue;
// Look for a perfect match based on device and partition number.
for ( bvr1 = NULL, bvr = bvrChain; bvr; bvr = bvr->next )
{
if ( ( bvr->flags & kBVFlagNativeBoot ) == 0 ) continue;
bvr1 = bvr;
if ( bvr->part_no == partno ) break;
}
}
return bvr ? bvr : bvr1;
}
//==========================================================================
// getDeviceDescription() - Extracts unit number and partition number
// from bvr structure into "dw(u,p)" format.
// Returns length of the out string
int getDeviceDescription(BVRef bvr, char *str)
{
if(!str)
return 0;
bvr1 = bvr;
if ( bvr->part_no == partno ) break;
}
*str = '\0';
return bvr ? bvr : bvr1;
if (bvr)
{
const struct devsw *dp = devsw;
while(dp->name && bvr->biosdev >= dp->biosdev)
dp++;
dp--;
if (dp->name)
return sprintf(str, "%s(%d,%d)", dp->name, bvr->biosdev - dp->biosdev, bvr->part_no);
}
return 0;
}
branches/meklort/i386/libsaio/dram_controllers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
* dram controller access and scan from the pci host controller
* Integrated and adapted for chameleon 2.0 RC5 by Rekursor from bs0d work
* original source comes from:
*
* memtest86
*
* Released under version 2 of the Gnu Public License.
* By Chris Brady, cbrady@sgi.com
* ----------------------------------------------------
* MemTest86+ V4.00 Specific code (GPL V2.0)
* By Samuel DEMEULEMEESTER, sdemeule@memtest.org
* http://www.canardpc.com - http://www.memtest.org
*/
#ifndef __LIBSAIO_DRAM_CONTROLLERS_H
#define __LIBSAIO_DRAM_CONTROLLERS_H
#include "libsaio.h"
void scan_dram_controller();
struct mem_controller_t {
uint16_t vendor;
uint16_t device;
char *name;
void (*initialise)(pci_dt_t *dram_dev);
void (*poll_speed)(pci_dt_t *dram_dev);
void (*poll_timings)(pci_dt_t *dram_dev);
};
#endif /* !__LIBSAIO_DRAM_CONTROLLERS_H */
branches/meklort/i386/libsaio/nbp.c
9696
9797
9898
99
99
100100
101101
102102
/*==========================================================================
* GetDirEntry is not supported.
*/
static long NBPGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
static long NBPGetDirEntry(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
{
branches/meklort/i386/libsaio/ntfs.h
2222
2323
2424
25
25
extern void NTFSGetDescription(CICell ih, char *str, long strMaxLen);
extern bool NTFSProbe (const void *buf);
extern long NTFSGetUUID(CICell ih, char *uuidStr);
branches/meklort/i386/libsaio/nvidia.h
6767
6868
6969
70
71
72
73
70
71
72
73
74
75
76
77
78
7479
7580
7681
......
8792
8893
8994
95
9096
9197
9298
uint8_tsize;/* Size in multiples of 512 */
};
#define NV_PROM_OFFSET0x300000
#define NV_PROM_SIZE0x0000ffff
#define NV_PRAMIN_OFFSET0x00700000
#define NV_PRAMIN_SIZE0x00100000
#define NV_PROM_OFFSET0x300000
#define NV_PROM_SIZE0x0000ffff
#define NV_PRAMIN_OFFSET0x00700000
#define NV_PRAMIN_SIZE0x00100000
#define NV04_PFB_FIFO_DATA0x0010020c
#define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK0xfff00000
#define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT20
#define NVC0_MEM_CTRLR_COUNT0x00121c74
#define NVC0_MEM_CTRLR_RAM_AMOUNT0x0010f20c
#define NV_PBUS_PCI_NV_200x00001850
#define NV_PBUS_PCI_NV_20_ROM_SHADOW_DISABLED(0 << 0)
#define NV_ARCH_30 0x30
#define NV_ARCH_40 0x40
#define NV_ARCH_50 0x50
#define NV_ARCH_C0 0xC0
#define CHIPSET_NV03 0x0010
#define CHIPSET_NV04 0x0020
branches/meklort/i386/libsaio/acpi.h
5959
6060
6161
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
6288
6389
6490
......
7399
74100
75101
76
77
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
78135
79136
80137
......
93150
94151
95152
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110153
} __attribute__((packed));
// TODO Migrate
struct acpi_2_ssdt {
char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t Checksum;
char OEMID[6];
char OEMTableId[8];
uint32_t OEMRevision;
uint32_t CreatorId;
uint32_t CreatorRevision;
} __attribute__((packed));
// TODO Migrate
struct acpi_2_dsdt {
char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t Checksum;
char OEMID[6];
char OEMTableId[8];
uint32_t OEMRevision;
uint32_t CreatorId;
uint32_t CreatorRevision;
} __attribute__((packed));
// TODO Migrate
struct acpi_2_fadt {
char Signature[4];
uint32_t Length;
uint32_t DSDT;
uint8_t Model;// JrCs
uint8_t PM_Profile;// JrCs
/*We absolutely don't care about theese fields*/
uint8_t notimp1[66];
uint16_tSCI_Interrupt;
uint32_tSMI_Command_Port;
uint8_tACPI_Enable;
uint8_tACPI_Disable;
uint8_tS4BIOS_Command;
uint8_tPState_Control;
uint32_tPM1A_Event_Block_Address;
uint32_tPM1B_Event_Block_Address;
uint32_tPM1A_Control_Block_Address;
uint32_tPM1B_Control_Block_Address;
uint32_tPM2_Control_Block_Address;
uint32_tPM_Timer_Block_Address;
uint32_tGPE0_Block_Address;
uint32_tGPE1_Block_Address;
uint8_tPM1_Event_Block_Length;
uint8_tPM1_Control_Block_Length;
uint8_tPM2_Control_Block_Length;
uint8_tPM_Timer_Block_Length;
uint8_tGPE0_Block_Length;
uint8_tGPE1_Block_Length;
uint8_tGPE1_Base_Offset;
uint8_tCST_Support;
uint16_tC2_Latency;
uint16_tC3_Latency;
uint16_tCPU_Cache_Size;
uint16_tCache_Flush_Stride;
uint8_tDuty_Cycle_Offset;
uint8_tDuty_Cycle_Width;
uint8_tRTC_Day_Alarm_Index;
uint8_tRTC_Month_Alarm_Index;
uint8_tRTC_Century_Index;
uint16_tBoot_Flags;
uint8_tReserved0;
/* Begin Asere */
//Reset Fix
uint32_t Flags;
uint8_tnotimp2[96];
} __attribute__((packed));
struct acpi_2_dsdt {
char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t Checksum;
char OEMID[6];
char OEMTableId[8];
char OEMRevision[4];
char CreatorId[4];
char CreatorRevision[4];
chardsdtStart;// actual length is .Length
} __attribute__((packed));
#endif /* !__LIBSAIO_ACPI_H */
branches/meklort/i386/libsaio/platform.c
1212
1313
1414
15
1516
1617
1718
......
2425
2526
2627
28
2729
2830
2931
......
3739
3840
3941
40
42
43
44
45
4146
4247
4348
44
49
50
51
52
4553
54
4655
56
4757
4858
4959
......
5262
5363
5464
55
5665
5766
5867
59
60
61
68
6269
#include "cpu.h"
#include "mem.h"
#include "spd.h"
#include "dram_controllers.h"
#ifndef DEBUG_PLATFORM
#define DEBUG_PLATFORM 0
#endif
PlatformInfo_t Platform;
pci_dt_t * dram_controller_dev = NULL;
/** Return if a CPU feature specified by feature is activated (true) or not (false) */
bool platformCPUFeature(uint32_t feature)
/** scan mem for memory autodection purpose */
void scan_mem() {
bool useAutodetection = false;
static bool done = false;
if (done) return;
bool useAutodetection = true;
getBoolForKey(kUseMemDetect, &useAutodetection, &bootInfo->bootConfig);
if (useAutodetection) {
scan_memory(&Platform);
if (dram_controller_dev!=NULL) {
scan_dram_controller(dram_controller_dev); // Rek: pci dev ram controller direct and fully informative scan ...
}
scan_memory(&Platform); // unfortunately still necesary for some comp where spd cant read correct speed
scan_spd(&Platform);
//getc();
}
done = true;
}
/**
*/
void scan_platform(void)
{
memset(&Platform, 0, sizeof(Platform));
build_pci_dt();
scan_cpu(&Platform);
// disabled for now as options can't be read yet here:
// scan_mem();
//scan_mem(); Rek: called after pci devs init in fake_efi now ...
}
branches/meklort/i386/libsaio/cpu.c
1414
1515
1616
17
17
1818
1919
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
5720
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
11921
12022
12123
......
218120
219121
220122
123
124
221125
222126
223127
......
226130
227131
228132
229
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
230164
231165
232166
......
249183
250184
251185
186
187
188
252189
253190
254191
......
261198
262199
263200
264
201
202
265203
266204
267205
......
279217
280218
281219
282
220
283221
284222
285223
......
359297
360298
361299
362
300
363301
364302
365303
......
369307
370308
371309
310
372311
373312
374313
#if DEBUG_CPU
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#define DBG(x...)msglog(x)
#endif
static inline uint64_t rdtsc64(void)
{
uint64_t ret;
__asm__ volatile("rdtsc" : "=A" (ret));
return ret;
}
static inline uint64_t rdmsr64(uint32_t msr)
{
uint64_t ret;
__asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
return ret;
}
static inline void do_cpuid(uint32_t selector, uint32_t *data)
{
asm volatile ("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a" (selector));
}
static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
{
asm volatile ("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a" (selector), "c" (selector2));
}
// DFE: enable_PIT2 and disable_PIT2 come from older xnu
/*
* Enable or disable timer 2.
* Port 0x61 controls timer 2:
* bit 0 gates the clock,
* bit 1 gates output to speaker.
*/
static inline void enable_PIT2(void)
{
/* Enable gate, disable speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t" /* & ~0x03 */
" or $1,%%al \n\t"
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
static inline void disable_PIT2(void)
{
/* Disable gate and output to speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t"/* & ~0x03 */
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
// roughly based on Linux code
/* Set the 8254 channel 2 to mode 0 with the specified value.
In mode 0, the counter will initially set its gate low when the
timer expires. For this to be useful, you ought to set it high
before calling this function. The enable_PIT2 function does this.
*/
static inline void set_PIT2_mode0(uint16_t value)
{
__asm__ volatile(
" movb $0xB0,%%al \n\t"
" outb%%al,$0x43\n\t"
" movb%%dl,%%al\n\t"
" outb%%al,$0x42\n\t"
" movb%%dh,%%al\n\t"
" outb%%al,$0x42"
: : "d"(value) /*: no clobber */ );
}
/* Returns the number of times the loop ran before the PIT2 signaled */
static inline unsigned long poll_PIT2_gate(void)
{
unsigned long count = 0;
unsigned char nmi_sc_val;
do {
++count;
__asm__ volatile(
"inb$0x61,%0"
: "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
} while( (nmi_sc_val & 0x20) == 0);
return count;
}
/*
* DFE: Measures the TSC frequency in Hz (64-bit) using the ACPI PM timer
*/
static uint64_t measure_tsc_frequency(void)
}
#endif
p->CPU.Vendor= p->CPU.CPUID[CPUID_0][1];
p->CPU.Signature= p->CPU.CPUID[CPUID_1][0];
p->CPU.Stepping= bitfield(p->CPU.CPUID[CPUID_1][0], 3, 0);
p->CPU.Model= bitfield(p->CPU.CPUID[CPUID_1][0], 7, 4);
p->CPU.Family= bitfield(p->CPU.CPUID[CPUID_1][0], 11, 8);
p->CPU.ExtModel= bitfield(p->CPU.CPUID[CPUID_1][0], 19, 16);
p->CPU.NoCores= bitfield(p->CPU.CPUID[CPUID_4][0], 31, 26) + 1;
p->CPU.Model += (p->CPU.ExtModel << 4);
/* get brand string (if supported) */
/* Copyright: from Apple's XNU cpuid.c */
if (p->CPU.CPUID[CPUID_80][0] > 0x80000004) {
uint32_treg[4];
char str[128], *s;
/*
* The brand string 48 bytes (max), guaranteed to
* be NUL terminated.
*/
do_cpuid(0x80000002, reg);
bcopy((char *)reg, &str[0], 16);
do_cpuid(0x80000003, reg);
bcopy((char *)reg, &str[16], 16);
do_cpuid(0x80000004, reg);
bcopy((char *)reg, &str[32], 16);
for (s = str; *s != '\0'; s++) {
if (*s != ' ') break;
}
strlcpy(p->CPU.BrandString,s, sizeof(p->CPU.BrandString));
if (!strncmp(p->CPU.BrandString, CPU_STRING_UNKNOWN, min(sizeof(p->CPU.BrandString), strlen(CPU_STRING_UNKNOWN) + 1))) {
/*
* This string means we have a firmware-programmable brand string,
* and the firmware couldn't figure out what sort of CPU we have.
*/
p->CPU.BrandString[0] = '\0';
}
}
/* setup features */
if ((bit(23) & p->CPU.CPUID[CPUID_1][3]) != 0) {
p->CPU.Features |= CPU_FEATURE_MMX;
if ((bit(29) & p->CPU.CPUID[CPUID_81][3]) != 0) {
p->CPU.Features |= CPU_FEATURE_EM64T;
}
if ((bit(5) & p->CPU.CPUID[CPUID_1][3]) != 0) {
p->CPU.Features |= CPU_FEATURE_MSR;
}
//if ((bit(28) & p->CPU.CPUID[CPUID_1][3]) != 0) {
if (p->CPU.NoThreads > p->CPU.NoCores) {
p->CPU.Features |= CPU_FEATURE_HTT;
if ((p->CPU.Vendor == 0x756E6547 /* Intel */) && ((p->CPU.Family == 0x06) || (p->CPU.Family == 0x0f))) {
if ((p->CPU.Family == 0x06 && p->CPU.Model >= 0x0c) || (p->CPU.Family == 0x0f && p->CPU.Model >= 0x03)) {
/* Nehalem CPU model */
if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e)) {
if (p->CPU.Family == 0x06 && (p->CPU.Model == 0x1a || p->CPU.Model == 0x1e
|| p->CPU.Model == 0x1f || p->CPU.Model == 0x25 || p->CPU.Model == 0x2c)) {
msr = rdmsr64(MSR_PLATFORM_INFO);
DBG("msr(%d): platform_info %08x\n", __LINE__, msr & 0xffffffff);
currcoef = (msr >> 8) & 0xff;
}
cpuFrequency = tscFrequency;
} else {
msr = rdmsr64(IA32_PERF_STATUS);
msr = rdmsr64(MSR_IA32_PERF_STATUS);
DBG("msr(%d): ia32_perf_stat 0x%08x\n", __LINE__, msr & 0xffffffff);
currcoef = (msr >> 8) & 0x1f;
/* Non-integer bus ratio for the max-multi*/
p->CPU.TSCFrequency = tscFrequency;
p->CPU.FSBFrequency = fsbFrequency;
p->CPU.CPUFrequency = cpuFrequency;
#if DEBUG_CPU
DBG("CPU: Vendor/Model/ExtModel: 0x%x/0x%x/0x%x\n", p->CPU.Vendor, p->CPU.Model, p->CPU.ExtModel);
DBG("CPU: Family/ExtFamily: 0x%x/0x%x\n", p->CPU.Family, p->CPU.ExtFamily);
DBG("CPU: MaxCoef/CurrCoef: 0x%x/0x%x\n", p->CPU.MaxCoef, p->CPU.CurrCoef);
DBG("CPU: CPUFreq: %dMHz\n", p->CPU.CPUFrequency / 1000000);
DBG("CPU: NoCores/NoThreads: %d/%d\n", p->CPU.NoCores, p->CPU.NoThreads);
DBG("CPU: Features: 0x%08x\n", p->CPU.Features);
#if DEBUG_CPU
pause();
#endif
}
branches/meklort/i386/libsaio/platform.h
2323
2424
2525
26
27
28
29
30
31
32
33
34
35
36
37
2638
2739
2840
......
3345
3446
3547
48
3649
3750
38
51
3952
40
53
4154
4255
4356
......
7588
7689
7790
78
79
91
92
8093
8194
8295
83
84
85
86
87
96
97
98
99
100
88101
89102
90103
......
92105
93106
94107
108
109
95110
96111
97112
......
105120
106121
107122
108
123
109124
110125
111126
112127
113
128
129
130
131
132
133
134
135
136
137
114138
115139
116140
#define CPUID_816
#define CPUID_MAX7
#define CPU_MODEL_YONAH0x0E
#define CPU_MODEL_MEROM0x0F
#define CPU_MODEL_PENRYN0x17
#define CPU_MODEL_NEHALEM0x1A
#define CPU_MODEL_ATOM0x1C
#define CPU_MODEL_FIELDS0x1E/* Lynnfield, Clarksfield, Jasper */
#define CPU_MODEL_DALES0x1F/* Havendale, Auburndale */
#define CPU_MODEL_DALES_32NM0x25/* Clarkdale, Arrandale */
#define CPU_MODEL_WESTMERE0x2C/* Gulftown, Westmere-EP, Westmere-WS */
#define CPU_MODEL_NEHALEM_EX0x2E
#define CPU_MODEL_WESTMERE_EX0x2F
/* CPU Features */
#define CPU_FEATURE_MMX0x00000001// MMX Instruction Set
#define CPU_FEATURE_SSE0x00000002// SSE Instruction Set
#define CPU_FEATURE_EM64T0x00000040// 64Bit Support
#define CPU_FEATURE_HTT0x00000080// HyperThreading
#define CPU_FEATURE_MOBILE0x00000100// Mobile CPU
#define CPU_FEATURE_MSR0x00000200// MSR Support
/* SMBIOS Memory Types */
#define SMB_MEM_TYPE_UNDEFINED0
#define SMB_MEM_TYPE_UNDEFINED0
#define SMB_MEM_TYPE_OTHER1
#define SMB_MEM_TYPE_UNKNOWN2
#define SMB_MEM_TYPE_UNKNOWN2
#define SMB_MEM_TYPE_DRAM3
#define SMB_MEM_TYPE_EDRAM4
#define SMB_MEM_TYPE_VRAM5
#define UUID_LEN16
typedef struct _RamSlotInfo_t {
uint32_t ModuleSize;// Size of Module in MB
uint32_t Frequency; // in Mhz
uint32_tModuleSize;// Size of Module in MB
uint32_tFrequency; // in Mhz
const char*Vendor;
const char*PartNo;
const char*SerialNo;
char*spd;// SPD Dump
boolInUse;
uint8_tType;
uint8_t BankConnections; // table type 6, see (3.3.7)
uint8_t BankConnCnt;
char*spd;// SPD Dump
boolInUse;
uint8_tType;
uint8_tBankConnections; // table type 6, see (3.3.7)
uint8_tBankConnCnt;
} RamSlotInfo_t;
struct CPU {
uint32_tFeatures;// CPU Features like MMX, SSE2, VT, MobileCPU
uint32_tVendor;// Vendor
uint32_tSignature;// Signature
uint32_tStepping;// Stepping
uint32_tModel;// Model
uint32_tExtModel;// Extended Model
uint32_tFamily;// Family
uint64_tTSCFrequency;// TSC Frequency Hz
uint64_tFSBFrequency;// FSB Frequency Hz
uint64_tCPUFrequency;// CPU Frequency Hz
uint32_tBrandString[16];// 48 Byte Branding String
charBrandString[48];// 48 Byte Branding String
uint32_tCPUID[CPUID_MAX][4];// CPUID 0..4, 80..81 Raw Values
} CPU;
struct RAM {
RamSlotInfo_tDIMM[MAX_RAM_SLOTS];// Information about each slot
uint64_tFrequency;// Ram Frequency
uint32_tDivider;// Memory divider
uint8_tCAS;// CAS 1/2/2.5/3/4/5/6/7
uint8_tTRC;
uint8_tTRP;
uint8_tRAS;
uint8_tChannels;// Channel Configuration Single,Dual or Triple
uint8_tNoSlots;// Maximum no of slots available
uint8_tType;// Standard SMBIOS v2.5 Memory Type
RamSlotInfo_tDIMM[MAX_RAM_SLOTS];// Information about each slot
} RAM;
struct DMI {
branches/meklort/i386/libsaio/disk.c
6767
6868
6969
70
71
72
7073
7174
7275
......
7780
7881
7982
80
8183
8284
8385
......
871873
872874
873875
874
876
877
875878
876879
877880
......
14451448
14461449
14471450
1448
1449
1450
1451
1452
1453
1451
1452
1453
1454
1455
14541456
14551457
14561458
......
15541556
15551557
15561558
1557
1558
1559
1560
15591561
1562
1563
1564
1565
1566
1567
15601568
15611569
15621570
......
15891597
15901598
15911599
1592
1593
1600
15941601
15951602
1596
1597
1598
1599
1600
1601
1602
1603
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
16041615
16051616
16061617
......
16291640
16301641
16311642
1643
1644
16321645
16331646
16341647
......
16791692
16801693
16811694
1682
1683
1695
16841696
1685
1686
1687
1688
1697
16891698
1690
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
16911727
1692
1693
1728
1729
1730
1731
16941732
1695
1696
1697
1698
1699
1700
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
17011778
17021779
1703
1780
17041781
1705
1706
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
17071801
1708
1709
1710
1711
1802
1803
1804
1805
17121806
1713
1714
1715
1716
1717
1718
1719
1720
17211807
17221808
17231809
17241810
17251811
1726
1727
1728
1812
1813
1814
17291815
1730
1731
1732
17331816
17341817
1735
1736
1737
1738
1739
1740
1741
1742
1743
1818
1819
1820
1821
1822
1823
1824
1825
1826
17441827
1745
1746
1747
1828
17481829
17491830
17501831
#include "msdos.h"
#include "ext2fs.h"
#include "xml.h"
#include "disk.h"
#include <limits.h>
#include <IOKit/storage/IOApplePartitionScheme.h>
#include <IOKit/storage/IOGUIDPartitionScheme.h>
#include "efi.h"
#include "efi_tables.h"
#define BPS 512 /* sector size of the device */
#define PROBEFS_SIZE BPS * 4 /* buffer size for filesystem probe */
#define CD_BPS 2048 /* CD-ROM block size */
#define N_CACHE_SECS (BIOS_LEN / BPS) /* Must be a multiple of 4 for CD-ROMs */
biosdev, partno,
part->relsect,
part,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
NTFSGetUUID,
NTFSGetDescription,
(BVFree)free,
0, kBIOSDevTypeHardDrive, 0);
void rescanBIOSDevice(int biosdev)
{
struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev);
CacheReset();
diskFreeMap(oldMap);
oldMap = NULL;
scanBootVolumes(biosdev, 0);
struct DiskBVMap *oldMap = diskResetBootVolumes(biosdev);
CacheReset();
diskFreeMap(oldMap);
oldMap = NULL;
scanBootVolumes(biosdev, 0);
}
struct DiskBVMap* diskResetBootVolumes(int biosdev)
struct DiskBVMap * map = NULL;
int bvCount = 0;
const char *val;
char devsw[12];
const char *raw = 0;
char* val = 0;
int len;
getValueForKey(kHidePartition, &raw, &len, &bootInfo->bootConfig);
if(raw)
{
val = XMLDecode(raw);
}
/*
* Traverse gDISKBVmap to get references for
)
newBVR->visible = true;
/*
* Looking for "Hide Partition" entries in "hd(x,y) hd(n,m)" format
/* Looking for "Hide Partition" entries in 'hd(x,y)|uuid|"label" hd(m,n)|uuid|"label"' format
* to be able to hide foreign partitions from the boot menu.
*/
if ( (newBVR->flags & kBVFlagForeignBoot)
&& getValueForKey(kHidePartition, &val, &len, &bootInfo->bootConfig)
)
{
sprintf(devsw, "hd(%d,%d)", BIOS_DEV_UNIT(newBVR), newBVR->part_no);
if (strstr(val, devsw) != NULL)
newBVR->visible = false;
}
if ( (newBVR->flags & kBVFlagForeignBoot) )
{
char *start, *next = val;
long len = 0;
do
{
start = strbreak(next, &next, &len);
if(len && matchVolumeToString(newBVR, start, len) )
newBVR->visible = false;
}
while ( next && *next );
}
/*
* Use the first bvr entry as the starting chain pointer.
#endif
*count = bvCount;
free(val);
return chain;
}
//==========================================================================
/* If Rename Partition has defined an alias, then extract it for description purpose */
static const char * getVolumeLabelAlias( BVRef bvr, const char * str, long strMaxLen)
bool matchVolumeToString( BVRef bvr, const char* match, long matchLen)
{
const int MAX_ALIAS_SIZE=31;
static char szAlias[MAX_ALIAS_SIZE+1];
char *q=szAlias;
const char * szAliases = getStringForKey(kRenamePartition, &bootInfo->bootConfig);
char testStr[128];
if (!str || !*str || !szAliases) return 0; // no renaming wanted
if ( !bvr || !match || !*match)
return 0;
if ( bvr->biosdev < 0x80 || bvr->biosdev >= 0x100 )
return 0;
// Try to match hd(x,y) first.
sprintf(testStr, "hd(%d,%d)", BIOS_DEV_UNIT(bvr), bvr->part_no);
if ( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
// Try to match volume UUID.
if ( bvr->fs_getuuid && bvr->fs_getuuid(bvr, testStr) == 0)
{
if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
}
// Try to match volume label (always quoted).
if ( bvr->description )
{
bvr->description(bvr, testStr, sizeof(testStr)-1);
if( matchLen ? !strncmp(match, testStr, matchLen) : !strcmp(match, testStr) )
return true;
}
return false;
}
const char * p = strstr(szAliases, str);
if(!p || !(*p)) return 0; // this volume must not be renamed, or option is malformed
/* If Rename Partition has defined an alias, then extract it for description purpose
* The format for the rename string is the following:
* hd(x,y)|uuid|"label" "alias";hd(m,n)|uuid|"label" etc; ...
*/
p+= strlen(str); // skip the "hd(n,m) " field
// multiple aliases can be found separated by a semi-column
while(*p && *p != ';' && q<(szAlias+MAX_ALIAS_SIZE)) *q++=*p++;
*q='\0';
return szAlias;
bool getVolumeLabelAlias(BVRef bvr, char* str, long strMaxLen)
{
char *aliasList, *entryStart, *entryNext;
if ( !str || strMaxLen <= 0)
return false;
aliasList = XMLDecode(getStringForKey(kRenamePartition, &bootInfo->bootConfig));
if ( !aliasList )
return false;
for ( entryStart = entryNext = aliasList;
entryNext && *entryNext;
entryStart = entryNext )
{
char *volStart, *volEnd, *aliasStart;
long volLen, aliasLen;
// Delimit current entry
entryNext = strchr(entryStart, ';');
if ( entryNext )
{
*entryNext = '\0';
entryNext++;
}
volStart = strbreak(entryStart, &volEnd, &volLen);
if(!volLen)
continue;
aliasStart = strbreak(volEnd, 0, &aliasLen);
if(!aliasLen)
continue;
if ( matchVolumeToString(bvr, volStart, volLen) )
{
strncat(str, aliasStart, min(strMaxLen, aliasLen));
free(aliasList);
return true;
}
}
free(aliasList);
return false;
}
void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool verbose )
void getBootVolumeDescription( BVRef bvr, char * str, long strMaxLen, bool useDeviceDescription )
{
unsigned char type = (unsigned char) bvr->part_type;
char *p;
unsigned char type;
char *p = str;
if(!bvr || !p || strMaxLen <= 0)
return;
type = (unsigned char) bvr->part_type;
if (useDeviceDescription)
{
int len = getDeviceDescription(bvr, str);
if(len >= strMaxLen)
return;
strcpy(str + len, " ");
len++;
strMaxLen -= len;
p += len;
}
p = str;
if (verbose) {
sprintf( str, "hd(%d,%d) ", BIOS_DEV_UNIT(bvr), bvr->part_no);
for (; strMaxLen > 0 && *p != '\0'; p++, strMaxLen--);
/* See if a partition rename is preferred */
if(getVolumeLabelAlias(bvr, p, strMaxLen)) {
strncpy(bvr->label, p, strMaxLen);
return; // we're done here no need to seek for real name
}
// See if we should get the renamed alias name for this partion:
const char * szAliasName = getVolumeLabelAlias(bvr, str, strMaxLen);
if (szAliasName && *szAliasName)
{
strncpy(bvr->label, szAliasName, strMaxLen);
return; // we're done here no need to seek for real name
}
//
// Get the volume label using filesystem specific functions
// or use the alternate volume label if available.
//
if (*bvr->altlabel == '\0')
{
if (bvr->description)
if (*bvr->altlabel != '\0')
strncpy(p, bvr->altlabel, strMaxLen);
else if (bvr->description)
bvr->description(bvr, p, strMaxLen);
}
else
strncpy(p, bvr->altlabel, strMaxLen);
if (*p == '\0') {
const char * name = getNameForValue( fdiskTypes, type );
if (name == NULL) {
name = bvr->type_name;
}
if (name == NULL) {
sprintf(p, "TYPE %02x", type);
} else {
strncpy(p, name, strMaxLen);
}
const char * name = getNameForValue( fdiskTypes, type );
if (name == NULL) {
name = bvr->type_name;
}
if (name == NULL) {
sprintf(p, "TYPE %02x", type);
} else {
strncpy(p, name, strMaxLen);
}
}
/* See if a partion rename is wanted: */
// Set the devices label
sprintf(bvr->label, p);
}
branches/meklort/i386/libsaio/pci_setup.c
66
77
88
9
10
119
1210
1311
12
13
1414
1515
1616
......
2929
3030
3131
32
33
34
35
3236
3337
3438
......
5862
5963
6064
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
7765
7866
7967
#include "ati.h"
extern void set_eth_builtin(pci_dt_t *eth_dev);
//extern int ehci_acquire(pci_dt_t *pci_dev);
//extern int uhci_reset(pci_dt_t *pci_dev);
extern void notify_usb_dev(pci_dt_t *pci_dev);
extern void force_enable_hpet(pci_dt_t *lpc_dev);
extern pci_dt_t *dram_controller_dev;
void setup_pci_devs(pci_dt_t *pci_dt)
{
char *devicepath;
switch (current->class_id)
{
case PCI_CLASS_BRIDGE_HOST:
dram_controller_dev = current;
break;
case PCI_CLASS_NETWORK_ETHERNET:
if (do_eth_devprop)
set_eth_builtin(current);
case PCI_CLASS_SERIAL_USB:
notify_usb_dev(current);
/*
switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG))
{
// EHCI
case 0x20:
if (fix_ehci)
ehci_acquire(current);
break;
// UHCI
case 0x00:
if (fix_uhci)
uhci_reset(current);
break;
}
*/
break;
case PCI_CLASS_BRIDGE_ISA:
branches/meklort/i386/libsaio/cpu.h
1414
1515
1616
17
18
19
20
21
17
2218
19
20
21
22
23
24
25
26
2327
2428
2529
......
2933
3034
3135
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
32143
#define bitmask(h,l)((bit(h)|(bit(h)-1)) & ~(bit(l)-1))
#define bitfield(x,h,l)(((x) & bitmask(h,l)) >> l)
#defineIA32_PERF_STATUS0x198
#define MSR_FLEX_RATIO0x194
#defineMSR_PLATFORM_INFO0xCE
#define K8_FIDVID_STATUS0xC0010042
#define K10_COFVID_STATUS0xC0010071
#define CPU_STRING_UNKNOWN"Unknown CPU Typ"
#defineMSR_IA32_PERF_STATUS0x198
#define MSR_IA32_PERF_CONTROL0x199
#define MSR_IA32_EXT_CONFIG0x00EE
#define MSR_FLEX_RATIO0x194
#defineMSR_PLATFORM_INFO0xCE
#define K8_FIDVID_STATUS0xC0010042
#define K10_COFVID_STATUS0xC0010071
#define DEFAULT_FSB100000 /* for now, hardcoding 100MHz for old CPUs */
// DFE: This constant comes from older xnu:
#define CALIBRATE_TIME_MSEC30/* 30 msecs */
#define CALIBRATE_LATCH((CLKNUM * CALIBRATE_TIME_MSEC + 1000/2)/1000)
static inline uint64_t rdtsc64(void)
{
uint64_t ret;
__asm__ volatile("rdtsc" : "=A" (ret));
return ret;
}
static inline uint64_t rdmsr64(uint32_t msr)
{
uint64_t ret;
__asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
return ret;
}
static inline void wrmsr64(uint32_t msr, uint64_t val)
{
__asm__ volatile("wrmsr" : : "c" (msr), "A" (val));
}
static inline void intel_waitforsts(void) {
uint32_t inline_timeout = 100000;
while (rdmsr64(MSR_IA32_PERF_STATUS) & (1 << 21)) { if (!inline_timeout--) break; }
}
static inline void do_cpuid(uint32_t selector, uint32_t *data)
{
asm volatile ("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a" (selector));
}
static inline void do_cpuid2(uint32_t selector, uint32_t selector2, uint32_t *data)
{
asm volatile ("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a" (selector), "c" (selector2));
}
// DFE: enable_PIT2 and disable_PIT2 come from older xnu
/*
* Enable or disable timer 2.
* Port 0x61 controls timer 2:
* bit 0 gates the clock,
* bit 1 gates output to speaker.
*/
static inline void enable_PIT2(void)
{
/* Enable gate, disable speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t" /* & ~0x03 */
" or $1,%%al \n\t"
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
static inline void disable_PIT2(void)
{
/* Disable gate and output to speaker */
__asm__ volatile(
" inb $0x61,%%al \n\t"
" and $0xFC,%%al \n\t"/* & ~0x03 */
" outb %%al,$0x61 \n\t"
: : : "%al" );
}
// DFE: set_PIT2_mode0, poll_PIT2_gate, and measure_tsc_frequency are
// roughly based on Linux code
/* Set the 8254 channel 2 to mode 0 with the specified value.
In mode 0, the counter will initially set its gate low when the
timer expires. For this to be useful, you ought to set it high
before calling this function. The enable_PIT2 function does this.
*/
static inline void set_PIT2_mode0(uint16_t value)
{
__asm__ volatile(
" movb $0xB0,%%al \n\t"
" outb%%al,$0x43\n\t"
" movb%%dl,%%al\n\t"
" outb%%al,$0x42\n\t"
" movb%%dh,%%al\n\t"
" outb%%al,$0x42"
: : "d"(value) /*: no clobber */ );
}
/* Returns the number of times the loop ran before the PIT2 signaled */
static inline unsigned long poll_PIT2_gate(void)
{
unsigned long count = 0;
unsigned char nmi_sc_val;
do {
++count;
__asm__ volatile(
"inb$0x61,%0"
: "=q"(nmi_sc_val) /*:*/ /* no input */ /*:*/ /* no clobber */);
} while( (nmi_sc_val & 0x20) == 0);
return count;
}
#endif /* !__LIBSAIO_CPU_H */
branches/meklort/i386/libsaio/disk.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
* disk.h
* Chameleon
*
* Created by Daniel Miranda on 27/07/10.
* Copyright 2010 __MyCompanyName__. All rights reserved.
*
*/
#ifndef __LIBSAIO_DISK_H
#define __LIBSAIO_DISK_H
bool matchVolumeToString( BVRef bvr, const char* match, long strMaxLen);
#endif /* __LIBSAIO_DISK_H */
branches/meklort/i386/libsaio/cache.c
3939
4040
4141
42
42
4343
4444
4545
......
7474
7575
7676
77
77
7878
7979
8080
#define kCacheSize (0x100000)
#define kCacheMinBlockSize (0x200)
#define kCacheMaxBlockSize (0x4000)
#define kCacheMaxBlockSize (0x8000)
#define kCacheMaxEntries (kCacheSize / kCacheMinBlockSize)
static CICell gCacheIH;
#endif
if ((blockSize < kCacheMinBlockSize) ||
(blockSize >= kCacheMaxBlockSize))
(blockSize > kCacheMaxBlockSize))
return;
gCacheBlockSize = blockSize;
branches/meklort/i386/libsaio/saio_types.h
132132
133133
134134
135
135
136136
137137
138
138
139139
140140
141141
......
147147
148148
149149
150
150151
151152
152153
......
157158
158159
159160
160
161
161162
162163
163164
typedef long (*FSLoadFile)(CICell ih, char * filePath);
typedef long (*FSReadFile)(CICell ih, char *filePath, void *base, uint64_t offset, uint64_t length);
typedef long (*FSGetFileBlock)(CICell ih, char *filePath, unsigned long long *firstBlock);
typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long * dirIndex,
typedef long (*FSGetDirEntry)(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid);
typedef long (* FSGetUUID)(CICell ih, char *uuidStr);
typedef long (*FSGetUUID)(CICell ih, char *uuidStr);
typedef void (*BVGetDescription)(CICell ih, char * str, long strMaxLen);
// Can be just pointed to free or a special free function
typedef void (*BVFree)(CICell ih);
char * i_buf; /* file load address */
};
#define BPS 512 /* sector size of the device */
#define F_READ 0x1 /* file opened for reading */
#define F_WRITE 0x2 /* file opened for writing */
#define F_ALLOC 0x4 /* buffer allocated */
struct dirstuff {
char * dir_path; /* directory path */
long dir_index; /* directory entry index */
long long dir_index; /* directory entry index */
BVRef dir_bvr; /* volume reference */
};
branches/meklort/i386/libsaio/msdos.c
5454
5555
5656
57
57
5858
5959
6060
......
151151
152152
153153
154
154
155155
156156
157157
......
220220
221221
222222
223
223224
224
225
225
226226
227227
228228
229229
230230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
231255
232256
233257
......
266290
267291
268292
269
293
270294
271
295
296
272297
273
298
274299
275300
276
277
301
278302
279303
280304
......
615639
616640
617641
618
642
619643
620644
621645
......
626650
627651
628652
629
653
630654
631655
632656
......
651675
652676
653677
654
678
655679
656680
657681
......
720744
721745
722746
747
748
723749
724750
725751
......
754780
755781
756782
757
758
783
784
785
786
759787
760788
761789
#include "msdos.h"
#define LABEL_LENGTH11
#define MAX_DOS_BLOCKSIZE2048
#define MSDOS_CACHE_BLOCKSIZE BPS
#defineCLUST_FIRST2/* reserved cluster range */
#defineCLUST_RSRVD320x0ffffff8/* reserved cluster range */
if (msdoscurrent == ih)
{
CacheInit(ih, msdosclustersize);
CacheInit(ih, MSDOS_CACHE_BLOCKSIZE);
return 0;
}
}
msdosclustersize = msdosbps * spc;
msdoscurrent = ih;
msdoscurrent = ih;
CacheInit(ih, msdosclustersize);
CacheInit(ih, MSDOS_CACHE_BLOCKSIZE);
free (buf);
return 0;
}
static int
readSector(CICell ih, off_t readOffset, char *buf, int size)
{
// Caching only FAT entries (4 bytes) by utlizing the cache with sector aligned read requests.
if (size < BPS)
{
long long sectorOffset = (uint64_t)readOffset / BPS * BPS;
long relOffset = readOffset % BPS;
char *cacheBuffer;
cacheBuffer = malloc(MSDOS_CACHE_BLOCKSIZE);
CacheRead(ih, cacheBuffer, sectorOffset, MSDOS_CACHE_BLOCKSIZE, true);
bcopy(cacheBuffer + relOffset, buf, size);
free(cacheBuffer);
}
else
{
Seek(ih, readOffset);
Read(ih, (long)buf, size);
}
return 0;
}
static int
msdosreadcluster (CICell ih, uint8_t *buf, int size, off_t *cluster)
{
off_t readOffset;
Seek(ih, readOffset);
Read(ih, (long)buf, size);
}
/* Find first sector of FAT */
readOffset = msdosressector*msdosbps;
readOffset = msdosressector * msdosbps;
/* Find sector containing "cluster" entry in FAT */
readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits)/8;
readOffset += ((uint64_t)*cluster * (uint64_t)msdosfatbits) / 8;
/* Read one sector of the FAT */
Seek(ih, readOffset);
Read(ih, (long)tmpbuf, 4);
readSector(ih, readOffset, tmpbuf, 4);
switch (msdosfatbits) {
case 32:
return 0;
}
long MSDOSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
long MSDOSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid)
{
return -1;
if (dirPath[0] == '/')
dirPath++;
st = (struct msdosdirstate *)*dirIndex;
st = (struct msdosdirstate *)(long) *dirIndex;
if (!st)
{
st=malloc (sizeof (*st));
}
else
initRoot (st);
*dirIndex = (long)st;
*dirIndex = (long long) (long) st;
}
while((dirp = getnextdirent (ih, vfatname, st))&& (dirp->deAttributes & ATTR_VOLUME));
if (!dirp)
char *ptr = (char *)base;
struct direntry *dirp;
int i;
char devStr[12];
if (MSDOSInitPartition (ih)<0)
return -1;
if (filePath[0] == '/')
ptr+=msdosclustersize;
toread-=msdosclustersize;
}
verbose("Loaded FAT%d file: [%s] %d bytes from %x.\n",
msdosfatbits, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread, ih);
getDeviceDescription(ih, devStr);
verbose("Read FAT%d file: [%s/%s] %d bytes.\n",
msdosfatbits, devStr, filePath, (uint32_t)( toread<0 ) ? wastoread : wastoread-toread);
free (buf);
if (toread<0)
return wastoread;
branches/meklort/i386/libsaio/fake_efi.c
11
22
3
3
44
55
66
......
1111
1212
1313
14
14
1515
1616
1717
......
2222
2323
2424
25
26
27
28
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2953
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
5554
5655
5756
5857
5958
6059
61
62
63
60
61
62
6463
6564
66
6765
6866
6967
68
7069
7170
72
71
7372
7473
75
7674
7775
7876
......
8280
8381
8482
85
83
8684
8785
8886
87
8988
9089
9190
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
91
92
11293
11394
11495
11596
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
147140
148141
149
142
143
150144
151
152
153
145
146
147
154148
155149
156
157
150
151
152
153
154
155
158156
159
160
161
162
163
157
164158
165
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
166273
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
265381
266382
267383
268
269
270
271
272
384
385
386
387
388
273389
274390
275391
......
285401
286402
287403
288
404
289405
290
291
406
407
292408
293409
294410
295411
296412
297413
298
414
299415
300416
301417
302418
303
419
304420
305421
306422
......
317433
318434
319435
320
321436
322437
323438
324439
325440
326441
327
442
443
444
445
328446
329447
330
331
332
448
449
450
451
452
453
454
455
456
457
458
459
460
333461
334
462
463
464
335465
336
337
338
339
340
341
342
343
344
345
466
346467
468
469
347470
348
349
350
351
352
471
472
473
353474
354
355
475
476
356477
357
478
358479
359480
360
361
481
482
483
362484
363485
364486
365
487
488
489
366490
367491
368492
369
493
370494
371495
372496
373497
374
498
499
375500
376501
502
377503
378
504
505
506
507
508
509
379510
380
381
382
383
511
512
513
514
515
516
517
518
519
520
521
522
384523
385
386
387
388
389
390
524
525
526
527
391528
392
393
394
395
396
397529
398530
399
400
401
402
403
531
532
533
534
535
404536
405537
406538
407539
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
540
541
542
543
424544
425
545
546
547
548
549
550
551
552
553
554
426555
556
557
558
559
427560
428561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
429581
430582
431
583
432584
433585
434
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
435610
436
611
612
613
614
615
616
617
618
619
620
621
437622
438
439
440
623
624
625
441626
442
443
444
445
446
447
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
448652
449
450
451
452
653
654
655
656
453657
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
658
659
660
661
662
663
486664
487665
488
489
490
491
492
666
667
668
493669
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508670
509671
510
511
512
513
514
515
516
517
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
518689
519690
520
691
692
693
694
695
521696
697
522698
523
524699
525
526
527
528
529
700
701
530702
531
532
703
704
705
706
707
708
709
710
711
533712
534
535
713
714
536715
537
538
539
540
541
716
717
542718
543719
/*
* Copyright 2007 David F. Elliott. All rights reserved.
* Copyright 2007 David F. Elliott. All rights reserved.
*/
#include "libsaio.h"
#include "fake_efi.h"
#include "efi_tables.h"
#include "platform.h"
#include "dsdt_patcher.h"
#include "acpi_patcher.h"
#include "smbios_patcher.h"
#include "device_inject.h"
#include "convert.h"
extern void setup_pci_devs(pci_dt_t *pci_dt);
/*
Modern Darwin kernels require some amount of EFI because Apple machines all
have EFI. Modifying the kernel source to not require EFI is of course
possible but would have to be maintained as a separate patch because it is
unlikely that Apple wishes to add legacy support to their kernel.
* Modern Darwin kernels require some amount of EFI because Apple machines all
* have EFI. Modifying the kernel source to not require EFI is of course
* possible but would have to be maintained as a separate patch because it is
* unlikely that Apple wishes to add legacy support to their kernel.
*
* As you can see from the Apple-supplied code in bootstruct.c, it seems that
* the intention was clearly to modify this booter to provide EFI-like structures
* to the kernel rather than modifying the kernel to handle non-EFI stuff. This
* makes a lot of sense from an engineering point of view as it means the kernel
* for the as yet unreleased EFI-only Macs could still be booted by the non-EFI
* DTK systems so long as the kernel checked to ensure the boot tables were
* filled in appropriately. Modern xnu requires a system table and a runtime
* services table and performs no checks whatsoever to ensure the pointers to
* these tables are non-NULL.Therefore, any modern xnu kernel will page fault
* early on in the boot process if the system table pointer is zero.
*
* Even before that happens, the tsc_init function in modern xnu requires the FSB
* Frequency to be a property in the /efi/platform node of the device tree or else
* it panics the bootstrap process very early on.
*
* As of this writing, the current implementation found here is good enough
* to make the currently available xnu kernel boot without modification on a
* system with an appropriate processor. With a minor source modification to
* the tsc_init function to remove the explicit check for Core or Core 2
* processors the kernel can be made to boot on other processors so long as
* the code can be executed by the processor and the machine contains the
* necessary hardware.
*/
As you can see from the Apple-supplied code in bootstruct.c, it seems that
the intention was clearly to modify this booter to provide EFI-like structures
to the kernel rather than modifying the kernel to handle non-EFI stuff. This
makes a lot of sense from an engineering point of view as it means the kernel
for the as yet unreleased EFI-only Macs could still be booted by the non-EFI
DTK systems so long as the kernel checked to ensure the boot tables were
filled in appropriately. Modern xnu requires a system table and a runtime
services table and performs no checks whatsoever to ensure the pointers to
these tables are non-NULL. Therefore, any modern xnu kernel will page fault
early on in the boot process if the system table pointer is zero.
Even before that happens, the tsc_init function in modern xnu requires the FSB
Frequency to be a property in the /efi/platform node of the device tree or else
it panics the bootstrap process very early on.
As of this writing, the current implementation found here is good enough
to make the currently available xnu kernel boot without modification on a
system with an appropriate processor. With a minor source modification to
the tsc_init function to remove the explicit check for Core or Core 2
processors the kernel can be made to boot on other processors so long as
the code can be executed by the processor and the machine contains the
necessary hardware.
*/
/*==========================================================================
* Utility function to make a device tree string from an EFI_GUID
*/
static inline char * mallocStringForGuid(EFI_GUID const *pGuid)
{
char *string = malloc(37);
efi_guid_unparse_upper(pGuid, string);
return string;
char *string = malloc(37);
efi_guid_unparse_upper(pGuid, string);
return string;
}
/*==========================================================================
* Function to map 32 bit physical address to 64 bit virtual address
*/
static uint64_t ptov64(uint32_t addr)
{
return ((uint64_t)addr | 0xFFFFFF8000000000ULL);
return ((uint64_t)addr | 0xFFFFFF8000000000ULL);
}
/*==========================================================================
* Fake EFI implementation
*/
static EFI_UINT32 const FIRMWARE_REVISION = 132; /* FIXME: Find a constant for this. */
/* Default platform system_id (fix by IntVar) */
static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF";//random value gen by uuidgen
static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF"; //random value gen by uuidgen
/* Just a ret instruction */
static uint8_t const VOIDRET_INSTRUCTIONS[] = {0xc3};
/* movl $0x80000003,%eax; ret */
static uint8_t const UNSUPPORTEDRET_INSTRUCTIONS[] = {0xb8, 0x03, 0x00, 0x00, 0x80, 0xc3};
/* We use the fake_efi_pages struct so that we only need to do one kernel
* memory allocation for all needed EFI data. Otherwise, small allocations
* like the FIRMWARE_VENDOR string would take up an entire page.
* NOTE WELL: Do NOT assume this struct has any particular layout within itself.
* It is absolutely not intended to be publicly exposed anywhere
* We say pages (plural) although right now we are well within the 1 page size
* and probably will stay that way.
*/
struct fake_efi_pages
{
EFI_SYSTEM_TABLE_64 efiSystemTable;
EFI_RUNTIME_SERVICES_64 efiRuntimeServices;
EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];
};
EFI_SYSTEM_TABLE_64 *gST = NULL;
EFI_SYSTEM_TABLE_32 *gST32 = NULL;
EFI_SYSTEM_TABLE_64 *gST64 = NULL;
Node *gEfiConfigurationTableNode = NULL;
extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias)
{
EFI_UINTN i = gST->NumberOfTableEntries;
/* We only do adds, not modifications and deletes like InstallConfigurationTable */
if(i >= MAX_CONFIGURATION_TABLE_ENTRIES)
stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n");
if(pGuid == NULL)
return EFI_INVALID_PARAMETER;
if(table != NULL)
{
/* FIXME
((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;
++gST->NumberOfTableEntries;
*/
Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));
/* Use the pointer to the GUID we just stuffed into the system table */
DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);
/* The "table" property is the 32-bit (in our implementation) physical address of the table */
DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);
/* Assume the alias pointer is a global or static piece of data */
if(alias != NULL)
DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
EFI_UINTN i = 0;
//Azi: as is, cpu's with em64t will use EFI64 on pre 10.6 systems,
// wich seems to cause no problem. In case it does, force i386 arch.
if (archCpuType == CPU_TYPE_I386)
{
i = gST32->NumberOfTableEntries;
}
else
{
i = gST64->NumberOfTableEntries;
}
// We only do adds, not modifications and deletes like InstallConfigurationTable
if (i >= MAX_CONFIGURATION_TABLE_ENTRIES)
stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n");
if (pGuid == NULL)
return EFI_INVALID_PARAMETER;
if (table != NULL)
{
// FIXME
//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;
//++gST->NumberOfTableEntries;
Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));
// Use the pointer to the GUID we just stuffed into the system table
DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);
// The "table" property is the 32-bit (in our implementation) physical address of the table
DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);
// Assume the alias pointer is a global or static piece of data
if (alias != NULL)
DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);
return EFI_SUCCESS;
}
return EFI_UNSUPPORTED;
}
static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 *efiSystemTable)
//Azi: crc32 done in place, on the cases were it wasn't.
/*static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 *efiSystemTable)
{
efiSystemTable->Hdr.CRC32 = 0;
efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, efiSystemTable->Hdr.HeaderSize);
}
efiSystemTable->Hdr.CRC32 = 0;
efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, efiSystemTable->Hdr.HeaderSize);
}*/
/*
What we do here is simply allocate a fake EFI system table and a fake EFI
runtime services table.
* What we do here is simply allocate a fake EFI system table and a fake EFI
* runtime services table.
*
* Because we build against modern headers with kBootArgsRevision 4 we
* also take care to set efiMode = 32.
*/
Because we build against modern headers with kBootArgsRevision 4 we
also take care to set efiMode = 32.
*/
void
setupEfiTables(void)
void setupEfiTables32(void)
{
struct fake_efi_pages *fakeEfiPages= (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));
// We use the fake_efi_pages struct so that we only need to do one kernel
// memory allocation for all needed EFI data. Otherwise, small allocations
// like the FIRMWARE_VENDOR string would take up an entire page.
// NOTE WELL: Do NOT assume this struct has any particular layout within itself.
// It is absolutely not intended to be publicly exposed anywhere
// We say pages (plural) although right now we are well within the 1 page size
// and probably will stay that way.
struct fake_efi_pages
{
EFI_SYSTEM_TABLE_32 efiSystemTable;
EFI_RUNTIME_SERVICES_32 efiRuntimeServices;
EFI_CONFIGURATION_TABLE_32 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];
};
struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));
// Zero out all the tables in case fields are added later
bzero(fakeEfiPages, sizeof(struct fake_efi_pages));
// --------------------------------------------------------------------
// Initialize some machine code that will return EFI_UNSUPPORTED for
// functions returning int and simply return for void functions.
memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));
memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));
// --------------------------------------------------------------------
// System table
EFI_SYSTEM_TABLE_32 *efiSystemTable = gST32 = &fakeEfiPages->efiSystemTable;
efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_32);
efiSystemTable->Hdr.CRC32 = 0; // Initialize to zero and then do CRC32
efiSystemTable->Hdr.Reserved = 0;
efiSystemTable->FirmwareVendor = (EFI_PTR32)&fakeEfiPages->firmwareVendor;
memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));
efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;
// XXX: We may need to have basic implementations of ConIn/ConOut/StdErr
// The EFI spec states that all handles are invalid after boot services have been
// exited so we can probably get by with leaving the handles as zero.
efiSystemTable->ConsoleInHandle = 0;
efiSystemTable->ConIn = 0;
efiSystemTable->ConsoleOutHandle = 0;
efiSystemTable->ConOut = 0;
efiSystemTable->StandardErrorHandle = 0;
efiSystemTable->StdErr = 0;
efiSystemTable->RuntimeServices = (EFI_PTR32)&fakeEfiPages->efiRuntimeServices;
// According to the EFI spec, BootServices aren't valid after the
// boot process is exited so we can probably do without it.
// Apple didn't provide a definition for it in pexpert/i386/efi.h
// so I'm guessing they don't use it.
efiSystemTable->BootServices = 0;
efiSystemTable->NumberOfTableEntries = 0;
efiSystemTable->ConfigurationTable = (EFI_PTR32)fakeEfiPages->efiConfigurationTable;
// We're done. Now CRC32 the thing so the kernel will accept it.
// Must be initialized to zero before CRC32, done above.
gST32->Hdr.CRC32 = crc32(0L, gST32, gST32->Hdr.HeaderSize);
// --------------------------------------------------------------------
// Runtime services
EFI_RUNTIME_SERVICES_32 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;
efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;
efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;
efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_32);
efiRuntimeServices->Hdr.CRC32 = 0;
efiRuntimeServices->Hdr.Reserved = 0;
// There are a number of function pointers in the efiRuntimeServices table.
// These are the Foundation (e.g. core) services and are expected to be present on
// all EFI-compliant machines.Some kernel extensions (notably AppleEFIRuntime)
// will call these without checking to see if they are null.
//
// We don't really feel like doing an EFI implementation in the bootloader
// but it is nice if we can at least prevent a complete crash by
// at least providing some sort of implementation until one can be provided
// nicely in a kext.
void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;
void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;
efiRuntimeServices->GetTime = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->SetTime = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->GetWakeupTime = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->SetWakeupTime = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->SetVirtualAddressMap = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->ConvertPointer = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->GetVariable = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->GetNextVariableName = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->SetVariable = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->GetNextHighMonotonicCount = (EFI_PTR32)unsupportedret_fp;
efiRuntimeServices->ResetSystem = (EFI_PTR32)voidret_fp;
// We're done.Now CRC32 the thing so the kernel will accept it
efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);
// --------------------------------------------------------------------
// Finish filling in the rest of the boot args that we need.
bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
bootArgs->efiMode = kBootArgsEfiMode32;
// The bootArgs structure as a whole is bzero'd so we don't need to fill in
// things like efiRuntimeServices* and what not.
//
// In fact, the only code that seems to use that is the hibernate code so it
// knows not to save the pages. It even checks to make sure its nonzero.
}
/* Zero out all the tables in case fields are added later */
bzero(fakeEfiPages, sizeof(struct fake_efi_pages));
/* --------------------------------------------------------------------
* Initialize some machine code that will return EFI_UNSUPPORTED for
* functions returning int and simply return for void functions.
*/
memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));
memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));
/* -------------------------------------------------------------------- */
/* System table */
EFI_SYSTEM_TABLE_64 *efiSystemTable = gST = &fakeEfiPages->efiSystemTable;
efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64);
efiSystemTable->Hdr.CRC32 = 0; /* Initialize to zero and then do CRC32 */
efiSystemTable->Hdr.Reserved = 0;
efiSystemTable->FirmwareVendor = (EFI_PTR32)&fakeEfiPages->firmwareVendor;
memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));
efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;
/* XXX: We may need to have basic implementations of ConIn/ConOut/StdErr */
/* The EFI spec states that all handles are invalid after boot services have been
* exited so we can probably get by with leaving the handles as zero. */
efiSystemTable->ConsoleInHandle = 0;
efiSystemTable->ConIn = 0;
efiSystemTable->ConsoleOutHandle = 0;
efiSystemTable->ConOut = 0;
efiSystemTable->StandardErrorHandle = 0;
efiSystemTable->StdErr = 0;
efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices);
/* According to the EFI spec, BootServices aren't valid after the
* boot process is exited so we can probably do without it.
* Apple didn't provide a definition for it in pexpert/i386/efi.h
* so I'm guessing they don't use it.
*/
efiSystemTable->BootServices = 0;
efiSystemTable->NumberOfTableEntries = 0;
efiSystemTable->ConfigurationTable = (EFI_PTR32)fakeEfiPages->efiConfigurationTable;
/* We're done. Now CRC32 the thing so the kernel will accept it */
fixupEfiSystemTableCRC32(efiSystemTable);
/* -------------------------------------------------------------------- */
/* Runtime services */
EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;
efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;
efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;
efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64);
efiRuntimeServices->Hdr.CRC32 = 0;
efiRuntimeServices->Hdr.Reserved = 0;
/* There are a number of function pointers in the efiRuntimeServices table.
* These are the Foundation (e.g. core) services and are expected to be present on
* all EFI-compliant machines. Some kernel extensions (notably AppleEFIRuntime)
* will call these without checking to see if they are null.
*
* We don't really feel like doing an EFI implementation in the bootloader
* but it is nice if we can at least prevent a complete crash by
* at least providing some sort of implementation until one can be provided
* nicely in a kext.
*/
void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;
void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;
efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp);
/* We're done. Now CRC32 the thing so the kernel will accept it */
efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);
/* -------------------------------------------------------------------- */
/* Finish filling in the rest of the boot args that we need. */
bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
bootArgs->efiMode = kBootArgsEfiMode64;
/* The bootArgs structure as a whole is bzero'd so we don't need to fill in
* things like efiRuntimeServices* and what not.
*
* In fact, the only code that seems to use that is the hibernate code so it
* knows not to save the pages. It even checks to make sure its nonzero.
*/
void setupEfiTables64(void)
{
struct fake_efi_pages
{
EFI_SYSTEM_TABLE_64 efiSystemTable;
EFI_RUNTIME_SERVICES_64 efiRuntimeServices;
EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];
};
struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));
// Zero out all the tables in case fields are added later
bzero(fakeEfiPages, sizeof(struct fake_efi_pages));
// --------------------------------------------------------------------
// Initialize some machine code that will return EFI_UNSUPPORTED for
// functions returning int and simply return for void functions.
memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));
memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));
// --------------------------------------------------------------------
// System table
EFI_SYSTEM_TABLE_64 *efiSystemTable = gST64 = &fakeEfiPages->efiSystemTable;
efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64);
efiSystemTable->Hdr.CRC32 = 0; // Initialize to zero and then do CRC32
efiSystemTable->Hdr.Reserved = 0;
efiSystemTable->FirmwareVendor = ptov64((EFI_PTR32)&fakeEfiPages->firmwareVendor);
memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));
efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;
// XXX: We may need to have basic implementations of ConIn/ConOut/StdErr
// The EFI spec states that all handles are invalid after boot services have been
// exited so we can probably get by with leaving the handles as zero.
efiSystemTable->ConsoleInHandle = 0;
efiSystemTable->ConIn = 0;
efiSystemTable->ConsoleOutHandle = 0;
efiSystemTable->ConOut = 0;
efiSystemTable->StandardErrorHandle = 0;
efiSystemTable->StdErr = 0;
efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices);
// According to the EFI spec, BootServices aren't valid after the
// boot process is exited so we can probably do without it.
// Apple didn't provide a definition for it in pexpert/i386/efi.h
// so I'm guessing they don't use it.
efiSystemTable->BootServices = 0;
efiSystemTable->NumberOfTableEntries = 0;
efiSystemTable->ConfigurationTable = ptov64((EFI_PTR32)fakeEfiPages->efiConfigurationTable);
// We're done.Now CRC32 the thing so the kernel will accept it
gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize);
// --------------------------------------------------------------------
// Runtime services
EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;
efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;
efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;
efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64);
efiRuntimeServices->Hdr.CRC32 = 0;
efiRuntimeServices->Hdr.Reserved = 0;
// There are a number of function pointers in the efiRuntimeServices table.
// These are the Foundation (e.g. core) services and are expected to be present on
// all EFI-compliant machines.Some kernel extensions (notably AppleEFIRuntime)
// will call these without checking to see if they are null.
//
// We don't really feel like doing an EFI implementation in the bootloader
// but it is nice if we can at least prevent a complete crash by
// at least providing some sort of implementation until one can be provided
// nicely in a kext.
void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;
void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;
efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp);
efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp);
// We're done.Now CRC32 the thing so the kernel will accept it
efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);
// --------------------------------------------------------------------
// Finish filling in the rest of the boot args that we need.
bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
bootArgs->efiMode = kBootArgsEfiMode64;
// The bootArgs structure as a whole is bzero'd so we don't need to fill in
// things like efiRuntimeServices* and what not.
//
// In fact, the only code that seems to use that is the hibernate code so it
// knows not to save the pages. It even checks to make sure its nonzero.
}
/*
In addition to the EFI tables there is also the EFI device tree node.
In particular, we need /efi/platform to have an FSBFrequency key. Without it,
the tsc_init function will panic very early on in kernel startup, before
the console is available.
*/
* In addition to the EFI tables there is also the EFI device tree node.
* In particular, we need /efi/platform to have an FSBFrequency key. Without it,
* the tsc_init function will panic very early on in kernel startup, before
* the console is available.
*/
/*==========================================================================
* FSB Frequency detection
*/
/* From Foundation/Efi/Guid/Smbios/SmBios.c */
EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID;
EFI_GUID constgEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID;
#define SMBIOS_RANGE_START 0x000F0000
#define SMBIOS_RANGE_END 0x000FFFFF
#define SMBIOS_RANGE_START0x000F0000
#define SMBIOS_RANGE_END0x000FFFFF
/* '_SM_' in little endian: */
#define SMBIOS_ANCHOR_UINT32_LE 0x5f4d535f
#define EFI_ACPI_TABLE_GUID \
{ \
0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define EFI_ACPI_20_TABLE_GUID \
{ \
0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
}
EFI_GUID gEfiAcpiTableGuid = EFI_ACPI_TABLE_GUID;
static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor";
static const char const FIRMWARE_ABI_32_PROP_VALUE[] = "EFI32";
static const char const FIRMWARE_ABI_64_PROP_VALUE[] = "EFI64";
static const char const SYSTEM_ID_PROP[] = "system-id";
static const char const SYSTEM_SERIAL_PROP[] = "SystemSerialNumber";
static const char const SYSTEM_TYPE_PROP[] = "system-type";
static const char const MODEL_PROP[] = "Model";
/* Get an smbios option string option to convert to EFI_CHAR16 string */
/*
* Get an smbios option string option to convert to EFI_CHAR16 string
*/
static EFI_CHAR16* getSmbiosChar16(const char * key, size_t* len)
{
const char * src= getStringForKey(key, &bootInfo->smbiosConfig);
EFI_CHAR16* dst = 0;
size_t i=0;
const char*src = getStringForKey(key, &bootInfo->smbiosConfig);
EFI_CHAR16* dst = 0;
size_t i = 0;
if (!key || !(*key) || !len || !src) return 0;
*len = strlen(src);
dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 );
for (; i < (*len); i++) dst[i] = src[i];
dst[(*len)] = '\0';
*len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16
return dst;
}
if (!key || !(*key) || !len || !src) return 0;
/*
* Get the SystemID from the bios dmi info
*/
*len = strlen(src);
dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 );
for (; i < (*len); i++) dst[i] = src[i];
dst[(*len)] = '\0';
*len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16
return dst;
}
/* Get the SystemID from the bios dmi info */
static EFI_CHAR8* getSmbiosUUID()
staticEFI_CHAR8* getSmbiosUUID()
{
static EFI_CHAR8 uuid[UUID_LEN];
int i, isZero, isOnes;
struct SMBEntryPoint*smbios;
SMBByte*p;
inti, isZero, isOnes;
static EFI_CHAR8 uuid[UUID_LEN];
smbios = getSmbios(SMBIOS_PATCHED);/* checks for _SM_ anchor and table header checksum */
SMBByte*p;
smbios = getSmbios(SMBIOS_PATCHED); // checks for _SM_ anchor and table header checksum
if (smbios==NULL) return 0; // getSmbios() return a non null value if smbios is found
p = (SMBByte*) FindFirstDmiTableOfType(1, 0x19); /* Type 1: (3.3.2) System Information */
p = (SMBByte*) FindFirstDmiTableOfType(1, 0x19); // Type 1: (3.3.2) System Information
if (p==NULL) return NULL;
verbose("Found SMBIOS System Information Table 1\n");
p += 8;
for (i=0, isZero=1, isOnes=1; i<UUID_LEN; i++) {
for (i=0, isZero=1, isOnes=1; i<UUID_LEN; i++)
{
if (p[i] != 0x00) isZero = 0;
if (p[i] != 0xff) isOnes = 0;
}
if (isZero || isOnes) {/* empty or setable means: no uuid present */
if (isZero || isOnes) // empty or setable means: no uuid present
{
verbose("No UUID present in SMBIOS System Information Table\n");
return 0;
}
memcpy(uuid, p, UUID_LEN);
return uuid;
}
/* return a binary UUID value from the overriden SystemID and SMUUID if found,
/*
* return a binary UUID value from the overriden SystemID and SMUUID if found,
* or from the bios if not, or from a fixed value if no bios value is found
*/
static EFI_CHAR8* getSystemID()
{ // unable to determine UUID for host. Error: 35 fix
{
// unable to determine UUID for host. Error: 35 fix
// Rek: new SMsystemid option conforming to smbios notation standards, this option should
// belong to smbios config only ...
const char *sysId = getStringForKey(kSystemID, &bootInfo->bootConfig);
EFI_CHAR8*ret = getUUIDFromString(sysId);
// Rek: new SMsystemid option conforming to smbios notation standards, this option should
// belong to smbios config only ...
const char * sysId = getStringForKey(kSystemID, &bootInfo->bootConfig);
EFI_CHAR8* ret = getUUIDFromString(sysId);
if (!sysId || !ret) // try bios dmi info UUID extraction
{
ret = getSmbiosUUID();
sysId = 0;
}
if (!ret) // no bios dmi UUID available, set a fixed value for system-id
ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID));
verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output
return ret;
}
if(!sysId || !ret) { // try bios dmi info UUID extraction
ret = getSmbiosUUID();
sysId = 0;
}
if(!ret) // no bios dmi UUID available, set a fixed value for system-id
ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID));
/*
* Must be called AFTER setup Acpi because we need to take care of correct
* facp content to reflect in ioregs
*/
verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output
return ret;
}
// must be called AFTER setup Acpi because we need to take care of correct facp content to reflect in ioregs
void setupSystemType()
{
Node *node = DT__FindNode("/", false);
if (node == 0) stop("Couldn't get root node");
// we need to write this property after facp parsing
/* Export system-type only if it has been overrriden by the SystemType option */
DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type);
Node *node = DT__FindNode("/", false);
if (node == 0) stop("Couldn't get root node");
// we need to write this property after facp parsing
// Export system-type only if it has been overrriden by the SystemType option
DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type);
}
void setupEfiDeviceTree(void)
{
EFI_CHAR16* ret16=0;
EFI_CHAR8* ret=0;
size_t len=0;
Node *node;
node = DT__FindNode("/", false);
if (node == 0) stop("Couldn't get root node");
/* We could also just do DT__FindNode("/efi/platform", true)
* But I think eventually we want to fill stuff in the efi node
* too so we might as well create it so we have a pointer for it too.
*/
node = DT__AddChild(node, "efi");
DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
EFI_CHAR8* ret = 0;
EFI_CHAR16* ret16 = 0;
size_t len = 0;
Node*node;
if(platformCPUFeature(CPU_FEATURE_EM64T))
node = DT__FindNode("/", false);
if (node == 0) stop("Couldn't get root node");
// We could also just do DT__FindNode("/efi/platform", true)
// But I think eventually we want to fill stuff in the efi node
// too so we might as well create it so we have a pointer for it too.
node = DT__AddChild(node, "efi");
if (archCpuType == CPU_TYPE_I386)
{
DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE);
}
else
{
DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE);
}
DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);
// TODO: Fill in other efi properties if necessary
// Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
// is set up. That is, name and table properties
Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");
if (archCpuType == CPU_TYPE_I386)
{
// The value of the table property is the 32-bit physical address for the RuntimeServices table.
// Since the EFI system table already has a pointer to it, we simply use the address of that pointer
// for the pointer to the property data. Warning.. DT finalization calls free on that but we're not
// the only thing to use a non-malloc'd pointer for something in the DT
DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices);
}
else
{
DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE);
DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices);
}
DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);
// Set up the /efi/configuration-table node which will eventually have several child nodes for
// all of the configuration tables needed by various kernel extensions.
gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");
// Now fill in the /efi/platform Node
Node *efiPlatformNode = DT__AddChild(node, "platform");
// NOTE WELL: If you do add FSB Frequency detection, make sure to store
// the value in the fsbFrequency global and not an malloc'd pointer
// because the DT_AddProperty function does not copy its args.
if (Platform.CPU.FSBFrequency != 0)
DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
// Export TSC and CPU frequencies for use by the kernel or KEXTs
if (Platform.CPU.TSCFrequency != 0)
DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
if (Platform.CPU.CPUFrequency != 0)
DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
// Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist
if ((ret=getSystemID()))
DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret);
/* TODO: Fill in other efi properties if necessary */
// Export SystemSerialNumber if present
if ((ret16=getSmbiosChar16("SMserial", &len)))
DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16);
// Export Model if present
if ((ret16=getSmbiosChar16("SMproductname", &len)))
DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16);
// Fill /efi/device-properties node.
setupDeviceProperties(node);
}
/* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
* is set up. That is, name and table properties */
Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");
/*
* Load the smbios.plist override config file if any
*/
/* The value of the table property is the 32-bit physical address for the RuntimeServices table.
* Since the EFI system table already has a pointer to it, we simply use the address of that pointer
* for the pointer to the property data. Warning.. DT finalization calls free on that but we're not
* the only thing to use a non-malloc'd pointer for something in the DT
*/
DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices);
static void setupSmbiosConfigFile(const char *filename)
{
chardirSpecSMBIOS[128] = "";
const char *override_pathname = NULL;
intlen = 0, err = 0;
extern void scan_mem();
// Take in account user overriding
if (getValueForKey(kSMBIOSKey, &override_pathname, &len, &bootInfo->bootConfig) && len > 0)
{
// Specify a path to a file, e.g. SMBIOS=/Extra/macProXY.plist
sprintf(dirSpecSMBIOS, override_pathname);
err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig);
}
else
{
// Check selected volume's Extra.
sprintf(dirSpecSMBIOS, "/Extra/%s", filename);
if (err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig))
{
// Check booter volume/rdbt Extra.
sprintf(dirSpecSMBIOS, "bt(0,0)/Extra/%s", filename);
err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig);
}
}
/* Set up the /efi/configuration-table node which will eventually have several child nodes for
* all of the configuration tables needed by various kernel extensions.
*/
gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");
if (err)
{
verbose("No SMBIOS replacement found.\n");
}
/* Now fill in the /efi/platform Node */
Node *efiPlatformNode = DT__AddChild(node, "platform");
/* NOTE WELL: If you do add FSB Frequency detection, make sure to store
* the value in the fsbFrequency global and not an malloc'd pointer
* because the DT_AddProperty function does not copy its args.
*/
if(Platform.CPU.FSBFrequency != 0)
DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
/* Export TSC and CPU frequencies for use by the kernel or KEXTs */
if(Platform.CPU.TSCFrequency != 0)
DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
if(Platform.CPU.CPUFrequency != 0)
DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
/* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */
if((ret=getSystemID()))
DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret);
/* Export SystemSerialNumber if present */
if ((ret16=getSmbiosChar16("SMserial", &len)))
DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16);
/* Export Model if present */
if ((ret16=getSmbiosChar16("SMproductname", &len)))
DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16);
/* Fill /efi/device-properties node.
*/
setupDeviceProperties(node);
// get a chance to scan mem dynamically if user asks for it while having the config options loaded as well,
// as opposed to when it was in scan_platform(); also load the orig. smbios so that we can access dmi info without
// patching the smbios yet
getSmbios(SMBIOS_ORIGINAL);
scan_mem();
smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED);// process smbios asap
}
/* Load the smbios.plist override config file if any */
static void setupSmbiosConfigFile()
{
const char * value = getStringForKey(kSMBIOS, &bootInfo->bootConfig);
extern void scan_mem();
/*
* Installs all the needed configuration table entries
*/
if (!value) value = "/Extra/smbios.plist";
if (loadConfigFile(value, &bootInfo->smbiosConfig) == -1) {
verbose("No SMBIOS replacement found\n");
}
// get a chance to scan mem dynamically if user asks for it while having the config options loaded as well
// as opposed to when it was in scan_platform(), also load the orig. smbios so that we can access dmi info without
// patching the smbios yet
getSmbios(SMBIOS_ORIGINAL);
scan_mem();
smbios_p = (EFI_PTR32) getSmbios(SMBIOS_PATCHED);// process smbios asap
}
/* Installs all the needed configuration table entries */
static void setupEfiConfigurationTable()
{
smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED);
addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL);
// Setup ACPI with DSDT overrides (mackerintel's patch)
setupAcpi();
// We've obviously changed the count.. so fix up the CRC32
fixupEfiSystemTableCRC32(gST);
smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED);
addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL);
// Setup ACPI with DSDT overrides (mackerintel's patch)
setupAcpi();
// We've obviously changed the count.. so fix up the CRC32
if (archCpuType == CPU_TYPE_I386)
{
gST32->Hdr.CRC32 = 0;
gST32->Hdr.CRC32 = crc32(0L, gST32, gST32->Hdr.HeaderSize);
}
else
{
gST64->Hdr.CRC32 = 0;
gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize);
}
}
static void setupEfiDevices(setup)
/*
* Entrypoint from boot.c
*/
void setupFakeEfi(void)
{
// Generate efi device strings
setup_pci_devs(root_pci_dev);
}
/* Entrypoint from boot.c */
void setupFakeEfi(void)
{
// load smbios.plist file if any
setupSmbiosConfigFile();
// load smbios.plist file if any
setupSmbiosConfigFile("SMBIOS.plist");
// Generate efi device strings
setupEfiDevices();
// Initialize the base table
if (archCpuType == CPU_TYPE_I386)
{
setupEfiTables32();
}
else
{
setupEfiTables64();
}
// Initialize the base table
setupEfiTables();
// Initialize the device tree
setupEfiDeviceTree();
// Initialize the device tree
setupEfiDeviceTree();
// Add configuration table entries to both the services table and the device tree
setupEfiConfigurationTable();
// Add configuration table entries to both the services table and the device tree
setupEfiConfigurationTable();
}
branches/meklort/i386/libsaio/msdos.h
2424
2525
2626
27
27
2828
2929
3030
3131
3232
33
33
extern long MSDOSInitPartition(CICell ih);
extern long MSDOSLoadFile(CICell ih, char * filePath);
extern long MSDOSReadFile(CICell ih, char * filePath, void *base, uint64_t offset, uint64_t length);
extern long MSDOSGetDirEntry(CICell ih, char * dirPath, long * dirIndex,
extern long MSDOSGetDirEntry(CICell ih, char * dirPath, long long * dirIndex,
char ** name, long * flags, long * time,
FinderInfo * finderInfo, long * infoValid);
extern long MSDOSGetFileBlock(CICell ih, char *str, unsigned long long *firstBlock);
extern long MSDOSGetUUID(CICell ih, char *uuidStr);
extern void MSDOSFree(CICell ih);
extern int MSDOSProbe (const void *buf);
extern int MSDOSProbe (const void *buf);
branches/meklort/i386/libsaio/saio_internal.h
8989
9090
9191
92
93
9294
9395
96
9497
9598
9699
......
170173
171174
172175
173
176
174177
175178
176179
......
183186
184187
185188
189
190
191
186192
187193
188194
......
199205
200206
201207
208
202209
203210
204211
/* console.c */
extern bool gVerboseMode;
extern bool gErrors;
extern void initBooterLog(void);
extern void setupBooterLog(void);
extern void putchar(int ch);
extern int getchar(void);
extern void msglog(const char * format, ...);
extern int printf(const char *format, ...);
extern int error(const char *format, ...);
extern int verbose(const char *format, ...);
extern long LoadFile(const char *fileSpec);
extern long ReadFileAtOffset(const char * fileSpec, void *buffer, uint64_t offset, uint64_t length);
extern long LoadThinFatFile(const char *fileSpec, void **binary);
extern long GetDirEntry(const char *dirSpec, long *dirIndex, const char **name,
extern long GetDirEntry(const char *dirSpec, long long *dirIndex, const char **name,
long *flags, long *time);
extern long GetFileInfo(const char *dirSpec, const char *name,
long *flags, long *time);
extern int close(int fdesc);
extern int file_size(int fdesc);
extern int read(int fdesc, char *buf, int count);
extern int write(int fdesc, const char *buf, int count);
extern int writebyte(int fdesc, char value);
extern int writeint(int fdesc, int value);
extern int b_lseek(int fdesc, int addr, int ptr);
extern int tell(int fdesc);
extern const char * systemConfigDir(void);
extern void getBootVolumeDescription(BVRef bvr, char *str, long strMaxLen, bool verbose);
extern void setRootVolume(BVRef volume);
extern void setBootGlobals(BVRef chain);
extern int getDeviceDescription(BVRef volume, char *str);
extern int gBIOSDev;
extern int gBootFileType;
branches/meklort/i386/boot0/boot0.s
5555
5656
5757
58
58
5959
6060
6161
;
; Set to 1 to enable verbose mode
;
VERBOSEEQU 0
VERBOSEEQU 1
;
; Various constants.
branches/meklort/i386/boot1/boot1.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
; boot1.asm - boot1 written for turbo assembler, since gas only
; generates 32 bit code and this must run in real mode.
; To compile as hard disk boot1:
;tasm /m3 /dBOOTDEV=HDISK boot1
;tlink boot1
;exe2bin boot1
;ren boot1.bin boot1
; To compile as floppy boot1f:
;tasm /m3 /dBOOTDEV=FLOPPY boot1 ,boot1f
;tlink boot1f
;exe2bin boot1f
;ren boot1f.bin boot1f
;***********************************************************************
;This is the code for the NeXT boot1 bootsector.
;***********************************************************************
P486;enable i386 instructions
IDEAL
SEGMENT CSEG
ASSUME CS:CSEG,DS:CSEG
SDEBUG = 0
;BOOTSEG=100h; boot will be loaded at 4k
;BOOTOFF=0000h
BOOTSEG=00h
BOOTOFF=1000h
BUFSZ=2000h; 8K disk transfer buffer
; FDISK partition table in sector 0
PARTSTART=1beh; starting address of partition table
NUMPART=4; number of partitions in partition table
PARTSZ=16; each partition table entry is 16 bytes
BOOT_IND=0; offset of boot indicator in partition table
BEG_HEAD=1; offset of beginning head
BEG_SEC= 2; offset of beginning sector
BEG_CYL=3; offset of beginning cylinder
NAME_OFFSET=4; offset of partition name
PARTSEC=8; offset of partition sector specifier
NEXTNAME=0A7h; value of boot_ind, means bootable partition
LOADSZ=88; maxiumum possible size of unix boot-- 44k
FLOPPY=0
HDISK=80h
;BOOTDEV=?; set to 00h for floppy, 80h for hard disk
; (use a command line switch to set)
; NeXT disk label
DISKLABEL=15; sector num of 2nd disk label, 1st is trashed by bootsec
DL_DISKTAB=44
; We support disk label version 3 "3Vld" in our little endian world
DL_V3= 33566c64h
; NeXT disktab
DT_SECSIZE=48
DT_BOOT0_BLKNO=80
-
; This code is a replacement for boot1. It is loaded at 0x0:0x7c00
start:
movax,BOOTSEG
cli; interrupts off
movss,ax; set up stack seg
movsp,0fff0h
sti; reenable interrupts
xorax,ax
moves,ax
movds,ax
movsi,7C00h
cld; so pointers will get updated
movdi,0E000h; relocate boot program to 0xE000
movcx,100h; copy 256x2 bytes
repnzmovsw; move it
off1= 0E000h + (a1 - start)
jmpFAR 0000:off1; jump to a1 in relocated place
a1:
movax,0E00h
movds,ax
movax,BOOTSEG
moves,ax
; load the boot loader (boot2) into BOOTSEG:BUFSZ
callloadboot
; ljmp to the second stage boot loader (boot2).
; After ljmp, cs is BOOTSEG and boot1 (BUFSZ bytes) will be used
; as an internal buffer "intbuf".
xoredx,edx; bootdev = 0 for hard disk
IF( BOOTDEV EQ FLOPPY )
incedx; bootdev = 1 for floppy disk
ENDIF
;boot2 immediately follows disk buffer; 4K + BUFSZ
jmpFAR BOOTSEG:(BOOTOFF + BUFSZ)
; jump to boot2 in loaded location
loadboot:
movsi, OFFSET intro
callmessage; display intro message
; load second stage boot from fixed disk
; get boot drive parameters
; Note: I believe that the bootsector read may not be necessary;
; at least some blk0 bootsectors leave a pointer to the active
; partition entry in si (assuming there was another blk0 bootsec)
callgetinfo
-
IF( BOOTDEV EQ HDISK )
; read sector 0 into BOOTSEG:0 by using BIOS call (INT 13H 02H)
; this gets info on the disk's actual partition table
; However, in the case of multiple partitions, this may not
; be the same as the sector with the code here.
movdi,5; try 5 times to read bootsector
retry_disk:
xorbx, bx; buffer is BOOTSEG:0
movax,201h
movcx,bx
movdx,bx
movbx,BOOTOFF; actually, it's 0:BOOTOFF
inccx; cyl 0, sector 1
movdl,BOOTDEV; target 0, head 0
pushdi
int13h; read the bootsector
popdi
jnbread_success1
; woops, bios failed to read sector
xorax,ax
int13h; reset disk
decdi
jneretry_disk
jmpread_error; disk failed
read_success1:; find the NeXT partition
movbx,PARTSTART
movcx,NUMPART
again:
moval, [es:(bx+BOOTOFF)+NAME_OFFSET]
; get partition name
cmpal, NEXTNAME; is it NeXT partition?
jnecont; nope, keep looking
foundNextPart:; found it, get label location
moveax, [es:(bx+BOOTOFF)+PARTSEC]
; offset to NeXT partition
addeax, DISKLABEL; add offset to the label
jmpgetLabl; fetch that label
cont:
addbx, PARTSZ
loopagain; if more part table entries,
; keep looking
; fall through, didn't find NeXT disk partition entry
no_fdisk:
ENDIF
; Read NeXT disk label
moveax, DISKLABEL; Get block number of label
getLabl:
movbx,BOOTOFF; read into load area
movcx,1
callreadSectors
; we used to think about testing the disk label version here...
movbx,BOOTOFF; point to beginning of label
; Use values from label to read entire boot program
; Get block number of boot
; Get dl_secsize and dl_boot0_blkno[0]
movedx, [es:(bx + DL_DISKTAB+DT_SECSIZE)]
bswapedx; edx -> sector size
moveax, [es:(bx + DL_DISKTAB+DT_BOOT0_BLKNO)]
bswapeax; eax -> block #
; Compute dl_secsize * dt_boot0_blkno[0] / 512
shredx, 9; divide dl_secsize by 512
muledx; multiply boot block loc
; by dl_secsize/512
; eax has secno
movbx, (BUFSZ + BOOTOFF); read boot2 into BOOTSEG:BUFSZ
movedi, LOADSZ; read this many sectors
nexsec:
pusheax; push sector #
pushbx; push buffer address
movecx, edi; max number of sectors to read
callreadSectors
popbx
popeax
addeax, ecx; add number of sectors read
subdi, cx
shlcx, 9; multiply by 512 bytes per sector
addbx, cx
cmp di, 0
jnenexsec
ret
spt:DW0; sectors;track (one-based)
spc:DW0; tracks;cylinder (zero-based)
nsec:DW0; number of sectors to read
readSectors:; eax has starting block #, bx has offset from BOOTSEG
; cx has maximum number of sectors to read
; Trashes ax, bx, cx, dx
; BIOS call "INT 0x13 Function 0x2" to read sectors
;ah = 0x2al = number of sectors
;ch = cylindercl = sector
;dh = headdl = drive (0x80=hard disk, 0=floppy disk)
;es:bx = segment:offset of buffer
IF( BOOTDEV EQ FLOPPY )
pusheax
moval,'.'
callputchr
popeax
ENDIF
pushbx; save offset
mov [WORD nsec], cx
movebx, eax; bx -> block #
xorecx, ecx
movcx, [WORD spc]; cx -> sectors/cyl
xoredx,edx; prepare for division
divecx; eax = cyl, edx=remainder
pushax; save cylinder #, sec/spc
moveax, edx
movcx, [WORD spt]; ecx -> sectors/track
xoredx,edx; prepare for division
divecx; eax = head
pushax; save head, (secspc)/spt
moveax, ebx; reload block #
xoredx, edx; prepare for division
divecx; edx has sector #
subcx, dx ;cx now has number of sectors to read
cmpcx, [WORD nsec]
jgelast; use the minimum of bx and cx
mov[WORD nsec], cx
last:
movcx, dx; cl -> sector
inccl; starts @ 1
popax; get head
movdh, al; dh -> head
popax; get cyl
movch, al; ch -> cyl
movdl, BOOTDEV; floppy disk
xoral,al
shrax,2
orcl,al; retain pesky big cyl bits
;moval, 1; get # of sectors
;pop ax ; number of sectors to read
mov ax, [WORD nsec]
popbx; get buffer
movah, 2; bios read function
int13h
jbread_error
mov cx, [WORD nsec] ; return number of sectors read
ret
getinfo:; get some drive parameters
movdl, BOOTDEV; boot drive is drive C
movah, 8h
pushes
int13h
popes
moval, dh; max head #
incal; al -> tracks/cyl
andcx, 3fh; cl -> secs/track
mulcl; ax -> secs/cyl
mov[WORD spc], ax
mov[WORD spt], cx
ret
message:; write the error message in ds:esi
; to console
pushes
movax,ds
moves,ax
movbx, 1; bh=0, bl=1 (blue)
cld
nextb:
lodsb; load a byte into al
cmpal, 0
jedone
movah, 0eh; bios int 10, function 0xe
int10h; bios display a byte in tty mode
jmpnextb
done:popes
ret
putchr:
pushbx
movbx, 1; bh=0, bl=1 (blue)
movah, 0eh; bios int 10, function 0xe
int10h; bios display a byte in tty mode
popbx
ret
IFSDEBUG
hexout:-; print ebx as hex number
pushcx
pushax
movcx,8;output 8 nibbles
htop:
rolebx,4
moval,bl
andal,0fh
cmpal,0ah
jbo_digit
addal,'A'-10
jmpo_print
o_digit:addal,'0'
o_print:callputchr
deccx
jnehtop
;moval,10
;callputchr
;moval,13
;callputchr
moval,' '
callputchr
popax
popcx
ret
ENDIF
read_error:
movsi, OFFSET eread
boot_exit:; boot_exit: write error message and halt
callmessage; display error message
halt:jmphalt
intro:db10,'NEXTSTEP boot1 vXX.XX.XX.XX.XX',10,13,0
eread:db'Read error',10,13,0
; the last 2 bytes in the sector contain the signature
d1:
a2 = 510 - (d1 - start)
DB a2 dup (0)
DW 0AA55h
ENDS
END
branches/meklort/i386/boot1/boot1f32.s
7575
7676
7777
78
78
7979
8080
8181
kBoot1LoadAddrEQU0x7C00; boot1 load address
kBoot1RelocAddrEQU0xE000; boot1 relocated address
kBoot2SectorsEQU(384 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SectorsEQU(448 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SegmentEQU0x2000; boot2 load segment
kBoot2AddressEQUkSectorBytes; boot2 load address
branches/meklort/i386/boot1/boot1he.s
7979
8080
8181
82
82
8383
8484
8585
kBoot1ExtAddrEQUkBoot1RelocAddr + kSectorBytes; boot1 load address for sector 41-47
kHFSPlusBufferEQUkBoot1RelocAddr + kBoot1ExtSize; HFS+ Volume Header address
kBoot2SectorsEQU(384 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SectorsEQU(448 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SegmentEQU0x2000; boot2 load segment
kBoot2AddressEQUkSectorBytes; boot2 load address
branches/meklort/i386/boot1/boot1.s
5252
5353
5454
55
55
5656
5757
5858
......
7474
7575
7676
77
77
7878
7979
8080
;
; Set to 1 to enable verbose mode.
;
VERBOSEEQU0
VERBOSEEQU1
;
; Various constants.
kBoot1Sector1AddrEQUkBoot1RelocAddr + kSectorBytes; boot1 load address for sector 1
kHFSPlusBufferEQUkBoot1Sector1Addr + kSectorBytes; HFS+ Volume Header address
kBoot2SectorsEQU(384 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SectorsEQU(448 * 1024 - 512) / kSectorBytes; max size of 'boot' file in sectors
kBoot2SegmentEQU0x2000; boot2 load segment
kBoot2AddressEQUkSectorBytes; boot2 load address
branches/meklort/i386/boot1/boot1f32-install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/sh
# boot1f32-install.sh
#
# Created by mackerintel on 2/2/09.
# Copyright 2009 mackerintel. All rights reserved.
if [[ x$1 == x ]]; then
echo Usage: $0 disknumber;
exit 0;
fi
if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then
echo "/dev/disk${1}s1" "isn't" a FAT32 partition;
exit 1;
fi
if [ ! -f boot1f32 ]; then
echo "boot1f32 not found";
exit 1;
fi
dd if=/dev/disk${1}s1 count=1 bs=512 of=/tmp/origbs
cp boot1f32 /tmp/newbs
dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc
dd of=/dev/disk${1}s1 count=1 bs=512 if=/tmp/newbs
branches/meklort/i386/boot2/graphics.c
11271127
11281128
11291129
1130
1130
11311131
11321132
11331133
......
11931193
11941194
11951195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
12111215
12121216
12131217
......
12151219
12161220
12171221
1218
1222
1223
12191224
12201225
12211226
params[1] = 25;
}
setVESATextMode( params[0], params[1], 4 );
setVESATextMode( params[0], params[1], 4 );
bootArgs->Video.v_display = VGA_TEXT_MODE;
}
return;
}
if (gVerboseMode) {
currentTickTime = time18(); // late binding
if (currentTickTime < lastTickTime + MIN_TICKS) {
return;
} else {
lastTickTime = currentTickTime;
}
if (getVideoMode() == VGA_TEXT_MODE) {
if (currentIndicator >= sizeof(indicator)) {
currentIndicator = 0;
}
printf("%c\b", indicator[currentIndicator++]);
}
}
currentTickTime = time18(); // late binding
if (currentTickTime < lastTickTime + MIN_TICKS)
{
return;
}
else
{
lastTickTime = currentTickTime;
}
if (getVideoMode() == VGA_TEXT_MODE)
{
if (currentIndicator >= sizeof(indicator))
{
currentIndicator = 0;
}
putc(indicator[currentIndicator++]);
putc('\b');
}
}
void
{
if ( getVideoMode() == VGA_TEXT_MODE )
{
printf(" \b");
putc(' ');
putc('\b');
}
}
branches/meklort/i386/boot2/boot.c
8585
8686
8787
88
8889
89
9090
9191
9292
......
168168
169169
170170
171
172
171173
172174
173175
......
181183
182184
183185
184
185
186
187
186
187
188
189
188190
191
192
189193
190194
191195
......
195199
196200
197201
202
203
198204
199205
200206
......
254260
255261
256262
263
264
257265
258266
259267
......
333341
334342
335343
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
344352
345353
346354
......
356364
357365
358366
359
360
361367
362368
363369
......
386392
387393
388394
395
389396
390397
391398
392399
393400
394401
395
396
397
398
399
400402
401403
402404
......
404406
405407
406408
409
407410
408411
409412
410413
411414
412
413
414
415
416
417
418
419
415
420416
421417
422418
......
428424
429425
430426
431
432
433
434
427
435428
436429
437430
......
577570
578571
579572
580
581
582
583
584
585
573
574
586575
587576
588577
......
629618
630619
631620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
632653
633654
634655
//static void selectBiosDevice(void);
static unsigned long Adler32(unsigned char *buffer, long length);
static bool getOSVersion(char *str);
static bool gUnloadPXEOnExit = false;
/*
setupFakeEfi();
md0Ramdisk();
verbose("Starting Darwin %s\n",( archCpuType == CPU_TYPE_I386 ) ? "x86" : "x86_64");
// Cleanup the PXE base code.
}
bool dummyVal;
if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) {
printf("Press any key to continue...");
getc();
}
if (getBoolForKey(kWaitForKeypressKey, &dummyVal, &bootInfo->bootConfig) && dummyVal) {
printf("Press any key to continue...");
getc();
}
usb_loop();
// If we were in text mode, switch to graphics mode.
// This will draw the boot graphics unless we are in
// verbose mode.
else
drawBootGraphics();
setupBooterLog();
finalizeBootStruct();
usb_loop();
// Initialize boot info structure.
initKernBootStruct();
initBooterLog();
// Setup VGA text mode.
// Not sure if it is safe to call setVideoMode() before the
// config table has been loaded. Call video_mode() instead.
getc();
#endif
useGUI = true;
// Override useGUI default
getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig);
if (useGUI) {
patchVideoBios();
/* XXX AsereBLN handle error */
initGUI();
}
useGUI = true;
// Override useGUI default
getBoolForKey(kGUIKey, &useGUI, &bootInfo->bootConfig);
if (useGUI && initGUI())
{
// initGUI() returned with an error, disabling GUI.
useGUI = false;
}
setBootGlobals(bvChain);
bool tryresumedefault;
bool forceresume;
config_file_t systemVersion;// system.plist of booting partition
// additional variable for testing alternate kernel image locations on boot helper partitions.
char bootFileSpec[512];
bvChain = newFilteredBVChain(0x80, 0xFF, allowBVFlags, denyBVFlags, &gDeviceCount);
setBootGlobals(bvChain);
setupDeviceList(&bootInfo->themeConfig);
}
continue;
}
// Other status (e.g. 0) means that we should proceed with boot.
if( bootArgs->Video.v_display == GRAPHICS_MODE )
drawBackground();
// Found and loaded a config file. Proceed with boot.
// Turn off any GUI elements
if( bootArgs->Video.v_display == GRAPHICS_MODE )
{
gui.bootprompt.draw = false;
gui.menu.draw = false;
gui.infobox.draw = false;
gui.logo.draw = false;
drawBackground();
updateVRAM();
}
// Find out which version mac os we're booting.
if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion)) {
if (getValueForKey(kProductVersion, &val, &len, &systemVersion)) {
// getValueForKey uses const char for val
// so copy it and trim
strncpy(gMacOSVersion, val, MIN(len, 4));
gMacOSVersion[MIN(len, 4)] = '\0';
}
}
getOSVersion(gMacOSVersion);
if (platformCPUFeature(CPU_FEATURE_EM64T)) {
archCpuType = CPU_TYPE_X86_64;
archCpuType = CPU_TYPE_I386;
}
}
if (getValueForKey(k32BitModeFlag, &val, &len, &bootInfo->bootConfig)) {
archCpuType = CPU_TYPE_I386;
}
if (!getBoolForKey (kWake, &tryresume, &bootInfo->bootConfig)) {
tryresume = true;
tryresumedefault = true;
if (ret <= 0) {
printf("Can't find %s\n", bootFile);
if(gui.initialised) {
sleep(1);
drawBackground();
gui.devicelist.draw = true;
gui.redraw = true;
}
sleep(1);
if (gBootFileType == kNetworkDeviceType) {
// Return control back to PXE. Don't unload PXE base code.
gUnloadPXEOnExit = false;
}
*/
static bool getOSVersion(char *str)
{
bool valid = false;
config_file_t systemVersion;
const char *val;
int len;
if (!loadConfigFile("System/Library/CoreServices/SystemVersion.plist", &systemVersion))
{
valid = true;
}
else if (!loadConfigFile("System/Library/CoreServices/ServerVersion.plist", &systemVersion))
{
valid = true;
}
if (valid)
{
if (getValueForKey(kProductVersion, &val, &len, &systemVersion))
{
// getValueForKey uses const char for val
// so copy it and trim
*str = '\0';
strncat(str, val, MIN(len, 4));
}
else
valid = false;
}
return valid;
}
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5000
// NMAX (was 5521) the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
branches/meklort/i386/boot2/boot.h
4242
4343
4444
45
45
4646
4747
4848
4949
50
50
5151
5252
5353
54
54
5555
5656
5757
58
58
5959
6060
6161
62
63
64
65
62
63
64
65
6666
67
68
69
70
71
72
73
67
68
69
70
71
72
73
74
75
76
77
78
79
80
7481
75
76
82
83
7784
7885
79
80
81
82
83
86
87
8488
85
89
90
91
92
93
8694
87
88
89
90
91
95
9296
9397
9498
......
101105
102106
103107
104
108
105109
106110
107
108111
109112
110113
......
147150
148151
149152
150
151153
152154
153155
......
176178
177179
178180
181
179182
180183
181184
#define kKernelNameKey"Kernel"
#define kKernelCacheKey"Kernel Cache"
#define kBootDeviceKey"Boot Device"
#define kTimeoutKey"Timeout"
#define kTimeoutKey"Timeout"
#define kRootDeviceKey"rd"
#define kBootUUIDKey"boot-uuid"
#define kHelperRootUUIDKey"Root UUID"
#define kPlatformKey"platform"
#define kACPIKey"acpi"
#define kACPIKey"acpi"
#define kCDROMPromptKey"CD-ROM Prompt"
#define kCDROMOptionKey"CD-ROM Option Key"
#define kRescanPromptKey"Rescan Prompt"
#define kRescanKey"Rescan"
#define kRescanKey "Rescan"
#define kScanSingleDriveKey"Scan Single Drive"
#define kInsantMenuKey"Instant Menu"
#define kDefaultKernel"mach_kernel"
#define kGUIKey"GUI"
#define kGUIKey"GUI"
#define kBootBannerKey"Boot Banner"
#define kWaitForKeypressKey"Wait"
/* AsereBLN: added the other keys */
#define kUseAtiROM"UseAtiROM"/* ati.c */
#define kWake"Wake"/* boot.c */
#define kForceWake"ForceWake"/* boot.c */
#define kWakeImage"WakeImage"/* boot.c */
#define kUseAtiROM"UseAtiROM"/* ati.c */
#define kWake"Wake"/* boot.c */
#define kForceWake"ForceWake"/* boot.c */
#define kWakeImage"WakeImage"/* boot.c */
#define kProductVersion"ProductVersion"/* boot.c */
#define karch"arch"/* boot.c */
#define kDSDT"DSDT"/* dsdt_patcher.c */
#define kDropSSDT"DropSSDT"/* dsdt_patcher.c */
#define kRestartFix"RestartFix"/* dsdt_patcher.c */
#define kSMBIOS"SMBIOS"/* fake_efi.c */
#define kSystemID"SystemId"/* fake_efi.c */
#define kSystemType"SystemType"/* fake_efi.c */
#define karch"arch"/* boot.c */
#define kDSDT"DSDT"/* acpi_patcher.c */
#define kDropSSDT"DropSSDT"/* acpi_patcher.c */
#define kRestartFix"RestartFix"/* acpi_patcher.c */
#define kRestartFix"RestartFix" /* acpi_patcher.c */
#define kGeneratePStates"GeneratePStates"/* acpi_patcher.c */
#define kGenerateCStates"GenerateCStates"/* acpi_patcher.c */
#define kEnableC4States"EnableC4State"/* acpi_patcher.c */
#define kDeviceProperties"device-properties"/* device_inject.c */
#define kHidePartition"Hide Partition"/* disk.c */
#define kRenamePartition"Rename Partition"/* disk.c */
#define kSMBIOSKey"SMBIOS"/* fake_efi.c */
#define kSystemID"SystemId"/* fake_efi.c */
#define kSystemType"SystemType"/* fake_efi.c */
#define kUseNvidiaROM"UseNvidiaROM"/* nvidia.c */
#define kVBIOS"VBIOS"/* nvidia.c */
#define kPCIRootUID"PCIRootUID"/* pci_root.c */
#define kVBIOS"VBIOS"/* nvidia.c */
#define kPCIRootUID"PCIRootUID"/* pci_root.c */
#define kEthernetBuiltIn"EthernetBuiltIn"/* pci_setup.c */
#define kGraphicsEnabler"GraphicsEnabler"/* pci_setup.c */
#define kUSBBusFix"USBBusFix"/* pci_setup.c */
#define kEHCIacquire"EHCIacquire"/* pci_setup.c */
#define kUHCIreset"UHCIreset"/* usb.c */
#define kForceHPET"ForceHPET"/* usb.c */
#define kLegacyOff"USBLegacyOff"/* usb.c */
#define kForceHPET"ForceHPET"/* pci_setup.c */
#define kUseMemDetect"UseMemDetect" /* platform.c */
#define kSMBIOSdefaults"SMBIOSdefaults"/* smbios_patcher.c */
#define kEHCIhard"EHCIhard"/* usb.c */
#define kUSBBusFix"USBBusFix"/* usb.c */
#define kEHCIacquire"EHCIacquire"/* usb.c */
#define kUHCIreset"UHCIreset"/* usb.c */
#define kLegacyOff"USBLegacyOff"/* usb.c */
#define kEHCIhard"EHCIhard"/* usb.c */
#define kDefaultPartition"Default Partition"/* sys.c */
#define kDeviceProperties"device-properties"/* device_inject.c */
#define kHidePartition"Hide Partition"/* disk.c */
#define kRenamePartition"Rename Partition"/* disk.c */
#define kUseMemDetect "UseMemDetect" /* platform.c */
#define kRestartFix "RestartFix" /* dsdt_patcher.c */
#define kMD0Image"md0"/* ramdisk.h */
#define kScreenWidth"ScreenWidth"/* edid.h */
#define kScreenHeight"ScreenHeight"/* edid.h */
*/
#define kVerboseModeFlag"-v"
#define kSafeModeFlag"-x"
#define kOldSafeModeFlag"-f"
#define kIgnoreCachesFlag"-f"
#define kIgnoreBootFileFlag"-F"
#define kSingleUserModeFlag"-s"
#define k32BitModeFlag"-x32"
/*
* Booter behavior control
*/
extern int usb_loop();
/*
* graphics.c
*/
extern void drawPreview(void *src, uint8_t * saveunder);
extern int getVideoMode(void);
extern void loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or);
/*
* drivers.c
*/
branches/meklort/i386/boot2/drivers.c
191191
192192
193193
194
195
196
197
198
199
200
201
202
203
204
205
206
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
207213
208214
209215
......
237243
238244
239245
240
241
246
242247
243
248
244249
245250
246
247
251
252
253
254
255
256
248257
249258
250259
......
279288
280289
281290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
282316
283317
284318
285319
286320
287
321
322
288323
289324
290325
291326
292327
293
328
329
330
294331
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
332
333
334
311335
312
313
314
315
316
317
318
319
320
321
322
323
324
325336
326337
327338
......
356367
357368
358369
359
370
360371
361372
362373
{
verbose("Loading recovery extensions\n");
const char* recoveryFolder;
int len;
if (getValueForKey(kWakeImage, &recoveryFolder, &len, &bootInfo->bootConfig))
{
sprintf(dirSpecExtra, "/Extra/%s/", &recoveryFolder);
if(FileLoadDrivers(dirSpecExtra, 0) != 0)
{
verbose("Unable to locate recovery extensions\n");
}
}
else {
verbose("Unable to locate recovery extensions\n");
}
// Next try to load Extra extensions from the selected root partition.
strcpy(dirSpecExtra, "/Extra/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
// If failed, then try to load Extra extensions from the boot partition
// in case we have a separate booter partition or a bt(0,0) aliased ramdisk.
if ( !(gBIOSBootVolume->biosdev == gBootVolume->biosdev && gBIOSBootVolume->part_no == gBootVolume->part_no)
|| (gRAMDiskVolume && gRAMDiskBTAliased) )
{
// Next try a specfic OS version folder ie 10.5
sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
// Next we'll try the base
strcpy(dirSpecExtra, "bt(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
}
else
}
// Also try to load Extensions from boot helper partitions.
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
if (gBootVolume->flags & kBVFlagBooter)
{
strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
FileLoadDrivers(dirSpecExtra, 0);
strcpy(dirSpecExtra, "/com.apple.boot.R/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 0)
{
strcpy(dirSpecExtra, "/com.apple.boot.S/System/Library/");
FileLoadDrivers(dirSpecExtra, 0);
}
}
}
}
//==========================================================================
// FileLoadMKext
static long
FileLoadMKext( const char * dirSpec, const char * extDirSpec )
{
long ret, flags, time, time2;
char altDirSpec[512];
sprintf (altDirSpec, "%s%s", dirSpec, extDirSpec);
ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
{
ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
{
sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
if (LoadDriverMKext(gDriverSpec) == 0) return 0;
}
}
return -1;
}
//==========================================================================
// FileLoadDrivers
static long
FileLoadDrivers( char * dirSpec, long plugin )
{
long ret, length, index, flags, time, bundleType;
long ret, length, flags, time, bundleType;
long long index;
long result = -1;
const char * name;
if ( !plugin )
{
long time2;
// First try 10.6's path for loading Extensions.mkext.
if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)
return 0;
// TODO: refactor this part of code.
char altDirSpec[4500];
sprintf (altDirSpec,"%sCaches/com.apple.kext.caches/Startup/",dirSpec);
ret = GetFileInfo(altDirSpec, "Extensions.mkext", &flags, &time);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
{
ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
{
sprintf(gDriverSpec, "%sExtensions.mkext", altDirSpec);
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
if (LoadDriverMKext(gDriverSpec) == 0) return 0;
}
}
//
// Next try the legacy path.
else if (FileLoadMKext(dirSpec, "") == 0)
return 0;
ret = GetFileInfo(dirSpec, "Extensions.mkext", &flags, &time);
if ((ret == 0) && ((flags & kFileTypeMask) == kFileTypeFlat))
{
ret = GetFileInfo(dirSpec, "Extensions", &flags, &time2);
if ((ret != 0) || ((flags & kFileTypeMask) != kFileTypeDirectory) ||
(((gBootMode & kBootModeSafe) == 0) && (time == (time2 + 1))))
{
sprintf(gDriverSpec, "%sExtensions.mkext", dirSpec);
verbose("LoadDrivers: Loading from [%s]\n", gDriverSpec);
if (LoadDriverMKext(gDriverSpec) == 0) return 0;
}
}
strcat(dirSpec, "Extensions");
}
result = ret;
if (!plugin)
result = FileLoadDrivers(gDriverSpec, 1);
FileLoadDrivers(gDriverSpec, 1);
}
return result;
branches/meklort/i386/boot2/gui.c
1313
1414
1515
16
1617
1718
1819
1920
2021
21
22
23
24
25
26
2722
2823
24
25
2926
3027
3128
......
3330
3431
3532
36
33
3734
3835
3936
......
4239
4340
4441
45
46
42
43
4744
48
49
50
51
52
53
54
55
56
57
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
5863
59
60
61
62
63
64
65
66
67
68
69
64
65
66
7067
71
72
68
69
70
71
72
73
74
75
76
77
78
7379
74
75
80
81
7682
77
78
83
84
85
86
87
7988
8089
8190
82
83
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
84112
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
116137
117138
118139
......
148169
149170
150171
151
172
152173
174
175
176
177
178
179
180
181
182
183
184
153185
154
186
155187
156
157
158
159
160
161
162
163
164
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
165203
166
167
168
169
170
204
205
206
171207
172
173
174
175
176
208
177209
210
211
212
213
214
215
216
217
218
219
220
221
178222
179
223
180224
181225
182
226
227
183228
184229
185
230
231
232
233
186234
187235
188236
......
190238
191239
192240
193
194
195
196
197
198
199
200
201
202
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
203290
204
205
291
292
206293
207
208
209
210
211
212
213
214
215
294
295
296
216297
217298
218299
219
220300
221301
222
223
302
303
224304
225
226
227
228
229
230
231
232
233
234
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
235323
236
237
238
239
240
241
242
243
244
245
246
324
325
326
247327
248
249
328
329
330
331
332
333
334
335
336
337
338
250339
251
252
340
341
253342
254
255
343
344
256345
346
347
348
257349
258350
259351
......
326418
327419
328420
421
422
423
424
425
426
427
428
429
430
431
432
329433
330434
331435
......
348452
349453
350454
351
455
456
457
458
352459
353460
354461
355462
356
463
357464
358
359
360465
361466
362467
363468
364469
365470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
366536
367537
368538
......
411581
412582
413583
414
584
415585
416586
417
418
587
419588
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466589
467590
468591
......
558681
559682
560683
561
562
563
564
565
566
567
568
569684
570685
571686
......
575690
576691
577692
693
694
695
696
697
698
699
700
578701
702
579703
580
581704
582705
583
706
584707
585708
586
709
587710
588711
589
590712
591713
592714
......
603725
604726
605727
606
728
607729
608730
609731
......
613735
614736
615737
616
738
739
617740
618741
619742
......
630753
631754
632755
633
756
634757
635758
636
759
637760
638761
639762
......
642765
643766
644767
645
646
647
768
769
648770
649
771
650772
651773
652774
653
775
654776
655777
656778
657
779
658780
659781
660782
661
783
662784
663785
664786
665
787
666788
667789
668790
669791
670792
671793
794
795
796
797
798
799
800
672801
673802
674803
......
718847
719848
720849
721
850
722851
723
852
724853
725
854
855
726856
727
728
729
730
731
732
733
734
857
858
859
860
861
862
863
864
865
866
735867
736868
737869
738870
739
740
741871
742
743
744
745
746
747
748
749
750
751
752
753
754
755
872
873
874
875
876
877
878
879
880
881
882
883
884
885
756886
757887
758888
759
889
760890
761891
762892
......
16931823
16941824
16951825
1826
16961827
16971828
16981829
......
17041835
17051836
17061837
1707
1838
17081839
17091840
17101841
17111842
1712
1843
17131844
17141845
17151846
17161847
1717
17181848
17191849
17201850
17211851
1852
1853
1854
17221855
17231856
17241857
......
17261859
17271860
17281861
1729
1862
1863
1864
1865
17301866
17311867
1732
1868
17331869
17341870
17351871
#include "vers.h"
#include "edid.h"
#define IMG_REQUIRED -1
#define THEME_NAME_DEFAULT"Default"
static const char *theme_name = THEME_NAME_DEFAULT;
#ifdef EMBED_THEME
#include "art.h"
#define LOADPNG(img) \
if (loadThemeImage(#img) != 0) \
if (loadEmbeddedThemeImage(#img, __## img ##_png, __## img ##_png_len) != 0) \
return 1;
#else
#define LOADPNG(img)if (loadThemeImage(#img) != 0) { return 1; }
#endif
#define LOADPNG(img, alt_img) if (loadThemeImage(#img, alt_img) != 0) { return 1; }
#define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define vram VIDEO(baseAddr)
int lasttime=0; // we need this for animating maybe
int lasttime = 0; // we need this for animating maybe
extern int gDeviceCount;
* ATTENTION: the enum and the following array images[] MUST match !!!
*/
enum {
iBackground = 0,
iLogo,
iBackground = 0,
iLogo,
iDeviceGeneric,
iDeviceHFS,
iDeviceEXT3,
iDeviceFAT16,
iDeviceFAT32,
iDeviceNTFS,
iDeviceCDROM,
iSelection,
iDeviceScrollPrev,
iDeviceScrollNext,
iDeviceGeneric,
iDeviceGeneric_o,
iDeviceHFS,
iDeviceHFS_o,
iDeviceHFSRAID,
iDeviceHFSRAID_o,
iDeviceEXT3,
iDeviceEXT3_o,
iDeviceFAT,
iDeviceFAT_o,
iDeviceFAT16,
iDeviceFAT16_o,
iDeviceFAT32,
iDeviceFAT32_o,
iDeviceNTFS,
iDeviceNTFS_o,
iDeviceCDROM,
iDeviceCDROM_o,
iMenuBoot,
iMenuVerbose,
iMenuIgnoreCaches,
iMenuSingleUser,
iMenuMemoryInfo,
iMenuVideoInfo,
iMenuHelp,
iMenuVerboseDisabled,
iMenuIgnoreCachesDisabled,
iMenuSingleUserDisabled,
iMenuSelection,
iSelection,
iDeviceScrollPrev,
iDeviceScrollNext,
iProgressBar,
iProgressBarBackground,
iMenuBoot,
iMenuVerbose,
iMenuIgnoreCaches,
iMenuSingleUser,
iMenuMemoryInfo,
iMenuVideoInfo,
iMenuHelp,
iMenuVerboseDisabled,
iMenuIgnoreCachesDisabled,
iMenuSingleUserDisabled,
iMenuSelection,
iTextScrollPrev,
iTextScrollNext,
iProgressBar,
iProgressBarBackground,
iFontConsole,
iFontSmall,
iTextScrollPrev,
iTextScrollNext,
iFontConsole,
iFontSmall,
};
image_t images[] = {
{.name = "background",.image = NULL},
{.name = "logo",.image = NULL},
{.name = "background", .image = NULL},
{.name = "logo", .image = NULL},
{.name = "device_generic", .image = NULL},
{.name = "device_generic_o", .image = NULL},
{.name = "device_hfsplus", .image = NULL},
{.name = "device_hfsplus_o", .image = NULL},
{.name = "device_hfsraid", .image = NULL},
{.name = "device_hfsraid_o", .image = NULL},
{.name = "device_ext3", .image = NULL},
{.name = "device_ext3_o", .image = NULL},
{.name = "device_fat", .image = NULL},
{.name = "device_fat_o", .image = NULL},
{.name = "device_fat16", .image = NULL},
{.name = "device_fat16_o", .image = NULL},
{.name = "device_fat32", .image = NULL},
{.name = "device_fat32_o", .image = NULL},
{.name = "device_ntfs", .image = NULL},
{.name = "device_ntfs_o", .image = NULL},
{.name = "device_cdrom", .image = NULL},
{.name = "device_cdrom_o", .image = NULL},
{.name = "device_generic",.image = NULL},
{.name = "device_hfsplus",.image = NULL},
{.name = "device_ext3",.image = NULL},
{.name = "device_fat16",.image = NULL},
{.name = "device_fat32",.image = NULL},
{.name = "device_ntfs",.image = NULL},
{.name = "device_cdrom",.image = NULL},
{.name = "device_selection",.image = NULL},
{.name = "device_scroll_prev",.image = NULL},
{.name = "device_scroll_next",.image = NULL},
{.name = "menu_boot",.image = NULL},
{.name = "menu_verbose",.image = NULL},
{.name = "menu_ignore_caches",.image = NULL},
{.name = "menu_single_user",.image = NULL},
{.name = "menu_memory_info",.image = NULL},
{.name = "menu_video_info",.image = NULL},
{.name = "menu_help",.image = NULL},
{.name = "menu_verbose_disabled",.image = NULL},
{.name = "menu_ignore_caches_disabled",.image = NULL},
{.name = "menu_single_user_disabled",.image = NULL},
{.name = "menu_selection",.image = NULL},
{.name = "progress_bar",.image = NULL},
{.name = "progress_bar_background",.image = NULL},
{.name = "text_scroll_prev",.image = NULL},
{.name = "text_scroll_next",.image = NULL},
{.name = "font_console",.image = NULL},
{.name = "font_small",.image = NULL},
{.name = "device_selection", .image = NULL},
{.name = "device_scroll_prev", .image = NULL},
{.name = "device_scroll_next", .image = NULL},
{.name = "menu_boot", .image = NULL},
{.name = "menu_verbose", .image = NULL},
{.name = "menu_ignore_caches", .image = NULL},
{.name = "menu_single_user", .image = NULL},
{.name = "menu_memory_info", .image = NULL},
{.name = "menu_video_info", .image = NULL},
{.name = "menu_help", .image = NULL},
{.name = "menu_verbose_disabled", .image = NULL},
{.name = "menu_ignore_caches_disabled", .image = NULL},
{.name = "menu_single_user_disabled", .image = NULL},
{.name = "menu_selection", .image = NULL},
{.name = "progress_bar", .image = NULL},
{.name = "progress_bar_background", .image = NULL},
{.name = "text_scroll_prev", .image = NULL},
{.name = "text_scroll_next", .image = NULL},
{.name = "font_console", .image = NULL},
{.name = "font_small", .image = NULL},
};
int imageCnt = 0;
static bool infoMenuNativeBoot = false;
static unsigned long screen_params[4] = {0, 0, 0, 0};// here we store the used screen resolution
static unsigned long screen_params[4] = {DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT, 32, 0};// here we store the used screen resolution
static int getImageIndexByName(const char *name)
{
int i;
for (i = 0; i < sizeof(images) / sizeof(images[0]); i++)
{
if (strcmp(name, images[i].name) == 0)
return i; // found the name
}
return -1;
}
#ifdef EMBED_THEME
static int loadEmbeddedThemeImage(const char *image, unsigned char *image_data, unsigned int image_size)
static int getEmbeddedImageIndexByName(const char *name)
{
inti;
uint16_twidth;
uint16_theight;
uint8_t*imagedata;
for (i=0; i < sizeof(images) / sizeof(images[0]); i++) {
if (strcmp(image, images[i].name) == 0) {
if (images[i].image == NULL) {
images[i].image = malloc(sizeof(pixmap_t));
int upperLimit = sizeof(embeddedImages) / sizeof(embeddedImages[0]) - 1;
int lowerLimit = 0;
int compareIndex = (upperLimit - lowerLimit) >> 1; // Midpoint
int result;
// NOTE: This algorithm assumes that the embeddedImages is sorted.
// This is currently done using the make file. If the array is every
// manualy generated, this *will* fail to work properly.
while((result = strcmp(name, embeddedImages[compareIndex].name)) != 0)
{
if(result > 0)// We need to search a HIGHER index
{
if(compareIndex != lowerLimit)
{
lowerLimit = compareIndex;
}
width = 0;
height = 0;
imagedata = NULL;
if ((loadEmbeddedPngImage(image_data, image_size, &width, &height, &imagedata)) != 0) {
return 1;
else
{
return -1;
}
images[i].image->width = width;
images[i].image->height = height;
images[i].image->pixels = (pixel_t *)imagedata;
flipRB(images[i].image);
return 0;
compareIndex = (upperLimit + lowerLimit + 1) >> 1;// Midpoint, round up
}
else // We Need to search a LOWER index
{
if(compareIndex != upperLimit)
{
upperLimit = compareIndex;
}
else
{
return -1;
}
compareIndex = (upperLimit + lowerLimit) >> 1;// Midpoint, round down
}
}
return 1;
return compareIndex;
}
#endif
static int loadThemeImage(const char *image)
static int loadThemeImage(const char *image, int alt_image)
{
chardirspec[256];
inti;
int i;
#ifdef EMBED_THEME
int e;
#endif
uint16_twidth;
uint16_theight;
uint8_t*imagedata;
if ((strlen(image) + strlen(theme_name) + 20 ) > sizeof(dirspec)) {
return 1;
}
for (i=0; i < sizeof(images) / sizeof(images[0]); i++) {
if (strcmp(image, images[i].name) == 0) {
if (images[i].image == NULL) {
images[i].image = malloc(sizeof(pixmap_t));
}
sprintf(dirspec,"/Extra/Themes/%s/%s.png", theme_name, image);
width = 0;
height = 0;
imagedata = NULL;
if ((loadPngImage(dirspec, &width, &height, &imagedata)) != 0) {
if ((i = getImageIndexByName(image)) >= 0)
{
if (images[i].image == NULL) {
images[i].image = malloc(sizeof(pixmap_t));
}
sprintf(dirspec, "/Extra/Themes/%s/%s.png", theme_name, image);
width = 0;
height = 0;
imagedata = NULL;
if ((loadPngImage(dirspec, &width, &height, &imagedata)) == 0)
{
images[i].image->width = width;
images[i].image->height = height;
images[i].image->pixels = (pixel_t *)imagedata;
flipRB(images[i].image);
return 0;
}
#ifdef EMBED_THEME
else if ((e = getEmbeddedImageIndexByName(image)) >= 0)
{
unsigned char *embed_data;
unsigned int embed_size;
embed_data = embeddedImages[e].pngdata;
embed_size = *embeddedImages[e].length;
if (loadEmbeddedPngImage(embed_data, embed_size, &width, &height, &imagedata) == 0)
{
images[i].image->width = width;
images[i].image->height = height;
images[i].image->pixels = (pixel_t *)imagedata;
flipRB(images[i].image);
return 0;
}
return 0;
}
#endif
else if (alt_image != IMG_REQUIRED && images[alt_image].image->pixels != NULL)
{
// Using the passed alternate image for non-mandatory images.
// We don't clone the already existing pixmap, but using its properties instead!
images[i].image->width = images[alt_image].image->width;
images[i].image->height = images[alt_image].image->height;
images[i].image->pixels = images[alt_image].image->pixels;
return 0;
}
else
{
#ifndef EMBED_THEME
printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image);
sleep(2);
printf("ERROR: GUI: could not open '%s/%s.png'!\n", theme_name, image);
sleep(2);
#endif
return 1;
}
images[i].image->width = width;
images[i].image->height = height;
images[i].image->pixels = (pixel_t *)imagedata;
flipRB(images[i].image);
return 0;
}
}
return 1;
}
}
return 1;
}
static int loadGraphics(void)
{
LOADPNG(background);
LOADPNG(logo);
LOADPNG(background, IMG_REQUIRED);
LOADPNG(logo, IMG_REQUIRED);
LOADPNG(device_generic);
LOADPNG(device_hfsplus);
LOADPNG(device_ext3);
LOADPNG(device_fat16);
LOADPNG(device_fat32);
LOADPNG(device_ntfs);
LOADPNG(device_cdrom);
LOADPNG(device_selection);
LOADPNG(device_scroll_prev);
LOADPNG(device_scroll_next);
LOADPNG(device_generic, IMG_REQUIRED);
LOADPNG(device_generic_o, iDeviceGeneric);
LOADPNG(device_hfsplus, iDeviceGeneric);
LOADPNG(device_hfsplus_o, iDeviceHFS);
LOADPNG(device_hfsraid, iDeviceGeneric);
LOADPNG(device_hfsraid_o, iDeviceHFSRAID);
LOADPNG(device_ext3, iDeviceGeneric);
LOADPNG(device_ext3_o, iDeviceEXT3);
LOADPNG(device_fat, iDeviceGeneric);
LOADPNG(device_fat_o, iDeviceFAT);
LOADPNG(device_fat16, iDeviceFAT);
LOADPNG(device_fat16_o, iDeviceFAT_o);
LOADPNG(device_fat32, iDeviceFAT);
LOADPNG(device_fat32_o, iDeviceFAT_o);
LOADPNG(device_ntfs, iDeviceGeneric);
LOADPNG(device_ntfs_o, iDeviceNTFS);
LOADPNG(device_cdrom, iDeviceGeneric);
LOADPNG(device_cdrom_o, iDeviceCDROM);
LOADPNG(menu_boot);
LOADPNG(menu_verbose);
LOADPNG(menu_ignore_caches);
LOADPNG(menu_single_user);
LOADPNG(menu_memory_info);
LOADPNG(menu_video_info);
LOADPNG(menu_help);
LOADPNG(menu_verbose_disabled);
LOADPNG(menu_ignore_caches_disabled);
LOADPNG(menu_single_user_disabled);
LOADPNG(menu_selection);
LOADPNG(device_selection, IMG_REQUIRED);
LOADPNG(device_scroll_prev, IMG_REQUIRED);
LOADPNG(device_scroll_next, IMG_REQUIRED);
LOADPNG(progress_bar);
LOADPNG(progress_bar_background);
LOADPNG(menu_boot, IMG_REQUIRED);
LOADPNG(menu_verbose, IMG_REQUIRED);
LOADPNG(menu_ignore_caches, IMG_REQUIRED);
LOADPNG(menu_single_user, IMG_REQUIRED);
LOADPNG(menu_memory_info, IMG_REQUIRED);
LOADPNG(menu_video_info, IMG_REQUIRED);
LOADPNG(menu_help, IMG_REQUIRED);
LOADPNG(menu_verbose_disabled, IMG_REQUIRED);
LOADPNG(menu_ignore_caches_disabled, IMG_REQUIRED);
LOADPNG(menu_single_user_disabled, IMG_REQUIRED);
LOADPNG(menu_selection, IMG_REQUIRED);
LOADPNG(text_scroll_prev);
LOADPNG(text_scroll_next);
LOADPNG(progress_bar, IMG_REQUIRED);
LOADPNG(progress_bar_background, IMG_REQUIRED);
LOADPNG(font_console);
LOADPNG(font_small);
LOADPNG(text_scroll_prev, IMG_REQUIRED);
LOADPNG(text_scroll_next, IMG_REQUIRED);
LOADPNG(font_console, IMG_REQUIRED);
LOADPNG(font_small, IMG_REQUIRED);
initFont( &font_console, &images[iFontConsole]);
initFont( &font_small, &images[iFontSmall]);
return 0;
}
int freeWindowBuffer( window_t *window )
{
if (window->pixmap && window->pixmap->pixels)
{
free(window->pixmap->pixels);
free(window->pixmap);
return 0;
}
return 1;
}
void fillPixmapWithColor(pixmap_t *pm, uint32_t color)
{
int x,y;
blend( images[iBackground].image, gui.screen.pixmap, gui.background.pos );
// draw logo.png into background buffer
blend( images[iLogo].image, gui.screen.pixmap, gui.logo.pos);
if (gui.logo.draw)
{
blend( images[iLogo].image, gui.screen.pixmap, gui.logo.pos);
}
memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
}
void loadThemeValues(config_file_t *theme, bool overide)
void setupDeviceList(config_file_t *theme)
{
unsigned int screen_width = gui.screen.width;
unsigned int screen_height = gui.screen.height;
unsigned int pixel;
intalpha;// transparency level 0 (obligue) - 255 (transparent)
uint32_t color;// color value formatted RRGGBB
int val, len;
const char *string;
if(getIntForKey("devices_max_visible", &val, theme ))
gui.maxdevices = MIN( val, gDeviceCount );
if(getIntForKey("devices_iconspacing", &val, theme ))
gui.devicelist.iconspacing = val;
// check layout for horizontal or vertical
gui.layout = HorizontalLayout;
if(getValueForKey( "devices_layout", &string, &len, theme)) {
if (!strcmp (string, "vertical")) {
gui.layout = VerticalLayout;
}
}
switch (gui.layout) {
case VerticalLayout:
gui.devicelist.height = ((images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height) + gui.devicelist.iconspacing);
gui.devicelist.width = (images[iSelection].image->width + gui.devicelist.iconspacing);
if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) )
gui.devicelist.pos.x = pixel;
if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) )
gui.devicelist.pos.y = pixel;
break;
case HorizontalLayout:
default:
gui.devicelist.width = ((images[iSelection].image->width + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width) + gui.devicelist.iconspacing);
gui.devicelist.height = (images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing);
if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) )
gui.devicelist.pos.x = pixel;
else
gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2;
if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) )
gui.devicelist.pos.y = pixel;
else
gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2;
break;
}
if(getColorForKey("devices_bgcolor", &color, theme))
gui.devicelist.bgcolor = (color & 0x00FFFFFF);
if(getIntForKey("devices_transparency", &alpha, theme))
gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
if (gui.devicelist.pixmap)
{
freeWindowBuffer(&gui.devicelist);
createWindowBuffer(&gui.devicelist);
}
}
void loadThemeValues(config_file_t *theme)
{
unsigned int screen_width = gui.screen.width;
unsigned int screen_height = gui.screen.height;
unsigned int pixel;
intalpha;// transparency level 0 (obligue) - 255 (transparent)
uint32_t color;// color value formatted RRGGBB
int val;
/*
* Parse screen parameters
*/
if(getDimensionForKey("countdown_pos_y", &pixel, theme, screen_height , 0 ) )
gui.countdown.pos.y = pixel;
/*
/*
* Parse devicelist parameters
*/
if(getIntForKey("devices_max_visible", &val, theme ))
gui.maxdevices = MIN( val, gDeviceCount );
setupDeviceList(theme);
if(getIntForKey("devices_iconspacing", &val, theme ))
gui.devicelist.iconspacing = val;
// check layout for horizontal or vertical
gui.layout = HorizontalLayout;
if(getValueForKey( "devices_layout", &string, &len, theme)) {
if (!strcmp (string, "vertical")) {
gui.layout = VerticalLayout;
}
}
switch (gui.layout) {
case VerticalLayout:
gui.devicelist.height = ((images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->height + images[iDeviceScrollNext].image->height) + gui.devicelist.iconspacing);
gui.devicelist.width = (images[iSelection].image->width + gui.devicelist.iconspacing);
if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , images[iSelection].image->width ) )
gui.devicelist.pos.x = pixel;
if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , gui.devicelist.height ) )
gui.devicelist.pos.y = pixel;
break;
case HorizontalLayout:
default:
gui.devicelist.width = ((images[iSelection].image->width + gui.devicelist.iconspacing) * MIN(gui.maxdevices, gDeviceCount) + (images[iDeviceScrollPrev].image->width + images[iDeviceScrollNext].image->width) + gui.devicelist.iconspacing);
gui.devicelist.height = (images[iSelection].image->height + font_console.chars[0]->height + gui.devicelist.iconspacing);
if(getDimensionForKey("devices_pos_x", &pixel, theme, gui.screen.width , gui.devicelist.width ) )
gui.devicelist.pos.x = pixel;
else
gui.devicelist.pos.x = ( gui.screen.width - gui.devicelist.width ) / 2;
if(getDimensionForKey("devices_pos_y", &pixel, theme, gui.screen.height , images[iSelection].image->height ) )
gui.devicelist.pos.y = pixel;
else
gui.devicelist.pos.y = ( gui.screen.height - gui.devicelist.height ) / 2;
break;
}
if(getColorForKey("devices_bgcolor", &color, theme))
gui.devicelist.bgcolor = (color & 0x00FFFFFF);
if(getIntForKey("devices_transparency", &alpha, theme))
gui.devicelist.bgcolor = gui.devicelist.bgcolor | (( 255 - ( alpha & 0xFF) ) << 24);
/*
* Parse infobox parameters
*/
int initGUI(void)
{
//intval;
#ifdef EMBED_THEME
config_file_t*config;
config = &bootInfo->themeConfig;
if (ParseXMLFile((char *)__theme_plist, &config->dictionary) != 0) {
return 1;
}
#else
intlen;
chardirspec[256];
}
sprintf(dirspec, "/Extra/Themes/%s/theme.plist", theme_name);
if (loadConfigFile(dirspec, &bootInfo->themeConfig) != 0) {
#ifdef EMBED_THEME
config_file_t*config;
config = &bootInfo->themeConfig;
if (ParseXMLFile((char *)__theme_plist, &config->dictionary) != 0) {
return 1;
}
#else
return 1;
#endif
}
#endif
/*
// parse display size parameters
if (getIntForKey("screen_width", &val, &bootInfo->themeConfig)) {
if (getIntForKey("screen_width", &val, &bootInfo->themeConfig) && val > 0) {
screen_params[0] = val;
}
if (getIntForKey("screen_height", &val, &bootInfo->themeConfig)) {
if (getIntForKey("screen_height", &val, &bootInfo->themeConfig) && val > 0) {
screen_params[1] = val;
}
screen_params[2] = 32;
*/
getResolution(&screen_params[0], &screen_params[1], &screen_params[2]);
// load graphics otherwise fail and return
if (loadGraphics() == 0) {
loadThemeValues(&bootInfo->themeConfig, true);
loadThemeValues(&bootInfo->themeConfig);
colorFont(&font_small, gui.screen.font_small_color);
colorFont(&font_console, gui.screen.font_console_color);
if (createWindowBuffer(&gui.devicelist) == 0) {
if (createWindowBuffer(&gui.bootprompt) == 0) {
if (createWindowBuffer(&gui.infobox) == 0) {
if (createWindowBuffer(&gui.menu) == 0) {
if (createWindowBuffer(&gui.menu) == 0) {
gui.logo.draw = true;
drawBackground();
// lets copy the screen into the back buffer
memcpy( gui.backbuffer->pixels, gui.screen.pixmap->pixels, gui.backbuffer->width * gui.backbuffer->height * 4 );
return 1;
}
void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p)
void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected)
{
int devicetype;
if( diskIsCDROM(device) )
devicetype = iDeviceCDROM;// Use CDROM icon
else
{
case kPartitionTypeHFS:
// TODO: add apple raid icon choices
devicetype = iDeviceHFS;// Use HFS icon
// Use HFS or HFSRAID icon depending on bvr flags.
devicetype = (device->flags & kBVFlagBooter) ? iDeviceHFSRAID : iDeviceHFS;
break;
case kPartitionTypeHPFS:
devicetype = iDeviceNTFS;// Use HPFS / NTFS icon
break;
case kPartitionTypeFAT16:
devicetype = iDeviceFAT16;// Use FAT16 icon
break;
case kPartitionTypeFAT32:
devicetype = iDeviceFAT32;// Use FAT32 icon
break;
case kPartitionTypeEXT3:
devicetype = iDeviceEXT3;// Use EXT2/3 icon
break;
default:
devicetype = iDeviceGeneric;// Use Generic icon
break;
}
}
// Draw the selection image and use the next (device_*_o) image for the selected item.
if (isSelected)
{
blend(images[iSelection].image, buffer, centeredAt(images[iSelection].image, p));
devicetype++;
}
// draw icon
blend( images[devicetype].image, buffer, centeredAt( images[devicetype].image, p ));
}
// draw visible device icons
for ( i=0; i < gui.maxdevices; i++ )
for (i = 0; i < gui.maxdevices; i++)
{
BVRef param = menuItems[start+i].param;
BVRef param = menuItems[start + i].param;
if((start+i) == selection)
bool isSelected = ((start + i) == selection) ? true : false;
if (isSelected)
{
if(param->flags & kBVFlagNativeBoot)
infoMenuNativeBoot = true;
else
{
infoMenuNativeBoot = false;
if(infoMenuSelection >= INFOMENU_NATIVEBOOT_START && infoMenuSelection <= INFOMENU_NATIVEBOOT_END)
infoMenuSelection = 0;
}
if (param->flags & kBVFlagNativeBoot)
{
infoMenuNativeBoot = true;
}
else
{
infoMenuNativeBoot = false;
if(infoMenuSelection >= INFOMENU_NATIVEBOOT_START && infoMenuSelection <= INFOMENU_NATIVEBOOT_END)
infoMenuSelection = 0;
}
if(gui.menu.draw)
drawInfoMenuItems();
blend( images[iSelection].image, gui.devicelist.pixmap, centeredAt( images[iSelection].image, p ) );
#if DEBUG
gui.debug.cursor = pos( 10, 100);
dprintf( &gui.screen, "label %s\n", param->label );
dprintf( &gui.screen, "biosdev 0x%x\n", param->biosdev );
dprintf(&gui.screen, "width %d\n", gui.screen.width);
dprintf(&gui.screen, "height %d\n", gui.screen.height);
dprintf( &gui.screen, "type 0x%x\n", param->type );
dprintf( &gui.screen, "flags 0x%x\n", param->flags );
dprintf( &gui.screen, "part_no %d\n", param->part_no );
dprintf( &gui.screen, "part_boff 0x%x\n", param->part_boff );
dprintf( &gui.screen, "part_type 0x%x\n", param->part_type );
dprintf( &gui.screen, "bps 0x%x\n", param->bps );
dprintf( &gui.screen, "name %s\n", param->name );
dprintf( &gui.screen, "type_name %s\n", param->type_name );
dprintf( &gui.screen, "modtime %d\n", param->modTime );
gui.debug.cursor = pos( 10, 100);
dprintf( &gui.screen, "label %s\n", param->label );
dprintf( &gui.screen, "biosdev 0x%x\n", param->biosdev );
dprintf(&gui.screen, "width %d\n", gui.screen.width);
dprintf(&gui.screen, "height %d\n", gui.screen.height);
dprintf( &gui.screen, "type 0x%x\n", param->type );
dprintf( &gui.screen, "flags 0x%x\n", param->flags );
dprintf( &gui.screen, "part_no %d\n", param->part_no );
dprintf( &gui.screen, "part_boff 0x%x\n", param->part_boff );
dprintf( &gui.screen, "part_type 0x%x\n", param->part_type );
dprintf( &gui.screen, "bps 0x%x\n", param->bps );
dprintf( &gui.screen, "name %s\n", param->name );
dprintf( &gui.screen, "type_name %s\n", param->type_name );
dprintf( &gui.screen, "modtime %d\n", param->modTime );
#endif
}
drawDeviceIcon( param, gui.devicelist.pixmap, p );
drawDeviceIcon( param, gui.devicelist.pixmap, p, isSelected);
if (gui.layout == HorizontalLayout)
{
//int pos;
int length;
const char *dummyVal;
int oldScreenWidth, oldScreenHeight;
bool legacy_logo;
uint16_t x, y;
/*
// parse screen size parameters
if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig)) {
if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig) && pos > 0) {
screen_params[0] = pos;
} else {
screen_params[0] = DEFAULT_SCREEN_WIDTH;
}
if (getIntForKey("boot_height", &pos, &bootInfo->themeConfig)) {
if (getIntForKey("boot_height", &pos, &bootInfo->themeConfig) && pos > 0) {
screen_params[1] = pos;
} else {
screen_params[1] = DEFAULT_SCREEN_HEIGHT;
}
screen_params[2] = 32;
*/
getResolution(&screen_params[0], &screen_params[1], &screen_params[2]);
// Save current screen resolution.
oldScreenWidth = gui.screen.width;
oldScreenHeight = gui.screen.height;
gui.screen.width = screen_params[0];
gui.screen.height = screen_params[1];
// find best matching vesa mode for our requested width & height
getGraphicModeParams(screen_params);
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
// Set graphics mode if the booter was in text mode or the screen resolution has changed.
if (bootArgs->Video.v_display == VGA_TEXT_MODE
|| (screen_params[0] != oldScreenWidth && screen_params[1] != oldScreenHeight) )
{
setVideoMode(GRAPHICS_MODE, 0);
}
if (getValueForKey("-checkers", &dummyVal, &length, &bootInfo->bootConfig)) {
drawCheckerBoard();
} else {
branches/meklort/i386/boot2/gui.h
134134
135135
136136
137
137
138
138139
139140
140141
int initGUI();
void drawBackground();
void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p);
void setupDeviceList(config_file_t *theme);
void drawDeviceIcon(BVRef device, pixmap_t *buffer, position_t p, bool isSelected);
void drawDeviceList(int start, int end, int selection);
void drawProgressBar(pixmap_t *blendInto, uint16_t width, position_t p, uint8_t progress);
branches/meklort/i386/boot2/ramdisk.c
1616
1717
1818
19
2019
2120
2221
......
3635
3736
3837
39
38
39
40
4041
4142
4243
43
4444
4545
4646
47
48
47
4948
5049
51
5250
5351
52
5453
5554
5655
5756
58
5957
6058
61
59
6260
6361
6462
6563
6664
6765
68
66
6967
7068
7169
......
7674
7775
7876
79
8077
8178
8279
8380
8481
85
8682
87
83
84
8885
89
90
91
86
87
88
89
9290
9391
94
95
92
9693
97
94
9895
9996
10097
101
10298
10399
104
105
106
107
108
109
110
111
112
113
114
115
116
117
100
101
102
103
104
105
118106
119
120
121
122
123
124
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
125123
126124
127125
128126
129
130
127
128
131129
132
133
134
135
136
130
131
132
133
134
137135
138
139
140
141
142
143
144
145
146
147
136
137
138
139
140
148141
149
150
151
152
153
154
155
156
142
143
144
145
157146
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
147
148
149
185150
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
151
152
153
154
201155
202
203
204
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
205202
206203
207204
208205
209
210
211
212
213
214
206
207
208
209
210
211
212
213
214
215215
216216
217217
218218
219
220
219
220
221221
222
223
224
222
223
224
225225
226
227
228
226
227
228
229229
230
231
232
233
234
235
236
237
238
239
240
241
230
231
232
233
234
235
236
237
238
239
240
241
242
243
242244
243245
244246
245247
246
247
248
249
250
251
252
253
254
255
248
249
250
251
252
253
254
255
256
257
256258
257259
258260
259261
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
307309
bool gRAMDiskBTAliased = false;
char gRAMDiskFile[512];
// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
void md0Ramdisk()
{
if(fh < 0)
{
sprintf(filename, "rd(0,0)/Extra/%s", override_filename);
if((fh = open(filename, 0)) < 0)
fh = open(filename, 0);
if(fh < 0)
{
sprintf(filename, "/Extra/%s", override_filename);
fh = open(filename, 0);
}
}
}
if(fh < 0)
{
// Fallback to Postboot.img
sprintf(filename, "rd(0,0)/Extra/Postboot.img");
fh = open(filename, 0);
if(fh < 0)
{
sprintf(filename, "/Extra/Postboot.img");// Check /Extra if not in rd(0,0)
fh = open(filename, 0);
}
}
if (fh >= 0)
{
verbose("Enabling ramdisk %s\n", filename);
ramdiskPtr.size = file_size(fh);
ramdiskPtr.base = AllocateKernelMemory(ramdiskPtr.size);
if(ramdiskPtr.size && ramdiskPtr.base)
{
// Read new ramdisk image contents in kernel memory.
if(node != NULL)
{
DT__AddProperty(node, "RAMDisk", sizeof(RAMDiskParam), (void*)&ramdiskPtr);
}
else
{
verbose("Unable to notify Mac OS X of the ramdisk %s.\n", filename);
}
}
else {
else
{
verbose("Unable to read md0 image %s.\n", filename);
}
} else {
}
}
else
{
verbose("md0 image %s is empty.\n", filename);
}
close(fh);
}
}
void umountRAMDisk()
{
if (gRAMDiskMI != NULL)
{
// Release ramdisk BVRef and DiskBVMap.
struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
CacheReset();
diskFreeMap(oldMap);
// Free multiboot info and module structures.
if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
if (gRAMDiskMI != NULL) free(gRAMDiskMI);
// Reset multiboot structures.
gMI = gRAMDiskMI = NULL;
*gRAMDiskFile = '\0';
if (gRAMDiskMI != NULL)
{
// Release ramdisk BVRef and DiskBVMap.
struct DiskBVMap *oldMap = diskResetBootVolumes(0x100);
CacheReset();
diskFreeMap(oldMap);
// Release ramdisk driver hooks.
p_get_ramdisk_info = NULL;
p_ramdiskReadBytes = NULL;
printf("\nunmounting: done");
}
// Free multiboot info and module structures.
if ((void *)gRAMDiskMI->mi_mods_addr != NULL) free((void *)gRAMDiskMI->mi_mods_addr);
if (gRAMDiskMI != NULL) free(gRAMDiskMI);
// Reset multiboot structures.
gMI = gRAMDiskMI = NULL;
*gRAMDiskFile = '\0';
// Release ramdisk driver hooks.
p_get_ramdisk_info = NULL;
p_ramdiskReadBytes = NULL;
// Reset ramdisk bvr
gRAMDiskVolume = NULL;
printf("\nunmounting: done");
}
}
int mountRAMDisk(const char * param)
{
int fh = 0, ramDiskSize;
int error = 0;
int fh = 0, ramDiskSize;
int error = 0;
// Get file handle for ramdisk file.
fh = open(param, 0);
if (fh != -1)
{
printf("\nreading ramdisk image: %s", param);
// Get file handle for ramdisk file.
fh = open(param, 0);
if (fh != -1)
{
printf("\nreading ramdisk image: %s", param);
ramDiskSize = file_size(fh);
if (ramDiskSize > 0)
{
// Unmount previously mounted image if exists.
umountRAMDisk();
// Read new ramdisk image contents into PREBOOT_DATA area.
if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
}
else error = -1;
ramDiskSize = file_size(fh);
if (ramDiskSize > 0)
{
// Unmount previously mounted image if exists.
umountRAMDisk();
close(fh);
}
else error = -1;
if (error == 0)
{
// Save filename in gRAMDiskFile to display information.
strcpy(gRAMDiskFile, param);
// Read new ramdisk image contents into PREBOOT_DATA area.
if (read(fh, (char *)PREBOOT_DATA, ramDiskSize) != ramDiskSize) error = -1;
}
else error = -1;
// Set gMI as well for the multiboot ramdisk driver hook.
gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
// Fill in multiboot info and module structures.
if (gRAMDiskMI != NULL && ramdisk_module != NULL)
{
gRAMDiskMI->mi_mods_count = 1;
gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
ramdisk_module->mm_mod_start = PREBOOT_DATA;
ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
// Set ramdisk driver hooks.
p_get_ramdisk_info = &multiboot_get_ramdisk_info;
p_ramdiskReadBytes = &multibootRamdiskReadBytes;
int partCount; // unused
// Save bvr of the mounted image.
gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
if(gRAMDiskVolume == NULL)
{
umountRAMDisk();
printf("\nRamdisk contains no partitions.");
}
else
{
char dirSpec[128];
close(fh);
}
else error = -1;
// Reading ramdisk configuration.
strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
{
getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
}
else
{
printf("\nno ramdisk config...\n");
}
printf("\nmounting: done");
}
}
if (error == 0)
{
// Save filename in gRAMDiskFile to display information.
strcpy(gRAMDiskFile, param);
}
return error;
// Set gMI as well for the multiboot ramdisk driver hook.
gMI = gRAMDiskMI = malloc(sizeof(multiboot_info));
struct multiboot_module * ramdisk_module = malloc(sizeof(multiboot_module));
// Fill in multiboot info and module structures.
if (gRAMDiskMI != NULL && ramdisk_module != NULL)
{
gRAMDiskMI->mi_mods_count = 1;
gRAMDiskMI->mi_mods_addr = (uint32_t)ramdisk_module;
ramdisk_module->mm_mod_start = PREBOOT_DATA;
ramdisk_module->mm_mod_end = PREBOOT_DATA + ramDiskSize;
// Set ramdisk driver hooks.
p_get_ramdisk_info = &multiboot_get_ramdisk_info;
p_ramdiskReadBytes = &multibootRamdiskReadBytes;
int partCount; // unused
// Save bvr of the mounted image.
gRAMDiskVolume = diskScanBootVolumes(0x100, &partCount);
if(gRAMDiskVolume == NULL)
{
umountRAMDisk();
printf("\nRamdisk contains no partitions.");
}
else
{
char dirSpec[128];
// Reading ramdisk configuration.
strcpy(dirSpec, RAMDISKCONFIG_FILENAME);
if (loadConfigFile(dirSpec, &bootInfo->ramdiskConfig) == 0)
{
getBoolForKey("BTAlias", &gRAMDiskBTAliased, &bootInfo->ramdiskConfig);
}
else
{
printf("\nno ramdisk config...\n");
}
printf("\nmounting: done");
}
}
}
return error;
}
void setRAMDiskBTHook(bool mode)
{
gRAMDiskBTAliased = mode;
if (mode) {
printf("\nEnabled bt(0,0) alias.");
} else {
printf("\nDisabled bt(0,0) alias.");
}
gRAMDiskBTAliased = mode;
if (mode)
{
printf("\nEnabled bt(0,0) alias.");
}
else
{
printf("\nDisabled bt(0,0) alias.");
}
}
void showInfoRAMDisk(void)
{
int len;
const char *val;
int len;
const char *val;
if (gRAMDiskMI != NULL)
{
struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
if (gRAMDiskMI != NULL)
{
struct multiboot_module * ramdisk_module = (void *)gRAMDiskMI->mi_mods_addr;
printf("\nfile: %s %d", gRAMDiskFile,
ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
printf("\nfile: %s %d", gRAMDiskFile,
ramdisk_module->mm_mod_end - ramdisk_module->mm_mod_start);
printf("\nalias: %s", gRAMDiskBTAliased ? "enabled" : "disabled");
// Display ramdisk information if available.
if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
printf("\ninfo: %s", val);
else
printf("\nramdisk info not available.");
}
else
{
printf("\nNo ramdisk mounted.");
}
// Display ramdisk information if available.
if (getValueForKey("Info", &val, &len, &bootInfo->ramdiskConfig))
{
printf("\ninfo: %s", val);
}
else
{
printf("\nramdisk info not available.");
}
}
else
{
printf("\nNo ramdisk mounted.");
}
}
int loadPrebootRAMDisk()
{
mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
if (gRAMDiskMI != NULL)
{
printf("\n");
return 0;
}
else
{
return -1;
}
mountRAMDisk("bt(0,0)/Extra/Preboot.dmg");
if (gRAMDiskMI != NULL)
{
printf("\n");
return 0;
}
else
{
return -1;
}
}
void processRAMDiskCommand(char ** argPtr, const char * cmd)
{
char * ptr = *argPtr;
char param[1024];
getNextArg(&ptr, param);
if (strcmp(cmd, "m") == 0)
{
mountRAMDisk(param);
sleep(2);
}
else if (strcmp(cmd, "u") == 0)
{
umountRAMDisk();
sleep(2);
}
else if (strcmp(cmd, "e") == 0)
{
setRAMDiskBTHook(1);
sleep(2);
}
else if (strcmp(cmd, "d") == 0)
{
setRAMDiskBTHook(0);
sleep(2);
}
else if (strcmp(cmd, "i") == 0)
{
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition(0, 0, 1);
showInfoRAMDisk();
printf("\n\nPress any key to continue.\n");
getc();
setActiveDisplayPage(0);
}
else
{
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition(0, 0, 1);
printf("\nusage:\n");
printf("\n?rd i - display ramdisk information");
printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
printf("\n\nPress any key to continue.\n");
getc();
setActiveDisplayPage(0);
}
char * ptr = *argPtr;
char param[1024];
getNextArg(&ptr, param);
if (strcmp(cmd, "m") == 0)
{
mountRAMDisk(param);
sleep(2);
}
else if (strcmp(cmd, "u") == 0)
{
umountRAMDisk();
sleep(2);
}
else if (strcmp(cmd, "e") == 0)
{
setRAMDiskBTHook(true);
sleep(2);
}
else if (strcmp(cmd, "d") == 0)
{
setRAMDiskBTHook(false);
sleep(2);
}
else if (strcmp(cmd, "i") == 0)
{
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition(0, 0, 1);
showInfoRAMDisk();
printf("\n\nPress any key to continue.\n");
getc();
setActiveDisplayPage(0);
}
else
{
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition(0, 0, 1);
printf("\nusage:\n");
printf("\n?rd i - display ramdisk information");
printf("\n?rd m <filename> - mount ramdisk image\n?rd u - unmount ramdisk image");
printf("\n?rd e - enable bt(0,0) alias\n?rd d - disable bt(0,0) alias");
printf("\n\nPress any key to continue.\n");
getc();
setActiveDisplayPage(0);
}
}
branches/meklort/i386/boot2/options.c
111111
112112
113113
114
115
114
115
116116
117117
118118
......
182182
183183
184184
185
185
186186
187187
188188
189189
190190
191
192
193
194
195
196
197
198
199
200
191201
192202
193203
......
434444
435445
436446
437
438
447
439448
440449
441450
442451
443452
444
445
453
446454
447455
448456
449457
450458
451
452
459
453460
454461
455462
......
689696
690697
691698
692
693
694
695
699
700
701
696702
697703
704
705
706
698707
699708
700709
......
725734
726735
727736
737
738
739
740
741
742
743
744
728745
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
746
747
748
752749
753
750
751
752
753
754
755
756
757
754758
755759
756760
......
767771
768772
769773
770
771
774
775
772776
773777
774778
775779
776
777
778
780
781
779782
780783
781
784
782785
783786
784787
785
786788
787789
788790
789791
790
791
792792
793793
794794
......
803803
804804
805805
806
806
807807
808808
809809
......
855855
856856
857857
858
858
859859
860860
861861
......
867867
868868
869869
870
870871
871872
872873
......
13051306
13061307
13071308
1308
1309
1310
1311
1309
1310
1311
1312
1313
1314
1315
13121316
1313
1314
1317
1318
1319
1320
13151321
1316
1317
1318
1322
1323
1324
1325
13191326
1320
1321
1322
1323
1324
1325
13261327
13271328
13281329
position_t p = pos( gui.screen.width / 2 + 1 , ( gui.devicelist.pos.y + 3 ) + ( ( gui.devicelist.height - gui.devicelist.iconspacing ) / 2 ) );
char dummy[80];
getBootVolumeDescription( gBootVolume, dummy, 80, true );
drawDeviceIcon( gBootVolume, gui.screen.pixmap, p );
getBootVolumeDescription( gBootVolume, dummy, sizeof(dummy) - 1, true );
drawDeviceIcon( gBootVolume, gui.screen.pixmap, p, true );
drawStrCenteredAt( (char *) msg, &font_small, gui.screen.pixmap, gui.countdown.pos );
// make this screen the new background
{
gBootArgsPtr = gBootArgs;
memset(gBootArgs, '\0', BOOT_STRING_LEN);
if (bootArgs->Video.v_display == GRAPHICS_MODE) {
clearGraphicBootPrompt();
}
}
static void addBootArg(const char * argStr)
{
if ( (gBootArgsPtr + strlen(argStr) + 1) < gBootArgsEnd)
{
*gBootArgsPtr++ = ' ';
strcat(gBootArgs, argStr);
gBootArgsPtr += strlen(argStr);
}
}
//==========================================================================
static void showBootPrompt(int row, bool visible)
case BOOT_VERBOSE:
gVerboseMode = true;
gBootMode = kBootModeNormal;
*gBootArgsPtr++ = '-';
*gBootArgsPtr++ = 'v';
addBootArg(kVerboseModeFlag);
break;
case BOOT_IGNORECACHE:
gVerboseMode = false;
gBootMode = kBootModeNormal;
*gBootArgsPtr++ = '-';
*gBootArgsPtr++ = 'f';
addBootArg(kIgnoreCachesFlag);
break;
case BOOT_SINGLEUSER:
gVerboseMode = true;
gBootMode = kBootModeNormal;
*gBootArgsPtr++ = '-';
*gBootArgsPtr++ = 's';
addBootArg(kSingleUserModeFlag);
break;
}
}
// ensure we're in graphics mode if gui is setup
if (gui.initialised) {
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
setVideoMode(GRAPHICS_MODE, 0);
}
if (gui.initialised && bootArgs->Video.v_display == VGA_TEXT_MODE)
{
setVideoMode(GRAPHICS_MODE, 0);
}
// Clear command line boot arguments
clearBootArgs();
// Allow user to override default timeout.
if (multiboot_timeout_set) {
timeout = multiboot_timeout;
//gBootMode |= kBootModeSafe;
}
// Checking user pressed keys
bool f8press = false, spress = false, vpress = false;
while (readKeyboardStatus()) {
key = bgetc ();
if (key == 0x4200) f8press = true;
if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true;
if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true;
}
// If user typed F8, abort quiet mode, and display the menu.
{
bool f8press = false, spress = false, vpress = false;
int key;
while (readKeyboardStatus()) {
key = bgetc ();
if (key == 0x4200) f8press = true;
if ((key & 0xff) == 's' || (key & 0xff) == 'S') spress = true;
if ((key & 0xff) == 'v' || (key & 0xff) == 'V') vpress = true;
}
if (f8press) {
gBootMode &= ~kBootModeQuiet;
timeout = 0;
}
if ((gBootMode & kBootModeQuiet) && firstRun && vpress && (gBootArgsPtr + 3 < gBootArgsEnd)) {
*(gBootArgsPtr++) = ' ';
*(gBootArgsPtr++) = '-';
*(gBootArgsPtr++) = 'v';
}
if ((gBootMode & kBootModeQuiet) && firstRun && spress && (gBootArgsPtr + 3 < gBootArgsEnd)) {
*(gBootArgsPtr++) = ' ';
*(gBootArgsPtr++) = '-';
*(gBootArgsPtr++) = 's';
}
if (f8press) {
gBootMode &= ~kBootModeQuiet;
timeout = 0;
}
clearBootArgs();
// If user typed 'v' or 'V', boot in verbose mode.
if ((gBootMode & kBootModeQuiet) && firstRun && vpress) {
addBootArg(kVerboseModeFlag);
}
// If user typed 's' or 'S', boot in single user mode.
if ((gBootMode & kBootModeQuiet) && firstRun && spress) {
addBootArg(kSingleUserModeFlag);
}
if (bootArgs->Video.v_display == VGA_TEXT_MODE) {
setCursorPosition(0, 0, 0);
// When booting from CD, default to hard drive boot when possible.
if (isCDROM && firstRun) {
const char *val;
char *prompt;
char *name;
char *prompt = NULL;
char *name = NULL;
int cnt;
int optionKey;
if (getValueForKey(kCDROMPromptKey, &val, &cnt, &bootInfo->bootConfig)) {
cnt += 1;
prompt = malloc(cnt);
strlcpy(prompt, val, cnt);
prompt = malloc(cnt + 1);
strncat(prompt, val, cnt);
} else {
name = malloc(80);
getBootVolumeDescription(gBootVolume, name, 80, false);
getBootVolumeDescription(gBootVolume, name, 79, false);
prompt = malloc(256);
sprintf(prompt, "Press any key to start up from %s, or press F8 to enter startup options.", name);
free(name);
cnt = 0;
}
if (getIntForKey( kCDROMOptionKey, &optionKey, &bootInfo->bootConfig )) {
// The key specified is a special key.
} else if (getValueForKey( kCDROMOptionKey, &val, &cnt, &bootInfo->bootConfig ) && cnt >= 1) {
optionKey = val[0];
} else {
// Default to F8.
optionKey = 0x4200;
key = optionKey;
}
if (cnt) {
if (prompt != NULL) {
free(prompt);
}
// Associate a menu item for each BVRef.
for (bvr=bvChain, i=gDeviceCount-1, selectIndex=0; bvr; bvr=bvr->next) {
if (bvr->visible) {
getBootVolumeDescription(bvr, menuItems[i].name, 80, true);
getBootVolumeDescription(bvr, menuItems[i].name, sizeof(menuItems[i].name) - 1, true);
menuItems[i].param = (void *) bvr;
if (bvr == menuBVR) {
selectIndex = i;
if (bootArgs->Video.v_display == GRAPHICS_MODE) {
// redraw the background buffer
gui.logo.draw = true;
drawBackground();
gui.devicelist.draw = true;
gui.redraw = true;
strncpy(&argP[cnt], cp, userCnt);
argP[cnt+userCnt] = '\0';
if(!shouldboot)
{
gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) ||
getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig );
if(!shouldboot)
{
gVerboseMode = getValueForKey( kVerboseModeFlag, &val, &cnt, &bootInfo->bootConfig ) ||
getValueForKey( kSingleUserModeFlag, &val, &cnt, &bootInfo->bootConfig );
gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ?
kBootModeSafe : kBootModeNormal;
gBootMode = ( getValueForKey( kSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) ?
kBootModeSafe : kBootModeNormal;
if ( getValueForKey( kIgnoreCachesFlag, &val, &cnt, &bootInfo->bootConfig ) ) {
gBootMode = kBootModeSafe;
}
}
if ( getValueForKey( kOldSafeModeFlag, &val, &cnt, &bootInfo->bootConfig ) ) {
gBootMode = kBootModeSafe;
}
if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) )
{
strlcpy(gMKextName, val, cnt + 1);
}
if ( getValueForKey( kMKextCacheKey, &val, &cnt, &bootInfo->bootConfig ) ) {
strlcpy(gMKextName, val, cnt + 1);
}
}
free(configKernelFlags);
free(valueBuffer);
branches/meklort/i386/boot2/Makefile
2020
2121
2222
23
23
2424
2525
2626
......
5454
5555
5656
57
57
5858
5959
6060
......
9595
9696
9797
98
99
100
101
102
103
104
105
106
107
108
109
98110
99
100111
101112
102113
LIBSADIR = ../libsa
LIBSAIODIR = ../libsaio
UTILDIR = ../util
THEME = default
THEME = embed
THEMEDIR = ../../artwork/themes/$(THEME)
INC = -I. -I.. -I$(SYMDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(UTILDIR)
ifneq "" "$(wildcard /bin/mkdirs)"
$(HFILES) $(OTHERFILES)
DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
BOOT2ADDR = 20200
MAXBOOTSIZE = 392704
MAXBOOTSIZE = 458240
all: $(DIRS_NEEDED) boot
@echo "#define __BOOT2_ART_H" >> $(SYMROOT)/art.h
@cd $(SYMROOT)/embed && find . -name 'theme.plist' -exec xxd -i >> $(SYMROOT)/art.h {} \;
@cd $(SYMROOT)/embed && find . -name '*.png' -exec xxd -i >> $(SYMROOT)/art.h {} \;
@echo "typedef struct {" >> $(SYMROOT)/art.h
@echo "charname[32];" >> $(SYMROOT)/art.h
@echo "unsigned char*pngdata;" >> $(SYMROOT)/art.h
@echo "unsigned int*length;" >> $(SYMROOT)/art.h
@echo "} embeddedpng_t;" >> $(SYMROOT)/art.h
@echo "" >> $(SYMROOT)/art.h
@echo "embeddedpng_t embeddedImages[] = {" >> $(SYMROOT)/art.h
@cd $(SYMROOT)/embed && find . -name '*.png' | sort | cut -f 2 -d '/' | cut -f 1 -d '.' | \
awk '{ printf "\t{.name = \"%s\", .pngdata = __%s_png, .length = &__%s_png_len},\n", $$1, $$1, $$1 }' >> $(SYMROOT)/art.h
@echo "};" >> $(SYMROOT)/art.h
@echo "#endif /* !__BOOT2_ART_H */" >> $(SYMROOT)/art.h ;\
rm -rf $(SYMROOT)/embed ;\
embedded.h:
@cd $(SYMROOT)/../../doc && xxd -i BootHelp.txt > $(SYMROOT)/embedded.h
branches/meklort/i386/cdboot/cdboot.s
114114
115115
116116
117
117
118118
119119
120120
; at build time.
kSectorBytes EQU 2048; sector size in bytes
kBoot2Size EQU 65024; default load size for boot2
kBoot2MaxSize EQU 392704; max size for boot2
kBoot2MaxSize EQU 458240; max size for boot2
kBoot2Address EQU 0x0200 ; boot2 load address
kBoot2Segment EQU 0x2000 ; boot2 load segment
branches/meklort/i386/libsa/libsa.h
7070
7171
7272
73
74
75
76
77
7378
7479
7580
......
102107
103108
104109
110
111
112
105113
106114
107115
return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
}
//Azi: TODO - add more ponctuation characters as needed; at least these two, i need for PartNo.
static inline int ispunct(char c)
{
return (c == '.' || c == '-');
}
/*
* string.c
extern int strncasecmp(const char * s1, const char * s2, size_t n);
#endif
extern char * strchr(const char *str, int c);
extern char * strbreak(const char *str, char **next, long *len);
extern uint8_t checksum8( void * start, unsigned int length );
/*
branches/meklort/i386/libsa/string.c
257257
258258
259259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
260309
261310
262311
}
#endif
char* strchr(const char *str, int c)
{
do
{
if(*str == c)
return (char*)str;
}
while(*(str++));
return 0;
}
char* strbreak(const char *str, char **next, long *len)
{
char *start = (char*)str, *end;
bool quoted = false;
if ( !start || !len )
return 0;
*len = 0;
while ( isspace(*start) )
start++;
if (*start == '"')
{
start++;
end = strchr(start, '"');
if(end)
quoted = true;
else
end = strchr(start, '\0');
}
else
{
for ( end = start; *end && !isspace(*end); end++ )
{}
}
*len = end - start;
if(next)
*next = quoted ? end+1 : end;
return start;
}
/* COPYRIGHT NOTICE: checksum8 from AppleSMBIOS */
uint8_t checksum8( void * start, unsigned int length )
{
branches/meklort/i386/libsa/memory.h
4848
4949
5050
51
51
5252
5353
5454
......
7878
7979
8080
81
81
8282
8383
84
84
8585
8686
87
87
8888
8989
90
90
9191
9292
93
94
93
94
9595
9696
97
98
97
98
9999
100100
101101
# define BASE_SEG BOOT2_SEG
#endif
#define STACK_SEG 0x8000// zef: old STACK_SEG 0x5000
#define STACK_SEG 0x1000// zef: old STACK_SEG 0x5000
#define STACK_OFS 0xFFF0 // stack pointer
#define BOOT1U_SEG 0x1000
#define BOOT2_ADDR ADDR32(BOOT2_SEG, BOOT2_OFS)
// TODO: BOOT_ADDR ?
#define HIB_ADDR 0x00040000 // special hibernation area
#define HIB_ADDR 0x00040000 // special hibernation area
#define HIB_LEN 0x00060000
#define VIDEO_ADDR 0x000A0000 // unusable space
#define VIDEO_ADDR 0x000A0000 // unusable space
#define VIDEO_LEN 0x00060000
#define KERNEL_ADDR 0x00100000 // 128M kernel + drivers // Was 64
#define KERNEL_ADDR 0x00100000 // 128M kernel + drivers
#define KERNEL_LEN 0x08000000
#define ZALLOC_ADDR 0x08100000 // 192M zalloc area// Was 256
#define ZALLOC_ADDR 0x08100000 // 256M zalloc area
#define ZALLOC_LEN 0x10000000
#define LOAD_ADDR 0x14100000 // 95M File load buffer
#define LOAD_LEN 0x05F80000
#define LOAD_ADDR 0x18100000 // 64M File load buffer
#define LOAD_LEN 0x04000000
// Location of data fed to boot2 by the prebooter
#define PREBOOT_DATA 0x1A080000 // Still have enough room for a 95M ramdisk image
// in case of 512MB system memory.
#define PREBOOT_DATA 0x1C100000 // Still have enough room for a 63M ramdisk image
// in case of 512MB system memory.
#define TFTP_ADDR LOAD_ADDR // tftp download buffer
#define TFTP_LEN LOAD_LEN
branches/meklort/i386/util/bdmesg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
* BooterLog Dump Tool, part of the Chameleon Boot Loader Project
*
* Copyright 2010 by Islam M. Ahmed Zaid. All rights reserved.
*
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "IOKit/IOKitLib.h"
int main(int argc, char *argv[])
{
io_registry_entry_t root = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
if (!root)
{
printf("IORegistryEntry \"IOIOService:/\" not found.\n");
return 0;
}
CFTypeRef bootLog = IORegistryEntryCreateCFProperty(root, CFSTR("boot-log"), kCFAllocatorDefault, 0);
if (!bootLog)
{
printf("\"boot-log\" property not found.\n");
return 0;
}
//CFShow(bootLog);
const UInt8 *msglog = CFDataGetBytePtr((CFDataRef)bootLog);
if (msglog)
printf("%s\n", msglog);
return 0;
}
branches/meklort/i386/util/Makefile
1818
1919
2020
21
21
2222
2323
2424
......
2929
3030
3131
32
33
34
3235
3336
3437
CFILES = machOconv.c
ALLSRC = $(CFILES) $(MFILES) $(HFILES) $(EXPORT_HFILES)
PROGRAMS = machOconv
PROGRAMS = machOconv bdmesg
OUTFILES = $(PROGRAMS)
machOconv: machOconv.o
$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) machOconv.o
bdmesg: bdmesg.o
$(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 -o $(SYMROOT)/$(@F) bdmesg.o
include ../MakeInc.dir
#dependencies
branches/meklort/GPL_V2_LICENSE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
branches/meklort/CREDITS
33
44
55
6
7
8
9
10
11
12
13
14
15
16
17
18
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1922
2023
2124
22
23
24
25
26
27
28
29
30
31
32
33
34
35
25
26
27
28
29
30
31
32
33
34
35
36
37
Developers:
----------
Crazor
Dense
fassl
iNDi
JrCs
Kabyl
kaitek
mackerintel
mercurysquad
munky
rekursor
Turbo
zef
Crazor
Dense
fassl
iNDi
JrCs
Kabyl
kaitek
mackerintel
mercurysquad
munky
meklort
mozodojo
rekursor
Turbo
valv
zef
Thanks to:
---------
asereBLN
bumby
cosmo1t
dfe
Galaxy
kalyway
Krazubu
MasterChief
netkas
sckevyn
smith@@
THeKiNG
XyZ
asereBLN
Azimutz
bumby
cosmo1t
dfe
Galaxy
kalyway
Krazubu
MasterChief
netkas
sckevyn
smith@@
THeKiNG
branches/meklort/Makefile
4646
4747
4848
49
49
5050
5151
5252
......
115115
116116
117117
118
118119
119120
120121
# Currently builds for i386
#
all embedtheme tags debug install installhdrs: $(SYMROOT) $(OBJROOT)
all embedtheme tags debug install installhdrs modules: $(SYMROOT) $(OBJROOT)
@if [ -e ".svn" ]; then svnversion -n | tr -d [:alpha:] > revision; fi
@if [ -z "$(RC_ARCHS)" ]; then \
RC_ARCHS="i386"; \
@tar -czf $(SYMROOT)/$(PRODUCT)-src.tar.gz ${EXCLUDE} .
@tar -cjf $(SYMROOT)/$(PRODUCT)-src.tar.bz2 ${EXCLUDE} .
clean:
rm -rf sym obj dst
branches/meklort/README
1
2
3
4
5
6
7
Chameleon is a Darwin/XNU boot loader based on Apple's boot-132.
Because Chameleon now uses part of GPL V2 licensed code in 2 files,
it *must* conform to the most restrictive license that it uses that is the:
GPL Version 2 LICENSE
Chameleon can thus be (and has to be) freely distributed under the term of the GPL V2 license which prevails, as it is the most restrictive license.
branches/meklort/MEMTEST86_LICENSE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
dram_controllers.c/h that scans from the pci host controller USES
an adaptation for chameleon 2.0 RC5 from original :
========================
memtest86 license notice
========================
Released under version 2 of the Gnu Public License.
By Chris Brady, cbrady@sgi.com
----------------------------------------------------
MemTest86+ V4.00 Specific code (GPL V2.0)
By Samuel DEMEULEMEESTER, sdemeule@memtest.org
http://www.canardpc.com - http://www.memtest.org
============================
GPL version 2 license notice
============================
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Archive Download the corresponding diff file

Revision: 505