Chameleon

Chameleon Commit Details

Date:2010-09-23 06:07:11 (8 years 9 months ago)
Author:Evan Lojewski
Commit:543
Parents: 542
Message:Chameleon code shrinkage. Also moved a few things to modules.
Changes:
D/branches/meklort/i386/libsaio/hpet.c
D/branches/meklort/i386/libsaio/hpet.h
D/branches/meklort/i386/libsaio/usb.c
A/branches/meklort/i386/modules/USBFix/Makefile
A/branches/meklort/i386/modules/HPET/Makefile
A/branches/meklort/i386/modules/Ethernet
A/branches/meklort/i386/modules/USBFix/USBFix.c
A/branches/meklort/i386/modules/HPET/HPET.c
A/branches/meklort/i386/modules/HPET/hpet.h
A/branches/meklort/i386/modules/HPET
A/branches/meklort/i386/modules/USBFix
A/branches/meklort/i386/modules/USBFix/usb.c
A/branches/meklort/i386/modules/Ethernet/Ethernet.c
A/branches/meklort/i386/modules/Ethernet/Makefile
M/branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
M/branches/meklort/i386/boot2/resume.c
M/branches/meklort
M/branches/meklort/i386/boot2/boot.c
M/branches/meklort/i386/libsaio/vbe.c
M/branches/meklort/i386/modules/Memory/mem.c
M/branches/meklort/i386/libsaio/sys.c
M/branches/meklort/i386/libsaio/nbp.c
M/branches/meklort/i386/boot2/drivers.c
M/branches/meklort/i386/libsaio/disk.c
M/branches/meklort/i386/modules/ACPIPatcher/acpi_patcher.c
M/branches/meklort/i386/libsaio/pci_setup.c
M/branches/meklort/i386/libsaio/Makefile
M/branches/meklort/i386/modules/Symbols
M/branches/meklort/i386/libsaio/ufs.c
M/branches/meklort/i386/libsaio/smbios_patcher.c
M/branches/meklort/i386/boot2/graphics.c
M/branches/meklort/i386/modules/Memory/Memory.c
M/branches/meklort/i386/modules/GUI/graphic_utils.c
M/branches/meklort/i386/modules/Memory/dram_controllers.c
M/branches/meklort/i386/modules/GUI/graphic_utils.h
M/branches/meklort/i386/libsaio/pci_root.c
M/branches/meklort/i386/libsaio/convert.c
M/branches/meklort/i386/modules/Makefile
M/branches/meklort/i386/modules/Memory/spd.c
M/branches/meklort/i386/boot2/prompt.c
M/branches/meklort/i386/libsaio/fake_efi.c
M/branches/meklort/i386/libsaio/device_inject.c
M/branches/meklort/i386/modules/ACPIPatcher/ACPIPatcher.c
M/branches/meklort/i386/boot2/ramdisk.c
M/branches/meklort/i386/boot2/options.c
M/branches/meklort/i386/libsaio/asm.s

File differences

