summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2009-06-01 11:23:28 +0800
committerPatrick Tjin <pattjin@google.com>2014-07-21 20:22:39 -0700
commit7cc52cde55aa85061da67d64212e036ac74d9e73 (patch)
tree8b7a558f1c76b2cef950a440a5b5b6136930703a
parenta24ea5cfb4209b37f8d42f9ed5584ae9cce85bfc (diff)
downloadbootstub-7cc52cde55aa85061da67d64212e036ac74d9e73.tar.gz
SFI: use sfi mmap table to build a e820 table for boot_parameters
Signed-off-by: Feng Tang <feng.tang@intel.com>
-rw-r--r--Makefile5
-rw-r--r--bootstub.c4
-rw-r--r--sfi.c80
-rw-r--r--sfi.h58
4 files changed, 145 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 8e1f045..d6d69fa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-OBJ=bootstub.o spi-uart.o head.o
+OBJ=bootstub.o spi-uart.o head.o sfi.o
CFLAGS=-ffreestanding -Wall
#for cross compile
#CFLAGS=-m32 -ffreestanding -Wall
@@ -20,6 +20,9 @@ bootstub.o:bootstub.c bootstub.h
spi-uart.o:spi-uart.c spi-uart.h
gcc $(CFLAGS) -c spi-uart.c
+sfi.o:sfi.c
+ gcc $(CFLAGS) -c sfi.c
+
head.o:head.S bootstub.h
gcc $(CFLAGS) -c head.S
diff --git a/bootstub.c b/bootstub.c
index e6f0183..74b8753 100644
--- a/bootstub.c
+++ b/bootstub.c
@@ -21,6 +21,7 @@
#include "bootstub.h"
#include "bootparam.h"
#include "spi-uart.h"
+#include "sfi.h"
#define bs_printk(x) { if (! *(int *)SPI_UART_SUPPRESSION) bs_spi_printk(x);}
@@ -95,7 +96,6 @@ static size_t strnlen(const char *s, size_t maxlen)
return (es - s);
}
-
static void setup_boot_params(struct boot_params *bp, struct setup_header *sh)
{
memset(bp, 0, sizeof (struct boot_params));
@@ -111,6 +111,8 @@ static void setup_boot_params(struct boot_params *bp, struct setup_header *sh)
bp->hdr.ramdisk_image = (bp->alt_mem_k*1024 - bp->hdr.ramdisk_size) & 0xFFFFF000;
bp->hdr.hardware_subarch = X86_SUBARCH_MRST;
memcpy((u8*)bp->hdr.ramdisk_image, (u8 *)BZIMAGE_OFFSET + *(u32 *)BZIMAGE_SIZE_OFFSET, bp->hdr.ramdisk_size);
+
+ sfi_setup_e820(bp);
}
static int get_32bit_entry(unsigned char *ptr)
diff --git a/sfi.c b/sfi.c
new file mode 100644
index 0000000..001360f
--- /dev/null
+++ b/sfi.c
@@ -0,0 +1,80 @@
+#include "types.h"
+#include "bootparam.h"
+#include "bootstub.h"
+#include "spi-uart.h"
+#include "sfi.h"
+
+#define bs_printk(x) { if (!*(int *)SPI_UART_SUPPRESSION) bs_spi_printk(x); }
+
+#define SFI_BASE_ADDR 0x000E0000
+#define SFI_LENGTH 0x00020000
+
+static unsigned long sfi_search_mmap(unsigned long start, int len)
+{
+ unsigned long i = 0;
+ char *pchar = (char *)start;
+
+ for (i = 0; i < len; i += 4, pchar += 4) {
+ if (pchar[0] == 'M'
+ && pchar[1] == 'M'
+ && pchar[2] == 'A'
+ && pchar[3] == 'P')
+ return start + i;
+ }
+ return 0;
+}
+
+void sfi_setup_e820(struct boot_params *bp)
+{
+ struct sfi_table *sb;
+ struct sfi_mem_entry *mentry;
+ unsigned long long start, end, size;
+ int i, num, type, total;
+
+ bp->e820_entries = 0;
+ total = 0;
+
+ /* search for sfi mmap table */
+ sb = (struct sfi_table *)sfi_search_mmap(SFI_BASE_ADDR, SFI_LENGTH);
+ if (!sb)
+ return;
+
+ bs_printk("Bootstub: will use sfi mmap table for e820 table\n");
+ num = SFI_GET_ENTRY_NUM(sb, sfi_mem_entry);
+ mentry = (struct sfi_mem_entry *)sb->pentry;
+
+ for (i = 0; i < num; i++) {
+ start = mentry->phy_start;
+ size = mentry->pages << 12;
+ end = start + size;
+
+ if (start > end)
+ continue;
+
+ /* translate SFI mmap type to E820 map type */
+ switch (mentry->type) {
+ case SFI_MEM_CONV:
+ type = E820_RAM;
+ break;
+ case SFI_MEM_MMIO:
+ case SFI_MEM_UNUSABLE:
+ case SFI_RUNTIME_SERVICE_DATA:
+ mentry++;
+ continue;
+ default:
+ type = E820_RESERVED;
+ }
+
+ if (total == E820MAX)
+ break;
+ bp->e820_map[total].addr = start;
+ bp->e820_map[total].size = size;
+ bp->e820_map[total++].type = type;
+
+ mentry++;
+ }
+
+ bp->e820_entries = total;
+}
+
+
diff --git a/sfi.h b/sfi.h
new file mode 100644
index 0000000..f190f96
--- /dev/null
+++ b/sfi.h
@@ -0,0 +1,58 @@
+#ifndef _SFI_H
+#define _SFI_H
+
+/* Memory type definitions */
+enum sfi_mem_type {
+ SFI_MEM_RESERVED,
+ SFI_LOADER_CODE,
+ SFI_LOADER_DATA,
+ SFI_BOOT_SERVICE_CODE,
+ SFI_BOOT_SERVICE_DATA,
+ SFI_RUNTIME_SERVICE_CODE,
+ SFI_RUNTIME_SERVICE_DATA,
+ SFI_MEM_CONV,
+ SFI_MEM_UNUSABLE,
+ SFI_ACPI_RECLAIM,
+ SFI_ACPI_NVS,
+ SFI_MEM_MMIO,
+ SFI_MEM_IOPORT,
+ SFI_PAL_CODE,
+ SFI_MEM_TYPEMAX,
+};
+
+struct sfi_mem_entry {
+ enum sfi_mem_type type;
+ u64 phy_start;
+ u64 vir_start;
+ u64 pages;
+ u64 attrib;
+};
+
+struct sfi_table_header {
+ char signature[4];
+ u32 length;
+ u8 revision;
+ u8 checksum;
+ char oem_id[6];
+ char oem_table_id[8];
+};
+
+struct sfi_table {
+ struct sfi_table_header header;
+ u64 pentry[1];
+};
+
+#define SFI_TBL_HEADER_LEN 24
+
+#define SFI_GET_ENTRY_NUM(ptable, entry) \
+ ((ptable->header.length - SFI_TBL_HEADER_LEN) / \
+ (sizeof(struct entry)))
+
+#define E820_RAM 1
+#define E820_RESERVED 2
+#define E820_ACPI 3
+#define E820_NVS 4
+#define E820_UNUSABLE 5
+
+extern void sfi_setup_e820(struct boot_params *bp);
+#endif /* _SFI_H */