Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/libsaio/hpet.c

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

Archive Download this file

Revision: 539