sfi.c revision 33a7a35843afcacfefbc075371c5a7647611c5b2
1#include "types.h" 2#include "bootparam.h" 3#include "bootstub.h" 4#include "spi-uart.h" 5#include "sfi.h" 6 7#define bs_printk(x) { if (!*(int *)SPI_UART_SUPPRESSION) bs_spi_printk(x); } 8 9#define SFI_BASE_ADDR 0x000E0000 10#define SFI_LENGTH 0x00020000 11 12static unsigned long sfi_search_mmap(unsigned long start, int len) 13{ 14 unsigned long i = 0; 15 char *pchar = (char *)start; 16 17 for (i = 0; i < len; i += 4, pchar += 4) { 18 if (pchar[0] == 'M' 19 && pchar[1] == 'M' 20 && pchar[2] == 'A' 21 && pchar[3] == 'P') 22 return start + i; 23 } 24 return 0; 25} 26 27void sfi_setup_e820(struct boot_params *bp) 28{ 29 struct sfi_table *sb; 30 struct sfi_mem_entry *mentry; 31 unsigned long long start, end, size; 32 int i, num, type, total; 33 34 bp->e820_entries = 0; 35 total = 0; 36 37 /* search for sfi mmap table */ 38 sb = (struct sfi_table *)sfi_search_mmap(SFI_BASE_ADDR, SFI_LENGTH); 39 if (!sb) 40 return; 41 42 bs_printk("Bootstub: will use sfi mmap table for e820 table\n"); 43 num = SFI_GET_ENTRY_NUM(sb, sfi_mem_entry); 44 mentry = (struct sfi_mem_entry *)sb->pentry; 45 46 for (i = 0; i < num; i++) { 47 start = mentry->phy_start; 48 size = mentry->pages << 12; 49 end = start + size; 50 51 if (start > end) 52 continue; 53 54 /* translate SFI mmap type to E820 map type */ 55 switch (mentry->type) { 56 case SFI_MEM_CONV: 57 type = E820_RAM; 58 break; 59 case SFI_MEM_UNUSABLE: 60 case SFI_RUNTIME_SERVICE_DATA: 61 mentry++; 62 continue; 63 default: 64 type = E820_RESERVED; 65 } 66 67 if (total == E820MAX) 68 break; 69 bp->e820_map[total].addr = start; 70 bp->e820_map[total].size = size; 71 bp->e820_map[total++].type = type; 72 73 mentry++; 74 } 75 76 bp->e820_entries = total; 77} 78 79 80