Patchwork Update Coreboot support in Memtest86+ 4.10

login
register
about
Submitter Juhana Helovuo
Date 2010-12-10 19:54:18
Message ID <4D02856A.7010900@iki.fi>
Download mbox | patch
Permalink /patch/2415/
State New
Headers show

Comments

Juhana Helovuo - 2010-12-10 19:54:18
Hello All,

Here is a patch to make Memtest86+ 4.10 to work with current Coreboot.

The patch is almost the same as in
http://www.coreboot.org/pipermail/coreboot/2010-January/055358.html
and
http://www.coreboot.org/pipermail/coreboot/2010-January/055382.html .

However, the original version did not quite work for me, so I had to 
modify it slightly.

In addition to upgrading Coreboot support, this patch makes the 
following changes in Memtest86+:
* Do not use build host header files, but supply our own.
* Make the build process work on case-insensitive file system.

Before applying the patch, two source files must be renamed:
% mv linuxbios.c coreboot.c
% mv linuxbios_tables.h coreboot_tables.h

I have tested this on Qemu and Asus M4A78-EM with coreboot and SeaBIOS.
Memtest86+ ELF executable was added to CBFS as img/memtest and started 
from SeaBIOS boot menu. Additionally, I tested on Qemu with only 
Coreboot + VGA BIOS and Memtest86+ directly as payload.

If anyone cares to test this on their hardware, please report if this 
works for you.

Best regards,
Juhana Helovuo

Patch

diff -Naur memtest86+-4.10.renamed/coreboot.c memtest86+-4.10.j/coreboot.c
--- memtest86+-4.10.renamed/coreboot.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/coreboot.c	2010-12-07 21:45:16.000000000 +0200
@@ -1,4 +1,4 @@ 
-#include "linuxbios_tables.h"
+#include "coreboot_tables.h"
 #include "test.h"
 
 static unsigned long ip_compute_csum(void *addr, unsigned long length)
@@ -53,32 +53,32 @@ 
 	
 }
 
