From 3eb8eb7eba55cdfd64c8d50181ea066526ff6485 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Mon, 10 Mar 2014 16:13:58 -0500 Subject: 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 , the other for creating .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 Reviewed-on: http://review.coreboot.org/5379 Reviewed-by: Stefan Reinauer Tested-by: build bot (Jenkins) --- src/arch/x86/Makefile.inc | 14 ++++- src/arch/x86/boot/Makefile.inc | 1 - src/arch/x86/boot/ramstage_module_header.c | 24 ------- src/arch/x86/lib/c_start.S | 2 + src/cpu/intel/haswell/Makefile.inc | 6 +- src/cpu/intel/haswell/sipi_header.c | 6 -- src/cpu/intel/haswell/sipi_vector.S | 2 + src/cpu/intel/haswell/smmrelocate.c | 13 +++- src/cpu/x86/Makefile.inc | 6 +- src/cpu/x86/sipi_header.c | 6 -- src/cpu/x86/sipi_vector.S | 2 + src/cpu/x86/smm/Makefile.inc | 6 +- src/cpu/x86/smm/smm_module_handler.c | 13 +++- src/cpu/x86/smm/smm_module_header.c | 24 ------- src/cpu/x86/smm/smm_stub.S | 6 +- src/include/cpu/x86/smm.h | 12 +++- src/include/rmodule-defs.h | 24 ------- src/include/rmodule.h | 25 +++----- src/lib/Makefile.inc | 12 ++-- src/lib/rmodule.c | 86 +++++--------------------- src/lib/rmodule.ld | 66 +++----------------- src/soc/intel/baytrail/cpu.c | 10 ++- src/vendorcode/google/chromeos/Makefile.inc | 1 + src/vendorcode/google/chromeos/vboot_wrapper.c | 9 ++- 24 files changed, 116 insertions(+), 260 deletions(-) delete mode 100644 src/arch/x86/boot/ramstage_module_header.c delete mode 100644 src/cpu/intel/haswell/sipi_header.c delete mode 100644 src/cpu/x86/sipi_header.c delete mode 100644 src/cpu/x86/smm/smm_module_header.c (limited to 'src') 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 - -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 - - -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 - - -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 #include #include +#include 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 - -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 #include +#include #include 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); -- cgit v1.2.3