diff options
author | Aaron Durbin <adurbin@chromium.org> | 2014-03-10 16:13:58 -0500 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2014-03-20 23:55:55 +0100 |
commit | 3eb8eb7eba55cdfd64c8d50181ea066526ff6485 (patch) | |
tree | 6e465cb8cdd4c4f31450f387ae6560d65c9a8224 /src | |
parent | 4fde5a66b4a2b4117a45519ab0f63a9fd6bff835 (diff) | |
download | coreboot-3eb8eb7eba55cdfd64c8d50181ea066526ff6485.tar.xz |
rmodules: use rmodtool to create rmodules
Start using the rmodtool for generating rmodules.
rmodule_link() has been changed to create 2 rules:
one for the passed in <name>, the other for creating
<name>.rmod which is an ELF file in the format of
an rmodule.
Since the header is not compiled and linked together
with an rmodule there needs to be a way of marking
which symbol is the entry point. __rmodule_entry is
the symbol used for knowing the entry point. There
was a little churn in SMM modules to ensure an
rmodule entry point symbol takes a single argument.
Change-Id: Ie452ed866f6596bf13f137f5b832faa39f48d26e
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/5379
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src')
24 files changed, 116 insertions, 260 deletions
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc index 4b2869738c..acb4e98e63 100644 --- a/src/arch/x86/Makefile.inc +++ b/src/arch/x86/Makefile.inc @@ -93,7 +93,13 @@ ifneq ($(strip $(call strip_quotes,$(CONFIG_LINUX_INITRD))),) endif endif -$(obj)/coreboot.rom: $(obj)/coreboot.pre $(objcbfs)/coreboot_ram.elf $(CBFSTOOL) $(call strip_quotes,$(COREBOOT_ROM_DEPENDENCIES)) $$(INTERMEDIATE) $$(VBOOT_STUB_ELF) +ifeq ($(CONFIG_HAVE_REFCODE_BLOB),y) +REFCODE_BLOB=$(obj)/refcode.rmod +$(REFCODE_BLOB): $(RMODTOOL) + $(RMODTOOL) -i $(CONFIG_REFCODE_BLOB_FILE) -o $@ +endif + +$(obj)/coreboot.rom: $(obj)/coreboot.pre $(objcbfs)/coreboot_ram.elf $(CBFSTOOL) $(call strip_quotes,$(COREBOOT_ROM_DEPENDENCIES)) $$(INTERMEDIATE) $$(VBOOT_STUB) $(REFCODE_BLOB) @printf " CBFS $(subst $(obj)/,,$(@))\n" cp $(obj)/coreboot.pre $@.tmp $(CBFSTOOL) $@.tmp add-stage -f $(objcbfs)/coreboot_ram.elf -n $(CONFIG_CBFS_PREFIX)/coreboot_ram -c $(CBFS_COMPRESS_FLAG) @@ -140,7 +146,7 @@ ifeq ($(CONFIG_INCLUDE_CONFIG_FILE),y) $(CBFSTOOL) $@.tmp add -f $(obj)/config.tmp -n config -t raw; rm -f $(obj)/config.tmp ; fi endif ifeq ($(CONFIG_VBOOT_VERIFY_FIRMWARE),y) - $(CBFSTOOL) $@.tmp add-stage -f $(VBOOT_STUB_ELF) -n $(CONFIG_CBFS_PREFIX)/vboot -c $(CBFS_COMPRESS_FLAG) + $(CBFSTOOL) $@.tmp add-stage -f $(VBOOT_STUB) -n $(CONFIG_CBFS_PREFIX)/vboot -c $(CBFS_COMPRESS_FLAG) endif ifeq ($(CONFIG_HAVE_REFCODE_BLOB),y) $(CBFSTOOL) $@.tmp add-stage -f $(CONFIG_REFCODE_BLOB_FILE) -n $(CONFIG_CBFS_PREFIX)/refcode -c $(CBFS_COMPRESS_FLAG) @@ -205,6 +211,10 @@ ifeq ($(CONFIG_RELOCATABLE_RAMSTAGE),y) $(eval $(call rmodule_link,$(objcbfs)/coreboot_ram.debug, $(objgenerated)/coreboot_ram.o, $(CONFIG_HEAP_SIZE))) +# The rmodule_link defintion creates an elf file with .rmod extension. +$(objcbfs)/coreboot_ram.elf: $(objcbfs)/coreboot_ram.debug.rmod + cp $< $@ + else $(objcbfs)/coreboot_ram.debug: $(objgenerated)/coreboot_ram.o $(src)/arch/x86/coreboot_ram.ld diff --git a/src/arch/x86/boot/Makefile.inc b/src/arch/x86/boot/Makefile.inc index 629c644c7c..79c64170b4 100644 --- a/src/arch/x86/boot/Makefile.inc +++ b/src/arch/x86/boot/Makefile.inc @@ -11,7 +11,6 @@ ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpi.c ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += acpigen.c ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S -ramstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += ramstage_module_header.c $(obj)/arch/x86/boot/smbios.ramstage.o: $(obj)/build.h diff --git a/src/arch/x86/boot/ramstage_module_header.c b/src/arch/x86/boot/ramstage_module_header.c deleted file mode 100644 index b958c16085..0000000000 --- a/src/arch/x86/boot/ramstage_module_header.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 ChromeOS Authors - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <rmodule.h> - -extern char _start[]; - -DEFINE_RMODULE_HEADER(ramstage_module, _start, RMODULE_TYPE_STAGE); diff --git a/src/arch/x86/lib/c_start.S b/src/arch/x86/lib/c_start.S index 01ffa7c42c..faea22d6a6 100644 --- a/src/arch/x86/lib/c_start.S +++ b/src/arch/x86/lib/c_start.S @@ -19,6 +19,8 @@ thread_stacks: .section ".textfirst", "ax", @progbits .code32 .globl _start + .globl __rmodule_entry +__rmodule_entry: _start: cli lgdt %cs:gdtaddr diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc index 60c061ddd7..63c1939537 100644 --- a/src/cpu/intel/haswell/Makefile.inc +++ b/src/cpu/intel/haswell/Makefile.inc @@ -25,12 +25,12 @@ ramstage-srcs += $(SIPI_BIN) rmodules-y += sipi_vector.S rmodules-y += sipi_header.c -$(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules.o $(dir $(SIPI_ELF))sipi_header.rmodules.o +$(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules.o $(CC) $(LDFLAGS) -nostdlib -r -o $@ $^ -$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0)) +$(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_DOTO), 0)) -$(SIPI_BIN): $(SIPI_ELF) +$(SIPI_BIN): $(SIPI_ELF).rmod $(OBJCOPY) -O binary $< $@ $(SIPI_BIN).ramstage.o: $(SIPI_BIN) diff --git a/src/cpu/intel/haswell/sipi_header.c b/src/cpu/intel/haswell/sipi_header.c deleted file mode 100644 index 846a82d7c2..0000000000 --- a/src/cpu/intel/haswell/sipi_header.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <rmodule.h> - - -extern void *ap_start; - -DEFINE_RMODULE_HEADER(sipi_vector_header, ap_start, RMODULE_TYPE_SIPI_VECTOR); diff --git a/src/cpu/intel/haswell/sipi_vector.S b/src/cpu/intel/haswell/sipi_vector.S index 664a9ee8ee..e0abb7c9b2 100644 --- a/src/cpu/intel/haswell/sipi_vector.S +++ b/src/cpu/intel/haswell/sipi_vector.S @@ -58,6 +58,8 @@ apic_to_cpu_num: .text .code16 .global ap_start +.global __rmodule_entry +__rmodule_entry: ap_start: cli xorl %eax, %eax diff --git a/src/cpu/intel/haswell/smmrelocate.c b/src/cpu/intel/haswell/smmrelocate.c index 3f4f45ab4f..dfbcf2e46b 100644 --- a/src/cpu/intel/haswell/smmrelocate.c +++ b/src/cpu/intel/haswell/smmrelocate.c @@ -164,11 +164,18 @@ static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) /* The relocation work is actually performed in SMM context, but the code * resides in the ramstage module. This occurs by trampolining from the default * SMRAM entry point to here. */ -static void asmlinkage -cpu_smm_do_relocation(void *arg, int cpu, const struct smm_runtime *runtime) +static void asmlinkage cpu_smm_do_relocation(void *arg) { msr_t mtrr_cap; - struct smm_relocation_params *relo_params = arg; + struct smm_relocation_params *relo_params; + const struct smm_module_params *p; + const struct smm_runtime *runtime; + int cpu; + + p = arg; + runtime = p->runtime; + relo_params = p->arg; + cpu = p->cpu; if (cpu >= CONFIG_MAX_CPUS) { printk(BIOS_CRIT, diff --git a/src/cpu/x86/Makefile.inc b/src/cpu/x86/Makefile.inc index 277ba484a6..c0b50c59ae 100644 --- a/src/cpu/x86/Makefile.inc +++ b/src/cpu/x86/Makefile.inc @@ -6,6 +6,7 @@ ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c ramstage-$(CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING) += mirror_payload.c SIPI_ELF=$(obj)/cpu/x86/sipi_vector.elf +SIPI_RMOD=$(SIPI_ELF).rmod SIPI_BIN=$(SIPI_ELF:.elf=) SIPI_DOTO=$(SIPI_ELF:.elf=.o) @@ -13,14 +14,13 @@ ifeq ($(CONFIG_PARALLEL_MP),y) ramstage-srcs += $(SIPI_BIN) endif rmodules-$(CONFIG_PARALLEL_MP) += sipi_vector.S -rmodules-$(CONFIG_PARALLEL_MP) += sipi_header.c -$(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules.o $(dir $(SIPI_ELF))sipi_header.rmodules.o +$(SIPI_DOTO): $(dir $(SIPI_ELF))sipi_vector.rmodules.o $(CC) $(LDFLAGS) -nostdlib -r -o $@ $^ $(eval $(call rmodule_link,$(SIPI_ELF), $(SIPI_ELF:.elf=.o), 0)) -$(SIPI_BIN): $(SIPI_ELF) +$(SIPI_BIN): $(SIPI_RMOD) $(OBJCOPY) -O binary $< $@ $(SIPI_BIN).ramstage.o: $(SIPI_BIN) diff --git a/src/cpu/x86/sipi_header.c b/src/cpu/x86/sipi_header.c deleted file mode 100644 index 846a82d7c2..0000000000 --- a/src/cpu/x86/sipi_header.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <rmodule.h> - - -extern void *ap_start; - -DEFINE_RMODULE_HEADER(sipi_vector_header, ap_start, RMODULE_TYPE_SIPI_VECTOR); diff --git a/src/cpu/x86/sipi_vector.S b/src/cpu/x86/sipi_vector.S index 52b12d0314..c08c3911df 100644 --- a/src/cpu/x86/sipi_vector.S +++ b/src/cpu/x86/sipi_vector.S @@ -58,6 +58,8 @@ ap_count: .text .code16 .global ap_start +.global __rmodule_entry +__rmodule_entry: ap_start: cli xorl %eax, %eax diff --git a/src/cpu/x86/smm/Makefile.inc b/src/cpu/x86/smm/Makefile.inc index 8dcd130117..bb9c11d83b 100644 --- a/src/cpu/x86/smm/Makefile.inc +++ b/src/cpu/x86/smm/Makefile.inc @@ -21,10 +21,8 @@ ramstage-$(CONFIG_BACKUP_DEFAULT_SMM_REGION) += backup_default_smm.c ifeq ($(CONFIG_SMM_MODULES),y) smmstub-y += smm_stub.S -smmstub-y += smm_module_header.c smm-y += smiutil.c -smm-y += smm_module_header.c smm-y += smm_module_handler.c ramstage-y += smm_module_loader.c @@ -40,7 +38,7 @@ $(obj)/cpu/x86/smm/smmstub.o: $$(smmstub-objs) # Link the SMM stub module with a 0-byte heap. $(eval $(call rmodule_link,$(obj)/cpu/x86/smm/smmstub.elf, $(obj)/cpu/x86/smm/smmstub.o, 0)) -$(obj)/cpu/x86/smm/smmstub: $(obj)/cpu/x86/smm/smmstub.elf +$(obj)/cpu/x86/smm/smmstub: $(obj)/cpu/x86/smm/smmstub.elf.rmod $(OBJCOPY) -O binary $< $@ $(obj)/cpu/x86/smm/smmstub.ramstage.o: $(obj)/cpu/x86/smm/smmstub @@ -55,7 +53,7 @@ $(obj)/cpu/x86/smm/smm.o: $$(smm-objs) $(LIBGCC_FILE_NAME) $(eval $(call rmodule_link,$(obj)/cpu/x86/smm/smm.elf, $(obj)/cpu/x86/smm/smm.o, $(CONFIG_SMM_MODULE_HEAP_SIZE))) -$(obj)/cpu/x86/smm/smm: $(obj)/cpu/x86/smm/smm.elf +$(obj)/cpu/x86/smm/smm: $(obj)/cpu/x86/smm/smm.elf.rmod $(OBJCOPY) -O binary $< $@ $(obj)/cpu/x86/smm/smm.ramstage.o: $(obj)/cpu/x86/smm/smm diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index 444e3352c7..79863d8fef 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -20,6 +20,7 @@ #include <arch/io.h> #include <console/console.h> #include <cpu/x86/smm.h> +#include <rmodule.h> typedef enum { SMI_LOCKED, SMI_UNLOCKED } smi_semaphore; @@ -113,8 +114,16 @@ void *smm_get_save_state(int cpu) return base; } -void smm_handler_start(void *arg, int cpu, const struct smm_runtime *runtime) +void asmlinkage smm_handler_start(void *arg) { + const struct smm_module_params *p; + const struct smm_runtime *runtime; + int cpu; + + p = arg; + runtime = p->runtime; + cpu = p->cpu; + /* Make sure to set the global runtime. It's OK to race as the value * will be the same across CPUs as well as multiple SMIs. */ if (smm_runtime == NULL) @@ -157,6 +166,8 @@ void smm_handler_start(void *arg, int cpu, const struct smm_runtime *runtime) smi_set_eos(); } +RMODULE_ENTRY(smm_handler_start); + /* Provide a default implementation for all weak handlers so that relocation * entries in the modules make sense. Without default implementations the * weak relocations w/o a symbol have a 0 address which is where the modules diff --git a/src/cpu/x86/smm/smm_module_header.c b/src/cpu/x86/smm/smm_module_header.c deleted file mode 100644 index 3ee654f6cd..0000000000 --- a/src/cpu/x86/smm/smm_module_header.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 ChromeOS Authors - * - * 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; version 2 of the License. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <rmodule.h> - -extern char smm_handler_start[]; - -DEFINE_RMODULE_HEADER(smm_module, smm_handler_start, RMODULE_TYPE_SMM); diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S index 07eb5dcb6d..083cb577b6 100644 --- a/src/cpu/x86/smm/smm_stub.S +++ b/src/cpu/x86/smm/smm_stub.S @@ -61,6 +61,8 @@ fallback_stack_top: .text .code16 .global smm_handler_start +.global __rmodule_entry +__rmodule_entry: smm_handler_start: movl $(smm_relocate_gdt), %ebx data32 lgdt (%ebx) @@ -132,11 +134,13 @@ smm_trampoline32: 2: /* Call into the c-based SMM relocation function with the platform * parameters. Equivalent to: - * c_handler(c_handler_params, cpu_num, smm_runtime); + * struct arg = { c_handler_params, cpu_num, smm_runtime {; + * c_handler(&arg) */ push $(smm_runtime) push %ecx push c_handler_arg + push %esp mov c_handler, %eax call *%eax diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h index 3ab43ff2ce..f63420fab5 100644 --- a/src/include/cpu/x86/smm.h +++ b/src/include/cpu/x86/smm.h @@ -517,14 +517,20 @@ struct smm_runtime { u8 apic_id_to_cpu[CONFIG_MAX_CPUS]; } __attribute__ ((packed)); -typedef void asmlinkage (*smm_handler_t)(void *arg, int cpu, - const struct smm_runtime *runtime); +struct smm_module_params { + void *arg; + int cpu; + const struct smm_runtime *runtime; +}; + +/* smm_handler_t is called with arg of smm_module_params pointer. */ +typedef void asmlinkage (*smm_handler_t)(void *); #ifdef __SMM__ /* SMM Runtime helpers. */ /* Entry point for SMM modules. */ -void smm_handler_start(void *arg, int cpu, const struct smm_runtime *runtime); +void asmlinkage smm_handler_start(void *params); /* Retrieve SMM save state for a given CPU. WARNING: This does not take into * account CPUs which are configured to not save their state to RAM. */ diff --git a/src/include/rmodule-defs.h b/src/include/rmodule-defs.h index ee2d3f7bdd..4139ef3d41 100644 --- a/src/include/rmodule-defs.h +++ b/src/include/rmodule-defs.h @@ -25,30 +25,6 @@ #define RMODULE_MAGIC 0xf8fe #define RMODULE_VERSION_1 1 -#define FIELD_ENTRY(x_) ((uint32_t)&x_) -#define RMODULE_HEADER(entry_, type_) \ -{ \ - .magic = RMODULE_MAGIC, \ - .version = RMODULE_VERSION_1, \ - .type = type_, \ - .payload_begin_offset = FIELD_ENTRY(_payload_begin_offset), \ - .payload_end_offset = FIELD_ENTRY(_payload_end_offset), \ - .relocations_begin_offset = \ - FIELD_ENTRY(_relocations_begin_offset), \ - .relocations_end_offset = \ - FIELD_ENTRY(_relocations_end_offset), \ - .module_link_start_address = \ - FIELD_ENTRY(_module_link_start_addr), \ - .module_program_size = FIELD_ENTRY(_module_program_size), \ - .module_entry_point = FIELD_ENTRY(entry_), \ - .parameters_begin = FIELD_ENTRY(_module_params_begin), \ - .parameters_end = FIELD_ENTRY(_module_params_end), \ - .bss_begin = FIELD_ENTRY(_bss), \ - .bss_end = FIELD_ENTRY(_ebss), \ -} - -/* Private data structures below should not be used directly. */ - /* All fields with '_offset' in the name are byte offsets into the flat blob. * The linker and the linker script takes are of assigning the values. */ struct rmodule_header { diff --git a/src/include/rmodule.h b/src/include/rmodule.h index 2147ab0919..d229cf816a 100644 --- a/src/include/rmodule.h +++ b/src/include/rmodule.h @@ -21,6 +21,7 @@ #include <stdint.h> #include <stddef.h> +#include <string.h> #include <rmodule-defs.h> enum { @@ -50,11 +51,6 @@ int rmodule_load_alignment(const struct rmodule *m); int rmodule_calc_region(unsigned int region_alignment, size_t rmodule_size, size_t *region_size, int *load_offset); -#define DEFINE_RMODULE_HEADER(name_, entry_, type_) \ - struct rmodule_header name_ \ - __attribute__ ((section (".module_header"))) = \ - RMODULE_HEADER(entry_, type_) - /* Support for loading rmodule stages. This API is only available when * using dynamic cbmem because it uses the dynamic cbmem API to obtain * the backing store region for the stage. */ @@ -84,17 +80,12 @@ struct rmodule { void *relocations; }; -/* These are the symbols assumed that every module contains. The linker script - * provides these symbols. */ -extern char _relocations_begin_offset[]; -extern char _relocations_end_offset[]; -extern char _payload_end_offset[]; -extern char _payload_begin_offset[]; -extern char _bss[]; -extern char _ebss[]; -extern char _module_program_size[]; -extern char _module_link_start_addr[]; -extern char _module_params_begin[]; -extern char _module_params_end[]; +#if IS_ENABLED(CONFIG_RELOCATABLE_MODULES) +/* Rmodules have an entry point of named __rmodule_entry. */ +#define RMODULE_ENTRY(entry_) \ + void __rmodule_entry(void *) __attribute__((alias (STRINGIFY(entry_)))) +#else +#define RMODULE_ENTRY(entry_) +#endif #endif /* RMODULE_H */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index acd334e25d..93babd3c1f 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -133,17 +133,21 @@ ramstage-y += rmodule.c romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += rmodule.c RMODULE_LDSCRIPT := $(src)/lib/rmodule.ld -RMODULE_LDFLAGS := -nostartfiles -shared -z defs -nostdlib -Bsymbolic -T $(RMODULE_LDSCRIPT) +RMODULE_LDFLAGS := -nostartfiles -Wl,--emit-relocs -Wl,-z,defs -Wl,-Bsymbolic -Wl,-T,$(RMODULE_LDSCRIPT) # rmodule_link_rules is a function that should be called with: # (1) the object name to link # (2) the dependencies # (3) heap size of the relocatable module -# It will create the necessary Make rules. +# It will create the necessary Make rules to create a rmodule. The resulting +# rmdoule is named $(1).rmod define rmodule_link -$(strip $(1)): $(strip $(2)) $$(RMODULE_LDSCRIPT) $$(obj)/ldoptions - $$(LD) $$(RMODULE_LDFLAGS) --defsym=__heap_size=$(strip $(3)) -o $$@ $(strip $(2)) +$(strip $(1)): $(strip $(2)) $$(RMODULE_LDSCRIPT) $$(obj)/ldoptions $$(RMODTOOL) + $$(CC) $$(CFLAGS) $$(RMODULE_LDFLAGS) -Wl,--defsym=__heap_size=$(strip $(3)) -o $$@ -Wl,--start-group $(strip $(2)) $$(LIBGCC_FILE_NAME) -Wl,--end-group $$(NM) -n $$@ > $$(basename $$@).map + +$(strip $(1)).rmod: $(strip $(1)) + $$(RMODTOOL) -i $$^ -o $$@ endef endif diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c index 2cb70b8f33..a73e667fef 100644 --- a/src/lib/rmodule.c +++ b/src/lib/rmodule.c @@ -26,44 +26,6 @@ /* Change this define to get more verbose debugging for module loading. */ #define PK_ADJ_LEVEL BIOS_NEVER -#if CONFIG_ARCH_X86 -/* - * On X86, the only relocations currently allowed are R_386_RELATIVE which - * have '0' for the symbol info in the relocation metadata (in r_info). - * The reason is that the module is fully linked and just has the relocations' - * locations. - */ -typedef struct { - uint32_t r_offset; - uint32_t r_info; -} Elf32_Rel; - -#define R_386_RELATIVE 8 - -#define RELOCTION_ENTRY_SIZE sizeof(Elf32_Rel) -static inline int rmodule_reloc_offset(const void *reloc) -{ - const Elf32_Rel *rel = reloc; - return rel->r_offset; -} - -static inline int rmodule_reloc_valid(const void *reloc) -{ - const Elf32_Rel *rel = reloc; - return (rel->r_info == R_386_RELATIVE); -} - -static inline void *remodule_next_reloc(const void *reloc) -{ - const Elf32_Rel *rel = reloc; - rel++; - return (void *)rel; -} - -#else -#error Arch needs to add relocation information support for RMODULE -#endif - static inline int rmodule_is_loaded(const struct rmodule *module) { return module->location != NULL; @@ -71,7 +33,7 @@ static inline int rmodule_is_loaded(const struct rmodule *module) /* Calculate a loaded program address based on the blob address. */ static inline void *rmodule_load_addr(const struct rmodule *module, - uint32_t blob_addr) + uintptr_t blob_addr) { char *loc = module->location; return &loc[blob_addr - module->header->module_link_start_address]; @@ -151,13 +113,13 @@ static void rmodule_clear_bss(struct rmodule *module) memset(begin, 0, size); } -static inline int rmodule_number_relocations(const struct rmodule *module) +static inline size_t rmodule_number_relocations(const struct rmodule *module) { - int r; + size_t r; r = module->header->relocations_end_offset; r -= module->header->relocations_begin_offset; - r /= RELOCTION_ENTRY_SIZE; + r /= sizeof(uintptr_t); return r; } @@ -176,51 +138,33 @@ static void rmodule_copy_payload(const struct rmodule *module) memcpy(module->location, module->payload, module->payload_size); } -static inline uint32_t *rmodule_adjustment_location(const struct rmodule *module, - const void *reloc) -{ - int reloc_offset; - - /* Don't relocate header field entries -- only program relocations. */ - reloc_offset = rmodule_reloc_offset(reloc); - if (reloc_offset < module->header->module_link_start_address) - return NULL; - - return rmodule_load_addr(module, reloc_offset); -} - static int rmodule_relocate(const struct rmodule *module) { - int num_relocations; - const void *reloc; - uint32_t adjustment; + size_t num_relocations; + const uintptr_t *reloc; + uintptr_t adjustment; /* Each relocation needs to be adjusted relative to the beginning of * the loaded program. */ - adjustment = (uint32_t)rmodule_load_addr(module, 0); + adjustment = (uintptr_t)rmodule_load_addr(module, 0); reloc = module->relocations; num_relocations = rmodule_number_relocations(module); - printk(BIOS_DEBUG, "Processing %d relocs with adjust value of 0x%08x\n", + printk(BIOS_DEBUG, "Processing %zu relocs. Offset value of 0x%08x\n", num_relocations, adjustment); while (num_relocations > 0) { - uint32_t *adjust_loc; - - if (!rmodule_reloc_valid(reloc)) - return -1; + uintptr_t *adjust_loc; /* If the adjustment location is non-NULL adjust it. */ - adjust_loc = rmodule_adjustment_location(module, reloc); - if (adjust_loc != NULL) { - printk(PK_ADJ_LEVEL, "Adjusting %p: 0x%08x -> 0x%08x\n", + adjust_loc = rmodule_load_addr(module, *reloc); + printk(PK_ADJ_LEVEL, "Adjusting %p: 0x%08x -> 0x%08x\n", adjust_loc, *adjust_loc, *adjust_loc + adjustment); *adjust_loc += adjustment; - } - reloc = remodule_next_reloc(reloc); + reloc++; num_relocations--; } @@ -232,8 +176,8 @@ int rmodule_load_alignment(const struct rmodule *module) /* The load alignment is the start of the program's linked address. * The base address where the program is loaded needs to be a multiple * of the program's starting link address. That way all data alignment - * in the program is preserved. */ - return module->header->module_link_start_address; + * in the program is preserved. Default to 4KiB. */ + return 4096; } int rmodule_load(void *base, struct rmodule *module) diff --git a/src/lib/rmodule.ld b/src/lib/rmodule.ld index 0cdbb2fa25..9222f3b876 100644 --- a/src/lib/rmodule.ld +++ b/src/lib/rmodule.ld @@ -1,19 +1,15 @@ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) - /* * This linker script is used to link rmodules (relocatable modules). It * links at zero so that relocation fixups are easy when placing the binaries * anywhere in the address space. * * NOTE: The program's loadable sections (text, module_params, and data) are - * packed into the flat blob using the AT directive. The rmodule loader assumes - * the entire program resides in one contiguous address space. Therefore, - * alignment for a given section (if required) needs to be done at the end of - * the preceeding section. e.g. if the data section should be aligned to an 8 - * byte address the text section should have ALIGN(8) at the end of its section. - * Otherwise there won't be a consistent mapping between the flat blob and the - * loaded program. + * packed into the flat blob. The rmodule loader assumes the entire program + * resides in one contiguous address space. Therefore, alignment for a given + * section (if required) needs to be done at the end of the preceeding section. + * e.g. if the data section should be aligned to an 8 byte address the text + * section should have ALIGN(8) at the end of its section. Otherwise there + * won't be a consistent mapping between the flat blob and the loaded program. */ BASE_ADDRESS = 0x00000; @@ -22,21 +18,9 @@ SECTIONS { . = BASE_ADDRESS; - .header : AT (0) { - *(.module_header); - . = ALIGN(8); - } - - /* Align the start of the module program to a large enough alignment - * so that any data in the program with an alignement property is met. - * Essentially, this alignment is the maximum possible data alignment - * property a program can have. */ - . = ALIGN(4096); - _module_link_start_addr = .; - _payload_begin_offset = LOADADDR(.header) + SIZEOF(.header); - - .payload : AT (_payload_begin_offset) { + .payload : { /* C code of the module. */ + _ram_seg = .; *(.textfirst); *(.text); *(.text.*); @@ -88,9 +72,6 @@ SECTIONS . = ALIGN(8); } - /* _payload_end marks the end of the module's code and data. */ - _payload_end_offset = LOADADDR(.payload) + SIZEOF(.payload); - .bss (NOLOAD) : { /* C uninitialized data of the module. */ _bss = .; @@ -107,38 +88,11 @@ SECTIONS _heap = .; . = . + __heap_size; _eheap = .; + _eram_seg = .; } - /* _module_program_size is the total memory used by the program. */ - _module_program_size = _eheap - _module_link_start_addr; - - /* coreboot's ramstage uses the _ram_seg and _eram_seg symbols - * for determining its load location. Provide those to help it out. - * It's a nop for any non-ramstage rmodule. */ - _ram_seg = _module_link_start_addr; - _eram_seg = _module_link_start_addr + _module_program_size; - - /* The relocation information is linked on top of the BSS section - * because the BSS section takes no space on disk. The relocation data - * resides directly after the data section in the flat binary. */ - .relocations ADDR(.bss) : AT (_payload_end_offset) { - *(.rel.*); - } - _relocations_begin_offset = LOADADDR(.relocations); - _relocations_end_offset = _relocations_begin_offset + - SIZEOF(.relocations); - /DISCARD/ : { - /* Drop unnecessary sections. Since these modules are linked - * as shared objects there are dynamic sections. These sections - * aren't needed so drop them. */ - *(.comment); - *(.note); - *(.note.*); - *(.dynamic); - *(.dynsym); - *(.dynstr); - *(.gnu.hash); + /* Drop unnecessary sections. */ *(.eh_frame); } } diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 1226e471ad..c55053103c 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -112,11 +112,17 @@ static void adjust_apic_id_map(struct smm_loader_params *smm_params) runtime->apic_id_to_cpu[i] = mp_get_apic_id(i); } -static void asmlinkage -cpu_smm_do_relocation(void *arg, int cpu, const struct smm_runtime *runtime) +static void asmlinkage cpu_smm_do_relocation(void *arg) { msr_t smrr; em64t100_smm_state_save_area_t *smm_state; + const struct smm_module_params *p; + const struct smm_runtime *runtime; + int cpu; + + p = arg; + runtime = p->runtime; + cpu = p->cpu; if (cpu >= CONFIG_MAX_CPUS) { printk(BIOS_CRIT, diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc index 007bd575e7..21e1750b83 100644 --- a/src/vendorcode/google/chromeos/Makefile.inc +++ b/src/vendorcode/google/chromeos/Makefile.inc @@ -51,6 +51,7 @@ VB_INCLUDES += -I$(VB_SOURCE)/firmware/include INCLUDES += $(VB_INCLUDES) VBOOT_STUB_ELF = $(obj)/vendorcode/google/chromeos/vbootstub.elf +VBOOT_STUB = $(VBOOT_STUB_ELF).rmod VBOOT_STUB_DOTO = $(VBOOT_STUB_ELF:.elf=.o) # Dependency for the vboot rmodules. Ordering matters. diff --git a/src/vendorcode/google/chromeos/vboot_wrapper.c b/src/vendorcode/google/chromeos/vboot_wrapper.c index 66b7cfb276..fe3c022833 100644 --- a/src/vendorcode/google/chromeos/vboot_wrapper.c +++ b/src/vendorcode/google/chromeos/vboot_wrapper.c @@ -24,10 +24,6 @@ #include "vboot_context.h" #include "vboot_handoff.h" -static void vboot_wrapper(struct vboot_context *context); - -DEFINE_RMODULE_HEADER(vboot_wrapper_header, vboot_wrapper, RMODULE_TYPE_VBOOT); - /* Keep a global context pointer around for the callbacks to use. */ static struct vboot_context *gcontext; @@ -63,12 +59,14 @@ static void parse_component(const struct components *components, int num, fw->size = (uint32_t)components->entries[num].size; } -static void vboot_wrapper(struct vboot_context *context) +static void vboot_wrapper(void *arg) { int i; VbError_t res; const struct components *components; + struct vboot_context *context; + context = arg; gcontext = context; VbExDebug("Calling VbInit()\n"); @@ -266,3 +264,4 @@ VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length, return VBERROR_SUCCESS; } +RMODULE_ENTRY(vboot_wrapper); |