Skip to content

Commit afa9fc2

Browse files
committed
Add 8254CGE workaround
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
1 parent af17a97 commit afa9fc2

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

src/csmwrap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
130130
return -1;
131131
}
132132

133+
apply_intel_platform_workarounds();
134+
133135
csm_bin_base = (uintptr_t)BIOSROM_END - sizeof(Csm16_bin);
134136
priv.csm_bin_base = csm_bin_base;
135137
printf("csm_bin_base: 0x%lx\n", csm_bin_base);

src/csmwrap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern EFI_STATUS csmwrap_video_init(struct csmwrap_priv *priv);
3333
extern int build_coreboot_table(struct csmwrap_priv *priv);
3434
extern int copy_rsdt(struct csmwrap_priv *priv);
3535
int build_e820_map(struct csmwrap_priv *priv);
36+
int apply_intel_platform_workarounds(void);
3637

3738

3839
static inline int

src/intel_workarounds.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include <efi.h>
2+
#include "csmwrap.h"
3+
4+
#include "io.h"
5+
6+
#define PCI_DEVICE_NUMBER_PCH_P2SB 31
7+
#define PCI_FUNCTION_NUMBER_PCH_P2SB 1
8+
9+
#define SBREG_BAR 0x10
10+
#define SBREG_BARH 0x14
11+
12+
#define PID_ITSS 0xC4
13+
14+
#define R_PCH_PCR_ITSS_ITSSPRC 0x3300 ///< ITSS Power Reduction Control
15+
#define B_PCH_PCR_ITSS_ITSSPRC_PGCBDCGE (1 << 4) ///< PGCB Dynamic Clock Gating Enable
16+
#define B_PCH_PCR_ITSS_ITSSPRC_HPETDCGE (1 << 3) ///< HPET Dynamic Clock Gating Enable
17+
#define B_PCH_PCR_ITSS_ITSSPRC_8254CGE (1 << 2) ///< 8254 Static Clock Gating Enable
18+
#define B_PCH_PCR_ITSS_ITSSPRC_IOSFICGE (1 << 1) ///< IOSF-Sideband Interface Clock Gating Enable
19+
#define B_PCH_PCR_ITSS_ITSSPRC_ITSSCGE (1 << 0) ///< ITSS Clock Gate Enable
20+
21+
#define PCH_PCR_ADDRESS(Base, Pid, Offset) ((void *)(Base | (UINT32) (((Offset) & 0x0F0000) << 8) | ((UINT8)(Pid) << 16) | (UINT16) ((Offset) & 0xFFFF)))
22+
23+
#define PORT_PIT_COUNTER0 0x0040
24+
#define PORT_PIT_COUNTER1 0x0041
25+
#define PORT_PIT_COUNTER2 0x0042
26+
#define PORT_PIT_MODE 0x0043
27+
#define PORT_PS2_CTRLB 0x0061
28+
29+
// Bits for PORT_PIT_MODE
30+
#define PM_SEL_TIMER0 (0<<6)
31+
#define PM_SEL_TIMER1 (1<<6)
32+
#define PM_SEL_TIMER2 (2<<6)
33+
#define PM_SEL_READBACK (3<<6)
34+
#define PM_ACCESS_LATCH (0<<4)
35+
#define PM_ACCESS_LOBYTE (1<<4)
36+
#define PM_ACCESS_HIBYTE (2<<4)
37+
#define PM_ACCESS_WORD (3<<4)
38+
#define PM_MODE0 (0<<1)
39+
#define PM_MODE1 (1<<1)
40+
#define PM_MODE2 (2<<1)
41+
#define PM_MODE3 (3<<1)
42+
#define PM_MODE4 (4<<1)
43+
#define PM_MODE5 (5<<1)
44+
#define PM_CNT_BINARY (0<<0)
45+
#define PM_CNT_BCD (1<<0)
46+
#define PM_READ_COUNTER0 (1<<1)
47+
#define PM_READ_COUNTER1 (1<<2)
48+
#define PM_READ_COUNTER2 (1<<3)
49+
#define PM_READ_STATUSVALUE (0<<4)
50+
#define PM_READ_VALUE (1<<4)
51+
#define PM_READ_STATUS (2<<4)
52+
53+
static int pit_8254cge_workaround(void)
54+
{
55+
uint32_t reg;
56+
uint64_t base;
57+
58+
reg = pciConfigReadDWord(0, PCI_DEVICE_NUMBER_PCH_P2SB,
59+
PCI_FUNCTION_NUMBER_PCH_P2SB,
60+
0x0);
61+
62+
if ((reg & 0xFFFF) != 0x8086) {
63+
printf("No P2SB found, proceed to PIT test\n");
64+
goto test_pit;
65+
}
66+
67+
reg = pciConfigReadDWord(0, PCI_DEVICE_NUMBER_PCH_P2SB,
68+
PCI_FUNCTION_NUMBER_PCH_P2SB,
69+
SBREG_BAR);
70+
base = reg & ~0x0F;
71+
72+
reg = pciConfigReadDWord(0, PCI_DEVICE_NUMBER_PCH_P2SB,
73+
PCI_FUNCTION_NUMBER_PCH_P2SB,
74+
SBREG_BARH);
75+
base |= ((uint64_t)reg & 0xFFFFFFFF) << 32;
76+
77+
/* FIXME: Validate base */
78+
reg = readl(PCH_PCR_ADDRESS(base, PID_ITSS, R_PCH_PCR_ITSS_ITSSPRC));
79+
printf("ITSSPRC = %x, ITSSPRC.8254CGE= %x\n", reg, !!(reg & B_PCH_PCR_ITSS_ITSSPRC_8254CGE));
80+
/* Disable 8254CGE */
81+
reg &= ~B_PCH_PCR_ITSS_ITSSPRC_8254CGE;
82+
writel(PCH_PCR_ADDRESS(base, PID_ITSS, R_PCH_PCR_ITSS_ITSSPRC), reg);
83+
84+
test_pit:
85+
/* Lets hope we will not BOOM UEFI with this */
86+
outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE);
87+
uint16_t v1 = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8);
88+
89+
gBS->Stall(1000);
90+
outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE);
91+
uint16_t v2 = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8);
92+
if (v1 == v2) {
93+
printf("PIT test failed, not counting!\n");
94+
return -1;
95+
}
96+
97+
return 0;
98+
}
99+
100+
int apply_intel_platform_workarounds(void)
101+
{
102+
uint16_t device_id, vendor_id;
103+
104+
device_id = pciConfigReadWord(0, 0, 0, 0x2);
105+
vendor_id = pciConfigReadWord(0, 0, 0, 0x0);
106+
107+
if (vendor_id != 0x8086) {
108+
return 0;
109+
}
110+
111+
pit_8254cge_workaround();
112+
113+
return 0;
114+
}

