Chameleon

Chameleon Svn Source Tree

Root/branches/ErmaC/Enoch_Modules/i386/libsaio/hpet.c

1/*
2 * Copyright (c) 2009 Evan Lojewski. All rights reserved.
3 */
4
5#include "libsaio.h"
6#include "pci.h"
7#include "hpet.h"
8
9#ifndef DEBUG_HPET
10#define DEBUG_HPET 0
11#endif
12
13#if DEBUG_HPET
14#define DBG(x...) printf(x)
15#else
16#define DBG(x...)
17#endif
18
19void force_enable_hpet_intel(pci_dt_t *lpc_dev);
20void force_enable_hpet_nvidia(pci_dt_t *lpc_dev);
21void force_enable_hpet_via(pci_dt_t *lpc_dev);
22
23/*
24 * Force HPET enabled
25 *
26 * VIA fix from http://forum.voodooprojects.org/index.php/topic,1596.0.html
27 */
28
29static struct lpc_controller_t lpc_controllers_intel[] = {
30
31// Default unknown chipset
32{ 0, 0, "" },
33
34// Intel
35{ 0x8086, 0x24dc, "ICH5" },
36{ 0x8086, 0x2640, "ICH6" },
37{ 0x8086, 0x2641, "ICH6M" },
38{ 0x8086, 0x2670, "631xESB" },
39
40{ 0x8086, 0x27b0, "ICH7 DH" },
41{ 0x8086, 0x27b8, "ICH7" },
42{ 0x8086, 0x27b9, "ICH7M" },
43{ 0x8086, 0x27bd, "ICH7M DH" },
44
45{ 0x8086, 0x27bc, "NM10" },
46
47{ 0x8086, 0x2810, "ICH8R" },
48{ 0x8086, 0x2811, "ICH8M-E" },
49{ 0x8086, 0x2812, "ICH8DH" },
50{ 0x8086, 0x2814, "ICH8DO" },
51{ 0x8086, 0x2815, "ICH8M" },
52
53{ 0x8086, 0x2912, "ICH9DH" },
54{ 0x8086, 0x2914, "ICH9DO" },
55{ 0x8086, 0x2916, "ICH9R" },
56{ 0x8086, 0x2917, "ICH9M-E" },
57{ 0x8086, 0x2918, "ICH9" },
58{ 0x8086, 0x2919, "ICH9M" },
59
60{ 0x8086, 0x3a14, "ICH10DO" },
61{ 0x8086, 0x3a16, "ICH10R" },
62{ 0x8086, 0x3a18, "ICH10" },
63{ 0x8086, 0x3a1a, "ICH10D" },
64{ 0x8086, 0x3b00, "5 Series" },
65 { 0x8086, 0x3b01, "Mobile 5 Series" },
66{ 0x8086, 0x3b02, "5 Series" },
67{ 0x8086, 0x3b09, "Mobile 5 Series" },
68
69{ 0x8086, 0x1c42, "6 Series" },
70{ 0x8086, 0x1c44, "Z68" },
71{ 0x8086, 0x1c4c, "Q65" },
72{ 0x8086, 0x1c4e, "Q67" },
73{ 0x8086, 0x1c50, "B65" },
74{ 0x8086, 0x1c4a, "H67" },
75{ 0x8086, 0x1c46, "UM67" },
76{ 0x8086, 0x1c5c, "H61" },
77{ 0x8086, 0x1c52, "C202" },
78{ 0x8086, 0x1c54, "C204" },
79{ 0x8086, 0x1c56, "C206" },
80{ 0x8086, 0x1c43, "Mobile 6 Series" },
81{ 0x8086, 0x1c4f, "QM67" },
82{ 0x8086, 0x1c47, "UM67" },
83{ 0x8086, 0x1c4b, "HM67" },
84{ 0x8086, 0x1c49, "HM65" },
85{ 0x8086, 0x1c41, "Mobile SFF 6 Series" },
86{ 0x8086, 0x1c4d, "QS67" },
87
88};
89
90static struct lpc_controller_t lpc_controllers_nvidia[] = {
91
92// Default unknown chipset
93{ 0, 0, "" },
94
95// nVidia
96{ 0x10de, 0x0aac, "MCP79" },
97{ 0x10de, 0x0aae, "MCP79" },
98{ 0x10de, 0x0aaf, "MCP79" },
99{ 0x10de, 0x0d80, "MCP89" },
100{ 0x10de, 0x0d81, "MCP89" },
101{ 0x10de, 0x0d82, "MCP89" },
102{ 0x10de, 0x0d83, "MCP89" },
103
104};
105
106static struct lpc_controller_t lpc_controllers_via[] = {
107// Default unknown chipset
108{ 0, 0, "" },
109
110{ 0x1106, 0x3372, "VT8237S" },
111};
112
113
114void force_enable_hpet(pci_dt_t *lpc_dev)
115{
116switch(lpc_dev->vendor_id)
117{
118case 0x8086:
119force_enable_hpet_intel(lpc_dev);
120break;
121
122case 0x10de:
123force_enable_hpet_nvidia(lpc_dev);
124break;
125
126case 0x1106:
127force_enable_hpet_via(lpc_dev);
128break;
129}
130
131#if DEBUG_HPET
132printf("Press [Enter] to continue...\n");
133getchar();
134#endif
135
136}
137
138/* ErmaC add lpc fpr nVidia */
139void force_enable_hpet_nvidia(pci_dt_t *lpc_dev)
140{
141uint32_tval, hpet_address = 0xFED00000;
142int i;
143void*rcba;
144
145for(i = 1; i < sizeof(lpc_controllers_nvidia) / sizeof(lpc_controllers_nvidia[0]); i++)
146{
147if ((lpc_controllers_nvidia[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_nvidia[i].device == lpc_dev->device_id))
148{
149
150rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
151
152DBG("nVidia(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
153lpc_controllers_nvidia[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
154
155if (rcba == 0)
156{
157printf(" RCBA disabled; cannot force enable HPET\n");
158}
159else
160{
161val = REG32(rcba, 0x3404);
162if (val & 0x80)
163{
164// HPET is enabled in HPTC. Just not reported by BIOS
165DBG(" HPET is enabled in HPTC, just not reported by BIOS\n");
166hpet_address |= (val & 3) << 12 ;
167DBG(" HPET MMIO @ 0x%lx\n", hpet_address);
168}
169else
170{
171// HPET disabled in HPTC. Trying to enable
172DBG(" HPET is disabled in HPTC, trying to enable\n");
173REG32(rcba, 0x3404) = val | 0x80;
174hpet_address |= (val & 3) << 12 ;
175DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
176}
177
178// verify if the job is done
179val = REG32(rcba, 0x3404);
180if (!(val & 0x80))
181{
182printf(" Failed to force enable HPET\n");
183}
184}
185break;
186}
187}
188}
189
190void force_enable_hpet_via(pci_dt_t *lpc_dev)
191{
192uint32_tval, hpet_address = 0xFED00000;
193int i;
194
195for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
196{
197if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_via[i].device == lpc_dev->device_id))
198{
199val = pci_config_read32(lpc_dev->dev.addr, 0x68);
200
201DBG("VIA %s LPC Interface [%04x:%04x], MMIO\n",
202lpc_controllers_via[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
203
204if (val & 0x80)
205{
206hpet_address = (val & ~0x3ff);
207DBG("HPET at 0x%lx\n", hpet_address);
208}
209else
210{
211val = 0xfed00000 | 0x80;
212pci_config_write32(lpc_dev->dev.addr, 0x68, val);
213val = pci_config_read32(lpc_dev->dev.addr, 0x68);
214if (val & 0x80)
215{
216hpet_address = (val & ~0x3ff);
217DBG("Force enabled HPET at 0x%lx\n", hpet_address);
218}
219else
220{
221DBG("Unable to enable HPET");
222}
223}
224}
225}
226}
227
228void force_enable_hpet_intel(pci_dt_t *lpc_dev)
229{
230uint32_tval, hpet_address = 0xFED00000;
231int i;
232void*rcba;
233
234/* LPC on Intel ICH is always (?) at 00:1f.0 */
235for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
236{
237if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_intel[i].device == lpc_dev->device_id))
238{
239
240rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
241
242DBG("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
243lpc_controllers_intel[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
244
245if (rcba == 0)
246{
247printf(" RCBA disabled; cannot force enable HPET\n");
248}
249else
250{
251val = REG32(rcba, 0x3404);
252if (val & 0x80)
253{
254// HPET is enabled in HPTC. Just not reported by BIOS
255DBG(" HPET is enabled in HPTC, just not reported by BIOS\n");
256hpet_address |= (val & 3) << 12 ;
257DBG(" HPET MMIO @ 0x%lx\n", hpet_address);
258}
259else
260{
261// HPET disabled in HPTC. Trying to enable
262DBG(" HPET is disabled in HPTC, trying to enable\n");
263REG32(rcba, 0x3404) = val | 0x80;
264hpet_address |= (val & 3) << 12 ;
265DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
266}
267
268// verify if the job is done
269val = REG32(rcba, 0x3404);
270if (!(val & 0x80))
271{
272printf(" Failed to force enable HPET\n");
273}
274}
275break;
276}
277}
278}
279
280

Archive Download this file

Revision: 2238