Skip to content

Commit 909f30b

Browse files
committed
_drafts added for WIP stuff
1 parent e86b4dd commit 909f30b

File tree

4 files changed

+780
-0
lines changed

4 files changed

+780
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
layout: post
3+
title: "Resolving AGP Initialization Lockups on the Intel 440LX"
4+
date: 2025-08-04 15:00:00 +0200
5+
toc: true
6+
toc_label: "440LX AGP Issues"
7+
excerpt: "A deep dive into the chipset errata and register-level pitfalls that cause system hangs when enabling AGP in coreboot on the 440LX, and a robust software solution."
8+
header:
9+
teaser:
10+
categories:
11+
- Firmware
12+
- Hardware
13+
- Retro Computing
14+
tags:
15+
- coreboot
16+
- firmware
17+
- retro
18+
- i440lx
19+
- agp
20+
- bugfix
21+
---
22+
23+
## 440LX, Intel's First Go at AGP
24+
25+
There's a special kind of satisfaction in bringing modern, open-source firmware to a piece of vintage hardware. After getting coreboot running smoothly on the [MSI MS-6117](https://theretroweb.com/motherboards/s/msi-ms-6117-lx6) motherboard, I was feeling pretty good.
26+
27+
The final boss was in sight: enabling the Accelerated Graphics Port (AGP). I flipped the config switch, rebuilt, and... nothing. A hard lockup during the PCI scan.
28+
29+
The most baffling part? It hung even with no AGP card in the slot. This wasn't a fussy graphics card. This was the chipset itself throwing a tantrum.
30+
31+
This is the story of taming the Intel [440LX](https://theretroweb.com/chipsets/282)-Intel's first stab at AGP, and a masterclass in quirky hardware design.
32+
33+
---
34+
35+
## The First Clue: A Chipset with a Split Personality
36+
37+
My first assumption was a simple bug in my code, but the “no card” hang pointed to something deeper. It turns out the 440LX isn't a single northbridge in the way you'd expect. Instead, Intel designed it as two logical devices on the PCI bus:
38+
39+
- **Device 0 (ID 7180h):** Host Bridge - manages DRAM controller and AGP registers.
40+
- **Device 1 (ID 7181h):** Virtual PCI-to-PCI Bridge - exposes AGP as a secondary PCI bus.
41+
42+
This meant that the AGP engine on Device 0 wouldn’t function correctly unless Device 1 was properly initialized. My code was talking to the AGP registers before their parent bus existed.
43+
44+
---
45+
46+
## Datasheet Archaeology: Unearthing Ancient Bugs
47+
48+
The next stop was Intel’s specification updates. Buried within:
49+
50+
> **VGA Hang Erratum**: If a PCI device tries to access the legacy VGA memory range (0xA0000–0xBFFFF) while the VGA card is on AGP, the chipset locks up *completely*.
51+
> There is no hardware fix-only a strict software sequence can avoid it.
52+
53+
That explained the lockup with *no card inserted*. The firmware was forwarding VGA cycles to an empty AGP bus, resulting in deadlock.
54+
55+
---
56+
57+
## The Rules of Engagement
58+
59+
Key takeaways from the errata and datasheets:
60+
61+
- **Order matters**: Write `APSIZE` before `APBASE`. Get it wrong, and `APBASE` is undefined.
62+
- **Don’t enable the AGP aperture in firmware**: Let the OS driver handle that.
63+
- **Don’t confuse 440LX with 440BX**: 440LX architecturely is more akin to Intel's 430TX chipset with AGP and a new host bus slapped on.
64+
65+
---
66+
67+
## The Fix: A Two-Part Incantation
68+
69+
### Phase 1: Before PCI Enumeration
70+
71+
Set up the aperture carefully while leaving it disabled. This prevents undefined states and the VGA hang.
72+
73+
```c
74+
/**
75+
* @brief Initialize the AGP aperture early in ramstage.
76+
*/
77+
void i440lx_agp_aperture_init(struct device *dev)
78+
{
79+
uint32_t tolm, aperture_base;
80+
uint16_t paccfg;
81+
const uint32_t aperture_size = 64 * 1024 * 1024; /* 64 MB */
82+
83+
printk(BIOS_INFO, "440LX: Initializing AGP Aperture...\n");
84+
85+
/* Set a sane aperture size */
86+
pci_write_config8(dev, APSIZE, 0x30); /* 64MB */
87+
88+
/* Set base address above system RAM */
89+
tolm = find_pci_tolm(dev->bus);
90+
aperture_base = (tolm + (aperture_size - 1)) & ~(aperture_size - 1);
91+
pci_write_config32(dev, APBASE, aperture_base);
92+
93+
/* Configure PACCFG for VGA hang workaround */
94+
paccfg = pci_read_config16(dev, PACCFG);
95+
paccfg |= PACCFG_PCI_APER_DIS;
96+
paccfg &= ~PACCFG_GBL_APER_EN;
97+
paccfg &= ~PACCFG_MDA_PRESENT;
98+
pci_write_config16(dev, PACCFG, paccfg);
99+
}
100+
````
101+
102+
---
103+
104+
### Phase 2: After PCI Scan
105+
106+
Enable AGP protocol only if a VGA card is actually detected.
107+
108+
```c
109+
/**
110+
* @brief Finalize AGP configuration after PCI enumeration.
111+
*/
112+
void i440lx_agp_enable_devices(void)
113+
{
114+
struct device *host_bridge, *agp_bridge, *agp_dev;
115+
uint16_t bctrl;
116+
uint32_t agpcmd;
117+
118+
host_bridge = dev_find_slot(0, PCI_DEVFN(0, 0));
119+
agp_bridge = dev_find_slot(0, PCI_DEVFN(0, 1));
120+
agp_dev = dev_find_slot(1, PCI_DEVFN(0, 0));
121+
122+
if (!agp_dev || !agp_dev->enabled) {
123+
printk(BIOS_INFO, "440LX: No AGP device found. Keeping AGP disabled.\n");
124+
bctrl = pci_read_config16(agp_bridge, BCTRL);
125+
bctrl &= ~BCTRL_VGA_EN;
126+
pci_write_config16(agp_bridge, BCTRL, bctrl);
127+
return;
128+
}
129+
130+
/* Enable VGA forwarding if needed */
131+
if (pci_read_class(agp_dev) == PCI_CLASS_DISPLAY_VGA) {
132+
printk(BIOS_INFO, "440LX: Enabling VGA forwarding for AGP device.\n");
133+
bctrl = pci_read_config16(agp_bridge, BCTRL);
134+
bctrl |= BCTRL_VGA_EN;
135+
pci_write_config16(agp_bridge, BCTRL, bctrl);
136+
}
137+
138+
/* Enable AGP 2x mode */
139+
agpcmd = AGPCMD_AGP_EN | AGPCMD_RATE_2X;
140+
printk(BIOS_INFO, "440LX: Enabling AGP 2x mode.\n");
141+
142+
pci_write_config32(host_bridge, AGPCMD, agpcmd);
143+
pci_write_config32(agp_dev, agp_dev->cap_ptr + 4, agpcmd);
144+
}
145+
```
146+
---

0 commit comments

Comments
 (0)