Chameleon

Chameleon Commit Details

Date:2010-05-10 02:51:13 (13 years 11 months ago)
Author:Evan Lojewski
Commit:150
Parents: 149
Message:USBLecayOff patch. Runs immediately before kernel is started / after last file is loaded
Changes:
M/branches/meklort/i386/libsaio/dsdt_patcher.c
M/branches/meklort/i386/libsaio/edid.c
M/branches/meklort/i386/boot2/boot.c
M/branches/meklort/i386/libsaio/usb.c
M/branches/meklort/i386/boot2/boot.h
M/branches/meklort/i386/libsaio/pci_setup.c
M/branches/meklort/CHANGES

File differences

branches/meklort/CHANGES
1
2
13
24
35
- Added USB Legacy Off patch. Modified to run immediately *before* the kernel is executed, that
way no files need to be loaded after the usb device is reset.
- Backup original dsdt to /dsdt/originaldsdt in the IORegistery
- Added kernel patcher, removes the CPUID check panic in the kernel. Forces _cpuid_set_info to
return Penryn / cpuid model 23
branches/meklort/i386/libsaio/usb.c
2222
2323
2424
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
25187
26188
27189
#define DBG(x...)
#endif
#define MAX_USB_DEVS 9
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);
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;
}
}
int usb_loop()
{
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) {
fix_ehci = fix_uhci = fix_legacy = true;
} 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)
{
uhci_reset(current->pciDev);
legacy_off(current->pciDev);
ehci_acquire(current->pciDev);
current = current->next;
}
return 1;
}
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 calles
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;
branches/meklort/i386/libsaio/dsdt_patcher.c
260260
261261
262262
263
263
264264
265265
266266
struct acpi_2_dsdt *dsdt;
dsdt = (struct acpi_2_dsdt*) (fadt_mod->DSDT);
DT__AddProperty(node, "originaldsdt", (dsdt->Length + sizeof(struct acpi_2_dsdt) - 1), (void*)dsdt);/// Inset old dsdt. Length is header length (36) + dsdt length
DT__AddProperty(node, "originaldsdt", (dsdt->Length + sizeof(struct acpi_2_dsdt) - 1), (void*)dsdt);/// Insert old dsdt. Length is header length (36) + dsdt length
}
branches/meklort/i386/libsaio/pci_setup.c
66
77
88
9
10
9
10
11
1112
1213
1314
1415
1516
16
17
1718
1819
19
20
2021
2122
2223
23
24
25
26
27
28
2924
3025
3126
......
6257
6358
6459
60
61
6562
6663
67
64
6865
6966
7067
7168
7269
73
70
7471
7572
7673
7774
7875
76
7977
8078
8179
#include "ati.h"
extern void set_eth_builtin(pci_dt_t *eth_dev);
extern int ehci_acquire(pci_dt_t *pci_dev);
extern int uhci_reset(pci_dt_t *pci_dev);
//extern int ehci_acquire(pci_dt_t *pci_dev);
//extern int uhci_reset(pci_dt_t *pci_dev);
extern void notify_usb_dev(pci_dt_t *pci_dev);
extern void force_enable_hpet(pci_dt_t *lpc_dev);
void setup_pci_devs(pci_dt_t *pci_dt)
{
char *devicepath;
bool do_eth_devprop, do_gfx_devprop, fix_ehci, fix_uhci, fix_usb, do_enable_hpet;
bool do_eth_devprop, do_gfx_devprop, do_enable_hpet;
pci_dt_t *current = pci_dt;
do_eth_devprop = do_gfx_devprop = fix_ehci = fix_uhci = fix_usb = do_enable_hpet = false;
do_eth_devprop = do_gfx_devprop = do_enable_hpet = false;
getBoolForKey(kEthernetBuiltIn, &do_eth_devprop, &bootInfo->bootConfig);
getBoolForKey(kGraphicsEnabler, &do_gfx_devprop, &bootInfo->bootConfig);
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig) && fix_usb) {
fix_ehci = fix_uhci = true;
} else {
getBoolForKey(kEHCIacquire, &fix_ehci, &bootInfo->bootConfig);
getBoolForKey(kUHCIreset, &fix_uhci, &bootInfo->bootConfig);
}
getBoolForKey(kForceHPET, &do_enable_hpet, &bootInfo->bootConfig);
while (current)
break;
case PCI_CLASS_SERIAL_USB:
notify_usb_dev(current);
/*
switch (pci_config_read8(current->dev.addr, PCI_CLASS_PROG))
{
/* EHCI */
// EHCI
case 0x20:
if (fix_ehci)
ehci_acquire(current);
break;
/* UHCI */
// UHCI
case 0x00:
if (fix_uhci)
uhci_reset(current);
break;
}
*/
break;
case PCI_CLASS_BRIDGE_ISA:
branches/meklort/i386/libsaio/edid.c
4646
4747
4848
49
50
51
5249
5350
5451
//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );
//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );
free( edidInfo );
if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;
branches/meklort/i386/boot2/boot.c
8686
8787
8888
89
8990
9091
9192
......
192193
193194
194195
196
195197
196198
197199
static bool gUnloadPXEOnExit = false;
extern int usb_loop();
/*
* How long to wait (in seconds) to load the
* kernel after displaying the "boot:" prompt.
finalizeBootStruct();
usb_loop();
// Jump to kernel's entry point. There's no going back now.
startprog( kernelEntry, bootArgs );
branches/meklort/i386/boot2/boot.h
7878
7979
8080
81
82
81
82
83
8384
8485
8586
#define kGraphicsEnabler"GraphicsEnabler"/* pci_setup.c */
#define kUSBBusFix"USBBusFix"/* pci_setup.c */
#define kEHCIacquire"EHCIacquire"/* pci_setup.c */
#define kUHCIreset"UHCIreset"/* pci_setup.c */
#define kForceHPET"ForceHPET"/* pci_setup.c */
#define kUHCIreset"UHCIreset"/* usb.c */
#define kForceHPET"ForceHPET"/* usb.c */
#define kLegacyOff"USBLegacyOff"/* usb.c */
#define kSMBIOSdefaults"SMBIOSdefaults"/* smbios_patcher.c */
#define kEHCIhard"EHCIhard"/* usb.c */
#define kDefaultPartition"Default Partition"/* sys.c */

Archive Download the corresponding diff file

Revision: 150