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