gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / sim / ppc / corefile.c
CommitLineData
c906108c
SS
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
3fd725ef 7 the Free Software Foundation; either version 3 of the License, or
c906108c
SS
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
51b318de 16 along with this program; if not, see <http://www.gnu.org/licenses/>.
c906108c
SS
17
18 */
19
20
21#ifndef _CORE_C_
22#define _CORE_C_
23
24#include "basics.h"
25#include "device_table.h"
26#include "corefile.h"
27
28typedef struct _core_mapping core_mapping;
29struct _core_mapping {
30 /* common */
31 int level;
32 int space;
33 unsigned_word base;
34 unsigned_word bound;
35 unsigned nr_bytes;
36 /* memory map */
37 void *free_buffer;
38 void *buffer;
39 /* callback map */
40 device *device;
41 /* growth */
42 core_mapping *next;
43};
44
45struct _core_map {
46 core_mapping *first;
47};
48
49typedef enum {
50 core_read_map,
51 core_write_map,
52 core_execute_map,
53 nr_core_map_types,
54} core_map_types;
55
56struct _core {
57 core_map map[nr_core_map_types];
58};
59
60
61INLINE_CORE\
62(core *)
63core_create(void)
64{
65 return ZALLOC(core);
66}
67
68
69INLINE_CORE\
70(core *)
71core_from_device(device *root)
72{
73 root = device_root(root);
74 ASSERT(strcmp(device_name(root), "core") == 0);
75 return device_data(root);
76}
77
78
79INLINE_CORE\
80(void)
81core_init(core *memory)
82{
83 core_map_types access_type;
84 for (access_type = 0;
85 access_type < nr_core_map_types;
86 access_type++) {
87 core_map *map = memory->map + access_type;
88 /* blow away old mappings */
89 core_mapping *curr = map->first;
90 while (curr != NULL) {
91 core_mapping *tbd = curr;
92 curr = curr->next;
93 if (tbd->free_buffer != NULL) {
94 ASSERT(tbd->buffer != NULL);
d79fe0d6 95 free(tbd->free_buffer);
c906108c 96 }
d79fe0d6 97 free(tbd);
c906108c
SS
98 }
99 map->first = NULL;
100 }
101}
102
103
104
105/* the core has three sub mappings that the more efficient
106 read/write fixed quantity functions use */
107
108INLINE_CORE\
109(core_map *)
110core_readable(core *memory)
111{
112 return memory->map + core_read_map;
113}
114
115INLINE_CORE\
116(core_map *)
117core_writeable(core *memory)
118{
119 return memory->map + core_write_map;
120}
121
122INLINE_CORE\
123(core_map *)
124core_executable(core *memory)
125{
126 return memory->map + core_execute_map;
127}
128
129
130
131STATIC_INLINE_CORE\
132(core_mapping *)
133new_core_mapping(attach_type attach,
134 int space,
135 unsigned_word addr,
136 unsigned nr_bytes,
137 device *device,
138 void *buffer,
139 void *free_buffer)
140{
141 core_mapping *new_mapping = ZALLOC(core_mapping);
142 /* common */
143 new_mapping->level = attach;
144 new_mapping->space = space;
145 new_mapping->base = addr;
146 new_mapping->nr_bytes = nr_bytes;
147 new_mapping->bound = addr + (nr_bytes - 1);
148 if (attach == attach_raw_memory) {
149 new_mapping->buffer = buffer;
150 new_mapping->free_buffer = free_buffer;
151 }
152 else if (attach >= attach_callback) {
153 new_mapping->device = device;
154 }
155 else {
156 error("new_core_mapping() - internal error - unknown attach type %d\n",
157 attach);
158 }
159 return new_mapping;
160}
161
162
163STATIC_INLINE_CORE\
164(void)
165core_map_attach(core_map *access_map,
166 attach_type attach,
167 int space,
168 unsigned_word addr,
169 unsigned nr_bytes, /* host limited */
170 device *client, /*callback/default*/
171 void *buffer, /*raw_memory*/
172 void *free_buffer) /*raw_memory*/
173{
174 /* find the insertion point for this additional mapping and insert */
175 core_mapping *next_mapping;
176 core_mapping **last_mapping;
177
178 /* actually do occasionally get a zero size map */
179 if (nr_bytes == 0) {
180 device_error(client, "called on core_map_attach() with size zero");
181 }
182
183 /* find the insertion point (between last/next) */
184 next_mapping = access_map->first;
185 last_mapping = &access_map->first;
186 while(next_mapping != NULL
187 && (next_mapping->level < attach
188 || (next_mapping->level == attach
189 && next_mapping->bound < addr))) {
190 /* provided levels are the same */
191 /* assert: next_mapping->base > all bases before next_mapping */
192 /* assert: next_mapping->bound >= all bounds before next_mapping */
193 last_mapping = &next_mapping->next;
194 next_mapping = next_mapping->next;
195 }
196
197 /* check insertion point correct */
198 ASSERT(next_mapping == NULL || next_mapping->level >= attach);
199 if (next_mapping != NULL && next_mapping->level == attach
200 && next_mapping->base < (addr + (nr_bytes - 1))) {
201 device_error(client, "map overlap when attaching %d:0x%lx (%ld)",
202 space, (long)addr, (long)nr_bytes);
203 }
204
205 /* create/insert the new mapping */
206 *last_mapping = new_core_mapping(attach,
207 space, addr, nr_bytes,
208 client, buffer, free_buffer);
209 (*last_mapping)->next = next_mapping;
210}
211
212
213INLINE_CORE\
214(void)
215core_attach(core *memory,
216 attach_type attach,
217 int space,
218 access_type access,
219 unsigned_word addr,
220 unsigned nr_bytes, /* host limited */
221 device *client) /*callback/default*/
222{
223 core_map_types access_map;
224 void *buffer;
225 void *free_buffer;
226 if (attach == attach_raw_memory) {
227 /* Padd out the raw buffer to ensure that ADDR starts on a
228 correctly aligned boundary */
229 int padding = (addr % sizeof (unsigned64));
230 free_buffer = zalloc(nr_bytes + padding);
231 buffer = (char*)free_buffer + padding;
232 }
233 else {
234 buffer = NULL;
235 free_buffer = &buffer; /* marker for assertion */
236 }
237 for (access_map = 0;
238 access_map < nr_core_map_types;
239 access_map++) {
240 switch (access_map) {
241 case core_read_map:
242 if (access & access_read)
243 core_map_attach(memory->map + access_map,
244 attach,
245 space, addr, nr_bytes,
246 client, buffer, free_buffer);
247 free_buffer = NULL;
248 break;
249 case core_write_map:
250 if (access & access_write)
251 core_map_attach(memory->map + access_map,
252 attach,
253 space, addr, nr_bytes,
254 client, buffer, free_buffer);
255 free_buffer = NULL;
256 break;
257 case core_execute_map:
258 if (access & access_exec)
259 core_map_attach(memory->map + access_map,
260 attach,
261 space, addr, nr_bytes,
262 client, buffer, free_buffer);
263 free_buffer = NULL;
264 break;
265 default:
266 error("core_attach() internal error\n");
267 break;
268 }
269 }
270 /* allocated buffer must attach to at least one thing */
271 ASSERT(free_buffer == NULL);
272}
273
274
275STATIC_INLINE_CORE\
276(core_mapping *)
277core_map_find_mapping(core_map *map,
278 unsigned_word addr,
279 unsigned nr_bytes,
280 cpu *processor,
281 unsigned_word cia,
282 int abort) /*either 0 or 1 - helps inline */
283{
284 core_mapping *mapping = map->first;
285 ASSERT((addr & (nr_bytes - 1)) == 0); /* must be aligned */
286 ASSERT((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
287 while (mapping != NULL) {
288 if (addr >= mapping->base
289 && (addr + (nr_bytes - 1)) <= mapping->bound)
290 return mapping;
291 mapping = mapping->next;
292 }
293 if (abort)
294 error("core_find_mapping() - access to unmaped address, attach a default map to handle this - addr=0x%x nr_bytes=0x%x processor=0x%x cia=0x%x\n",
295 addr, nr_bytes, processor, cia);
296 return NULL;
297}
298
299
300STATIC_INLINE_CORE\
301(void *)
302core_translate(core_mapping *mapping,
303 unsigned_word addr)
304{
305 return (void *)(((char *)mapping->buffer) + addr - mapping->base);
306}
307
308
309INLINE_CORE\
310(unsigned)
311core_map_read_buffer(core_map *map,
312 void *buffer,
313 unsigned_word addr,
314 unsigned len)
315{
316 unsigned count = 0;
317 while (count < len) {
318 unsigned_word raddr = addr + count;
319 core_mapping *mapping =
320 core_map_find_mapping(map,
321 raddr, 1,
322 NULL, /*processor*/
323 0, /*cia*/
324 0); /*dont-abort*/
325 if (mapping == NULL)
326 break;
327 if (mapping->device != NULL) {
328 int nr_bytes = len - count;
329 if (raddr + nr_bytes - 1> mapping->bound)
330 nr_bytes = mapping->bound - raddr + 1;
331 if (device_io_read_buffer(mapping->device,
332 (unsigned_1*)buffer + count,
333 mapping->space,
334 raddr,
335 nr_bytes,
336 0, /*processor*/
337 0 /*cpu*/) != nr_bytes)
338 break;
339 count += nr_bytes;
340 }
341 else {
342 ((unsigned_1*)buffer)[count] =
343 *(unsigned_1*)core_translate(mapping, raddr);
344 count += 1;
345 }
346 }
347 return count;
348}
349
350
351INLINE_CORE\
352(unsigned)
353core_map_write_buffer(core_map *map,
354 const void *buffer,
355 unsigned_word addr,
356 unsigned len)
357{
358 unsigned count = 0;
359 while (count < len) {
360 unsigned_word raddr = addr + count;
361 core_mapping *mapping = core_map_find_mapping(map,
362 raddr, 1,
363 NULL, /*processor*/
364 0, /*cia*/
365 0); /*dont-abort*/
366 if (mapping == NULL)
367 break;
368 if (mapping->device != NULL) {
369 int nr_bytes = len - count;
370 if (raddr + nr_bytes - 1 > mapping->bound)
371 nr_bytes = mapping->bound - raddr + 1;
372 if (device_io_write_buffer(mapping->device,
373 (unsigned_1*)buffer + count,
374 mapping->space,
375 raddr,
376 nr_bytes,
377 0, /*processor*/
378 0 /*cpu*/) != nr_bytes)
379 break;
380 count += nr_bytes;
381 }
382 else {
383 *(unsigned_1*)core_translate(mapping, raddr) =
384 ((unsigned_1*)buffer)[count];
385 count += 1;
386 }
387 }
388 return count;
389}
390
391
392/* define the read/write 1/2/4/8/word functions */
393
394#define N 1
395#include "corefile-n.h"
396#undef N
397
398#define N 2
399#include "corefile-n.h"
400#undef N
401
402#define N 4
403#include "corefile-n.h"
404#undef N
405
406#define N 8
407#include "corefile-n.h"
408#undef N
409
410#define N word
411#include "corefile-n.h"
412#undef N
413
414#endif /* _CORE_C_ */
This page took 1.095618 seconds and 4 git commands to generate.