-#define for_each_lbrec(head, rec) \
-	for(rec = (struct lb_record *)(((char *)head) + sizeof(*head)); \
+#define for_each_cbrec(head, rec) \
+	for(rec = (struct cb_record *)(((char *)head) + sizeof(*head)); \
 		(((char *)rec) < (((char *)head) + sizeof(*head) + head->table_bytes))  && \
 		(rec->size >= 1) && \
 		((((char *)rec) + rec->size) <= (((char *)head) + sizeof(*head) + head->table_bytes)); \
-		rec = (struct lb_record *)(((char *)rec) + rec->size)) 
+		rec = (struct cb_record *)(((char *)rec) + rec->size)) 
 		
 
-static int count_lb_records(struct lb_header *head)
+static int count_cb_records(struct cb_header *head)
 {
-	struct lb_record *rec;
+	struct cb_record *rec;
 	int count;
 	count = 0;
-	for_each_lbrec(head, rec) {
+	for_each_cbrec(head, rec) {
 		count++;
 	}
 	return count;
 }
 
-static struct lb_header * __find_lb_table(unsigned long start, unsigned long end)
+static struct cb_header * __find_cb_table(unsigned long start, unsigned long end)
 {
 	unsigned long addr;
 	/* For now be stupid.... */
 	for(addr = start; addr < end; addr += 16) {
-		struct lb_header *head = (struct lb_header *)addr;
-		struct lb_record *recs = (struct lb_record *)(addr + sizeof(*head));
+		struct cb_header *head = (struct cb_header *)addr;
+		struct cb_record *recs = (struct cb_record *)(addr + sizeof(*head));
 		if (memcmp(head->signature, "LBIO", 4) != 0)
 			continue;
 		if (head->header_bytes != sizeof(*head))
@@ -88,42 +88,62 @@ 
 		if (ip_compute_csum((unsigned char *)recs, head->table_bytes) 
 			!= head->table_checksum)
 			continue;
-		if (count_lb_records(head) != head->table_entries)
+		if (count_cb_records(head) != head->table_entries)
 			continue;
 		return head;
 	};
 	return 0;
 }
 
-static struct lb_header * find_lb_table(void)
+static struct cb_header * find_cb_table(void)
 {
-	struct lb_header *head;
+	struct cb_header *head;
+	struct cb_record *rec;
+	struct cb_forward *forward;
 	head = 0;
 	if (!head) {
 		/* First try at address 0 */
-		head = __find_lb_table(0x00000, 0x1000);
+		head = __find_cb_table(0x00000, 0x1000);
 	}
 	if (!head) {
 		/* Then try at address 0xf0000 */
-		head = __find_lb_table(0xf0000, 0x100000);
+		head = __find_cb_table(0xf0000, 0x100000);
 	}
+	forward = 0;
+	if (head) {
+		/* Check whether there is a forward header */
+		for_each_cbrec(head, rec) {
+			if (rec->tag == CB_TAG_FORWARD) {
+				forward = (struct cb_forward *)rec;
+				break;
+			}
+		}
+	}
+	if (forward) {
+		/* if there is, all valid information is in the 
+		 * referenced coreboot table
+		 */
+		head = __find_cb_table(forward->forward, 
+				       forward->forward + 0x1000);
+	}
+
 	return head;
 }
 
-int query_linuxbios(void)
+int query_coreboot(void)
 {
-	struct lb_header *head;
-	struct lb_record *rec;
-	struct lb_memory *mem;
+	struct cb_header *head;
+	struct cb_record *rec;
+	struct cb_memory *mem;
 	int i, entries;
-	head = find_lb_table();
+	head = find_cb_table();
 	if (!head) {
 		return 0;
 	}
 	mem = 0;
-	for_each_lbrec(head, rec) {
-		if (rec->tag == LB_TAG_MEMORY) {
-			mem = (struct lb_memory *)rec;
+	for_each_cbrec(head, rec) {
+		if (rec->tag == CB_TAG_MEMORY) {
+			mem = (struct cb_memory *)rec;
 			break;
 		}
 	}
@@ -143,7 +163,7 @@ 
 		}
 		start = mem->map[i].start;
 		size = mem->map[i].size;
-		type = (mem->map[i].type == LB_MEM_RAM)?E820_RAM: E820_RESERVED;
+		type = (mem->map[i].type == CB_MEM_RAM)?E820_RAM: E820_RESERVED;
 		mem_info.e820[mem_info.e820_nr].addr = start;
 		mem_info.e820[mem_info.e820_nr].size = size;
 		mem_info.e820[mem_info.e820_nr].type = type;
diff -Naur memtest86+-4.10.renamed/coreboot_tables.h memtest86+-4.10.j/coreboot_tables.h
--- memtest86+-4.10.renamed/coreboot_tables.h	2010-12-10 20:47:33.000000000 +0200
+++ memtest86+-4.10.j/coreboot_tables.h	2010-12-07 21:40:19.000000000 +0200
@@ -1,9 +1,9 @@ 
-#ifndef LINUXBIOS_TABLES_H
-#define LINUXBIOS_TABLES_H
+#ifndef COREBOOT_TABLES_H
+#define COREBOOT_TABLES_H
 
 #include "stdint.h"
 
-/* The linuxbios table information is for conveying information
+/* The coreboot table information is for conveying information
  * from the firmware to the loaded OS image.  Primarily this
  * is expected to be information that cannot be discovered by
  * other means, such as quering the hardware directly.
@@ -32,7 +32,7 @@ 
  */
 
 
-struct lb_header
+struct cb_header
 {
 	uint8_t  signature[4]; /* LBIO */
 	uint32_t header_bytes;
@@ -48,35 +48,39 @@ 
  * boot enviroment record if you don't know what it easy.  This allows
  * forward compatibility with records not yet defined.
  */
-struct lb_record {
+struct cb_record {
 	uint32_t tag;		/* tag ID */
 	uint32_t size;		/* size of record (in bytes) */
 };
 
-#define LB_TAG_UNUSED	0x0000
+#define CB_TAG_UNUSED	0x0000
 
-#define LB_TAG_MEMORY	0x0001
+#define CB_TAG_MEMORY	0x0001
 
-struct lb_memory_range {
+struct cb_memory_range {
 	uint64_t start;
 	uint64_t size;
 	uint32_t type;
-#define LB_MEM_RAM      1
-#define LB_MEM_RESERVED 2
-	
+#define CB_MEM_RAM		 1	/* Memory anyone can use */
+#define CB_MEM_RESERVED		 2	/* Don't use this memory region */
+#define CB_MEM_ACPI		 3	/* ACPI Tables */
+#define CB_MEM_NVS		 4	/* ACPI NVS Memory */
+#define CB_MEM_UNUSABLE		 5	/* Unusable address space */
+#define CB_MEM_VENDOR_RSVD	 6	/* Vendor Reserved */
+#define CB_MEM_TABLE		16	/* Ram configuration tables are kept in */
 };
 
-struct lb_memory {
+struct cb_memory {
 	uint32_t tag;
 	uint32_t size;
-	struct lb_memory_range map[0];
+	struct cb_memory_range map[0];
 };
 
-#define LB_TAG_HWRPB	0x0002
-struct lb_hwrpb {
+#define CB_TAG_FORWARD	0x0011
+struct cb_forward {
 	uint32_t tag;
 	uint32_t size;
-	uint64_t hwrpb;
+	uint64_t forward;
 };
 
-#endif /* LINUXBIOS_TABLES_H */
+#endif /* COREBOOT_TABLES_H */
diff -Naur memtest86+-4.10.renamed/dmi.c memtest86+-4.10.j/dmi.c
--- memtest86+-4.10.renamed/dmi.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/dmi.c	2010-12-07 21:40:19.000000000 +0200
@@ -10,7 +10,7 @@ 
 
 
 #include "test.h"
-#include <stdint.h>
+#include "types.h"
 
 
 #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
diff -Naur memtest86+-4.10.renamed/error.c memtest86+-4.10.j/error.c
--- memtest86+-4.10.renamed/error.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/error.c	2010-12-07 21:40:19.000000000 +0200
@@ -11,7 +11,6 @@ 
  
 #include "test.h"
 #include "config.h"
-#include <sys/io.h>
 #include "dmi.h"
 #define NULL 0
 
diff -Naur memtest86+-4.10.renamed/init.c memtest86+-4.10.j/init.c
--- memtest86+-4.10.renamed/init.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/init.c	2010-12-10 20:30:10.000000000 +0200
@@ -98,11 +98,11 @@ 
 	/* Determine the memory map */
 	if ((firmware == FIRMWARE_UNKNOWN) &&
 		(memsz_mode != SZ_MODE_PROBE)) {
-		if (query_linuxbios()) {
-			firmware = FIRMWARE_LINUXBIOS;
+	if (query_coreboot()) {
+			firmware = FIRMWARE_COREBOOT;
 		}
 		else if (query_pcbios()) {
-			firmware = FIRMWARE_PCBIOS;
+		    firmware = FIRMWARE_PCBIOS;
 		}
 	}
 
diff -Naur memtest86+-4.10.renamed/io.h memtest86+-4.10.j/io.h
--- memtest86+-4.10.renamed/io.h	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/io.h	2010-12-10 20:11:19.000000000 +0200
@@ -116,4 +116,18 @@ 
 ((__builtin_constant_p((port)) && (port) < 256) ? \
 	__inlc(port) : \
 	__inl(port))
+
+/* for test.c, but probably all IO functions should be declared explicitly */
+static inline unsigned char inb_p(unsigned short port)
+{
+	unsigned char value;
+	__asm__ __volatile__("inb %w1,%b0\noutb %%al,$0x80" : "=a"(value) : "Nd"(port));
+	return value;
+}
+
+static inline void outb_p(unsigned char value, unsigned short port)
+{
+	  __asm__ __volatile__ ("outb %b0,%w1\noutb %%al,$0x80" : : "a"(value), "Nd"(port));
+}
+
 #endif
diff -Naur memtest86+-4.10.renamed/Makefile memtest86+-4.10.j/Makefile
--- memtest86+-4.10.renamed/Makefile	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/Makefile	2010-12-07 21:42:35.000000000 +0200
@@ -10,11 +10,12 @@ 
 
 AS=as -32
 CC=gcc
+OBJCOPY=$(CROSS)objcopy
 
 CFLAGS= -Wall -march=i486 -m32 -O2 -fomit-frame-pointer -fno-builtin -ffreestanding -fPIC -fno-stack-protector
 
-OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
-      config.o linuxbios.o memsize.o pci.o controller.o random.o spd.o \
+OBJS= head.pre.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
+      config.o coreboot.o memsize.o pci.o controller.o random.o spd.o \
       error.o dmi.o cpuid.o
 
 all: memtest.bin memtest
@@ -28,22 +29,22 @@ 
 	$(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS)
 
 memtest_shared.bin: memtest_shared
-	objcopy -O binary $< memtest_shared.bin
+	$(OBJCOPY) -O binary $< memtest_shared.bin
 
 memtest: memtest_shared.bin memtest.lds
 	$(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@
 
-head.s: head.S config.h defs.h test.h
+head.pre.s: head.S config.h defs.h test.h
 	$(CC) -E -traditional $< -o $@
 
-bootsect.s: bootsect.S config.h defs.h
+bootsect.pre.s: bootsect.S config.h defs.h
 	$(CC) -E -traditional $< -o $@
 
-setup.s: setup.S config.h defs.h
+setup.pre.s: setup.S config.h defs.h
 	$(CC) -E -traditional $< -o $@
 
-memtest.bin: memtest_shared.bin bootsect.o setup.o memtest.bin.lds
-	$(LD) -T memtest.bin.lds bootsect.o setup.o -b binary \
+memtest.bin: memtest_shared.bin bootsect.pre.o setup.pre.o memtest.bin.lds
+	$(LD) -T memtest.bin.lds bootsect.pre.o setup.pre.o -b binary \
 	memtest_shared.bin -o memtest.bin
 
 reloc.o: reloc.c
@@ -53,7 +54,7 @@ 
 	$(CC) -c -Wall -march=i486 -m32 -Os -fomit-frame-pointer -fno-builtin -ffreestanding test.c
 
 clean:
-	rm -f *.o *.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin
+	rm -f *.o *.pre.s *.iso memtest.bin memtest memtest_shared memtest_shared.bin
 
 asm:
 	@./makedos.sh
@@ -68,7 +69,7 @@ 
 
 install-precomp:
 	dd <precomp.bin >$(FDISK) bs=8192
-	
+
 dos: all
 	cat mt86+_loader memtest.bin > memtest.exe
 
diff -Naur memtest86+-4.10.renamed/memsize.c memtest86+-4.10.j/memsize.c
--- memtest86+-4.10.renamed/memsize.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/memsize.c	2010-12-07 21:45:27.000000000 +0200
@@ -26,7 +26,7 @@ 
 static void memsize_801(void);
 static int sanitize_e820_map(struct e820entry *orig_map,
 	struct e820entry *new_bios, short old_nr);
-static void memsize_linuxbios();
+static void memsize_coreboot(void);
 static void memsize_probe(void);
 static int check_ram(void);
 
@@ -78,8 +78,8 @@ 
 	if (firmware == FIRMWARE_PCBIOS) {
 		memsize_820();
 	}
-	else if (firmware == FIRMWARE_LINUXBIOS) {
-		memsize_linuxbios();
+	else if (firmware == FIRMWARE_COREBOOT) {
+		memsize_coreboot();
 	}
 }
 
@@ -107,7 +107,7 @@ 
 		}
 	}
 }
-static void memsize_linuxbios(void)
+static void memsize_coreboot(void)
 {
 	int i, n;
 	/* Build the memory map for testing */
@@ -125,7 +125,7 @@ 
 		n++;
 	}
 	v->msegs = n;
-	cprint(LINE_INFO, COL_MMAP, "LxBIOS");
+	cprint(LINE_INFO, COL_MMAP, "coreboot");
 }
 static void memsize_820()
 {
diff -Naur memtest86+-4.10.renamed/memtest.lds memtest86+-4.10.j/memtest.lds
--- memtest86+-4.10.renamed/memtest.lds	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/memtest.lds	2010-12-10 20:28:13.000000000 +0200
@@ -3,9 +3,11 @@ 
 
 ENTRY(_start); 
 SECTIONS {
-	. = 0x5000;

+	. = 0x100000;

 	_start = . ;
 	.data : {
 		*(.data)
 	}
+	_end = . ;

+	_syssize = (_end - _start + 15) >> 4; 

 }
diff -Naur memtest86+-4.10.renamed/reloc.c memtest86+-4.10.j/reloc.c
--- memtest86+-4.10.renamed/reloc.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/reloc.c	2010-12-07 21:40:19.000000000 +0200
@@ -1,7 +1,6 @@ 
 #include <stddef.h>
 #include "stdint.h"
 #include "elf.h"
-#include <string.h>
 
 #define __ELF_NATIVE_CLASS 32
 #define ELF_MACHINE_NO_RELA 1
diff -Naur memtest86+-4.10.renamed/test.c memtest86+-4.10.j/test.c
--- memtest86+-4.10.renamed/test.c	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/test.c	2010-12-07 21:40:19.000000000 +0200
@@ -11,9 +11,9 @@ 
 
 #include "test.h"
 #include "config.h"
-#include <sys/io.h>
+#include "io.h"
 #include "dmi.h"
-#include <inttypes.h>
+#include "types.h"
 
 extern int segs, bail;
 extern volatile ulong *p;
diff -Naur memtest86+-4.10.renamed/test.h memtest86+-4.10.j/test.h
--- memtest86+-4.10.renamed/test.h	2010-12-10 20:47:32.000000000 +0200
+++ memtest86+-4.10.j/test.h	2010-12-07 21:40:19.000000000 +0200
@@ -104,7 +104,7 @@ 
 int memcmp(const void *s1, const void *s2, ulong count);
 int strncmp(const char *s1, const char *s2, ulong n);
 void *memmove(void *dest, const void *src, ulong n);
-int query_linuxbios(void);
+int query_coreboot(void);
 int query_pcbios(void);
 int insertaddress(ulong);
 void printpatn(void);
@@ -350,7 +350,7 @@ 
 
 #define FIRMWARE_UNKNOWN   0
 #define FIRMWARE_PCBIOS    1
-#define FIRMWARE_LINUXBIOS 2
+#define FIRMWARE_COREBOOT  2
 
 extern struct vars * const v;
 extern unsigned char _start[], _end[], startup_32[];
@@ -364,4 +364,4 @@ 
 #define CPM_SEQ    3
 
 #endif /* __ASSEMBLY__ */
-#endif /* _TEST_H_ */
\ No newline at end of file
+#endif /* _TEST_H_ */
diff -Naur memtest86+-4.10.renamed/types.h memtest86+-4.10.j/types.h
--- memtest86+-4.10.renamed/types.h	1970-01-01 02:00:00.000000000 +0200
+++ memtest86+-4.10.j/types.h	2010-12-10 20:29:11.000000000 +0200
@@ -0,0 +1,9 @@ 
+/* memtest86+ is self contained, so it may not use system include files */
+/* These definitions are 32-bit versions from Debian Linux "squeeze" /usr/include/stdint.h */
+typedef unsigned int uintptr_t; /* There is no * here */
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;