gdb: remove newlines from some linux_nat_debug_printf calls
[binutils-gdb.git] / sim / ppc / cpu.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1997, 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 3 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, see <http://www.gnu.org/licenses/>.
17
18 */
19
20
21 #ifndef _CPU_C_
22 #define _CPU_C_
23
24 /* This must come before any other includes. */
25 #include "defs.h"
26
27 #include <setjmp.h>
28
29 #include "cpu.h"
30 #include "idecode.h"
31
32 #include <string.h>
33
34 struct _cpu {
35
36 /* the registers */
37 registers regs;
38
39 /* current instruction address */
40 unsigned_word program_counter;
41
42 /* the memory maps */
43 core *physical; /* all of memory */
44 vm *virtual;
45 vm_instruction_map *instruction_map; /* instructions */
46 vm_data_map *data_map; /* data */
47
48 /* the system this processor is contained within */
49 cpu_mon *monitor;
50 os_emul *os_emulation;
51 psim *system;
52 event_queue *events;
53 int cpu_nr;
54
55 /* Current CPU model information */
56 model_data *model_ptr;
57
58 #if WITH_IDECODE_CACHE_SIZE
59 /* a cache to store cracked instructions */
60 idecode_cache icache[WITH_IDECODE_CACHE_SIZE];
61 #endif
62
63 /* any interrupt state */
64 interrupts ints;
65
66 /* address reservation: keep the physical address and the contents
67 of memory at that address */
68 memory_reservation reservation;
69
70 /* offset from event time to this cpu's idea of the local time */
71 int64_t time_base_local_time;
72 int64_t decrementer_local_time;
73 event_entry_tag decrementer_event;
74
75 };
76
77 INLINE_CPU\
78 (cpu *)
79 cpu_create(psim *system,
80 core *memory,
81 cpu_mon *monitor,
82 os_emul *os_emulation,
83 int cpu_nr)
84 {
85 cpu *processor = ZALLOC(cpu);
86
87 /* create the virtual memory map from the core */
88 processor->physical = memory;
89 processor->virtual = vm_create(memory);
90 processor->instruction_map = vm_create_instruction_map(processor->virtual);
91 processor->data_map = vm_create_data_map(processor->virtual);
92
93 if (CURRENT_MODEL_ISSUE > 0)
94 processor->model_ptr = model_create (processor);
95
96 /* link back to core system */
97 processor->system = system;
98 processor->events = psim_event_queue(system);
99 processor->cpu_nr = cpu_nr;
100 processor->monitor = monitor;
101 processor->os_emulation = os_emulation;
102
103 return processor;
104 }
105
106
107 INLINE_CPU\
108 (void)
109 cpu_init(cpu *processor)
110 {
111 memset(&processor->regs, 0, sizeof(processor->regs));
112 /* vm init is delayed until after the device tree has been init as
113 the devices may further init the cpu */
114 if (CURRENT_MODEL_ISSUE > 0)
115 model_init (processor->model_ptr);
116 }
117
118
119 /* find ones way home */
120
121 INLINE_CPU\
122 (psim *)
123 cpu_system(cpu *processor)
124 {
125 return processor->system;
126 }
127
128 INLINE_CPU\
129 (int)
130 cpu_nr(cpu *processor)
131 {
132 return processor->cpu_nr;
133 }
134
135 INLINE_CPU\
136 (cpu_mon *)
137 cpu_monitor(cpu *processor)
138 {
139 return processor->monitor;
140 }
141
142 INLINE_CPU\
143 (os_emul *)
144 cpu_os_emulation(cpu *processor)
145 {
146 return processor->os_emulation;
147 }
148
149 INLINE_CPU\
150 (model_data *)
151 cpu_model(cpu *processor)
152 {
153 return processor->model_ptr;
154 }
155
156
157 /* program counter manipulation */
158
159 INLINE_CPU\
160 (void)
161 cpu_set_program_counter(cpu *processor,
162 unsigned_word new_program_counter)
163 {
164 processor->program_counter = new_program_counter;
165 }
166
167 INLINE_CPU\
168 (unsigned_word)
169 cpu_get_program_counter(cpu *processor)
170 {
171 return processor->program_counter;
172 }
173
174
175 INLINE_CPU\
176 (void)
177 cpu_restart(cpu *processor,
178 unsigned_word nia)
179 {
180 ASSERT(processor != NULL);
181 cpu_set_program_counter(processor, nia);
182 psim_restart(processor->system, processor->cpu_nr);
183 }
184
185 INLINE_CPU\
186 (void)
187 cpu_halt(cpu *processor,
188 unsigned_word nia,
189 stop_reason reason,
190 int signal)
191 {
192 ASSERT(processor != NULL);
193 if (CURRENT_MODEL_ISSUE > 0)
194 model_halt(processor->model_ptr);
195 cpu_set_program_counter(processor, nia);
196 psim_halt(processor->system, processor->cpu_nr, reason, signal);
197 }
198
199 EXTERN_CPU\
200 (void)
201 cpu_error(cpu *processor,
202 unsigned_word cia,
203 const char *fmt,
204 ...)
205 {
206 char message[1024];
207 va_list ap;
208
209 /* format the message */
210 va_start(ap, fmt);
211 vsprintf(message, fmt, ap);
212 va_end(ap);
213
214 /* sanity check */
215 if (strlen(message) >= sizeof(message))
216 error("cpu_error: buffer overflow");
217
218 if (processor != NULL) {
219 printf_filtered("cpu %d, cia 0x%lx: %s\n",
220 processor->cpu_nr + 1, (unsigned long)cia, message);
221 cpu_halt(processor, cia, was_signalled, -1);
222 }
223 else {
224 error("cpu: %s", message);
225 }
226 }
227
228
229 /* The processors local concept of time */
230
231 INLINE_CPU\
232 (int64_t)
233 cpu_get_time_base(cpu *processor)
234 {
235 return (event_queue_time(processor->events)
236 - processor->time_base_local_time);
237 }
238
239 INLINE_CPU\
240 (void)
241 cpu_set_time_base(cpu *processor,
242 int64_t time_base)
243 {
244 processor->time_base_local_time = (event_queue_time(processor->events)
245 - time_base);
246 }
247
248 INLINE_CPU\
249 (int32_t)
250 cpu_get_decrementer(cpu *processor)
251 {
252 return (processor->decrementer_local_time
253 - event_queue_time(processor->events));
254 }
255
256 STATIC_INLINE_CPU\
257 (void)
258 cpu_decrement_event(void *data)
259 {
260 cpu *processor = (cpu*)data;
261 processor->decrementer_event = NULL;
262 decrementer_interrupt(processor);
263 }
264
265 INLINE_CPU\
266 (void)
267 cpu_set_decrementer(cpu *processor,
268 int32_t decrementer)
269 {
270 int64_t old_decrementer = cpu_get_decrementer(processor);
271 event_queue_deschedule(processor->events, processor->decrementer_event);
272 processor->decrementer_event = NULL;
273 processor->decrementer_local_time = (event_queue_time(processor->events)
274 + decrementer);
275 if (decrementer < 0 && old_decrementer >= 0)
276 /* A decrementer interrupt occures if the sign of the decrement
277 register is changed from positive to negative by the load
278 instruction */
279 decrementer_interrupt(processor);
280 else if (decrementer >= 0)
281 processor->decrementer_event = event_queue_schedule(processor->events,
282 decrementer,
283 cpu_decrement_event,
284 processor);
285 }
286
287
288 #if WITH_IDECODE_CACHE_SIZE
289 /* allow access to the cpu's instruction cache */
290 INLINE_CPU\
291 (idecode_cache *)
292 cpu_icache_entry(cpu *processor,
293 unsigned_word cia)
294 {
295 return &processor->icache[cia / 4 % WITH_IDECODE_CACHE_SIZE];
296 }
297
298
299 INLINE_CPU\
300 (void)
301 cpu_flush_icache(cpu *processor)
302 {
303 int i;
304 /* force all addresses to 0xff... so that they never hit */
305 for (i = 0; i < WITH_IDECODE_CACHE_SIZE; i++)
306 processor->icache[i].address = MASK(0, 63);
307 }
308 #endif
309
310
311 /* address map revelation */
312
313 INLINE_CPU\
314 (vm_instruction_map *)
315 cpu_instruction_map(cpu *processor)
316 {
317 return processor->instruction_map;
318 }
319
320 INLINE_CPU\
321 (vm_data_map *)
322 cpu_data_map(cpu *processor)
323 {
324 return processor->data_map;
325 }
326
327 INLINE_CPU\
328 (void)
329 cpu_page_tlb_invalidate_entry(cpu *processor,
330 unsigned_word ea)
331 {
332 vm_page_tlb_invalidate_entry(processor->virtual, ea);
333 }
334
335 INLINE_CPU\
336 (void)
337 cpu_page_tlb_invalidate_all(cpu *processor)
338 {
339 vm_page_tlb_invalidate_all(processor->virtual);
340 }
341
342
343 /* interrupt access */
344
345 INLINE_CPU\
346 (interrupts *)
347 cpu_interrupts(cpu *processor)
348 {
349 return &processor->ints;
350 }
351
352
353
354 /* reservation access */
355
356 INLINE_CPU\
357 (memory_reservation *)
358 cpu_reservation(cpu *processor)
359 {
360 return &processor->reservation;
361 }
362
363
364 /* register access */
365
366 INLINE_CPU\
367 (registers *)
368 cpu_registers(cpu *processor)
369 {
370 return &processor->regs;
371 }
372
373 INLINE_CPU\
374 (void)
375 cpu_synchronize_context(cpu *processor,
376 unsigned_word cia)
377 {
378 #if (WITH_IDECODE_CACHE_SIZE)
379 /* kill of the cache */
380 cpu_flush_icache(processor);
381 #endif
382
383 /* update virtual memory */
384 vm_synchronize_context(processor->virtual,
385 processor->regs.spr,
386 processor->regs.sr,
387 processor->regs.msr,
388 processor, cia);
389 }
390
391
392 /* might again be useful one day */
393
394 INLINE_CPU\
395 (void)
396 cpu_print_info(cpu *processor, int verbose)
397 {
398 }
399
400 #endif /* _CPU_C_ */