Hello,
I am trying to get coreboot working on Asus M4A785-M with Athlon II X2 240e CPU (Socket AM3). So far there is no success.
The mainboard is based on AMD785G + SB710 chipset, which has integrated ATI VGA.
http://www.asus.com/product.aspx?P_ID=ef0qgvMIwOUagAVl&templete=2
The super IO chip is labeled ITE IT8712F-S.
Please see the listings at the end of this post for details.
There is only pin header connector for COM1 serial port on the mainboard. The back panel DB9 connector with cable to attach to the mainboard must be bought separately. (The one I got has too short cable to reach the PCI slot openings. And it was supposed to be an original Asus part!)
The BIOS ROM is Macronix MX25L8005PC-15G, 1 MByte, DIP-8, mounted in a socket. Flashrom 0.9.1 recognizes the chip and is able to read and write it.
I have built a small circuit board where I have two BIOS chips and can select between them with a switch. The board is sitting in the BIOS socket. This makes it easier to recover after flashing something non-bootable.
I have tried with coreboot revision 5631 from SVN.
First, I connected the board via a null-modem cable to another Linux machine, started getty at ttyS0, 115200 bps at the target machine and minicom at the other machine. I get login prompt and can log in via ttyS0, so the serial connection works.
Then I tried to build coreboot for ASRock 939A785GMH/128M, since it is based on the same chip set. Flashing succeeds, but booting does not work. Power light comes on, fans start, but otherwise there is no sign of life, nothing on the serial port.
Then I noticed that the super IO type is different, make a new directory under src/mainboard/asus for this board type, copy the contents from the ASRock board, and change the references to the super I/O from a Winbond chip to the ITE IT8712F.
There seemed to be a some code in the romstage.c that toggled the GPIO pins in the super I/O chip, in function sio_init(). I made a guess that this was something specific to the Winbond chip, so I commented those out. The guess was based on #define -lines after the #include -section.
Also I generated a new irq_tables.c with the utility provided with coreboot sources.
Now, when attempting to boot, I get the following from the serial port:
coreboot-4.0-r5631M Mon Jun 14 04:56:01 EEST 2010 starting... bsp_apicid=0x0 Enabling routing table for node 00 done. Enabling SMP settings
coreboot-4.0-r5631M Mon Jun 14 04:56:01 EEST 2010 starting... bsp_apicid=0x0 Enabling routing table for node 00 done. Enabling SMP settings
coreboot-4.0-r5631M Mon Jun 14 04:56:01 EEST 2010 starting... bsp_apicid=0x0 Enabling routing table for node 00 done. Enabling SMP settings
[...the same repeats...]
Now what to do next?
The wiki documentation left me wondering what exactly are the necessary steps to port coreboot, provided that all the basic components are already supported. Which board-specific files are needed, and which ones can be auto-generated vs. manually coded?
Best regards, Juhana Helovuo
$ lspci -tvnn
-[0000:00]-+-00.0 Advanced Micro Devices [AMD] RS780 Host Bridge Alternate [1022:9601] +-01.0-[0000:01]--+-05.0 ATI Technologies Inc Device [1002:9710] | -05.1 ATI Technologies Inc Device [1002:970f] +-0a.0-[0000:02]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] +-11.0 ATI Technologies Inc SB700/SB800 SATA Controller [IDE mode] [1002:4390] +-12.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-12.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-12.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-13.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-13.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-13.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-14.0 ATI Technologies Inc SBx00 SMBus Controller [1002:4385] +-14.1 ATI Technologies Inc SB700/SB800 IDE Controller [1002:439c] +-14.2 ATI Technologies Inc SBx00 Azalia (Intel HDA) [1002:4383] +-14.3 ATI Technologies Inc SB700/SB800 LPC host controller [1002:439d] +-14.4-[0000:03]-- +-14.5 ATI Technologies Inc SB700/SB800 USB OHCI2 Controller [1002:4399] +-18.0 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] HyperTransport Configuration [1022:1200] +-18.1 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Address Map [1022:1201] +-18.2 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] DRAM Controller [1022:1202] +-18.3 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Miscellaneous Control [1022:1203] -18.4 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Link Control [1022:1204]
All the PCI(-E) slots are empty. Everything in the above listing is integrated to the mainboard.
# ./superiotool -d superiotool r5549 Found ITE IT8712F (id=0x8712, rev=0x8) at 0x2e Register dump: idx 20 21 22 23 24 2b val 87 12 08 00 00 00 def 87 12 08 00 00 00 LDN 0x00 (Floppy) idx 30 60 61 70 74 f0 f1 val 00 03 f0 06 02 00 00 def 00 03 f0 06 02 00 00 LDN 0x01 (COM1) idx 30 60 61 70 f0 f1 f2 f3 val 01 03 f8 04 00 50 00 7f def 00 03 f8 04 00 50 00 7f LDN 0x02 (COM2) idx 30 60 61 70 f0 f1 f2 f3 val 00 02 f8 03 00 50 00 7f def 00 02 f8 03 00 50 00 7f LDN 0x03 (Parallel port) idx 30 60 61 62 63 70 74 f0 val 01 03 78 00 00 07 04 00 def 00 03 78 07 78 07 03 03 LDN 0x04 (Environment controller) idx 30 60 61 62 63 70 f0 f1 f2 f3 f4 f5 f6 val 01 02 90 02 30 00 00 00 00 00 00 00 ff def 00 02 90 02 30 09 00 00 00 00 00 NA NA LDN 0x05 (Keyboard) idx 30 60 61 62 63 70 71 f0 val 01 00 60 00 64 01 02 04 def 01 00 60 00 64 01 02 08 LDN 0x06 (Mouse) idx 30 70 71 f0 val 01 0c 02 00 def 00 0c 02 00 LDN 0x07 (GPIO) idx 25 26 27 28 29 2a 2c 60 61 62 63 64 65 70 71 72 73 74 b0 b1 b2 b3 b4 b5 b8 b9 ba bb bc bd c0 c1 c2 c3 c4 c8 c9 ca cb cc e0 e1 e2 e3 e4 f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd val c0 23 00 00 00 00 1f 00 00 03 00 00 00 00 01 00 38 00 00 00 00 00 00 00 00 00 00 00 00 00 c0 23 00 00 00 c0 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a 00 00 00 00 00 00 00 def 01 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 40 00 01 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 NA 00 LDN 0x08 (MIDI port) idx 30 60 61 70 f0 val 00 03 00 0a 00 def 00 03 00 0a 00 LDN 0x09 (Game port) idx 30 60 61 val 00 02 01 def 00 02 01 LDN 0x0a (Consumer IR) idx 30 60 61 70 f0 val 00 03 10 0b 06 def 00 03 10 0b 00
Juhana Helovuo kirjoitti:
Hello,
I am trying to get coreboot working on Asus M4A785-M with Athlon II X2 240e CPU (Socket AM3). So far there is no success.
Hello again,
There is now some progress in this port.
- Found out that the northbridge was wrong. We should use AMD Family 10 instead of AMD K8.
- Started porting effort again, this time from AMD Tilapia board, since it seemed to be a closer match.
- Configured for AM3 CPU socket and DDR2 settings for memory controller (not DDR3).
Coreboot now boots past the romstage and starts setting up PCI devices. Unfortunately, it crashes at some point during PCI setup. I do not have access to the boot log right now, but could post it later.
I suspect that the devicetree.cb source file is somehow wrong and therefore coreboot does some wrong initialization or probe, which causes an immediate reboot.
Is there a reference manual for writing the devicetree.cb file? All the documents I found in the Coreboot wiki seemed to describe some past version of it.
Can the correctness of devicetree.cb be somehow verified against lspci output? If so, how?
Best regards, Juhana Helovuo
Coreboot now boots past the romstage and starts setting up PCI devices. Unfortunately, it crashes at some point during PCI setup. I do not have access to the boot log right now, but could post it later.
That would be helpful.
I suspect that the devicetree.cb source file is somehow wrong and therefore coreboot does some wrong initialization or probe, which causes an immediate reboot.
Usually an incorrect device tree wouldn't cause a reboot. Do the devices selected in your Kconfig file match the devices in your device tree?
Is there a reference manual for writing the devicetree.cb file? All the documents I found in the Coreboot wiki seemed to describe some past version of it.
The best thing to do is copy a device tree from a similar board. The hard thing about AMD device trees is that the chips in a HyperTransport chain need to be listed in reverse order. You'll get a lot more malloc debugging statements if your device tree is incorrect, since it will find the devices (just not where it expects to), and the devices from the tree will be disabled.
Can the correctness of devicetree.cb be somehow verified against lspci output? If so, how?
The best way is looking through the log to see which devices are allocated with malloc, and which get disabled.
Thanks, Myles
On Wed, 2010-06-16 at 08:30 -0600, Myles Watson wrote:
Coreboot now boots past the romstage and starts setting up PCI devices. Unfortunately, it crashes at some point during PCI setup. I do not have access to the boot log right now, but could post it later.
That would be helpful.
Ok, here I have a boot log attached, in case anyone is interested.
At the end of the log the machine resets and the same starts over from the beginning.
I do not know what the PCI device setup should look like, but towards the end of the log it seems to iterate over the same devices many times.
Best regards, Juhana Helovuo
On Wed, Jun 16, 2010 at 1:55 PM, Juhana Helovuo juhe@iki.fi wrote:
On Wed, 2010-06-16 at 08:30 -0600, Myles Watson wrote:
Coreboot now boots past the romstage and starts setting up PCI devices. Unfortunately, it crashes at some point during PCI setup. I do not have access to the boot log right now, but could post it later.
That would be helpful.
Ok, here I have a boot log attached, in case anyone is interested.
At the end of the log the machine resets and the same starts over from the beginning.
I do not know what the PCI device setup should look like, but towards the end of the log it seems to iterate over the same devices many times.
Yes. I'm not sure why that's happening. Could you send your devicetree.cb?
Thanks, Myles
I think the IT8712 has a watchdog enabled. You need to disable it.
Call it8712f_kill_watchdog()
Thanks, Rudolf
On Wed, 2010-06-16 at 14:04 -0600, Myles Watson wrote:
On Wed, Jun 16, 2010 at 1:55 PM, Juhana Helovuo juhe@iki.fi wrote:
On Wed, 2010-06-16 at 08:30 -0600, Myles Watson wrote:
Coreboot now boots past the romstage and starts setting up PCI devices. Unfortunately, it crashes at some point during PCI setup. I do not have access to the boot log right now, but could post it later.
That would be helpful.
Ok, here I have a boot log attached, in case anyone is interested.
At the end of the log the machine resets and the same starts over from the beginning.
I do not know what the PCI device setup should look like, but towards the end of the log it seems to iterate over the same devices many times.
Yes. I'm not sure why that's happening. Could you send your devicetree.cb?
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
Perhaps I should start out with a very minimalist devicetree and then add parts as needed?
Is there a way to derive the correct contents, or at least the outline, of devicetree.cb from "lspci" dumps?
Best regards, Juhana Helovuo
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Thanks.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
OK
Perhaps I should start out with a very minimalist devicetree and then add parts as needed?
Yes. Instead of commenting out devices from the Tilapia board, I think you should turn them off. The exception to that is: #device pci 18.0 on end #device pci 18.0 on end
Those are the HyperTransport links. There is no explicit way to set a link number in the device tree, so multiple copies of the device are added. If you move those around, your devices will be on different links. In other words, if you move both of those lines (not commented out) above the other device pci 18.0 on, then your devices will be on link 2 instead of link 0.
Is there a way to derive the correct contents, or at least the outline, of devicetree.cb from "lspci" dumps?
You can look at lspci -xxx from the factory BIOS and look at the register settings to determine which link is being used, or you can just try moving those lines around.
Thanks, Myles
On Thu, 2010-06-17 at 07:31 -0600, Myles Watson wrote:
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Thanks.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
OK
Perhaps I should start out with a very minimalist devicetree and then add parts as needed?
Yes. Instead of commenting out devices from the Tilapia board, I think you should turn them off. The exception to that is: #device pci 18.0 on end #device pci 18.0 on end
You can look at lspci -xxx from the factory BIOS and look at the register settings to determine which link is being used, or you can just try moving those lines around.
Now this command gives only hex dumps. I have some idea what the PCI part (first 64 bytes) means, but I have no clue how to interpret the dump to find out the Hypertransport topology. Is there some web reference for this? The lspci listing is attached.
Placing those duplicate "device pci 18.0 on end" entries either before or after the main entry seems to have no effect.
After some experiments with different devicetrees, I did not get very much further. PCI scan is still stuck in infinite loop.
If I switch device 0.0 off, the device enumeration dies, because RS780 device is not found, which is quite logical.
If I switch off the super IO device, I no longer get debug output after that device is switched off, again quite easy to understand.
Otherwise, switching devices on or off does not seem to change the end result: The PCI scan gets into an infinte loop (or recursion). Please see the attached boot log. It was generated using the attached devicetree.cb file.
I added some extra debug print statements to src/devices/pci_device.c, function pci_scan_bus:
/* For all children that implement scan_bus() (i.e. bridges) * scan the bus behind that child. */ printk(BIOS_DEBUG, "PCI: pci_scan_bus entering children of devfn %x.%x - devfn %x.%x\n", PCI_SLOT(min_devfn), PCI_FUNC(min_devfn), PCI_SLOT(max_devfn), PCI_FUNC(max_devfn) ); for (child = bus->children; child; child = child->sibling) { printk(BIOS_DEBUG, " %s\n", dev_path(child) ); } printk(BIOS_DEBUG, "PCI: pci_scan_bus child list end.\n");
for (child = bus->children; child; child = child->sibling) { max = scan_bus(child, max); }
The first for-loop and printk statemements around it were added to see if there is a recursion path through pci_scan_bus.
The resulting log shows that this piece of code is only executed once, so the answer was no.
If I have understood correctly, this part of the boot process scans through the PCI busses and devices by querying the hardware. Can it get into a loop like this, if the hardware gives funny answers?
By my logic, this could be caused by at least three things: - bad devicetree.cb - hardware gives funny answers to PCI scan - bug in the PCI scan logic
Presumably, the first step would be to distinguish among these.
Where would be an appropriate place to insert printk's to find out what is going on?
Best regards, Juhana Helovuo
On Thu, 2010-06-17 at 07:31 -0600, Myles Watson wrote:
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Thanks.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
OK
Hello again,
Infinitely looping PCI scan in pci_device.c was resolved:
I added the following lines to the beginning of pci_scan_bus:
// Maximum sane devfn is 0xFF if (max_devfn > 0xff) { printk(BIOS_DEBUG, "PCI: pci_scan_bus upper limit too big. Using 0xff.\n"); max_devfn=0xff; }
And then the relevant part of the log is:
PCI: pci_scan_bus for bus 00 PCI: pci_scan_bus limits devfn 0 - devfn ffffffff PCI: pci_scan_bus upper limit too big. Using 0xff. POST: 0x24
It seems that the scan loop was not infinite after all, but just tried to enumerate devices from 0 to 0xffffffff, which seemed like inifinity. I could not find out who calls pci_scan_bus, nor where does the too large upper limit come from.
Now the boot process goes through bus probing and starts enabling devices. This goes on until it is time to enable to LPC controller, which I suppose is the bridge to the IT8712F Super I/O -chip. At that point the boot process freezes, or at least there is no more serial output. I added some debug printouts as follows:
[src/southbridge/amd/sb700/sb700_lpc.c]
static void lpc_init(device_t dev) { u8 byte; u32 dword; device_t sm_dev;
printk(BIOS_DEBUG, "sb700 entering lpc_init\n"); /* Enable the LPC Controller */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); dword = pci_read_config32(sm_dev, 0x64); dword |= 1 << 20; pci_write_config32(sm_dev, 0x64, dword);
/* Initialize isa dma */ printk(BIOS_DEBUG, "sb700 initializing isa dma\n"); isa_dma_init(); printk(BIOS_DEBUG, "sb700 isa dma initialized\n");
/* Enable DMA transaction on the LPC bus */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 2); pci_write_config8(dev, 0x40, byte); printk(BIOS_DEBUG, "sb700 DMA enabled on LPC bus\n");
/* Disable the timeout mechanism on LPC */ byte = pci_read_config8(dev, 0x48); byte &= ~(1 << 7); pci_write_config8(dev, 0x48, byte); printk(BIOS_DEBUG, "sb700 LPC Timeout disabled\n");
/* Disable LPC MSI Capability */ byte = pci_read_config8(dev, 0x78); byte &= ~(1 << 1); pci_write_config8(dev, 0x78, byte); printk(BIOS_DEBUG, "sb700 exiting lpc_init\n"); }
And the resulting end of boot log is:
[...cut...] PCI: 00:14.1 init Check CBFS header at fffffd2e magic is 4f524243 Found CBFS header at fffffd2e Check fallback/romstage CBFS: follow chain: fff00000 + 38 + 14769 + align -> fff147c0 Check fallback/coreboot_ram CBFS: follow chain: fff147c0 + 38 + ddc2 + align -> fff225c0 Check fallback/payload CBFS: follow chain: fff225c0 + 38 + 22483 + align -> fff44a80 Check CBFS: follow chain: fff44a80 + 28 + bb286 + align -> fffffd40 CBFS: Could not find file pci1002,439c.rom PCI: 00:14.2 init base = 0xd4200000 codec_mask = 05 2(th) codec viddid: ffffffff 0(th) codec viddid: ffffffff PCI: 00:14.3 init sb700 entering lpc_init sb700 initializing isa dma [log ends here]
PCI tree with the factory BIOS is:
# lspci -tvnn -[0000:00]-+-00.0 Advanced Micro Devices [AMD] RS780 Host Bridge Alternate [1022:9601] +-01.0-[0000:01]--+-05.0 ATI Technologies Inc Device [1002:9710] | -05.1 ATI Technologies Inc Device [1002:970f] +-0a.0-[0000:02]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] +-11.0 ATI Technologies Inc SB700/SB800 SATA Controller [IDE mode] [1002:4390] +-12.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-12.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-12.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-13.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-13.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-13.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-14.0 ATI Technologies Inc SBx00 SMBus Controller [1002:4385] +-14.1 ATI Technologies Inc SB700/SB800 IDE Controller [1002:439c] +-14.2 ATI Technologies Inc SBx00 Azalia (Intel HDA) [1002:4383] +-14.3 ATI Technologies Inc SB700/SB800 LPC host controller [1002:439d] +-14.4-[0000:03]-- +-14.5 ATI Technologies Inc SB700/SB800 USB OHCI2 Controller [1002:4399] +-18.0 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] HyperTransport Configuration [1022:1200] +-18.1 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Address Map [1022:1201] +-18.2 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] DRAM Controller [1022:1202] +-18.3 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Miscellaneous Control [1022:1203] -18.4 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Link Control [1022:1204]
So it seems that something goes wrong inside isa_dma_init();
Now I am not sure what I could try next. As the LPC is needed for Super I/O access, it seems like it cannot be just left out, and configuring the LPC controller to "off" will also kill the serial port.
Any suggestions?
Best regards, Juhana Helovuo
The file that you're looking for is src/pc80/isa-dma.c. I suspect that isa dma init isn't actually shutting the system down, just resetting whatever COM you're getting serial output from. Either comment out that dma port, or try re-initializing the serial console after doing isa_dma_init().
-Corey
On Sun, Jul 18, 2010 at 2:22 PM, Juhana Helovuo juhe@iki.fi wrote:
On Thu, 2010-06-17 at 07:31 -0600, Myles Watson wrote:
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Thanks.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
OK
Hello again,
Infinitely looping PCI scan in pci_device.c was resolved:
I added the following lines to the beginning of pci_scan_bus:
// Maximum sane devfn is 0xFF if (max_devfn > 0xff) { printk(BIOS_DEBUG, "PCI: pci_scan_bus upper limit too big. Using 0xff.\n"); max_devfn=0xff; }
And then the relevant part of the log is:
PCI: pci_scan_bus for bus 00 PCI: pci_scan_bus limits devfn 0 - devfn ffffffff PCI: pci_scan_bus upper limit too big. Using 0xff. POST: 0x24
It seems that the scan loop was not infinite after all, but just tried to enumerate devices from 0 to 0xffffffff, which seemed like inifinity. I could not find out who calls pci_scan_bus, nor where does the too large upper limit come from.
Now the boot process goes through bus probing and starts enabling devices. This goes on until it is time to enable to LPC controller, which I suppose is the bridge to the IT8712F Super I/O -chip. At that point the boot process freezes, or at least there is no more serial output. I added some debug printouts as follows:
[src/southbridge/amd/sb700/sb700_lpc.c]
static void lpc_init(device_t dev) { u8 byte; u32 dword; device_t sm_dev;
printk(BIOS_DEBUG, "sb700 entering lpc_init\n"); /* Enable the LPC Controller */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); dword = pci_read_config32(sm_dev, 0x64); dword |= 1 << 20; pci_write_config32(sm_dev, 0x64, dword);
/* Initialize isa dma */ printk(BIOS_DEBUG, "sb700 initializing isa dma\n"); isa_dma_init(); printk(BIOS_DEBUG, "sb700 isa dma initialized\n");
/* Enable DMA transaction on the LPC bus */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 2); pci_write_config8(dev, 0x40, byte); printk(BIOS_DEBUG, "sb700 DMA enabled on LPC bus\n");
/* Disable the timeout mechanism on LPC */ byte = pci_read_config8(dev, 0x48); byte &= ~(1 << 7); pci_write_config8(dev, 0x48, byte); printk(BIOS_DEBUG, "sb700 LPC Timeout disabled\n");
/* Disable LPC MSI Capability */ byte = pci_read_config8(dev, 0x78); byte &= ~(1 << 1); pci_write_config8(dev, 0x78, byte); printk(BIOS_DEBUG, "sb700 exiting lpc_init\n"); }
And the resulting end of boot log is:
[...cut...] PCI: 00:14.1 init Check CBFS header at fffffd2e magic is 4f524243 Found CBFS header at fffffd2e Check fallback/romstage CBFS: follow chain: fff00000 + 38 + 14769 + align -> fff147c0 Check fallback/coreboot_ram CBFS: follow chain: fff147c0 + 38 + ddc2 + align -> fff225c0 Check fallback/payload CBFS: follow chain: fff225c0 + 38 + 22483 + align -> fff44a80 Check CBFS: follow chain: fff44a80 + 28 + bb286 + align -> fffffd40 CBFS: Could not find file pci1002,439c.rom PCI: 00:14.2 init base = 0xd4200000 codec_mask = 05 2(th) codec viddid: ffffffff 0(th) codec viddid: ffffffff PCI: 00:14.3 init sb700 entering lpc_init sb700 initializing isa dma [log ends here]
PCI tree with the factory BIOS is:
# lspci -tvnn -[0000:00]-+-00.0 Advanced Micro Devices [AMD] RS780 Host Bridge Alternate [1022:9601] +-01.0-[0000:01]--+-05.0 ATI Technologies Inc Device [1002:9710] | -05.1 ATI Technologies Inc Device [1002:970f] +-0a.0-[0000:02]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] +-11.0 ATI Technologies Inc SB700/SB800 SATA Controller [IDE mode] [1002:4390] +-12.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-12.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-12.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-13.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-13.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-13.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-14.0 ATI Technologies Inc SBx00 SMBus Controller [1002:4385] +-14.1 ATI Technologies Inc SB700/SB800 IDE Controller [1002:439c] +-14.2 ATI Technologies Inc SBx00 Azalia (Intel HDA) [1002:4383] +-14.3 ATI Technologies Inc SB700/SB800 LPC host controller [1002:439d] +-14.4-[0000:03]-- +-14.5 ATI Technologies Inc SB700/SB800 USB OHCI2 Controller [1002:4399] +-18.0 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] HyperTransport Configuration [1022:1200] +-18.1 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Address Map [1022:1201] +-18.2 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] DRAM Controller [1022:1202] +-18.3 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Miscellaneous Control [1022:1203] -18.4 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Link Control [1022:1204]
So it seems that something goes wrong inside isa_dma_init();
Now I am not sure what I could try next. As the LPC is needed for Super I/O access, it seems like it cannot be just left out, and configuring the LPC controller to "off" will also kill the serial port.
Any suggestions?
Best regards, Juhana Helovuo
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot
Hello All,
Thanks for the tip, Corey.
I commented out the call to isa_dma_init(). Now there is both progress and new problems:
Progress:
* Coreboot runs to completion, loads a payload from CBFS, and jumps to execute it.
* I managed to extract the VGA BIOS image, and add it to CBFS. It works, i.e. initializes the display, and I can see the coreboot log on VGA also.
Problems:
* So far no success with payloads. ** SeaBIOS gives no output at all. ** GRUB 2 only clears screen, prints "Welcome to GRUB" on VGA, and then freezes. ** Both payload images are tested to work with coreboot on QEMU. In QEMU they give sane output and try to load OS.
* There is a suspicious keyboard timeout message in the log.
Clearly something is out of place, but I cannot immediately figure out what to do next. Any suggestions?
Best regards, Juhana Helovuo
On Sun, 2010-07-18 at 15:41 -0400, Corey Osgood wrote:
The file that you're looking for is src/pc80/isa-dma.c. I suspect that isa dma init isn't actually shutting the system down, just resetting whatever COM you're getting serial output from. Either comment out that dma port, or try re-initializing the serial console after doing isa_dma_init().
-Corey
On Sun, Jul 18, 2010 at 2:22 PM, Juhana Helovuo juhe@iki.fi wrote:
On Thu, 2010-06-17 at 07:31 -0600, Myles Watson wrote:
Yes, here it is attached. It is copied and modified from AMD Tilapia mainboard, because that seemed to be a close relative.
Thanks.
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested. That changed the behavior so that the machine no longer reboots in the middle of iterating through PCI busses and devices, but instead it seems to go on iterating infinitely, or presumably until malloc runs out of memory.
OK
Hello again,
Infinitely looping PCI scan in pci_device.c was resolved:
I added the following lines to the beginning of pci_scan_bus:
// Maximum sane devfn is 0xFF if (max_devfn > 0xff) { printk(BIOS_DEBUG, "PCI: pci_scan_bus upper limit too big. Using 0xff.\n"); max_devfn=0xff; }
And then the relevant part of the log is:
PCI: pci_scan_bus for bus 00 PCI: pci_scan_bus limits devfn 0 - devfn ffffffff PCI: pci_scan_bus upper limit too big. Using 0xff. POST: 0x24
It seems that the scan loop was not infinite after all, but just tried to enumerate devices from 0 to 0xffffffff, which seemed like inifinity. I could not find out who calls pci_scan_bus, nor where does the too large upper limit come from.
Now the boot process goes through bus probing and starts enabling devices. This goes on until it is time to enable to LPC controller, which I suppose is the bridge to the IT8712F Super I/O -chip. At that point the boot process freezes, or at least there is no more serial output. I added some debug printouts as follows:
[src/southbridge/amd/sb700/sb700_lpc.c]
static void lpc_init(device_t dev) { u8 byte; u32 dword; device_t sm_dev;
printk(BIOS_DEBUG, "sb700 entering lpc_init\n"); /* Enable the LPC Controller */ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0)); dword = pci_read_config32(sm_dev, 0x64); dword |= 1 << 20; pci_write_config32(sm_dev, 0x64, dword); /* Initialize isa dma */ printk(BIOS_DEBUG, "sb700 initializing isa dma\n"); isa_dma_init(); printk(BIOS_DEBUG, "sb700 isa dma initialized\n"); /* Enable DMA transaction on the LPC bus */ byte = pci_read_config8(dev, 0x40); byte |= (1 << 2); pci_write_config8(dev, 0x40, byte); printk(BIOS_DEBUG, "sb700 DMA enabled on LPC bus\n"); /* Disable the timeout mechanism on LPC */ byte = pci_read_config8(dev, 0x48); byte &= ~(1 << 7); pci_write_config8(dev, 0x48, byte); printk(BIOS_DEBUG, "sb700 LPC Timeout disabled\n"); /* Disable LPC MSI Capability */ byte = pci_read_config8(dev, 0x78); byte &= ~(1 << 1); pci_write_config8(dev, 0x78, byte); printk(BIOS_DEBUG, "sb700 exiting lpc_init\n");
}
And the resulting end of boot log is:
[...cut...] PCI: 00:14.1 init Check CBFS header at fffffd2e magic is 4f524243 Found CBFS header at fffffd2e Check fallback/romstage CBFS: follow chain: fff00000 + 38 + 14769 + align -> fff147c0 Check fallback/coreboot_ram CBFS: follow chain: fff147c0 + 38 + ddc2 + align -> fff225c0 Check fallback/payload CBFS: follow chain: fff225c0 + 38 + 22483 + align -> fff44a80 Check CBFS: follow chain: fff44a80 + 28 + bb286 + align -> fffffd40 CBFS: Could not find file pci1002,439c.rom PCI: 00:14.2 init base = 0xd4200000 codec_mask = 05 2(th) codec viddid: ffffffff 0(th) codec viddid: ffffffff PCI: 00:14.3 init sb700 entering lpc_init sb700 initializing isa dma [log ends here]
PCI tree with the factory BIOS is:
# lspci -tvnn -[0000:00]-+-00.0 Advanced Micro Devices [AMD] RS780 Host Bridge Alternate [1022:9601] +-01.0-[0000:01]--+-05.0 ATI Technologies Inc Device [1002:9710] | -05.1 ATI Technologies Inc Device [1002:970f] +-0a.0-[0000:02]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] +-11.0 ATI Technologies Inc SB700/SB800 SATA Controller [IDE mode] [1002:4390] +-12.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-12.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-12.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-13.0 ATI Technologies Inc SB700/SB800 USB OHCI0 Controller [1002:4397] +-13.1 ATI Technologies Inc SB700 USB OHCI1 Controller [1002:4398] +-13.2 ATI Technologies Inc SB700/SB800 USB EHCI Controller [1002:4396] +-14.0 ATI Technologies Inc SBx00 SMBus Controller [1002:4385] +-14.1 ATI Technologies Inc SB700/SB800 IDE Controller [1002:439c] +-14.2 ATI Technologies Inc SBx00 Azalia (Intel HDA) [1002:4383] +-14.3 ATI Technologies Inc SB700/SB800 LPC host controller [1002:439d] +-14.4-[0000:03]-- +-14.5 ATI Technologies Inc SB700/SB800 USB OHCI2 Controller [1002:4399] +-18.0 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] HyperTransport Configuration [1022:1200] +-18.1 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Address Map [1022:1201] +-18.2 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] DRAM Controller [1022:1202] +-18.3 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Miscellaneous Control [1022:1203] -18.4 Advanced Micro Devices [AMD] Family 10h [Opteron, Athlon64, Sempron] Link Control [1022:1204]
So it seems that something goes wrong inside isa_dma_init();
Now I am not sure what I could try next. As the LPC is needed for Super I/O access, it seems like it cannot be just left out, and configuring the LPC controller to "off" will also kill the serial port.
Any suggestions?
Best regards, Juhana Helovuo
-- coreboot mailing list: coreboot@coreboot.org http://www.coreboot.org/mailman/listinfo/coreboot
Clearly something is out of place, but I cannot immediately figure out what to do next. Any suggestions?
Your UMA is conflicting with your Coreboot tables. It is at least part of the problem.
uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES 1. 0000000000001000-000000000009ffff: RAM 2. 00000000000c0000-000000006fffffff: RAM 3. 0000000070000000-000000007fffffff: RESERVED Wrote coreboot table at: 7fffe000 - 7fffe8bc checksum 3af4
Since your UMA is 0x70000000-0x7fffffff, your Coreboot tables should end up at 6fffe000, not 7fffe000.
Thanks, Myles
On Thu, 2010-07-29 at 10:18 -0600, Myles Watson wrote:
Clearly something is out of place, but I cannot immediately figure out what to do next. Any suggestions?
Your UMA is conflicting with your Coreboot tables. It is at least part of the problem.
uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES
- 0000000000001000-000000000009ffff: RAM
- 00000000000c0000-000000006fffffff: RAM
- 0000000070000000-000000007fffffff: RESERVED
Wrote coreboot table at: 7fffe000 - 7fffe8bc checksum 3af4
Since your UMA is 0x70000000-0x7fffffff, your Coreboot tables should end up at 6fffe000, not 7fffe000.
Ok, thanks again for the tip. This would have taken me ages to figure out by myself.
I could - at least partially - resolve this by disabling the "high tables" configuration option from Coreboot. If there is a better way, I did not yet find it out. (I suppose UMA means the range of main RAM assigned to the use of VGA controller.)
Now there is more progress:
* Coreboot successfully loads "coreinfo" payload, which seems to work nicely (on serial port).
* Coreboot successfully loads grub2 bootloader, which seems to work also, i.e. keyboard, vga, and ata disks work.
Problems:
* Seabios still does not give any sign of life.
* Grub can load linux kernel and ramdisk from IDE disk to memory, but kernel boot process fails.
The Linux kernel sometimes boots up to "Memory: 2056736k/2097152k available" and sometimes to "Inode-cache hash table entries: 131072"
Please see attached Linux boot logs for details. The boot log with original Asus BIOS is for reference.
Since the Linux boot process does not always crash at the same stage, I suspect that this may be some timing problem, such as the Super IO watchdog acting up again.
I got the impression that the kernel initializes some devices by following instructions from ACPI tables. Currently I am using ACPI source codes for AMD Tilapia mainboard from Coreboot sources. At least the Super IO chip type is different there. Maybe this accidentally enables the watchdog again?
To get more suitable ACPI tables, I dumped ACPI DSDT binary from /proc/acpi/dsdt and disassembled it with iasl compiler. This resulted in a rather long and incomprehensible ASL source program.
However, I could not use it, because recompiling it with "iasl -tc" gives a long list of errors (iasl gives up at 200 errors), e.g.
Maximum error count (200) exceeded DSDT.dsl 271: Notify (_SB.PWRB, 0x02) Error 4062 - Object does not exist ^ (_SB.PWRB)
DSDT.dsl 619: LNKC, Error 4062 - ^ Object does not exist (LNKC)
DSDT.dsl 627: LNKD, Error 4062 - ^ Object does not exist (LNKD)
[...]
DSDT.dsl 5471: If (LEqual (STCL, 0x0101)) Error 4094 - ^ syntax error, unexpected PARSEOP_IF
DSDT.dsl 5885: Device (SMBS) Error 4055 - ^ Name already exists in scope (SMBS)
DSDT.dsl 5888: OperationRegion (SMBS, PCI_Config, Zero, 0x0100) Error 4055 - Name already exists in scope ^ (SMBS)
DSDT.dsl 5904: Scope { Error 4094 - ^ syntax error, unexpected PARSEOP_SCOPE, expecting $end
Most of the errors are "Object does not exist", so I presume I am missing some kind of library or #include code, but where to get those?
Additionally, I have tried to generate IRQ routing table with the "getpir" utility included with coreboot. It claims to find and extract a table, generates C code, which compiles ok, but booting with it does not work. When writing the table to memory during boot, coreboot complains that the table length is wrong and checksum does not match.
Any pointers to getting working ACPI and IRQ tables for Linux? Or how to fix the ACPI information extracted from Asus BIOS?
Best regards, Juhana Helovuo
On Tue, Aug 3, 2010 at 6:31 AM, Juhana Helovuo juhe@iki.fi wrote:
On Thu, 2010-07-29 at 10:18 -0600, Myles Watson wrote:
Clearly something is out of place, but I cannot immediately figure out what to do next. Any suggestions?
Your UMA is conflicting with your Coreboot tables. It is at least part of the problem.
uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES 1. 0000000000001000-000000000009ffff: RAM 2. 00000000000c0000-000000006fffffff: RAM 3. 0000000070000000-000000007fffffff: RESERVED Wrote coreboot table at: 7fffe000 - 7fffe8bc checksum 3af4
Since your UMA is 0x70000000-0x7fffffff, your Coreboot tables should end up at 6fffe000, not 7fffe000.
Ok, thanks again for the tip. This would have taken me ages to figure out by myself.
I could - at least partially - resolve this by disabling the "high tables" configuration option from Coreboot. If there is a better way, I did not yet find it out. (I suppose UMA means the range of main RAM assigned to the use of VGA controller.)
That's right. You probably want to reorder some code for your board so that the UMA area is reserved before the coreboot tables.
Now there is more progress:
- Coreboot successfully loads "coreinfo" payload, which seems to work
nicely (on serial port).
- Coreboot successfully loads grub2 bootloader, which seems to work
also, i.e. keyboard, vga, and ata disks work.
Problems:
- Seabios still does not give any sign of life.
SeaBIOS is loaded into the same location as the coreboot tables, so without hihg tables it won't work.
- Grub can load linux kernel and ramdisk from IDE disk to memory, but
kernel boot process fails.
The Linux kernel sometimes boots up to "Memory: 2056736k/2097152k available" and sometimes to "Inode-cache hash table entries: 131072"
Please see attached Linux boot logs for details. The boot log with original Asus BIOS is for reference.
Since the Linux boot process does not always crash at the same stage, I suspect that this may be some timing problem, such as the Super IO watchdog acting up again.
Since you have 2G of RAM available according to your boot log, I suspect that you're having a conflict with UMA again. I would start there.
To get more suitable ACPI tables, I dumped ACPI DSDT binary from /proc/acpi/dsdt and disassembled it with iasl compiler. This resulted in a rather long and incomprehensible ASL source program.
However, I could not use it, because recompiling it with "iasl -tc" gives a long list of errors (iasl gives up at 200 errors), e.g.
You can look at some of the DSDTs for other boards for hints on how to do forward declarations. Some of the objects may be contained in the SSDT, which may be dynamically generated.
Good luck, Myles
On Tue, 2010-08-03 at 08:30 -0600, Myles Watson wrote:
Since you have 2G of RAM available according to your boot log, I suspect that you're having a conflict with UMA again. I would start there.
Yes, that seemed to be it.
I added excplicit specification for high tables in mainboard.c as follows:
high_tables_base = uma_memory_base - 0x4000000; high_tables_size = HIGH_TABLES_SIZE * 1024;
I also tried setting uma_memory_base to
uma_memory_base = msr.lo / 2;
instead of
uma_memory_base = msr.lo - uma_memory_size;
With 2048 MB RAM this sets UMA to 0x40000000.
This fixed the seemingly corrupted ACPI DSDT headers, as the vendor and revision strings printed out in Linux boot log looked like random binary garbage.
I also made a custom DSDT source file by disassembling the Asus original DSDT binary, and then hand-picking some parts from there, which seemed to be most essential, such as parts defining processors, links(?), interrupts, and built-in PCI devices. Some parts I could not take, since they contained code that wouldn't compile with current IASL compiler, most notably all of ISA and Super I/O stuff.
By this process I could fix some errors, such as identifier use before definition, simply by reodering code blocks so that definition is always before use.
Some parts of the original DSDT contained executable code, such as if-statements at the module level, i.e. outside method definitions. In some cases I fixed this by executing all the definitions unconditionally, and in some cases just by leaving out that code block. It looks like that executable code outside methods was legal in ACPI 1.0 but no longer in 2.0 and afterwards.
A lot of the original DSDT seemed to describe namespace "ASOC", which seems to contain definitions of how to tweak voltages and frequencies of various mainbaord parts, i.e. overclocking or similar tuning. Those I left out completely.
For some reason, booting after reflashing does not work at the first attempt, but freezes at "Welcome to Grub!" -screen. Cycling power off and on again results in a successful boot to Grub menu.
With the stripped-down DSDT, I can get Grub2 to boot Linux up to login prompt and many devices also work, at least VGA console, IDE disk, and Ethernet. Remote ssh login works also.
However, there are lots of complaints about missing IRQ mapping definitions during boot, and Linux ACPI interpreter cannot load all the definitions, although IASL compiles them without complaint. So far I have not been able to figure out what is wrong there.
Please see the attached Linux boot log for details.
Also, Linux does not seem to know where the UMA is located. I believe it should get this from ACPI tables, but those are not working. Since it does not know where UMA is, Linux is bound to sooner or later corrupt UMA, or vice versa.
By looking at boot logs with original Asus BIOS, it looks like ACPI tables tell Linux that memory 0x70000000 - 0x7fffffff is reserved as "iomem" to device "pnp 00:01".
Now the next step would be to get Linux to accept the ACPI tables, but I do not really know where to begin debugging them.
Best Regards, Juhana Helovuo
Since you have 2G of RAM available according to your boot log, I suspect that you're having a conflict with UMA again. I would start there.
Yes, that seemed to be it.
I'm glad that narrowed it down for you.
I added excplicit specification for high tables in mainboard.c as follows:
high_tables_base = uma_memory_base - 0x4000000; high_tables_size = HIGH_TABLES_SIZE * 1024;
I also tried setting uma_memory_base to
uma_memory_base = msr.lo / 2;
instead of
uma_memory_base = msr.lo - uma_memory_size;
I wouldn't change that. I think it's easier to leave UMA at the end.
With 2048 MB RAM this sets UMA to 0x40000000.
From your log:
[ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 0000000000001000 (reserved) [ 0.000000] BIOS-e820: 0000000000001000 - 00000000000a0000 (usable) [ 0.000000] BIOS-e820: 00000000000c0000 - 00000000000f0000 (usable) [ 0.000000] BIOS-e820: 00000000000f0000 - 00000000000f1000 (reserved) [ 0.000000] BIOS-e820: 00000000000f1000 - 0000000080000000 (usable)
Until you see the correct areas reserved in the RAM map for high_tables and UMA, there's not much point in booting Linux. When those areas are reserved correctly they will show up in the table.
Thanks, Myles
On Thu, 2010-08-05 at 13:05 -0600, Myles Watson wrote:
I wouldn't change that. I think it's easier to leave UMA at the end.
With 2048 MB RAM this sets UMA to 0x40000000.
From your log: [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 0000000000001000 (reserved) [ 0.000000] BIOS-e820: 0000000000001000 - 00000000000a0000 (usable) [ 0.000000] BIOS-e820: 00000000000c0000 - 00000000000f0000 (usable) [ 0.000000] BIOS-e820: 00000000000f0000 - 00000000000f1000 (reserved) [ 0.000000] BIOS-e820: 00000000000f1000 - 0000000080000000 (usable)
Until you see the correct areas reserved in the RAM map for high_tables and UMA, there's not much point in booting Linux. When those areas are reserved correctly they will show up in the table.
Ok, now I understand that Linux memory management is overwriting everything listed in the e820 table as "usable". If coreboot tables are not listed as reserved or ACPI, they will get corrupted.
The problem is, I have not been able to change the table to show correct values despite several attempts.
The memory table of coreboot is as follows:
Adding high table area uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES 1. 0000000000001000-000000000009ffff: RAM 2. 00000000000c0000-000000006ffeffff: RAM 3. 000000006fff0000-000000006fffffff: CONFIGURATION TABLES 4. 0000000070000000-000000007fffffff: RESERVED Wrote coreboot table at: 6fffe000 - 6fffe8d0 checksum eb01 coreboot table: 2256 bytes. POST: 0x9e 0. FREE SPACE 70000000 00000000 1. GDT 6fff0200 00000200 2. IRQ TABLE 6fff0400 00001000 3. SMP TABLE 6fff1400 00001000 4. ACPI 6fff2400 0000bc00 5. COREBOOT 6fffe000 00002000 Check CBFS header at fffffd2e
This seems quite ok to me: UMA is reserved at the top of RAM and coreboot tables right before that.
But at the Linux boot log the memory map shows up like this:
[ 0.000000] Command line: BOOT_IMAGE=/vmlinuz root=/dev/hda console=tty1 console=ttyS0,0 [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 0000000000001000 (reserved) [ 0.000000] BIOS-e820: 0000000000001000 - 00000000000a0000 (usable) [ 0.000000] BIOS-e820: 00000000000c0000 - 00000000000f0000 (usable) [ 0.000000] BIOS-e820: 00000000000f0000 - 00000000000f1000 (reserved) [ 0.000000] BIOS-e820: 00000000000f1000 - 0000000080000000 (usable) [ 0.000000] max_pfn_mapped = 524288
So the reservations got lost somewhere between Coreboot and Linux. (Grub2?)
The e820 memory map with factory BIOS looks like this:
[ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: 0000000000000000 - 000000000009ec00 (usable) [ 0.000000] BIOS-e820: 000000000009ec00 - 00000000000a0000 (reserved) [ 0.000000] BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved) [ 0.000000] BIOS-e820: 0000000000100000 - 000000006ff90000 (usable) [ 0.000000] BIOS-e820: 000000006ff90000 - 000000006ffa8000 (ACPI data) [ 0.000000] BIOS-e820: 000000006ffa8000 - 000000006ffd0000 (ACPI NVS) [ 0.000000] BIOS-e820: 000000006ffd0000 - 0000000070000000 (reserved) [ 0.000000] BIOS-e820: 00000000fff00000 - 0000000100000000 (reserved) [ 0.000000] Entering add_active_range(0, 0, 158) 0 entries of 3200 used [ 0.000000] Entering add_active_range(0, 256, 458640) 1 entries of 3200 used [ 0.000000] max_pfn_mapped = 1048576 [ 0.000000] init_memory_mapping [...] [ 0.000000] Scanning NUMA topology in Northbridge 24 [ 0.000000] No NUMA configuration found [ 0.000000] Faking a node at 0000000000000000-000000006ff90000 [ 0.000000] Entering add_active_range(0, 0, 158) 0 entries of 3200 used [ 0.000000] Entering add_active_range(0, 256, 458640) 1 entries of 3200 used [ 0.000000] Bootmem setup node 0 0000000000000000-000000006ff90000
There is no UMA reserved, but ACPI data area is.
UMA is set aside only later, as directed by ACPI tables, I presume:
[ 0.331068] pnp: PnP ACPI init [ 0.331068] ACPI: bus type pnp registered [ 0.331068] pnp 00:00: parse allocated resources [ 0.331068] pnp 00:00: add io 0xcf8-0xcff flags 0x1 [ 0.331068] pnp 00:00: Plug and Play ACPI device, IDs PNP0a03 (active) [ 0.331068] pnp 00:01: parse allocated resources [ 0.331068] pnp 00:01: add mem 0x0-0xffffffffffffffff flags 0x10000000 [ 0.331068] pnp 00:01: add mem 0x70000000-0x7fffffff flags 0x0 [ 0.331068] pnp 00:01: PNP0c02: calling quirk_system_pci_resources+0x0/0x15c
Another interesting difference is that for some reason the "Bootmem" module of Linux uses memory only up to 0x6ff90000 with factory BIOS, thus leaving alone ACPI data area and UMA.
With Coreboot, Linux "Bootmem" decides to use up to 0x80000000, which seems to corrupt Coreboot tables.
I tried to protect the tables and UMA with kernel memmap-command line parameters to specify the location of coreboot tables at 0x6fff0000 (64k) and "reserved" for UMA at 0x70000000 (256M), but then Bootmem module somehow decides to use only 0x10000000 bytes of memory, and then it finds that initramdisk is loaded above the top of that memory.
Additionally, kernel command line parameter memmap=256M$0x70000000 results in a line in e820 RAM map, but the range is printed as "usable" instead of "reserved". This is very strange, since in the kernel source code areas specified with "$" are clearly marked as reserved.
It is still somewhat unclear where and how all of these memory maps are transmitted from Coreboot to Linux. I could not find the callback for BIOS e820 calls in Coreboot sources.
Best regards, Juhana Helovuo
It is still somewhat unclear where and how all of these memory maps are transmitted from Coreboot to Linux. I could not find the callback for BIOS e820 calls in Coreboot sources.
Coreboot doesn't do callbacks. If you're using SeaBIOS, it handles the callbacks and gets the information from the Coreboot tables. Grub2 got its information from the multiboot tables last time I looked.
Have you tried SeaBIOS again now that the UMA area and high tables are right?
Thanks, Myles
On Thu, 2010-08-19 at 14:39 -0600, Myles Watson wrote:
It is still somewhat unclear where and how all of these memory maps are transmitted from Coreboot to Linux. I could not find the callback for BIOS e820 calls in Coreboot sources.
Coreboot doesn't do callbacks. If you're using SeaBIOS, it handles the callbacks and gets the information from the Coreboot tables. Grub2 got its information from the multiboot tables last time I looked.
Ok, I see. So there has to be a boot loader or BIOS between Coreboot and Linux to set up BIOS e820 callbacks, or find some other way to explain the memory layout to Linux.
Have you tried SeaBIOS again now that the UMA area and high tables are right?
Yes, I just did. For some reason it still does not do anything at all. The last output I see is from Coreboot:
Jumping to boot code at fdf82 POST: 0xfe entry = 0x000fdf82 lb_start = 0x00200000 lb_size = 0x00128000 adjust = 0x6fcc8000 buffer = 0x6fda0000 elf_boot_notes = 0x00219e24 adjusted_boot_notes = 0x6fee1e24
Then nothing after this, both on serial port and VGA. The SeaBIOS image was precompiled 0.6.0 ELF from the SeaBIOS "home page".
So far I have Grub2 more or less working, so is Coreinfo, and I can also get response (VGA & keyboard) from FILO, although it does not find my disks. Grub2 sees my IDE disk and cdrom as "ata6" and "ata7".
Best Regards, Juhana Helovuo
On Thu, Aug 26, 2010 at 9:31 AM, Juhana Helovuo juhe@iki.fi wrote:
On Thu, 2010-08-19 at 14:39 -0600, Myles Watson wrote:
It is still somewhat unclear where and how all of these memory maps are transmitted from Coreboot to Linux. I could not find the callback for BIOS e820 calls in Coreboot sources.
Coreboot doesn't do callbacks. If you're using SeaBIOS, it handles the callbacks and gets the information from the Coreboot tables. Grub2 got its information from the multiboot tables last time I looked.
Ok, I see. So there has to be a boot loader or BIOS between Coreboot and Linux to set up BIOS e820 callbacks, or find some other way to explain the memory layout to Linux.
Have you tried SeaBIOS again now that the UMA area and high tables are right?
Yes, I just did. For some reason it still does not do anything at all. The last output I see is from Coreboot:
Jumping to boot code at fdf82 POST: 0xfe entry = 0x000fdf82 lb_start = 0x00200000 lb_size = 0x00128000 adjust = 0x6fcc8000 buffer = 0x6fda0000 elf_boot_notes = 0x00219e24 adjusted_boot_notes = 0x6fee1e24
Then nothing after this, both on serial port and VGA. The SeaBIOS image was precompiled 0.6.0 ELF from the SeaBIOS "home page".
So far I have Grub2 more or less working, so is Coreinfo, and I can also get response (VGA & keyboard) from FILO, although it does not find my disks. Grub2 sees my IDE disk and cdrom as "ata6" and "ata7".
Multiboot Information structure has been written. POST: 0x9d Adding CBMEM entry as no. 5 Writing high table forward entry at 0x00000500 Wrote coreboot table at: 00000500 - 00000518 checksum 9fde New low_table_end: 0x00000518 Now going to write high coreboot table at 0x7fffe000 rom_table_end = 0x7fffe000 Adjust low_table_end from 0x00000518 to 0x00001000 Adjust rom_table_end from 0x7fffe000 to 0x80000000 Adding high table area uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES 1. 0000000000001000-000000000009ffff: RAM 2. 00000000000c0000-000000006fffffff: RAM 3. 0000000070000000-000000007fffffff: RESERVED Wrote coreboot table at: 7fffe000 - 7fffe8bc checksum 3af4 coreboot table: 2236 bytes.
It doesn't seem good that the Multiboot table gets written before the UMA and high table areas are added. I would think that's why they don't show up.
I don't have a good reason why SeaBIOS isn't working.
Thanks, Myles
Multiboot Information structure has been written. POST: 0x9d Adding CBMEM entry as no. 5 Writing high table forward entry at 0x00000500 Wrote coreboot table at: 00000500 - 00000518 checksum 9fde New low_table_end: 0x00000518 Now going to write high coreboot table at 0x7fffe000 rom_table_end = 0x7fffe000 Adjust low_table_end from 0x00000518 to 0x00001000 Adjust rom_table_end from 0x7fffe000 to 0x80000000 Adding high table area uma_memory_start=0x70000000, uma_memory_size=0x10000000 coreboot memory table: 0. 0000000000000000-0000000000000fff: CONFIGURATION TABLES
- 0000000000001000-000000000009ffff: RAM
- 00000000000c0000-000000006fffffff: RAM
- 0000000070000000-000000007fffffff: RESERVED
Wrote coreboot table at: 7fffe000 - 7fffe8bc checksum 3af4 coreboot table: 2236 bytes.
It doesn't seem good that the Multiboot table gets written before the UMA and high table areas are added. I would think that's why they don't show up.
Maybe this log is too old. If my comments don't apply anymore, could you send your latest log to the list?
Thanks, Myles
On Thu, 2010-08-26 at 09:40 -0600, Myles Watson wrote:
It doesn't seem good that the Multiboot table gets written before the UMA and high table areas are added. I would think that's why they don't show up.
Yes, that was it, thanks for the advice.
I checked with coreinfo, and multiboot table did not have a clue about high tables area or UMA. Furthermore, it looked very much like the e820 table Linux was receiving.
Reading the source of multiboot table writer in Coreboot, it says in the comments that adding reserved memory areas is not yet implemented.
Then I set out to implement that. I figured that the easiest way to get the memory areas is to copy them from coreboot table. The problem in this approach was that multiboot table is written to memory before coreboot table is constructed, so there is nothing to copy.
To get around this, I changed the writing order so that coreboot table is written to memory first, and then multiboot table is copied from that. I hope this does not break any specification.
In any case, this resulted in a working BIOS e820 memory map for Linux, which can now be booted from Grub2.
I hope I could soon contribute a patch for this mainboard to the Coreboot project, but first I have to clean the code I have mangled back and forth.
Best Regards, Juhana Helovuo
It doesn't seem good that the Multiboot table gets written before the UMA and high table areas are added. I would think that's why they don't show up.
Yes, that was it, thanks for the advice.
I'm glad it helped.
I checked with coreinfo, and multiboot table did not have a clue about high tables area or UMA. Furthermore, it looked very much like the e820 table Linux was receiving.
Reading the source of multiboot table writer in Coreboot, it says in the comments that adding reserved memory areas is not yet implemented.
Then I set out to implement that. I figured that the easiest way to get the memory areas is to copy them from coreboot table. The problem in this approach was that multiboot table is written to memory before coreboot table is constructed, so there is nothing to copy.
To get around this, I changed the writing order so that coreboot table is written to memory first, and then multiboot table is copied from that. I hope this does not break any specification.
In any case, this resulted in a working BIOS e820 memory map for Linux, which can now be booted from Grub2.
I hope I could soon contribute a patch for this mainboard to the Coreboot project, but first I have to clean the code I have mangled back and forth.
I'd suggest a separate patch for the multiboot tables fix. I'm looking forward to seeing how you fixed it.
Thanks, Myles
Juhana Helovuo wrote:
Since the Linux boot process does not always crash at the same stage, I suspect that this may be some timing problem, such as the Super IO watchdog acting up again.
I would use memtest86 as payload and let it run over night.
//Peter
Juhana Helovuo said the following:
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested.
BTW, if it's not too hard, could you please share what value that register (IT8712F_CONFIG_REG_WATCHDOG) has before being reset to zero in it8712f_kill_watchdog? Thanks!
On Thu, 2010-07-29 at 20:14 +0300, Andriy Gapon wrote:
Juhana Helovuo said the following:
Meanwhile, I added call to it8712f_kill_watchdog() , like Rudolf Marek suggested.
BTW, if it's not too hard, could you please share what value that register (IT8712F_CONFIG_REG_WATCHDOG) has before being reset to zero in it8712f_kill_watchdog? Thanks!
Ok, but I am not sure how one is supposed to read the Super I/O registers, since there is only a write routine. I made an educated guess and wrote a read routine as follows:
Added in superio/ite/it8712f/it8712f_early_serial.c :
static uint8_t it8712f_sio_read(uint8_t ldn, uint8_t index) { outb(IT8712F_CONFIG_REG_LDN, SIO_BASE); outb(ldn, SIO_DATA); outb(index, SIO_BASE); return inb(SIO_DATA); }
uint8_t it8712f_kill_watchdog(void) { uint8_t prev_config; it8712f_enter_conf();
prev_config = it8712f_sio_read(0x07, IT8712F_CONFIG_REG_WATCHDOG);
/* Kill the Watchdog */ it8712f_sio_write(0x07, IT8712F_CONFIG_REG_WATCHDOG, 0x00);
it8712f_exit_conf(); return prev_config; }
Then in mainboard/asus/m4a785-m/romstage.c :
it8712f_enable_serial(0, CONFIG_TTYS0_BASE); watchdog_prev_config = it8712f_kill_watchdog(); /* disable watchdog, so it does not reset while still booting */ uart_init(); [...] printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx); printk(BIOS_DEBUG, "Super I/O Watchdog was killed. Previous WD config was %02x\n",watchdog_prev_config);
The result is:
coreboot-4.0-r5631M Fri Jul 30 21:27:07 EEST 2010 starting...
BSP Family_Model: 00100f62 *sysinfo range: [000cc000,000cdfa0] bsp_apicid = 00 cpu_init_detectedx = 00000000 Super I/O Watchdog was killed. Previous WD config was 30
Hope this makes sense, Juhana Helovuo