Copyright year update in most files of the GDB Project.
[platform/upstream/binutils.git] / sim / mn10300 / dv-mn103cpu.c
1 /*  This file is part of the program GDB, the GNU debugger.
2     
3     Copyright (C) 1998, 2007-2012 Free Software Foundation, Inc.
4     Contributed by Cygnus Solutions.
5     
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18     
19     */
20
21
22 #include "sim-main.h"
23 #include "hw-main.h"
24
25 /* DEVICE
26
27    
28    mn103cpu - mn10300 cpu virtual device
29
30    
31    DESCRIPTION
32
33    
34    Implements the external mn10300 functionality.  This includes the
35    delivery of interrupts generated from other devices and the
36    handling of device specific registers.
37
38
39    PROPERTIES
40    
41
42    reg = <address> <size>
43
44    Specify the address of the mn10300's control register block.  This
45    block contains the Interrupt Vector Registers.
46
47    The reg property value `0x20000000 0x42' locates the register block
48    at the address specified in the mn10300 user guide.
49
50
51    PORTS
52
53
54    reset (input)
55
56    Currently ignored.
57
58
59    nmi (input)
60
61    Deliver a non-maskable interrupt to the processor.
62
63
64    level (input)
65
66    Maskable interrupt level port port.  The interrupt controller
67    notifies the processor of any change in the level of pending
68    requested interrupts via this port.
69
70
71    ack (output)
72
73    Output signal indicating that the processor is delivering a level
74    interrupt.  The value passed with the event specifies the level of
75    the interrupt being delivered.
76
77
78    BUGS
79
80
81    When delivering an interrupt, this code assumes that there is only
82    one processor (number 0).
83
84    This code does not attempt to be efficient at handling pending
85    interrupts.  It simply schedules the interrupt delivery handler
86    every instruction cycle until all pending interrupts go away.  An
87    alternative implementation might modify instructions that change
88    the PSW and have them check to see if the change makes an interrupt
89    delivery possible.
90
91    */
92
93
94 /* The interrupt vectors */
95
96 enum { NR_VECTORS = 7, };
97
98
99 /* The interrupt controller register address blocks */
100
101 struct mn103cpu_block {
102   unsigned_word base;
103   unsigned_word bound;
104 };
105
106
107 struct mn103cpu {
108   struct mn103cpu_block block;
109   struct hw_event *pending_handler;
110   int pending_level;
111   int pending_nmi;
112   int pending_reset;
113   /* the visible registers */
114   unsigned16 interrupt_vector[NR_VECTORS];
115   unsigned16 internal_memory_control;
116   unsigned16 cpu_mode;
117 };
118
119
120
121 /* input port ID's */ 
122
123 enum {
124   RESET_PORT,
125   NMI_PORT,
126   LEVEL_PORT,
127 };
128
129
130 /* output port ID's */
131
132 enum {
133   ACK_PORT,
134 };
135
136 static const struct hw_port_descriptor mn103cpu_ports[] = {
137
138   /* interrupt inputs */
139   { "reset", RESET_PORT, 0, input_port, },
140   { "nmi", NMI_PORT, 0, input_port, },
141   { "level", LEVEL_PORT, 0, input_port, },
142
143   /* interrupt ack (latch) output from cpu */
144   { "ack", ACK_PORT, 0, output_port, },
145
146   { NULL, },
147 };
148
149
150 /* Finish off the partially created hw device.  Attach our local
151    callbacks.  Wire up our port names etc */
152
153 static hw_io_read_buffer_method mn103cpu_io_read_buffer;
154 static hw_io_write_buffer_method mn103cpu_io_write_buffer;
155 static hw_port_event_method mn103cpu_port_event;
156
157 static void
158 attach_mn103cpu_regs (struct hw *me,
159                       struct mn103cpu *controller)
160 {
161   unsigned_word attach_address;
162   int attach_space;
163   unsigned attach_size;
164   reg_property_spec reg;
165   if (hw_find_property (me, "reg") == NULL)
166     hw_abort (me, "Missing \"reg\" property");
167   if (!hw_find_reg_array_property (me, "reg", 0, &reg))
168     hw_abort (me, "\"reg\" property must contain three addr/size entries");
169   hw_unit_address_to_attach_address (hw_parent (me),
170                                      &reg.address,
171                                      &attach_space,
172                                      &attach_address,
173                                      me);
174   controller->block.base = attach_address;
175   hw_unit_size_to_attach_size (hw_parent (me),
176                                &reg.size,
177                                &attach_size, me);
178   controller->block.bound = attach_address + (attach_size - 1);
179   if ((controller->block.base & 3) != 0)
180     hw_abort (me, "cpu register block must be 4 byte aligned");
181   hw_attach_address (hw_parent (me),
182                      0,
183                      attach_space, attach_address, attach_size,
184                      me);
185 }
186
187
188 static void
189 mn103cpu_finish (struct hw *me)
190 {
191   struct mn103cpu *controller;
192
193   controller = HW_ZALLOC (me, struct mn103cpu);
194   set_hw_data (me, controller);
195   set_hw_io_read_buffer (me, mn103cpu_io_read_buffer);
196   set_hw_io_write_buffer (me, mn103cpu_io_write_buffer);
197   set_hw_ports (me, mn103cpu_ports);
198   set_hw_port_event (me, mn103cpu_port_event);
199
200   /* Attach ourself to our parent bus */
201   attach_mn103cpu_regs (me, controller);
202
203   /* Initialize the read-only registers */
204   controller->pending_level = 7; /* FIXME */
205   /* ... */
206 }
207
208
209
210 /* An event arrives on an interrupt port */
211
212 static void
213 deliver_mn103cpu_interrupt (struct hw *me,
214                             void *data)
215 {
216   struct mn103cpu *controller = hw_data (me);
217   SIM_DESC simulator = hw_system (me);
218   sim_cpu *cpu = STATE_CPU (simulator, 0);
219
220   if (controller->pending_reset)
221     {
222       controller->pending_reset = 0;
223       /* need to clear all registers et.al! */
224       HW_TRACE ((me, "Reset!"));
225       hw_abort (me, "Reset!");
226     }
227   else if (controller->pending_nmi)
228     {
229       controller->pending_nmi = 0;
230       store_word (SP - 4, CIA_GET (cpu));
231       store_half (SP - 8, PSW);
232       PSW &= ~PSW_IE;
233       SP = SP - 8;
234       CIA_SET (cpu, 0x40000008);
235       HW_TRACE ((me, "nmi pc=0x%08lx psw=0x%04x sp=0x%08lx",
236                  (long) CIA_GET (cpu), (unsigned) PSW, (long) SP));
237     }
238   else if ((controller->pending_level < EXTRACT_PSW_LM)
239            && (PSW & PSW_IE))
240     {
241       /* Don't clear pending level.  Request continues to be pending
242          until the interrupt controller clears/changes it */
243       store_word (SP - 4, CIA_GET (cpu));
244       store_half (SP - 8, PSW);
245       PSW &= ~PSW_IE;
246       PSW &= ~PSW_LM;
247       PSW |= INSERT_PSW_LM (controller->pending_level);
248       SP = SP - 8;
249       CIA_SET (cpu, 0x40000000 + controller->interrupt_vector[controller->pending_level]);
250       HW_TRACE ((me, "port-out ack %d", controller->pending_level));
251       hw_port_event (me, ACK_PORT, controller->pending_level);
252       HW_TRACE ((me, "int level=%d pc=0x%08lx psw=0x%04x sp=0x%08lx",
253                  controller->pending_level,
254                  (long) CIA_GET (cpu), (unsigned) PSW, (long) SP));
255     }
256
257   if (controller->pending_level < 7) /* FIXME */
258     {
259       /* As long as there is the potential need to deliver an
260          interrupt we keep rescheduling this routine. */
261       if (controller->pending_handler != NULL)
262         controller->pending_handler =
263           hw_event_queue_schedule (me, 1, deliver_mn103cpu_interrupt, NULL);
264     }
265   else
266     {
267       /* Don't bother re-scheduling the interrupt handler as there is
268          nothing to deliver */
269       controller->pending_handler = NULL;
270     }
271
272 }
273
274
275 static void
276 mn103cpu_port_event (struct hw *me,
277                      int my_port,
278                      struct hw *source,
279                      int source_port,
280                      int level)
281 {
282   struct mn103cpu *controller = hw_data (me);
283
284   /* Schedule our event handler *now* */
285   if (controller->pending_handler == NULL)
286     controller->pending_handler =
287       hw_event_queue_schedule (me, 0, deliver_mn103cpu_interrupt, NULL);
288
289   switch (my_port)
290     {
291       
292     case RESET_PORT:
293       controller->pending_reset = 1;
294       HW_TRACE ((me, "port-in reset"));
295       break;
296       
297     case NMI_PORT:
298       controller->pending_nmi = 1;
299       HW_TRACE ((me, "port-in nmi"));
300       break;
301       
302     case LEVEL_PORT:
303       controller->pending_level = level;
304       HW_TRACE ((me, "port-in level=%d", level));
305       break;
306       
307     default:
308       hw_abort (me, "bad switch");
309       break;
310
311     }
312 }
313
314
315 /* Read/write to a CPU register */
316
317 enum mn103cpu_regs {
318   INVALID_REG,
319   IVR0_REG,
320   IVR1_REG,
321   IVR2_REG,
322   IVR3_REG,
323   IVR4_REG,
324   IVR5_REG,
325   IVR6_REG,
326   IMCR_REG,
327   CPUM_REG,
328 };
329
330 static enum mn103cpu_regs
331 decode_mn103cpu_addr (struct hw *me,
332                       struct mn103cpu *controller,
333                       unsigned_word base)
334 {
335   switch (base - controller->block.base)
336     {
337     case 0x000: return IVR0_REG;
338     case 0x004: return IVR1_REG;
339     case 0x008: return IVR2_REG;
340     case 0x00c: return IVR3_REG;
341     case 0x010: return IVR4_REG;
342     case 0x014: return IVR5_REG;
343     case 0x018: return IVR6_REG;
344     case 0x020: return IMCR_REG;
345     case 0x040: return CPUM_REG;
346     default: return INVALID_REG;
347     }
348 }
349
350 static unsigned
351 mn103cpu_io_read_buffer (struct hw *me,
352                          void *dest,
353                          int space,
354                          unsigned_word base,
355                          unsigned nr_bytes)
356 {
357   struct mn103cpu *controller = hw_data (me);
358   unsigned16 val = 0;
359   enum mn103cpu_regs reg = decode_mn103cpu_addr (me, controller, base);
360
361   switch (reg)
362     {
363     case IVR0_REG:
364     case IVR1_REG:
365     case IVR2_REG:
366     case IVR3_REG:
367     case IVR4_REG:
368     case IVR5_REG:
369     case IVR6_REG:
370       val = controller->interrupt_vector[reg - IVR0_REG];
371       break;
372     case IMCR_REG:
373       val = controller->internal_memory_control;
374       break;
375     case CPUM_REG:
376       val = controller->cpu_mode;
377       break;
378     default:
379       /* just ignore the read */
380       break;
381     }
382
383   if (nr_bytes == 2)
384     *(unsigned16*) dest = H2LE_2 (val);
385
386   return nr_bytes;
387 }     
388
389 static unsigned
390 mn103cpu_io_write_buffer (struct hw *me,
391                           const void *source,
392                           int space,
393                           unsigned_word base,
394                           unsigned nr_bytes)
395 {
396   struct mn103cpu *controller = hw_data (me);
397   unsigned16 val;
398   enum mn103cpu_regs reg;
399
400   if (nr_bytes != 2)
401     hw_abort (me, "must be two byte write");
402
403   reg = decode_mn103cpu_addr (me, controller, base);
404   val = LE2H_2 (* (unsigned16 *) source);
405
406   switch (reg)
407     {
408     case IVR0_REG:
409     case IVR1_REG:
410     case IVR2_REG:
411     case IVR3_REG:
412     case IVR4_REG:
413     case IVR5_REG:
414     case IVR6_REG:
415       controller->interrupt_vector[reg - IVR0_REG] = val;
416       HW_TRACE ((me, "ivr%d = 0x%04lx", reg - IVR0_REG, (long) val));
417       break;
418     default:
419       /* just ignore the write */
420       break;
421     }
422
423   return nr_bytes;
424 }     
425
426
427 const struct hw_descriptor dv_mn103cpu_descriptor[] = {
428   { "mn103cpu", mn103cpu_finish, },
429   { NULL },
430 };