[PATCH 01/13] sandbox: Move memory-related functions to a separate file
Simon Glass
sjg at chromium.org
Wed May 27 18:10:11 CEST 2026
The memory code in cpu.c is quite large and really should be in its own
file. Add a new mem.c file and move memory-related functions to it.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
arch/sandbox/cpu/Makefile | 2 +-
arch/sandbox/cpu/cpu.c | 274 +-----------------------------------
arch/sandbox/cpu/mem.c | 288 ++++++++++++++++++++++++++++++++++++++
3 files changed, 290 insertions(+), 274 deletions(-)
create mode 100644 arch/sandbox/cpu/mem.c
diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index ee3c04c49e1..19daf29deef 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -5,7 +5,7 @@
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
-obj-y := cache.o cpu.o state.o initjmp.o os.o
+obj-y := cache.o cpu.o mem.o state.o initjmp.o os.o
extra-y := start.o
extra-$(CONFIG_SANDBOX_SDL) += sdl.o
obj-$(CONFIG_XPL_BUILD) += spl.o
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index b8fabd07d0b..472c2a41710 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -9,27 +9,16 @@
#include <cpu_func.h>
#include <errno.h>
#include <log.h>
+#include <mapmem.h>
#include <os.h>
-#include <setjmp.h>
#include <asm/global_data.h>
-#include <asm/io.h>
#include <asm/malloc.h>
#include <asm/state.h>
-#include <dm/ofnode.h>
#include <linux/delay.h>
#include <linux/libfdt.h>
DECLARE_GLOBAL_DATA_PTR;
-/* Enable access to PCI memory with map_sysmem() */
-static bool enable_pci_map;
-
-#ifdef CONFIG_PCI
-/* Last device that was mapped into memory, and length of mapping */
-static struct udevice *map_dev;
-unsigned long map_len;
-#endif
-
void __noreturn sandbox_exit(void)
{
/* Do this here while it still has an effect */
@@ -61,267 +50,6 @@ int cleanup_before_linux_select(int flags)
return 0;
}
-/**
- * is_in_sandbox_mem() - Checks if a pointer is within sandbox's emulated DRAM
- *
- * This provides a way to check if a pointer is owned by sandbox (and is within
- * its RAM) or not. Sometimes pointers come from a test which conceptually runs
- * output sandbox, potentially with direct access to the C-library malloc()
- * function, or the sandbox stack (which is not actually within the emulated
- * DRAM.
- *
- * Such pointers obviously cannot be mapped into sandbox's DRAM, so we must
- * detect them an process them separately, by recording a mapping to a tag,
- * which we can use to map back to the pointer later.
- *
- * @ptr: Pointer to check
- * Return: true if this is within sandbox emulated DRAM, false if not
- */
-static bool is_in_sandbox_mem(const void *ptr)
-{
- return (const uint8_t *)ptr >= gd->arch.ram_buf &&
- (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size;
-}
-
-/**
- * phys_to_virt() - Converts a sandbox RAM address to a pointer
- *
- * Sandbox uses U-Boot addresses from 0 to the size of DRAM. These index into
- * the emulated DRAM buffer used by sandbox. This function converts such an
- * address to a pointer into this buffer, which can be used to access the
- * memory.
- *
- * If the address is outside this range, it is assumed to be a tag
- */
-void *phys_to_virt(phys_addr_t paddr)
-{
- struct sandbox_mapmem_entry *mentry;
- struct sandbox_state *state;
-
- /* If the address is within emulated DRAM, calculate the value */
- if (paddr < gd->ram_size)
- return (void *)(gd->arch.ram_buf + paddr);
-
- /*
- * Otherwise search out list of tags for the correct pointer previously
- * created by map_to_sysmem()
- */
- state = state_get_current();
- list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
- if (mentry->tag == paddr) {
- log_debug("Used map from %lx to %p\n", (ulong)paddr,
- mentry->ptr);
- mentry->refcnt++;
- return mentry->ptr;
- }
- }
-
- printf("%s: Cannot map sandbox address %lx (SDRAM from 0 to %lx)\n",
- __func__, (ulong)paddr, (ulong)gd->ram_size);
- os_abort();
-
- /* Not reached */
- return NULL;
-}
-
-struct sandbox_mapmem_entry *find_tag(const void *ptr)
-{
- struct sandbox_mapmem_entry *mentry;
- struct sandbox_state *state = state_get_current();
-
- list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
- if (mentry->ptr == ptr) {
- log_debug("Used map from %p to %lx\n", ptr,
- mentry->tag);
- return mentry;
- }
- }
-
- return NULL;
-}
-
-phys_addr_t virt_to_phys(void *ptr)
-{
- struct sandbox_mapmem_entry *mentry;
-
- /*
- * If it is in emulated RAM, don't bother looking for a tag. Just
- * calculate the pointer using the provides offset into the RAM buffer.
- */
- if (is_in_sandbox_mem(ptr))
- return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf);
-
- mentry = find_tag(ptr);
- if (!mentry) {
- /* Abort so that gdb can be used here */
- printf("%s: Cannot map sandbox address %p (SDRAM from 0 to %lx)\n",
- __func__, ptr, (ulong)gd->ram_size);
- os_abort();
- }
- log_debug("Used map from %p to %lx\n", ptr, mentry->tag);
-
- return mentry->tag;
-}
-
-void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
-{
-#if defined(CONFIG_PCI) && !defined(CONFIG_XPL_BUILD)
- unsigned long plen = len;
- void *ptr;
-
- map_dev = NULL;
- if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
- if (plen != len) {
- printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
- __func__, (uint)paddr, len, plen);
- }
- map_len = len;
- log_debug("pci map %lx -> %p\n", (ulong)paddr, ptr);
- return ptr;
- }
-#endif
-
- return phys_to_virt(paddr);
-}
-
-void unmap_physmem(const void *ptr, unsigned long flags)
-{
- struct sandbox_mapmem_entry *mentry;
-
-#ifdef CONFIG_PCI
- if (map_dev) {
- pci_unmap_physmem(ptr, map_len, map_dev);
- map_dev = NULL;
- }
-#endif
-
- /* If it is in emulated RAM, we didn't create a tag, so nothing to do */
- if (is_in_sandbox_mem(ptr))
- return;
-
- mentry = find_tag(ptr);
- if (mentry) {
- if (!--mentry->refcnt) {
- list_del(&mentry->sibling_node);
- log_debug("Removed map from %p to %lx\n", ptr,
- (ulong)mentry->tag);
- free(mentry);
- }
- } else {
- log_warning("Address not mapped: %p\n", ptr);
- }
-}
-
-phys_addr_t map_to_sysmem(const void *ptr)
-{
- struct sandbox_mapmem_entry *mentry;
-
- /*
- * If it is in emulated RAM, don't bother creating a tag. Just return
- * the offset into the RAM buffer.
- */
- if (is_in_sandbox_mem(ptr))
- return (u8 *)ptr - gd->arch.ram_buf;
-
- /*
- * See if there is an existing tag with this pointer. If not, set up a
- * new one.
- */
- mentry = find_tag(ptr);
- if (!mentry) {
- struct sandbox_state *state = state_get_current();
-
- mentry = malloc(sizeof(*mentry));
- if (!mentry) {
- printf("%s: Error: Out of memory\n", __func__);
- os_exit(ENOMEM);
- }
- mentry->tag = state->next_tag++;
- mentry->ptr = (void *)ptr;
- mentry->refcnt = 0;
- list_add_tail(&mentry->sibling_node, &state->mapmem_head);
- log_debug("Added map from %p to %lx\n", ptr,
- (ulong)mentry->tag);
- }
-
- mentry->refcnt++;
-
- /*
- * Return the tag as the address to use. A later call to map_sysmem()
- * will return ptr
- */
- return mentry->tag;
-}
-
-void sandbox_map_list(void)
-{
- struct sandbox_mapmem_entry *mentry;
- struct sandbox_state *state = state_get_current();
-
- printf("Sandbox memory-mapping\n");
- printf("%8s %16s %6s\n", "Addr", "Mapping", "Refcnt");
- list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
- printf("%8lx %p %6d\n", mentry->tag, mentry->ptr,
- mentry->refcnt);
- }
-}
-
-unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size)
-{
- struct sandbox_state *state = state_get_current();
-
- if (!state->allow_memio)
- return 0;
-
- switch (size) {
- case SB_SIZE_8:
- return *(u8 *)addr;
- case SB_SIZE_16:
- return *(u16 *)addr;
- case SB_SIZE_32:
- return *(u32 *)addr;
- case SB_SIZE_64:
- return *(u64 *)addr;
- }
-
- return 0;
-}
-
-void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size)
-{
- struct sandbox_state *state = state_get_current();
-
- if (!state->allow_memio)
- return;
-
- switch (size) {
- case SB_SIZE_8:
- *(u8 *)addr = val;
- break;
- case SB_SIZE_16:
- *(u16 *)addr = val;
- break;
- case SB_SIZE_32:
- *(u32 *)addr = val;
- break;
- case SB_SIZE_64:
- *(u64 *)addr = val;
- break;
- }
-}
-
-void sandbox_set_enable_memio(bool enable)
-{
- struct sandbox_state *state = state_get_current();
-
- state->allow_memio = enable;
-}
-
-void sandbox_set_enable_pci_map(int enable)
-{
- enable_pci_map = enable;
-}
-
void dcache_enable(void)
{
}
diff --git a/arch/sandbox/cpu/mem.c b/arch/sandbox/cpu/mem.c
new file mode 100644
index 00000000000..54a55c1558c
--- /dev/null
+++ b/arch/sandbox/cpu/mem.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright 2025 Simon Glass <sjg at chromium.org>
+ */
+
+#define LOG_CATEGORY LOGC_SANDBOX
+
+#include <errno.h>
+#include <log.h>
+#include <malloc.h>
+#include <os.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/state.h>
+#include <linux/list.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Enable access to PCI memory with map_sysmem() */
+static bool enable_pci_map;
+
+#ifdef CONFIG_PCI
+/* Last device that was mapped into memory, and length of mapping */
+static struct udevice *map_dev;
+unsigned long map_len;
+#endif
+
+/**
+ * is_in_sandbox_mem() - Checks if a pointer is within sandbox's emulated DRAM
+ *
+ * This provides a way to check if a pointer is owned by sandbox (and is within
+ * its RAM) or not. Sometimes pointers come from a test which conceptually runs
+ * output sandbox, potentially with direct access to the C-library malloc()
+ * function, or the sandbox stack (which is not actually within the emulated
+ * DRAM.
+ *
+ * Such pointers obviously cannot be mapped into sandbox's DRAM, so we must
+ * detect them an process them separately, by recording a mapping to a tag,
+ * which we can use to map back to the pointer later.
+ *
+ * @ptr: Pointer to check
+ * Return: true if this is within sandbox emulated DRAM, false if not
+ */
+static bool is_in_sandbox_mem(const void *ptr)
+{
+ return (const uint8_t *)ptr >= gd->arch.ram_buf &&
+ (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size;
+}
+
+/**
+ * phys_to_virt() - Converts a sandbox RAM address to a pointer
+ *
+ * Sandbox uses U-Boot addresses from 0 to the size of DRAM. These index into
+ * the emulated DRAM buffer used by sandbox. This function converts such an
+ * address to a pointer into this buffer, which can be used to access the
+ * memory.
+ *
+ * If the address is outside this range, it is assumed to be a tag
+ */
+void *phys_to_virt(phys_addr_t paddr)
+{
+ struct sandbox_mapmem_entry *mentry;
+ struct sandbox_state *state;
+
+ /* If the address is within emulated DRAM, calculate the value */
+ if (paddr < gd->ram_size)
+ return (void *)(gd->arch.ram_buf + paddr);
+
+ /*
+ * Otherwise search out list of tags for the correct pointer previously
+ * created by map_to_sysmem()
+ */
+ state = state_get_current();
+ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
+ if (mentry->tag == paddr) {
+ log_debug("Used map from %lx to %p\n", (ulong)paddr,
+ mentry->ptr);
+ mentry->refcnt++;
+ return mentry->ptr;
+ }
+ }
+
+ printf("%s: Cannot map sandbox address %lx (SDRAM from 0 to %lx)\n",
+ __func__, (ulong)paddr, (ulong)gd->ram_size);
+ os_abort();
+
+ /* Not reached */
+ return NULL;
+}
+
+struct sandbox_mapmem_entry *find_tag(const void *ptr)
+{
+ struct sandbox_mapmem_entry *mentry;
+ struct sandbox_state *state = state_get_current();
+
+ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
+ if (mentry->ptr == ptr) {
+ log_debug("Used map from %p to %lx\n", ptr,
+ mentry->tag);
+ return mentry;
+ }
+ }
+
+ return NULL;
+}
+
+phys_addr_t virt_to_phys(void *ptr)
+{
+ struct sandbox_mapmem_entry *mentry;
+
+ /*
+ * If it is in emulated RAM, don't bother looking for a tag. Just
+ * calculate the pointer using the provides offset into the RAM buffer.
+ */
+ if (is_in_sandbox_mem(ptr))
+ return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf);
+
+ mentry = find_tag(ptr);
+ if (!mentry) {
+ /* Abort so that gdb can be used here */
+ printf("%s: Cannot map sandbox address %p (SDRAM from 0 to %lx)\n",
+ __func__, ptr, (ulong)gd->ram_size);
+ os_abort();
+ }
+ log_debug("Used map from %p to %lx\n", ptr, mentry->tag);
+
+ return mentry->tag;
+}
+
+void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+{
+#if defined(CONFIG_PCI) && !defined(CONFIG_XPL_BUILD)
+ unsigned long plen = len;
+ void *ptr;
+
+ map_dev = NULL;
+ if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
+ if (plen != len) {
+ printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
+ __func__, (uint)paddr, len, plen);
+ }
+ map_len = len;
+ log_debug("pci map %lx -> %p\n", (ulong)paddr, ptr);
+ return ptr;
+ }
+#endif
+
+ return phys_to_virt(paddr);
+}
+
+void unmap_physmem(const void *ptr, unsigned long flags)
+{
+ struct sandbox_mapmem_entry *mentry;
+
+#ifdef CONFIG_PCI
+ if (map_dev) {
+ pci_unmap_physmem(ptr, map_len, map_dev);
+ map_dev = NULL;
+ }
+#endif
+
+ /* If it is in emulated RAM, we didn't create a tag, so nothing to do */
+ if (is_in_sandbox_mem(ptr))
+ return;
+
+ mentry = find_tag(ptr);
+ if (mentry) {
+ if (!--mentry->refcnt) {
+ list_del(&mentry->sibling_node);
+ log_debug("Removed map from %p to %lx\n", ptr,
+ (ulong)mentry->tag);
+ free(mentry);
+ }
+ } else {
+ log_warning("Address not mapped: %p\n", ptr);
+ }
+}
+
+phys_addr_t map_to_sysmem(const void *ptr)
+{
+ struct sandbox_mapmem_entry *mentry;
+
+ /*
+ * If it is in emulated RAM, don't bother creating a tag. Just return
+ * the offset into the RAM buffer.
+ */
+ if (is_in_sandbox_mem(ptr))
+ return (u8 *)ptr - gd->arch.ram_buf;
+
+ /*
+ * See if there is an existing tag with this pointer. If not, set up a
+ * new one.
+ */
+ mentry = find_tag(ptr);
+ if (!mentry) {
+ struct sandbox_state *state = state_get_current();
+
+ mentry = malloc(sizeof(*mentry));
+ if (!mentry) {
+ printf("%s: Error: Out of memory\n", __func__);
+ os_exit(ENOMEM);
+ }
+ mentry->tag = state->next_tag++;
+ mentry->ptr = (void *)ptr;
+ mentry->refcnt = 0;
+ list_add_tail(&mentry->sibling_node, &state->mapmem_head);
+ log_debug("Added map from %p to %lx\n", ptr,
+ (ulong)mentry->tag);
+ }
+
+ mentry->refcnt++;
+
+ /*
+ * Return the tag as the address to use. A later call to map_sysmem()
+ * will return ptr
+ */
+ return mentry->tag;
+}
+
+void sandbox_map_list(void)
+{
+ struct sandbox_mapmem_entry *mentry;
+ struct sandbox_state *state = state_get_current();
+
+ printf("Sandbox memory-mapping\n");
+ printf("%8s %16s %6s\n", "Addr", "Mapping", "Refcnt");
+ list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
+ printf("%8lx %p %6d\n", mentry->tag, mentry->ptr,
+ mentry->refcnt);
+ }
+}
+
+unsigned long sandbox_read(const void *addr, enum sandboxio_size_t size)
+{
+ struct sandbox_state *state = state_get_current();
+
+ if (!state->allow_memio)
+ return 0;
+
+ switch (size) {
+ case SB_SIZE_8:
+ return *(u8 *)addr;
+ case SB_SIZE_16:
+ return *(u16 *)addr;
+ case SB_SIZE_32:
+ return *(u32 *)addr;
+ case SB_SIZE_64:
+ return *(u64 *)addr;
+ }
+
+ return 0;
+}
+
+void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size)
+{
+ struct sandbox_state *state = state_get_current();
+
+ if (!state->allow_memio)
+ return;
+
+ switch (size) {
+ case SB_SIZE_8:
+ *(u8 *)addr = val;
+ break;
+ case SB_SIZE_16:
+ *(u16 *)addr = val;
+ break;
+ case SB_SIZE_32:
+ *(u32 *)addr = val;
+ break;
+ case SB_SIZE_64:
+ *(u64 *)addr = val;
+ break;
+ }
+}
+
+void sandbox_set_enable_memio(bool enable)
+{
+ struct sandbox_state *state = state_get_current();
+
+ state->allow_memio = enable;
+}
+
+void sandbox_set_enable_pci_map(int enable)
+{
+ enable_pci_map = enable;
+}
--
2.43.0
More information about the U-Boot
mailing list