1 /* This file is part of the program psim.
3 Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
26 #include "device_table.h"
29 typedef struct _core_mapping core_mapping
;
30 struct _core_mapping
{
58 core_map map
[nr_core_map_types
];
72 core_from_device(device
*root
)
74 root
= device_root(root
);
75 ASSERT(strcmp(device_name(root
), "core") == 0);
76 return device_data(root
);
82 core_init(core
*memory
)
84 core_map_types access_type
;
86 access_type
< nr_core_map_types
;
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
;
94 if (tbd
->free_buffer
!= NULL
) {
95 ASSERT(tbd
->buffer
!= NULL
);
96 zfree(tbd
->free_buffer
);
106 /* the core has three sub mappings that the more efficient
107 read/write fixed quantity functions use */
111 core_readable(core
*memory
)
113 return memory
->map
+ core_read_map
;
118 core_writeable(core
*memory
)
120 return memory
->map
+ core_write_map
;
125 core_executable(core
*memory
)
127 return memory
->map
+ core_execute_map
;
134 new_core_mapping(attach_type attach
,
142 core_mapping
*new_mapping
= ZALLOC(core_mapping
);
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
;
153 else if (attach
>= attach_callback
) {
154 new_mapping
->device
= device
;
157 error("new_core_mapping() - internal error - unknown attach type %d\n",
166 core_map_attach(core_map
*access_map
,
170 unsigned nr_bytes
, /* host limited */
171 device
*client
, /*callback/default*/
172 void *buffer
, /*raw_memory*/
173 void *free_buffer
) /*raw_memory*/
175 /* find the insertion point for this additional mapping and insert */
176 core_mapping
*next_mapping
;
177 core_mapping
**last_mapping
;
179 /* actually do occasionally get a zero size map */
181 device_error(client
, "called on core_map_attach() with size zero");
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
;
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
);
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
;
216 core_attach(core
*memory
,
221 unsigned nr_bytes
, /* host limited */
222 device
*client
) /*callback/default*/
224 core_map_types access_map
;
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
;
236 free_buffer
= &buffer
; /* marker for assertion */
239 access_map
< nr_core_map_types
;
241 switch (access_map
) {
243 if (access
& access_read
)
244 core_map_attach(memory
->map
+ access_map
,
246 space
, addr
, nr_bytes
,
247 client
, buffer
, free_buffer
);
251 if (access
& access_write
)
252 core_map_attach(memory
->map
+ access_map
,
254 space
, addr
, nr_bytes
,
255 client
, buffer
, free_buffer
);
258 case core_execute_map
:
259 if (access
& access_exec
)
260 core_map_attach(memory
->map
+ access_map
,
262 space
, addr
, nr_bytes
,
263 client
, buffer
, free_buffer
);
267 error("core_attach() internal error\n");
271 /* allocated buffer must attach to at least one thing */
272 ASSERT(free_buffer
== NULL
);
278 core_map_find_mapping(core_map
*map
,
283 int abort
) /*either 0 or 1 - helps inline */
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
)
292 mapping
= mapping
->next
;
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
);
303 core_translate(core_mapping
*mapping
,
306 return (void *)(((char *)mapping
->buffer
) + addr
- mapping
->base
);
312 core_map_read_buffer(core_map
*map
,
318 while (count
< len
) {
319 unsigned_word raddr
= addr
+ count
;
320 core_mapping
*mapping
=
321 core_map_find_mapping(map
,
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
,
338 0 /*cpu*/) != nr_bytes
)
343 ((unsigned_1
*)buffer
)[count
] =
344 *(unsigned_1
*)core_translate(mapping
, raddr
);
354 core_map_write_buffer(core_map
*map
,
360 while (count
< len
) {
361 unsigned_word raddr
= addr
+ count
;
362 core_mapping
*mapping
= core_map_find_mapping(map
,
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
,
379 0 /*cpu*/) != nr_bytes
)
384 *(unsigned_1
*)core_translate(mapping
, raddr
) =
385 ((unsigned_1
*)buffer
)[count
];
393 /* define the read/write 1/2/4/8/word functions */
396 #include "corefile-n.h"
400 #include "corefile-n.h"
404 #include "corefile-n.h"
408 #include "corefile-n.h"
412 #include "corefile-n.h"
415 #endif /* _CORE_C_ */