1 /* This file is part of the program psim.
3 Copyright (C) 1994-1995, 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.
25 #ifndef STATIC_INLINE_CPU
26 #define STATIC_INLINE_CPU STATIC_INLINE
39 /* current instruction address */
40 unsigned_word program_counter;
43 core *physical; /* all of memory */
45 vm_instruction_map *instruction_map; /* instructions */
46 vm_data_map *data_map; /* data */
48 /* current state of interrupt inputs */
49 int external_exception_pending;
51 /* the system this processor is contained within */
56 /* if required, a cache to store decoded instructions */
57 #if WITH_IDECODE_CACHE
58 idecode_cache icache[IDECODE_CACHE_SIZE];
61 /* address reservation: keep the physical address and the contents
62 of memory at that address */
63 memory_reservation reservation;
65 /* offset from event time to this cpu's idea of the local time */
66 signed64 time_base_local_time;
67 signed64 decrementer_local_time;
68 event_entry_tag decrementer_event;
70 /* Counts of number of instructions executed. */
76 cpu_create(psim *system,
81 cpu *processor = ZALLOC(cpu);
83 /* create the virtual memory map from the core */
84 processor->physical = memory;
85 processor->virtual = vm_create(memory);
86 processor->instruction_map = vm_create_instruction_map(processor->virtual);
87 processor->data_map = vm_create_data_map(processor->virtual);
89 /* link back to core system */
90 processor->system = system;
91 processor->events = events;
92 processor->cpu_nr = cpu_nr;
98 /* find ones way home */
101 cpu_system(cpu *processor)
103 return processor->system;
107 cpu_nr(cpu *processor)
109 return processor->cpu_nr;
112 INLINE_CPU event_queue *
113 cpu_event_queue(cpu *processor)
115 return processor->events;
119 /* The processors local concept of time */
122 cpu_get_time_base(cpu *processor)
124 return (event_queue_time(processor->events)
125 + processor->time_base_local_time);
129 cpu_set_time_base(cpu *processor,
132 processor->time_base_local_time = (event_queue_time(processor->events)
137 cpu_get_decrementer(cpu *processor)
139 return (processor->decrementer_local_time
140 - event_queue_time(processor->events));
143 STATIC_INLINE_CPU void
144 cpu_decrement_event(event_queue *queue,
147 cpu *processor = (cpu*)data;
148 if (!decrementer_interrupt(processor)) {
149 processor->decrementer_event = event_queue_schedule(processor->events,
157 cpu_set_decrementer(cpu *processor,
158 signed32 decrementer)
160 signed64 old_decrementer = (processor->decrementer_local_time
161 - event_queue_time(processor->events));
162 event_queue_deschedule(processor->events, processor->decrementer_event);
163 processor->decrementer_local_time = (event_queue_time(processor->events)
165 if (decrementer < 0 && old_decrementer >= 0)
166 /* dec interrupt occures if the sign of the decrement reg is
167 changed by the load operation */
168 processor->decrementer_event = event_queue_schedule(processor->events,
172 else if (decrementer >= 0)
173 processor->decrementer_event = event_queue_schedule(processor->events,
180 /* program counter manipulation */
183 cpu_set_program_counter(cpu *processor,
184 unsigned_word new_program_counter)
186 processor->program_counter = new_program_counter;
189 INLINE_CPU unsigned_word
190 cpu_get_program_counter(cpu *processor)
192 return processor->program_counter;
196 cpu_restart(cpu *processor,
199 processor->program_counter = nia;
200 psim_restart(processor->system, processor->cpu_nr);
204 cpu_halt(cpu *processor,
209 processor->program_counter = cia;
210 psim_halt(processor->system, processor->cpu_nr, cia, reason, signal);
214 #if WITH_IDECODE_CACHE
215 /* allow access to the cpu's instruction cache */
216 INLINE_CPU idecode_cache *
217 cpu_icache(cpu *processor)
219 return processor->icache;
224 /* address map revelation */
226 INLINE_CPU vm_instruction_map *
227 cpu_instruction_map(cpu *processor)
229 return processor->instruction_map;
232 INLINE_CPU vm_data_map *
233 cpu_data_map(cpu *processor)
235 return processor->data_map;
239 cpu_core(cpu *processor)
241 return processor->physical;
245 /* reservation access */
247 INLINE_CPU memory_reservation *
248 cpu_reservation(cpu *processor)
250 return &processor->reservation;
254 /* register access */
256 INLINE_CPU registers *
257 cpu_registers(cpu *processor)
259 return &processor->regs;
263 cpu_synchronize_context(cpu *processor)
265 #if WITH_IDECODE_CACHE
266 /* kill off the contents of the cache */
268 for (i = 0; i < IDECODE_CACHE_SIZE; i++)
269 processor->icache[i].address = MASK(0,63);
271 vm_synchronize_context(processor->virtual,
274 processor->regs.msr);
278 /* # of instructions counter access */
281 cpu_increment_number_of_insns(cpu *processor)
283 processor->number_of_insns++;
287 cpu_get_number_of_insns(cpu *processor)
289 return processor->number_of_insns;
293 cpu_print_info(cpu *processor, int verbose)
295 printf_filtered("CPU #%d executed %ld instructions.\n",
297 processor->number_of_insns);