the following patch was just integrated into master:
commit e12cb2e04130e4eb1f1e1f126e6195eee0758b56
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
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(a)chromium.org>
See http://review.coreboot.org/5379 for details.
-gerrit
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5379
-gerrit
commit e12cb2e04130e4eb1f1e1f126e6195eee0758b56
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
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(a)chromium.org>
---
Makefile.inc | 6 +-
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 ++-
25 files changed, 121 insertions(+), 261 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 19ba294..fcd680d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -252,10 +252,14 @@ build-dirs:
#######################################################################
# Build the tools
CBFSTOOL:=$(obj)/cbfstool
+RMODTOOL:=$(obj)/rmodtool
$(CBFSTOOL): $(objutil)/cbfstool/cbfstool
cp $< $@
+$(RMODTOOL): $(objutil)/cbfstool/rmodtool
+ cp $< $@
+
_WINCHECK=$(shell uname -o 2> /dev/null)
STACK=
ifeq ($(_WINCHECK),Msys)
@@ -390,5 +394,5 @@ crosstools-arm: clean-for-update
crossgcc-clean: clean-for-update
$(MAKE) -C util/crossgcc clean
-tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
+tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/rmodtool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 4b28697..acb4e98 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 629c644..79c6417 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 b958c16..0000000
--- 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 01ffa7c..faea22d 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 60c061d..63c1939 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 846a82d..0000000
--- 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 664a9ee..e0abb7c 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 3f4f45a..dfbcf2e 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 277ba48..c0b50c5 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 846a82d..0000000
--- 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 52b12d0..c08c391 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 8dcd130..bb9c11d 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 444e335..79863d8 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 3ee654f..0000000
--- 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 07eb5dc..083cb57 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 3ab43ff..f63420f 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 ee2d3f7..4139ef3 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 2147ab0..d229cf8 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 acd334e..93babd3 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 $$(a)).map
+
+$(strip $(1)).rmod: $(strip $(1))
+ $$(RMODTOOL) -i $$^ -o $$@
endef
endif
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 2cb70b8..a73e667 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 0cdbb2f..9222f3b 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 1226e47..c550531 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 007bd57..21e1750 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 66b7cfb..fe3c022 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);
Stefan Reinauer (stefan.reinauer(a)coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5379
-gerrit
commit 7d8679f8ce87823d4417c30dbacf190e071062e9
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
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(a)chromium.org>
---
Makefile.inc | 6 +-
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 ++-
25 files changed, 121 insertions(+), 261 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 19ba294..fcd680d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -252,10 +252,14 @@ build-dirs:
#######################################################################
# Build the tools
CBFSTOOL:=$(obj)/cbfstool
+RMODTOOL:=$(obj)/rmodtool
$(CBFSTOOL): $(objutil)/cbfstool/cbfstool
cp $< $@
+$(RMODTOOL): $(objutil)/cbfstool/rmodtool
+ cp $< $@
+
_WINCHECK=$(shell uname -o 2> /dev/null)
STACK=
ifeq ($(_WINCHECK),Msys)
@@ -390,5 +394,5 @@ crosstools-arm: clean-for-update
crossgcc-clean: clean-for-update
$(MAKE) -C util/crossgcc clean
-tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
+tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/rmodtool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 4b28697..acb4e98 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 629c644..79c6417 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 b958c16..0000000
--- 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 01ffa7c..faea22d 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 60c061d..63c1939 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 846a82d..0000000
--- 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 664a9ee..e0abb7c 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 3f4f45a..dfbcf2e 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 277ba48..c0b50c5 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 846a82d..0000000
--- 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 52b12d0..c08c391 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 8dcd130..bb9c11d 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 444e335..79863d8 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 3ee654f..0000000
--- 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 07eb5dc..083cb57 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 3ab43ff..f63420f 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 ee2d3f7..4139ef3 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 2147ab0..d229cf8 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 acd334e..93babd3 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 $$(a)).map
+
+$(strip $(1)).rmod: $(strip $(1))
+ $$(RMODTOOL) -i $$^ -o $$@
endef
endif
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 2cb70b8..a73e667 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 0cdbb2f..9222f3b 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 1226e47..c550531 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 007bd57..21e1750 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 66b7cfb..fe3c022 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);
the following patch was just integrated into master:
commit 5cf859ce68b7890d5ca376e91d31930164522639
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Fri Mar 7 15:11:53 2014 -0600
util: add rmodtool for parsing ELF files to rmodules
The current implementation of creating rmodules relies
on invoking the linker in a certain manner with the
relocations overlaid on the BSS section. It's not really
surprising that the linker doesn't always behave the way
one wants depending on the linker used and the architecture.
Instead, introduce rmodtool which takes an ELF file as an
input, parses it, and creates a new ELF file in the format
the rmodule loader expects.
Change-Id: I31ac2d327d450ef841c3a7d9740b787278382bef
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
See http://review.coreboot.org/5378 for details.
-gerrit
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5379
-gerrit
commit 480146a4d3998bdcbff71404ec36ee83b8285dd7
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
rmodules: use rmodtool to create rmdoules
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(a)chromium.org>
---
Makefile.inc | 6 +-
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 ++-
25 files changed, 121 insertions(+), 261 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 19ba294..fcd680d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -252,10 +252,14 @@ build-dirs:
#######################################################################
# Build the tools
CBFSTOOL:=$(obj)/cbfstool
+RMODTOOL:=$(obj)/rmodtool
$(CBFSTOOL): $(objutil)/cbfstool/cbfstool
cp $< $@
+$(RMODTOOL): $(objutil)/cbfstool/rmodtool
+ cp $< $@
+
_WINCHECK=$(shell uname -o 2> /dev/null)
STACK=
ifeq ($(_WINCHECK),Msys)
@@ -390,5 +394,5 @@ crosstools-arm: clean-for-update
crossgcc-clean: clean-for-update
$(MAKE) -C util/crossgcc clean
-tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
+tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/rmodtool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 4b28697..acb4e98 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 629c644..79c6417 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 b958c16..0000000
--- 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 01ffa7c..faea22d 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 60c061d..63c1939 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 846a82d..0000000
--- 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 664a9ee..e0abb7c 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 3f4f45a..dfbcf2e 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 277ba48..c0b50c5 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 846a82d..0000000
--- 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 52b12d0..c08c391 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 8dcd130..bb9c11d 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 444e335..79863d8 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 3ee654f..0000000
--- 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 07eb5dc..083cb57 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 3ab43ff..f63420f 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 ee2d3f7..4139ef3 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 2147ab0..d229cf8 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 acd334e..93babd3 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 $$(a)).map
+
+$(strip $(1)).rmod: $(strip $(1))
+ $$(RMODTOOL) -i $$^ -o $$@
endef
endif
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 2cb70b8..a73e667 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 0cdbb2f..9222f3b 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 1226e47..c550531 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 007bd57..21e1750 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 66b7cfb..fe3c022 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);
Edward O'Callaghan (eocallaghan(a)alterapraxis.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5385
-gerrit
commit ab639d70a41f93b99dfe46e00025ed2e18defe85
Author: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
Date: Fri Mar 14 01:06:22 2014 +1100
drivers/hwm: Add a generic hwm driver.
Make generic, testing with Fintek Super I/O....
currently wired in to fintek superio, need to move arary of
values to mainboard.c??
Change-Id: Ic7bdea55907e379aad9e74b87b514e8038ef9fd0
Signed-off-by: Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
---
src/drivers/Kconfig | 1 +
src/drivers/Makefile.inc | 1 +
src/drivers/hwm/Kconfig | 6 ++
src/drivers/hwm/Makefile.inc | 20 +++++
src/drivers/hwm/superio_hwm.c | 144 ++++++++++++++++++++++++++++++
src/include/hwm/superio_hwm.h | 32 +++++++
src/mainboard/jetway/nf81-t56n-lf/Kconfig | 4 +
src/superio/fintek/f71869ad/chip.h | 1 +
src/superio/fintek/f71869ad/superio.c | 5 +-
9 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig
index 5267ff8..c09e57f 100644
--- a/src/drivers/Kconfig
+++ b/src/drivers/Kconfig
@@ -22,6 +22,7 @@ source src/drivers/dec/Kconfig
source src/drivers/elog/Kconfig
source src/drivers/emulation/Kconfig
source src/drivers/generic/Kconfig
+source src/drivers/hwm/Kconfig
source src/drivers/i2c/Kconfig
source src/drivers/ics/Kconfig
source src/drivers/intel/Kconfig
diff --git a/src/drivers/Makefile.inc b/src/drivers/Makefile.inc
index 197a900..4b944cb 100644
--- a/src/drivers/Makefile.inc
+++ b/src/drivers/Makefile.inc
@@ -39,3 +39,4 @@ subdirs-y += ipmi
subdirs-y += elog
subdirs-y += xpowers
subdirs-$(CONFIG_ARCH_X86) += pc80
+subdirs-$(CONFIG_ARCH_X86) += hwm
diff --git a/src/drivers/hwm/Kconfig b/src/drivers/hwm/Kconfig
new file mode 100644
index 0000000..dc60fd7
--- /dev/null
+++ b/src/drivers/hwm/Kconfig
@@ -0,0 +1,6 @@
+config DRIVERS_SUPERIO_HWM
+ bool "Super I/O HWM"
+ default n
+ help
+ Just enough of a driver to make coreboot control system fans.
+ No configuration is necessary for the OS to pick up the device.
diff --git a/src/drivers/hwm/Makefile.inc b/src/drivers/hwm/Makefile.inc
new file mode 100644
index 0000000..ccb6de0
--- /dev/null
+++ b/src/drivers/hwm/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+##
+## 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
+##
+
+ramstage-$(CONFIG_DRIVERS_SUPERIO_HWM) += superio_hwm.c
diff --git a/src/drivers/hwm/superio_hwm.c b/src/drivers/hwm/superio_hwm.c
new file mode 100644
index 0000000..4d87d4a
--- /dev/null
+++ b/src/drivers/hwm/superio_hwm.c
@@ -0,0 +1,144 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This code should work for all Fintek Super I/O HWM's. */
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <stdlib.h>
+#include <hwm/superio_hwm.h>
+
+/* Helper functions */
+static void write_index(u16 port, u8 reg, u8 value)
+{
+ outb(reg, port);
+ outb(value, port + 1);
+}
+
+static u8 read_index(u16 port, u8 reg)
+{
+ outb(reg, port);
+ return inb(port + 1);
+}
+/* .. */
+
+/* Initialize F71869AD hardware monitor registers, which are at 0x225. */
+/* XXX: make configurable.. */
+static void init_registers(u16 base)
+{
+ u8 reg, value;
+ int i;
+
+ /* XXX: work out correct values??? */
+ u8 hwm_reg_values[] = {
+ /* reg mask data */
+ 0x08, 0x00, 0x98, /* SMBus Address p.53 */
+ 0x0a, 0x00, 0x02, /* Configure pins 57/58 as PECI_REQ#/PECI (AMD_TSI) p.54 */
+ /* Tfan1 = Tnow + (Ta - Tb)*Ct where, */
+ 0xaf, 0x00, 0x8c, /* FAN1_TEMP_SEL_DIG, FAN1_TEMP_SEL (Tnow) set to come from CR7Ah p.73 */
+ 0x9f, 0x00, 0x8a, /* set FAN_PROG_SEL = 1 */
+ 0x94, 0x00, 0x00, /* FAN1_BASE_TEMP (Tb) set when FAN_PROG_SEL=1, p.64-65 */
+ 0x96, 0x00, 0x07, /* set TFAN1_ADJ_SEL (Ta) p.67 to use CR7Ah p.61 */
+ 0x95, 0x00, 0x22, /* TFAN1_ADJ_{UP,DOWN}_RATE (Ct=1/2 up & down) in 0x95 when FAN_PROG_SEL = 1, p.65-66 */
+ 0x9f, 0x00, 0x0a, /* set FAN_PROG_SEL = 0 */
+ /* .. */
+ 0x02, 0x00, 0x30, /* OVT_MODE p.52 */
+ 0x63, 0x00, 0x20, /* Temperature BEEP Enable Register p.58 */
+ 0x66, 0x00, 0x02, /* OVT and Alert Output Enable Register 1 p.59 */
+ 0x82, 0x00, 0x76, /* Temperature sensors 1 OVT limit p.61 */
+ 0x91, 0x00, 0x07, /* FAN Interrupt Status Register p.63 */
+ 0xa3, 0x00, 0x0e, /* FAN1 RPM mode p.70 */
+ 0xa9, 0x00, 0x14, /* VT1 Boundary 2 Temperature p.71 */
+ 0xaa, 0x00, 0xff, /* FAN1 Segment 1 Speed Count */
+ 0xab, 0x00, 0x0e, /* FAN1 Segment 2 Speed Count */
+ 0xae, 0x00, 0x07, /* FAN1 Segment 3 Speed Count */
+#if 0
+ /* ..? */
+ 0xed, 0x00, 0x01, /* SMB/TSI Command Byte p.83 */
+ 0xee, 0x00, 0x01, /* SMB_Status p.83 */
+ 0xef, 0x00, 0x89, /* SMB_Protocal p.83 */
+#endif
+ };
+
+ for (i = 0; i < ARRAY_SIZE(hwm_reg_values); i += 3) {
+ reg = hwm_reg_values[i];
+ value = read_index(base, reg);
+ value &= 0xff & hwm_reg_values[i + 1];
+ value |= 0xff & hwm_reg_values[i + 2];
+ printk(BIOS_DEBUG, "Super I/O HWM: base = 0x%04x, reg = 0x%02x, "
+ "value = 0x%02x\n", base, reg, value);
+ write_index(base, reg, value);
+ value = read_index(base, reg);
+ printk(BIOS_DEBUG, "Super I/O HWM (read back): base = 0x%04x, reg = 0x%02x, "
+ "value = 0x%02x\n", base, reg, value);
+ }
+}
+/* .. */
+
+/* Main driver */
+void hwm_init(device_t dev)
+{
+ if (!CONFIG_DRIVERS_SUPERIO_HWM)
+ return;
+
+ /* return if hwm is disabled in devicetree.cb */
+ struct drivers_superio_hwm_config *config = dev->chip_info;
+ if (!dev->enabled || !config)
+ return;
+
+ u32 hwm_base = config->base;
+
+ printk(BIOS_DEBUG, "Super I/O HWM: Initializing Hardware Monitor at pnp %04x\n"
+ , hwm_base);
+
+ struct resource *res = find_resource(dev, PNP_IDX_IO0);
+ if (!res) {
+ printk(BIOS_WARNING, "Super I/O HWM: No HWM resource found.\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "Super I/O HWM: Base Address at 0x%x\n", (u32)res->base);
+ printk(BIOS_WARNING, "Super I/O HWM: Configuring registers...\n");
+ init_registers(res->base);
+}
+
+/*
+static void hwm_noop(device_t dummy)
+{
+}
+
+static struct device_operations hwm_ops = {
+ .read_resources = hwm_noop,
+ .set_resources = hwm_noop,
+ .enable_resources = hwm_noop,
+ .init = hwm_init,
+};
+
+static void enable_dev(device_t dev)
+{
+ dev->ops = &hwm_ops;
+}
+
+struct chip_operations hwm_fintek_ops = {
+ CHIP_NAME("Super I/O Hardware Monitor.")
+ .enable_dev = enable_dev
+};
+*/
diff --git a/src/include/hwm/superio_hwm.h b/src/include/hwm/superio_hwm.h
new file mode 100644
index 0000000..49e431c
--- /dev/null
+++ b/src/include/hwm/superio_hwm.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2014 Edward O'Callaghan <eocallaghan(a)alterapraxis.com>
+ *
+ * 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
+ */
+
+#ifndef DRIVERS_SUPERIO_HWM_H
+#define DRIVERS_SUPERIO_HWM_H
+
+#include <device/device.h>
+
+/* Initialization parameters?? */
+typedef struct drivers_superio_hwm_config {
+ u32 base;
+} hwm_config_t;
+
+void hwm_init(device_t dev);
+
+#endif /* DRIVERS_SUPERIO_HWM_H */
diff --git a/src/mainboard/jetway/nf81-t56n-lf/Kconfig b/src/mainboard/jetway/nf81-t56n-lf/Kconfig
index 2d0272f..dd0b528 100644
--- a/src/mainboard/jetway/nf81-t56n-lf/Kconfig
+++ b/src/mainboard/jetway/nf81-t56n-lf/Kconfig
@@ -114,4 +114,8 @@ config DRIVERS_PS2_KEYBOARD
bool
default y
+config DRIVERS_SUPERIO_HWM
+ bool
+ default y
+
endif # BOARD_JETWAY_NF81_T56N_LF
diff --git a/src/superio/fintek/f71869ad/chip.h b/src/superio/fintek/f71869ad/chip.h
index 5b18c33..fe5be17 100644
--- a/src/superio/fintek/f71869ad/chip.h
+++ b/src/superio/fintek/f71869ad/chip.h
@@ -21,6 +21,7 @@
#ifndef SUPERIO_FINTEK_F71869AD_CHIP_H
#define SUPERIO_FINTEK_F71869AD_CHIP_H
+#include <hwm/superio_hwm.h>
#include <pc80/keyboard.h>
#include <device/device.h>
diff --git a/src/superio/fintek/f71869ad/superio.c b/src/superio/fintek/f71869ad/superio.c
index dbcb812..3c2a303 100644
--- a/src/superio/fintek/f71869ad/superio.c
+++ b/src/superio/fintek/f71869ad/superio.c
@@ -37,6 +37,9 @@ static void f71869ad_init(device_t dev)
switch(dev->path.pnp.device) {
/* TODO: Might potentially need code for HWM or FDC etc. */
+ case F71869AD_HWM:
+ hwm_init(dev);
+ break;
case F71869AD_KBC:
pc_keyboard_init(&conf->keyboard);
break;
@@ -109,7 +112,7 @@ static struct pnp_info pnp_dev_info[] = {
{ &ops, F71869AD_SP1, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
{ &ops, F71869AD_SP2, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
{ &ops, F71869AD_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x07f8, 0}, },
- { &ops, F71869AD_HWM, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, },
+ { &ops, F71869AD_HWM, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
{ &ops, F71869AD_KBC, PNP_IO0 | PNP_IRQ0 | PNP_IRQ1, {0x07ff, 0}, },
{ &ops, F71869AD_GPIO, PNP_IO0 | PNP_IRQ0, {0x07f8, 0}, },
{ &ops, F71869AD_BSEL, PNP_IO0, {0x07f8, 0}, },
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5379
-gerrit
commit ce8a6dae1214cd450d8baf3b40ff566b7024c721
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
rmodules: use rmodtool to create rmdoules
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(a)chromium.org>
---
Makefile.inc | 6 +-
src/arch/x86/Makefile.inc | 8 ++-
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 ++-
25 files changed, 115 insertions(+), 261 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 19ba294..fcd680d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -252,10 +252,14 @@ build-dirs:
#######################################################################
# Build the tools
CBFSTOOL:=$(obj)/cbfstool
+RMODTOOL:=$(obj)/rmodtool
$(CBFSTOOL): $(objutil)/cbfstool/cbfstool
cp $< $@
+$(RMODTOOL): $(objutil)/cbfstool/rmodtool
+ cp $< $@
+
_WINCHECK=$(shell uname -o 2> /dev/null)
STACK=
ifeq ($(_WINCHECK),Msys)
@@ -390,5 +394,5 @@ crosstools-arm: clean-for-update
crossgcc-clean: clean-for-update
$(MAKE) -C util/crossgcc clean
-tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
+tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/rmodtool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 4b28697..72bea1e 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -93,7 +93,7 @@ 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)
+$(obj)/coreboot.rom: $(obj)/coreboot.pre $(objcbfs)/coreboot_ram.elf $(CBFSTOOL) $(call strip_quotes,$(COREBOOT_ROM_DEPENDENCIES)) $$(INTERMEDIATE) $$(VBOOT_STUB)
@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 +140,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 +205,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 629c644..79c6417 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 b958c16..0000000
--- 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 01ffa7c..faea22d 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 60c061d..63c1939 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 846a82d..0000000
--- 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 664a9ee..e0abb7c 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 3f4f45a..dfbcf2e 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 277ba48..c0b50c5 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 846a82d..0000000
--- 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 52b12d0..c08c391 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 8dcd130..bb9c11d 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 444e335..79863d8 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 3ee654f..0000000
--- 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 07eb5dc..083cb57 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 3ab43ff..f63420f 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 ee2d3f7..4139ef3 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 2147ab0..d229cf8 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 acd334e..93babd3 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 $$(a)).map
+
+$(strip $(1)).rmod: $(strip $(1))
+ $$(RMODTOOL) -i $$^ -o $$@
endef
endif
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 2cb70b8..a73e667 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 0cdbb2f..9222f3b 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 1226e47..c550531 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 007bd57..21e1750 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 66b7cfb..fe3c022 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);
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5379
-gerrit
commit 2b6d0f407e187a7a9d609959c4a86452fe2cd124
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Mon Mar 10 16:13:58 2014 -0500
rmodules: use rmodtool to create rmdoules
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(a)chromium.org>
---
Makefile.inc | 6 +-
src/arch/x86/Makefile.inc | 8 ++-
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 ++-
25 files changed, 115 insertions(+), 261 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc
index 19ba294..fcd680d 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -252,10 +252,14 @@ build-dirs:
#######################################################################
# Build the tools
CBFSTOOL:=$(obj)/cbfstool
+RMODTOOL:=$(obj)/rmodtool
$(CBFSTOOL): $(objutil)/cbfstool/cbfstool
cp $< $@
+$(RMODTOOL): $(objutil)/cbfstool/rmodtool
+ cp $< $@
+
_WINCHECK=$(shell uname -o 2> /dev/null)
STACK=
ifeq ($(_WINCHECK),Msys)
@@ -390,5 +394,5 @@ crosstools-arm: clean-for-update
crossgcc-clean: clean-for-update
$(MAKE) -C util/crossgcc clean
-tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
+tools: $(objutil)/kconfig/conf $(objutil)/cbfstool/cbfstool $(objutil)/cbfstool/rmodtool $(objutil)/nvramtool/nvramtool $(objutil)/romcc/romcc $(objutil)/sconfig/sconfig
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 4b28697..72bea1e 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -93,7 +93,7 @@ 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)
+$(obj)/coreboot.rom: $(obj)/coreboot.pre $(objcbfs)/coreboot_ram.elf $(CBFSTOOL) $(call strip_quotes,$(COREBOOT_ROM_DEPENDENCIES)) $$(INTERMEDIATE) $$(VBOOT_STUB)
@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 +140,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 +205,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 629c644..79c6417 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 b958c16..0000000
--- 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 01ffa7c..faea22d 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 60c061d..63c1939 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 846a82d..0000000
--- 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 664a9ee..e0abb7c 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 3f4f45a..dfbcf2e 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 277ba48..c0b50c5 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 846a82d..0000000
--- 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 52b12d0..c08c391 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 8dcd130..bb9c11d 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 444e335..79863d8 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 3ee654f..0000000
--- 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 07eb5dc..083cb57 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 3ab43ff..f63420f 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 ee2d3f7..4139ef3 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 2147ab0..d229cf8 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 acd334e..93babd3 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 $$(a)).map
+
+$(strip $(1)).rmod: $(strip $(1))
+ $$(RMODTOOL) -i $$^ -o $$@
endef
endif
diff --git a/src/lib/rmodule.c b/src/lib/rmodule.c
index 2cb70b8..a73e667 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 0cdbb2f..9222f3b 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 1226e47..c550531 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 007bd57..21e1750 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 66b7cfb..fe3c022 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);