aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sandbox/cpu/cpu.c')
-rw-r--r--arch/sandbox/cpu/cpu.c155
1 files changed, 133 insertions, 22 deletions
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index cde0b055a6..fdfb209f77 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Copyright (c) 2011 The Chromium OS Authors. 3 * Copyright (c) 2011 The Chromium OS Authors.
4 */ 4 */
5#define DEBUG 5
6#include <common.h> 6#include <common.h>
7#include <dm.h> 7#include <dm.h>
8#include <errno.h> 8#include <errno.h>
@@ -57,14 +57,104 @@ int cleanup_before_linux_select(int flags)
57 return 0; 57 return 0;
58} 58}
59 59
60/**
61 * is_in_sandbox_mem() - Checks if a pointer is within sandbox's emulated DRAM
62 *
63 * This provides a way to check if a pointer is owned by sandbox (and is within
64 * its RAM) or not. Sometimes pointers come from a test which conceptually runs
65 * output sandbox, potentially with direct access to the C-library malloc()
66 * function, or the sandbox stack (which is not actually within the emulated
67 * DRAM.
68 *
69 * Such pointers obviously cannot be mapped into sandbox's DRAM, so we must
70 * detect them an process them separately, by recording a mapping to a tag,
71 * which we can use to map back to the pointer later.
72 *
73 * @ptr: Pointer to check
74 * @return true if this is within sandbox emulated DRAM, false if not
75 */
76static bool is_in_sandbox_mem(const void *ptr)
77{
78 return (const uint8_t *)ptr >= gd->arch.ram_buf &&
79 (const uint8_t *)ptr < gd->arch.ram_buf + gd->ram_size;
80}
81
82/**
83 * phys_to_virt() - Converts a sandbox RAM address to a pointer
84 *
85 * Sandbox uses U-Boot addresses from 0 to the size of DRAM. These index into
86 * the emulated DRAM buffer used by sandbox. This function converts such an
87 * address to a pointer into this buffer, which can be used to access the
88 * memory.
89 *
90 * If the address is outside this range, it is assumed to be a tag
91 */
60void *phys_to_virt(phys_addr_t paddr) 92void *phys_to_virt(phys_addr_t paddr)
61{ 93{
62 return (void *)(gd->arch.ram_buf + paddr); 94 struct sandbox_mapmem_entry *mentry;
95 struct sandbox_state *state;
96
97 /* If the address is within emulated DRAM, calculate the value */
98 if (paddr < gd->ram_size)
99 return (void *)(gd->arch.ram_buf + paddr);
100
101 /*
102 * Otherwise search out list of tags for the correct pointer previously
103 * created by map_to_sysmem()
104 */
105 state = state_get_current();
106 list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
107 if (mentry->tag == paddr) {
108 debug("%s: Used map from %lx to %p\n", __func__,
109 (ulong)paddr, mentry->ptr);
110 return mentry->ptr;
111 }
112 }
113
114 printf("%s: Cannot map sandbox address %lx (SDRAM from 0 to %lx)\n",
115 __func__, (ulong)paddr, (ulong)gd->ram_size);
116 os_abort();
117
118 /* Not reached */
119 return NULL;
63} 120}
64 121
65phys_addr_t virt_to_phys(void *vaddr) 122struct sandbox_mapmem_entry *find_tag(const void *ptr)
66{ 123{
67 return (phys_addr_t)((uint8_t *)vaddr - gd->arch.ram_buf); 124 struct sandbox_mapmem_entry *mentry;
125 struct sandbox_state *state = state_get_current();
126
127 list_for_each_entry(mentry, &state->mapmem_head, sibling_node) {
128 if (mentry->ptr == ptr) {
129 debug("%s: Used map from %p to %lx\n", __func__, ptr,
130 mentry->tag);
131 return mentry;
132 }
133 }
134 return NULL;
135}
136
137phys_addr_t virt_to_phys(void *ptr)
138{
139 struct sandbox_mapmem_entry *mentry;
140
141 /*
142 * If it is in emulated RAM, don't bother looking for a tag. Just
143 * calculate the pointer using the provides offset into the RAM buffer.
144 */
145 if (is_in_sandbox_mem(ptr))
146 return (phys_addr_t)((uint8_t *)ptr - gd->arch.ram_buf);
147
148 mentry = find_tag(ptr);
149 if (!mentry) {
150 /* Abort so that gdb can be used here */
151 printf("%s: Cannot map sandbox address %p (SDRAM from 0 to %lx)\n",
152 __func__, ptr, (ulong)gd->ram_size);
153 os_abort();
154 }
155 debug("%s: Used map from %p to %lx\n", __func__, ptr, mentry->tag);
156
157 return mentry->tag;
68} 158}
69 159
70void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) 160void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
@@ -87,24 +177,57 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
87 return phys_to_virt(paddr); 177 return phys_to_virt(paddr);
88} 178}
89 179
90void unmap_physmem(const void *vaddr, unsigned long flags) 180void unmap_physmem(const void *ptr, unsigned long flags)
91{ 181{
92#ifdef CONFIG_PCI 182#ifdef CONFIG_PCI
93 if (map_dev) { 183 if (map_dev) {
94 pci_unmap_physmem(vaddr, map_len, map_dev); 184 pci_unmap_physmem(ptr, map_len, map_dev);
95 map_dev = NULL; 185 map_dev = NULL;
96 } 186 }
97#endif 187#endif
98} 188}
99 189
100void sandbox_set_enable_pci_map(int enable) 190phys_addr_t map_to_sysmem(const void *ptr)
101{ 191{
102 enable_pci_map = enable; 192 struct sandbox_mapmem_entry *mentry;
193
194 /*
195 * If it is in emulated RAM, don't bother creating a tag. Just return
196 * the offset into the RAM buffer.
197 */
198 if (is_in_sandbox_mem(ptr))
199 return (u8 *)ptr - gd->arch.ram_buf;
200
201 /*
202 * See if there is an existing tag with this pointer. If not, set up a
203 * new one.
204 */
205 mentry = find_tag(ptr);
206 if (!mentry) {
207 struct sandbox_state *state = state_get_current();
208
209 mentry = malloc(sizeof(*mentry));
210 if (!mentry) {
211 printf("%s: Error: Out of memory\n", __func__);
212 os_exit(ENOMEM);
213 }
214 mentry->tag = state->next_tag++;
215 mentry->ptr = (void *)ptr;
216 list_add_tail(&mentry->sibling_node, &state->mapmem_head);
217 debug("%s: Added map from %p to %lx\n", __func__, ptr,
218 (ulong)mentry->tag);
219 }
220
221 /*
222 * Return the tag as the address to use. A later call to map_sysmem()
223 * will return ptr
224 */
225 return mentry->tag;
103} 226}
104 227
105phys_addr_t map_to_sysmem(const void *ptr) 228void sandbox_set_enable_pci_map(int enable)
106{ 229{
107 return (u8 *)ptr - gd->arch.ram_buf; 230 enable_pci_map = enable;
108} 231}
109 232
110void flush_dcache_range(unsigned long start, unsigned long stop) 233void flush_dcache_range(unsigned long start, unsigned long stop)
@@ -165,15 +288,3 @@ ulong timer_get_boot_us(void)
165 288
166 return (count - base_count) / 1000; 289 return (count - base_count) / 1000;
167} 290}
168
169int setjmp(jmp_buf jmp)
170{
171 return os_setjmp((ulong *)jmp, sizeof(*jmp));
172}
173
174void longjmp(jmp_buf jmp, int ret)
175{
176 os_longjmp((ulong *)jmp, ret);
177 while (1)
178 ;
179}