summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/avr32/cpu/at32ap700x/mmu.c2
-rw-r--r--arch/x86/cpu/coreboot/Makefile58
-rw-r--r--arch/x86/cpu/coreboot/asm-offsets.c25
-rw-r--r--arch/x86/cpu/coreboot/coreboot_car.S29
-rw-r--r--arch/x86/cpu/coreboot/ipchecksum.c54
-rw-r--r--arch/x86/cpu/coreboot/sdram.c75
-rw-r--r--arch/x86/cpu/coreboot/sysinfo.c39
-rw-r--r--arch/x86/cpu/coreboot/tables.c183
-rw-r--r--arch/x86/include/asm/arch-coreboot/ipchecksum.h37
-rw-r--r--arch/x86/include/asm/arch-coreboot/sysinfo.h63
-rw-r--r--arch/x86/include/asm/arch-coreboot/tables.h241
-rw-r--r--arch/x86/include/asm/zimage.h36
-rw-r--r--arch/x86/lib/bootm.c21
-rw-r--r--arch/x86/lib/zimage.c276
14 files changed, 1011 insertions, 128 deletions
diff --git a/arch/avr32/cpu/at32ap700x/mmu.c b/arch/avr32/cpu/at32ap700x/mmu.c
index c3a1b93..0e28b21 100644
--- a/arch/avr32/cpu/at32ap700x/mmu.c
+++ b/arch/avr32/cpu/at32ap700x/mmu.c
@@ -22,7 +22,7 @@ void mmu_init_r(unsigned long dest_addr)
*/
vmr_table_addr = (uintptr_t)&mmu_vmr_table;
sysreg_write(PTBR, vmr_table_addr);
- printf("VMR table @ 0x%08x\n", vmr_table_addr);
+ printf("VMR table @ 0x%08lx\n", vmr_table_addr);
/* Enable paging */
sysreg_write(MMUCR, SYSREG_BF(DRP, 1) | SYSREG_BF(DLA, 1)
diff --git a/arch/x86/cpu/coreboot/Makefile b/arch/x86/cpu/coreboot/Makefile
new file mode 100644
index 0000000..13f5f8a
--- /dev/null
+++ b/arch/x86/cpu/coreboot/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (c) 2011 The Chromium OS Authors.
+#
+# (C) Copyright 2008
+# Graeme Russ, graeme.russ@gmail.com.
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2002
+# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)lib$(SOC).o
+
+COBJS-$(CONFIG_SYS_COREBOOT) += tables.o
+COBJS-$(CONFIG_SYS_COREBOOT) += ipchecksum.o
+COBJS-$(CONFIG_SYS_COREBOOT) += sdram.o
+COBJS-$(CONFIG_SYS_COREBOOT) += sysinfo.o
+
+SOBJS-$(CONFIG_SYS_COREBOOT) += coreboot_car.o
+
+SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+
+all: $(obj).depend $(LIB)
+
+$(LIB): $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/x86/cpu/coreboot/asm-offsets.c b/arch/x86/cpu/coreboot/asm-offsets.c
new file mode 100644
index 0000000..97937da
--- /dev/null
+++ b/arch/x86/cpu/coreboot/asm-offsets.c
@@ -0,0 +1,25 @@
+/*
+ * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <common.h>
+#include <linux/kbuild.h>
+
+int main(void)
+{
+ DEFINE(GENERATED_GD_RELOC_OFF, offsetof(gd_t, reloc_off));
+ return 0;
+}
diff --git a/arch/x86/cpu/coreboot/coreboot_car.S b/arch/x86/cpu/coreboot/coreboot_car.S
new file mode 100644
index 0000000..3cc2575
--- /dev/null
+++ b/arch/x86/cpu/coreboot/coreboot_car.S
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010-2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+.section .text
+
+.globl car_init
+car_init:
+ jmp car_init_ret
diff --git a/arch/x86/cpu/coreboot/ipchecksum.c b/arch/x86/cpu/coreboot/ipchecksum.c
new file mode 100644
index 0000000..57733d8
--- /dev/null
+++ b/arch/x86/cpu/coreboot/ipchecksum.c
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * It has originally been taken from the FreeBSD project.
+ *
+ * Copyright (c) 2001 Charles Mott <cm@linktel.net>
+ * Copyright (c) 2008 coresystems GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <compiler.h>
+#include <asm/arch-coreboot/ipchecksum.h>
+
+unsigned short ipchksum(const void *vptr, unsigned long nbytes)
+{
+ int sum, oddbyte;
+ const unsigned short *ptr = vptr;
+
+ sum = 0;
+ while (nbytes > 1) {
+ sum += *ptr++;
+ nbytes -= 2;
+ }
+ if (nbytes == 1) {
+ oddbyte = 0;
+ ((u8 *)&oddbyte)[0] = *(u8 *) ptr;
+ ((u8 *)&oddbyte)[1] = 0;
+ sum += oddbyte;
+ }
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ return ~sum;
+}
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
new file mode 100644
index 0000000..f8fdac6
--- /dev/null
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2010,2011
+ * Graeme Russ, <graeme.russ@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/e820.h>
+#include <asm/u-boot-x86.h>
+#include <asm/global_data.h>
+#include <asm/arch-coreboot/sysinfo.h>
+#include <asm/arch-coreboot/tables.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
+{
+ int i;
+
+ unsigned num_entries = min(lib_sysinfo.n_memranges, max_entries);
+ if (num_entries < lib_sysinfo.n_memranges) {
+ printf("Warning: Limiting e820 map to %d entries.\n",
+ num_entries);
+ }
+ for (i = 0; i < num_entries; i++) {
+ struct memrange *memrange = &lib_sysinfo.memrange[i];
+
+ entries[i].addr = memrange->base;
+ entries[i].size = memrange->size;
+ entries[i].type = memrange->type;
+ }
+ return num_entries;
+}
+
+int dram_init_f(void)
+{
+ int i;
+ phys_size_t ram_size = 0;
+
+ for (i = 0; i < lib_sysinfo.n_memranges; i++) {
+ struct memrange *memrange = &lib_sysinfo.memrange[i];
+ unsigned long long end = memrange->base + memrange->size;
+
+ if (memrange->type == CB_MEM_RAM && end > ram_size)
+ ram_size = end;
+ }
+ gd->ram_size = ram_size;
+ if (ram_size == 0)
+ return -1;
+ return 0;
+}
+
+int dram_init(void)
+{
+ return 0;
+}
diff --git a/arch/x86/cpu/coreboot/sysinfo.c b/arch/x86/cpu/coreboot/sysinfo.c
new file mode 100644
index 0000000..9b3e660
--- /dev/null
+++ b/arch/x86/cpu/coreboot/sysinfo.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <asm/arch-coreboot/sysinfo.h>
+
+/*
+ * This needs to be in the .data section so that it's copied over during
+ * relocation. By default it's put in the .bss section which is simply filled
+ * with zeroes when transitioning from "ROM", which is really RAM, to other
+ * RAM.
+ */
+struct sysinfo_t lib_sysinfo __attribute__((section(".data")));
diff --git a/arch/x86/cpu/coreboot/tables.c b/arch/x86/cpu/coreboot/tables.c
new file mode 100644
index 0000000..0e3451b
--- /dev/null
+++ b/arch/x86/cpu/coreboot/tables.c
@@ -0,0 +1,183 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <asm/arch-coreboot/ipchecksum.h>
+#include <asm/arch-coreboot/sysinfo.h>
+#include <asm/arch-coreboot/tables.h>
+
+/*
+ * Some of this is x86 specific, and the rest of it is generic. Right now,
+ * since we only support x86, we'll avoid trying to make lots of infrastructure
+ * we don't need. If in the future, we want to use coreboot on some other
+ * architecture, then take out the generic parsing code and move it elsewhere.
+ */
+
+/* === Parsing code === */
+/* This is the generic parsing code. */
+
+static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_memory *mem = (struct cb_memory *)ptr;
+ int count = MEM_RANGE_COUNT(mem);
+ int i;
+
+ if (count > SYSINFO_MAX_MEM_RANGES)
+ count = SYSINFO_MAX_MEM_RANGES;
+
+ info->n_memranges = 0;
+
+ for (i = 0; i < count; i++) {
+ struct cb_memory_range *range =
+ (struct cb_memory_range *)MEM_RANGE_PTR(mem, i);
+
+ info->memrange[info->n_memranges].base =
+ UNPACK_CB64(range->start);
+
+ info->memrange[info->n_memranges].size =
+ UNPACK_CB64(range->size);
+
+ info->memrange[info->n_memranges].type = range->type;
+
+ info->n_memranges++;
+ }
+}
+
+static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_serial *ser = (struct cb_serial *)ptr;
+ if (ser->type != CB_SERIAL_TYPE_IO_MAPPED)
+ return;
+ info->ser_ioport = ser->baseaddr;
+}
+
+static void cb_parse_optiontable(unsigned char *ptr, struct sysinfo_t *info)
+{
+ info->option_table = (struct cb_cmos_option_table *)ptr;
+}
+
+static void cb_parse_checksum(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cmos_checksum *cmos_cksum = (struct cb_cmos_checksum *)ptr;
+ info->cmos_range_start = cmos_cksum->range_start;
+ info->cmos_range_end = cmos_cksum->range_end;
+ info->cmos_checksum_location = cmos_cksum->location;
+}
+
+static void cb_parse_framebuffer(unsigned char *ptr, struct sysinfo_t *info)
+{
+ info->framebuffer = (struct cb_framebuffer *)ptr;
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+ struct cb_header *header;
+ unsigned char *ptr = (unsigned char *)addr;
+ int i;
+
+ for (i = 0; i < len; i += 16, ptr += 16) {
+ header = (struct cb_header *)ptr;
+ if (!strncmp((const char *)header->signature, "LBIO", 4))
+ break;
+ }
+
+ /* We walked the entire space and didn't find anything. */
+ if (i >= len)
+ return -1;
+
+ if (!header->table_bytes)
+ return 0;
+
+ /* Make sure the checksums match. */
+ if (ipchksum((u16 *) header, sizeof(*header)) != 0)
+ return -1;
+
+ if (ipchksum((u16 *) (ptr + sizeof(*header)),
+ header->table_bytes) != header->table_checksum)
+ return -1;
+
+ /* Now, walk the tables. */
+ ptr += header->header_bytes;
+
+ for (i = 0; i < header->table_entries; i++) {
+ struct cb_record *rec = (struct cb_record *)ptr;
+
+ /* We only care about a few tags here (maybe more later). */
+ switch (rec->tag) {
+ case CB_TAG_FORWARD:
+ return cb_parse_header(
+ (void *)(unsigned long)
+ ((struct cb_forward *)rec)->forward,
+ len, info);
+ continue;
+ case CB_TAG_MEMORY:
+ cb_parse_memory(ptr, info);
+ break;
+ case CB_TAG_SERIAL:
+ cb_parse_serial(ptr, info);
+ break;
+ case CB_TAG_CMOS_OPTION_TABLE:
+ cb_parse_optiontable(ptr, info);
+ break;
+ case CB_TAG_OPTION_CHECKSUM:
+ cb_parse_checksum(ptr, info);
+ break;
+ /*
+ * FIXME we should warn on serial if coreboot set up a
+ * framebuffer buf the payload does not know about it.
+ */
+ case CB_TAG_FRAMEBUFFER:
+ cb_parse_framebuffer(ptr, info);
+ break;
+ }
+
+ ptr += rec->size;
+ }
+
+ return 1;
+}
+
+/* == Architecture specific == */
+/* This is the x86 specific stuff. */
+
+/* Assume no translation or that memory is identity mapped. */
+static void *phys_to_virt(unsigned long virt)
+{
+ return (void *)(uintptr_t)virt;
+}
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ int ret = cb_parse_header(phys_to_virt(0x00000000), 0x1000, info);
+
+ if (ret != 1)
+ ret = cb_parse_header(phys_to_virt(0x000f0000), 0x1000, info);
+
+ return (ret == 1) ? 0 : -1;
+}
diff --git a/arch/x86/include/asm/arch-coreboot/ipchecksum.h b/arch/x86/include/asm/arch-coreboot/ipchecksum.h
new file mode 100644
index 0000000..1d73b4d
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/ipchecksum.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * It has originally been taken from the FreeBSD project.
+ *
+ * Copyright (c) 2001 Charles Mott <cm@linktel.net>
+ * Copyright (c) 2008 coresystems GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COREBOOT_IPCHECKSUM_H
+#define _COREBOOT_IPCHECKSUM_H
+
+unsigned short ipchksum(const void *vptr, unsigned long nbytes);
+
+#endif
diff --git a/arch/x86/include/asm/arch-coreboot/sysinfo.h b/arch/x86/include/asm/arch-coreboot/sysinfo.h
new file mode 100644
index 0000000..5c44e1a
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/sysinfo.h
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COREBOOT_SYSINFO_H
+#define _COREBOOT_SYSINFO_H
+
+#include <compiler.h>
+
+/* Allow a maximum of 16 memory range definitions. */
+#define SYSINFO_MAX_MEM_RANGES 16
+
+struct sysinfo_t {
+ unsigned int cpu_khz;
+ unsigned short ser_ioport;
+ unsigned long ser_base; /* for mmapped serial */
+
+ int n_memranges;
+
+ struct memrange {
+ unsigned long long base;
+ unsigned long long size;
+ unsigned int type;
+ } memrange[SYSINFO_MAX_MEM_RANGES];
+
+ struct cb_cmos_option_table *option_table;
+ u32 cmos_range_start;
+ u32 cmos_range_end;
+ u32 cmos_checksum_location;
+
+ struct cb_framebuffer *framebuffer;
+
+ unsigned long *mbtable; /** Pointer to the multiboot table */
+};
+
+extern struct sysinfo_t lib_sysinfo;
+
+#endif
diff --git a/arch/x86/include/asm/arch-coreboot/tables.h b/arch/x86/include/asm/arch-coreboot/tables.h
new file mode 100644
index 0000000..c286973
--- /dev/null
+++ b/arch/x86/include/asm/arch-coreboot/tables.h
@@ -0,0 +1,241 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COREBOOT_TABLES_H
+#define _COREBOOT_TABLES_H
+
+#include <compiler.h>
+
+struct cbuint64 {
+ u32 lo;
+ u32 hi;
+};
+
+struct cb_header {
+ u8 signature[4];
+ u32 header_bytes;
+ u32 header_checksum;
+ u32 table_bytes;
+ u32 table_checksum;
+ u32 table_entries;
+};
+
+struct cb_record {
+ u32 tag;
+ u32 size;
+};
+
+#define CB_TAG_UNUSED 0x0000
+#define CB_TAG_MEMORY 0x0001
+
+struct cb_memory_range {
+ struct cbuint64 start;
+ struct cbuint64 size;
+ u32 type;
+};
+
+#define CB_MEM_RAM 1
+#define CB_MEM_RESERVED 2
+#define CB_MEM_ACPI 3
+#define CB_MEM_NVS 4
+#define CB_MEM_UNUSABLE 5
+#define CB_MEM_VENDOR_RSVD 6
+#define CB_MEM_TABLE 16
+
+struct cb_memory {
+ u32 tag;
+ u32 size;
+ struct cb_memory_range map[0];
+};
+
+#define CB_TAG_HWRPB 0x0002
+
+struct cb_hwrpb {
+ u32 tag;
+ u32 size;
+ u64 hwrpb;
+};
+
+#define CB_TAG_MAINBOARD 0x0003
+
+struct cb_mainboard {
+ u32 tag;
+ u32 size;
+ u8 vendor_idx;
+ u8 part_number_idx;
+ u8 strings[0];
+};
+
+#define CB_TAG_VERSION 0x0004
+#define CB_TAG_EXTRA_VERSION 0x0005
+#define CB_TAG_BUILD 0x0006
+#define CB_TAG_COMPILE_TIME 0x0007
+#define CB_TAG_COMPILE_BY 0x0008
+#define CB_TAG_COMPILE_HOST 0x0009
+#define CB_TAG_COMPILE_DOMAIN 0x000a
+#define CB_TAG_COMPILER 0x000b
+#define CB_TAG_LINKER 0x000c
+#define CB_TAG_ASSEMBLER 0x000d
+
+struct cb_string {
+ u32 tag;
+ u32 size;
+ u8 string[0];
+};
+
+#define CB_TAG_SERIAL 0x000f
+
+struct cb_serial {
+ u32 tag;
+ u32 size;
+#define CB_SERIAL_TYPE_IO_MAPPED 1
+#define CB_SERIAL_TYPE_MEMORY_MAPPED 2
+ u32 type;
+ u32 baseaddr;
+ u32 baud;
+};
+
+#define CB_TAG_CONSOLE 0x00010
+
+struct cb_console {
+ u32 tag;
+ u32 size;
+ u16 type;
+};
+
+#define CB_TAG_CONSOLE_SERIAL8250 0
+#define CB_TAG_CONSOLE_VGA 1 /* OBSOLETE */
+#define CB_TAG_CONSOLE_BTEXT 2 /* OBSOLETE */
+#define CB_TAG_CONSOLE_LOGBUF 3
+#define CB_TAG_CONSOLE_SROM 4 /* OBSOLETE */
+#define CB_TAG_CONSOLE_EHCI 5
+
+#define CB_TAG_FORWARD 0x00011
+
+struct cb_forward {
+ u32 tag;
+ u32 size;
+ u64 forward;
+};
+
+#define CB_TAG_FRAMEBUFFER 0x0012
+struct cb_framebuffer {
+ u32 tag;
+ u32 size;
+
+ u64 physical_address;
+ u32 x_resolution;
+ u32 y_resolution;
+ u32 bytes_per_line;
+ u8 bits_per_pixel;
+ u8 red_mask_pos;
+ u8 red_mask_size;
+ u8 green_mask_pos;
+ u8 green_mask_size;
+ u8 blue_mask_pos;
+ u8 blue_mask_size;
+ u8 reserved_mask_pos;
+ u8 reserved_mask_size;
+};
+
+#define CB_TAG_CMOS_OPTION_TABLE 0x00c8
+struct cb_cmos_option_table {
+ u32 tag;
+ u32 size;
+ u32 header_length;
+};
+
+#define CB_TAG_OPTION 0x00c9
+#define CMOS_MAX_NAME_LENGTH 32
+struct cb_cmos_entries {
+ u32 tag;
+ u32 size;
+ u32 bit;
+ u32 length;
+ u32 config;
+ u32 config_id;
+ u8 name[CMOS_MAX_NAME_LENGTH];
+};
+
+
+#define CB_TAG_OPTION_ENUM 0x00ca
+#define CMOS_MAX_TEXT_LENGTH 32
+struct cb_cmos_enums {
+ u32 tag;
+ u32 size;
+ u32 config_id;
+ u32 value;
+ u8 text[CMOS_MAX_TEXT_LENGTH];
+};
+
+#define CB_TAG_OPTION_DEFAULTS 0x00cb
+#define CMOS_IMAGE_BUFFER_SIZE 128
+struct cb_cmos_defaults {
+ u32 tag;
+ u32 size;
+ u32 name_length;
+ u8 name[CMOS_MAX_NAME_LENGTH];
+ u8 default_set[CMOS_IMAGE_BUFFER_SIZE];
+};
+
+#define CB_TAG_OPTION_CHECKSUM 0x00cc
+#define CHECKSUM_NONE 0
+#define CHECKSUM_PCBIOS 1
+struct cb_cmos_checksum {
+ u32 tag;
+ u32 size;
+ u32 range_start;
+ u32 range_end;
+ u32 location;
+ u32 type;
+};
+
+/* Helpful macros */
+
+#define MEM_RANGE_COUNT(_rec) \
+ (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))
+
+#define MEM_RANGE_PTR(_rec, _idx) \
+ (((u8 *) (_rec)) + sizeof(*(_rec)) \
+ + (sizeof((_rec)->map[0]) * (_idx)))
+
+#define MB_VENDOR_STRING(_mb) \
+ (((unsigned char *) ((_mb)->strings)) + (_mb)->vendor_idx)
+
+#define MB_PART_STRING(_mb) \
+ (((unsigned char *) ((_mb)->strings)) + (_mb)->part_number_idx)
+
+#define UNPACK_CB64(_in) \
+ ((((u64) _in.hi) << 32) | _in.lo)
+
+struct sysinfo_t;
+
+int get_coreboot_info(struct sysinfo_t *info);
+
+#endif
diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h
index a02637f..f03ea80 100644
--- a/arch/x86/include/asm/zimage.h
+++ b/arch/x86/include/asm/zimage.h
@@ -24,30 +24,12 @@
#ifndef _ASM_ZIMAGE_H_
#define _ASM_ZIMAGE_H_
+#include <asm/bootparam.h>
+#include <asm/e820.h>
+
/* linux i386 zImage/bzImage header. Offsets relative to
* the start of the image */
-#define CMD_LINE_MAGIC_OFF 0x020 /* Magic 0xa33f if the offset below is valid */
-#define CMD_LINE_OFFSET_OFF 0x022 /* Offset to comandline */
-#define SETUP_SECTS_OFF 0x1F1 /* The size of the setup in sectors */
-#define ROOT_FLAGS_OFF 0x1F2 /* If set, the root is mounted readonly */
-#define VID_MODE_OFF 0x1FA /* Video mode control */
-#define ROOT_DEV_OFF 0x1FC /* Default root device number */
-#define BOOT_FLAG_OFF 0x1FE /* 0xAA55 magic number */
-#define HEADER_OFF 0x202 /* Magic signature "HdrS" */
-#define VERSION_OFF 0x206 /* Boot protocol version supported */
-#define REALMODE_SWTCH_OFF 0x208 /* Boot loader hook (see below) */
-#define START_SYS_OFF 0x20C /* Points to kernel version string */
-#define TYPE_OF_LOADER_OFF 0x210 /* Boot loader identifier */
-#define LOADFLAGS_OFF 0x211 /* Boot protocol option flags */
-#define SETUP_MOVE_SIZE_OFF 0x212 /* Move to high memory size (used with hooks) */
-#define CODE32_START_OFF 0x214 /* Boot loader hook (see below) */
-#define RAMDISK_IMAGE_OFF 0x218 /* initrd load address (set by boot loader) */
-#define RAMDISK_SIZE_OFF 0x21C /* initrd size (set by boot loader) */
-#define HEAP_END_PTR_OFF 0x224 /* Free memory after setup end */
-#define CMD_LINE_PTR_OFF 0x228 /* 32-bit pointer to the kernel command line */
-
-
#define HEAP_FLAG 0x80
#define BIG_KERNEL_FLAG 0x01
@@ -65,10 +47,14 @@
#define BZIMAGE_LOAD_ADDR 0x100000
#define ZIMAGE_LOAD_ADDR 0x10000
-void *load_zimage(char *image, unsigned long kernel_size,
- unsigned long initrd_addr, unsigned long initrd_size,
- int auto_boot);
+/* Implementation defined function to install an e820 map. */
+unsigned install_e820_map(unsigned max_entries, struct e820entry *);
+
+struct boot_params *load_zimage(char *image, unsigned long kernel_size,
+ void **load_address);
+int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
+ unsigned long initrd_addr, unsigned long initrd_size);
-void boot_zimage(void *setup_base);
+void boot_zimage(void *setup_base, void *load_address);
#endif
diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c
index bac7b4f..83caf6b 100644
--- a/arch/x86/lib/bootm.c
+++ b/arch/x86/lib/bootm.c
@@ -28,16 +28,20 @@
#include <command.h>
#include <image.h>
#include <u-boot/zlib.h>
+#include <asm/bootparam.h>
#include <asm/byteorder.h>
#include <asm/zimage.h>
+#define COMMAND_LINE_OFFSET 0x9000
+
/*cmd_boot.c*/
int do_bootm_linux(int flag, int argc, char * const argv[],
bootm_headers_t *images)
{
- void *base_ptr = NULL;
- ulong os_data, os_len;
- image_header_t *hdr;
+ struct boot_params *base_ptr = NULL;
+ ulong os_data, os_len;
+ image_header_t *hdr;
+ void *load_address;
#if defined(CONFIG_FIT)
const void *data;
@@ -74,14 +78,19 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
}
#ifdef CONFIG_CMD_ZBOOT
- base_ptr = load_zimage((void *)os_data, os_len,
- images->rd_start, images->rd_end - images->rd_start, 0);
+ base_ptr = load_zimage((void *)os_data, os_len, &load_address);
#endif
if (NULL == base_ptr) {
printf("## Kernel loading failed ...\n");
goto error;
+ }
+ if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
+ 0, images->rd_start,
+ images->rd_end - images->rd_start)) {
+ printf("## Setting up boot parameters failed ...\n");
+ goto error;
}
#ifdef DEBUG
@@ -92,7 +101,7 @@ int do_bootm_linux(int flag, int argc, char * const argv[],
/* we assume that the kernel is in place */
printf("\nStarting kernel ...\n\n");
- boot_zimage(base_ptr);
+ boot_zimage(base_ptr, load_address);
/* does not return */
error:
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 8b42b5c..bb40517 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2011 The Chromium OS Authors.
* (C) Copyright 2002
* Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
*
@@ -51,6 +52,16 @@
#define COMMAND_LINE_SIZE 2048
+unsigned generic_install_e820_map(unsigned max_entries,
+ struct e820entry *entries)
+{
+ return 0;
+}
+
+unsigned install_e820_map(unsigned max_entries,
+ struct e820entry *entries)
+ __attribute__((weak, alias("generic_install_e820_map")));
+
static void build_command_line(char *command_line, int auto_boot)
{
char *env_command_line;
@@ -78,40 +89,47 @@ static void build_command_line(char *command_line, int auto_boot)
printf("Kernel command line: \"%s\"\n", command_line);
}
-void *load_zimage(char *image, unsigned long kernel_size,
- unsigned long initrd_addr, unsigned long initrd_size,
- int auto_boot)
+static int kernel_magic_ok(struct setup_header *hdr)
{
- void *setup_base;
- int setup_size;
- int bootproto;
- int big_image;
- void *load_address;
- struct setup_header *hdr;
-
- hdr = (struct setup_header *)(image + SETUP_SECTS_OFF);
-
- /* base address for real-mode segment */
- setup_base = (void *)DEFAULT_SETUP_BASE;
-
if (KERNEL_MAGIC != hdr->boot_flag) {
- printf("Error: Invalid Boot Flag (found 0x%04x, expected 0x%04x)\n",
- hdr->boot_flag, KERNEL_MAGIC);
+ printf("Error: Invalid Boot Flag "
+ "(found 0x%04x, expected 0x%04x)\n",
+ hdr->boot_flag, KERNEL_MAGIC);
return 0;
} else {
printf("Valid Boot Flag\n");
+ return 1;
}
+}
- /* determine boot protocol version */
- if (KERNEL_V2_MAGIC == hdr->header) {
+static int get_boot_protocol(struct setup_header *hdr)
+{
+ if (hdr->header == KERNEL_V2_MAGIC) {
printf("Magic signature found\n");
-
- bootproto = hdr->version;
+ return hdr->version;
} else {
/* Very old kernel */
printf("Magic signature not found\n");
- bootproto = 0x0100;
+ return 0x0100;
}
+}
+
+struct boot_params *load_zimage(char *image, unsigned long kernel_size,
+ void **load_address)
+{
+ struct boot_params *setup_base;
+ int setup_size;
+ int bootproto;
+ int big_image;
+
+ struct boot_params *params = (struct boot_params *)image;
+ struct setup_header *hdr = &params->hdr;
+
+ /* base address for real-mode segment */
+ setup_base = (struct boot_params *)DEFAULT_SETUP_BASE;
+
+ if (!kernel_magic_ok(hdr))
+ return 0;
/* determine size of setup */
if (0 == hdr->setup_sects) {
@@ -126,27 +144,50 @@ void *load_zimage(char *image, unsigned long kernel_size,
if (setup_size > SETUP_MAX_SIZE)
printf("Error: Setup is too large (%d bytes)\n", setup_size);
+ /* determine boot protocol version */
+ bootproto = get_boot_protocol(hdr);
+
+ printf("Using boot protocol version %x.%02x\n",
+ (bootproto & 0xff00) >> 8, bootproto & 0xff);
+
+ if (bootproto >= 0x0200) {
+ if (hdr->setup_sects >= 15) {
+ printf("Linux kernel version %s\n",
+ (char *)params +
+ hdr->kernel_version + 0x200);
+ } else {
+ printf("Setup Sectors < 15 - "
+ "Cannot print kernel version.\n");
+ }
+ }
+
/* Determine image type */
big_image = (bootproto >= 0x0200) &&
(hdr->loadflags & BIG_KERNEL_FLAG);
/* Determine load address */
- load_address = (void *)(big_image ?
- BZIMAGE_LOAD_ADDR :
- ZIMAGE_LOAD_ADDR);
+ if (big_image)
+ *load_address = (void *)BZIMAGE_LOAD_ADDR;
+ else
+ *load_address = (void *)ZIMAGE_LOAD_ADDR;
+#if defined CONFIG_ZBOOT_32
+ printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
+ memset(setup_base, 0, sizeof(*setup_base));
+ setup_base->hdr = params->hdr;
+#else
/* load setup */
printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n",
(ulong)setup_base, setup_size);
memmove(setup_base, image, setup_size);
+#endif
- printf("Using boot protocol version %x.%02x\n",
- (bootproto & 0xff00) >> 8, bootproto & 0xff);
+ if (bootproto >= 0x0204)
+ kernel_size = hdr->syssize * 16;
+ else
+ kernel_size -= setup_size;
if (bootproto == 0x0100) {
- *(u16 *)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
- *(u16 *)(setup_base + CMD_LINE_OFFSET_OFF) = COMMAND_LINE_OFFSET;
-
/*
* A very old kernel MUST have its real-mode code
* loaded at 0x90000
@@ -157,33 +198,60 @@ void *load_zimage(char *image, unsigned long kernel_size,
/* Copy the command line */
memmove((void *)0x99000,
- setup_base + COMMAND_LINE_OFFSET,
+ (u8 *)setup_base + COMMAND_LINE_OFFSET,
COMMAND_LINE_SIZE);
/* Relocated */
- setup_base = (void *)0x90000;
+ setup_base = (struct boot_params *)0x90000;
}
/* It is recommended to clear memory up to the 32K mark */
- memset((void *)0x90000 + setup_size, 0,
- SETUP_MAX_SIZE-setup_size);
+ memset((u8 *)0x90000 + setup_size, 0,
+ SETUP_MAX_SIZE - setup_size);
}
- /* We are now setting up the real-mode version of the header */
- hdr = (struct setup_header *)(setup_base + SETUP_SECTS_OFF);
+ if (big_image) {
+ if (kernel_size > BZIMAGE_MAX_SIZE) {
+ printf("Error: bzImage kernel too big! "
+ "(size: %ld, max: %d)\n",
+ kernel_size, BZIMAGE_MAX_SIZE);
+ return 0;
+ }
+ } else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
+ printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
+ kernel_size, ZIMAGE_MAX_SIZE);
+ return 0;
+ }
+
+ printf("Loading %s at address %p (%ld bytes)\n",
+ big_image ? "bzImage" : "zImage", *load_address, kernel_size);
+
+ memmove(*load_address, image + setup_size, kernel_size);
+
+ return setup_base;
+}
+
+int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
+ unsigned long initrd_addr, unsigned long initrd_size)
+{
+ struct setup_header *hdr = &setup_base->hdr;
+ int bootproto = get_boot_protocol(hdr);
+
+#if defined CONFIG_ZBOOT_32
+ setup_base->e820_entries = install_e820_map(
+ ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
+#endif
+ if (bootproto == 0x0100) {
+ setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
+ setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET;
+ }
if (bootproto >= 0x0200) {
hdr->type_of_loader = 8;
- if (hdr->setup_sects >= 15)
- printf("Linux kernel version %s\n",
- (char *)(setup_base +
- (hdr->kernel_version + 0x200)));
- else
- printf("Setup Sectors < 15 - Cannot print kernel version.\n");
-
if (initrd_addr) {
- printf("Initial RAM disk at linear address 0x%08lx, size %ld bytes\n",
+ printf("Initial RAM disk at linear address "
+ "0x%08lx, size %ld bytes\n",
initrd_addr, initrd_size);
hdr->ramdisk_image = initrd_addr;
@@ -197,49 +265,42 @@ void *load_zimage(char *image, unsigned long kernel_size,
}
if (bootproto >= 0x0202) {
- hdr->cmd_line_ptr = (u32)setup_base + COMMAND_LINE_OFFSET;
+ hdr->cmd_line_ptr = (uintptr_t)cmd_line;
} else if (bootproto >= 0x0200) {
-
- *(u16 *)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
- *(u16 *)(setup_base + CMD_LINE_OFFSET_OFF) = COMMAND_LINE_OFFSET;
+ setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
+ setup_base->screen_info.cl_offset =
+ (uintptr_t)cmd_line - (uintptr_t)setup_base;
hdr->setup_move_size = 0x9100;
}
- if (bootproto >= 0x0204)
- kernel_size = hdr->syssize * 16;
- else
- kernel_size -= setup_size;
-
-
- if (big_image) {
- if ((kernel_size) > BZIMAGE_MAX_SIZE) {
- printf("Error: bzImage kernel too big! (size: %ld, max: %d)\n",
- kernel_size, BZIMAGE_MAX_SIZE);
- return 0;
- }
-
- } else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
- printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
- kernel_size, ZIMAGE_MAX_SIZE);
- return 0;
- }
-
/* build command line at COMMAND_LINE_OFFSET */
- build_command_line(setup_base + COMMAND_LINE_OFFSET, auto_boot);
-
- printf("Loading %czImage at address 0x%08x (%ld bytes)\n",
- big_image ? 'b' : ' ', (u32)load_address, kernel_size);
-
-
- memmove(load_address, image + setup_size, kernel_size);
-
- /* ready for booting */
- return setup_base;
+ build_command_line(cmd_line, auto_boot);
+ return 0;
}
-void boot_zimage(void *setup_base)
+void boot_zimage(void *setup_base, void *load_address)
{
+ printf("\nStarting kernel ...\n\n");
+
+#if defined CONFIG_ZBOOT_32
+ /*
+ * Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params
+ * structure, and then jump to the kernel. We assume that %cs is
+ * 0x10, 4GB flat, and read/execute, and the data segments are 0x18,
+ * 4GB flat, and read/write. U-boot is setting them up that way for
+ * itself in arch/i386/cpu/cpu.c.
+ */
+ __asm__ __volatile__ (
+ "movl $0, %%ebp \n"
+ "cli \n"
+ "jmp %[kernel_entry] \n"
+ :: [kernel_entry]"a"(load_address),
+ [boot_params] "S"(setup_base),
+ "b"(0), "D"(0)
+ : "%ebp"
+ );
+#else
struct pt_regs regs;
memset(&regs, 0, sizeof(struct pt_regs));
@@ -248,56 +309,79 @@ void boot_zimage(void *setup_base)
regs.xss = regs.xds;
regs.esp = 0x9000;
regs.eflags = 0;
- enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, &regs,
- &regs);
+ enter_realmode(((u32)setup_base + SETUP_START_OFFSET) >> 4, 0,
+ &regs, &regs);
+#endif
}
int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
- void *base_ptr;
+ struct boot_params *base_ptr;
void *bzImage_addr = NULL;
+ void *load_address;
char *s;
ulong bzImage_size = 0;
+ ulong initrd_addr = 0;
+ ulong initrd_size = 0;
disable_interrupts();
/* Setup board for maximum PC/AT Compatibility */
setup_pcat_compatibility();
- if (argc >= 2)
+ if (argc >= 2) {
/* argv[1] holds the address of the bzImage */
s = argv[1];
- else
+ } else {
s = getenv("fileaddr");
+ }
if (s)
bzImage_addr = (void *)simple_strtoul(s, NULL, 16);
- if (argc >= 3)
+ if (argc >= 3) {
/* argv[2] holds the size of the bzImage */
bzImage_size = simple_strtoul(argv[2], NULL, 16);
+ }
+
+ if (argc >= 4)
+ initrd_addr = simple_strtoul(argv[3], NULL, 16);
+ if (argc >= 5)
+ initrd_size = simple_strtoul(argv[4], NULL, 16);
- /* Lets look for*/
- base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0);
+ /* Lets look for */
+ base_ptr = load_zimage(bzImage_addr, bzImage_size, &load_address);
if (!base_ptr) {
printf("## Kernel loading failed ...\n");
- } else {
- printf("## Transferring control to Linux (at address %08x) ...\n",
- (u32)base_ptr);
+ return -1;
+ }
+ if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
+ 0, initrd_addr, initrd_size)) {
+ printf("Setting up boot parameters failed ...\n");
+ return -1;
+ }
- /* we assume that the kernel is in place */
- printf("\nStarting kernel ...\n\n");
+ printf("## Transferring control to Linux "
+ "(at address %08x) ...\n",
+ (u32)base_ptr);
- boot_zimage(base_ptr);
- /* does not return */
- }
+ /* we assume that the kernel is in place */
+ boot_zimage(base_ptr, load_address);
+ /* does not return */
return -1;
}
U_BOOT_CMD(
- zboot, 2, 0, do_zboot,
+ zboot, 5, 0, do_zboot,
"Boot bzImage",
- ""
+ "[addr] [size] [initrd addr] [initrd size]\n"
+ " addr - The optional starting address of the bzimage.\n"
+ " If not set it defaults to the environment\n"
+ " variable \"fileaddr\".\n"
+ " size - The optional size of the bzimage. Defaults to\n"
+ " zero.\n"
+ " initrd addr - The address of the initrd image to use, if any.\n"
+ " initrd size - The size of the initrd image to use, if any.\n"
);