From patchwork Thu Sep 9 16:12:55 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Add support for Asus M4A785-M, with build instructions Date: Thu, 09 Sep 2010 16:12:55 -0000 From: Juhana Helovuo X-Patchwork-Id: 1898 Message-Id: <1284048775.538.23.camel@bart> To: Myles Watson Cc: Scott , coreboot@coreboot.org On Sat, 2010-09-04 at 15:23 -0600, Myles Watson wrote: > It would be a lot easier to review if you split the patch into smaller pieces. > > 1. Use svn cp to copy the tilapia board directory for your board > 2. Make the changes so it works for your board (just copy the files > you already have from another location) > 3. svn diff > > This will produce a patch with only your changes. > > Split out work-around patches as well. Something is broken for your > board, and that needs to be fixed, but I don't think we should change > the PCI scan code. Ok, this makes sense. The previous patch I sent was unnecessarily large. There are now three smaller patches attached: (1) Changes specific to this board. Fairly small changes from AMD Tilapia. Requires (2) to work. (2) Small, hopefully non-intrusive, patches to generic code that are required to prevent hangups/crashes on this board. (3) Multiboot table patch required to get UMA and high coreboot tables locations to Grub and Linux. Independent of (1) and (2). Signed-off-by: Juhana Helovuo I tested appying these patches, building and flashing using the following procedure: 1. Check out Coreboot from SVN % svn co svn://coreboot.org/coreboot/trunk coreboot * The revision used here was 5792. 2. chdir to coreboot 3. svn cp src/mainboard/amd/tilapia_fam10 src/mainboard/asus/m4a785-m 4. patch % patch -p1 < ../patches/asus-m4a785m-small-patch.patch % patch -p1 < ../patches/multiboot-table-after-cb-table-r5756-v2.patch % patch -p1 < ../patches/generic-code-patches-for-m4a785m.patch 5. make menuconfig * Select mainboard vendor & model * ROM chip size 1 MByte * Select: Use VGA console once initialized * Select Use onboard VGA as primary video device * Add payload (grub2 and coreinfo tested to work) * Add VGA BIOS: The BIOS for the on-board ATI Radeon HD 4200 can be extracted with dd from /dev/mem as shown in http://www.coreboot.org/VGA_support . The bios_extract utility can extract some other option ROMs, but it crashes before it gets the VGA ROM. * If on-board VGA BIOS is added, set VGA device PCI IDs to "1002,9710" 6. make * The result should be a working coreboot.rom. This procedure worked for me. Can someone acknowledge that the patches do not break anything? The changes required in generic code are a bit ugly, but I am not familiar enough with Coreboot to figure out any neater solution. Best regards, Juhana Helovuo diff -u -r -N -x .svn coreboot.orig.r5756/src/arch/i386/boot/multiboot.c coreboot.r5756/src/arch/i386/boot/multiboot.c --- coreboot.orig.r5756/src/arch/i386/boot/multiboot.c 2010-08-31 05:11:34.000000000 +0300 +++ coreboot.r5756/src/arch/i386/boot/multiboot.c 2010-09-01 01:22:30.000000000 +0300 @@ -22,55 +22,13 @@ #include #include #include +#include +#include + static struct multiboot_mmap_entry *mb_mem; struct multiboot_info *mbi = NULL; -static struct { - u64 addr; - u64 len; -} reserved_mem[2]; - -static void build_mb_mem_range_nooverlap(u64 addr, u64 len) -{ - int i; - for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) { - /* free region fully contained in reserved region, abort */ - if (addr >= reserved_mem[i].addr && addr + len <= reserved_mem[i].addr + reserved_mem[i].len) - return; - /* reserved region splits free region */ - if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr + reserved_mem[i].len) { - build_mb_mem_range_nooverlap(addr, reserved_mem[i].addr - addr); - build_mb_mem_range_nooverlap(reserved_mem[i].addr + reserved_mem[i].len, (addr + len) - (reserved_mem[i].addr + reserved_mem[i].len)); - return; - } - /* left overlap */ - if (addr < reserved_mem[i].addr + reserved_mem[i].len && addr + len > reserved_mem[i].addr + reserved_mem[i].len) { - len += addr; - addr = reserved_mem[i].addr + reserved_mem[i].len; - len -= addr; - /* len += addr - old_addr */ - continue; - } - /* right overlap */ - if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr) { - len = reserved_mem[i].addr - addr; - continue; - } - /* none of the above, just add it */ - } - - mb_mem->addr = addr; - mb_mem->len = len; - mb_mem->type = 1; - mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size); - mb_mem++; -} - -static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res) -{ - build_mb_mem_range_nooverlap(res->base, res->size); -} #define ROUND(_r,_a) (((_r) + (((_a) - 1))) & ~((_a) - 1)) @@ -78,7 +36,11 @@ unsigned long low_table_start, unsigned long low_table_end, unsigned long rom_table_start, unsigned long rom_table_end) { + struct lb_memory* coreboot_table; + int entries; int i; + struct multiboot_mmap_entry *multiboot_mmap_table; + int mb_mem_count = 0; mbi = (struct multiboot_info *)rom_table_end; @@ -87,28 +49,45 @@ mbi->mmap_addr = (u32) rom_table_end; mb_mem = (struct multiboot_mmap_entry *)rom_table_end; + multiboot_mmap_table = mb_mem; // Save a copy for dumpig table later - /* FIXME This code is broken, it does not know about high memory - * tables, nor does it reserve the coreboot table area. - */ - /* reserved regions */ - reserved_mem[0].addr = low_table_start; - reserved_mem[0].len = ROUND(low_table_end - low_table_start, 4096); - reserved_mem[1].addr = rom_table_start; - reserved_mem[1].len = ROUND(rom_table_end - rom_table_start, 4096); - - for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) { - mb_mem->addr = reserved_mem[i].addr; - mb_mem->len = reserved_mem[i].len; - mb_mem->type = 2; - mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size); - mb_mem++; + /* copy regions from coreboot tables */ + coreboot_table = get_lb_mem(); + entries = (coreboot_table->size - sizeof(*coreboot_table))/sizeof(coreboot_table->map[0]); + + if (coreboot_table == NULL || entries < 1) { + printk(BIOS_INFO, "%s: Cannot find coreboot table for filling multiboot table.\n", + __FILE__); + return (unsigned long) mb_mem; } - /* free regions */ - search_global_resources( IORESOURCE_MEM | IORESOURCE_CACHEABLE, - IORESOURCE_MEM | IORESOURCE_CACHEABLE, build_mb_mem_range, NULL); - + for (i = 0; i < entries; i++) { + uint64_t entry_start = unpack_lb64(coreboot_table->map[i].start); + uint64_t entry_size = unpack_lb64(coreboot_table->map[i].size); + mb_mem->addr = entry_start; + mb_mem->len = entry_size; + switch (coreboot_table->map[i].type) { + case LB_MEM_RAM: + mb_mem->type = MULTIBOOT_MEMORY_AVAILABLE; + break; + default: + mb_mem->type = MULTIBOOT_MEMORY_RESERVED; // anything else than usable RAM + break; + } + mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size); + mb_mem++; + mb_mem_count++; + } + + printk(BIOS_DEBUG, "Multiboot memory table dump, %d entries.\n",mb_mem_count); + for (i = 0; i < mb_mem_count; i++) { + printk(BIOS_DEBUG, " %02d. %016llx %016llx : %s\n", i , + multiboot_mmap_table[i].addr, + multiboot_mmap_table[i].len, + (multiboot_mmap_table[i].type == 1 ? "RAM" : "RESERVED") + ); + } + mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr; mbi->flags |= MB_INFO_MEM_MAP; diff -u -r -N -x .svn coreboot.orig.r5756/src/arch/i386/boot/tables.c coreboot.r5756/src/arch/i386/boot/tables.c --- coreboot.orig.r5756/src/arch/i386/boot/tables.c 2010-08-31 05:11:34.000000000 +0300 +++ coreboot.r5756/src/arch/i386/boot/tables.c 2010-08-31 05:15:11.000000000 +0300 @@ -179,14 +179,6 @@ #endif -#if CONFIG_MULTIBOOT - post_code(0x9d); - - /* The Multiboot information structure */ - rom_table_end = write_multiboot_info( - low_table_start, low_table_end, - rom_table_start, rom_table_end); -#endif #define MAX_COREBOOT_TABLE_SIZE (8 * 1024) post_code(0x9d); @@ -210,7 +202,7 @@ new_high_table_pointer - high_table_pointer); } else { /* The coreboot table must be in 0-4K or 960K-1M */ - write_coreboot_table(low_table_start, low_table_end, + rom_table_end = write_coreboot_table(low_table_start, low_table_end, rom_table_start, rom_table_end); } @@ -224,6 +216,15 @@ cbmem_add(CBMEM_ID_RESUME, 1024 * (1024-64)); #endif +#if CONFIG_MULTIBOOT + post_code(0x9d); + + /* The Multiboot information structure */ + rom_table_end = write_multiboot_info( + low_table_start, low_table_end, + rom_table_start, rom_table_end); +#endif + // Remove before sending upstream cbmem_list(); diff -u -r -N -x .svn coreboot.orig.r5756/src/include/cpu/x86/multiboot.h coreboot.r5756/src/include/cpu/x86/multiboot.h --- coreboot.orig.r5756/src/include/cpu/x86/multiboot.h 2010-08-31 05:11:34.000000000 +0300 +++ coreboot.r5756/src/include/cpu/x86/multiboot.h 2010-08-31 05:15:11.000000000 +0300 @@ -167,6 +167,9 @@ uint16_t vbe_interface_len; }; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 + struct multiboot_mmap_entry { uint32_t size; uint64_t addr;