branches/meklort/i386/libsaio/usb.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
/*
* usb.c
*
*
* Created by mackerintel on 12/20/08.
* Copyright 2008 mackerintel. All rights reserved.
*
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#ifndef DEBUG_USB
#define DEBUG_USB 0
#endif
#if DEBUG_USB
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
struct pciList
{
pci_dt_t* pciDev;
struct pciList* next;
};
struct pciList* usbList = NULL;
int legacy_off (pci_dt_t *pci_dev);
int ehci_acquire (pci_dt_t *pci_dev);
int uhci_reset (pci_dt_t *pci_dev);
// Add usb device to the list
void notify_usb_dev(pci_dt_t *pci_dev)
{
struct pciList* current = usbList;
if(!usbList)
{
usbList = (struct pciList*)malloc(sizeof(struct pciList));
usbList->next = NULL;
usbList->pciDev = pci_dev;
}
else
{
while(current != NULL && current->next != NULL)
{
current = current->next;
}
current->next = (struct pciList*)malloc(sizeof(struct pciList));
current = current->next;
current->pciDev = pci_dev;
current->next = NULL;
}
}
// Loop through the list and call the apropriate patch function
int usb_loop()
{
int retVal = 1;
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy = false;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig))
{
fix_ehci = fix_uhci = fix_legacy = fix_usb;// Disable all if none set
}
else
{
getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);
getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);
getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig);
}
struct pciList* current = usbList;
while(current)
{
switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG))
{
// EHCI
case 0x20:
if(fix_ehci) retVal &= ehci_acquire(current->pciDev);
if(fix_legacy) retVal &= legacy_off(current->pciDev);
break;
// UHCI
case 0x00:
if (fix_uhci) retVal &= uhci_reset(current->pciDev);
break;
}
current = current->next;
}
return retVal;
}
int legacy_off (pci_dt_t *pci_dev)
{
// Set usb legacy off modification by Signal64
// NOTE: This *must* be called after the last file is loaded from the drive in the event that we are booting form usb.
// NOTE2: This should be called after any getc() call. (aka, after the Wait=y keyworkd is used)
// AKA: Make this run immediatly before the kernel is called
uint32_tcapaddr, opaddr;
uint8_teecp;
uint32_tusbcmd, usbsts, usbintr;
uint32_tusblegsup, usblegctlsts;
int isOSowned;
int isBIOSowned;
verbose("Setting Legacy USB Off on controller [%04x:%04x] at %02x:%2x.%x\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func);
// capaddr = Capability Registers = dev.addr + offset stored in dev.addr + 0x10 (USBBASE)
capaddr = pci_config_read32(pci_dev->dev.addr, 0x10);
// opaddr = Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0)
opaddr = capaddr + *((unsigned char*)(capaddr));
// eecp = EHCI Extended Capabilities offset = capaddr HCCPARAMS bits 15:8
eecp=*((unsigned char*)(capaddr + 9));
DBG("capaddr=%x opaddr=%x eecp=%x\n", capaddr, opaddr, eecp);
usbcmd = *((unsigned int*)(opaddr));// Command Register
usbsts = *((unsigned int*)(opaddr + 4));// Status Register
usbintr = *((unsigned int*)(opaddr + 8));// Interrupt Enable Register
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
// read PCI Config 32bit USBLEGSUP (eecp+0)
usblegsup = pci_config_read32(pci_dev->dev.addr, eecp);
// informational only
isBIOSowned = !!((usblegsup) & (1 << (16)));
isOSowned = !!((usblegsup) & (1 << (24)));
// read PCI Config 32bit USBLEGCTLSTS (eecp+4)
usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4);
DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts);
// Reset registers to Legacy OFF
DBG("Clearing USBLEGCTLSTS\n");
pci_config_write32(pci_dev->dev.addr, eecp + 4, 0);//usblegctlsts
// if delay value is in milliseconds it doesn't appear to work.
// setting value to anything up to 65535 does not add the expected delay here.
delay(100);
usbcmd = *((unsigned int*)(opaddr));
usbsts = *((unsigned int*)(opaddr + 4));
usbintr = *((unsigned int*)(opaddr + 8));
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
DBG("Clearing Registers\n");
// clear registers to default
usbcmd = (usbcmd & 0xffffff00);
*((unsigned int*)(opaddr)) = usbcmd;
*((unsigned int*)(opaddr + 8)) = 0;//usbintr - clear interrupt registers
*((unsigned int*)(opaddr + 4)) = 0x1000;//usbsts - clear status registers
pci_config_write32(pci_dev->dev.addr, eecp, 1);//usblegsup
// get the results
usbcmd = *((unsigned int*)(opaddr));
usbsts = *((unsigned int*)(opaddr + 4));
usbintr = *((unsigned int*)(opaddr + 8));
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
// read 32bit USBLEGSUP (eecp+0)
usblegsup = pci_config_read32(pci_dev->dev.addr, eecp);
// informational only
isBIOSowned = !!((usblegsup) & (1 << (16)));
isOSowned = !!((usblegsup) & (1 << (24)));
// read 32bit USBLEGCTLSTS (eecp+4)
usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4);
DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts);
verbose("Legacy USB Off Done\n");
return 1;
}
int ehci_acquire (pci_dt_t *pci_dev)
{
intj, k;
uint32_tbase;
uint8_teecp;
uint8_tlegacy[8];
boolisOwnershipConflict;
boolalwaysHardBIOSReset;
alwaysHardBIOSReset = false;
if (!getBoolForKey(kEHCIhard, &alwaysHardBIOSReset, &bootInfo->bootConfig)) {
alwaysHardBIOSReset = true;
}
pci_config_write16(pci_dev->dev.addr, 0x04, 0x0002);
base = pci_config_read32(pci_dev->dev.addr, 0x10);
verbose("EHCI controller [%04x:%04x] at %02x:%2x.%x DMA @%x\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func,
base);
if (*((unsigned char*)base) < 0xc)
{
DBG("Config space too small: no legacy implementation\n");
return 1;
}
eecp = *((unsigned char*)(base + 9));
if (!eecp) {
DBG("No extended capabilities: no legacy implementation\n");
return 1;
}
DBG("eecp=%x\n",eecp);
// bad way to do it
// pci_conf_write(pci_dev->dev.addr, eecp, 4, 0x01000001);
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
DBG("%02x ", legacy[j]);
}
DBG("\n");
//Real Job: based on orByte's AppleUSBEHCI.cpp
//We try soft reset first - some systems hang on reboot with hard reset
// Definitely needed during reboot on 10.4.6
isOwnershipConflict = ((legacy[3] & 1 != 0) && (legacy[2] & 1 != 0));
if (!alwaysHardBIOSReset && isOwnershipConflict) {
DBG("EHCI - Ownership conflict - attempting soft reset ...\n");
DBG("EHCI - toggle OS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 3, 0);
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
if (legacy[3] == 0) {
break;
}
delay(10);
}
}
DBG("Found USBLEGSUP_ID - value %x:%x - writing OSOwned\n", legacy[3],legacy[2]);
pci_config_write8(pci_dev->dev.addr, eecp + 3, 1);
// wait for kEHCI_USBLEGSUP_BIOSOwned bit to clear
for (k = 0; k < 25; k++) {
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if (legacy[2] == 0) {
break;
}
delay(10);
}
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
isOwnershipConflict = ((legacy[2]) != 0);
if (isOwnershipConflict) {
// Soft reset has failed. Assume SMI being ignored
// Hard reset
// Force Clear BIOS BIT
DBG("EHCI - Ownership conflict - attempting hard reset ...\n");
DBG ("%x:%x\n",legacy[3],legacy[2]);
DBG("EHCI - Force BIOS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 2, 0);
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if ((legacy[2]) == 0) {
break;
}
delay(10);
}
// Disable further SMI events
for (j = 4; j < 8; j++) {
pci_config_write8(pci_dev->dev.addr, eecp + j, 0);
}
}
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x\n",legacy[3],legacy[2]);
// Final Ownership Resolution Check...
if (legacy[2] & 1) {
DBG("EHCI controller unable to take control from BIOS\n");
return 0;
}
DBG("EHCI Acquire OS Ownership done\n");
return 1;
}
int uhci_reset (pci_dt_t *pci_dev)
{
uint32_t base, port_base;
base = pci_config_read32(pci_dev->dev.addr, 0x20);
port_base = (base >> 5) & 0x07ff;
verbose("UHCI controller [%04x:%04x] at %02x:%2x.%x base %x(%x)\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func,
port_base, base);
pci_config_write16(pci_dev->dev.addr, 0xc0, 0x8f00);
outw (port_base, 0x0002);
delay(10);
outw (port_base+4,0);
delay(10);
outw (port_base,0);
return 1;
}
branches/meklort/i386/libsaio/hpet.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
/*
* Force HPET enabled
*
* via fix from http://forum.voodooprojects.org/index.php/topic,1596.0.html
*/
#include "libsaio.h"
#include "pci.h"
#include "hpet.h"
#ifndef DEBUG_HPET
#define DEBUG_HPET 0
#endif
#if DEBUG_HPET
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
void force_enable_hpet_intel(pci_dt_t *lpc_dev);
void force_enable_hpet_via(pci_dt_t *lpc_dev);
static struct lpc_controller_t lpc_controllers_intel[] = {
// Default unknown chipset
{ 0, 0, "" },
// Intel
{ 0x8086, 0x24dc, "ICH5" },
{ 0x8086, 0x2640, "ICH6" },
{ 0x8086, 0x2641, "ICH6M" },
{ 0x8086, 0x27b0, "ICH7 DH" },
{ 0x8086, 0x27b8, "ICH7" },
{ 0x8086, 0x27b9, "ICH7M" },
{ 0x8086, 0x27bd, "ICH7M DH" },
{ 0x8086, 0x2810, "ICH8R" },
{ 0x8086, 0x2811, "ICH8M-E" },
{ 0x8086, 0x2812, "ICH8DH" },
{ 0x8086, 0x2814, "ICH8DO" },
{ 0x8086, 0x2815, "ICH8M" },
{ 0x8086, 0x2912, "ICH9DH" },
{ 0x8086, 0x2914, "ICH9DO" },
{ 0x8086, 0x2916, "ICH9R" },
{ 0x8086, 0x2917, "ICH9M-E" },
{ 0x8086, 0x2918, "ICH9" },
{ 0x8086, 0x2919, "ICH9M" },
{ 0x8086, 0x3a14, "ICH10DO" },
{ 0x8086, 0x3a16, "ICH10R" },
{ 0x8086, 0x3a18, "ICH10" },
{ 0x8086, 0x3a1a, "ICH10D" },
};
static struct lpc_controller_t lpc_controllers_via[] = {
// Default unknown chipset
{ 0, 0, "" },
{ 0x1106, 0x3372, "VT8237S" },
};
void force_enable_hpet(pci_dt_t *lpc_dev)
{
switch(lpc_dev->vendor_id)
{
case 0x8086:
force_enable_hpet_intel(lpc_dev);
break;
case 0x1106:
force_enable_hpet_via(lpc_dev);
break;
}
#if DEBUG_HPET
printf("Press [Enter] to continue...\n");
getc();
#endif
}
void force_enable_hpet_via(pci_dt_t *lpc_dev)
{
uint32_tval, hpet_address = 0xFED00000;
int i;
/* LPC on Intel ICH is always (?) at 00:1f.0 */
for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
{
if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id)
&& (lpc_controllers_via[i].device == lpc_dev->device_id))
{
val = pci_config_read32(lpc_dev->dev.addr, 0x68);
DBG("VIA %s LPC Interface [%04x:%04x], MMIO\n",
lpc_controllers[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
if (val & 0x80) {
hpet_address = (val & ~0x3ff);
DBG("HPET at 0x%lx\n", hpet_address);
}
else
{
val = 0xfed00000 | 0x80;
pci_config_write32(lpc_dev->dev.addr, 0x68, val);
val = pci_config_read32(lpc_dev->dev.addr, 0x68);
if (val & 0x80) {
hpet_address = (val & ~0x3ff);
DBG("Force enabled HPET at 0x%lx\n", hpet_address);
}
else {
DBG("Unable to enable HPET");
}
}
}
}
}
void force_enable_hpet_intel(pci_dt_t *lpc_dev)
{
uint32_tval, hpet_address = 0xFED00000;
int i;
void*rcba;
/* LPC on Intel ICH is always (?) at 00:1f.0 */
for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
{
if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id)
&& (lpc_controllers_intel[i].device == lpc_dev->device_id))
{
rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
DBG("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
lpc_controllers[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
if (rcba == 0)
printf(" RCBA disabled; cannot force enable HPET\n");
else
{
val = REG32(rcba, 0x3404);
if (val & 0x80)
{
// HPET is enabled in HPTC. Just not reported by BIOS
DBG(" HPET is enabled in HPTC, just not reported by BIOS\n");
hpet_address |= (val & 3) << 12 ;
DBG(" HPET MMIO @ 0x%lx\n", hpet_address);
}
else
{
// HPET disabled in HPTC. Trying to enable
DBG(" HPET is disabled in HPTC, trying to enable\n");
REG32(rcba, 0x3404) = val | 0x80;
hpet_address |= (val & 3) << 12 ;
DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
}
// verify if the job is done
val = REG32(rcba, 0x3404);
if (!(val & 0x80))
printf(" Failed to force enable HPET\n");
}
break;
}
}
}
branches/meklort/i386/libsaio/hpet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
*
*/
#ifndef __LIBSAIO_HPET_H
#define __LIBSAIO_HPET_H
#include "libsaio.h"
#define REG32(base, reg) ((volatile uint32_t *)base)[(reg) >> 2]
void force_enable_hpet(pci_dt_t *lpc_dev);
struct lpc_controller_t {
unsigned vendor;
unsigned device;
char *name;
};
#endif /* !__LIBSAIO_HPET_H */
branches/meklort/i386/libsaio/asm.s
418418
419419
420420
421
421422
422423
423424
......
459460
460461
461462
463
462464
463465
464466
ret
#ifndef BOOT1
#if UNUSED
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// loader()
//
leave
ret
#endif
#endif
#if UNUSED
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
branches/meklort/i386/libsaio/vbe.c
2929
3030
3131
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
6232
6333
6434
......
8454
8555
8656
87
57
8858
8959
9060
......
10474
10575
10676
77
10778
10879
10980
......
141112
142113
143114
144
115
145116
146117
147118
......
266237
267238
268239
240
241
269242
270243
271244
......
279252
280253
281254
255
282256
283257
284258
......
292266
293267
294268
269
270
295271
296272
297273
......
325301
326302
327303
304
#include "libsaio.h"
#include "vbe.h"
/*
* Various inline routines for video I/O
*/
static inline void
outi (int port, int index, int val)
{
outw (port, (val << 8) | index);
}
static inline void
outib (int port, int index, int val)
{
outb (port, index);
outb (port + 1, val);
}
static inline int
ini (int port, int index)
{
outb (port, index);
return inb (port + 1);
}
static inline void
rmwi (int port, int index, int clear, int set)
{
outb (port, index);
outb (port + 1, (inb (port + 1) & ~clear) | set);
}
/*
* Globals
*/
bios(&bb);
return(bb.eax.r.h);
}
#if UNUSED
int getVBEDACFormat(unsigned char *format)
{
bb.intno = 0x10;
bios(&bb);
return(bb.eax.r.h);
}
#endif
int getEDID( void * edidBlock, UInt8 block)
{
/*
* from http://www.azillionmonkeys.com/qed/sqroot.html
*/
#if UNUSED
double Sqrt( double y )
{
double x, z, tempf;
return 0;
}
#endif
int setVBEMode(unsigned short mode, const VBECRTCInfoBlock * timing)
{
bb.intno = 0x10;
return(bb.eax.r.h);
}
int setVBEPalette(void *palette)
{
bb.intno = 0x10;
return(bb.eax.r.h);
}
#if UNUSED
int getVBEPalette(void *palette)
{
bb.intno = 0x10;
*pixelClock = bb.ecx.rx;
return(bb.eax.r.h);
}
#endif
branches/meklort/i386/libsaio/Makefile
4141
4242
4343
44
44
4545
4646
4747
xml.o ntfs.o msdos.o md5c.o device_tree.o \
cpu.o platform.o \
fake_efi.o ext2fs.o \
hpet.o usb.o pci_setup.o \
pci_setup.o \
device_inject.o pci_root.o \
convert.o
branches/meklort/i386/libsaio/ufs.c
2626
2727
2828
29
3029
3130
3231
......
532531
533532
534533
535
534
*
* DRI: Josh de Cesare
*/
#include <sl.h>
#include "ufs.h"
}
return bytesLeft;
}
}
branches/meklort/i386/libsaio/smbios_patcher.c
141141
142142
143143
144
144
145145
146146
147147
148148
149149
150
150
151151
152152
153153
......
157157
158158
159159
160
160
161161
162162
163163
164
164
165165
166166
167167
......
204204
205205
206206
207
207
208208
209209
210210
211211
212
212
213213
214214
215215
216216
217
217
218218
219
219
220220
221221
222222
223
223
224224
225225
226226
......
275275
276276
277277
278
278
279279
280280
281281
......
290290
291291
292292
293
293
294294
295295
296296
297
297
298298
299299
300300
......
306306
307307
308308
309
309
310310
311311
312
312
313313
314314
315315
316
316
317317
318318
319319
320
320
321321
322322
323323
......
330330
331331
332332
333
333
334334
335335
336336
337337
338
338
339339
340340
341341
342342
343
343
344344
345
345
346346
347347
348348
......
365365
366366
367367
368
369
370
371
368
369
370
371
372372
373373
374374
......
380380
381381
382382
383
384
385
386
383
384
385
386
387387
388388
389389
......
395395
396396
397397
398
399
400
401
398
399
400
401
402402
403403
404404
......
409409
410410
411411
412
413
412
413
414414
415
416
415
416
417417
418418
419419
......
424424
425425
426426
427
428
429
430
427
428
429
430
431431
432432
433433
const SMStrEntryPair*sm_defaults;
if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
if (Platform.CPU.NoCores > 1) {
if (Platform->CPU.NoCores > 1) {
sm_defaults=sm_macbookpro_defaults;
} else {
sm_defaults=sm_macbook_defaults;
}
} else {
switch (Platform.CPU.NoCores)
switch (Platform->CPU.NoCores)
{
case 1:
sm_defaults=sm_macmini_defaults;
break;
default:
{
switch (Platform.CPU.Family)
switch (Platform->CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
switch (Platform->CPU.Model)
{
case CPU_MODEL_FIELDS: // Intel Core i5, i7 LGA1156 (45nm)
case CPU_MODEL_DALES: // Intel Core i5, i7 LGA1156 (45nm) ???
static int sm_get_fsb(const char *name, int table_num)
{
return Platform.CPU.FSBFrequency/1000000;
return Platform->CPU.FSBFrequency/1000000;
}
static int sm_get_cpu (const char *name, int table_num)
{
return Platform.CPU.CPUFrequency/1000000;
return Platform->CPU.CPUFrequency/1000000;
}
static int sm_get_bus_speed (const char *name, int table_num)
{
if (Platform.CPU.Vendor == 0x756E6547) // Intel
if (Platform->CPU.Vendor == 0x756E6547) // Intel
{
switch (Platform.CPU.Family)
switch (Platform->CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
switch (Platform->CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH:// Yonah0x0E
qpimult = pci_config_read32(PCIADDR(nhm_bus, 2, 1), 0x50);
qpimult &= 0x7F;
DBG("qpimult %d\n", qpimult);
qpibusspeed = (qpimult * 2 * (Platform.CPU.FSBFrequency/1000000));
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);
static int sm_get_simplecputype()
{
if (Platform.CPU.NoCores >= 4)
if (Platform->CPU.NoCores >= 4)
{
return 0x0501; // Quad-Core Xeon
}
else if (Platform.CPU.NoCores == 1)
else if (Platform->CPU.NoCores == 1)
{
return 0x0201; // Core Solo
};
{
static bool done = false;
if (Platform.CPU.Vendor == 0x756E6547) // Intel
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);
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)
switch (Platform->CPU.Family)
{
case 0x06:
{
switch (Platform.CPU.Model)
switch (Platform->CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH: // Yonah
return 0x0701; // Core i7
case CPU_MODEL_FIELDS: // Lynnfield, Clarksfield, Jasper
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
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"))
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"))
if (strstr(Platform->CPU.BrandString, "Core(TM) i3"))
return 0x901; // Core i3
if (strstr(Platform.CPU.BrandString, "Core(TM) i5"))
if (strstr(Platform->CPU.BrandString, "Core(TM) i5"))
return 0x601; // Core i5
return 0x0701; // Core i7
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0) {
DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type);
return Platform.RAM.DIMM[map].Type;
map = Platform->DMI.DIMM[table_num];
if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Type != 0) {
DBG("RAM Detected Type = %d\n", Platform->RAM.DIMM[map].Type);
return Platform->RAM.DIMM[map].Type;
}
}
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Frequency != 0) {
DBG("RAM Detected Freq = %d Mhz\n", Platform.RAM.DIMM[map].Frequency);
return Platform.RAM.DIMM[map].Frequency;
map = Platform->DMI.DIMM[table_num];
if (Platform->RAM.DIMM[map].InUse && Platform->RAM.DIMM[map].Frequency != 0) {
DBG("RAM Detected Freq = %d Mhz\n", Platform->RAM.DIMM[map].Frequency);
return Platform->RAM.DIMM[map].Frequency;
}
}
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0) {
DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].Vendor);
return Platform.RAM.DIMM[map].Vendor;
map = Platform->DMI.DIMM[table_num];
if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].Vendor) > 0) {
DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].Vendor);
return Platform->RAM.DIMM[map].Vendor;
}
}
return "N/A";
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) {
map = Platform->DMI.DIMM[table_num];
if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].SerialNo) > 0) {
DBG("name = %s, map=%d, RAM Detected SerialNo[%d]='%s'\n", name ? name : "",
map, table_num, Platform.RAM.DIMM[map].SerialNo);
return Platform.RAM.DIMM[map].SerialNo;
map, table_num, Platform->RAM.DIMM[map].SerialNo);
return Platform->RAM.DIMM[map].SerialNo;
}
}
return "N/A";
intmap;
if (table_num < MAX_RAM_SLOTS) {
map = Platform.DMI.DIMM[table_num];
if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0) {
DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].PartNo);
return Platform.RAM.DIMM[map].PartNo;
map = Platform->DMI.DIMM[table_num];
if (Platform->RAM.DIMM[map].InUse && strlen(Platform->RAM.DIMM[map].PartNo) > 0) {
DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform->RAM.DIMM[map].PartNo);
return Platform->RAM.DIMM[map].PartNo;
}
}
return "N/A";
branches/meklort/i386/libsaio/pci_root.c
1818
1919
2020
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
4621
4722
4823
static int rootuid = 10; //value means function wasnt ran yet
static unsigned int findrootuid(unsigned char * dsdt, int len)
{
int i;
for (i=0; i<64 && i<len-5; i++) //not far than 64 symbols from pci root
{
if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)
{
return dsdt[i+4];
}
}
return 11;
}
unsigned int findpciroot(unsigned char * dsdt,int len)
{
int i;
for (i=0; i<len-4; i++) {
if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08)) {
return findrootuid(dsdt+i, len-i);
}
}
return 10;
}
int getPciRootUID(void)
{
const char *val;
branches/meklort/i386/libsaio/device_inject.c
315315
316316
317317
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
318
free(string);
string = NULL;
}
/* a fine place for this code */
int devprop_add_network_template(struct DevPropDevice *device, uint16_t vendor_id)
{
if(!device)
return 0;
uint8_t builtin = 0x0;
if((vendor_id != 0x168c) && (builtin_set == 0))
{
builtin_set = 1;
builtin = 0x01;
}
if(!devprop_add_value(device, "built-in", (uint8_t*)&builtin, 1))
return 0;
devices_number++;
return 1;
}
void set_eth_builtin(pci_dt_t *eth_dev)
{
char *devicepath = get_pci_dev_path(eth_dev);
struct DevPropDevice *device = (struct DevPropDevice*)malloc(sizeof(struct DevPropDevice));
verbose("LAN Controller [%04x:%04x] :: %s\n", eth_dev->vendor_id, eth_dev->device_id, devicepath);
if (!string)
string = devprop_create_string();
device = devprop_add_device(string, devicepath);
if(device)
{
verbose("Setting up lan keys\n");
devprop_add_network_template(device, eth_dev->vendor_id);
stringdata = (uint8_t*)malloc(sizeof(uint8_t) * string->length);
if(stringdata)
{
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
}
}
}
}
branches/meklort/i386/libsaio/sys.c
10341034
10351035
10361036
1037
10371038
10381039
10391040
10401041
10411042
1042
1043
1044
1045
10431046
1047
10441048
10451049
10461050
1051
10471052
10481053
10491054
bvr = bvr1 = NULL;
// Try resolving "rd" and "bt" devices first.
#ifndef OPTION_ROM
if (biosdev == kPseudoBIOSDevRAMDisk)
{
if (gRAMDiskVolume)
bvr1 = gRAMDiskVolume;
}
else if (biosdev == kPseudoBIOSDevBooter)
else
#endif
if (biosdev == kPseudoBIOSDevBooter)
{
#ifndef OPTION_ROM
if (gRAMDiskVolume != NULL && gRAMDiskBTAliased)
bvr1 = gRAMDiskVolume;
else
#endif
bvr1 = gBIOSBootVolume;
}
else
branches/meklort/i386/libsaio/nbp.c
2121
2222
2323
24
24
2525
2626
2727
......
134134
135135
136136
137
138137
139138
140139
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef OPTION_ROM
#include "libsaio.h"
/* This NBP code is pretty useless because it just blindly calls INT 2B.
return gNetBVR;
}
#else
#ifndef OPTION_ROM
BVRef nbpScanBootVolumes( int biosdev, int * countPtr )
{
return NULL;
branches/meklort/i386/libsaio/disk.c
19201920
19211921
19221922
1923
19231924
19241925
19251926
......
19951996
19961997
19971998
1999
19982000
1999
20002001
20012002
20022003
length,
(void *) addr );
}
#ifndef OPTION_ROM
int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len )
{
return 0;
}
#endif
int diskIsCDROM(BVRef bvr)
{
struct driveInfo di;
branches/meklort/i386/libsaio/pci_setup.c
44
55
66
7
8
9
10
11
127
138
14
159
1610
17
1811
19
20
21
2212
2313
2414
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
15
4216
4317
4418
#include "pci.h"
#include "modules.h"
extern void set_eth_builtin(pci_dt_t *eth_dev);
extern void notify_usb_dev(pci_dt_t *pci_dev);
extern void force_enable_hpet(pci_dt_t *lpc_dev);
void setup_pci_devs(pci_dt_t *pci_dt)
{
bool do_eth_devprop, do_enable_hpet;
pci_dt_t *current = pci_dt;
do_eth_devprop = do_enable_hpet = false;
getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig);
getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);
while (current)
{
execute_hook("PCIDevice", current, NULL, NULL, NULL);
switch (current->class_id) {
case PCI_CLASS_NETWORK_ETHERNET:
if (do_eth_devprop)
set_eth_builtin(current);
break;
case PCI_CLASS_SERIAL_USB:
notify_usb_dev(current);
break;
case PCI_CLASS_BRIDGE_ISA:
if (do_enable_hpet)
force_enable_hpet(current);
break;
}
setup_pci_devs(current->children);
current = current->next;
}
branches/meklort/i386/libsaio/convert.c
77
88
99
10
1011
1112
1213
......
2021
2122
2223
23
24
2425
2526
2627
#include "convert.h"
#ifndef OPTION_ROM
/** Transform a 16 bytes hexadecimal value UUID to a string */
const char * getStringFromUUID(const EFI_CHAR8* eUUID)
{
uuid[12],uuid[13],uuid[14],uuid[15]);
return msg ;
}
#endif
/** Parse an UUID string into an (EFI_CHAR8*) buffer */
EFI_CHAR8* getUUIDFromString(const char *source)
{
branches/meklort/i386/libsaio/fake_efi.c
519519
520520
521521
522
522
523523
524
524525
525526
526527
......
535536
536537
537538
538
539
539540
540541
541542
......
597598
598599
599600
600
601
601
602
602603
603604
604
605
605
606
606607
607
608
608
609
609610
610611
611612
if (!ret) // no bios dmi UUID available, set a fixed value for system-id
ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID));
#ifndef OPTION_ROM
verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output
#endif
return ret;
}
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);
DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform->Type), &Platform->Type);
}
void setupEfiDeviceTree(void)
// 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);
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.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);
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()))
branches/meklort/i386/boot2/resume.c
159159
160160
161161
162
162163
164
163165
164166
165167
uint8_t progressSaveUnder[kIOHibernateProgressCount][kIOHibernateProgressSaveUnderSize];
ReadFileAtOffset (image_filename, (char *)buffer, sizeof(IOHibernateImageHeader), preview_offset+header->previewSize);
#ifndef OPTION_ROM
drawPreview ((void *)(long)(buffer+preview_offset + header->previewPageListSize), &(progressSaveUnder[0][0]));
#endif
previewTotalSectors = (imageSize-(preview_offset+header->previewSize))/512;
previewLoadedSectors = 0;
previewSaveunder = &(progressSaveUnder[0][0]);
branches/meklort/i386/boot2/graphics.c
4646
4747
4848
49
50
49
50
5151
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
8052
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
17953
18054
18155
......
465339
466340
467341
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
504342
343
505344
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
617345
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632346
633347
634348
......
701415
702416
703417
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727418
728419
729420
......
848539
849540
850541
851
852542
853543
854544
......
903593
904594
905595
596
906597
907598
908599
......
1045736
1046737
1047738
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072739
1073740
1074741
1075
742
1076743
1077744
1078745
......
1090757
1091758
1092759
1093
760
1094761
1095762
1096763
......
1103770
1104771
1105772
1106
773
1107774
1108775
1109776
#define MIN(x, y) ((x) < (y) ? (x) : (y))
//==========================================================================
// getVBEInfoString
#ifndef OPTION_ROM
#endif
char *getVBEInfoString()
{
VBEInfoBlock vbeInfo;
int err, small;
char *buff = malloc(sizeof(char)*256);
if(!buff) return 0;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if (err != errSuccess)
return 0;
if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
return 0;
small = (vbeInfo.TotalMemory < 16);
sprintf(buff, "VESA v%d.%d %d%s (%s)\n",
vbeInfo.VESAVersion >> 8,
vbeInfo.VESAVersion & 0xf,
small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
small ? "KB" : "MB",
VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
return buff;
}
//==========================================================================
//
void
printVBEModeInfo()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
int line;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return;
line = 0;
// Activate and clear page 1
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
printf( getVBEInfoString() );
printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
*modePtr != modeEndOfList; modePtr++ )
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
if (line++ >= 20) {
pause();
line = 0;
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
}
}
if (line != 0) {
pause();
}
setActiveDisplayPage(0);
}
char *getVBEModeInfoString()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return 0;
char *buff=malloc(sizeof(char)*3072);
if(!buff) return 0;
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
*modePtr != modeEndOfList; modePtr++ )
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
sprintf(buff+strlen(buff), "Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
}
return buff;
}
//==========================================================================
// getVESAModeWithProperties
//
// Return the VESA mode that matches the properties specified.
return err;
}
int
convertImage( unsigned short width,
unsigned short height,
const unsigned char *imageData,
unsigned char **newImageData )
{
int cnt;
unsigned char *img = 0;
unsigned short *img16;
unsigned long *img32;
switch ( VIDEO(depth) ) {
case 16 :
img16 = malloc(width * height * 2);
if ( !img16 ) break;
for (cnt = 0; cnt < (width * height); cnt++)
img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16);
img = (unsigned char *)img16;
break;
case 32 :
img32 = malloc(width * height * 4);
if ( !img32 ) break;
for (cnt = 0; cnt < (width * height); cnt++)
img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32);
img = (unsigned char *)img32;
break;
default :
img = malloc(width * height);
bcopy(imageData, img, width * height);
break;
}
*newImageData = img;
return 0;
}
#ifndef OPTION_ROM
void blendImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
uint8_t *data)
{
uint16_t drawWidth;
uint8_t *vram = (uint8_t *) VIDEO(baseAddr) + VIDEO(rowBytes) * y + 4 * x;
drawWidth = MIN(width, VIDEO(width) - x);
height = MIN(height, VIDEO(height) - y);
while (height--) {
switch (VIDEO (depth))
{
case 32: /* Optimized version*/
{
uint32_t s; uint32_t* d; // Source (img) and destination (bkgd) pixels
uint32_t a; // Alpha
uint32_t dstrb, dstg, srcrb, srcg, drb, dg, rb, g, tempB; // Intermediate variables
uint16_t pos;
for (pos = 0; pos < drawWidth * 4; pos += 4) {
// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
s = *((uint32_t*) (data + pos));
d = (uint32_t*) (vram + pos);
// Flip B and R in source
// TODO: use XCHG and inline assembly to do this in a faster, saner way
tempB = (s & 0xFF0000); // save B
s = (s & 0xFF00FFFF) | ((s & 0xFF) << 16); // put R in B
s = (s & 0xFFFFFF00) | (tempB >> 16); // put B in R
a = (s >> 24) + 1;
dstrb = *d & 0xFF00FF; dstg = *d & 0xFF00;
srcrb = s & 0xFF00FF; srcg = s & 0xFF00;
drb = srcrb - dstrb;
dg = srcg - dstg;
drb *= a; dg *= a;
drb >>= 8; dg >>= 8;
rb = (drb + dstrb) & 0xFF00FF;
g = (dg + dstg) & 0xFF00;
*d = rb | g;
}
}
break;
default: /*Universal version*/
{
uint32_t s;
uint32_t a; // Alpha
uint32_t dr, dg, db, sr, sg, sb; // Intermediate variables
uint16_t pos;
int bpp = (VIDEO (depth) + 7)/8;
for (pos = 0; pos < drawWidth; pos ++) {
// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
s = *((uint32_t*) (data + 4*pos));
sb = (s & 0xFF0000) >> 16;
sg = (s & 0xFF00) >> 8;
sr = (s & 0xFF);
a = (s >> 24) + 1;
switch (VIDEO (depth))
{
case 24:
db = ((*(uint32_t *)(vram + bpp*pos))&0xff);
dg = ((*(uint32_t *)(vram + bpp*pos))&0xff00)>>8;
dr = ((*(uint32_t *)(vram + bpp*pos))&0xff0000)>>16;
break;
case 16://16-bit seems to be 15-bit
/*db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
dg = ((*(uint16_t *)(vram + bpp*pos))&0x07e0)>>3;
dr = ((*(uint16_t *)(vram + bpp*pos))&0xf800)>>8;
break;*/
case 15:
db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
dg = ((*(uint16_t *)(vram + bpp*pos))&0x03e0)>>2;
dr = ((*(uint16_t *)(vram + bpp*pos))&0x7c00)>>7;
break;
default:
return;
}
dr = (((sr - dr) * a) >> 8) + dr;
dg = (((sg - dg) * a) >> 8) + dg;
db = (((sb - db) * a) >> 8) + db;
switch (VIDEO (depth))
{
case 24:
*(uint32_t *)(vram + bpp*pos) = (*(uint32_t *)(vram + bpp*pos) &0xff000000)
| (db&0xff) | ((dg&0xff)<<8) | ((dr&0xff)<<16);
break;
case 16:
//*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xfc)<<3) | ((dr&0xf8)<<8);
//break;
case 15:
*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xf8)<<2) | ((dr&0xf8)<<7);
break;
}
}
}
break;
}
vram += VIDEO(rowBytes);
data += width * 4;
}
}
void drawCheckerBoard()
{
uint32_t *vram = (uint32_t *) VIDEO(baseAddr);
uint16_t x, y;
uint8_t color;
for (y = 0; y < VIDEO(height); y++, vram += VIDEO(width)) {
for (x = 0; x < VIDEO(width); x++) {
color = 204 + 51 * (((x / 8) % 2) == ((y / 8) % 2));
vram[x] = (color << 16) | (color << 8) | color;
}
}
}
//==========================================================================
// LookUpCLUTIndex
}
}
//==========================================================================
// drawDataRectangle
void drawDataRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char * data )
{
unsigned short drawWidth;
long pixelBytes = VIDEO(depth) / 8;
unsigned char * vram = (unsigned char *) VIDEO(baseAddr) +
VIDEO(rowBytes) * y + pixelBytes * x;
drawWidth = MIN(width, VIDEO(width) - x);
height = MIN(height, VIDEO(height) - y);
while ( height-- ) {
bcopy( data, vram, drawWidth * pixelBytes );
vram += VIDEO(rowBytes);
data += width * pixelBytes;
}
}
void
loadImageScale (void *input, int iw, int ih, int ip, void *output, int ow, int oh, int op, int or)
{
}
}
}
void updateProgressBar(uint8_t * saveunder, int32_t firstBlob, int32_t select)
{
uint8_t * screen;
}
}
}
#endif
//==========================================================================
currentIndicator = 0;
}
void getGraphicModeParams(unsigned long params[]) {
params[3] = 0;
VBEModeInfoBlock minfo;
unsigned short vesaVersion;
unsigned short mode = modeEndOfList;
getNumberArrayFromProperty( kGraphicsModeKey, params, 4);
mode = getVESAModeWithProperties( params[0], params[1], params[2],
maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
params[0] = minfo.XResolution;
params[1] = minfo.YResolution;
params[2] = 32;
}
//==========================================================================
// Return the current video mode, VGA_TEXT_MODE or GRAPHICS_MODE.
int getVideoMode(void)
inline int getVideoMode(void)
{
return bootArgs->Video.v_display;
}
spinActivityIndicator(int sectors)
{
static unsigned long lastTickTime = 0, currentTickTime;
#ifndef OPTION_ROM
if (previewTotalSectors && previewSaveunder)
{
int blob, lastBlob;
updateProgressBar (previewSaveunder, lastBlob, blob);
return;
}
#endif
currentTickTime = time18(); // late binding
if (currentTickTime < lastTickTime + MIN_TICKS)
{
branches/meklort/i386/boot2/boot.c
7676
7777
7878
79
80
8179
8280
8381
......
8684
8785
8886
87
8988
89
9090
9191
9292
......
184184
185185
186186
187
188
189
187
190188
191189
192190
......
203201
204202
205203
206
207
208
204
209205
210206
211207
//intmenucount = 0;
int gDeviceCount = 0;
boolrecoveryMode = false;
BVRef bvr;
BVRef menuBVR;
BVRef bvChain;
static unsigned long Adler32(unsigned char *buffer, long length);
static bool getOSVersion(char *str);
#ifndef OPTION_ROM
static bool gUnloadPXEOnExit = false;
#endif
/*
* How long to wait (in seconds) to load the
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.
setupBooterLog();
finalizeBootStruct();
usb_loop();
execute_hook("Kernel Start", (void*)kernelEntry, (void*)bootArgs, NULL, NULL);// Notify modules that the kernel is about to be started
// Jump to kernel's entry point. There's no going back now.
branches/meklort/i386/boot2/drivers.c
4242
4343
4444
45
4645
47
4846
49
50
51
52
53
54
55
56
47
48
49
50
51
52
53
54
5755
5856
5957
6058
61
62
63
64
65
66
59
60
61
62
63
64
6765
6866
6967
......
7169
7270
7371
74
75
76
77
78
79
80
81
72
73
74
75
76
77
78
79
8280
8381
8482
8583
86
87
84
85
8886
8987
88
9089
90
9191
9292
9393
9494
95
9596
97
9698
9799
98100
......
121123
122124
123125
124
126
125127
126128
127129
......
129131
130132
131133
132
134
133135
134136
135137
136
138
137139
138140
139
141
140142
141
143
142144
143145
144146
......
154156
155157
156158
157
159
158160
159161
160
162
161163
162164
163165
......
167169
168170
169171
170
172
171173
172174
173
175
176
174177
175178
176179
177180
178181
179
182
180183
181184
182185
......
184187
185188
186189
187
188
189
190
190
191
192
191193
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
194
195
217196
218197
219198
220199
221200
222
201
223202
224203
225204
......
227206
228207
229208
209
230210
211
212
213
231214
232215
233216
......
240223
241224
242225
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
243257
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
258
259
260
261
262
281263
282
264
283265
284
266
285267
286
268
287269
288270
289271
......
293275
294276
295277
296
297
278
279
298280
299
300
301
302
303
304
305
306
307
308
309
310
311
312
281
282
283
284
285
286
287
288
289
290
291
292
293
294
313295
314296
315297
......
322304
323305
324306
325
307
326308
327309
328310
329311
330
331
312
313
332314
333315
334
335
316
317
336318
337319
338
320
339321
340322
341323
342324
343
325
344326
345327
346328
347329
348330
349331
350
332
351333
352334
353
335
354336
355337
356338
357339
358340
359
341
360342
361343
362344
363
345
364346
365
347
366348
367
368
349
350
369351
370
352
371353
372
354
373355
374356
375357
376358
377359
378
360
379361
380362
381363
382364
383
365
384366
385367
386
368
387369
388370
389371
390372
391
392
373
374
393375
394376
395377
396
378
397379
398380
399381
......
405387
406388
407389
408
390
409391
410392
411
393
412394
413395
414396
......
419401
420402
421403
422
404
423405
424
406
425407
426408
427409
428
410
429411
430412
431
432413
414
433415
434416
435417
436418
437419
438
420
439421
440422
441423
442424
443
425
444426
445427
446428
447
429
448430
449431
450
432
451433
452434
453435
454436
455
437
456438
457439
458440
......
469451
470452
471453
472
454
473455
474456
475457
476458
477459
478460
479
461
480462
481463
482
464
483465
484
466
485467
486468
487
469
488470
489471
490
472
491473
492
474
493475
494
476
495477
496478
497
479
498480
499481
500
482
501483
502484
503485
504
486
505487
506
488
507489
508
490
509491
510492
511
493
512494
513
495
514496
515497
516498
517499
518
500
519501
520502
521
503
522504
523505
524506
525507
526
508
527509
528
510
529511
530512
531
513
532514
533515
534516
......
536518
537519
538520
539
521
540522
541
523
542524
543525
544526
......
558540
559541
560542
561
543
562544
563545
564546
......
575557
576558
577559
578
579
560
561
580562
581
563
582564
583565
584566
585567
586568
587
569
588570
589571
590572
......
599581
600582
601583
602
584
603585
604586
605
587
606588
607589
608
609
610
590
591
592
611593
612594
613595
614
596
615597
616598
617
599
618600
619601
620602
......
622604
623605
624606
625
607
626608
627609
628610
......
631613
632614
633615
634
616
635617
636
618
637619
638620
639621
......
641623
642624
643625
644
626
645627
646628
647629
......
650632
651633
652634
653
635
654636
655637
656638
......
673655
674656
675657
676
658
677659
678660
679661
......
709691
710692
711693
712
694
713695
714696
715697
......
746728
747729
748730
749
731
750732
751
733
752734
753735
754736
755737
756
738
757739
758
740
759741
760742
761
743
762744
763745
764
746
765747
766
748
767749
768750
769
770
751
752
771753
772754
773755
774756
775
757
776758
777759
778760
......
780762
781763
782764
783
765
784766
785
767
786768
787
769
788770
789
771
790772
791
773
792774
793
775
794776
795777
796778
......
806788
807789
808790
809
791
810792
811793
812794
......
816798
817799
818800
819
801
820802
821803
822804
......
828810
829811
830812
831
813
832814
833815
834
816
835817
836818
837819
......
844826
845827
846828
847
848
849
850
851
852
853
854
829
830
831
832
833
834
835
836
855837
856838
857
839
858840
859
860
861
862
863
841
842
843
844
845
864846
865
866
847
848
867849
extern char gMacOSVersion;
extern intrecoveryMode;
struct Module {
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *executablePath;
char *bundlePath;
long bundlePathLength;
struct Module *nextModule;
long willLoad;
TagPtr dict;
char *plistAddr;
long plistLength;
char *executablePath;
char *bundlePath;
long bundlePathLength;
};
typedef struct Module Module, *ModulePtr;
struct DriverInfo {
char *plistAddr;
long plistLength;
void *executableAddr;
long executableLength;
void *bundlePathAddr;
long bundlePathLength;
char *plistAddr;
long plistLength;
void *executableAddr;
long executableLength;
void *bundlePathAddr;
long bundlePathLength;
};
typedef struct DriverInfo DriverInfo, *DriverInfoPtr;
#define kDriverPackageSignature2 'MOSX'
struct DriversPackage {
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long alder32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long alder32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
unsigned long reserved2;
};
typedef struct DriversPackage DriversPackage;
enum {
kCFBundleType2,
kCFBundleType3
kCFBundleType2,
kCFBundleType3
};
#ifndef OPTION_ROM
long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
#endif
static unsigned long Alder32( unsigned char * buffer, long length );
static long FileLoadDrivers(char *dirSpec, long plugin);
#ifndef OPTION_ROM
static long NetLoadDrivers(char *dirSpec);
#endif
static long LoadDriverMKext(char *fileSpec);
static long LoadDriverPList(char *dirSpec, char *name, long bundleType);
static long LoadMatchedModules(void);
lowHalf = 1;
highHalf = 0;
for ( cnt = 0; cnt < length; cnt++ )
{
if ((cnt % 5000) == 0)
lowHalf %= 65521L;
highHalf %= 65521L;
}
lowHalf += buffer[cnt];
highHalf += lowHalf;
}
lowHalf %= 65521L;
highHalf %= 65521L;
result = (highHalf << 16) | lowHalf;
return result;
}
gFileSpec = malloc( 4096 );
gTempSpec = malloc( 4096 );
gFileName = malloc( 4096 );
if ( !gExtensionsSpec || !gDriverSpec || !gFileSpec || !gTempSpec || !gFileName )
stop("InitDriverSupport error");
return 0;
}
long LoadDrivers( char * dirSpec )
{
char dirSpecExtra[1024];
if ( InitDriverSupport() != 0 )
return 0;
#ifndef OPTION_ROM
// Load extra drivers if a hook has been installed.
if (LoadExtraDrivers_p != NULL)
{
(*LoadExtraDrivers_p)(&FileLoadDrivers);
}
if ( gBootFileType == kNetworkDeviceType )
{
if (NetLoadDrivers(dirSpec) != 0) {
return -1;
}
}
else if ( gBootFileType == kBlockDeviceType )
{
// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
if(recoveryMode)
else
#endif
if ( gBootFileType == kBlockDeviceType )
{
verbose("Loading 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
{
// First try to load Extra extensions from the ramdisk if isn't aliased as bt(0,0).
#ifndef OPTION_ROM
if (gRAMDiskVolume && !gRAMDiskBTAliased)
{
strcpy(dirSpecExtra, "rd(0,0)/Extra/");
FileLoadDrivers(dirSpecExtra, 0);
}
#endif
// 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)
#ifndef OPTION_ROM
|| (gRAMDiskVolume && gRAMDiskBTAliased) )
#else
)
#endif
{
// First try a specfic OS version folder ie 10.5
sprintf(dirSpecExtra, "bt(0,0)/Extra/%s/", &gMacOSVersion);
}
}
// TODO: fix this, the order does matter, and it's not correct now.
// Also try to load Extensions from boot helper partitions.
if (gBootVolume->flags & kBVFlagBooter)
{
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 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);
}
}
}
if (gMKextName[0] != '\0')
{
verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
if ( LoadDriverMKext(gMKextName) != 0 )
{
error("Could not load %s\n", gMKextName);
return -1;
}
}
else
{
strcpy(gExtensionsSpec, dirSpec);
strcat(gExtensionsSpec, "System/Library/");
FileLoadDrivers(gExtensionsSpec, 0);
}
}
// Also try to load Extensions from boot helper partitions.
if (gBootVolume->flags & kBVFlagBooter)
{
strcpy(dirSpecExtra, "/com.apple.boot.P/System/Library/");
if (FileLoadDrivers(dirSpecExtra, 0) != 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);
}
}
}
if (gMKextName[0] != '\0')
{
verbose("LoadDrivers: Loading from [%s]\n", gMKextName);
if ( LoadDriverMKext(gMKextName) != 0 )
{
error("Could not load %s\n", gMKextName);
return -1;
}
}
else
{
strcpy(gExtensionsSpec, dirSpec);
strcat(gExtensionsSpec, "System/Library/");
FileLoadDrivers(gExtensionsSpec, 0);
}
}
else
{
return 0;
}
else
{
return 0;
}
MatchPersonalities();
MatchLibraries();
LoadMatchedModules();
return 0;
}
static long
FileLoadMKext( const char * dirSpec, const char * extDirSpec )
{
long ret, flags, time, time2;
char altDirSpec[512];
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;
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;
}
//==========================================================================
long long index;
long result = -1;
const char * name;
if ( !plugin )
{
// First try 10.6's path for loading Extensions.mkext.
if (FileLoadMKext(dirSpec, "Caches/com.apple.kext.caches/Startup/") == 0)
return 0;
return 0;
// Next try the legacy path.
else if (FileLoadMKext(dirSpec, "") == 0)
return 0;
return 0;
strcat(dirSpec, "Extensions");
}
index = 0;
while (1) {
ret = GetDirEntry(dirSpec, &index, &name, &flags, &time);
if (ret == -1) break;
// Make sure this is a directory.
if ((flags & kFileTypeMask) != kFileTypeDirectory) continue;
// Make sure this is a kext.
length = strlen(name);
if (strcmp(name + length - 5, ".kext")) continue;
// Save the file name.
strcpy(gFileName, name);
// Determine the bundle type.
sprintf(gTempSpec, "%s/%s", dirSpec, gFileName);
ret = GetFileInfo(gTempSpec, "Contents", &flags, &time);
if (ret == 0) bundleType = kCFBundleType2;
else bundleType = kCFBundleType3;
if (!plugin)
sprintf(gDriverSpec, "%s/%s/%sPlugIns", dirSpec, gFileName,
(bundleType == kCFBundleType2) ? "Contents/" : "");
ret = LoadDriverPList(dirSpec, gFileName, bundleType);
if (result != 0)
result = ret;
result = ret;
if (!plugin)
FileLoadDrivers(gDriverSpec, 1);
FileLoadDrivers(gDriverSpec, 1);
}
return result;
}
//==========================================================================
//
#ifndef OPTION_ROM
static long
NetLoadDrivers( char * dirSpec )
{
long tries;
#if NODEF
long cnt;
// Get the name of the kernel
cnt = strlen(gBootFile);
while (cnt--) {
if ((gBootFile[cnt] == '\\') || (gBootFile[cnt] == ',')) {
cnt++;
break;
cnt++;
break;
}
}
#endif
// INTEL modification
sprintf(gDriverSpec, "%s%s.mkext", dirSpec, bootInfo->bootFile);
if (LoadDriverMKext(gDriverSpec) == 0) break;
}
if (tries == -1) return -1;
return 0;
}
#endif
//==========================================================================
// loadDriverMKext
long length;
char segName[32];
DriversPackage * package;
#define GetPackageElement(e) OSSwapBigToHostInt32(package->e)
// Load the MKext.
length = LoadThinFatFile(fileSpec, (void **)&package);
if (length < sizeof (DriversPackage)) return -1;
// call hook to notify modules that the mkext has been loaded
execute_hook("LoadDriverMKext", (void*)fileSpec, (void*)package, (void*) length, NULL);
// Verify the MKext.
if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
( GetPackageElement(signature2) != kDriverPackageSignature2) ||
( GetPackageElement(length) > kLoadSize ) ||
( GetPackageElement(alder32) !=
Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
{
return -1;
}
// Make space for the MKext.
driversLength = GetPackageElement(length);
driversAddr = AllocateKernelMemory(driversLength);
// Copy the MKext.
memcpy((void *)driversAddr, (void *)package, driversLength);
// Add the MKext to the memory map.
sprintf(segName, "DriversPackage-%lx", driversAddr);
AllocateMemoryRange(segName, driversAddr, driversLength,
kBootDriverTypeMKEXT);
return 0;
}
char * tmpExecutablePath = 0;
char * tmpBundlePath = 0;
long ret = -1;
do {
// Save the driver path.
sprintf(gFileSpec, "%s/%s/%s", dirSpec, name,
(bundleType == kCFBundleType2) ? "Contents/MacOS/" : "");
executablePathLength = strlen(gFileSpec) + 1;
tmpExecutablePath = malloc(executablePathLength);
if (tmpExecutablePath == 0) break;
strcpy(tmpExecutablePath, gFileSpec);
sprintf(gFileSpec, "%s/%s", dirSpec, name);
bundlePathLength = strlen(gFileSpec) + 1;
tmpBundlePath = malloc(bundlePathLength);
if (tmpBundlePath == 0) break;
strcpy(tmpBundlePath, gFileSpec);
// Construct the file spec to the plist, then load it.
sprintf(gFileSpec, "%s/%s/%sInfo.plist", dirSpec, name,
(bundleType == kCFBundleType2) ? "Contents/" : "");
length = LoadFile(gFileSpec);
if (length == -1) break;
length = length + 1;
buffer = malloc(length);
if (buffer == 0) break;
strlcpy(buffer, (char *)kLoadAddr, length);
// Parse the plist.
ret = ParseXML(buffer, &module, &personalities);
if (ret != 0) { break; }
// Allocate memory for the driver path and the plist.
module->executablePath = tmpExecutablePath;
module->bundlePath = tmpBundlePath;
module->bundlePathLength = bundlePathLength;
module->plistAddr = malloc(length);
if ((module->executablePath == 0) || (module->bundlePath == 0) || (module->plistAddr == 0))
break;
// Save the driver path in the module.
//strcpy(module->driverPath, tmpDriverPath);
tmpExecutablePath = 0;
tmpBundlePath = 0;
// Add the plist to the module.
strlcpy(module->plistAddr, (char *)kLoadAddr, length);
module->plistLength = length;
// Add the module to the end of the module list.
if (gModuleHead == 0)
else
gModuleTail->nextModule = module;
gModuleTail = module;
// Add the persionalities to the personality list.
if (personalities) personalities = personalities->tag;
while (personalities != 0)
{
if ( buffer ) free( buffer );
if ( tmpExecutablePath ) free( tmpExecutablePath );
if ( tmpBundlePath ) free( tmpBundlePath );
return ret;
}
DriverInfoPtr driver;
long length, driverAddr, driverLength;
void *executableAddr = 0;
module = gModuleHead;
while (module != 0)
{
if (module->willLoad)
{
prop = XMLGetProperty(module->dict, kPropCFBundleExecutable);
if (prop != 0)
{
fileName = prop->string;
}
else
length = 0;
if (length != -1)
{
//driverModuleAddr = (void *)kLoadAddr;
//driverModuleAddr = (void *)kLoadAddr;
//if (length != 0)
//{
// ThinFatFile(&driverModuleAddr, &length);
//}
// ThinFatFile(&driverModuleAddr, &length);
//}
// Make make in the image area.
execute_hook("LoadMatchedModules", module, &length, executableAddr, NULL);
driverLength = sizeof(DriverInfo) + module->plistLength + length + module->bundlePathLength;
driverAddr = AllocateKernelMemory(driverLength);
// Set up the DriverInfo.
driver = (DriverInfoPtr)driverAddr;
driver->plistAddr = (char *)(driverAddr + sizeof(DriverInfo));
if (length != 0)
{
driver->executableAddr = (void *)(driverAddr + sizeof(DriverInfo) +
module->plistLength);
module->plistLength);
driver->executableLength = length;
}
else
driver->executableLength = 0;
}
driver->bundlePathAddr = (void *)(driverAddr + sizeof(DriverInfo) +
module->plistLength + driver->executableLength);
module->plistLength + driver->executableLength);
driver->bundlePathLength = module->bundlePathLength;
// Save the plist, module and bundle.
strcpy(driver->plistAddr, module->plistAddr);
if (length != 0)
memcpy(driver->executableAddr, executableAddr, length);
}
strcpy(driver->bundlePathAddr, module->bundlePath);
// Add an entry to the memory map.
sprintf(segName, "Driver-%lx", (unsigned long)driver);
AllocateMemoryRange(segName, driverAddr, driverLength,
}
module = module->nextModule;
}
return 0;
}
TagPtr prop, prop2;
ModulePtr module, module2;
long done;
do {
done = 1;
module = gModuleHead;
}
}
while (!done);
return 0;
}
long length, pos;
TagPtr moduleDict, required;
ModulePtr tmpModule;
pos = 0;
while (1)
{
length = XMLParseNextTag(buffer + pos, &moduleDict);
if (length == -1) break;
pos += length;
if (moduleDict == 0) continue;
if (moduleDict->type == kTagTypeDict) break;
XMLFreeTag(moduleDict);
}
if (length == -1) return -1;
required = XMLGetProperty(moduleDict, kPropOSBundleRequired);
if ( (required == 0) ||
(required->type != kTagTypeString) ||
!strcmp(required->string, "Safe Boot"))
(required->type != kTagTypeString) ||
!strcmp(required->string, "Safe Boot"))
{
XMLFreeTag(moduleDict);
return -2;
}
tmpModule = malloc(sizeof(Module));
if (tmpModule == 0)
{
return -1;
}
tmpModule->dict = moduleDict;
// For now, load any module that has OSBundleRequired != "Safe Boot".
tmpModule->willLoad = 1;
*module = tmpModule;
// Get the personalities.
*personalities = XMLGetProperty(moduleDict, kPropIOKitPersonalities);
return 0;
}
u_int32_t uncompressed_size, size;
void *buffer;
unsigned long len;
#if 0
printf("kernel header:\n");
printf("signature: 0x%x\n", kernel_header->signature);
printf("compressed_size: 0x%x\n", kernel_header->compressed_size);
getc();
#endif
if (kernel_header->signature == OSSwapBigToHostConstInt32('comp')) {
if (kernel_header->compress_type != OSSwapBigToHostConstInt32('lzss')) {
error("kernel compression is bad\n");
if (kernel_header->root_path[0] && strcmp(gBootFile, kernel_header->root_path))
return -1;
#endif
uncompressed_size = OSSwapBigToHostInt32(kernel_header->uncompressed_size);
binary = buffer = malloc(uncompressed_size);
size = decompress_lzss((u_int8_t *) binary, &kernel_header->data[0],
OSSwapBigToHostInt32(kernel_header->compressed_size));
if (uncompressed_size != size) {
return -1;
}
}
ret = ThinFatFile(&binary, &len);
if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = ThinFatFile(&binary, &len);
}
ret = ThinFatFile(&binary, &len);
if (ret == 0 && len == 0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = ThinFatFile(&binary, &len);
}
//patch_kernel(binary);
ret = DecodeMachO(binary, rentry, raddr, rsize);
ret = DecodeMachO(binary, rentry, raddr, rsize);
if (ret<0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = DecodeMachO(binary, rentry, raddr, rsize);
}
if (ret<0 && archCpuType==CPU_TYPE_X86_64)
{
archCpuType=CPU_TYPE_I386;
ret = DecodeMachO(binary, rentry, raddr, rsize);
}
return ret;
return ret;
}
branches/meklort/i386/boot2/prompt.c
3535
3636
3737
38
3839
40
3941
4042
4143
char bootPrompt[] =
"Press Enter to start up Darwin/x86 with no options, or you can:\n"
" Type -v and press Enter to start up with diagnostic messages\n"
#ifndef OPTION_ROM
" Type ? and press Enter to learn about advanced startup options\n\n"
#endif
"boot: ";
#ifndef OPTION_ROM
branches/meklort/i386/boot2/ramdisk.c
99
1010
1111
12
1213
1314
1415
1516
1617
1718
19
1820
1921
2022
#include "multiboot.h"
#include "ramdisk.h"
#ifndef OPTION_ROM
struct multiboot_info * gRAMDiskMI = NULL;
// gRAMDiskVolume holds the bvr for the mounted ramdisk image.
BVRef gRAMDiskVolume = NULL;
bool gRAMDiskBTAliased = false;
char gRAMDiskFile[512];
#endif
// Notify OS X that a ramdisk has been setup. XNU with attach this to /dev/md0
void md0Ramdisk()
branches/meklort/i386/boot2/options.c
449449
450450
451451
452
452453
453454
454455
......
506507
507508
508509
509
510510
511511
512512
......
525525
526526
527527
528
528529
529530
530531
......
613614
614615
615616
616
617617
618618
619619
......
761761
762762
763763
764
765
764766
765767
766768
767
768
769
770
771
772
769773
770774
771775
......
773777
774778
775779
776
777780
778781
779782
return kn;
}
#ifndef OPTION_ROM
//==========================================================================
void printMemoryInfo(void)
}
return buff;
}
//==========================================================================
void lspci(void)
setActiveDisplayPage(0);
}
}
#endif
//==========================================================================
if (!(gBootMode & kBootModeQuiet)) {
// Display banner and show hardware info.
printf(bootBanner, (bootInfo->convmem + bootInfo->extmem) / 1024);
printf(getVBEInfoString());
}
changeCursor(0, kMenuTopRow, kCursorTypeUnderline, 0);
verbose("Scanning device %x...", gBIOSDev);
/*
* TODO: this needs to be refactored.
*/
#ifndef OPTION_ROM
#ifdef UNUSED
if (strcmp( booterCommand, "video" ) == 0)
{
printVBEModeInfo();
}
else if ( strcmp( booterCommand, "memory" ) == 0)
}
else
#endif
if ( strcmp( booterCommand, "memory" ) == 0)
{
printMemoryInfo();
}
{
lspci();
}
#ifndef OPTION_ROM
else if (strcmp(booterCommand, "more") == 0)
{
showTextFile(booterParam);
branches/meklort/i386/modules/HPET/HPET.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
/*
* Copyright (c) 2009 Evan Lojewski. All rights reserved.
*
*/
#include "libsaio.h"
#include "modules.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#include "hpet.h"
#ifndef DEBUG_HPET
#define DEBUG_HPET 0
#endif
#if DEBUG_HPET
#define DBG(x...) printf(x)
#else
#define DBG(x...)
#endif
void force_enable_hpet_intel(pci_dt_t *lpc_dev);
void force_enable_hpet_via(pci_dt_t *lpc_dev);
void HPET_hook(void* arg1, void* arg2, void* arg3, void* arg4)
{
pci_dt_t* current = arg1;
if(current->class_id != PCI_CLASS_BRIDGE_ISA) return;
bool do_enable_hpet = false;
getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);
if (do_enable_hpet)
force_enable_hpet(current);
}
void HPET_start()
{
register_hook_callback("PCIDevice", &HPET_hook);
}
/*
* Force HPET enabled
*
* via fix from http://forum.voodooprojects.org/index.php/topic,1596.0.html
*/
static struct lpc_controller_t lpc_controllers_intel[] = {
// Default unknown chipset
{ 0, 0, "" },
// Intel
{ 0x8086, 0x24dc, "ICH5" },
{ 0x8086, 0x2640, "ICH6" },
{ 0x8086, 0x2641, "ICH6M" },
{ 0x8086, 0x27b0, "ICH7 DH" },
{ 0x8086, 0x27b8, "ICH7" },
{ 0x8086, 0x27b9, "ICH7M" },
{ 0x8086, 0x27bd, "ICH7M DH" },
{ 0x8086, 0x2810, "ICH8R" },
{ 0x8086, 0x2811, "ICH8M-E" },
{ 0x8086, 0x2812, "ICH8DH" },
{ 0x8086, 0x2814, "ICH8DO" },
{ 0x8086, 0x2815, "ICH8M" },
{ 0x8086, 0x2912, "ICH9DH" },
{ 0x8086, 0x2914, "ICH9DO" },
{ 0x8086, 0x2916, "ICH9R" },
{ 0x8086, 0x2917, "ICH9M-E" },
{ 0x8086, 0x2918, "ICH9" },
{ 0x8086, 0x2919, "ICH9M" },
{ 0x8086, 0x3a14, "ICH10DO" },
{ 0x8086, 0x3a16, "ICH10R" },
{ 0x8086, 0x3a18, "ICH10" },
{ 0x8086, 0x3a1a, "ICH10D" },
};
static struct lpc_controller_t lpc_controllers_via[] = {
// Default unknown chipset
{ 0, 0, "" },
{ 0x1106, 0x3372, "VT8237S" },
};
void force_enable_hpet(pci_dt_t *lpc_dev)
{
switch(lpc_dev->vendor_id)
{
case 0x8086:
force_enable_hpet_intel(lpc_dev);
break;
case 0x1106:
force_enable_hpet_via(lpc_dev);
break;
}
#if DEBUG_HPET
printf("Press [Enter] to continue...\n");
getc();
#endif
}
void force_enable_hpet_via(pci_dt_t *lpc_dev)
{
uint32_tval, hpet_address = 0xFED00000;
int i;
/* LPC on Intel ICH is always (?) at 00:1f.0 */
for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
{
if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id)
&& (lpc_controllers_via[i].device == lpc_dev->device_id))
{
val = pci_config_read32(lpc_dev->dev.addr, 0x68);
DBG("VIA %s LPC Interface [%04x:%04x], MMIO\n",
lpc_controllers[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
if (val & 0x80) {
hpet_address = (val & ~0x3ff);
DBG("HPET at 0x%lx\n", hpet_address);
}
else
{
val = 0xfed00000 | 0x80;
pci_config_write32(lpc_dev->dev.addr, 0x68, val);
val = pci_config_read32(lpc_dev->dev.addr, 0x68);
if (val & 0x80) {
hpet_address = (val & ~0x3ff);
DBG("Force enabled HPET at 0x%lx\n", hpet_address);
}
else {
DBG("Unable to enable HPET");
}
}
}
}
}
void force_enable_hpet_intel(pci_dt_t *lpc_dev)
{
uint32_tval, hpet_address = 0xFED00000;
int i;
void*rcba;
/* LPC on Intel ICH is always (?) at 00:1f.0 */
for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
{
if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id)
&& (lpc_controllers_intel[i].device == lpc_dev->device_id))
{
rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
DBG("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
lpc_controllers[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
if (rcba == 0)
printf(" RCBA disabled; cannot force enable HPET\n");
else
{
val = REG32(rcba, 0x3404);
if (val & 0x80)
{
// HPET is enabled in HPTC. Just not reported by BIOS
DBG(" HPET is enabled in HPTC, just not reported by BIOS\n");
hpet_address |= (val & 3) << 12 ;
DBG(" HPET MMIO @ 0x%lx\n", hpet_address);
}
else
{
// HPET disabled in HPTC. Trying to enable
DBG(" HPET is disabled in HPTC, trying to enable\n");
REG32(rcba, 0x3404) = val | 0x80;
hpet_address |= (val & 3) << 12 ;
DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
}
// verify if the job is done
val = REG32(rcba, 0x3404);
if (!(val & 0x80))
printf(" Failed to force enable HPET\n");
}
break;
}
}
}
branches/meklort/i386/modules/HPET/hpet.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
*
*/
#ifndef __LIBSAIO_HPET_H
#define __LIBSAIO_HPET_H
#include "libsaio.h"
#define REG32(base, reg) ((volatile uint32_t *)base)[(reg) >> 2]
void force_enable_hpet(pci_dt_t *lpc_dev);
struct lpc_controller_t {
unsigned vendor;
unsigned device;
char *name;
};
#endif /* !__LIBSAIO_HPET_H */
branches/meklort/i386/modules/HPET/Makefile
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
MODULE_NAME = HPET
MODULE_VERSION = "1.0.0"
MODULE_COMPAT_VERSION = "1.0.0"
MODULE_START = _$(MODULE_NAME)_start
MODULE_DEPENDENCIES =
DIR = HPET
include ../../MakePaths.dir
OBJROOT=../../../obj/i386/modules/$(DIR)
SYMROOT=../../../sym/i386/modules/
DSTROOT=../../../dst/i386/modules/
UTILDIR = ../../util
LIBSADIR = ../../libsa
LIBSAIODIR = ../../libsaio
BOOT2DIR = ../../boot2
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
OPTIM = -Os -Oz
DEBUG = -DNOTHING
#DEBUG = -DDEBUG_HELLO_WORLD=1
CFLAGS= $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \
-D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \
-DRCZ_COMPRESSED_FILE_SUPPORT $(DEBUG) \
-fno-builtin $(OMIT_FRAME_POINTER_CFLAG) \
-mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \
-march=pentium4 -msse2 -mfpmath=sse -msoft-float -fno-common -mdynamic-no-pic
DEFINES=
CONFIG = hd
INC = -I. -I.. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(BOOT2DIR)
ifneq "" "$(wildcard /bin/mkdirs)"
MKDIRS = /bin/mkdirs
else
MKDIRS = /bin/mkdir -p
endif
AS = as
LD = ld
# LIBS= -lc_static
LIBS=
VPATH = $(OBJROOT):$(SYMROOT)
HPET_OBJS = HPET.o
SFILES =
CFILES =
HFILES =
EXPORTED_HFILES =
INSTALLED_HFILES =
OTHERFILES = Makefile
ALLSRC = $(SFILES) $(CFILES) \
$(HFILES) $(OTHERFILES)
DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
all embedtheme optionrom: ${HPET_OBJS} dylib
dylib: ${HPET_OBJS}
ld -flat_namespace -arch i386 \
-undefined suppress \
-alias $(MODULE_START) start \
-dylib -read_only_relocs suppress \
-S -x -Z -dead_strip_dylibs \
-no_uuid \
-current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \
-final_output $(MODULE_NAME) \
$(OBJROOT)/HPET.o -o $(SYMROOT)/$(MODULE_NAME).dylib
HPET.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "HPET.c" $(INC) -o "$(OBJROOT)/HPET.o"
include ../../MakeInc.dir
# dependencies
-include $(OBJROOT)/Makedep
branches/meklort/i386/modules/USBFix/USBFix.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
/*
* Copyright (c) 2009 Evan Lojewski. All rights reserved.
*
*/
#include "libsaio.h"
#include "modules.h"
#include "pci.h"
int usb_loop();
void notify_usb_dev(pci_dt_t *pci_dev);
void USBFix_pci_hook(void* binary, void* arg2, void* arg3, void* arg4)
{
if(current->class_id != PCI_CLASS_SERIAL_USB) return;
notify_usb_dev(current);
}
void USBFix_start_hook(void* binary, void* arg2, void* arg3, void* arg4)
{
usb_loop();
}
void HelloWorld_start()
{
//printf("Hooking 'ExecKernel'\n");
register_hook_callback("PCIDevice", &USBFix_pci_hook);
register_hook_callback("Kernel Start", &USBFix_start_hook);
}
branches/meklort/i386/modules/USBFix/usb.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
/*
* usb.c
*
*
* Created by mackerintel on 12/20/08.
* Copyright 2008 mackerintel. All rights reserved.
*
*/
#include "libsaio.h"
#include "boot.h"
#include "bootstruct.h"
#include "pci.h"
#ifndef DEBUG_USB
#define DEBUG_USB 0
#endif
#if DEBUG_USB
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
struct pciList
{
pci_dt_t* pciDev;
struct pciList* next;
};
struct pciList* usbList = NULL;
int legacy_off (pci_dt_t *pci_dev);
int ehci_acquire (pci_dt_t *pci_dev);
int uhci_reset (pci_dt_t *pci_dev);
// Add usb device to the list
void notify_usb_dev(pci_dt_t *pci_dev)
{
struct pciList* current = usbList;
if(!usbList)
{
usbList = (struct pciList*)malloc(sizeof(struct pciList));
usbList->next = NULL;
usbList->pciDev = pci_dev;
}
else
{
while(current != NULL && current->next != NULL)
{
current = current->next;
}
current->next = (struct pciList*)malloc(sizeof(struct pciList));
current = current->next;
current->pciDev = pci_dev;
current->next = NULL;
}
}
// Loop through the list and call the apropriate patch function
int usb_loop()
{
int retVal = 1;
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy = false;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig))
{
fix_ehci = fix_uhci = fix_legacy = fix_usb;// Disable all if none set
}
else
{
getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);
getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);
getBoolForKey(kLegacyOff, &fix_legacy, &bootInfo->bootConfig);
}
struct pciList* current = usbList;
while(current)
{
switch (pci_config_read8(current->pciDev->dev.addr, PCI_CLASS_PROG))
{
// EHCI
case 0x20:
if(fix_ehci) retVal &= ehci_acquire(current->pciDev);
if(fix_legacy) retVal &= legacy_off(current->pciDev);
break;
// UHCI
case 0x00:
if (fix_uhci) retVal &= uhci_reset(current->pciDev);
break;
}
current = current->next;
}
return retVal;
}
int legacy_off (pci_dt_t *pci_dev)
{
// Set usb legacy off modification by Signal64
// NOTE: This *must* be called after the last file is loaded from the drive in the event that we are booting form usb.
// NOTE2: This should be called after any getc() call. (aka, after the Wait=y keyworkd is used)
// AKA: Make this run immediatly before the kernel is called
uint32_tcapaddr, opaddr;
uint8_teecp;
uint32_tusbcmd, usbsts, usbintr;
uint32_tusblegsup, usblegctlsts;
int isOSowned;
int isBIOSowned;
verbose("Setting Legacy USB Off on controller [%04x:%04x] at %02x:%2x.%x\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func);
// capaddr = Capability Registers = dev.addr + offset stored in dev.addr + 0x10 (USBBASE)
capaddr = pci_config_read32(pci_dev->dev.addr, 0x10);
// opaddr = Operational Registers = capaddr + offset (8bit CAPLENGTH in Capability Registers + offset 0)
opaddr = capaddr + *((unsigned char*)(capaddr));
// eecp = EHCI Extended Capabilities offset = capaddr HCCPARAMS bits 15:8
eecp=*((unsigned char*)(capaddr + 9));
DBG("capaddr=%x opaddr=%x eecp=%x\n", capaddr, opaddr, eecp);
usbcmd = *((unsigned int*)(opaddr));// Command Register
usbsts = *((unsigned int*)(opaddr + 4));// Status Register
usbintr = *((unsigned int*)(opaddr + 8));// Interrupt Enable Register
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
// read PCI Config 32bit USBLEGSUP (eecp+0)
usblegsup = pci_config_read32(pci_dev->dev.addr, eecp);
// informational only
isBIOSowned = !!((usblegsup) & (1 << (16)));
isOSowned = !!((usblegsup) & (1 << (24)));
// read PCI Config 32bit USBLEGCTLSTS (eecp+4)
usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4);
DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts);
// Reset registers to Legacy OFF
DBG("Clearing USBLEGCTLSTS\n");
pci_config_write32(pci_dev->dev.addr, eecp + 4, 0);//usblegctlsts
// if delay value is in milliseconds it doesn't appear to work.
// setting value to anything up to 65535 does not add the expected delay here.
delay(100);
usbcmd = *((unsigned int*)(opaddr));
usbsts = *((unsigned int*)(opaddr + 4));
usbintr = *((unsigned int*)(opaddr + 8));
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
DBG("Clearing Registers\n");
// clear registers to default
usbcmd = (usbcmd & 0xffffff00);
*((unsigned int*)(opaddr)) = usbcmd;
*((unsigned int*)(opaddr + 8)) = 0;//usbintr - clear interrupt registers
*((unsigned int*)(opaddr + 4)) = 0x1000;//usbsts - clear status registers
pci_config_write32(pci_dev->dev.addr, eecp, 1);//usblegsup
// get the results
usbcmd = *((unsigned int*)(opaddr));
usbsts = *((unsigned int*)(opaddr + 4));
usbintr = *((unsigned int*)(opaddr + 8));
DBG("usbcmd=%08x usbsts=%08x usbintr=%08x\n", usbcmd, usbsts, usbintr);
// read 32bit USBLEGSUP (eecp+0)
usblegsup = pci_config_read32(pci_dev->dev.addr, eecp);
// informational only
isBIOSowned = !!((usblegsup) & (1 << (16)));
isOSowned = !!((usblegsup) & (1 << (24)));
// read 32bit USBLEGCTLSTS (eecp+4)
usblegctlsts = pci_config_read32(pci_dev->dev.addr, eecp + 4);
DBG("usblegsup=%08x isOSowned=%d isBIOSowned=%d usblegctlsts=%08x\n", usblegsup, isOSowned, isBIOSowned, usblegctlsts);
verbose("Legacy USB Off Done\n");
return 1;
}
int ehci_acquire (pci_dt_t *pci_dev)
{
intj, k;
uint32_tbase;
uint8_teecp;
uint8_tlegacy[8];
boolisOwnershipConflict;
boolalwaysHardBIOSReset;
alwaysHardBIOSReset = false;
if (!getBoolForKey(kEHCIhard, &alwaysHardBIOSReset, &bootInfo->bootConfig)) {
alwaysHardBIOSReset = true;
}
pci_config_write16(pci_dev->dev.addr, 0x04, 0x0002);
base = pci_config_read32(pci_dev->dev.addr, 0x10);
verbose("EHCI controller [%04x:%04x] at %02x:%2x.%x DMA @%x\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func,
base);
if (*((unsigned char*)base) < 0xc)
{
DBG("Config space too small: no legacy implementation\n");
return 1;
}
eecp = *((unsigned char*)(base + 9));
if (!eecp) {
DBG("No extended capabilities: no legacy implementation\n");
return 1;
}
DBG("eecp=%x\n",eecp);
// bad way to do it
// pci_conf_write(pci_dev->dev.addr, eecp, 4, 0x01000001);
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
DBG("%02x ", legacy[j]);
}
DBG("\n");
//Real Job: based on orByte's AppleUSBEHCI.cpp
//We try soft reset first - some systems hang on reboot with hard reset
// Definitely needed during reboot on 10.4.6
isOwnershipConflict = ((legacy[3] & 1 != 0) && (legacy[2] & 1 != 0));
if (!alwaysHardBIOSReset && isOwnershipConflict) {
DBG("EHCI - Ownership conflict - attempting soft reset ...\n");
DBG("EHCI - toggle OS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 3, 0);
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
if (legacy[3] == 0) {
break;
}
delay(10);
}
}
DBG("Found USBLEGSUP_ID - value %x:%x - writing OSOwned\n", legacy[3],legacy[2]);
pci_config_write8(pci_dev->dev.addr, eecp + 3, 1);
// wait for kEHCI_USBLEGSUP_BIOSOwned bit to clear
for (k = 0; k < 25; k++) {
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if (legacy[2] == 0) {
break;
}
delay(10);
}
for (j = 0;j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
isOwnershipConflict = ((legacy[2]) != 0);
if (isOwnershipConflict) {
// Soft reset has failed. Assume SMI being ignored
// Hard reset
// Force Clear BIOS BIT
DBG("EHCI - Ownership conflict - attempting hard reset ...\n");
DBG ("%x:%x\n",legacy[3],legacy[2]);
DBG("EHCI - Force BIOS Ownership to 0\n");
pci_config_write8(pci_dev->dev.addr, eecp + 2, 0);
for (k = 0; k < 25; k++) {
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x,",legacy[3],legacy[2]);
if ((legacy[2]) == 0) {
break;
}
delay(10);
}
// Disable further SMI events
for (j = 4; j < 8; j++) {
pci_config_write8(pci_dev->dev.addr, eecp + j, 0);
}
}
for (j = 0; j < 8; j++) {
legacy[j] = pci_config_read8(pci_dev->dev.addr, eecp + j);
}
DBG ("%x:%x\n",legacy[3],legacy[2]);
// Final Ownership Resolution Check...
if (legacy[2] & 1) {
DBG("EHCI controller unable to take control from BIOS\n");
return 0;
}
DBG("EHCI Acquire OS Ownership done\n");
return 1;
}
int uhci_reset (pci_dt_t *pci_dev)
{
uint32_t base, port_base;
base = pci_config_read32(pci_dev->dev.addr, 0x20);
port_base = (base >> 5) & 0x07ff;
verbose("UHCI controller [%04x:%04x] at %02x:%2x.%x base %x(%x)\n",
pci_dev->vendor_id, pci_dev->device_id,
pci_dev->dev.bits.bus, pci_dev->dev.bits.dev, pci_dev->dev.bits.func,
port_base, base);
pci_config_write16(pci_dev->dev.addr, 0xc0, 0x8f00);
outw (port_base, 0x0002);
delay(10);
outw (port_base+4,0);
delay(10);
outw (port_base,0);
return 1;
}
branches/meklort/i386/modules/USBFix/Makefile
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
MODULE_NAME = USBFix
MODULE_VERSION = "1.0.0"
MODULE_COMPAT_VERSION = "1.0.0"
MODULE_START = _$(MODULE_NAME)_start
MODULE_DEPENDENCIES =
DIR = USBFix
include ../../MakePaths.dir
OBJROOT=../../../obj/i386/modules/$(DIR)
SYMROOT=../../../sym/i386/modules/
DSTROOT=../../../dst/i386/modules/
UTILDIR = ../../util
LIBSADIR = ../../libsa
LIBSAIODIR = ../../libsaio
BOOT2DIR = ../../boot2
INSTALLDIR = $(DSTROOT)/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/standalone
OPTIM = -Os -Oz
DEBUG = -DNOTHING
#DEBUG = -DDEBUG_HELLO_WORLD=1
CFLAGS= $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost \
-D__ARCHITECTURE__=\"i386\" -DSAIO_INTERNAL_USER \
-DRCZ_COMPRESSED_FILE_SUPPORT $(DEBUG) \
-fno-builtin $(OMIT_FRAME_POINTER_CFLAG) \
-mpreferred-stack-boundary=2 -fno-align-functions -fno-stack-protector \
-march=pentium4 -msse2 -mfpmath=sse -msoft-float -fno-common -mdynamic-no-pic
DEFINES=
CONFIG = hd
INC = -I. -I.. -I$(SYMROOT) -I$(UTILDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(BOOT2DIR)
ifneq "" "$(wildcard /bin/mkdirs)"
MKDIRS = /bin/mkdirs
else
MKDIRS = /bin/mkdir -p
endif
AS = as
LD = ld
# LIBS= -lc_static
LIBS=
VPATH = $(OBJROOT):$(SYMROOT)
USB_OBJS = USBFix.o usb.o
SFILES =
CFILES =
HFILES =
EXPORTED_HFILES =
INSTALLED_HFILES =
OTHERFILES = Makefile
ALLSRC = $(SFILES) $(CFILES) \
$(HFILES) $(OTHERFILES)
DIRS_NEEDED = $(OBJROOT) $(SYMROOT)
all embedtheme optionrom: ${USB_OBJS} dylib
dylib: ${USB_OBJS}
ld -flat_namespace -arch i386 \
-undefined suppress \
-alias $(MODULE_START) start \
-dylib -read_only_relocs suppress \
-S -x -Z -dead_strip_dylibs \
-no_uuid \
-current_version $(MODULE_VERSION) -compatibility_version $(MODULE_COMPAT_VERSION) \
-final_output $(MODULE_NAME) \
$(OBJROOT)/USBFix.o \
$(OBJROOT)/usb.o \
-o $(SYMROOT)/$(MODULE_NAME).dylib
USBFix.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "USBFix.c" $(INC) -o "$(OBJROOT)/USBFix.o"
usb.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c "usb.c" $(INC) -o "$(OBJROOT)/usb.o"
include ../../MakeInc.dir
# dependencies
-include $(OBJROOT)/Makedep
branches/meklort/i386/modules/ACPIPatcher/acpi_patcher.c
215215
216216
217217
218
218
219219
220220
221221
......
340340
341341
342342
343
343
344344
345345
346346
347347
348
348
349349
350350
351351
......
359359
360360
361361
362
362
363363
364364
365
365
366366
367367
368368
......
474474
475475
476476
477
477
478478
479479
480480
......
568568
569569
570570
571
571
572572
573573
574574
......
594594
595595
596596
597
597
598598
599599
600
600
601601
602
603
602
603
604604
605605
606
606
607607
608608
609
609
610610
611611
612612
613
614
613
614
615615
616616
617617
618
618
619619
620620
621621
0x00, 0x00, 0x00, 0x79, 0x00
};
if (Platform.CPU.Vendor != 0x756E6547) {
if (Platform->CPU.Vendor != 0x756E6547) {
verbose ("Not an Intel platform: C-States will not be generated !!!\n");
return NULL;
}
0x31, 0x03, 0x10, 0x20,/* 1.._*/
};
if (Platform.CPU.Vendor != 0x756E6547) {
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)) {
if (!(Platform->CPU.Features & CPU_FEATURE_MSR)) {
verbose ("Unsupported CPU: P-States will not be generated !!!\n");
return NULL;
}
uint8_t p_states_count = 0;
// Retrieving P-States, ported from code by superhai (c)
switch (Platform.CPU.Family) {
switch (Platform->CPU.Family) {
case 0x06:
{
switch (Platform.CPU.Model)
switch (Platform->CPU.Model)
{
case 0x0D: // ?
case CPU_MODEL_YONAH: // Yonah
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 fsb = Platform->CPU.FSBFrequency / 1000000; // = 400
uint32_t halffsb = (fsb + 1) >> 1;// = 200
uint32_t frequency = (multiplier * fsb);// = 3200
const char * value;
// Restart Fix
if (Platform.CPU.Vendor == 0x756E6547) {/* Intel */
if (Platform->CPU.Vendor == 0x756E6547) {/* Intel */
fix_restart = true;
getBoolForKey(kRestartFix, &fix_restart, &bootInfo->bootConfig);
} else {
// Determine system type / PM_Model
if ( (value=getStringForKey(kSystemType, &bootInfo->bootConfig))!=NULL)
{
if (Platform.Type > 6)
if (Platform->Type > 6)
{
if(fadt_mod->PM_Profile<=6)
Platform.Type = fadt_mod->PM_Profile; // get the fadt if correct
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);
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);
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 (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;
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;
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()
branches/meklort/i386/modules/ACPIPatcher/ACPIPatcher.c
1111
1212
1313
14
15
1416
1517
1618
......
9496
9597
9698
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
#include "acpi_patcher.h"
int ACPIPatcher_getPciRootUID(void);
unsigned int findpciroot(unsigned char * dsdt,int len);
static unsigned int findrootuid(unsigned char * dsdt, int len);
void ACPIPatcher_setupEfiConfigurationTable_hook(void* binary, void* arg2, void* arg3, void* arg4)
{
verbose("Using PCI-Root-UID value: %d\n", ACPIPatcher_rootuid);
return ACPIPatcher_rootuid;
}
unsigned int findpciroot(unsigned char * dsdt,int len)
{
int i;
for (i=0; i<len-4; i++) {
if(dsdt[i] == 'P' && dsdt[i+1] == 'C' && dsdt[i+2] == 'I' && (dsdt[i+3] == 0x08 || dsdt [i+4] == 0x08)) {
return findrootuid(dsdt+i, len-i);
}
}
return 10;
}
static unsigned int findrootuid(unsigned char * dsdt, int len)
{
int i;
for (i=0; i<64 && i<len-5; i++) //not far than 64 symbols from pci root
{
if(dsdt[i] == '_' && dsdt[i+1] == 'U' && dsdt[i+2] == 'I' && dsdt[i+3] == 'D' && dsdt[i+5] == 0x08)
{
return dsdt[i+4];
}
}
return 11;
}
branches/meklort/i386/modules/GUI/graphic_utils.h
1212
1313
1414
15
16
17
1518
1619
1720
#include "boot.h"
char *getVBEInfoString();
typedef union {
struct {
uint8_t b;
branches/meklort/i386/modules/GUI/graphic_utils.c
55
66
77
8
9
810
911
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
10364
11365
12366
*/
#include "boot.h"
#include "graphic_utils.h"
#include "graphics.h"
#include "vbe.h"
#include "gui.h"
#define VIDEO(x) (bootArgs->Video.v_ ## x)
#define MIN(x, y) ((x) < (y) ? (x) : (y))
int
convertImage( unsigned short width,
unsigned short height,
const unsigned char *imageData,
unsigned char **newImageData )
{
int cnt;
unsigned char *img = 0;
unsigned short *img16;
unsigned long *img32;
switch ( VIDEO(depth) ) {
case 16 :
img16 = malloc(width * height * 2);
if ( !img16 ) break;
for (cnt = 0; cnt < (width * height); cnt++)
img16[cnt] = lookUpCLUTIndex(imageData[cnt], 16);
img = (unsigned char *)img16;
break;
case 32 :
img32 = malloc(width * height * 4);
if ( !img32 ) break;
for (cnt = 0; cnt < (width * height); cnt++)
img32[cnt] = lookUpCLUTIndex(imageData[cnt], 32);
img = (unsigned char *)img32;
break;
default :
img = malloc(width * height);
bcopy(imageData, img, width * height);
break;
}
*newImageData = img;
return 0;
}
//==========================================================================
//
void
printVBEModeInfo()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
int line;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return;
line = 0;
// Activate and clear page 1
setActiveDisplayPage(1);
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
printf("Video modes supported:\n", VBEDecodeFP(const char *, vbeInfo.OEMStringPtr));
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
*modePtr != modeEndOfList; modePtr++ )
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
printf("Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
if (line++ >= 20) {
pause();
line = 0;
clearScreenRows(0, 24);
setCursorPosition( 0, 0, 1 );
}
}
if (line != 0) {
pause();
}
setActiveDisplayPage(0);
}
char *getVBEModeInfoString()
{
VBEInfoBlock vbeInfo;
unsigned short * modePtr;
VBEModeInfoBlock modeInfo;
int err;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if ( err != errSuccess )
return 0;
char *buff=malloc(sizeof(char)*3072);
if(!buff) return 0;
// Loop through the mode list, and find the matching mode.
for ( modePtr = VBEDecodeFP( unsigned short *, vbeInfo.VideoModePtr );
*modePtr != modeEndOfList; modePtr++ )
{
// Get mode information.
bzero( &modeInfo, sizeof(modeInfo) );
err = getVBEModeInfo( *modePtr, &modeInfo );
if ( err != errSuccess )
{
continue;
}
sprintf(buff+strlen(buff), "Mode %x: %dx%dx%d mm:%d attr:%x\n",
*modePtr, modeInfo.XResolution, modeInfo.YResolution,
modeInfo.BitsPerPixel, modeInfo.MemoryModel,
modeInfo.ModeAttributes);
}
return buff;
}
void blendImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
uint8_t *data)
{
uint16_t drawWidth;
uint8_t *vram = (uint8_t *) VIDEO(baseAddr) + VIDEO(rowBytes) * y + 4 * x;
drawWidth = MIN(width, VIDEO(width) - x);
height = MIN(height, VIDEO(height) - y);
while (height--) {
switch (VIDEO (depth))
{
case 32: /* Optimized version*/
{
uint32_t s; uint32_t* d; // Source (img) and destination (bkgd) pixels
uint32_t a; // Alpha
uint32_t dstrb, dstg, srcrb, srcg, drb, dg, rb, g, tempB; // Intermediate variables
uint16_t pos;
for (pos = 0; pos < drawWidth * 4; pos += 4) {
// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
s = *((uint32_t*) (data + pos));
d = (uint32_t*) (vram + pos);
// Flip B and R in source
// TODO: use XCHG and inline assembly to do this in a faster, saner way
tempB = (s & 0xFF0000); // save B
s = (s & 0xFF00FFFF) | ((s & 0xFF) << 16); // put R in B
s = (s & 0xFFFFFF00) | (tempB >> 16); // put B in R
a = (s >> 24) + 1;
dstrb = *d & 0xFF00FF; dstg = *d & 0xFF00;
srcrb = s & 0xFF00FF; srcg = s & 0xFF00;
drb = srcrb - dstrb;
dg = srcg - dstg;
drb *= a; dg *= a;
drb >>= 8; dg >>= 8;
rb = (drb + dstrb) & 0xFF00FF;
g = (dg + dstg) & 0xFF00;
*d = rb | g;
}
}
break;
default: /*Universal version*/
{
uint32_t s;
uint32_t a; // Alpha
uint32_t dr, dg, db, sr, sg, sb; // Intermediate variables
uint16_t pos;
int bpp = (VIDEO (depth) + 7)/8;
for (pos = 0; pos < drawWidth; pos ++) {
// Fast pseudo-vector alpha blending, adapted from: http://www.stereopsis.com/doubleblend.html
s = *((uint32_t*) (data + 4*pos));
sb = (s & 0xFF0000) >> 16;
sg = (s & 0xFF00) >> 8;
sr = (s & 0xFF);
a = (s >> 24) + 1;
switch (VIDEO (depth))
{
case 24:
db = ((*(uint32_t *)(vram + bpp*pos))&0xff);
dg = ((*(uint32_t *)(vram + bpp*pos))&0xff00)>>8;
dr = ((*(uint32_t *)(vram + bpp*pos))&0xff0000)>>16;
break;
case 16://16-bit seems to be 15-bit
/*db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
dg = ((*(uint16_t *)(vram + bpp*pos))&0x07e0)>>3;
dr = ((*(uint16_t *)(vram + bpp*pos))&0xf800)>>8;
break;*/
case 15:
db = ((*(uint16_t *)(vram + bpp*pos))&0x1f)<<3;
dg = ((*(uint16_t *)(vram + bpp*pos))&0x03e0)>>2;
dr = ((*(uint16_t *)(vram + bpp*pos))&0x7c00)>>7;
break;
default:
return;
}
dr = (((sr - dr) * a) >> 8) + dr;
dg = (((sg - dg) * a) >> 8) + dg;
db = (((sb - db) * a) >> 8) + db;
switch (VIDEO (depth))
{
case 24:
*(uint32_t *)(vram + bpp*pos) = (*(uint32_t *)(vram + bpp*pos) &0xff000000)
| (db&0xff) | ((dg&0xff)<<8) | ((dr&0xff)<<16);
break;
case 16:
//*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xfc)<<3) | ((dr&0xf8)<<8);
//break;
case 15:
*(uint16_t *)(vram + bpp*pos) = ((db&0xf8)>>3) | ((dg&0xf8)<<2) | ((dr&0xf8)<<7);
break;
}
}
}
break;
}
vram += VIDEO(rowBytes);
data += width * 4;
}
}
void drawCheckerBoard()
{
uint32_t *vram = (uint32_t *) VIDEO(baseAddr);
uint16_t x, y;
uint8_t color;
for (y = 0; y < VIDEO(height); y++, vram += VIDEO(width)) {
for (x = 0; x < VIDEO(width); x++) {
color = 204 + 51 * (((x / 8) % 2) == ((y / 8) % 2));
vram[x] = (color << 16) | (color << 8) | color;
}
}
}
//==========================================================================
// drawDataRectangle
void drawDataRectangle( unsigned short x,
unsigned short y,
unsigned short width,
unsigned short height,
unsigned char * data )
{
unsigned short drawWidth;
long pixelBytes = VIDEO(depth) / 8;
unsigned char * vram = (unsigned char *) VIDEO(baseAddr) +
VIDEO(rowBytes) * y + pixelBytes * x;
drawWidth = MIN(width, VIDEO(width) - x);
height = MIN(height, VIDEO(height) - y);
while ( height-- ) {
bcopy( data, vram, drawWidth * pixelBytes );
vram += VIDEO(rowBytes);
data += width * pixelBytes;
}
}
void getGraphicModeParams(unsigned long params[]) {
params[3] = 0;
VBEModeInfoBlock minfo;
unsigned short vesaVersion;
unsigned short mode = modeEndOfList;
getNumberArrayFromProperty( kGraphicsModeKey, params, 4);
mode = getVESAModeWithProperties( params[0], params[1], params[2],
maColorModeBit |
maModeIsSupportedBit |
maGraphicsModeBit |
maLinearFrameBufferAvailBit,
0,
&minfo, &vesaVersion );
params[0] = minfo.XResolution;
params[1] = minfo.YResolution;
params[2] = 32;
}
//==========================================================================
// getVBEInfoString
char *getVBEInfoString()
{
VBEInfoBlock vbeInfo;
int err, small;
char *buff = malloc(sizeof(char)*256);
if(!buff) return 0;
bzero( &vbeInfo, sizeof(vbeInfo) );
strcpy( (char*)&vbeInfo, "VBE2" );
err = getVBEInfo( &vbeInfo );
if (err != errSuccess)
return 0;
if ( strncmp( (char *)vbeInfo.VESASignature, "VESA", 4 ) )
return 0;
small = (vbeInfo.TotalMemory < 16);
sprintf(buff, "VESA v%d.%d %d%s (%s)\n",
vbeInfo.VESAVersion >> 8,
vbeInfo.VESAVersion & 0xf,
small ? (vbeInfo.TotalMemory * 64) : (vbeInfo.TotalMemory / 16),
small ? "KB" : "MB",
VBEDecodeFP(const char *, vbeInfo.OEMStringPtr) );
return buff;
}
void blend( const pixmap_t *blendThis, // Source image
pixmap_t *blendInto, // Dest image
const position_t position) // Where to place the source image
branches/meklort/i386/modules/KernelPatcher/kernel_patcher.c
77
88
99
10
10
1111
1212
1313
......
5757
5858
5959
60
60
6161
6262
63
63
6464
6565
6666
6767
6868
69
69
7070
7171
7272
......
240240
241241
242242
243
243
244244
245245
246246
#include "kernel_patcher.h"
#include "platform.h"
#include "modules.h"
extern PlatformInfo_t Platform;
extern PlatformInfo_t* Platform;
patchRoutine_t* patches = NULL;
kernSymbols_t* kernelSymbols = NULL;
// AKA, don't at 64bit patches if it's a 32bit only machine
patchRoutine_t* entry;
// TODO: verify Platform.CPU.Model is populated this early in bootup
// TODO: verify Platform->CPU.Model is populated this early in bootup
// Check to ensure that the patch is valid on this machine
// If it is not, exit early form this function
if(cpus != Platform.CPU.Model)
if(cpus != Platform->CPU.Model)
{
if(cpus != CPUID_MODEL_ANY)
{
if(cpus == CPUID_MODEL_UNKNOWN)
{
switch(Platform.CPU.Model)
switch(Platform->CPU.Model)
{
case 13:
case CPUID_MODEL_YONAH:
**/
void patch_cpuid_set_info_all(void* kernelData)
{
switch(Platform.CPU.Model)
switch(Platform->CPU.Model)
{
case CPUID_MODEL_ATOM:
if(determineKernelArchitecture(kernelData) == KERNEL_32)
branches/meklort/i386/modules/Memory/mem.c
110110
111111
112112
113
113
114114
115115
116
116
117117
118118
119119
120120
121121
122122
123
124
123
124
125125
126126
127127
......
130130
131131
132132
133
134
133
134
135135
136136
137137
struct DMIMemoryDevice* memDev[MAX_RAM_SLOTS]; //17
/* We mainly don't use obsolete tables 5,6 because most of computers don't handle it anymore */
Platform.DMI.MemoryModules = 0;
Platform->DMI.MemoryModules = 0;
/* Now lets peek info rom table 16,17 as for some bios, table 5 & 6 are not used */
physMemArray = (struct DMIPhysicalMemoryArray*) FindFirstDmiTableOfType(16, 4);
Platform.DMI.MaxMemorySlots = physMemArray ? physMemArray->numberOfMemoryDevices : 0;
Platform->DMI.MaxMemorySlots = physMemArray ? physMemArray->numberOfMemoryDevices : 0;
i = 0;
for(dmihdr = FindFirstDmiTableOfType(17, 4);
dmihdr;
dmihdr = FindNextDmiTableOfType(17, 4) ) {
memDev[i] = (struct DMIMemoryDevice*) dmihdr;
if (memDev[i]->size !=0 ) Platform.DMI.MemoryModules++;
if (memDev[i]->speed>0) Platform.RAM.DIMM[i].Frequency = memDev[i]->speed; // take it here for now but we'll check spd and dmi table 6 as well
if (memDev[i]->size !=0 ) Platform->DMI.MemoryModules++;
if (memDev[i]->speed>0) Platform->RAM.DIMM[i].Frequency = memDev[i]->speed; // take it here for now but we'll check spd and dmi table 6 as well
i++;
}
// for table 6, we only have a look at the current speed
dmihdr;
dmihdr = FindNextDmiTableOfType(6, 4) ) {
memInfo[i] = (struct DMIMemoryModuleInfo*) dmihdr;
if (memInfo[i]->currentSpeed > Platform.RAM.DIMM[i].Frequency)
Platform.RAM.DIMM[i].Frequency = memInfo[i]->currentSpeed; // favor real overclocked speed if any
if (memInfo[i]->currentSpeed > Platform->RAM.DIMM[i].Frequency)
Platform->RAM.DIMM[i].Frequency = memInfo[i]->currentSpeed; // favor real overclocked speed if any
i++;
}
#if 0
branches/meklort/i386/modules/Memory/spd.c
8080
8181
8282
83
83
8484
8585
8686
......
9393
9494
9595
96
96
9797
9898
9999
......
261261
262262
263263
264
264
265265
266266
267267
268268
269269
270
270
271271
272272
273273
......
308308
309309
310310
311
312
311
312
313313
314314
315315
......
337337
338338
339339
340
341
340
341
342342
343343
344344
while( inb(base + SMBHSTSTS) & 0x01)
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform->CPU.TSCFrequency / 100);
if(t > 50) return 0xFF;// hack, exit if unresponsive.
}
while (!( inb(base + SMBHSTSTS) & 0x02))// wait til command finished
{
rdtsc(l2, h2);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform.CPU.TSCFrequency / 100);
t = ((h2 - h1) * 0xffffffff + (l2 - l1)) / (Platform->CPU.TSCFrequency / 100);
if (t > 5)
break;// break after 5ms
}
getBoolForKey("DumpSPD", &dump, &bootInfo->bootConfig);
bool fullBanks = // needed at least for laptops
Platform.DMI.MemoryModules == Platform.DMI.MaxMemorySlots;
Platform->DMI.MemoryModules == Platform->DMI.MaxMemorySlots;
// Search MAX_RAM_SLOTS slots
char spdbuf[256];
for (i = 0; i < MAX_RAM_SLOTS; i++){
DBG("Scanning slot %d\n", i);
slot = &Platform.RAM.DIMM[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) ) {
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;
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) {
}
}
// laptops sometimes show slot 0 and 2 with slot 1 empty when only 2 slots are presents so:
Platform.DMI.DIMM[i]=
i>0 && Platform.RAM.DIMM[1].InUse==false && fullBanks && Platform.DMI.MaxMemorySlots==2 ?
Platform->DMI.DIMM[i]=
i>0 && Platform->RAM.DIMM[1].InUse==false && fullBanks && Platform->DMI.MaxMemorySlots==2 ?
mapping[i] : i; // for laptops case, mapping setup would need to be more generic than this
slot->spd = NULL;
branches/meklort/i386/modules/Memory/Memory.c
1313
1414
1515
16
16
1717
1818
1919
#include "mem.h"
#include "modules.h"
pci_dt_t *dram_controller_dev;
pci_dt_t * dram_controller_dev = NULL;
void Memory_hook(void* arg1, void* arg2, void* arg3, void* arg4);
branches/meklort/i386/modules/Memory/dram_controllers.c
159159
160160
161161
162
162
163163
164
164
165165
166166
167167
......
231231
232232
233233
234
234
235235
236236
237237
......
245245
246246
247247
248
248
249249
250250
251251
......
290290
291291
292292
293
293
294294
295295
296
296
297297
298298
299
299
300300
301301
302
302
303303
304304
305
305
306306
307307
308
308
309309
310
310
311311
312312
313313
......
337337
338338
339339
340
340
341341
342342
343
343
344344
345345
346
346
347347
348348
349
349
350350
351351
352
352
353353
354354
355
355
356356
357
357
358358
359359
360360
......
413413
414414
415415
416
416
417417
418
418
419419
420420
421421
422
422
423423
424
424
425425
426426
427
427
428428
429429
430
430
431431
432432
433
433
434434
435435
436436
437
437
438438
439
439
440440
441441
442442
......
450450
451451
452452
453
453
454454
455455
456456
......
465465
466466
467467
468
468
469469
470470
471
471
472472
473473
474
474
475475
476476
477
477
478478
479479
480480
481
481
482482
483
483
484484
485
485
486486
487487
488488
......
552552
553553
554554
555
556
557
558
555
556
557
558
559559
560560
561561
DBG("mch_ratio %d\n", mch_ratio);
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
Platform->RAM.Frequency = (Platform->CPU.FSBFrequency * mch_ratio) / 100000;
DBG("ram_fsb %d\n", Platform.RAM.Frequency);
DBG("ram_fsb %d\n", Platform->RAM.Frequency);
}
}
// Compute RAM Frequency
Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;
Platform->RAM.Frequency = (Platform->CPU.FSBFrequency * mch_ratio) / 100000;
}
mch_ratio = (mc_dimm_clk_ratio & 0x1F);
// Compute RAM Frequency
Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2;
Platform->RAM.Frequency = Platform->CPU.FSBFrequency * mch_ratio / 2;
}
/*
Misc_Register = *ptr & 0xFFFFFFFF;
// 965 Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
Platform->RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3;
Platform->RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 16) & 0xF;
Platform->RAM.TRC = (Read_Register >> 16) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
Platform->RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 11) & 0x1F;
Platform->RAM.RAS = (Precharge_Register >> 11) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
Platform->RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
Platform->RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get im965 Memory Timings
Precharge_Register = *ptr & 0xFFFFFFFF;
// Series only support DDR2
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
Platform->RAM.Type = SMB_MEM_TYPE_DDR2;
// CAS Latency (tCAS)
Platform.RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3;
Platform->RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = ((Precharge_Register >> 5) & 7) + 2;
Platform->RAM.TRC = ((Precharge_Register >> 5) & 7) + 2;
// RAS Precharge (tRP)
Platform.RAM.TRP= (Precharge_Register & 7) + 2;
Platform->RAM.TRP= (Precharge_Register & 7) + 2;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (Precharge_Register >> 21) & 0x1F;
Platform->RAM.RAS = (Precharge_Register >> 21) & 0x1F;
if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
Platform->RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
Platform->RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get P35 Memory Timings
// Determine DDR-II or DDR-III
if (Memory_Check & 1)
Platform.RAM.Type = SMB_MEM_TYPE_DDR2;
Platform->RAM.Type = SMB_MEM_TYPE_DDR2;
else
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
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;
Platform->RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 6;
else
Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9;
Platform->RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (Read_Register >> 17) & 0xF;
Platform->RAM.TRC = (Read_Register >> 17) & 0xF;
// RAS Precharge (tRP)
Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;
Platform->RAM.TRP = (ACT_Register >> 13) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = Precharge_Register & 0x3F;
Platform->RAM.RAS = Precharge_Register & 0x3F;
// Channel configuration
if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF))
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
Platform->RAM.Channels = SMB_MEM_CHANNEL_DUAL;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
Platform->RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
}
// Get Nehalem Memory Timings
mc_control = (mc_control >> 8) & 0x7;
// DDR-III
Platform.RAM.Type = SMB_MEM_TYPE_DDR3;
Platform->RAM.Type = SMB_MEM_TYPE_DDR3;
// Get the first valid channel
if(mc_control & 1)
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;
Platform->RAM.CAS = ((mc_channel_mrs_value >> 4) & 0xF ) + 4;
// RAS-To-CAS (tRCD)
Platform.RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF;
Platform->RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF;
// RAS Active to precharge (tRAS)
Platform.RAM.RAS = (mc_channel_bank_timing >> 4) & 0x1F;
Platform->RAM.RAS = (mc_channel_bank_timing >> 4) & 0x1F;
// RAS Precharge (tRP)
Platform.RAM.TRP = mc_channel_bank_timing & 0xF;
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;
Platform->RAM.Channels = SMB_MEM_CHANNEL_SINGLE;
else if (mc_control == 7)
Platform.RAM.Channels = SMB_MEM_CHANNEL_TRIPLE;
Platform->RAM.Channels = SMB_MEM_CHANNEL_TRIPLE;
else
Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;
Platform->RAM.Channels = SMB_MEM_CHANNEL_DUAL;
}
static struct mem_controller_t dram_controllers[] = {
dram_controllers[i].poll_speed(dram_dev);
verbose("Frequency detected: %d MHz (%d) %s Channel %d-%d-%d-%d\n",