summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devel/porting.rst84
-rw-r--r--Documentation/devicetree/bindings/mtd/partition.rst4
-rw-r--r--Makefile6
-rw-r--r--arch/arm/boards/rockchip-rk3568-evb/board.c2
-rw-r--r--arch/arm/cpu/Kconfig1
-rw-r--r--arch/arm/cpu/Makefile2
-rw-r--r--arch/arm/cpu/common.c15
-rw-r--r--arch/arm/cpu/head_64.S33
-rw-r--r--arch/arm/cpu/psci-client.c6
-rw-r--r--arch/arm/cpu/psci-of.c5
-rw-r--r--arch/arm/cpu/psci.c2
-rw-r--r--arch/arm/cpu/uncompress.c4
-rw-r--r--arch/arm/dts/imx8mp-evk.dts4
-rw-r--r--arch/arm/include/asm/barebox-arm-head.h17
-rw-r--r--arch/arm/include/asm/barebox-arm.h45
-rw-r--r--arch/arm/include/asm/psci.h3
-rw-r--r--arch/arm/lib/pbl.lds.S9
-rw-r--r--arch/arm/mach-layerscape/ppa.c2
-rw-r--r--arch/arm/mach-mvebu/include/mach/barebox-arm-head.h17
-rw-r--r--arch/arm/mach-socfpga/arria10-init.c2
-rw-r--r--arch/arm/mach-socfpga/arria10-sdram.c20
-rw-r--r--arch/riscv/boot/uncompress.c4
-rw-r--r--arch/riscv/include/asm/sections.h3
-rw-r--r--arch/riscv/lib/reloc.c10
-rw-r--r--drivers/clk/imx/clk-imx5.c7
-rw-r--r--drivers/net/e1000/eeprom.c6
-rw-r--r--drivers/net/e1000/main.c2
-rw-r--r--images/Makefile1
-rw-r--r--include/asm-generic/memory_layout.h7
-rw-r--r--include/asm-generic/reloc.h69
-rw-r--r--include/linux/reset.h6
31 files changed, 276 insertions, 122 deletions
diff --git a/Documentation/devel/porting.rst b/Documentation/devel/porting.rst
index 01ee26e0d6..f95e8cbba3 100644
--- a/Documentation/devel/porting.rst
+++ b/Documentation/devel/porting.rst
@@ -113,6 +113,9 @@ there depends on the previously running code. If a previous stage has already
initialized the DRAM, the only thing you need to do is to set up a stack and
call the common PBL code with a memory region and your device tree blob::
+ #include <asm/barebox-arm.h>
+ #include <console.h>
+
ENTRY_FUNCTION_WITHSTACK(start_my_board, MY_STACK_TOP, r0, r1, r2)
{
extern char __dtb_my_board_start[];
@@ -128,22 +131,24 @@ call the common PBL code with a memory region and your device tree blob::
Lets look at this line by line:
- - ``ENTRY_FUNCTION_WITHSTACK(start_my_board, STACK_TOP, r0, r1, r2)``
+``ENTRY_FUNCTION_WITHSTACK(start_my_board, MY_STACK_TOP, r0, r1, r2)``
The entry point is special: It needs to be located at the beginning of the
image, it does not return and may run before a stack is set up.
To make it possible to write this entry point in C, the macro places
- a machine code prologue that uses ``STACK_TOP`` as the initial stack
+ a machine code prologue that uses ``MY_STACK_TOP`` as the initial stack
pointer. If the stack is already set up, you may pass 0 here.
Additionally, the macro passes along a number of registers, in case the
Boot ROM has placed something interesting there.
- - ``extern char __dtb_my_board_start[];``
+``extern char __dtb_my_board_start[];``
When a device tree is built as part of the PBL, ``__dtb_*_start`` and
- ``__dtb_*_end`` will be defined for it. Declare the start variable, so
- you can pass along the address of the device tree.
+ ``__dtb_*_end`` will be defined for it by the build system;
+ its name is determined by the name of the device tree source file.
+ Declare the start variable, so you can pass along the address of the device
+ tree.
- - ``relocate_to_current_adr();``
+``relocate_to_current_adr();``
Machine code contains a mixture of relative and absolute addressing.
Because the PBL doesn't know in advance which address it's loaded to,
the link address of global variables may not be correct. To correct
@@ -152,28 +157,34 @@ Lets look at this line by line:
by this function. Note that this is self-modifying code, so it's not
safe to call this when executing in-place from flash or ROM.
- - ``setup_c();``
+``setup_c();``
As a size optimization, zero-initialized variables of static storage
duration are not written to the executable. Instead only the region
where they should be located is described and at runtime that region
is zeroed. This is what ``setup_c()`` does.
- - ``pbl_set_putc(my_serial_putc, (void *)BASE_ADDR);``
+``pbl_set_putc(my_serial_putc, (void *)BASE_ADDR);``
Now that we have a C environment set up, lets set our first global
- variable. ``pbl_set_putc`` saves a function pointer that can be used
- to output a single character. This can be used for the early PBL
- console to output messages even before any drivers are initialized.
+ variable. ``pbl_set_putc`` saves a pointer to a function
+ (``my_serial_putc``) that is called by the ``pr_*`` functions to output a
+ single character. This can be used for the early PBL console to output
+ messages even before any drivers are initialized.
+ The second parameter (UART register base address in this instance) is passed
+ as a user parameter when the provided function is called.
- - ``barebox_arm_entry`` will compute a new stack top from the supplied memory
- region and uncompress barebox proper and pass along its arguments.
+``barebox_arm_entry(...)``
+ This will compute a new stack top from the supplied memory
+ region, uncompress barebox proper and pass along its arguments.
Looking at other boards you might see some different patterns:
- - ``*_cpu_lowlevel_init();``: Often some common initialization and quirk handling
+``*_cpu_lowlevel_init();``
+ Often some common initialization and quirk handling
needs to be done at start. If a board similar to yours does this, you probably
want to do likewise.
- - ``__naked``: All functions called before stack is correctly initialized must be
+``__naked``
+ All functions called before stack is correctly initialized must be
marked with this attribute. Otherwise, function prologue and epilogue may access
the uninitialized stack. Note that even with ``__naked``, the compiler may still
spill excess local C variables used in a naked function to the stack before it
@@ -184,39 +195,45 @@ Looking at other boards you might see some different patterns:
by using ``ENTRY_FUNCTION_WITHSTACK``, which will take care to initialize the
stack beforehand. If either a barebox assembly entry point,
``ENTRY_FUNCTION_WITHSTACK`` or earlier firmware has set up the stack, there is
- no reason to use ``__naked``, just use ``ENTRY_FNCTION_WITHSTACK`` with a zero
+ no reason to use ``__naked``, just use ``ENTRY_FUNCTION_WITHSTACK`` with a zero
stack top.
- - ``noinline``: Compiler code inlining is oblivious to stack manipulation in
+``noinline``
+ Compiler code inlining is oblivious to stack manipulation in
inline assembly. If you want to ensure a new function has its own stack frame
(e.g. after setting up the stack in a ``__naked`` function), you must jump to
- a ``__noreturn noinline`` function.
+ a ``__noreturn noinline`` function. This is already handled by
+ ``ENTRY_FUNCTION_WITHSTACK``.
- - ``arm_setup_stack``: For 32-bit ARM, ``arm_setup_stack`` initializes the stack
+``arm_setup_stack``
+ For 32-bit ARM, ``arm_setup_stack`` initializes the stack
top when called from a naked C function, which allowed to write the entry point
directly in C. Modern code should use ``ENTRY_FUNCTION_WITHSTACK`` instead.
Note that in both cases the stack pointer will be decremented before pushing values.
Avoid interleaving with C-code. See ``__naked`` above for more details.
- - ``__dtb_z_my_board_start[];``: Because the PBL normally doesn't parse anything out
+``__dtb_z_my_board_start[];``
+ Because the PBL normally doesn't parse anything out
of the device tree blob, boards can benefit from keeping the device tree blob
- compressed and only unpack it in barebox proper. Such LZO-compressed device trees
+ compressed and only unpack it in barebox proper. Such compressed device trees
are prefixed with ``__dtb_z_``. It's usually a good idea to use this.
- - ``imx6q_barebox_entry(...);`` Sometimes it's possible to query the memory
+``imx6q_barebox_entry(...);``
+ Sometimes it's possible to query the memory
controller for the size of RAM. If there are SoC-specific helpers to achieve
this, you should use them.
- - ``get_runtime_offset()/global_variable_offset()`` returns the difference
+``get_runtime_offset()/global_variable_offset()``
+ This functions return the difference
between the link and load address. This is zero after relocation, but the
function can be useful to pass along the correct address of a variable when
relocation has not yet occurred. If you need to use this for anything more
then passing along the FDT address, you should reconsider and probably rather
call ``relocate_to_current_adr();``.
- - ``*_start_image(...)/*_load_image(...)/*_xload_*(...)``:
+``*_start_image(...)/*_load_image(...)/*_xload_*(...)``
If the SRAM couldn't fit both PBL and the compressed barebox proper, PBL
- will need to chainload full barebox binary from disk.
+ will need to chainload full barebox binary from the boot medium.
Repeating previous advice: The specifics about how different SoCs handle
things can vary widely. You're best served by mimicking a similar recently
@@ -388,9 +405,18 @@ New header format
=================
Your loader may require a specific header or format. If the header is meant
-to be executable, it should preferably be added as inline assembly to
-the start of the PBL entry points. See ``__barebox_arm_head`` and
-``__barebox_riscv_header``. Otherwise, add a new tool to ``scripts/``
+to be executable, it should be written in assembly.
+If the C compiler for that platform supports ``__attribute__((naked))``, it
+can be written in inline assembly inside such a naked function. See for
+example ``__barebox_arm_head`` for ARM32 or ``__barebox_riscv_header`` for RISC-V.
+
+For platforms, without naked function support, inline assembly may not be used
+and the entry point should be written in a dedicated assembly file.
+This is the case with ARM64, see for example ``__barebox_arm64_head`` and the
+``ENTRY_PROC`` macro.
+
+Another way, which is often used for non-executable headers with extra
+meta-information like a checksum, is adding a new tool to ``scripts/``
and have it run as part the image build process. ``images/`` contains
various examples.
@@ -418,7 +444,7 @@ well as its prerequisites like clocks, resets or pin multiplexers.
Examples for this are the i.MX xload functions. Some BootROMs boot from
a FAT file system. There is vfat support in the PBL. Refer to the sama5d2
-baord support for an example.
+board support for an example.
Core drivers
============
diff --git a/Documentation/devicetree/bindings/mtd/partition.rst b/Documentation/devicetree/bindings/mtd/partition.rst
index 6db54070a9..627b59eda0 100644
--- a/Documentation/devicetree/bindings/mtd/partition.rst
+++ b/Documentation/devicetree/bindings/mtd/partition.rst
@@ -4,7 +4,7 @@ Representing flash partitions in devicetree
In addition to the upstream binding, another property is added:
Optional properties:
-- ``partuuid`` : The partition UUID for this partition.
+- ``partuuid`` : The global partition UUID for this partition.
Additionally, barebox also supports partitioning the eMMC boot partitions if
the partition table node is named appropriately:
@@ -16,7 +16,7 @@ Examples:
.. code-block:: none
- flash@0 {
+ / {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
diff --git a/Makefile b/Makefile
index d7f1e3779a..fc11189d23 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 2022
-PATCHLEVEL = 10
+PATCHLEVEL = 11
SUBLEVEL = 0
EXTRAVERSION =
NAME = None
@@ -659,6 +659,10 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-check)
# Platforms that have their setjmp appropriately implemented may override this
KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
+# We don't have the necessary infrastructure to benefit from ARMv8.3+ pointer
+# authentication. On older CPUs, they are interpreted as NOPs bloating the code
+KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none)
+
KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
# Align the bit size of userspace programs with the kernel
diff --git a/arch/arm/boards/rockchip-rk3568-evb/board.c b/arch/arm/boards/rockchip-rk3568-evb/board.c
index 212c801c93..ef886e67ed 100644
--- a/arch/arm/boards/rockchip-rk3568-evb/board.c
+++ b/arch/arm/boards/rockchip-rk3568-evb/board.c
@@ -94,7 +94,7 @@ static int rk3568_evb_detect_hwid(void)
return 0;
err_hwid:
- pr_err("couldn't retrieve hardware ID");
+ pr_err("couldn't retrieve hardware ID\n");
return ret;
}
late_initcall(rk3568_evb_detect_hwid);
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 9b5a833abf..3ef3604737 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -16,6 +16,7 @@ config CPU_64
bool
select PHYS_ADDR_T_64BIT
select HAVE_PBL_IMAGE
+ select HAVE_PBL_MULTI_IMAGES
select HAS_DMA
# Select CPU types depending on the architecture selected. This selects
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index c0993c1abe..7674c1464c 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -13,6 +13,8 @@ AFLAGS_hyp.pbl.o :=-Wa,-march=armv7-a -Wa,-mcpu=all
obj-y += start.o entry.o entry_ll$(S64).o
KASAN_SANITIZE_start.o := n
+pbl-$(CONFIG_CPU_64) += head_64.o
+
pbl-$(CONFIG_BOARD_ARM_GENERIC_DT) += board-dt-2nd.o
pbl-$(CONFIG_BOARD_ARM_GENERIC_DT_AARCH64) += board-dt-2nd-aarch64.o
diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c
index 7cd97e938b..47da9fbe49 100644
--- a/arch/arm/cpu/common.c
+++ b/arch/arm/cpu/common.c
@@ -61,16 +61,19 @@ void pbl_barebox_break(void)
*/
void relocate_to_current_adr(void)
{
- unsigned long offset, offset_var;
+ unsigned long offset;
unsigned long __maybe_unused *dynsym, *dynend;
void *dstart, *dend;
/* Get offset between linked address and runtime address */
offset = get_runtime_offset();
- offset_var = global_variable_offset();
- dstart = (void *)__rel_dyn_start + offset_var;
- dend = (void *)__rel_dyn_end + offset_var;
+ /*
+ * We have yet to relocate, so using runtime_address
+ * to compute the relocated address
+ */
+ dstart = runtime_address(__rel_dyn_start);
+ dend = runtime_address(__rel_dyn_end);
#if defined(CONFIG_CPU_64)
while (dstart < dend) {
@@ -96,8 +99,8 @@ void relocate_to_current_adr(void)
dstart += sizeof(*rel);
}
#elif defined(CONFIG_CPU_32)
- dynsym = (void *)__dynsym_start + offset_var;
- dynend = (void *)__dynsym_end + offset_var;
+ dynsym = runtime_address(__dynsym_start);
+ dynend = runtime_address(__dynsym_end);
while (dstart < dend) {
struct elf32_rel *rel = dstart;
diff --git a/arch/arm/cpu/head_64.S b/arch/arm/cpu/head_64.S
new file mode 100644
index 0000000000..f934e96c6e
--- /dev/null
+++ b/arch/arm/cpu/head_64.S
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <linux/linkage.h>
+#include <asm/barebox-arm64.h>
+#include <asm/image.h>
+
+/* Linker will point these at board-specific symbols */
+.globl __pbl_board_stack_top
+.globl __pbl_board_entry
+
+.section .text_head_prologue_common, "x"
+ENTRY(__barebox_arm64_head)
+ nop
+ adr x9, __pbl_board_stack_top
+ ldr w9, [x9]
+ cbz x9, 1f
+ mov sp, x9
+1:
+#ifdef CONFIG_PBL_BREAK
+ brk #17
+ nop
+#else
+ nop
+ nop
+#endif
+ b __pbl_board_entry
+ .org 0x20
+ .asciz "barebox"
+ .word 0xffffffff
+ .word _barebox_image_size /* image size to copy */
+ .rept 8
+ .word 0x55555555
+ .endr
+END(__barebox_arm64_head)
diff --git a/arch/arm/cpu/psci-client.c b/arch/arm/cpu/psci-client.c
index 7d5b3768b5..f9b1c684bf 100644
--- a/arch/arm/cpu/psci-client.c
+++ b/arch/arm/cpu/psci-client.c
@@ -108,9 +108,9 @@ static u32 invoke_psci_fn_smc(ulong function, ulong arg0, ulong arg1, ulong arg2
return res.a0;
}
-static int of_psci_do_fixup(struct device_node *root, void *context)
+static int of_psci_do_fixup(struct device_node *root, void *method)
{
- return of_psci_fixup(root, *(u32 *)context);
+ return of_psci_fixup(root, version, (const void *)method);
}
static int __init psci_probe(struct device_d *dev)
@@ -156,7 +156,7 @@ static int __init psci_probe(struct device_d *dev)
version >> 16, version & 0xffff);
if (actual_version != of_version)
- of_register_fixup(of_psci_do_fixup, &version);
+ of_register_fixup(of_psci_do_fixup, (void *)method);
ret = poweroff_handler_register_fn(psci_poweroff);
if (ret)
diff --git a/arch/arm/cpu/psci-of.c b/arch/arm/cpu/psci-of.c
index ef83b0edee..be16b08617 100644
--- a/arch/arm/cpu/psci-of.c
+++ b/arch/arm/cpu/psci-of.c
@@ -7,7 +7,8 @@
#include <asm/psci.h>
#include <linux/arm-smccc.h>
-int of_psci_fixup(struct device_node *root, unsigned long psci_version)
+int of_psci_fixup(struct device_node *root, unsigned long psci_version,
+ const char *method)
{
struct device_node *psci;
int ret;
@@ -46,7 +47,7 @@ int of_psci_fixup(struct device_node *root, unsigned long psci_version)
if (ret)
return ret;
- ret = of_property_write_string(psci, "method", "smc");
+ ret = of_property_write_string(psci, "method", method);
if (ret)
return ret;
diff --git a/arch/arm/cpu/psci.c b/arch/arm/cpu/psci.c
index d1056e0659..70c97e03a5 100644
--- a/arch/arm/cpu/psci.c
+++ b/arch/arm/cpu/psci.c
@@ -189,7 +189,7 @@ static int of_psci_do_fixup(struct device_node *root, void *unused)
if (bootm_arm_security_state() < ARM_STATE_NONSECURE)
return 0;
- return of_psci_fixup(root, ARM_PSCI_VER_1_0);
+ return of_psci_fixup(root, ARM_PSCI_VER_1_0, "smc");
}
int psci_cpu_entry_c(void)
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 537ee63229..65de87f109 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -53,8 +53,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
unsigned long pc = get_pc();
/* piggy data is not relocated, so determine the bounds now */
- pg_start = input_data + global_variable_offset();
- pg_end = input_data_end + global_variable_offset();
+ pg_start = runtime_address(input_data);
+ pg_end = runtime_address(input_data_end);
if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) {
/*
diff --git a/arch/arm/dts/imx8mp-evk.dts b/arch/arm/dts/imx8mp-evk.dts
index 3264ade4b8..77b438287c 100644
--- a/arch/arm/dts/imx8mp-evk.dts
+++ b/arch/arm/dts/imx8mp-evk.dts
@@ -35,6 +35,10 @@
reset-deassert-us = <100000>;
};
+&reg_usdhc2_vmmc {
+ off-on-delay-us = <20000>;
+};
+
&usdhc2 {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h
index 099e1bef3c..1a1d58c1aa 100644
--- a/arch/arm/include/asm/barebox-arm-head.h
+++ b/arch/arm/include/asm/barebox-arm-head.h
@@ -18,13 +18,13 @@ void barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2);
#define ARM_HEAD_SPARE_OFS 0x30
#define ARM_HEAD_SPARE_MARKER 0x55555555
+#ifdef CONFIG_CPU_32
#ifdef CONFIG_HAVE_MACH_ARM_HEAD
#include <mach/barebox-arm-head.h>
#else
static inline void __barebox_arm_head(void)
{
__asm__ __volatile__ (
-#ifdef CONFIG_CPU_32
#ifdef CONFIG_THUMB2_BAREBOX
".arm\n"
"adr r9, 1f + 1\n"
@@ -45,31 +45,17 @@ static inline void __barebox_arm_head(void)
"1: b 1b\n"
"1: b 1b\n"
#endif
-#else
- /* 5 instructions added by ENTRY_FUNCTION */
- /* two instruction long function prologue */
- /* only use if stack is initialized! */
- "b 2f\n"
-#endif
".asciz \"barebox\"\n"
-#ifdef CONFIG_CPU_32
".word _text\n" /* text base. If copied there,
* barebox can skip relocation
*/
-#else
- ".word 0xffffffff\n"
-#endif
".word _barebox_image_size\n" /* image size to copy */
".rept 8\n"
".word 0x55555555\n"
".endr\n"
"2:\n"
#ifdef CONFIG_PBL_BREAK
-#ifdef CONFIG_CPU_V8
- "brk #17\n"
-#else
"bkpt #17\n"
-#endif
"nop\n"
#else
"nop\n"
@@ -85,6 +71,7 @@ static inline void barebox_arm_head(void)
);
}
#endif
+#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index a34f77f2ab..dd12f642d9 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -136,24 +136,7 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase,
}
}
-#ifdef CONFIG_CPU_64
-
-#define ____emit_entry_prologue(name, instr, ...) do { \
- static __attribute__ ((unused,section(".text_head_prologue_" __stringify(name)))) \
- const u32 __entry_prologue[] = {(instr), ##__VA_ARGS__}; \
- barrier_data(__entry_prologue); \
-} while(0)
-
-#define __emit_entry_prologue(name, instr1, instr2, instr3, instr4, instr5) \
- ____emit_entry_prologue(name, instr1, instr2, instr3, instr4, instr5)
-
-#define __ARM_SETUP_STACK(name, stack_top) \
- __emit_entry_prologue(name, 0x14000002 /* b pc+0x8 */, \
- stack_top /* 32-bit literal */, \
- 0x18ffffe9 /* ldr w9, top */, \
- 0xb4000049 /* cbz x9, pc+0x8 */, \
- 0x9100013f /* mov sp, x9 */)
-#else
+#ifndef CONFIG_CPU_64
#define __ARM_SETUP_STACK(name, stack_top) if (stack_top) arm_setup_stack(stack_top)
#endif
@@ -166,6 +149,9 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase,
* code block will not be inlined and may spill to stack right away.
*/
#ifdef CONFIG_CPU_64
+
+void __barebox_arm64_head(ulong x0, ulong x1, ulong x2);
+
#define ENTRY_FUNCTION_WITHSTACK(name, stack_top, arg0, arg1, arg2) \
void name(ulong r0, ulong r1, ulong r2); \
\
@@ -174,39 +160,44 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase,
void __section(.text_head_entry_##name) name \
(ulong r0, ulong r1, ulong r2) \
{ \
- __barebox_arm_head(); \
- __ARM_SETUP_STACK(name, stack_top); \
+ static __section(.pbl_board_stack_top_##name) \
+ const u32 __stack_top = (stack_top); \
+ __keep_symbolref(__barebox_arm64_head); \
+ __keep_symbolref(__stack_top); \
__##name(r0, r1, r2); \
} \
static void noinline __##name \
(ulong arg0, ulong arg1, ulong arg2)
+
+#define ENTRY_FUNCTION(name, arg0, arg1, arg2) \
+ ENTRY_FUNCTION_WITHSTACK(name, 0, arg0, arg1, arg2)
+
#else
#define ENTRY_FUNCTION_WITHSTACK(name, stack_top, arg0, arg1, arg2) \
static void ____##name(ulong, ulong, ulong); \
ENTRY_FUNCTION(name, arg0, arg1, arg2) \
{ \
- __ARM_SETUP_STACK(name, stack_top); \
+ if (stack_top) \
+ arm_setup_stack(stack_top); \
____##name(arg0, arg1, arg2); \
} \
static void noinline ____##name \
(ulong arg0, ulong arg1, ulong arg2)
-#endif
-
#define ENTRY_FUNCTION(name, arg0, arg1, arg2) \
void name(ulong r0, ulong r1, ulong r2); \
\
static void __##name(ulong, ulong, ulong); \
\
- void NAKED __section(.text_head_entry_##name) name \
+ void __naked __section(.text_head_entry_##name) name \
(ulong r0, ulong r1, ulong r2) \
{ \
__barebox_arm_head(); \
- __ARM_SETUP_STACK(name, 0); \
__##name(r0, r1, r2); \
} \
- static void NAKED noinline __##name \
- (ulong arg0, ulong arg1, ulong arg2)
+ static void __naked noinline __##name \
+ (ulong arg0, ulong arg1, ulong arg2)
+#endif
/*
* When using compressed images in conjunction with relocatable images
diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
index 3c1d046eb9..dbb9adfc3e 100644
--- a/arch/arm/include/asm/psci.h
+++ b/arch/arm/include/asm/psci.h
@@ -144,6 +144,7 @@ static inline int psci_printf(const char *fmt, ...)
int psci_get_cpu_id(void);
-int of_psci_fixup(struct device_node *root, unsigned long psci_version);
+int of_psci_fixup(struct device_node *root, unsigned long psci_version,
+ const char *method);
#endif /* __ARM_PSCI_H__ */
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index ae1babdcfd..114ec7bc81 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -44,6 +44,15 @@ SECTIONS
. = ALIGN(4);
.rodata : { *(.rodata*) }
+ . = ALIGN(4);
+ __pbl_board_stack_top = .;
+ .rodata.pbl_board_stack_top : {
+ *(.pbl_board_stack_top_*)
+ /* Dummy for when BootROM sets up usable stack */
+ LONG(0x00000000);
+ }
+ ASSERT(. - __pbl_board_stack_top <= 8, "Only One PBL per Image allowed")
+
.barebox_imd : { BAREBOX_IMD }
_etext = .; /* End of text and rodata section */
diff --git a/arch/arm/mach-layerscape/ppa.c b/arch/arm/mach-layerscape/ppa.c
index d962fba751..144d052475 100644
--- a/arch/arm/mach-layerscape/ppa.c
+++ b/arch/arm/mach-layerscape/ppa.c
@@ -46,7 +46,7 @@ static int of_psci_do_fixup(struct device_node *root, void *unused)
break;
}
- return of_psci_fixup(root, psci_version);
+ return of_psci_fixup(root, psci_version, "smc");
}
static int ppa_init(void *ppa, size_t ppa_size, void *sec_firmware_addr)
diff --git a/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h
index 12f8cfc5a0..2ef3377402 100644
--- a/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h
+++ b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h
@@ -6,7 +6,6 @@
static inline void __barebox_arm_head(void)
{
__asm__ __volatile__ (
-#ifdef CONFIG_CPU_32
#ifdef CONFIG_THUMB2_BAREBOX
".arm\n"
"adr r9, 1f + 1\n"
@@ -27,22 +26,10 @@ static inline void __barebox_arm_head(void)
"1: b 1b\n"
"1: b 1b\n"
#endif
-#else
- "b 2f\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
-#endif
".asciz \"barebox\"\n"
-#ifdef CONFIG_CPU_32
".word _text\n" /* text base. If copied there,
* barebox can skip relocation
*/
-#else
- ".word 0xffffffff\n"
-#endif
".word _barebox_image_size\n" /* image size to copy */
/*
@@ -58,11 +45,7 @@ static inline void __barebox_arm_head(void)
".endr\n"
"2:\n"
#ifdef CONFIG_PBL_BREAK
-#ifdef CONFIG_CPU_V8
- "brk #17\n"
-#else
"bkpt #17\n"
-#endif
"nop\n"
#else
"nop\n"
diff --git a/arch/arm/mach-socfpga/arria10-init.c b/arch/arm/mach-socfpga/arria10-init.c
index 2fa44c21c5..93bc3368d3 100644
--- a/arch/arm/mach-socfpga/arria10-init.c
+++ b/arch/arm/mach-socfpga/arria10-init.c
@@ -174,7 +174,7 @@ void arria10_init(struct arria10_mainpll_cfg *mainpll,
* Enable address filtering (Bit[0])
*/
writel(0x00000001, ARRIA10_MPUL2_ADRFLTR_START);
- writel(0x00000002, ARRIA10_SYSMGR_NOC_ADDR_REMAP_VALUE);
+ writel(0x00000000, ARRIA10_SYSMGR_NOC_ADDR_REMAP_VALUE);
arria10_reset_peripherals();
diff --git a/arch/arm/mach-socfpga/arria10-sdram.c b/arch/arm/mach-socfpga/arria10-sdram.c
index 35c355df71..a6eb63299a 100644
--- a/arch/arm/mach-socfpga/arria10-sdram.c
+++ b/arch/arm/mach-socfpga/arria10-sdram.c
@@ -468,6 +468,18 @@ static void arria10_sdram_mmr_init(void)
}
}
+static void arria10_f2sdram_bridges_reset(void)
+{
+ uint32_t val;
+
+ /* Release F2SDRAM bridges from reset */
+ val = readl(ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_BRGMODRST);
+ val &= ~(ARRIA10_RSTMGR_BRGMODRST_F2SSDRAM0 |
+ ARRIA10_RSTMGR_BRGMODRST_F2SSDRAM1 |
+ ARRIA10_RSTMGR_BRGMODRST_F2SSDRAM2);
+ writel(val, ARRIA10_RSTMGR_ADDR + ARRIA10_RSTMGR_BRGMODRST);
+}
+
static int arria10_sdram_firewall_setup(void)
{
uint32_t mpu_en = 0;
@@ -486,7 +498,7 @@ static int arria10_sdram_firewall_setup(void)
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_MPUREGION3ADDR);
writel(0xffff0000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM0REGION0ADDR);
- mpu_en |= ARRIA10_NOC_FW_DDR_MPU_MPUREG1EN;
+ mpu_en |= ARRIA10_NOC_FW_DDR_MPU_F2SDR0REG0EN;
writel(mpu_en, ARRIA10_SDR_FW_MPU_FPGA_EN);
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM0REGION1ADDR);
@@ -494,7 +506,7 @@ static int arria10_sdram_firewall_setup(void)
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM0REGION3ADDR);
writel(0xffff0000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM1REGION0ADDR);
- mpu_en |= ARRIA10_NOC_FW_DDR_MPU_MPUREG2EN;
+ mpu_en |= ARRIA10_NOC_FW_DDR_MPU_F2SDR1REG0EN;
writel(mpu_en, ARRIA10_SDR_FW_MPU_FPGA_EN);
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM1REGION1ADDR);
@@ -502,7 +514,7 @@ static int arria10_sdram_firewall_setup(void)
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM1REGION3ADDR);
writel(0xffff0000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM2REGION0ADDR);
- mpu_en |= ARRIA10_NOC_FW_DDR_MPU_MPUREG3EN;
+ mpu_en |= ARRIA10_NOC_FW_DDR_MPU_F2SDR2REG0EN;
writel(mpu_en, ARRIA10_SDR_FW_MPU_FPGA_EN);
writel(0x00000000, ARRIA10_SDR_FW_MPU_FPGA_FPGA2SDRAM2REGION1ADDR);
@@ -512,6 +524,8 @@ static int arria10_sdram_firewall_setup(void)
writel(0xffff0000, ARRIA10_NOC_FW_DDR_L3_HPSREGION0ADDR);
writel(ARRIA10_NOC_FW_DDR_L3_HPSREG0EN, ARRIA10_NOC_FW_DDR_L3_EN);
+ arria10_f2sdram_bridges_reset();
+
return 0;
}
diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
index ee24f81e01..84142acf9c 100644
--- a/arch/riscv/boot/uncompress.c
+++ b/arch/riscv/boot/uncompress.c
@@ -36,8 +36,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
irq_init_vector(riscv_mode());
/* piggy data is not relocated, so determine the bounds now */
- pg_start = input_data + get_runtime_offset();
- pg_end = input_data_end + get_runtime_offset();
+ pg_start = runtime_address(input_data);
+ pg_end = runtime_address(input_data_end);
pg_len = pg_end - pg_start;
uncompressed_len = input_data_len();
diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
index 6673648bcd..cea039cc5e 100644
--- a/arch/riscv/include/asm/sections.h
+++ b/arch/riscv/include/asm/sections.h
@@ -6,6 +6,7 @@
#include <asm-generic/sections.h>
#include <linux/types.h>
#include <asm/unaligned.h>
+#include <asm/reloc.h>
extern char __rel_dyn_start[];
extern char __rel_dyn_end[];
@@ -19,7 +20,7 @@ unsigned long get_runtime_offset(void);
static inline unsigned int input_data_len(void)
{
- return get_unaligned((const u32 *)(input_data_end + get_runtime_offset() - 4));
+ return get_unaligned((const u32 *)runtime_address(input_data_end) - 1);
}
#endif
diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
index 13118a9ac5..0c1ec8b488 100644
--- a/arch/riscv/lib/reloc.c
+++ b/arch/riscv/lib/reloc.c
@@ -42,9 +42,13 @@ void relocate_to_current_adr(void)
if (!offset)
return;
- dstart = __rel_dyn_start + offset;
- dend = __rel_dyn_end + offset;
- dynsym = (void *)__dynsym_start + offset;
+ /*
+ * We have yet to relocate, so using runtime_address
+ * to compute the relocated address
+ */
+ dstart = runtime_address(__rel_dyn_start);
+ dend = runtime_address(__rel_dyn_end);
+ dynsym = runtime_address(__dynsym_start);
for (rela = dstart; (void *)rela < dend; rela++) {
unsigned long *fixup;
diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c
index c7a1818bd7..81af9a9c88 100644
--- a/drivers/clk/imx/clk-imx5.c
+++ b/drivers/clk/imx/clk-imx5.c
@@ -205,6 +205,8 @@ static void __init mx5_clocks_common_init(struct device_d *dev, void __iomem *ba
writel(0xffffffff, base + CCM_CCGR6);
writel(0xffffffff, base + CCM_CCGR7);
+ clks[IMX5_CLK_DUMMY] = clk_fixed("dummy", 0);
+
if (!IS_ENABLED(CONFIG_COMMON_CLK_OF_PROVIDER) || !dev->device_node) {
clks[IMX5_CLK_CKIL] = clk_fixed("ckil", 32768);
clks[IMX5_CLK_OSC] = clk_fixed("osc", 24000000);
@@ -312,6 +314,7 @@ static int __init mx50_clocks_init(struct device_d *dev, void __iomem *regs)
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM1_BASE_ADDR, "per");
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX50_PWM2_BASE_ADDR, "per");
clkdev_add_physbase(clks[IMX5_CLK_AHB], MX50_OTG_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX50_WDOG1_BASE_ADDR, NULL);
return 0;
}
@@ -392,6 +395,8 @@ static int __init mx51_clocks_init(struct device_d *dev, void __iomem *regs)
clkdev_add_physbase(clks[IMX5_CLK_IPG], MX51_ATA_BASE_ADDR, NULL);
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM1_BASE_ADDR, "per");
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX51_PWM2_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX51_WDOG_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX51_WDOG2_BASE_ADDR, NULL);
if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
mx51_clocks_ipu_init(regs);
@@ -488,6 +493,8 @@ static int __init mx53_clocks_init(struct device_d *dev, void __iomem *regs)
clkdev_add_physbase(clks[IMX5_CLK_AHB], MX53_SATA_BASE_ADDR, NULL);
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM1_BASE_ADDR, "per");
clkdev_add_physbase(clks[IMX5_CLK_PER_ROOT], MX53_PWM2_BASE_ADDR, "per");
+ clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX53_WDOG1_BASE_ADDR, NULL);
+ clkdev_add_physbase(clks[IMX5_CLK_DUMMY], MX53_WDOG2_BASE_ADDR, NULL);
if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
mx53_clocks_ipu_init(regs);
diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c
index 1072bc54ef..27143bd6d0 100644
--- a/drivers/net/e1000/eeprom.c
+++ b/drivers/net/e1000/eeprom.c
@@ -800,7 +800,7 @@ int e1000_validate_eeprom_checksum(struct e1000_hw *hw)
/* Read the EEPROM */
if (e1000_read_eeprom(hw, 0, EEPROM_CHECKSUM_REG + 1, buf) < 0) {
- dev_err(&hw->edev.dev, "Unable to read EEPROM!\n");
+ dev_err(hw->dev, "Unable to read EEPROM!\n");
return -E1000_ERR_EEPROM;
}
@@ -816,8 +816,8 @@ int e1000_validate_eeprom_checksum(struct e1000_hw *hw)
return 0;
/* Hrm, verification failed, print an error */
- dev_err(&hw->edev.dev, "EEPROM checksum is incorrect!\n");
- dev_err(&hw->edev.dev, " ...register was 0x%04hx, calculated 0x%04hx\n",
+ dev_err(hw->dev, "EEPROM checksum is incorrect!\n");
+ dev_err(hw->dev, " ...register was 0x%04hx, calculated 0x%04hx\n",
checksum_reg, checksum);
return -E1000_ERR_EEPROM;
diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c
index 363730de0a..1f84cf2949 100644
--- a/drivers/net/e1000/main.c
+++ b/drivers/net/e1000/main.c
@@ -3226,7 +3226,7 @@ static int e1000_sw_init(struct eth_device *edev)
/* identify the MAC */
result = e1000_set_mac_type(hw);
if (result) {
- dev_err(&hw->edev.dev, "Unknown MAC Type\n");
+ dev_err(hw->dev, "Unknown MAC Type\n");
return result;
}
diff --git a/images/Makefile b/images/Makefile
index 218a24ff1d..aa5814710f 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -59,6 +59,7 @@ $(pbl-lds): $(obj)/../arch/$(SRCARCH)/lib/pbl.lds.S FORCE
quiet_cmd_elf__ ?= LD $@
cmd_elf__ ?= $(LD) $(LDFLAGS_pbl) --gc-sections \
-e $(2) -Map $@.map $(LDFLAGS_$(@F)) -o $@ \
+ --defsym=__pbl_board_entry=$(2) \
-T $(pbl-lds) \
--whole-archive $(BAREBOX_PBL_OBJS) $(obj)/piggy.o \
$(obj)/sha_sum.o
diff --git a/include/asm-generic/memory_layout.h b/include/asm-generic/memory_layout.h
index 5cfd2a43a0..7593e18da1 100644
--- a/include/asm-generic/memory_layout.h
+++ b/include/asm-generic/memory_layout.h
@@ -23,4 +23,11 @@
#define MALLOC_SIZE CONFIG_MALLOC_SIZE
#define STACK_SIZE CONFIG_STACK_SIZE
+/*
+ * This generates a useless load from the specified symbol
+ * to ensure linker garbage collection doesn't delete it
+ */
+#define __keep_symbolref(sym) \
+ __asm__ __volatile__("": :"r"(&sym) :)
+
#endif /* __ASM_GENERIC_MEMORY_LAYOUT_H */
diff --git a/include/asm-generic/reloc.h b/include/asm-generic/reloc.h
index 90459371eb..06fccbd6f3 100644
--- a/include/asm-generic/reloc.h
+++ b/include/asm-generic/reloc.h
@@ -3,8 +3,77 @@
#ifndef _ASM_GENERIC_RELOC_H_
#define _ASM_GENERIC_RELOC_H_
+#include <linux/build_bug.h>
+#include <linux/compiler.h>
+
#ifndef global_variable_offset
#define global_variable_offset() get_runtime_offset()
#endif
+/*
+ * Using sizeof() on incomplete types always fails, so we use GCC's
+ * __builtin_object_size() instead. This is the mechanism underlying
+ * FORTIFY_SOURCE. &symbol should always be something GCC can compute
+ * a size for, even without annotations, unless it's incomplete.
+ * The second argument ensures we get 0 for failure.
+ */
+#define __has_type_complete(sym) __builtin_object_size(&(sym), 2)
+
+#define __has_type_byte_array(sym) (sizeof(*sym) == 1 + __must_be_array(sym))
+
+/*
+ * runtime_address() defined below is supposed to be used exclusively
+ * with linker defined symbols, e.g. unsigned char input_end[].
+ *
+ * We can't completely ensure that, but this gets us close enough
+ * to avoid most abuse of runtime_address().
+ */
+#define __is_incomplete_byte_array(sym) \
+ (!__has_type_complete(sym) && __has_type_byte_array(sym))
+
+/*
+ * While accessing global variables before C environment is setup is
+ * questionable, we can't avoid it when we decide to write our
+ * relocation routines in C. This invites a tricky problem with
+ * this naive code:
+ *
+ * var = &variable + global_variable_offset(); relocate_to_current_adr();
+ *
+ * Compiler is within rights to rematerialize &variable after
+ * relocate_to_current_adr(), which is unfortunate because we
+ * then end up adding a relocated &variable with the relocation
+ * offset once more. We avoid this here by hiding address with
+ * RELOC_HIDE. This is required as a simple compiler barrier()
+ * with "memory" clobber is not immune to compiler proving that
+ * &sym fits in a register and as such is unaffected by the memory
+ * clobber. barrier_data(&sym) would work too, but that comes with
+ * aforementioned compiler "memory" barrier, that we don't care for.
+ *
+ * We don't necessarily need the volatile variable assignment when
+ * using the compiler-gcc.h RELOC_HIDE implementation as __asm__
+ * __volatile__ takes care of it, but the generic RELOC_HIDE
+ * implementation has GCC misscompile runtime_address() when not passing
+ * in a volatile object. Volatile casts instead of variable assignments
+ * also led to miscompilations with GCC v11.1.1 for THUMB2.
+ */
+
+#define runtime_address(sym) ({ \
+ void *volatile __addrof_sym = (sym); \
+ if (!__is_incomplete_byte_array(sym)) \
+ __unsafe_runtime_address(); \
+ RELOC_HIDE(__addrof_sym, global_variable_offset()); \
+})
+
+/*
+ * Above will fail for "near" objects, e.g. data in the same
+ * translation unit or with LTO, as the compiler can be smart
+ * enough to omit relocation entry and just generate PC relative
+ * accesses leading to base address being added twice. We try to
+ * catch most of these here by triggering an error when runtime_address()
+ * is used with anything that is not a byte array of unknown size.
+ */
+extern void *__compiletime_error(
+ "runtime_address() may only be called on linker defined symbols."
+) __unsafe_runtime_address(void);
+
#endif
diff --git a/include/linux/reset.h b/include/linux/reset.h
index c1282a84c7..2d788547f4 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -49,6 +49,12 @@ static inline int reset_control_deassert(struct reset_control *rstc)
}
static inline struct reset_control *
+of_reset_control_get(struct device_node *node, const char *id)
+{
+ return NULL;
+}
+
+static inline struct reset_control *
reset_control_get(struct device_d *dev, const char *id)
{
return NULL;