From email@example.com Wed Oct 6 10:56:16 2004 Date: Wed, 6 Oct 2004 06:47:08 +0100 From: Nick Barker To: Ronald G. Minnich Subject: EPIA-M / MII a large patch
As announced on the list, here is my patch for freebios2 - epia-m/mii
The patch contains both bug fixes and new features as follows:
- ACPI power management and interrupt routing - Boot from onboard compact flash - Legacy VGA Bios working - mtrr's set up correctly for VGA - AGP and GART set up correctly - vt1211 h/w monitor, com ports, lpt and fdc enabled - 1/2 speed baud rate problem resolved
Caveat The patch uses the memory setup code ported into C from version 1 for the EPIA-M, but has been adjusted for 256Mb only - i.e. the size that I'm currently using. This code, in northbridge/raminit.c, is an ugly hack to get the system up and booted, and I do not particularly offer it as the 'final solution'. I've always assumed that one day it would be replaced with proper autodetection - a job for someone with access to the appropriate documentation i.e. vt8623 datasheets.
I have tried to restrict any changes to epia-m specific files, however there are a few generic files that I have had to make some changes in, particularly in the ACPI, vga bios and mtrr areas. These changes 'should' be benign to other platforms.
There are other areas which I consider 'hackish', in particular the setting up of the cardbus bridge. This device is ignored altogether by the PCI detection code because it has a header type of PCI to cardbus bridge (type 2 I think). Having failed to understand the intricacies of the pci detection and configuration mechanism, I have resorted to setting up the bridge manually, and with fixed memory resources, as annotated in the code.
The Config.lb provided is set up for filo and legacy vga bios. In other words it makes an image 192K big to which a captured vga bios should be prepended.
The patch is relative to the web based CVS snapshot of 20041004-1100.
ACPI power management and interrupt routing
I have added the code which creates three new ACPI tables, and sets up the southbridge power management unit into ACPI mode.
The new tables are the: Fixed ACPI Description Table (FADT) Firmware ACPI Control Structure (FACS) Differentiated System Description Table (DSDT)
The FADT mostly describes the power management unit, and is declared in fadt.c in the mainboard/via/epia-m directory.
The FACS is intended to provide non volatile memory to the ACPI system for suspend to disk activities. However it is currently implemented as a zeroed table. I have only included it because Linux ACPI complains if there isn't one if a FADT has been provided.
The DSDT describes the interrupt routing and power management capabilities of devices, and is what Linux uses for interrupt routing if it can. The DSDT, defined in mainboard/via/epia-m/dsdt.c is exactly that provided with the original Award bios. It has been created using the following approximate steps:
1) Under Award Bios, 'cat /proc/acpi/dsdt > dsdt' 2) Decompile dsdt with Intel's iasl - 'iasl -d dsdt' 3) Compile to C table with Intel's iasl - 'iasl -tc dsdt.dsl' 4) Copy output to mainboard/via/epia-m/dsdt.c
The award dsdt may carry the same IPR situation as the VGA bios, and it could be that the file dsdt.c should not be distributed with the code. However it is easy enough to create your own using the steps above.
The ACPI code seems to be fully functional - giving software off and reset, as well as providing power button click events (the whole reason I wrote this !!). I assume the ACPI subsystem in Linux is also shifting the processor into S1 and S2 states, and doing other things that ACPI should do, but I haven't confirmed that yet.
Boot from onboard Compact Flash
I have added a new device to the southbridge tree - southbridge/ricoh/rl5c476, which is the setup code for the Ricoh cardbus bridge found on the MII. I wasn't quite sure where to put it in the source tree, but I guessed it was more like a southbridge than anything else.
The code sets up a compact flash in the CF slot as an IDE drive based at address 0x1e8, in other words the standard address for the third IDE controller as used by Filo, Linux, and I guess Etherboot.
The code is a bit clunky in as much as it allocates fixed addresses for memory windows - which ought to be allocated by the pci detection code, but I can't figure out how to make this happen.
Filo detects the CF as drive 'hde' as long as filo has been compiled with SUPPORT_PCI=1 commented out. With SUPPORT_PCI included, filo only searches for PCI devices of the IDE controller type, whereas without it, filo will check its standard addresses for an IDE controller.
You can configure Linux to support the CF in one of two ways, depending upon your needs:
- Standard IDE disk support. Just let the standard IDE detection code in Linux pick up the CF as a standard device. This has the advantage of being quick and easy to get going. However if you then start up pcmcia utils to deal with the pcmcia slot, you will run into difficulties as the pcmcia-utils package resets the CF slot. There might be options you can use to instruct pcmcia-utils to ignore the CF slot entirely, but I haven't found them yet.
- PCMCIA-UTILS support. Firstly you have to tell the standard IDE detection code NOT to look for the third IDE controller, do so with a linux command line option of 'ide2=noprobe'. Next you need to set up an initrd. The pcmcia-utils HOWTO describes how to do this with 'pcinitrd'. In addition you have to add the program 'resetcf' from freebios2/util directory to the initrd, and make sure it is called just before the socket driver is loaded in the linuxrc file. This step is necessary because the yenta socket driver does not correctly clear down the state of the CF socket as left by freebios2 (detail - yenta socket driver never clears the io offset used by freebios2 to make the CF look like /dev/hde - I guess it normally relies on the power on default being zero!!!). My linux command line in filo looks like:
AUTOBOOT_FILE = "hde:/vmlinuz initrd=hde:/initrd.gz root=/dev/hde console=tty0 ide2=noprobe"
Legacy VGA BIOS
I struggled for some time getting the VGA bios to work properly, as others on the mailing list seem to be also. Here is a list of my findings:
Some people are finding that the bios initialisation code is crashing with a random interrupt vector. This always seemed to happen at cs:ip=c000:0188. A look at the actual instruction at that location reveals that it is an STI instruction which enables hardware interrupt processing, not an INTXX instruction. On freebios2, the i8259 interrupt controller is never initialised, so it is understandable that if the vga bios has been playing with interrupts that after the STI intruction a random interupt vector is issued by the i8259 - and hence the problems as reported. My fix is to include the version 1 i8259 initialisation code, and that allows the bios to finish.
The next problem encounterred was that after vga initialisation, the screen didn't come on. After groping around the XFree sources for the CLE266 I discovered a bios call to select which output device(s) to enable, and have added a call to that function to turn on the standard console. Anyone wanting the TV output or LCD panel output are recommended to look at the Xserver sources for that bios call.
The final problem was that the freebios2 code was setting up the video memory window at 0xa0000 - 0xbffff as cacheable in its fixed mtrr code. This was resolved by getting sizeram() in northbridge.c to break the main area of memory into 2 chuncks either side of this window.
MTRR's for VGA
I have added code to create correct mtrr's for the VGA framebuffer and the AGP. This has meant some minor changes in mtrr.c
AGP port and GART
The AGP bridge seems to work correctly after setting it up like award. The GART window is hard coded at address 0xd0000000, as per award, and could/should be set by the pci_device allocation code. Linux AGP support does not crash the system and I believe it to be fully working.
I have created a new superio device for the vt1211, which sets up the hardware monitor, com ports, lpt and fdc. The h/w monitor set up values are taken from v1. None of this has been tested beyond Linux correctly spotting the devices.
1/2 speed baud rate problem
I believe that the 1/2 speed baud rate problem is down to trying to do things before the southbridge and certain clocks have fully settled down. By putting a delay after the rtc_init() and before trying to use the SMB bus, the problem seems to be rectified. The counter in the delay loop could be optimised if anyone out there has the desire - 1000 isn't enough, whilst 5000 is.
As an indicator that the BIOS is going, I've got the power LED to blink rapidly from early on, until the BIOS has just about finished its job. Could be first thing for newcomers to look for when they don't get any other form of output.