* [PATCH v2 1/6] memory: add support for requesting barebox area as a whole
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 2/6] treewide: use request_barebox_region for possible barebox memory regions Ahmad Fatoum
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
barebox-specific code and data is normally located at the end of
early-known memory. To ensure it's not overwritten, parts of it are
reserved with request_sdram_region at different places.
Gaps in the reservation lead to multiple issues in the past.
So for documentation purposes and to avoid functiosn like
memory_bank_first_find_space finding vacant area where there isn't,
allow architectures call register_barebox_area to do one full
SDRAM request for the area.
Region requests for subsets of this area will be switched in the
follow-up commit to use the new request_barebox_region, which allocates
a subregion if it lies inside a registered barebox area and defers
to request_sdram_region otherwise.
The motivation for this patch is that with the addition of handoff data,
doing separate memory reservation for every accounting structure (cookie
and linked list) in addition to the data could make iomem output a bit
unwieldy, but we really want to avoid anyone else overwriting it.
While at it, we also rename the regions for barebox code and bss to be
more descriptive.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- new patch
---
common/memory.c | 38 ++++++++++++++++++++++++++++++++++++--
include/memory.h | 6 ++++++
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index 583843cc34c0..8e68b5e8bb20 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -57,6 +57,40 @@ void mem_malloc_init(void *start, void *end)
mem_malloc_initialized = 1;
}
+static struct resource *barebox_res;
+static resource_size_t barebox_start;
+static resource_size_t barebox_size;
+
+void register_barebox_area(resource_size_t start,
+ resource_size_t size)
+{
+ barebox_start = start,
+ barebox_size = size;
+}
+
+static int mem_register_barebox(void)
+{
+ if (barebox_start && barebox_size)
+ barebox_res = request_sdram_region("barebox", barebox_start,
+ barebox_size);
+ return 0;
+}
+postmem_initcall(mem_register_barebox);
+
+struct resource *request_barebox_region(const char *name,
+ resource_size_t start,
+ resource_size_t size)
+{
+ resource_size_t end = start + size - 1;
+
+ if (barebox_res && barebox_res->start <= start &&
+ end <= barebox_res->end)
+ return __request_region(barebox_res, start, end,
+ name, IORESOURCE_MEM);
+
+ return request_sdram_region(name, start, size);
+}
+
static int mem_malloc_resource(void)
{
#if !defined __SANDBOX__
@@ -69,7 +103,7 @@ static int mem_malloc_resource(void)
request_sdram_region("malloc space",
malloc_start,
malloc_end - malloc_start + 1);
- request_sdram_region("barebox",
+ request_sdram_region("barebox code",
(unsigned long)&_stext,
(unsigned long)&_etext -
(unsigned long)&_stext);
@@ -77,7 +111,7 @@ static int mem_malloc_resource(void)
(unsigned long)&_sdata,
(unsigned long)&_edata -
(unsigned long)&_sdata);
- request_sdram_region("bss",
+ request_sdram_region("barebox bss",
(unsigned long)&__bss_start,
(unsigned long)&__bss_stop -
(unsigned long)&__bss_start);
diff --git a/include/memory.h b/include/memory.h
index d8691972ec9b..571effd3b0d6 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -61,4 +61,10 @@ static inline u64 memory_sdram_size(unsigned int cols,
return (u64)banks * width << (rows + cols);
}
+void register_barebox_area(resource_size_t start, resource_size_t size);
+
+struct resource *request_barebox_region(const char *name,
+ resource_size_t start,
+ resource_size_t size);
+
#endif
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/6] treewide: use request_barebox_region for possible barebox memory regions
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 1/6] memory: add support for requesting barebox area as a whole Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 3/6] ARM: cpu: start: register barebox memory area Ahmad Fatoum
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This is a prerequisite for allowing architectures to call
register_barebox_area() to register the whole barebox region.
No functional change (yet).
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- new patch
---
arch/arm/cpu/cpu.c | 2 +-
arch/arm/cpu/mmu_32.c | 8 ++++----
arch/arm/cpu/mmu_64.c | 4 ++--
arch/arm/cpu/start.c | 2 +-
arch/arm/mach-imx/scratch.c | 2 +-
arch/mips/lib/cpu-probe.c | 2 +-
arch/powerpc/mach-mpc5xxx/cpu.c | 2 +-
arch/powerpc/mach-mpc85xx/cpu.c | 2 +-
arch/riscv/boot/start.c | 4 ++--
arch/riscv/cpu/core.c | 2 +-
common/memory.c | 6 +++---
fs/pstore/ram_core.c | 2 +-
12 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index 5f1ffe9a3c76..b00e9e51e5ea 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -102,7 +102,7 @@ static int arm_request_stack(void)
if (efi_is_payload())
return 0;
- if (!request_sdram_region("stack", arm_stack_top - STACK_SIZE, STACK_SIZE))
+ if (!request_barebox_region("stack", arm_stack_top - STACK_SIZE, STACK_SIZE))
pr_err("Error: Cannot request SDRAM region for stack\n");
return 0;
diff --git a/arch/arm/cpu/mmu_32.c b/arch/arm/cpu/mmu_32.c
index 3a8d025ecdee..24d83d933661 100644
--- a/arch/arm/cpu/mmu_32.c
+++ b/arch/arm/cpu/mmu_32.c
@@ -390,7 +390,7 @@ static void create_vector_table(unsigned long adr)
void *vectors;
u32 *pte;
- vectors_sdram = request_sdram_region("vector table", adr, PAGE_SIZE);
+ vectors_sdram = request_barebox_region("vector table", adr, PAGE_SIZE);
if (vectors_sdram) {
/*
* The vector table address is inside the SDRAM physical
@@ -486,7 +486,7 @@ static void create_guard_page(void)
return;
guard_page = arm_mem_guard_page_get();
- request_sdram_region("guard page", guard_page, PAGE_SIZE);
+ request_barebox_region("guard page", guard_page, PAGE_SIZE);
remap_range((void *)guard_page, PAGE_SIZE, MAP_FAULT);
pr_debug("Created guard page\n");
@@ -535,8 +535,8 @@ void __mmu_init(bool mmu_on)
struct memory_bank *bank;
uint32_t *ttb = get_ttb();
- if (!request_sdram_region("ttb", (unsigned long)ttb,
- ARM_EARLY_PAGETABLE_SIZE))
+ if (!request_barebox_region("ttb", (unsigned long)ttb,
+ ARM_EARLY_PAGETABLE_SIZE))
/*
* This can mean that:
* - the early MMU code has put the ttb into a place
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index 71c0d8930e63..7c7834201b65 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -219,7 +219,7 @@ static void create_guard_page(void)
return;
guard_page = arm_mem_guard_page_get();
- request_sdram_region("guard page", guard_page, PAGE_SIZE);
+ request_barebox_region("guard page", guard_page, PAGE_SIZE);
remap_range((void *)guard_page, PAGE_SIZE, MAP_FAULT);
pr_debug("Created guard page\n");
@@ -233,7 +233,7 @@ void __mmu_init(bool mmu_on)
uint64_t *ttb = get_ttb();
struct memory_bank *bank;
- if (!request_sdram_region("ttb", (unsigned long)ttb,
+ if (!request_barebox_region("ttb", (unsigned long)ttb,
ARM_EARLY_PAGETABLE_SIZE))
/*
* This can mean that:
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 2adc60fa8831..a73224bab930 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -134,7 +134,7 @@ EXPORT_SYMBOL_GPL(arm_mem_membase_get);
static int barebox_memory_areas_init(void)
{
if(barebox_boarddata)
- request_sdram_region("board data", (unsigned long)barebox_boarddata,
+ request_barebox_region("board data", (unsigned long)barebox_boarddata,
barebox_boarddata_size);
if (IS_ENABLED(CONFIG_KASAN))
diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
index 60d15a4f1a33..002b499fab3a 100644
--- a/arch/arm/mach-imx/scratch.c
+++ b/arch/arm/mach-imx/scratch.c
@@ -95,7 +95,7 @@ const struct optee_header *imx_scratch_get_optee_hdr(void)
static int imx8m_reserve_scratch_area(void)
{
- return PTR_ERR_OR_ZERO(request_sdram_region("scratch area",
+ return PTR_ERR_OR_ZERO(request_barebox_region("scratch area",
(ulong)arm_mem_scratch_get(),
sizeof(struct imx_scratch_space)));
}
diff --git a/arch/mips/lib/cpu-probe.c b/arch/mips/lib/cpu-probe.c
index fc202815973f..ccb27a81497f 100644
--- a/arch/mips/lib/cpu-probe.c
+++ b/arch/mips/lib/cpu-probe.c
@@ -231,7 +231,7 @@ unsigned long mips_stack_top;
static int mips_request_stack(void)
{
- if (!request_sdram_region("stack", mips_stack_top - STACK_SIZE, STACK_SIZE))
+ if (!request_barebox_region("stack", mips_stack_top - STACK_SIZE, STACK_SIZE))
pr_err("Error: Cannot request SDRAM region for stack\n");
return 0;
diff --git a/arch/powerpc/mach-mpc5xxx/cpu.c b/arch/powerpc/mach-mpc5xxx/cpu.c
index 9c99bdd26f9b..647109b7fb63 100644
--- a/arch/powerpc/mach-mpc5xxx/cpu.c
+++ b/arch/powerpc/mach-mpc5xxx/cpu.c
@@ -40,7 +40,7 @@ static int mpc5xxx_reserve_region(void)
struct resource *r;
/* keep this in sync with the assembler routines setting up the stack */
- r = request_sdram_region("stack", _text_base - STACK_SIZE, STACK_SIZE);
+ r = request_barebox_region("stack", _text_base - STACK_SIZE, STACK_SIZE);
if (r == NULL) {
pr_err("Failed to request stack region at: 0x%08lx/0x%08lx\n",
_text_base - STACK_SIZE, _text_base - 1);
diff --git a/arch/powerpc/mach-mpc85xx/cpu.c b/arch/powerpc/mach-mpc85xx/cpu.c
index 2119352f84a7..acfd4699a2ff 100644
--- a/arch/powerpc/mach-mpc85xx/cpu.c
+++ b/arch/powerpc/mach-mpc85xx/cpu.c
@@ -96,7 +96,7 @@ phys_size_t fsl_get_effective_memsize(void)
static int fsl_reserve_region(void)
{
- request_sdram_region("stack", _text_base - STACK_SIZE,
+ request_barebox_region("stack", _text_base - STACK_SIZE,
STACK_SIZE);
return 0;
}
diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
index d20526293bac..2e18105bbfb3 100644
--- a/arch/riscv/boot/start.c
+++ b/arch/riscv/boot/start.c
@@ -98,8 +98,8 @@ EXPORT_SYMBOL_GPL(riscv_mem_endmem_get);
static int barebox_memory_areas_init(void)
{
if(barebox_boarddata)
- request_sdram_region("board data", (unsigned long)barebox_boarddata,
- barebox_boarddata_size);
+ request_barebox_region("board data", (unsigned long)barebox_boarddata,
+ barebox_boarddata_size);
return 0;
}
diff --git a/arch/riscv/cpu/core.c b/arch/riscv/cpu/core.c
index 38aa40275829..ad9030ede78b 100644
--- a/arch/riscv/cpu/core.c
+++ b/arch/riscv/cpu/core.c
@@ -28,7 +28,7 @@
static int riscv_request_stack(void)
{
extern unsigned long riscv_stack_top;
- return PTR_ERR_OR_ZERO(request_sdram_region("stack", riscv_stack_top - STACK_SIZE, STACK_SIZE));
+ return PTR_ERR_OR_ZERO(request_barebox_region("stack", riscv_stack_top - STACK_SIZE, STACK_SIZE));
}
coredevice_initcall(riscv_request_stack);
diff --git a/common/memory.c b/common/memory.c
index 8e68b5e8bb20..eb7838d03613 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -103,15 +103,15 @@ static int mem_malloc_resource(void)
request_sdram_region("malloc space",
malloc_start,
malloc_end - malloc_start + 1);
- request_sdram_region("barebox code",
+ request_barebox_region("barebox code",
(unsigned long)&_stext,
(unsigned long)&_etext -
(unsigned long)&_stext);
- request_sdram_region("barebox data",
+ request_barebox_region("barebox data",
(unsigned long)&_sdata,
(unsigned long)&_edata -
(unsigned long)&_sdata);
- request_sdram_region("barebox bss",
+ request_barebox_region("barebox bss",
(unsigned long)&__bss_start,
(unsigned long)&__bss_stop -
(unsigned long)&__bss_start);
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 24948d701744..fbc936a44fd6 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -342,7 +342,7 @@ void persistent_ram_zap(struct persistent_ram_zone *prz)
static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
struct persistent_ram_zone *prz, int memtype)
{
- prz->res = request_sdram_region(prz->label ?: "ramoops", start, size);
+ prz->res = request_barebox_region(prz->label ?: "ramoops", start, size);
if (!prz->res)
return -ENOMEM;
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 3/6] ARM: cpu: start: register barebox memory area
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 1/6] memory: add support for requesting barebox area as a whole Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 2/6] treewide: use request_barebox_region for possible barebox memory regions Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 4/6] ARM: move blob_is_arm_boarddata() to include Ahmad Fatoum
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
By registering the barebox area, we ensure that functions like
memory_bank_first_find_space() skip over the memory area barebox uses
for itself.
The OS can still reclaim this area once barebox has shutdown.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- new patch
---
arch/arm/cpu/start.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index a73224bab930..4f68119d5089 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -219,6 +219,8 @@ __noreturn __prereloc void barebox_non_pbl_start(unsigned long membase,
pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n",
malloc_start, malloc_end - malloc_start);
+ register_barebox_area(barebox_base, endmem - barebox_base);
+
kasan_init(membase, memsize, malloc_start - (memsize >> KASAN_SHADOW_SCALE_SHIFT));
mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 4/6] ARM: move blob_is_arm_boarddata() to include
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
` (2 preceding siblings ...)
2024-05-17 6:45 ` [PATCH v2 3/6] ARM: cpu: start: register barebox memory area Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 5/6] add handoff-data support Ahmad Fatoum
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
From: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20240430105310.3149242-2-s.hauer@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
v1 -> v2:
- no change
---
arch/arm/cpu/start.c | 7 -------
arch/arm/include/asm/barebox-arm.h | 7 +++++++
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 4f68119d5089..8461184db467 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -36,13 +36,6 @@ static unsigned long arm_membase;
static void *barebox_boarddata;
static unsigned long barebox_boarddata_size;
-static bool blob_is_arm_boarddata(const void *blob)
-{
- const struct barebox_arm_boarddata *bd = blob;
-
- return bd->magic == BAREBOX_ARM_BOARDDATA_MAGIC;
-}
-
const struct barebox_boarddata *barebox_get_boarddata(void)
{
if (!barebox_boarddata || !blob_is_arm_boarddata(barebox_boarddata))
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index c64e74f8f03a..8447ef7ba7fa 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -32,6 +32,13 @@ void __noreturn barebox_arm_entry(unsigned long membase, unsigned long memsize,
#define barebox_arm_boarddata barebox_boarddata
#define BAREBOX_ARM_BOARDDATA_MAGIC BAREBOX_BOARDDATA_MAGIC
+static inline bool blob_is_arm_boarddata(const void *blob)
+{
+ const struct barebox_arm_boarddata *bd = blob;
+
+ return bd->magic == BAREBOX_ARM_BOARDDATA_MAGIC;
+}
+
u32 barebox_arm_machine(void);
unsigned long arm_mem_ramoops_get(void);
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 5/6] add handoff-data support
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
` (3 preceding siblings ...)
2024-05-17 6:45 ` [PATCH v2 4/6] ARM: move blob_is_arm_boarddata() to include Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-17 6:45 ` [PATCH v2 6/6] ARM: pass handoff data from PBL to proper Ahmad Fatoum
2024-05-21 7:14 ` [PATCH v2 0/6] add PBL handoff-data support Sascha Hauer
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox
From: Sascha Hauer <s.hauer@pengutronix.de>
We need to pass data from the PBL to barebox proper. Right now we do
this with passing the data in registers which is quite limited. As the
amount of information that has to be passed increases it's time to
overcome this limitation.
With this patch we introduce handoff-data which is a linked list of
memory blobs that can be passed from PBL to barebox proper.
The data format is done in a way that enables us to compile the list
entries and the data into the binary, so that no memory allocations
are needed in PBL.
Link: https://lore.barebox.org/20240430105310.3149242-3-s.hauer@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
v1 -> v2:
- move header into pbl/ subdirectory
- implement __handoff_data_size with head as argument
- call new request_barebox_region instead of request_sdram_region
---
include/pbl/handoff-data.h | 53 ++++++++++
pbl/Makefile | 1 +
pbl/handoff-data.c | 194 +++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+)
create mode 100644 include/pbl/handoff-data.h
create mode 100644 pbl/handoff-data.c
diff --git a/include/pbl/handoff-data.h b/include/pbl/handoff-data.h
new file mode 100644
index 000000000000..7f883421df16
--- /dev/null
+++ b/include/pbl/handoff-data.h
@@ -0,0 +1,53 @@
+#ifndef __PBL_HANDOFF_DATA_H
+#define __PBL_HANDOFF_DATA_H
+
+#include <linux/list.h>
+
+struct handoff_data {
+ struct list_head entries;
+};
+
+#define HANDOFF_DATA_BAREBOX(n) (0x28061971 + (n))
+#define HANDOFF_DATA_INTERNAL_DT HANDOFF_DATA_BAREBOX(0)
+#define HANDOFF_DATA_INTERNAL_DT_Z HANDOFF_DATA_BAREBOX(1)
+#define HANDOFF_DATA_EXTERNAL_DT HANDOFF_DATA_BAREBOX(2)
+#define HANDOFF_DATA_BOARDDATA HANDOFF_DATA_BAREBOX(3)
+
+#define HANDOFF_DATA_BOARD(n) (0x951726fb + (n))
+
+struct handoff_data_entry {
+ struct list_head list;
+ void *data;
+ size_t size;
+ unsigned int cookie;
+#define HANDOFF_DATA_FLAG_NO_COPY BIT(0)
+ unsigned int flags;
+};
+
+#define handoff_data_add_flags(_cookie, _data, _size, _flags) \
+ do { \
+ static struct handoff_data_entry hde; \
+ hde.cookie = _cookie; \
+ hde.data = _data; \
+ hde.size = _size; \
+ hde.flags = _flags; \
+ \
+ handoff_data_add_entry(&hde); \
+ } while (0);
+
+#define handoff_data_add(_cookie, _data, _size) \
+ handoff_data_add_flags((_cookie), (_data), (_size), 0)
+
+void handoff_data_add_entry(struct handoff_data_entry *entry);
+void handoff_data_move(void *dest);
+void handoff_data_set(struct handoff_data *handoff);
+void *handoff_data_get_entry(unsigned int cookie, size_t *size);
+int handoff_data_show(void);
+
+size_t __handoff_data_size(const struct handoff_data *hd);
+static inline size_t handoff_data_size(void)
+{
+ return __handoff_data_size(NULL);
+}
+
+#endif /* __PBL_HANDOFF_DATA_H */
diff --git a/pbl/Makefile b/pbl/Makefile
index f6e98e78be3f..79837c56114a 100644
--- a/pbl/Makefile
+++ b/pbl/Makefile
@@ -8,3 +8,4 @@ pbl-y += string.o
pbl-y += decomp.o
pbl-$(CONFIG_LIBFDT) += fdt.o
pbl-$(CONFIG_PBL_CONSOLE) += console.o
+obj-pbl-y += handoff-data.o
diff --git a/pbl/handoff-data.c b/pbl/handoff-data.c
new file mode 100644
index 000000000000..e6745797c038
--- /dev/null
+++ b/pbl/handoff-data.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <common.h>
+#include <pbl/handoff-data.h>
+#include <init.h>
+#include <linux/list.h>
+#include <memory.h>
+
+static struct handoff_data *handoff_data = (void *)-1;
+
+static struct handoff_data *handoff_data_get(void)
+{
+ static struct handoff_data __handoff_data;
+
+ /*
+ * Sometimes the PBL copies itself to some other location and is
+ * re-entered at that location. For example on some i.MX SoCs we have
+ * to move the PBL out of the SRAM (which will be occupied by the TF-A
+ * later). We force the handoff_data variable into the data segment.
+ * When moving the PBL somewhere else with handoff_data set we move the
+ * content of the variable with it and thus find it to have the correct
+ * value in the new PBL.
+ */
+ if (handoff_data == (void *)-1) {
+ handoff_data = &__handoff_data;
+ INIT_LIST_HEAD(&handoff_data->entries);
+ }
+
+ return handoff_data;
+}
+
+/**
+ * handoff_data_set - set the handoff data to be at a specified pointer
+ * @handoff: the place where the handoff data is
+ *
+ * This sets the handoff data to @handoff. To be used by barebox proper
+ * to pass the place where the handoff data has been placed by the PBL.
+ */
+void handoff_data_set(struct handoff_data *handoff)
+{
+ handoff_data = handoff;
+}
+
+/**
+ * handoff_data_add_entry - add a new handoff data entry
+ * @hde: the new entry
+ *
+ * This adds a new handoff data entry.
+ */
+void handoff_data_add_entry(struct handoff_data_entry *hde)
+{
+ struct handoff_data *hd = handoff_data_get();
+
+ list_add_tail(&hde->list, &hd->entries);
+}
+
+/**
+ * handoff_data_size - calculate the handoff data size
+ *
+ * This calculates the size needed for the current handoff data
+ * when put to a contiguous memory regions. Can be used to get the
+ * size needed in preparation for a handoff_data_move()
+ */
+size_t __handoff_data_size(const struct handoff_data *hd)
+{
+ struct handoff_data_entry *hde;
+ size_t size = 0;
+ size_t dsize = 0;
+
+ if (!hd)
+ hd = handoff_data_get();
+
+ dsize += sizeof(*hd);
+
+ list_for_each_entry(hde, &hd->entries, list) {
+ dsize += sizeof(*hde);
+ size += ALIGN(hde->size, 8);
+ }
+
+ return dsize + size;
+}
+
+/**
+ * handoff_data_move - move handoff data to specified destination
+ * @dest: The place where to move the handoff data to
+ *
+ * This moves the handoff data to @dest and also sets the new location
+ * to @dest. This can be used to move the handoff data to a contiguous
+ * region outside the binary. Note once moved no data should be added,
+ * as that would make the handoff_data discontigoous again.
+ */
+void handoff_data_move(void *dest)
+{
+ struct handoff_data *hd = handoff_data_get();
+ struct handoff_data *hdnew = dest;
+ struct handoff_data_entry *hde;
+
+ INIT_LIST_HEAD(&hdnew->entries);
+
+ dest = hdnew + 1;
+
+ list_for_each_entry(hde, &hd->entries, list) {
+ struct handoff_data_entry *newde = dest;
+
+ dest = newde + 1;
+
+ if (hde->flags & HANDOFF_DATA_FLAG_NO_COPY) {
+ newde->data = hde->data;
+ } else {
+ memcpy(dest, hde->data, hde->size);
+ newde->data = dest;
+ dest += ALIGN(hde->size, 8);
+ }
+
+ newde->size = hde->size;
+ newde->cookie = hde->cookie;
+ list_add_tail(&newde->list, &hdnew->entries);
+ }
+
+ handoff_data_set(hdnew);
+}
+
+/**
+ * handoff_data_get_entry - get the memory associated to a cookie
+ * @cookie: the cookie the data is identified with
+ * @size: size of the memory returned
+ *
+ * This returns the memory associated with @cookie.
+ */
+void *handoff_data_get_entry(unsigned int cookie, size_t *size)
+{
+ struct handoff_data *hd = handoff_data_get();
+ struct handoff_data_entry *hde;
+
+ list_for_each_entry(hde, &hd->entries, list) {
+ if (hde->cookie == cookie) {
+ *size = hde->size;
+ return hde->data;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * handoff_data_show - show current handoff data entries
+ *
+ * This prints the current handoff data entries to the console for debugging
+ * purposes.
+ */
+int handoff_data_show(void)
+{
+ struct handoff_data *hd = handoff_data_get();
+ struct handoff_data_entry *hde;
+
+ list_for_each_entry(hde, &hd->entries, list) {
+ printf("handoff 0x%08x at 0x%p (size %zu)\n",
+ hde->cookie, hde->data, hde->size);
+ }
+
+ return 0;
+}
+
+static const char *handoff_data_entry_name(struct handoff_data_entry *hde)
+{
+ static char name[sizeof("handoff 12345678")];
+
+ switch (hde->cookie) {
+ case HANDOFF_DATA_INTERNAL_DT:
+ return "handoff FDT (internal)";
+ case HANDOFF_DATA_INTERNAL_DT_Z:
+ return "handoff FDT (internal, compressed)";
+ case HANDOFF_DATA_EXTERNAL_DT:
+ return "handoff FDT (external)";
+ case HANDOFF_DATA_BOARDDATA:
+ return "handoff boarddata";
+ default:
+ sprintf(name, "handoff %08x", hde->cookie);
+ return name;
+ }
+}
+
+static int handoff_data_reserve(void)
+{
+ struct handoff_data *hd = handoff_data_get();
+ struct handoff_data_entry *hde;
+
+ list_for_each_entry(hde, &hd->entries, list) {
+ const char *name = handoff_data_entry_name(hde);
+ request_barebox_region(name, (resource_size_t)hde->data, hde->size);
+ }
+
+ return 0;
+}
+late_initcall(handoff_data_reserve);
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 6/6] ARM: pass handoff data from PBL to proper
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
` (4 preceding siblings ...)
2024-05-17 6:45 ` [PATCH v2 5/6] add handoff-data support Ahmad Fatoum
@ 2024-05-17 6:45 ` Ahmad Fatoum
2024-05-21 7:14 ` [PATCH v2 0/6] add PBL handoff-data support Sascha Hauer
6 siblings, 0 replies; 8+ messages in thread
From: Ahmad Fatoum @ 2024-05-17 6:45 UTC (permalink / raw)
To: barebox
From: Sascha Hauer <s.hauer@pengutronix.de>
Use newly introduced handoff data to pass data from PBL to barebox
proper. This will allow us later to pass more SoC and/or board specific
data from PBL to barebox proper.
Link: https://lore.barebox.org/20240430105310.3149242-4-s.hauer@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
v1 -> v2:
- delete no longer used arm_mem_boarddata()
- in PBL, add board data before computing size, so it's taken into
account
- in barebox proper, fix arm_mem_barebox_image() to take account of
handoff data size
- support NULL boarddata passed in by PBL entry point. This is
possibly useful for boards that have board data in ROM that they
want to pass in a custom manner
---
arch/arm/cpu/start.c | 74 ++++++++----------------------
arch/arm/cpu/uncompress.c | 36 +++++++++++++--
arch/arm/include/asm/barebox-arm.h | 24 ++++++----
3 files changed, 66 insertions(+), 68 deletions(-)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 8461184db467..2158edafa4a9 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -21,6 +21,7 @@
#include <asm/mmu.h>
#include <linux/kasan.h>
#include <memory.h>
+#include <pbl/handoff-data.h>
#include <uncompress.h>
#include <compressed-dtb.h>
#include <malloc.h>
@@ -38,10 +39,9 @@ static unsigned long barebox_boarddata_size;
const struct barebox_boarddata *barebox_get_boarddata(void)
{
- if (!barebox_boarddata || !blob_is_arm_boarddata(barebox_boarddata))
- return NULL;
+ size_t size;
- return barebox_boarddata;
+ return handoff_data_get_entry(HANDOFF_DATA_BOARDDATA, &size);
}
u32 barebox_arm_machine(void)
@@ -56,19 +56,24 @@ void *barebox_arm_boot_dtb(void)
int ret = 0;
struct barebox_boarddata_compressed_dtb *compressed_dtb;
static void *boot_dtb;
+ void *blob;
+ size_t size;
if (boot_dtb)
return boot_dtb;
- if (barebox_boarddata && blob_is_fdt(barebox_boarddata)) {
- pr_debug("%s: using barebox_boarddata\n", __func__);
- return barebox_boarddata;
- }
+ blob = handoff_data_get_entry(HANDOFF_DATA_INTERNAL_DT, &size);
+ if (blob)
+ return blob;
- if (!fdt_blob_can_be_decompressed(barebox_boarddata))
+ blob = handoff_data_get_entry(HANDOFF_DATA_INTERNAL_DT_Z, &size);
+ if (!blob)
return NULL;
- compressed_dtb = barebox_boarddata;
+ if (!fdt_blob_can_be_decompressed(blob))
+ return NULL;
+
+ compressed_dtb = blob;
pr_debug("%s: using compressed_dtb\n", __func__);
@@ -94,18 +99,6 @@ void *barebox_arm_boot_dtb(void)
return boot_dtb;
}
-static inline unsigned long arm_mem_boarddata(unsigned long membase,
- unsigned long endmem,
- unsigned long size)
-{
- unsigned long mem;
-
- mem = arm_mem_barebox_image(membase, endmem, arm_barebox_size);
- mem -= ALIGN(size, 64);
-
- return mem;
-}
-
unsigned long arm_mem_ramoops_get(void)
{
return arm_mem_ramoops(arm_stack_top);
@@ -143,10 +136,9 @@ __noreturn __prereloc void barebox_non_pbl_start(unsigned long membase,
{
unsigned long endmem = membase + memsize;
unsigned long malloc_start, malloc_end;
- unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE;
- unsigned long barebox_base = arm_mem_barebox_image(membase,
- endmem,
- barebox_size);
+ unsigned long barebox_base = arm_mem_barebox_image(membase, endmem,
+ barebox_image_size,
+ boarddata);
if (IS_ENABLED(CONFIG_CPU_V7))
armv7_hyp_install();
@@ -164,37 +156,9 @@ __noreturn __prereloc void barebox_non_pbl_start(unsigned long membase,
arm_membase = membase;
arm_endmem = endmem;
arm_stack_top = arm_mem_stack_top(endmem);
- arm_barebox_size = barebox_size;
+ arm_barebox_size = barebox_image_size + MAX_BSS_SIZE;
malloc_end = barebox_base;
- if (boarddata) {
- uint32_t totalsize = 0;
- const char *name;
-
- if (blob_is_fdt(boarddata)) {
- totalsize = get_unaligned_be32(boarddata + 4);
- name = "DTB";
- } else if (blob_is_compressed_fdt(boarddata)) {
- struct barebox_boarddata_compressed_dtb *bd = boarddata;
- totalsize = bd->datalen + sizeof(*bd);
- name = "Compressed DTB";
- } else if (blob_is_arm_boarddata(boarddata)) {
- totalsize = sizeof(struct barebox_arm_boarddata);
- name = "machine type";
- }
-
- if (totalsize) {
- unsigned long mem = arm_mem_boarddata(membase, endmem,
- totalsize);
- pr_debug("found %s in boarddata, copying to 0x%08lx\n",
- name, mem);
- barebox_boarddata = memcpy((void *)mem, boarddata,
- totalsize);
- barebox_boarddata_size = totalsize;
- malloc_end = mem;
- }
- }
-
/*
* Maximum malloc space is the Kconfig value if given
* or 1GB.
@@ -218,6 +182,8 @@ __noreturn __prereloc void barebox_non_pbl_start(unsigned long membase,
mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
+ handoff_data_set(boarddata);
+
if (IS_ENABLED(CONFIG_BOOTM_OPTEE))
of_add_reserve_entry(endmem - OPTEE_SIZE, endmem - 1);
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 612a5b65ff4c..af702d510eb7 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -10,6 +10,7 @@
#include <init.h>
#include <linux/sizes.h>
#include <pbl.h>
+#include <pbl/handoff-data.h>
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
#include <asm-generic/memory_layout.h>
@@ -18,6 +19,7 @@
#include <asm/cache.h>
#include <asm/mmu.h>
#include <asm/unaligned.h>
+#include <compressed-dtb.h>
#include <debug_ll.h>
@@ -29,6 +31,24 @@ unsigned long free_mem_end_ptr;
extern unsigned char input_data[];
extern unsigned char input_data_end[];
+static void add_handoff_data(void *boarddata)
+{
+ if (!boarddata)
+ return;
+ if (blob_is_fdt(boarddata)) {
+ handoff_data_add(HANDOFF_DATA_INTERNAL_DT, boarddata,
+ get_unaligned_be32(boarddata + 4));
+ } else if (blob_is_compressed_fdt(boarddata)) {
+ struct barebox_boarddata_compressed_dtb *bd = boarddata;
+
+ handoff_data_add(HANDOFF_DATA_INTERNAL_DT_Z, boarddata,
+ bd->datalen + sizeof(*bd));
+ } else if (blob_is_arm_boarddata(boarddata)) {
+ handoff_data_add(HANDOFF_DATA_BOARDDATA, boarddata,
+ sizeof(struct barebox_arm_boarddata));
+ }
+}
+
void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
void *boarddata)
{
@@ -38,6 +58,7 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
unsigned long barebox_base;
void *pg_start, *pg_end;
unsigned long pc = get_pc();
+ void *handoff_data;
/* piggy data is not relocated, so determine the bounds now */
pg_start = runtime_address(input_data);
@@ -56,9 +77,6 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
pg_len = pg_end - pg_start;
uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4));
- barebox_base = arm_mem_barebox_image(membase, endmem,
- uncompressed_len + MAX_BSS_SIZE);
-
setup_c();
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
@@ -66,6 +84,14 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
if (IS_ENABLED(CONFIG_MMU))
mmu_early_enable(membase, memsize);
+ /* Add handoff data now, so arm_mem_barebox_image takes it into account */
+ add_handoff_data(boarddata);
+
+ barebox_base = arm_mem_barebox_image(membase, endmem,
+ uncompressed_len, NULL);
+
+ handoff_data = (void *)barebox_base + uncompressed_len + MAX_BSS_SIZE;
+
free_mem_ptr = barebox_base - ARM_MEM_EARLY_MALLOC_SIZE;
free_mem_end_ptr = barebox_base;
@@ -74,6 +100,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
+ handoff_data_move(handoff_data);
+
sync_caches_for_execution();
if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
@@ -86,5 +114,5 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
if (IS_ENABLED(CONFIG_CPU_V7) && boot_cpu_mode() == HYP_MODE)
armv7_switch_to_hyp();
- barebox(membase, memsize, boarddata);
+ barebox(membase, memsize, handoff_data);
}
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index 8447ef7ba7fa..e9afd8f4539c 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -18,6 +18,7 @@
#include <linux/pagemap.h>
#include <linux/types.h>
#include <linux/compiler.h>
+#include <pbl/handoff-data.h>
#include <asm/barebox-arm-head.h>
#include <asm/common.h>
#include <asm/sections.h>
@@ -158,10 +159,22 @@ static inline unsigned long arm_mem_guard_page_get(void)
return arm_mem_guard_page(arm_mem_endmem_get());
}
+/*
+ * When using compressed images in conjunction with relocatable images
+ * the PBL code must pick a suitable place where to uncompress the barebox
+ * image. For doing this the PBL code must know the size of the final
+ * image including the BSS segment. The BSS size is unknown to the PBL
+ * code, so define a maximum BSS size here.
+ */
+#define MAX_BSS_SIZE SZ_1M
+
static inline unsigned long arm_mem_barebox_image(unsigned long membase,
unsigned long endmem,
- unsigned long size)
+ unsigned long uncompressed_len,
+ const struct handoff_data *handoff_data)
{
+ unsigned long size = uncompressed_len + MAX_BSS_SIZE + __handoff_data_size(handoff_data);
+
endmem = arm_mem_ramoops(endmem);
return ALIGN_DOWN(endmem - size, SZ_1M);
@@ -237,15 +250,6 @@ void __barebox_arm64_head(ulong x0, ulong x1, ulong x2);
__barebox_arm_head, arg0, arg1, arg2)
#endif
-/*
- * When using compressed images in conjunction with relocatable images
- * the PBL code must pick a suitable place where to uncompress the barebox
- * image. For doing this the PBL code must know the size of the final
- * image including the BSS segment. The BSS size is unknown to the PBL
- * code, so define a maximum BSS size here.
- */
-#define MAX_BSS_SIZE SZ_1M
-
#define barebox_image_size (__image_end - __image_start)
#ifdef CONFIG_CPU_32
--
2.39.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/6] add PBL handoff-data support
2024-05-17 6:45 [PATCH v2 0/6] add PBL handoff-data support Ahmad Fatoum
` (5 preceding siblings ...)
2024-05-17 6:45 ` [PATCH v2 6/6] ARM: pass handoff data from PBL to proper Ahmad Fatoum
@ 2024-05-21 7:14 ` Sascha Hauer
6 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2024-05-21 7:14 UTC (permalink / raw)
To: barebox, Ahmad Fatoum
On Fri, 17 May 2024 08:45:05 +0200, Ahmad Fatoum wrote:
> This series replaces the 3 patches from v1 that are in next.
>
> The first 3 patches are new: They ensure that the handoff structs
> (linked list pointers, cookie, flags, ...) are also reserved in the
> SDRAM banks and not only the data.
>
> The three patches after that differ to v1 mainly in that reservation
> of space for the handoff data is correctly taken care of. This was
> erroneous both in PBL and in barebox proper and led to problems for me
> trying to boot a Qemu Virt64 machine that has for some reason a FDT that
> describes its size in the header as 1MiB.
>
> [...]
Applied, thanks!
[1/6] memory: add support for requesting barebox area as a whole
https://git.pengutronix.de/cgit/barebox/commit/?id=59289e3d8cc3 (link may not be stable)
[2/6] treewide: use request_barebox_region for possible barebox memory regions
https://git.pengutronix.de/cgit/barebox/commit/?id=64fa27a491b8 (link may not be stable)
[3/6] ARM: cpu: start: register barebox memory area
https://git.pengutronix.de/cgit/barebox/commit/?id=3f7b6146669c (link may not be stable)
[4/6] ARM: move blob_is_arm_boarddata() to include
https://git.pengutronix.de/cgit/barebox/commit/?id=fad13ab1cdc6 (link may not be stable)
[5/6] add handoff-data support
https://git.pengutronix.de/cgit/barebox/commit/?id=e72ea06e3ad3 (link may not be stable)
[6/6] ARM: pass handoff data from PBL to proper
https://git.pengutronix.de/cgit/barebox/commit/?id=b02063a8aa22 (link may not be stable)
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 8+ messages in thread