Beispiel #1
0
static void do_ptr(char *dest, char *src, uint32_t offset, uint8_t size)
{
	char *p, *q;
	int id;
	union {
		long long ll;
		char b[8];
	} data;

	id = fw_cfg_file_id(src);
	p = id_to_addr(id);
	if (!p)
		panic();

	id = fw_cfg_file_id(dest);
	q = id_to_addr(id);
	if (!q)
		panic();

	q += offset;

	/* Assumes little endian */
	data.ll = 0;
	memcpy(&data.b, q, size);
	data.ll += (uintptr_t) p;
	memcpy(q, &data.b, size);
}
Beispiel #2
0
void extract_acpi(void)
{
	int id = fw_cfg_file_id("etc/table-loader");
	int n = fw_cfg_file_size(id);
	struct loader_cmd script[n / sizeof(struct loader_cmd)];
	int i;

	if (!n)
		return;

	fw_cfg_read_file(id, script, n);

	for (i = 0; i < ARRAY_SIZE(script); i++) {
		struct loader_cmd *s = &script[i];
		switch(script[i].cmd) {
		case CMD_ALLOC:
			do_alloc(s->alloc.file, s->alloc.align, s->alloc.zone);
			break;
		case CMD_PTR:
			do_ptr(s->ptr.dest, s->ptr.src, s->ptr.offset, s->ptr.size);
			break;
		case CMD_CHECKSUM:
			do_checksum(s->checksum.file, s->checksum.offset,
				    s->checksum.start, s->checksum.len);
			break;
		case CMD_QUIT:
			return;
		default:
			panic();
		}
	}
}
Beispiel #3
0
static void do_alloc(char *file, uint32_t align, uint8_t zone)
{
	int id = fw_cfg_file_id(file);
	int n = fw_cfg_file_size(id);
	char *p;

	if (id == -1)
		panic();

	if (align < 16)
		align = 16;

	if (zone == ALLOC_FSEG)
		p = malloc_fseg_align(n, align);
	else
		p = malloc_align(n, align);

	set_file_addr(id, p);
	fw_cfg_read_file(id, p, n);

	/* For PVH boot, save the PA where the RSDP is stored */
	if (zone == ALLOC_FSEG) {
		if (!memcmp(p, "RSD PTR ", 8)) {
			start_info.rsdp_paddr = (uintptr_t)id_to_addr(id);
		}
	}
}
Beispiel #4
0
static void do_checksum(char *file, uint32_t offset, uint32_t start, uint32_t len)
{
	uint8_t *p;
	int id;
	int n;

	id = fw_cfg_file_id(file);
	p = id_to_addr(id);
	if (!p)
		panic();

	n = fw_cfg_file_size(id);
	if (offset >= n || n < start || len > n - start)
		panic();

	p[offset] -= csum8(&p[start], len);
}
Beispiel #5
0
static void extract_e820(void)
{
	int id = fw_cfg_file_id("etc/e820");
	uint32_t size;
	int nr_map;
	int i;

	if (id == -1)
		panic();

	size = fw_cfg_file_size(id);
	nr_map = size / sizeof(e820->map[0]) + 4;
	fw_cfg_file_select(id);

	e820 = malloc(offsetof(struct e820map, map[nr_map]));
	e820->nr_map = nr_map;
	e820->map[0] = (struct e820entry)
		{ .addr = 0, .size = 639 * 1024, .type = E820_RAM }; /* low RAM */
	e820->map[1] = (struct e820entry)
		{ .addr = 639 * 1024, .size = 1024, .type = E820_RESERVED }; /* EBDA */
	e820->map[2] = (struct e820entry)
		{ .addr = 0xd0000, .size = 128 * 1024, .type = E820_NVS }; /* ACPI tables */
	e820->map[3] = (struct e820entry)
		{ .addr = 0xf0000, .size = 64 * 1024, .type = E820_RESERVED }; /* firmware */
	fw_cfg_read(&e820->map[4], size);
	for (i = 4; i < e820->nr_map; i++)
		if (e820->map[i].addr == 0) {
			lowmem = e820->map[i].size;
			e820->map[i].addr = 1024 * 1024;
			e820->map[i].size -= 1024 * 1024;
			break;
		}

	e820_seg = ((uintptr_t) e820) >> 4;
}

static bool detect_cbfs_and_boot(void)
{
	size_t sz;
	void *base = pflash_base(1, &sz);

	if (!base)
		return false;

	return boot_from_cbfs(base, sz);
}

int main(void)
{
	setup_hw();

	// Now go to the F-segment: we need to move away from flash area
	// in order to probe CBFS!
	asm("ljmp $0x8, $1f; 1:");

	setup_pci();
	setup_idt();
	fw_cfg_setup();
	extract_acpi();
	extract_e820();
	// extract_smbios();
	if (!detect_cbfs_and_boot())
		boot_from_fwcfg();
	panic();
}