From 2c3a054f4fe0e6c894b2a0df405b1541d568a511 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 19 Feb 2016 12:16:09 +0100 Subject: [PATCH] WIP --- configure.ac | 1 + gentpl.py | 5 +- grub-core/Makefile.am | 11 +- grub-core/Makefile.core.def | 23 +++- .../commands/i386/coreboot/cb_timestamps.c | 2 +- grub-core/commands/i386/coreboot/cbls.c | 2 +- grub-core/kern/arm/coreboot/cbtable.c | 74 ++++++++++ grub-core/kern/arm/coreboot/coreboot.S | 40 ++++++ grub-core/kern/arm/coreboot/init.c | 127 ++++++++++++++++++ grub-core/kern/coreboot/mmap.c | 6 +- grub-core/kern/i386/coreboot/cbtable.c | 2 +- grub-core/term/i386/coreboot/cbmemc.c | 2 +- grub-core/video/coreboot/cbfb.c | 2 +- include/grub/arm/linux.h | 2 +- include/grub/coreboot/lbio.h | 3 + include/grub/offsets.h | 3 + 16 files changed, 288 insertions(+), 17 deletions(-) create mode 100644 grub-core/kern/arm/coreboot/cbtable.c create mode 100644 grub-core/kern/arm/coreboot/coreboot.S create mode 100644 grub-core/kern/arm/coreboot/init.c diff --git a/configure.ac b/configure.ac index 46f899610..2e35eed24 100644 --- a/configure.ac +++ b/configure.ac @@ -167,6 +167,7 @@ case "$target_cpu"-"$platform" in mipsel-fuloong) platform=loongson ;; mipsel-loongson) ;; arm-uboot) ;; + arm-coreboot) ;; arm-efi) ;; arm64-efi) ;; *-emu) ;; diff --git a/gentpl.py b/gentpl.py index 4076f8807..edbb13516 100644 --- a/gentpl.py +++ b/gentpl.py @@ -53,6 +53,7 @@ GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi" GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] GROUPS["uboot"] = [ "arm_uboot" ] GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] +GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] # emu is a special case so many core functionality isn't needed on this platform GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") @@ -65,7 +66,7 @@ GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] GROUPS["usb"] = GROUPS["pci"] # If gfxterm is main output console integrate it into kernel -GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot" ] +GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] GROUPS["videomodules"] = GRUB_PLATFORMS[:]; for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) @@ -75,7 +76,7 @@ GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) # Flattened Device Trees (FDT) -GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi" ] +GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "arm_coreboot" ] # Needs software helpers for division # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 04e9395fd..bb31e625a 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -112,7 +112,7 @@ endif if COND_i386_coreboot KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h -KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/coreboot/lbio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h @@ -239,6 +239,15 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h endif +if COND_arm_coreboot +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +endif + if COND_arm_efi KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/efi/loader.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 24fe49199..e379e679f 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -92,6 +92,8 @@ kernel = { emu_cppflags = '$(CPPFLAGS_GNULIB)'; arm_uboot_ldflags = '-Wl,-r,-d'; arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + arm_coreboot_ldflags = '-Wl,-r,-d'; + arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; i386_pc_startup = kern/i386/pc/startup.S; i386_efi_startup = kern/i386/efi/startup.S; @@ -105,7 +107,8 @@ kernel = { mips_startup = kern/mips/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; - arm_uboot_startup = kern/arm/uboot/startup.S; + arm_uboot_startup = kern/arm/startup.S; + arm_coreboot_startup = kern/arm/startup.S; arm_efi_startup = kern/arm/efi/startup.S; arm64_efi_startup = kern/arm64/efi/startup.S; @@ -149,6 +152,11 @@ kernel = { uboot = kern/uboot/init.c; uboot = kern/uboot/hw.c; uboot = term/uboot/console.c; + arm_uboot = kern/arm/uboot/init.c; + arm_uboot = kern/arm/uboot/uboot.S; + + arm_coreboot = kern/arm/coreboot/init.c; + arm_coreboot = kern/arm/coreboot/coreboot.S; terminfoinkernel = term/terminfo.c; terminfoinkernel = term/tparm.c; @@ -223,8 +231,9 @@ kernel = { i386_qemu = kern/vga_init.c; i386_qemu = kern/i386/qemu/mmap.c; - i386_coreboot = kern/i386/coreboot/mmap.c; + coreboot = kern/coreboot/mmap.c; i386_coreboot = kern/i386/coreboot/cbtable.c; + arm_coreboot = kern/arm/coreboot/cbtable.c; i386_multiboot = kern/i386/multiboot_mmap.c; @@ -752,6 +761,7 @@ module = { enable = arm_efi; enable = arm64_efi; enable = arm_uboot; + enable = arm_coreboot; }; module = { @@ -819,7 +829,7 @@ module = { common = commands/gptsync.c; }; -module = { +/*module = { name = halt; nopc = commands/halt.c; i386_pc = commands/i386/pc/halt.c; @@ -854,7 +864,7 @@ module = { xen = lib/xen/reboot.c; uboot = lib/uboot/reboot.c; common = commands/reboot.c; -}; +};*/ module = { name = hashsum; @@ -1546,6 +1556,7 @@ module = { cmos = lib/cmos_datetime.c; efi = lib/efi/datetime.c; uboot = lib/uboot/datetime.c; + arm_coreboot = lib/uboot/datetime.c; sparc64_ieee1275 = lib/ieee1275/datetime.c; powerpc_ieee1275 = lib/ieee1275/datetime.c; sparc64_ieee1275 = lib/ieee1275/cmos.c; @@ -1655,7 +1666,7 @@ module = { arm64 = loader/arm64/xen_boot.c; enable = arm64; }; - +/* module = { name = linux; x86 = loader/i386/linux.c; @@ -1671,7 +1682,7 @@ module = { common = lib/cmdline.c; enable = noemu; }; - +*/ module = { name = fdt; arm64 = loader/arm64/fdt.c; diff --git a/grub-core/commands/i386/coreboot/cb_timestamps.c b/grub-core/commands/i386/coreboot/cb_timestamps.c index e72f38d6e..e97ea6bed 100644 --- a/grub-core/commands/i386/coreboot/cb_timestamps.c +++ b/grub-core/commands/i386/coreboot/cb_timestamps.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/commands/i386/coreboot/cbls.c b/grub-core/commands/i386/coreboot/cbls.c index e0a10596f..102291f42 100644 --- a/grub-core/commands/i386/coreboot/cbls.c +++ b/grub-core/commands/i386/coreboot/cbls.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/grub-core/kern/arm/coreboot/cbtable.c b/grub-core/kern/arm/coreboot/cbtable.c new file mode 100644 index 000000000..35680c15b --- /dev/null +++ b/grub-core/kern/arm/coreboot/cbtable.c @@ -0,0 +1,74 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2007,2008,2013 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#pragma GCC diagnostic ignored "-Wcast-align" + +/* Helper for grub_linuxbios_table_iterate. */ +static int +check_signature (grub_linuxbios_table_header_t tbl_header) +{ + if (! grub_memcmp (tbl_header->signature, "LBIO", 4)) + return 1; + + return 0; +} + +grub_err_t +grub_linuxbios_table_iterate (int (*hook) (grub_linuxbios_table_item_t, + void *), + void *hook_data) +{ + grub_linuxbios_table_header_t table_header + = (grub_linuxbios_table_header_t) grub_arm_saved_registers.r[0]; + grub_linuxbios_table_item_t table_item; + + if (!check_signature (table_header)) + return 0; + + signature_found: + table_item = + (grub_linuxbios_table_item_t) ((char *) table_header + + table_header->header_size); + for (; table_item < (grub_linuxbios_table_item_t) ((char *) table_header + + table_header->header_size + + table_header->table_size); + table_item = (grub_linuxbios_table_item_t) ((char *) table_item + table_item->size)) + { + if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK + && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1))) + { + table_header = (grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1); + goto signature_found; + } + if (hook (table_item, hook_data)) + return 1; + } + + return 0; +} diff --git a/grub-core/kern/arm/coreboot/coreboot.S b/grub-core/kern/arm/coreboot/coreboot.S new file mode 100644 index 000000000..b056a2cbf --- /dev/null +++ b/grub-core/kern/arm/coreboot/coreboot.S @@ -0,0 +1,40 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2016 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .file "coreboot.S" + .text + .syntax unified +#if !defined (__thumb2__) + .arch armv7a + .arm +#else + .arch armv7 + .thumb +#endif + +FUNCTION(grub_armv7_get_timer_value) + isb + mrrc p15, 1, r0, r1, c14 + bx lr + +FUNCTION(grub_armv7_get_timer_frequency) + mrc p15, 0, r0, c14, c0, 0 + bx lr + diff --git a/grub-core/kern/arm/coreboot/init.c b/grub-core/kern/arm/coreboot/init.c new file mode 100644 index 000000000..f65c36041 --- /dev/null +++ b/grub-core/kern/arm/coreboot/init.c @@ -0,0 +1,127 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2013 Free Software Foundation, Inc. + * + * GRUB 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 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern grub_uint8_t _start[]; +extern grub_uint8_t _end[]; +extern grub_uint8_t _edata[]; + +grub_uint64_t +grub_armv7_get_timer_value(void); + +grub_uint32_t +grub_armv7_get_timer_frequency(void); + +void __attribute__ ((noreturn)) +grub_exit (void) +{ + /* We can't use grub_fatal() in this function. This would create an infinite + loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ + while (1) + grub_cpu_idle (); +} + +static grub_uint64_t modend; +static int have_memory = 0; + +/* Helper for grub_machine_init. */ +static int +heap_init (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type, + void *data __attribute__ ((unused))) +{ + grub_uint64_t begin = addr, end = addr + size; + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + /* Restrict ourselves to 32-bit memory space. */ + if (begin > GRUB_ULONG_MAX) + return 0; + if (end > GRUB_ULONG_MAX) + end = GRUB_ULONG_MAX; +#endif + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + + if (modend && begin < modend) + begin = modend; + + if (end <= begin) + return 0; + + grub_mm_init_region ((void *) (grub_addr_t) begin, (grub_size_t) (end - begin)); + + have_memory = 1; + + return 0; +} + +static grub_uint32_t timer_frequency_in_khz; + +static grub_uint64_t +get_time_ms (void) +{ + return grub_divmod64 (grub_armv7_get_timer_value(), timer_frequency_in_khz, 0); +} + +void +grub_machine_init (void) +{ + modend = grub_modules_get_end (); + + grub_video_coreboot_fb_early_init (); + + grub_machine_mmap_iterate (heap_init, NULL); + if (!have_memory) + grub_fatal ("No memory found"); + + grub_video_coreboot_fb_late_init (); + + grub_font_init (); + grub_gfxterm_init (); + + timer_frequency_in_khz = grub_armv7_get_timer_frequency() / 1000; + if (timer_frequency_in_khz == 0) + grub_fatal ("No timer found"); + grub_install_get_time_ms (get_time_ms); +} + +void +grub_machine_get_bootlocation (char **device __attribute__ ((unused)), + char **path __attribute__ ((unused))) +{ +} + +void +grub_machine_fini (int flags __attribute__ ((unused))) +{ +} diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c index 4d29f6b7d..caf8f7cef 100644 --- a/grub-core/kern/coreboot/mmap.c +++ b/grub-core/kern/coreboot/mmap.c @@ -16,8 +16,8 @@ * along with GRUB. If not, see . */ -#include -#include +#include +#include #include #include #include @@ -49,6 +49,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) { grub_uint64_t start = mem_region->addr; grub_uint64_t end = mem_region->addr + mem_region->size; +#ifdef __i386__ /* Mark region 0xa0000 - 0x100000 as reserved. */ if (start < 0x100000 && end >= 0xa0000 && mem_region->type == GRUB_MACHINE_MEMORY_AVAILABLE) @@ -75,6 +76,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data) if (end <= start) continue; } +#endif if (ctx->hook (start, end - start, /* Multiboot mmaps match with the coreboot mmap definition. Therefore, we can just pass type diff --git a/grub-core/kern/i386/coreboot/cbtable.c b/grub-core/kern/i386/coreboot/cbtable.c index 1669bc0ca..5beb1ed69 100644 --- a/grub-core/kern/i386/coreboot/cbtable.c +++ b/grub-core/kern/i386/coreboot/cbtable.c @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include diff --git a/grub-core/term/i386/coreboot/cbmemc.c b/grub-core/term/i386/coreboot/cbmemc.c index 25e64a05c..129248c7f 100644 --- a/grub-core/term/i386/coreboot/cbmemc.c +++ b/grub-core/term/i386/coreboot/cbmemc.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/grub-core/video/coreboot/cbfb.c b/grub-core/video/coreboot/cbfb.c index dede0c37e..9af81fa5b 100644 --- a/grub-core/video/coreboot/cbfb.c +++ b/grub-core/video/coreboot/cbfb.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include struct grub_linuxbios_table_framebuffer *grub_video_coreboot_fbtable; diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h index 059dbba42..2d4bc5770 100644 --- a/include/grub/arm/linux.h +++ b/include/grub/arm/linux.h @@ -25,7 +25,7 @@ #include "system.h" -#if defined GRUB_MACHINE_UBOOT +#if defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_COREBOOT) # include # define LINUX_ADDRESS (start_of_ram + 0x8000) # define LINUX_INITRD_ADDRESS (start_of_ram + 0x02000000) diff --git a/include/grub/coreboot/lbio.h b/include/grub/coreboot/lbio.h index 1c3fa6f19..df40d2e56 100644 --- a/include/grub/coreboot/lbio.h +++ b/include/grub/coreboot/lbio.h @@ -20,6 +20,9 @@ #ifndef _GRUB_MACHINE_LBIO_HEADER #define _GRUB_MACHINE_LBIO_HEADER 1 +#include +#include + struct grub_linuxbios_table_header { grub_uint8_t signature[4]; diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 3502a4310..47025403a 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -109,6 +109,7 @@ #define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0 #define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0 +#define GRUB_KERNEL_ARM_COREBOOT_MOD_GAP 0x0 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 #define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3 @@ -120,6 +121,8 @@ #define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN 0x8 #define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE 0x4 +#define GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN 0x8 +#define GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE 0x4 /* Minimal gap between _end and the start of the modules. It's a hack for PowerMac to prevent "CLAIM failed" error. The real fix is to -- 2.47.2