Hiya again. I've gotten the CompuLab CM-iVCF board (Was: VIA EDEN ESP (C3) + Apollo CLE266(VT8623) + VT8237R + W83627HG) getting to start booting Windows XP (There was data at the address the northbridge code looks for SPD, but closer inspection revealed it was neither SPD nor EDID. I hard-coded the memory initialization, this also solved problem with the romcc compiled code not fitting into the bootblock). Unfortunately, now I can't seem to get the VGA-BIOS/northbridge VGA adapter working. Biggest problem seems to be that the Unichrome device is on second PCI bus, and I can't find any documentation or example on how to configure CoreBoot to probe and activate devices on other buses. In lspci this shows up as device 01:00.0, but the devicemap parser doesn't accept the bus number. I have tried to place it hierachically under AGP Bridge on the first bus, but CoreBoot still parses it as 00:00.0 and doesn't find the correct device. So how do I define a device on second PCI bus for CoreBoot? I am also looking at the vgabios.c code in epia-m board, but notice that it has been disabled (ie. the device initialization functions no longer called). Is there some reason for this? The Wiki still talks about concatenating the VGA BIOS to the image, although the current way seems to be to include it in CBFS. Is there anywhere I can find more information about the best/preferred way to integrate VGA BIOS into CoreBoot?
Andrej Skirn wrote:
So how do I define a device on second PCI bus for CoreBoot?
It should be discovered automatically.
The Wiki still talks about concatenating the VGA BIOS to the image, although the current way seems to be to include it in CBFS.
Indeed so.
Are you using Kconfig or the old method with buildtarget?
With Kconfig the way to do it is to select if and how to run the VGA BIOS (which x86 emulator to use, or if to run in real mode) and provide the filename.
Is there anywhere I can find more information about the best/preferred way to integrate VGA BIOS into CoreBoot?
Not all VGA BIOSes work when run by coreboot, so sometimes it's neccessary to use SeaBIOS as payload and let it run the VGA BIOS.
//Peter
Peter Stuge wrote:
Andrej Skirn wrote:
So how do I define a device on second PCI bus for CoreBoot?
It should be discovered automatically.
Thanks for the reply. I'm probably missing something really elementary, but still can't get CoreBoot to locate and enable the video device. Even considered trying to run the VGA BIOS cold without enabling the device in vain hope it would know how to enable it, but calling cbfs_and_run_core() from hardwaremain requires at the least more build script wizardry than I can yet figure out. Here's some details in case somebody can offer leads on what's wrong. The CLE266 datasheet appears to be currently available at http://www.datasheetarchive.com/CLE266-datasheet.html in case anybody's interested, though I'd expect the problem to be more with standard PCI setup. It's basically using EPIA-M code from the svn head for all of this Northbridge related code.
I've set up the relation in devicetree with: device pci 1.0 on # AGP device pci 0.0 on end # VGA end In practice this does nothing, of course, but does let me see bit more debug output about what goes wrong (I have cut out repetitive "bad id" rows):
scan_static_bus for Root Device In vt8623 enable_dev for device APIC_CLUSTER: 0. APIC_CLUSTER: 0 enabled In vt8623 enable_dev for device PCI_DOMAIN: 0000. Finding PCI configuration type. PCI: Using configuration type 1 POST: 0x5f PCI_DOMAIN: 0000 enabled PCI_DOMAIN: 0000 scanning... PCI: pci_scan_bus for bus 00 POST: 0x24 malloc Enter, size 1092, free_mem_ptr 00030000 malloc 00030000 PCI: 00:00.0 [1106/3123] ops PCI: 00:00.0 [1106/3123] enabled In vt8623 enable_dev for device PCI: 00:01.0. PCI: 00:01.0 [1106/b091] bus ops PCI: 00:01.0 [1106/b091] enabled PCI: 00:02.0, bad id 0xffffffff ... PCI: 00:0e.0, bad id 0xffffffff PCI: 00:0f.0 [1106/3149] ops PCI: 00:0f.0 [1106/3149] enabled PCI: 00:0f.1 [1106/0571] ops PCI: 00:0f.1 [1106/0571] enabled PCI: 00:0f.2, bad id 0xffffffff ... PCI: 00:0f.7, bad id 0xffffffff PCI: 00:10.0 [1106/3038] ops PCI: 00:10.0 [1106/3038] enabled PCI: 00:10.1 [1106/3038] ops PCI: 00:10.1 [1106/3038] enabled PCI: 00:10.2 [1106/3038] ops PCI: 00:10.2 [1106/3038] enabled PCI: 00:10.3 [1106/3038] ops PCI: 00:10.3 [1106/3038] enabled PCI: 00:10.4 [1106/3104] ops PCI: 00:10.4 [1106/3104] enabled PCI: 00:10.5 [1106/d104] disabled PCI: 00:10.6, bad id 0xffffffff PCI: 00:10.7, bad id 0xffffffff PCI: 00:11.0 [1106/3227] bus ops PCI: 00:11.0 [1106/3227] enabled PCI: 00:11.1, bad id 0xffffffff ... PCI: 00:11.7, bad id 0xffffffff PCI: 00:12.0 [1106/3065] ops PCI: 00:12.0 [1106/3065] disabled PCI: 00:12.1, bad id 0xffffffff ... PCI: 00:1f.0, bad id 0xffffffff POST: 0x25 do_pci_scan_bridge for PCI: 00:01.0 PCI: pci_scan_bus for bus 01 POST: 0x24 In vt8623 enable_dev for device PCI: 01:00.0. Disabling static device: PCI: 01:00.0 PCI: 01:00.1, bad id 0xffffffff ... PCI: 01:1f.0, bad id 0xffffffff POST: 0x25 PCI: pci_scan_bus returning with max=001 POST: 0x55 do_pci_scan_bridge returns max 1
Trying to force the graphics device enable regardless: In vt8623 enable_dev for device PCI: 01:00.0. PCI: 01:00.0 [ffff/ffff/00ffff] has unknown header type ff, ignoring. PCI: 01:00.0 [ffff/ffff] enabled No operations
Apparently all the device registers read as ffh, this could mean the bridge is not set-up correctly, so I hard-coded the secondary & subordinate bus numbers to 1 in auto.c and the actual Northbridge code (some of the EPIA seems to do this anyway), but this changed nothing: dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8633_1), 0); if (dev == PCI_DEV_INVALID) die("AGP Bridge Not Found\n"); pci_write_config16(dev, 0x4, 0x0007); /* Secondary Bus Number */ pci_write_config8(dev, 0x19, 0x01); /* Subordinate Bus Number */ pci_write_config8(dev, 0x1a, 0x01);
Dump of non-zero AGP Bridge registers at end of auto.c (epia-m + custom code): 00:06 11 91 b0 07 00 30 02 00 00 04 06 00 00 01 00 10:00 00 00 00 00 00 00 00 00 01 01 00 f0 00 00 00 20:00 dc f0 dd 00 d8 f0 db 00 00 00 00 00 00 00 00 30:00 00 00 00 80 00 00 00 00 00 00 00 00 00 0c 00 40:00 08 00 22 20 72 00 00 00 00 00 00 00 00 00 00 80:01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
Dump of AGP Bridge registers in SeaBIOS 0.4.2: 00: 6 11 91 b0 7 0 30 22 0 0 4 6 0 0 1 0 10: 0 0 0 0 0 0 0 0 0 1 1 0 f0 0 0 0 20: 0 fb f0 fc 0 f4 f0 f7 0 0 0 0 0 0 0 0 30: 0 0 0 0 80 0 0 0 0 0 0 0 0 0 c 0 40: 83 45 0 44 24 72 0 0 0 0 0 0 0 0 0 0 80: 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0
(I'm not concerned with most of the registers at this point, as the VGA BIOS and operating system should be setting a number of them)
Dump of the same from running system with factory BIOS and Windows XP: Bus 0 (PCI), Device Number 1, Device Function 0 Vendor 1106h VIA Technologies Inc Device B091h VT8633 Apollo Pro 266 CPU to AGP Controller Command 0007h (I/O Access, Memory Access, BusMaster) Status A230h (Has Capabilities List, Supports 66MHz, Received Master Abort, Detected Parity Error, Medium Timing) Revision 00h, Header Type 01h, Bus Latency Timer 00h Self test 00h (Self test not supported) PCI Class Bridge, type PCI to PCI PCI Bridge Information: Primary Bus Number 0, Secondary Bus Number 1, Subordinate Bus Number 1 Secondary Bus Command 000Ch (ISA mapping, VGA mapping) Secondary Bus Status 0000h Secondary Bus Latency 00h I/O Port Range Passed to Secondary Bus : None Memory Range Passed to Secondary Bus : DC000000h to DDFFFFFFh Prefetchable Memory Range Passed to Secondary Bus : D8000000h to DBFFFFFFh New Capabilities List Present: Power Management Capability, Version 1.1 Supports low power State D1 Does not support PME# signalling Current Power State : D0 (Device operational, no power saving)
Hex-Dump of device configuration space follows: 0000 06 11 91 B0 07 00 30 A2 00 00 04 06 00 00 01 00 0010 00 00 00 00 00 00 00 00 00 01 01 00 F0 00 00 00 0020 00 DC F0 DD 00 D8 F0 DB 00 00 00 00 00 00 00 00 0030 00 00 00 00 80 00 00 00 00 00 00 00 00 00 0C 00 0040 83 C5 00 44 24 72 00 00 00 00 00 00 00 00 00 00 0080 01 00 02 02 00 00 00 00 00 00 00 00 00 00 00 00
The Wiki still talks about concatenating the VGA BIOS to the image, although the current way seems to be to include it in CBFS.
Indeed so.
Are you using Kconfig or the old method with buildtarget?
With Kconfig the way to do it is to select if and how to run the VGA BIOS (which x86 emulator to use, or if to run in real mode) and provide the filename.
I added the target into Kconfig and set up the options/files in menuconfig. The VGA BIOS is added into CBFS with correct vendor & device id's, but it's not getting called because the video device behind the AGP bridge isn't getting found, either by CoreBoot or SeaBios. I'd run it manually just in case it knows how to enable itself, but can't figure how to do that correctly.
On 1/3/10 3:22 PM, Andrej Skirn wrote:
I've set up the relation in devicetree with: device pci 1.0 on # AGP device pci 0.0 on end # VGA end
Are you building with Kconfig or with "newbuild"? If you are not using Kconfig, you have to edit the file Config.lb instead of the file devicetree.cb
In vt8623 enable_dev for device PCI: 01:00.0. Disabling static device: PCI: 01:00.0
The device is explicitly disabled in the static device tree.
Stefan
Stefan Reinauer wrote:
Are you building with Kconfig or with "newbuild"? If you are not using Kconfig, you have to edit the file Config.lb instead of the file devicetree.cb
Kconfig, but I have same device tree in both Config.lb and devicetree.cb. Just in case you're wondering, the results are exactly same even if I don't have the VGA device defined in the device trees, just without the extra debug output (meaning just "PCI: 01:00.0, bad id 0xffffffff" instead).
In vt8623 enable_dev for device PCI: 01:00.0. Disabling static device: PCI: 01:00.0
The device is explicitly disabled in the static device tree.
There's discussion on just this debug message/issue on the v3 at the threat on http://www.mail-archive.com/coreboot@coreboot.org/msg04745.html; which I believe you're well familiar with. Anyway, what that debug message really means is the device appears in the static device tree (devicetree.cb) but has an undefined vendor & device id. In this case, they're 0xffffffff which suggests the bridge isn't really functioning. I can't spot any relevant differences from the factory BIOS Northbridge registers, though. The EPIA-M code is very old and the CLE266 Northbridge code has only ever been used with it, so there might be some gotcha's with that.
On 1/3/10 4:13 PM, Andrej Skirn wrote:
Stefan Reinauer wrote:
Are you building with Kconfig or with "newbuild"? If you are not using Kconfig, you have to edit the file Config.lb instead of the file devicetree.cb
Kconfig, but I have same device tree in both Config.lb and devicetree.cb. Just in case you're wondering, the results are exactly same even if I don't have the VGA device defined in the device trees, just without the extra debug output (meaning just "PCI: 01:00.0, bad id 0xffffffff" instead).
In vt8623 enable_dev for device PCI: 01:00.0. Disabling static device: PCI: 01:00.0
The device is explicitly disabled in the static device tree.
There's discussion on just this debug message/issue on the v3 at the threat on http://www.mail-archive.com/coreboot@coreboot.org/msg04745.html; which I believe you're well familiar with. Anyway, what that debug message really means is the device appears in the static device tree (devicetree.cb) but has an undefined vendor & device id. In this case, they're 0xffffffff which suggests the bridge isn't really functioning. I can't spot any relevant differences from the factory BIOS Northbridge registers, though. The EPIA-M code is very old and the CLE266 Northbridge code has only ever been used with it, so there might be some gotcha's with that.
Indeed, good catch.
Maybe the AGP bridge is not initialized correctly, or at all. This could cause the device to not be visible on that bus.
Do you have a CLE266 datasheet with the AGP bridge registers so you could compare what legacy BIOS does in comparison to coreboot?
Best regards,
Stefan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
I think I can help you. It looks to me that bit 7 at offset 0xe1 is not set as default anymore (otherwise the code never worked?). You would need to set it early so VGA gets visible in "enable" phase. The patch fixes that. Also I disabled the direct access FB because it was hardcoded. I forgotten what is for, maybe libv will know. It looks like the code sets VGA framebuffer size to 32MB (this is hardcoded elsewhere check the comments)
Please try the attached patch I think it could fix it.
Thanks,
Rudolf
On Sun, Jan 03, 2010 at 10:15:33PM +0100, Rudolf Marek wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
I think I can help you. It looks to me that bit 7 at offset 0xe1 is not set as default anymore (otherwise the code never worked?). You would need to set it early so VGA gets visible in "enable" phase. The patch fixes that. Also I disabled the direct access FB because it was hardcoded. I forgotten what is for, maybe libv will know. It looks like the code sets VGA framebuffer size to 32MB (this is hardcoded elsewhere check the comments)
Please try the attached patch I think it could fix it.
Thanks,
Rudolf
Index: northbridge.c
--- northbridge.c (revision 4978) +++ northbridge.c (working copy) @@ -41,32 +41,32 @@ pci_write_config16(dev, 0x80, 0x610f); pci_write_config32(dev, 0x88, 0x00000002);
- /* dont know if this is right ID fix it */ fb_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3122, 0); if (fb_dev) {
This is just a quick way of checking whether the unichrome was enabled at all, so yes, right id.
/* Fixup GART and framebuffer addresses properly.
* First setup frame buffer properly.
*/
//fb = pci_read_config32(dev, 0x10); /* Base addres of framebuffer */
fb = 0xd0000000;
printk_debug("Frame buffer at %8x\n",fb);
c = pci_read_config8(dev, 0xe1) & 0xf0; /* size of vga */
c |= fb>>28; /* upper nibble of frame buffer address */
c = 0xdd;
pci_write_config8(dev, 0xe1, c);
c = 0x81; /* enable framebuffer */
pci_write_config8(dev, 0xe0, c);
/* step 1 enable */
pci_write_config8(dev, 0xe1, 0x80);
/* step 2 enable the VGA without the direct access framebuffer - TOPMEM-32MB must get reserved */
pci_write_config8(dev, 0xe2, 0x42); /* 'cos award does */ }pci_write_config8(dev, 0xe1, 0xd0);
}
static void nullfunc(){}
+static void vga_en(struct device *dev) +{
- /* enable VGA, so the bridges gets VGA_EN and resources are set */
- pci_write_config8(dev, 0xe1, 0x80);
+}
static struct device_operations northbridge_operations = { .read_resources = nullfunc, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources,
- .init = northbridge_init
- .init = northbridge_init,
- .enable = vga_en,
};
static const struct pci_driver northbridge_driver __pci_driver = { @@ -108,11 +108,15 @@ msr_t clocks1,clocks2,instructions,setup;
printk_debug("VGA random fixup ...\n");
- // why it does not rely on std resource system?
+/* pci_write_config8(dev, 0x04, 0x07); pci_write_config8(dev, 0x0d, 0x20); pci_write_config32(dev,0x10,0xd8000008); pci_write_config32(dev,0x14,0xdc000000);
+*/
History.
// set up performnce counters for debugging vga init sequence //setup.lo = 0x1c0; // count instructions //wrmsr(0x187,setup); @@ -254,6 +258,7 @@ ramregs[i]); } printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024); +//it looks like one set 32MB of VGA? tomk = rambits*16*1024 - 32768; /* Compute the top of Low memory */ tolmk = pci_tolm >> 10;
Anything else than 32mb and it dies a horrible death later on when linux tries to use the disks.
Direct fb access allows any access to the framebuffer on the unichrome to be intercepted by the memory controller. Unichrome and memory controller are on the same die here, and since the unichrome uses part of main ram for its memory, any access to the unichrome memory would mean requests being made from the unichrome to the memory controller. Without direct fb access, a lot of on chip bandwidth is effectively thrown away sending fb accesses back and forth.
Luc Verhaegen.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
+/* pci_write_config8(dev, 0x04, 0x07); pci_write_config8(dev, 0x0d, 0x20); pci_write_config32(dev,0x10,0xd8000008); pci_write_config32(dev,0x14,0xdc000000);
+*/
History.
Aha and in raminit.c it looks like some hardcoded bars too :/
// set up performnce counters for debugging vga init sequence //setup.lo = 0x1c0; // count instructions //wrmsr(0x187,setup); @@ -254,6 +258,7 @@ ramregs[i]); } printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024); +//it looks like one set 32MB of VGA? tomk = rambits*16*1024 - 32768; /* Compute the top of Low memory */ tolmk = pci_tolm >> 10;
Anything else than 32mb and it dies a horrible death later on when linux tries to use the disks.
Hm looks familiar to me. Maybe it dies when the DMA is done to the buffer which is located in low mem in the 0xA0000 - 0xF0000 region? Maybe the framebuffer will just change where the DMA buffers gets allocated... Or it is some other bug ;) Does your linux use 640-1MB region as normal RAM?
Direct fb access allows any access to the framebuffer on the unichrome to be intercepted by the memory controller. Unichrome and memory controller are on the same die here, and since the unichrome uses part of main ram for its memory, any access to the unichrome memory would mean requests being made from the unichrome to the memory controller. Without direct fb access, a lot of on chip bandwidth is effectively thrown away sending fb accesses back and forth.
Ok, so we can live without it for now and then re-enable it later maybe with some intelligent resource handling.
Thank you, Rudolf
Rudolf Marek wrote:
I think I can help you. It looks to me that bit 7 at offset 0xe1 is not set as default anymore (otherwise the code never worked?). You would need to set it early so VGA gets visible in "enable" phase. The patch fixes that.
Thanks, that bit does solve the problem with finding the video device. I discovered it indepently about the time you sent the e-mail; it's fairly well hidden in the actual datasheet, but BIOS porting guide for another VIA chipset I have mentions it. It also appears to be enabled on a commented-out line in raminit.c of all places; maybe this was commented out later? The other bits of the register set in the commented-out line don't seem to make sense.
Sadly, just enabling the vide device hasn't solved the legacy VGA-bios problem (although I suppose it would allow Linux to use it). Nothing comes on-screen from coreboot alone, and cb complains about various unimplemented interrupts. Appears that SeaBios vgahooks are needed to get the display adapter to initialize at all, and nothing comes on-screen until SeaBios runs the legacy VGA bios - apparently second time. Disabling either initialization, nothing comes on screen again. I don't see any mention of needing SeaBios to get the VGA working on the Wiki, although Peter Stuge suggested it. This poses a problem though, since I'd like to have the screen working as early as possible, and I'm not certain it's a good idea to initialize it twice in any case. I don't even see why it would work as it does, since coreboot seems to call the legacy VGA BIOS before it has initialized SeaBios, yet it would seem to be running the vgahooks from SeaBios at that point already.
Also vga_enable_console() will hang most of the time; cn700 for example has that call commented out with a remark of "VGA seems to work without this, but crash & burn with it". Disabling it seems to have no ill effects, so far.
Also I disabled the direct access FB because it was hardcoded. I forgotten what is for, maybe libv will know. It looks like the code sets VGA framebuffer size to 32MB (this is hardcoded elsewhere check the comments)
On the board I'm testing this, if the Direct Access FB is disabled, it won't work at all. In fact, it only boots to screen if direct access framebuffer size is 16M (which the factory BIOS sets it to) and enabled. Usually it seems to hang right after SeaBios has ran the calibration loop in timer_setup().
Unfortunately it is hard to tell as the legacy VGA-bios will occassionally start doing random stuff (hang, print garbage on serial, report various random interrupts etc.) until the system is power-cycled. I don't normally do that as it confuses my USB serial-adapter and just do a PCI reset instead, making it hard to always tell what part is bugging. On http://www.coreboot.org/The_EPIA-M/MII section "Legacy VGA BIOS" it mentions something that is relevant to this (Legacy VGA BIOS enabling hardware interrupts, which it does, but interrut controller not being initialized). Unfortunately I can't find the patch it talks about, and it doesn't seem to be in the source tree.
Additionally, commenting out this section causes only garbage to come up on screen:
printk_debug("VGA random fixup ...\n");
- // why it does not rely on std resource system?
+/* pci_write_config8(dev, 0x04, 0x07); pci_write_config8(dev, 0x0d, 0x20); pci_write_config32(dev,0x10,0xd8000008); pci_write_config32(dev,0x14,0xdc000000);
+*/
Please try the attached patch I think it could fix it.
Enabling the display device works. The rest of the patch doesn't work for me. So IF the Direct Access Framebuffer is set to 16M and enabled, the VGA resource registers are left hardcoded, vga_enable_console is not called, the Legacy VGA BIOS is initialized in both coreboot and SeaBios and the Legacy VGA BIOS doesn't bomb on random interrupt vector or something else bizarre, the SeaBios version string comes up on screen but then SeaBios hangs in do_boot, after printing B of "Booting from". Without VGA BIOS it gets past this point and starts loading the OS. (Without display I can't tell exactly how successful it is at this, though).
I'm presently in progress of verifying the resource settings for overlaps and other errors. I'd appreciate any pointers to examples or discussion of the "std resource system" and in particular how the resource allocation is supposed to be done in coreboot presently. The patch http://www.coreboot.org/The_EPIA-M/MII speaks about would also be helpful. Or any insight into the coreboot/SeaBios legacy VGA BIOS inter-operation.
Andrej Skirn wrote:
I don't see any mention of needing SeaBios to get the VGA working on the Wiki, although Peter Stuge suggested it.
It depends on the VGA BIOS. Some of them rely on more BIOS interrupt services being available, some work with less services. coreboot tries to provide some few interrupt services to please the VGA BIOS but it is in no way a substitute for what SeaBIOS provides.
If you have native code for initializing graphics in coreboot (currently only for the Chrome on K8M890 IIRC) then neither VGA BIOS nor other BIOS interrupt service junk is needed - and native code typically runs much faster because it does much less.
This poses a problem though, since I'd like to have the screen working as early as possible,
How long time do you have before SeaBIOS runs the VGA BIOS? With some optimizations, Kevin got this time down to roughly 500ms. Is that too long? (200 of these were the VGA BIOS itself.)
and I'm not certain it's a good idea to initialize it twice in any case.
Back in the day I used to do a real mode call from DOS programs to c000:0003 which would basically re-run the VGA BIOS unless it had self-modified during the first run. This always worked very reliably and I expect it will still.
I don't normally do that as it confuses my USB serial-adapter and just do a PCI reset instead,
I strongly recommend against this. Instead please make sure to always power cycle, in order to always start with a clean state. It's even good to leave power off for a while, ideally lots of seconds, to make sure there's no charge left in power rail capacitors or RAM.
but then SeaBios hangs in do_boot, after printing B of "Booting from". Without VGA BIOS it gets past this point and starts loading the OS. (Without display I can't tell exactly how successful it is at this, though).
Can you try to use the serial output to get more debug information?
Another data point might be to use Google's SGABIOS, it's a VGA BIOS with a serial port backend.
//Peter