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 2be0da9ca7b4be8559ab8e46630a3d7824f8fe2e
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);
the following patch was just integrated into master:
commit b99f3635ed63c5269edc8df321d4f864b91b17ba
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 11 11:48:56 2014 -0500
cbfstool: add ELF writing support
In order to generate rmodules in the format of ELF files
there needs to be support for writing out ELF files. The
ELF writer is fairly simple. It accpets sections that can
be associated with an optional buffer (file data). For each
section flagged with SHF_ALLOC a PT_LOAD segment is generated.
There isn't smart merging of the sections into a single PT_LOAD
segment.
Change-Id: I4d1a11f2e65be2369fb3f8bff350cbb28e14c89d
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
See http://review.coreboot.org/5377 for details.
-gerrit
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 94e8afdb5ca9af58c22cce2cdb1e28c3443d61e4
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 | 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);
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 d0fcc23897cbc4b4823500638a7e5fa80167a32e
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 | 142 ++++++++++++++++++++++++++++++
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, 211 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..49bc90f
--- /dev/null
+++ b/src/drivers/hwm/superio_hwm.c
@@ -0,0 +1,142 @@
+/*
+ * 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 */
+ 0x0a, 0x00, 0x02, /* Configure pins 57/58 as PECI_REQ#/PECI (AMD_TSI) p.54 */
+ 0x08, 0x00, 0x98, /* SMBus Address p.53 */
+ 0xe9, 0x00, 0xff, /* SMB Data Buff 9 ??? */
+ 0xed, 0x00, 0x01, /* SMB/TSI Command Byte p.83 */
+ 0xee, 0x00, 0xc0, /* SMB_Status p.83 */
+ 0xef, 0x00, 0x02, /* SMB_Protocal p.83 */
+ /* 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 */
+ };
+
+ 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}, },