Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazi/i386/modules/HPET/HPET.c

1/*
2 * Force HPET enabled, via fix from:
3 *
4 * http://forum.voodooprojects.org/index.php/topic,1596.0.html
5 */
6
7//#include "libsaio.h"
8#include "boot.h"
9#include "pci.h"
10#include "hpet.h"
11#include "modules.h"
12
13/*#ifndef DEBUG_HPET
14#define DEBUG_HPET 0
15#endif
16
17#if DEBUG_HPET
18#define DBG(x...) printf(x)
19#else
20#define DBG(x...)
21#endif
22*/
23
24
25void force_enable_hpet_intel(pci_dt_t *lpc_dev);
26void force_enable_hpet_via(pci_dt_t *lpc_dev);
27
28
29void HPET_hook(void* arg1, void* arg2, void* arg3, void* arg4)
30{
31bool do_enable_hpet = false;
32pci_dt_t* current = arg1;
33
34if (current->class_id != PCI_CLASS_BRIDGE_ISA)
35return;
36
37getBoolForKey(kForceHPETKey, &do_enable_hpet, &bootInfo->bootConfig);
38
39if (do_enable_hpet)
40force_enable_hpet(current);
41}
42
43void HPET_start()
44{
45register_hook_callback("PCIDevice", &HPET_hook);
46}
47
48// Intel chipsets
49static struct lpc_controller_t lpc_controllers_intel[] = {
50
51// Default unknown chipset
52{ 0, 0, "" },
53
54// Intel
55{ 0x8086, 0x24dc, "ICH5" },
56{ 0x8086, 0x2640, "ICH6" },
57{ 0x8086, 0x2641, "ICH6M" },
58
59{ 0x8086, 0x27b0, "ICH7 DH" },
60{ 0x8086, 0x27b8, "ICH7" },
61{ 0x8086, 0x27b9, "ICH7M" },
62{ 0x8086, 0x27bd, "ICH7M DH" },
63
64{ 0x8086, 0x27bc, "NM10" }, // Atom
65
66{ 0x8086, 0x2810, "ICH8R" },
67{ 0x8086, 0x2811, "ICH8M-E" },
68{ 0x8086, 0x2812, "ICH8DH" },
69{ 0x8086, 0x2814, "ICH8DO" },
70{ 0x8086, 0x2815, "ICH8M" },
71
72{ 0x8086, 0x2912, "ICH9DH" },
73{ 0x8086, 0x2914, "ICH9DO" },
74{ 0x8086, 0x2916, "ICH9R" },
75{ 0x8086, 0x2917, "ICH9M-E" },
76{ 0x8086, 0x2918, "ICH9" },
77{ 0x8086, 0x2919, "ICH9M" },
78
79{ 0x8086, 0x3a14, "ICH10DO" },
80{ 0x8086, 0x3a16, "ICH10R" },
81{ 0x8086, 0x3a18, "ICH10" },
82{ 0x8086, 0x3a1a, "ICH10D" },
83};
84
85// VIA chipsets
86static struct lpc_controller_t lpc_controllers_via[] = {
87// Default unknown chipset
88{ 0, 0, "" },
89
90{ 0x1106, 0x3372, "VT8237S" },
91};
92
93void force_enable_hpet(pci_dt_t *lpc_dev)
94{
95switch(lpc_dev->vendor_id)
96{
97case 0x8086:
98force_enable_hpet_intel(lpc_dev);
99break;
100
101case 0x1106:
102force_enable_hpet_via(lpc_dev);
103break;
104}
105
106/*#if DEBUG_HPET
107pause();
108#endif*/
109}
110
111void force_enable_hpet_via(pci_dt_t *lpc_dev)
112{
113int i;
114uint32_t val, hpet_address = 0xFED00000;
115
116for (i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
117{
118if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id)
119&& (lpc_controllers_via[i].device == lpc_dev->device_id))
120{
121val = pci_config_read32(lpc_dev->dev.addr, 0x68);
122
123verbose("VIA %s LPC Interface [%04x:%04x], MMIO\n",
124lpc_controllers_via[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
125
126if (val & 0x80)
127{
128hpet_address = (val & ~0x3ff);
129verbose("HPET at 0x%lx\n", hpet_address);
130}
131else
132{
133val = 0xfed00000 | 0x80;
134
135pci_config_write32(lpc_dev->dev.addr, 0x68, val);
136
137val = pci_config_read32(lpc_dev->dev.addr, 0x68);
138
139if (val & 0x80)
140{
141hpet_address = (val & ~0x3ff);
142verbose("Force enabled HPET at 0x%lx\n", hpet_address);
143}
144else
145{
146verbose("Unable to enable HPET");
147}
148}
149}
150}
151}
152
153void force_enable_hpet_intel(pci_dt_t *lpc_dev)
154{
155inti;
156void *rcba;
157uint32_tval, hpet_address = 0xFED00000;
158
159/* LPC on Intel ICH is always (?) at 00:1f.0 */
160for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
161{
162if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id)
163&& (lpc_controllers_intel[i].device == lpc_dev->device_id))
164{
165rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
166
167verbose("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
168lpc_controllers_intel[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
169
170if (rcba == 0)
171verbose(" RCBA disabled; cannot force enable HPET\n");
172else
173{
174val = REG32(rcba, 0x3404);
175
176if (val & 0x80)
177{
178// HPET is enabled in HPTC. Just not reported by BIOS
179verbose(" HPET is enabled in HPTC, just not reported by BIOS\n");
180hpet_address |= (val & 3) << 12 ;
181verbose(" HPET MMIO @ 0x%lx\n", hpet_address);
182}
183else
184{
185// HPET disabled in HPTC. Trying to enable
186verbose(" HPET is disabled in HPTC, trying to enable\n");
187REG32(rcba, 0x3404) = val | 0x80;
188hpet_address |= (val & 3) << 12 ;
189verbose(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
190}
191
192// verify if the job is done
193val = REG32(rcba, 0x3404);
194
195if (!(val & 0x80))
196verbose(" Failed to force enable HPET\n");
197}
198break;
199}
200}
201}
202

Archive Download this file

Revision: 1047