src/io.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,40 @@
44
#include <efi.h>
55
#include <printf.h>
66

7+
#define barrier() __asm__ __volatile__("": : :"memory")
8+
9+
static inline void writel(void *addr, uint32_t val) {
10+
barrier();
11+
*(volatile uint32_t *)addr = val;
12+
}
13+
static inline void writew(void *addr, uint16_t val) {
14+
barrier();
15+
*(volatile uint16_t *)addr = val;
16+
}
17+
static inline void writeb(void *addr, uint8_t val) {
18+
barrier();
19+
*(volatile uint8_t *)addr = val;
20+
}
21+
static inline uint64_t readq(const void *addr) {
22+
uint64_t val = *(volatile const uint64_t *)addr;
23+
barrier();
24+
return val;
25+
}
26+
static inline uint32_t readl(const void *addr) {
27+
uint32_t val = *(volatile const uint32_t *)addr;
28+
barrier();
29+
return val;
30+
}
31+
static inline uint16_t readw(const void *addr) {
32+
uint16_t val = *(volatile const uint16_t *)addr;
33+
barrier();
34+
return val;
35+
}
36+
static inline uint8_t readb(const void *addr) {
37+
uint8_t val = *(volatile const uint8_t *)addr;
38+
barrier();
39+
return val;
40+
}
741

842
#ifdef __OPTIMIZE__
943

0 commit comments

Comments
 (0)