Chameleon

Chameleon Svn Source Tree

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

  • Property svn:executable set to
1/*
2 * Copyright (c) 2009 Evan Lojewski. All rights reserved.
3 */
4
5#include "libsaio.h"
6#include "boot.h"
7#include "bootstruct.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
24/*
25 * Force HPET enabled
26 *
27 * VIA fix from http://forum.voodooprojects.org/index.php/topic,1596.0.html
28 */
29
30static struct lpc_controller_t lpc_controllers_intel[] = {
31
32// Default unknown chipset
33{ 0, 0, "" },
34
35// Intel
36{ 0x8086, 0x24dc, "ICH5" },
37{ 0x8086, 0x2640, "ICH6" },
38{ 0x8086, 0x2641, "ICH6M" },
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};
65
66static struct lpc_controller_t lpc_controllers_via[] = {
67// Default unknown chipset
68{ 0, 0, "" },
69
70{ 0x1106, 0x3372, "VT8237S" },
71};
72
73
74void force_enable_hpet(pci_dt_t *lpc_dev)
75{
76switch(lpc_dev->vendor_id)
77{
78case 0x8086:
79force_enable_hpet_intel(lpc_dev);
80break;
81
82case 0x1106:
83force_enable_hpet_via(lpc_dev);
84break;
85}
86
87
88#if DEBUG_HPET
89printf("Press [Enter] to continue...\n");
90getc();
91#endif
92}
93
94void force_enable_hpet_via(pci_dt_t *lpc_dev)
95{
96uint32_tval, hpet_address = 0xFED00000;
97int i;
98
99for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
100{
101if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id)
102&& (lpc_controllers_via[i].device == lpc_dev->device_id))
103{
104val = pci_config_read32(lpc_dev->dev.addr, 0x68);
105
106DBG("VIA %s LPC Interface [%04x:%04x], MMIO\n",
107lpc_controllers_via[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
108
109if (val & 0x80) {
110hpet_address = (val & ~0x3ff);
111DBG("HPET at 0x%lx\n", hpet_address);
112}
113else
114{
115val = 0xfed00000 | 0x80;
116pci_config_write32(lpc_dev->dev.addr, 0x68, val);
117val = pci_config_read32(lpc_dev->dev.addr, 0x68);
118if (val & 0x80) {
119hpet_address = (val & ~0x3ff);
120DBG("Force enabled HPET at 0x%lx\n", hpet_address);
121}
122else {
123DBG("Unable to enable HPET");
124}
125}
126}
127}
128}
129
130
131
132void force_enable_hpet_intel(pci_dt_t *lpc_dev)
133{
134uint32_tval, hpet_address = 0xFED00000;
135int i;
136void*rcba;
137
138/* LPC on Intel ICH is always (?) at 00:1f.0 */
139for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
140{
141if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id)
142&& (lpc_controllers_intel[i].device == lpc_dev->device_id))
143{
144
145rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
146
147DBG("Intel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
148lpc_controllers_intel[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
149
150if (rcba == 0)
151printf(" RCBA disabled; cannot force enable HPET\n");
152else
153{
154val = REG32(rcba, 0x3404);
155if (val & 0x80)
156{
157// HPET is enabled in HPTC. Just not reported by BIOS
158DBG(" HPET is enabled in HPTC, just not reported by BIOS\n");
159hpet_address |= (val & 3) << 12 ;
160DBG(" HPET MMIO @ 0x%lx\n", hpet_address);
161}
162else
163{
164// HPET disabled in HPTC. Trying to enable
165DBG(" HPET is disabled in HPTC, trying to enable\n");
166REG32(rcba, 0x3404) = val | 0x80;
167hpet_address |= (val & 3) << 12 ;
168DBG(" Force enabled HPET, MMIO @ 0x%lx\n", hpet_address);
169}
170
171// verify if the job is done
172val = REG32(rcba, 0x3404);
173if (!(val & 0x80))
174printf(" Failed to force enable HPET\n");
175}
176break;
177}
178}
179}
180

Archive Download this file

Revision: 709