1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, 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.
30 core_init(engine
*system
)
32 core
*memory
= &system
->memory
;
37 /* blow away old mappings */
38 core_mapping
*curr
= memory
->map
[map
].first
;
39 while (curr
!= NULL
) {
40 core_mapping
*tbd
= curr
;
42 if (tbd
->free_buffer
) {
43 ASSERT(tbd
->buffer
!= NULL
);
48 memory
->map
[map
].first
= NULL
;
54 STATIC_INLINE_SIM_CORE\
56 new_core_mapping(engine
*system
,
65 core_mapping
*new_mapping
= ZALLOC(core_mapping
);
67 new_mapping
->level
= attach
;
68 new_mapping
->space
= space
;
69 new_mapping
->base
= addr
;
70 new_mapping
->nr_bytes
= nr_bytes
;
71 new_mapping
->bound
= addr
+ (nr_bytes
- 1);
72 if (attach
== attach_raw_memory
) {
73 new_mapping
->buffer
= buffer
;
74 new_mapping
->free_buffer
= free_buffer
;
76 else if (attach
>= attach_callback
) {
77 new_mapping
->device
= device
;
80 engine_error(system
, "new_core_mapping - internal error - unknown attach type %d\n",
87 STATIC_INLINE_SIM_CORE\
89 core_map_attach(engine
*system
,
94 unsigned nr_bytes
, /* host limited */
95 device
*client
, /*callback/default*/
96 void *buffer
, /*raw_memory*/
97 int free_buffer
) /*raw_memory*/
99 /* find the insertion point for this additional mapping and then
101 core_mapping
*next_mapping
;
102 core_mapping
**last_mapping
;
104 ASSERT((attach
>= attach_callback
&& client
!= NULL
&& buffer
== NULL
&& !free_buffer
)
105 || (attach
== attach_raw_memory
&& client
== NULL
&& buffer
!= NULL
));
107 /* actually do occasionally get a zero size map */
110 device_error(client
, "called on core_map_attach with size zero");
112 engine_error(system
, "called on core_map_attach with size zero");
116 /* find the insertion point (between last/next) */
117 next_mapping
= access_map
->first
;
118 last_mapping
= &access_map
->first
;
119 while(next_mapping
!= NULL
120 && (next_mapping
->level
< attach
121 || (next_mapping
->level
== attach
122 && next_mapping
->bound
< addr
))) {
123 /* provided levels are the same */
124 /* assert: next_mapping->base > all bases before next_mapping */
125 /* assert: next_mapping->bound >= all bounds before next_mapping */
126 last_mapping
= &next_mapping
->next
;
127 next_mapping
= next_mapping
->next
;
130 /* check insertion point correct */
131 ASSERT(next_mapping
== NULL
|| next_mapping
->level
>= attach
);
132 if (next_mapping
!= NULL
&& next_mapping
->level
== attach
133 && next_mapping
->base
< (addr
+ (nr_bytes
- 1))) {
135 device_error(client
, "map overlap when attaching %d:0x%lx (%ld)",
136 space
, (long)addr
, (long)nr_bytes
);
138 engine_error(system
, "map overlap when attaching %d:0x%lx (%ld)",
139 space
, (long)addr
, (long)nr_bytes
);
143 /* create/insert the new mapping */
144 *last_mapping
= new_core_mapping(system
,
146 space
, addr
, nr_bytes
,
147 client
, buffer
, free_buffer
);
148 (*last_mapping
)->next
= next_mapping
;
154 core_attach(engine
*system
,
159 unsigned nr_bytes
, /* host limited */
161 void *optional_buffer
)
163 core
*memory
= &system
->memory
;
167 if ((access
& access_read_write_exec
) == 0
168 || (access
& ~access_read_write_exec
) != 0) {
170 device_error(client
, "invalid access for core attach");
172 engine_error(system
, "invalid access for core attach");
175 /* verify the attach type */
176 if (attach
== attach_raw_memory
) {
177 if (optional_buffer
== NULL
) {
178 buffer
= zalloc(nr_bytes
);
182 buffer
= optional_buffer
;
186 else if (attach
>= attach_callback
) {
192 device_error(client
, "core_attach - conflicting buffer and attach arguments");
194 engine_error(system
, "core_attach - conflicting buffer and attach arguments");
199 /* attach the region to all applicable access maps */
205 if (access
& access_read
)
206 core_map_attach(system
, &memory
->map
[map
],
208 space
, addr
, nr_bytes
,
209 client
, buffer
, !buffer_freed
);
213 if (access
& access_write
)
214 core_map_attach(system
, &memory
->map
[map
],
216 space
, addr
, nr_bytes
,
217 client
, buffer
, !buffer_freed
);
220 case core_execute_map
:
221 if (access
& access_exec
)
222 core_map_attach(system
, &memory
->map
[map
],
224 space
, addr
, nr_bytes
,
225 client
, buffer
, !buffer_freed
);
229 engine_error(system
, "core_attach - internal error - bad switch");
236 STATIC_INLINE_SIM_CORE\
238 core_map_find_mapping(engine
*system
,
242 int abort
) /*either 0 or 1 - helps inline */
244 core_mapping
*mapping
= system
->memory
.map
[map
].first
;
245 ASSERT((addr
& (nr_bytes
- 1)) == 0); /* must be aligned */
246 ASSERT((addr
+ (nr_bytes
- 1)) >= addr
); /* must not wrap */
247 while (mapping
!= NULL
) {
248 if (addr
>= mapping
->base
249 && (addr
+ (nr_bytes
- 1)) <= mapping
->bound
)
251 mapping
= mapping
->next
;
254 engine_error(system
, "access to unmaped address 0x%x (%d bytes)\n",
260 STATIC_INLINE_SIM_CORE\
262 core_translate(core_mapping
*mapping
,
265 return (void *)(((char *)mapping
->buffer
) + addr
- mapping
->base
);
271 core_map_read_buffer(engine
*system
,
278 while (count
< len
) {
279 unsigned_word raddr
= addr
+ count
;
280 core_mapping
*mapping
=
281 core_map_find_mapping(system
, map
,
287 if (mapping
->device
!= NULL
) {
288 int nr_bytes
= len
- count
;
289 if (raddr
+ nr_bytes
- 1> mapping
->bound
)
290 nr_bytes
= mapping
->bound
- raddr
+ 1;
291 if (device_io_read_buffer(mapping
->device
,
292 (unsigned_1
*)buffer
+ count
,
295 nr_bytes
) != nr_bytes
)
302 ((unsigned_1
*)buffer
)[count
] =
303 *(unsigned_1
*)core_translate(mapping
, raddr
);
313 core_map_write_buffer(engine
*system
,
320 while (count
< len
) {
321 unsigned_word raddr
= addr
+ count
;
322 core_mapping
*mapping
= core_map_find_mapping(system
, map
,
328 if (WITH_CALLBACK_MEMORY
329 && mapping
->device
!= NULL
) {
330 int nr_bytes
= len
- count
;
331 if (raddr
+ nr_bytes
- 1 > mapping
->bound
)
332 nr_bytes
= mapping
->bound
- raddr
+ 1;
333 if (device_io_write_buffer(mapping
->device
,
334 (unsigned_1
*)buffer
+ count
,
337 nr_bytes
) != nr_bytes
)
344 *(unsigned_1
*)core_translate(mapping
, raddr
) =
345 ((unsigned_1
*)buffer
)[count
];
353 /* define the read/write 1/2/4/8/word functions */
356 #include "sim-n-core.h"
360 #include "sim-n-core.h"
364 #include "sim-n-core.h"
368 #include "sim-n-core.h"
372 #include "sim-n-core.h"
This page took 0.037967 seconds and 5 git commands to generate.