Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/modules/HPET/HPET.c

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

Archive Download this file

Revision: 1166