I found another bug in LAR handling of the option table by staring at
the logs. (Yes, I read logs.)
Looking at the log of a qemu x86 boot, I'd say something is really
broken. Look at the excerpts of my log quoted below:
> [...]
> LAR: Attempting to open 'fallback/initram/segment0'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: seen member normal/initram/segment0
> LAR: seen member bootblock
> LAR: File not found!
> [...]
> LAR: Attempting to open 'normal/initram/segment0'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: seen member normal/initram/segment0
> LAR: CHECK normal/initram/segment0 @ 0xfff040d0
> [...]
> LAR: Attempting to open 'normal/stage2/segment0'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: CHECK normal/stage2/segment0 @ 0xfff00400
> [...]
> LAR: Attempting to open 'normal/stage2/segment1'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: CHECK normal/stage2/segment1 @ 0xfff004c0
> [...]
> LAR: Attempting to open 'normal/stage2/segment2'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: CHECK normal/stage2/segment2 @ 0xfff03f40
> [...]
> LAR: Attempting to open 'normal/stage2/segment3'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: seen member normal/initram/segment0
> LAR: seen member bootblock
> LAR: File not found!
> [...]
> LAR: Attempting to open 'normal/option_table'.
> LAR: Start 0xfffc0000 len 0x3c000

WTF?!? This start address is obviously very wrong.

> LAR: seen member bootblock
> LAR: File not found!

Which results in not finding the option table.

> [...]
> LAR: Attempting to open 'normal/payload'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: seen member normal/initram/segment0
> LAR: seen member bootblock
> LAR: File not found!
> [...]
> LAR: Attempting to open 'normal/payload/segment0'.
> LAR: Start 0xfff00000 len 0x100000
> LAR: seen member normal/option_table
> LAR: seen member normal/stage2/segment0
> LAR: seen member normal/stage2/segment1
> LAR: seen member normal/stage2/segment2
> LAR: seen member normal/initram/segment0
> LAR: seen member bootblock
> LAR: File not found!
> [...]

Short version of the above:
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfffc0000 len 0x3c000 <------BUG!
> LAR: Start 0xfff00000 len 0x100000
> LAR: Start 0xfff00000 len 0x100000

The bug is in arch/x86/mc146818rtc.c:

> struct cmos_option_table *get_option_table(void)
> {
>       struct mem_file result, archive;
>       int ret;
>
>       // FIXME - i want to be dynamic.
>       archive.len=(CONFIG_COREBOOT_ROMSIZE_KB-16)*1024;

len is wrong.

>       archive.start=(void *)(0UL-(CONFIG_COREBOOT_ROMSIZE_KB*1024)); 

start is even more wrong.

>       ret = find_file(&archive, "normal/option_table", &result);
>       if (ret) {
>               printk(BIOS_ERR, "No such file '%s'.\n",
>                               "normal/option_table");
>               return (struct cmos_option_table *)NULL;
>       }
>       return (struct cmos_option_table *) result.start;
> }

Use the existing init_archive function to find the LAR in memory.
This fixes the case where the option table was not found depending
on a few unrelated parameters.

Signed-off-by: Carl-Daniel Hailfinger <[EMAIL PROTECTED]>


Index: LinuxBIOSv3-optiontable/arch/x86/mc146818rtc.c
===================================================================
--- LinuxBIOSv3-optiontable/arch/x86/mc146818rtc.c      (Revision 583)
+++ LinuxBIOSv3-optiontable/arch/x86/mc146818rtc.c      (Arbeitskopie)
@@ -183,9 +183,7 @@
        struct mem_file result, archive;
        int ret;
 
-       // FIXME - i want to be dynamic.
-       archive.len=(CONFIG_COREBOOT_ROMSIZE_KB-16)*1024;
-       archive.start=(void *)(0UL-(CONFIG_COREBOOT_ROMSIZE_KB*1024)); 
+       init_archive(&archive);
 
        ret = find_file(&archive, "normal/option_table", &result);
        if (ret) {


Regards,
Carl-Daniel

-- 
http://www.hailfinger.org/


-- 
coreboot mailing list
[email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to