OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [ppc/] [corefile.c] - Blame information for rev 26

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.