diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | bootstub.c | 4 | ||||
-rw-r--r-- | sfi.c | 80 | ||||
-rw-r--r-- | sfi.h | 58 |
4 files changed, 145 insertions, 2 deletions
@@ -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 @@ -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) @@ -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; +} + + @@ -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 */ |