Commit 20dcee9483361ee0621cf6d68d271ecde686fd9c

Authored by pbrook
1 parent 62ea5b0b

MCF5208 emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2924 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -467,7 +467,7 @@ ifeq ($(TARGET_BASE_ARCH), sh4)
467 467 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
468 468 endif
469 469 ifeq ($(TARGET_BASE_ARCH), m68k)
470   -VL_OBJS+= an5206.o mcf5206.o ptimer.o
  470 +VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o
471 471 VL_OBJS+= m68k-semi.o
472 472 endif
473 473 ifdef CONFIG_GDBSTUB
... ...
hw/an5206.c
... ... @@ -40,7 +40,9 @@ static void an5206_init(int ram_size, int vga_ram_size, int boot_device,
40 40 env = cpu_init();
41 41 if (!cpu_model)
42 42 cpu_model = "m5206";
43   - cpu_m68k_set_model(env, cpu_model);
  43 + if (cpu_m68k_set_model(env, cpu_model)) {
  44 + cpu_abort(env, "Unable to find m68k CPU definition\n");
  45 + }
44 46  
45 47 /* Initialize CPU registers. */
46 48 env->vbr = 0;
... ...
hw/mcf5206.c
... ... @@ -139,285 +139,12 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
139 139 return s;
140 140 }
141 141  
142   -/* UART */
143   -
144   -typedef struct {
145   - uint8_t mr[2];
146   - uint8_t sr;
147   - uint8_t isr;
148   - uint8_t imr;
149   - uint8_t bg1;
150   - uint8_t bg2;
151   - uint8_t fifo[4];
152   - uint8_t tb;
153   - int current_mr;
154   - int fifo_len;
155   - int tx_enabled;
156   - int rx_enabled;
157   - qemu_irq irq;
158   - CharDriverState *chr;
159   -} m5206_uart_state;
160   -
161   -/* UART Status Register bits. */
162   -#define M5206_UART_RxRDY 0x01
163   -#define M5206_UART_FFULL 0x02
164   -#define M5206_UART_TxRDY 0x04
165   -#define M5206_UART_TxEMP 0x08
166   -#define M5206_UART_OE 0x10
167   -#define M5206_UART_PE 0x20
168   -#define M5206_UART_FE 0x40
169   -#define M5206_UART_RB 0x80
170   -
171   -/* Interrupt flags. */
172   -#define M5206_UART_TxINT 0x01
173   -#define M5206_UART_RxINT 0x02
174   -#define M5206_UART_DBINT 0x04
175   -#define M5206_UART_COSINT 0x80
176   -
177   -/* UMR1 flags. */
178   -#define M5206_UART_BC0 0x01
179   -#define M5206_UART_BC1 0x02
180   -#define M5206_UART_PT 0x04
181   -#define M5206_UART_PM0 0x08
182   -#define M5206_UART_PM1 0x10
183   -#define M5206_UART_ERR 0x20
184   -#define M5206_UART_RxIRQ 0x40
185   -#define M5206_UART_RxRTS 0x80
186   -
187   -static void m5206_uart_update(m5206_uart_state *s)
188   -{
189   - s->isr &= ~(M5206_UART_TxINT | M5206_UART_RxINT);
190   - if (s->sr & M5206_UART_TxRDY)
191   - s->isr |= M5206_UART_TxINT;
192   - if ((s->sr & ((s->mr[0] & M5206_UART_RxIRQ)
193   - ? M5206_UART_FFULL : M5206_UART_RxRDY)) != 0)
194   - s->isr |= M5206_UART_RxINT;
195   -
196   - qemu_set_irq(s->irq, (s->isr & s->imr) != 0);
197   -}
198   -
199   -static uint32_t m5206_uart_read(m5206_uart_state *s, uint32_t addr)
200   -{
201   - switch (addr) {
202   - case 0x00:
203   - return s->mr[s->current_mr];
204   - case 0x04:
205   - return s->sr;
206   - case 0x0c:
207   - {
208   - uint8_t val;
209   - int i;
210   -
211   - if (s->fifo_len == 0)
212   - return 0;
213   -
214   - val = s->fifo[0];
215   - s->fifo_len--;
216   - for (i = 0; i < s->fifo_len; i++)
217   - s->fifo[i] = s->fifo[i + 1];
218   - s->sr &= ~M5206_UART_FFULL;
219   - if (s->fifo_len == 0)
220   - s->sr &= ~M5206_UART_RxRDY;
221   - m5206_uart_update(s);
222   - return val;
223   - }
224   - case 0x10:
225   - /* TODO: Implement IPCR. */
226   - return 0;
227   - case 0x14:
228   - return s->isr;
229   - case 0x18:
230   - return s->bg1;
231   - case 0x1c:
232   - return s->bg2;
233   - default:
234   - return 0;
235   - }
236   -}
237   -
238   -/* Update TxRDY flag and set data if present and enabled. */
239   -static void m5206_uart_do_tx(m5206_uart_state *s)
240   -{
241   - if (s->tx_enabled && (s->sr & M5206_UART_TxEMP) == 0) {
242   - if (s->chr)
243   - qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
244   - s->sr |= M5206_UART_TxEMP;
245   - }
246   - if (s->tx_enabled) {
247   - s->sr |= M5206_UART_TxRDY;
248   - } else {
249   - s->sr &= ~M5206_UART_TxRDY;
250   - }
251   -}
252   -
253   -static void m5206_do_command(m5206_uart_state *s, uint8_t cmd)
254   -{
255   - /* Misc command. */
256   - switch ((cmd >> 4) & 3) {
257   - case 0: /* No-op. */
258   - break;
259   - case 1: /* Reset mode register pointer. */
260   - s->current_mr = 0;
261   - break;
262   - case 2: /* Reset receiver. */
263   - s->rx_enabled = 0;
264   - s->fifo_len = 0;
265   - s->sr &= ~(M5206_UART_RxRDY | M5206_UART_FFULL);
266   - break;
267   - case 3: /* Reset transmitter. */
268   - s->tx_enabled = 0;
269   - s->sr |= M5206_UART_TxEMP;
270   - s->sr &= ~M5206_UART_TxRDY;
271   - break;
272   - case 4: /* Reset error status. */
273   - break;
274   - case 5: /* Reset break-change interrupt. */
275   - s->isr &= ~M5206_UART_DBINT;
276   - break;
277   - case 6: /* Start break. */
278   - case 7: /* Stop break. */
279   - break;
280   - }
281   -
282   - /* Transmitter command. */
283   - switch ((cmd >> 2) & 3) {
284   - case 0: /* No-op. */
285   - break;
286   - case 1: /* Enable. */
287   - s->tx_enabled = 1;
288   - m5206_uart_do_tx(s);
289   - break;
290   - case 2: /* Disable. */
291   - s->tx_enabled = 0;
292   - m5206_uart_do_tx(s);
293   - break;
294   - case 3: /* Reserved. */
295   - fprintf(stderr, "m5206_uart: Bad TX command\n");
296   - break;
297   - }
298   -
299   - /* Receiver command. */
300   - switch (cmd & 3) {
301   - case 0: /* No-op. */
302   - break;
303   - case 1: /* Enable. */
304   - s->rx_enabled = 1;
305   - break;
306   - case 2:
307   - s->rx_enabled = 0;
308   - break;
309   - case 3: /* Reserved. */
310   - fprintf(stderr, "m5206_uart: Bad RX command\n");
311   - break;
312   - }
313   -}
314   -
315   -static void m5206_uart_write(m5206_uart_state *s, uint32_t addr, uint32_t val)
316   -{
317   - switch (addr) {
318   - case 0x00:
319   - s->mr[s->current_mr] = val;
320   - s->current_mr = 1;
321   - break;
322   - case 0x04:
323   - /* CSR is ignored. */
324   - break;
325   - case 0x08: /* Command Register. */
326   - m5206_do_command(s, val);
327   - break;
328   - case 0x0c: /* Transmit Buffer. */
329   - s->sr &= ~M5206_UART_TxEMP;
330   - s->tb = val;
331   - m5206_uart_do_tx(s);
332   - break;
333   - case 0x10:
334   - /* ACR is ignored. */
335   - break;
336   - case 0x14:
337   - s->imr = val;
338   - break;
339   - default:
340   - break;
341   - }
342   - m5206_uart_update(s);
343   -}
344   -
345   -static void m5206_uart_reset(m5206_uart_state *s)
346   -{
347   - s->fifo_len = 0;
348   - s->mr[0] = 0;
349   - s->mr[1] = 0;
350   - s->sr = M5206_UART_TxEMP;
351   - s->tx_enabled = 0;
352   - s->rx_enabled = 0;
353   - s->isr = 0;
354   - s->imr = 0;
355   -}
356   -
357   -static void m5206_uart_push_byte(m5206_uart_state *s, uint8_t data)
358   -{
359   - /* Break events overwrite the last byte if the fifo is full. */
360   - if (s->fifo_len == 4)
361   - s->fifo_len--;
362   -
363   - s->fifo[s->fifo_len] = data;
364   - s->fifo_len++;
365   - s->sr |= M5206_UART_RxRDY;
366   - if (s->fifo_len == 4)
367   - s->sr |= M5206_UART_FFULL;
368   -
369   - m5206_uart_update(s);
370   -}
371   -
372   -static void m5206_uart_event(void *opaque, int event)
373   -{
374   - m5206_uart_state *s = (m5206_uart_state *)opaque;
375   -
376   - switch (event) {
377   - case CHR_EVENT_BREAK:
378   - s->isr |= M5206_UART_DBINT;
379   - m5206_uart_push_byte(s, 0);
380   - break;
381   - default:
382   - break;
383   - }
384   -}
385   -
386   -static int m5206_uart_can_receive(void *opaque)
387   -{
388   - m5206_uart_state *s = (m5206_uart_state *)opaque;
389   -
390   - return s->rx_enabled && (s->sr & M5206_UART_FFULL) == 0;
391   -}
392   -
393   -static void m5206_uart_receive(void *opaque, const uint8_t *buf, int size)
394   -{
395   - m5206_uart_state *s = (m5206_uart_state *)opaque;
396   -
397   - m5206_uart_push_byte(s, buf[0]);
398   -}
399   -
400   -static m5206_uart_state *m5206_uart_init(qemu_irq irq, CharDriverState *chr)
401   -{
402   - m5206_uart_state *s;
403   -
404   - s = qemu_mallocz(sizeof(m5206_uart_state));
405   - s->chr = chr;
406   - s->irq = irq;
407   - if (chr) {
408   - qemu_chr_add_handlers(chr, m5206_uart_can_receive, m5206_uart_receive,
409   - m5206_uart_event, s);
410   - }
411   - m5206_uart_reset(s);
412   - return s;
413   -}
414   -
415 142 /* System Integration Module. */
416 143  
417 144 typedef struct {
418 145 CPUState *env;
419 146 m5206_timer_state *timer[2];
420   - m5206_uart_state *uart[2];
  147 + void *uart[2];
421 148 uint8_t scr;
422 149 uint8_t icr[14];
423 150 uint16_t imr; /* 1 == interrupt is masked. */
... ... @@ -540,9 +267,9 @@ static uint32_t m5206_mbar_read(m5206_mbar_state *s, uint32_t offset)
540 267 } else if (offset >= 0x120 && offset < 0x140) {
541 268 return m5206_timer_read(s->timer[1], offset - 0x120);
542 269 } else if (offset >= 0x140 && offset < 0x160) {
543   - return m5206_uart_read(s->uart[0], offset - 0x140);
  270 + return mcf_uart_read(s->uart[0], offset - 0x140);
544 271 } else if (offset >= 0x180 && offset < 0x1a0) {
545   - return m5206_uart_read(s->uart[1], offset - 0x180);
  272 + return mcf_uart_read(s->uart[1], offset - 0x180);
546 273 }
547 274 switch (offset) {
548 275 case 0x03: return s->scr;
... ... @@ -580,10 +307,10 @@ static void m5206_mbar_write(m5206_mbar_state *s, uint32_t offset,
580 307 m5206_timer_write(s->timer[1], offset - 0x120, value);
581 308 return;
582 309 } else if (offset >= 0x140 && offset < 0x160) {
583   - m5206_uart_write(s->uart[0], offset - 0x140, value);
  310 + mcf_uart_write(s->uart[0], offset - 0x140, value);
584 311 return;
585 312 } else if (offset >= 0x180 && offset < 0x1a0) {
586   - m5206_uart_write(s->uart[1], offset - 0x180, value);
  313 + mcf_uart_write(s->uart[1], offset - 0x180, value);
587 314 return;
588 315 }
589 316 switch (offset) {
... ... @@ -798,13 +525,13 @@ qemu_irq *mcf5206_init(uint32_t base, CPUState *env)
798 525 s = (m5206_mbar_state *)qemu_mallocz(sizeof(m5206_mbar_state));
799 526 iomemtype = cpu_register_io_memory(0, m5206_mbar_readfn,
800 527 m5206_mbar_writefn, s);
801   - cpu_register_physical_memory(base, 0x00000fff, iomemtype);
  528 + cpu_register_physical_memory(base, 0x00001000, iomemtype);
802 529  
803 530 pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
804 531 s->timer[0] = m5206_timer_init(pic[9]);
805 532 s->timer[1] = m5206_timer_init(pic[10]);
806   - s->uart[0] = m5206_uart_init(pic[12], serial_hds[0]);
807   - s->uart[1] = m5206_uart_init(pic[13], serial_hds[1]);
  533 + s->uart[0] = mcf_uart_init(pic[12], serial_hds[0]);
  534 + s->uart[1] = mcf_uart_init(pic[13], serial_hds[1]);
808 535 s->env = env;
809 536  
810 537 m5206_mbar_reset(s);
... ...
hw/mcf5208.c 0 โ†’ 100644
  1 +/*
  2 + * Motorola ColdFire MCF5208 SoC emulation.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + *
  6 + * This code is licenced under the GPL
  7 + */
  8 +#include "vl.h"
  9 +
  10 +#define SYS_FREQ 66000000
  11 +
  12 +#define PCSR_EN 0x0001
  13 +#define PCSR_RLD 0x0002
  14 +#define PCSR_PIF 0x0004
  15 +#define PCSR_PIE 0x0008
  16 +#define PCSR_OVW 0x0010
  17 +#define PCSR_DBG 0x0020
  18 +#define PCSR_DOZE 0x0040
  19 +#define PCSR_PRE_SHIFT 8
  20 +#define PCSR_PRE_MASK 0x0f00
  21 +
  22 +typedef struct {
  23 + qemu_irq irq;
  24 + ptimer_state *timer;
  25 + uint16_t pcsr;
  26 + uint16_t pmr;
  27 + uint16_t pcntr;
  28 +} m5208_timer_state;
  29 +
  30 +static void m5208_timer_update(m5208_timer_state *s)
  31 +{
  32 + if ((s->pcsr & (PCSR_PIE | PCSR_PIF)) == (PCSR_PIE | PCSR_PIF))
  33 + qemu_irq_raise(s->irq);
  34 + else
  35 + qemu_irq_lower(s->irq);
  36 +}
  37 +
  38 +static void m5208_timer_write(m5208_timer_state *s, int offset,
  39 + uint32_t value)
  40 +{
  41 + int prescale;
  42 + int limit;
  43 + switch (offset) {
  44 + case 0:
  45 + /* The PIF bit is set-to-clear. */
  46 + if (value & PCSR_PIF) {
  47 + s->pcsr &= ~PCSR_PIF;
  48 + value &= ~PCSR_PIF;
  49 + }
  50 + /* Avoid frobbing the timer if we're just twiddling IRQ bits. */
  51 + if (((s->pcsr ^ value) & ~PCSR_PIE) == 0) {
  52 + s->pcsr = value;
  53 + m5208_timer_update(s);
  54 + return;
  55 + }
  56 +
  57 + if (s->pcsr & PCSR_EN)
  58 + ptimer_stop(s->timer);
  59 +
  60 + s->pcsr = value;
  61 +
  62 + prescale = 1 << ((s->pcsr & PCSR_PRE_MASK) >> PCSR_PRE_SHIFT);
  63 + ptimer_set_freq(s->timer, (SYS_FREQ / 2) / prescale);
  64 + if (s->pcsr & PCSR_RLD)
  65 + limit = 0xffff;
  66 + else
  67 + limit = s->pmr;
  68 + ptimer_set_limit(s->timer, limit, 0);
  69 +
  70 + if (s->pcsr & PCSR_EN)
  71 + ptimer_run(s->timer, 0);
  72 + break;
  73 + case 2:
  74 + s->pmr = value;
  75 + s->pcsr &= ~PCSR_PIF;
  76 + if (s->pcsr & PCSR_RLD)
  77 + value = 0xffff;
  78 + ptimer_set_limit(s->timer, value, s->pcsr & PCSR_OVW);
  79 + break;
  80 + case 4:
  81 + break;
  82 + default:
  83 + /* Should never happen. */
  84 + abort();
  85 + }
  86 + m5208_timer_update(s);
  87 +}
  88 +
  89 +static void m5208_timer_trigger(void *opaque)
  90 +{
  91 + m5208_timer_state *s = (m5208_timer_state *)opaque;
  92 + s->pcsr |= PCSR_PIF;
  93 + m5208_timer_update(s);
  94 +}
  95 +
  96 +typedef struct {
  97 + m5208_timer_state timer[2];
  98 +} m5208_sys_state;
  99 +
  100 +static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
  101 +{
  102 + m5208_sys_state *s = (m5208_sys_state *)opaque;
  103 + switch (addr) {
  104 + /* PIT0 */
  105 + case 0xfc080000:
  106 + return s->timer[0].pcsr;
  107 + case 0xfc080002:
  108 + return s->timer[0].pmr;
  109 + case 0xfc080004:
  110 + return ptimer_get_count(s->timer[0].timer);
  111 + /* PIT1 */
  112 + case 0xfc084000:
  113 + return s->timer[1].pcsr;
  114 + case 0xfc084002:
  115 + return s->timer[1].pmr;
  116 + case 0xfc084004:
  117 + return ptimer_get_count(s->timer[1].timer);
  118 +
  119 + /* SDRAM Controller. */
  120 + case 0xfc0a8110: /* SDCS0 */
  121 + {
  122 + int n;
  123 + for (n = 0; n < 32; n++) {
  124 + if (ram_size < (2u << n))
  125 + break;
  126 + }
  127 + return (n - 1) | 0x40000000;
  128 + }
  129 + case 0xfc0a8114: /* SDCS1 */
  130 + return 0;
  131 +
  132 + default:
  133 + cpu_abort(cpu_single_env, "m5208_sys_read: Bad offset 0x%x\n",
  134 + (int)addr);
  135 + return 0;
  136 + }
  137 +}
  138 +
  139 +static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
  140 + uint32_t value)
  141 +{
  142 + m5208_sys_state *s = (m5208_sys_state *)opaque;
  143 + switch (addr) {
  144 + /* PIT0 */
  145 + case 0xfc080000:
  146 + case 0xfc080002:
  147 + case 0xfc080004:
  148 + m5208_timer_write(&s->timer[0], addr & 0xf, value);
  149 + return;
  150 + /* PIT1 */
  151 + case 0xfc084000:
  152 + case 0xfc084002:
  153 + case 0xfc084004:
  154 + m5208_timer_write(&s->timer[1], addr & 0xf, value);
  155 + return;
  156 + default:
  157 + cpu_abort(cpu_single_env, "m5208_sys_write: Bad offset 0x%x\n",
  158 + (int)addr);
  159 + break;
  160 + }
  161 +}
  162 +
  163 +static CPUReadMemoryFunc *m5208_sys_readfn[] = {
  164 + m5208_sys_read,
  165 + m5208_sys_read,
  166 + m5208_sys_read
  167 +};
  168 +
  169 +static CPUWriteMemoryFunc *m5208_sys_writefn[] = {
  170 + m5208_sys_write,
  171 + m5208_sys_write,
  172 + m5208_sys_write
  173 +};
  174 +
  175 +static void mcf5208_sys_init(qemu_irq *pic)
  176 +{
  177 + int iomemtype;
  178 + m5208_sys_state *s;
  179 + QEMUBH *bh;
  180 + int i;
  181 +
  182 + s = (m5208_sys_state *)qemu_mallocz(sizeof(m5208_sys_state));
  183 + iomemtype = cpu_register_io_memory(0, m5208_sys_readfn,
  184 + m5208_sys_writefn, s);
  185 + /* SDRAMC. */
  186 + cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
  187 + /* Timers. */
  188 + for (i = 0; i < 2; i++) {
  189 + bh = qemu_bh_new(m5208_timer_trigger, &s->timer[i]);
  190 + s->timer[i].timer = ptimer_init(bh);
  191 + cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
  192 + iomemtype);
  193 + s->timer[i].irq = pic[4 + i];
  194 + }
  195 +}
  196 +
  197 +static void mcf5208evb_init(int ram_size, int vga_ram_size, int boot_device,
  198 + DisplayState *ds, const char **fd_filename, int snapshot,
  199 + const char *kernel_filename, const char *kernel_cmdline,
  200 + const char *initrd_filename, const char *cpu_model)
  201 +{
  202 + CPUState *env;
  203 + int kernel_size;
  204 + uint64_t elf_entry;
  205 + target_ulong entry;
  206 + qemu_irq *pic;
  207 +
  208 + env = cpu_init();
  209 + if (!cpu_model)
  210 + cpu_model = "m5208";
  211 + if (cpu_m68k_set_model(env, cpu_model)) {
  212 + cpu_abort(env, "Unable to find m68k CPU definition\n");
  213 + }
  214 +
  215 + /* Initialize CPU registers. */
  216 + env->vbr = 0;
  217 + /* TODO: Configure BARs. */
  218 +
  219 + /* DRAM at 0x20000000 */
  220 + cpu_register_physical_memory(0x40000000, ram_size,
  221 + qemu_ram_alloc(ram_size) | IO_MEM_RAM);
  222 +
  223 + /* Internal SRAM. */
  224 + cpu_register_physical_memory(0x80000000, 16384,
  225 + qemu_ram_alloc(16384) | IO_MEM_RAM);
  226 +
  227 + /* Internal peripherals. */
  228 + pic = mcf_intc_init(0xfc048000, env);
  229 +
  230 + mcf_uart_mm_init(0xfc060000, pic[26], serial_hds[0]);
  231 + mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
  232 + mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
  233 +
  234 + mcf5208_sys_init(pic);
  235 +
  236 + /* 0xfc000000 SCM. */
  237 + /* 0xfc004000 XBS. */
  238 + /* 0xfc008000 FlexBus CS. */
  239 + /* 0xfc030000 FEC. */
  240 + /* 0xfc040000 SCM + Power management. */
  241 + /* 0xfc044000 eDMA. */
  242 + /* 0xfc048000 INTC. */
  243 + /* 0xfc058000 I2C. */
  244 + /* 0xfc05c000 QSPI. */
  245 + /* 0xfc060000 UART0. */
  246 + /* 0xfc064000 UART0. */
  247 + /* 0xfc068000 UART0. */
  248 + /* 0xfc070000 DMA timers. */
  249 + /* 0xfc080000 PIT0. */
  250 + /* 0xfc084000 PIT1. */
  251 + /* 0xfc088000 EPORT. */
  252 + /* 0xfc08c000 Watchdog. */
  253 + /* 0xfc090000 clock module. */
  254 + /* 0xfc0a0000 CCM + reset. */
  255 + /* 0xfc0a4000 GPIO. */
  256 + /* 0xfc0a8000 SDRAM controller. */
  257 +
  258 + /* Load kernel. */
  259 + if (!kernel_filename) {
  260 + fprintf(stderr, "Kernel image must be specified\n");
  261 + exit(1);
  262 + }
  263 +
  264 + kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
  265 + entry = elf_entry;
  266 + if (kernel_size < 0) {
  267 + kernel_size = load_uboot(kernel_filename, &entry, NULL);
  268 + }
  269 + if (kernel_size < 0) {
  270 + kernel_size = load_image(kernel_filename, phys_ram_base);
  271 + entry = 0x20000000;
  272 + }
  273 + if (kernel_size < 0) {
  274 + fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
  275 + exit(1);
  276 + }
  277 +
  278 + env->pc = entry;
  279 +}
  280 +
  281 +QEMUMachine mcf5208evb_machine = {
  282 + "mcf5208evb",
  283 + "MCF5206EVB",
  284 + mcf5208evb_init,
  285 +};
... ...
hw/mcf_intc.c 0 โ†’ 100644
  1 +/*
  2 + * ColdFire Interrupt Controller emulation.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + *
  6 + * This code is licenced under the GPL
  7 + */
  8 +#include "vl.h"
  9 +
  10 +typedef struct {
  11 + uint64_t ipr;
  12 + uint64_t imr;
  13 + uint64_t ifr;
  14 + uint64_t enabled;
  15 + uint8_t icr[64];
  16 + CPUState *env;
  17 + int active_vector;
  18 +} mcf_intc_state;
  19 +
  20 +static void mcf_intc_update(mcf_intc_state *s)
  21 +{
  22 + uint64_t active;
  23 + int i;
  24 + int best;
  25 + int best_level;
  26 +
  27 + active = (s->ipr | s->ifr) & s->enabled & ~s->imr;
  28 + best_level = 0;
  29 + best = 64;
  30 + if (active) {
  31 + for (i = 0; i < 64; i++) {
  32 + if ((active & 1) != 0 && s->icr[i] >= best_level) {
  33 + best_level = s->icr[i];
  34 + best = i;
  35 + }
  36 + active >>= 1;
  37 + }
  38 + }
  39 + s->active_vector = ((best == 64) ? 24 : (best + 64));
  40 + m68k_set_irq_level(s->env, best_level, s->active_vector);
  41 +}
  42 +
  43 +static uint32_t mcf_intc_read(void *opaque, target_phys_addr_t addr)
  44 +{
  45 + int offset;
  46 + mcf_intc_state *s = (mcf_intc_state *)opaque;
  47 + offset = addr & 0xff;
  48 + if (offset >= 0x40 && offset < 0x80) {
  49 + return s->icr[offset - 0x40];
  50 + }
  51 + switch (offset) {
  52 + case 0x00:
  53 + return (uint32_t)(s->ipr >> 32);
  54 + case 0x04:
  55 + return (uint32_t)s->ipr;
  56 + case 0x08:
  57 + return (uint32_t)(s->imr >> 32);
  58 + case 0x0c:
  59 + return (uint32_t)s->imr;
  60 + case 0x10:
  61 + return (uint32_t)(s->ifr >> 32);
  62 + case 0x14:
  63 + return (uint32_t)s->ifr;
  64 + case 0xe0: /* SWIACK. */
  65 + return s->active_vector;
  66 + case 0xe1: case 0xe2: case 0xe3: case 0xe4:
  67 + case 0xe5: case 0xe6: case 0xe7:
  68 + /* LnIACK */
  69 + cpu_abort(cpu_single_env, "mcf_intc_read: LnIACK not implemented\n");
  70 + default:
  71 + return 0;
  72 + }
  73 +}
  74 +
  75 +static void mcf_intc_write(void *opaque, target_phys_addr_t addr, uint32_t val)
  76 +{
  77 + int offset;
  78 + mcf_intc_state *s = (mcf_intc_state *)opaque;
  79 + offset = addr & 0xff;
  80 + if (offset >= 0x40 && offset < 0x80) {
  81 + int n = offset - 0x40;
  82 + s->icr[n] = val;
  83 + if (val == 0)
  84 + s->enabled &= ~(1ull << n);
  85 + else
  86 + s->enabled |= (1ull << n);
  87 + mcf_intc_update(s);
  88 + return;
  89 + }
  90 + switch (offset) {
  91 + case 0x00: case 0x04:
  92 + /* Ignore IPR writes. */
  93 + return;
  94 + case 0x08:
  95 + s->imr = (s->imr & 0xffffffff) | ((uint64_t)val << 32);
  96 + break;
  97 + case 0x0c:
  98 + s->imr = (s->imr & 0xffffffff00000000ull) | (uint32_t)val;
  99 + break;
  100 + default:
  101 + cpu_abort(cpu_single_env, "mcf_intc_write: Bad write offset %d\n",
  102 + offset);
  103 + break;
  104 + }
  105 + mcf_intc_update(s);
  106 +}
  107 +
  108 +static void mcf_intc_set_irq(void *opaque, int irq, int level)
  109 +{
  110 + mcf_intc_state *s = (mcf_intc_state *)opaque;
  111 + if (irq >= 64)
  112 + return;
  113 + if (level)
  114 + s->ipr |= 1ull << irq;
  115 + else
  116 + s->ipr &= ~(1ull << irq);
  117 + mcf_intc_update(s);
  118 +}
  119 +
  120 +static void mcf_intc_reset(mcf_intc_state *s)
  121 +{
  122 + s->imr = ~0ull;
  123 + s->ipr = 0;
  124 + s->ifr = 0;
  125 + s->enabled = 0;
  126 + memset(s->icr, 0, 64);
  127 + s->active_vector = 24;
  128 +}
  129 +
  130 +static CPUReadMemoryFunc *mcf_intc_readfn[] = {
  131 + mcf_intc_read,
  132 + mcf_intc_read,
  133 + mcf_intc_read
  134 +};
  135 +
  136 +static CPUWriteMemoryFunc *mcf_intc_writefn[] = {
  137 + mcf_intc_write,
  138 + mcf_intc_write,
  139 + mcf_intc_write
  140 +};
  141 +
  142 +qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env)
  143 +{
  144 + mcf_intc_state *s;
  145 + int iomemtype;
  146 +
  147 + s = qemu_mallocz(sizeof(mcf_intc_state));
  148 + s->env = env;
  149 + mcf_intc_reset(s);
  150 +
  151 + iomemtype = cpu_register_io_memory(0, mcf_intc_readfn,
  152 + mcf_intc_writefn, s);
  153 + cpu_register_physical_memory(base, 0x100, iomemtype);
  154 +
  155 + return qemu_allocate_irqs(mcf_intc_set_irq, s, 64);
  156 +}
... ...
hw/mcf_uart.c 0 โ†’ 100644
  1 +/*
  2 + * ColdFire UART emulation.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + *
  6 + * This code is licenced under the GPL
  7 + */
  8 +#include "vl.h"
  9 +
  10 +typedef struct {
  11 + uint8_t mr[2];
  12 + uint8_t sr;
  13 + uint8_t isr;
  14 + uint8_t imr;
  15 + uint8_t bg1;
  16 + uint8_t bg2;
  17 + uint8_t fifo[4];
  18 + uint8_t tb;
  19 + int current_mr;
  20 + int fifo_len;
  21 + int tx_enabled;
  22 + int rx_enabled;
  23 + qemu_irq irq;
  24 + CharDriverState *chr;
  25 +} mcf_uart_state;
  26 +
  27 +/* UART Status Register bits. */
  28 +#define MCF_UART_RxRDY 0x01
  29 +#define MCF_UART_FFULL 0x02
  30 +#define MCF_UART_TxRDY 0x04
  31 +#define MCF_UART_TxEMP 0x08
  32 +#define MCF_UART_OE 0x10
  33 +#define MCF_UART_PE 0x20
  34 +#define MCF_UART_FE 0x40
  35 +#define MCF_UART_RB 0x80
  36 +
  37 +/* Interrupt flags. */
  38 +#define MCF_UART_TxINT 0x01
  39 +#define MCF_UART_RxINT 0x02
  40 +#define MCF_UART_DBINT 0x04
  41 +#define MCF_UART_COSINT 0x80
  42 +
  43 +/* UMR1 flags. */
  44 +#define MCF_UART_BC0 0x01
  45 +#define MCF_UART_BC1 0x02
  46 +#define MCF_UART_PT 0x04
  47 +#define MCF_UART_PM0 0x08
  48 +#define MCF_UART_PM1 0x10
  49 +#define MCF_UART_ERR 0x20
  50 +#define MCF_UART_RxIRQ 0x40
  51 +#define MCF_UART_RxRTS 0x80
  52 +
  53 +static void mcf_uart_update(mcf_uart_state *s)
  54 +{
  55 + s->isr &= ~(MCF_UART_TxINT | MCF_UART_RxINT);
  56 + if (s->sr & MCF_UART_TxRDY)
  57 + s->isr |= MCF_UART_TxINT;
  58 + if ((s->sr & ((s->mr[0] & MCF_UART_RxIRQ)
  59 + ? MCF_UART_FFULL : MCF_UART_RxRDY)) != 0)
  60 + s->isr |= MCF_UART_RxINT;
  61 +
  62 + qemu_set_irq(s->irq, (s->isr & s->imr) != 0);
  63 +}
  64 +
  65 +uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr)
  66 +{
  67 + mcf_uart_state *s = (mcf_uart_state *)opaque;
  68 + switch (addr & 0x3f) {
  69 + case 0x00:
  70 + return s->mr[s->current_mr];
  71 + case 0x04:
  72 + return s->sr;
  73 + case 0x0c:
  74 + {
  75 + uint8_t val;
  76 + int i;
  77 +
  78 + if (s->fifo_len == 0)
  79 + return 0;
  80 +
  81 + val = s->fifo[0];
  82 + s->fifo_len--;
  83 + for (i = 0; i < s->fifo_len; i++)
  84 + s->fifo[i] = s->fifo[i + 1];
  85 + s->sr &= ~MCF_UART_FFULL;
  86 + if (s->fifo_len == 0)
  87 + s->sr &= ~MCF_UART_RxRDY;
  88 + mcf_uart_update(s);
  89 + return val;
  90 + }
  91 + case 0x10:
  92 + /* TODO: Implement IPCR. */
  93 + return 0;
  94 + case 0x14:
  95 + return s->isr;
  96 + case 0x18:
  97 + return s->bg1;
  98 + case 0x1c:
  99 + return s->bg2;
  100 + default:
  101 + return 0;
  102 + }
  103 +}
  104 +
  105 +/* Update TxRDY flag and set data if present and enabled. */
  106 +static void mcf_uart_do_tx(mcf_uart_state *s)
  107 +{
  108 + if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) {
  109 + if (s->chr)
  110 + qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
  111 + s->sr |= MCF_UART_TxEMP;
  112 + }
  113 + if (s->tx_enabled) {
  114 + s->sr |= MCF_UART_TxRDY;
  115 + } else {
  116 + s->sr &= ~MCF_UART_TxRDY;
  117 + }
  118 +}
  119 +
  120 +static void mcf_do_command(mcf_uart_state *s, uint8_t cmd)
  121 +{
  122 + /* Misc command. */
  123 + switch ((cmd >> 4) & 3) {
  124 + case 0: /* No-op. */
  125 + break;
  126 + case 1: /* Reset mode register pointer. */
  127 + s->current_mr = 0;
  128 + break;
  129 + case 2: /* Reset receiver. */
  130 + s->rx_enabled = 0;
  131 + s->fifo_len = 0;
  132 + s->sr &= ~(MCF_UART_RxRDY | MCF_UART_FFULL);
  133 + break;
  134 + case 3: /* Reset transmitter. */
  135 + s->tx_enabled = 0;
  136 + s->sr |= MCF_UART_TxEMP;
  137 + s->sr &= ~MCF_UART_TxRDY;
  138 + break;
  139 + case 4: /* Reset error status. */
  140 + break;
  141 + case 5: /* Reset break-change interrupt. */
  142 + s->isr &= ~MCF_UART_DBINT;
  143 + break;
  144 + case 6: /* Start break. */
  145 + case 7: /* Stop break. */
  146 + break;
  147 + }
  148 +
  149 + /* Transmitter command. */
  150 + switch ((cmd >> 2) & 3) {
  151 + case 0: /* No-op. */
  152 + break;
  153 + case 1: /* Enable. */
  154 + s->tx_enabled = 1;
  155 + mcf_uart_do_tx(s);
  156 + break;
  157 + case 2: /* Disable. */
  158 + s->tx_enabled = 0;
  159 + mcf_uart_do_tx(s);
  160 + break;
  161 + case 3: /* Reserved. */
  162 + fprintf(stderr, "mcf_uart: Bad TX command\n");
  163 + break;
  164 + }
  165 +
  166 + /* Receiver command. */
  167 + switch (cmd & 3) {
  168 + case 0: /* No-op. */
  169 + break;
  170 + case 1: /* Enable. */
  171 + s->rx_enabled = 1;
  172 + break;
  173 + case 2:
  174 + s->rx_enabled = 0;
  175 + break;
  176 + case 3: /* Reserved. */
  177 + fprintf(stderr, "mcf_uart: Bad RX command\n");
  178 + break;
  179 + }
  180 +}
  181 +
  182 +void mcf_uart_write(void *opaque, target_phys_addr_t addr, uint32_t val)
  183 +{
  184 + mcf_uart_state *s = (mcf_uart_state *)opaque;
  185 + switch (addr & 0x3f) {
  186 + case 0x00:
  187 + s->mr[s->current_mr] = val;
  188 + s->current_mr = 1;
  189 + break;
  190 + case 0x04:
  191 + /* CSR is ignored. */
  192 + break;
  193 + case 0x08: /* Command Register. */
  194 + mcf_do_command(s, val);
  195 + break;
  196 + case 0x0c: /* Transmit Buffer. */
  197 + s->sr &= ~MCF_UART_TxEMP;
  198 + s->tb = val;
  199 + mcf_uart_do_tx(s);
  200 + break;
  201 + case 0x10:
  202 + /* ACR is ignored. */
  203 + break;
  204 + case 0x14:
  205 + s->imr = val;
  206 + break;
  207 + default:
  208 + break;
  209 + }
  210 + mcf_uart_update(s);
  211 +}
  212 +
  213 +static void mcf_uart_reset(mcf_uart_state *s)
  214 +{
  215 + s->fifo_len = 0;
  216 + s->mr[0] = 0;
  217 + s->mr[1] = 0;
  218 + s->sr = MCF_UART_TxEMP;
  219 + s->tx_enabled = 0;
  220 + s->rx_enabled = 0;
  221 + s->isr = 0;
  222 + s->imr = 0;
  223 +}
  224 +
  225 +static void mcf_uart_push_byte(mcf_uart_state *s, uint8_t data)
  226 +{
  227 + /* Break events overwrite the last byte if the fifo is full. */
  228 + if (s->fifo_len == 4)
  229 + s->fifo_len--;
  230 +
  231 + s->fifo[s->fifo_len] = data;
  232 + s->fifo_len++;
  233 + s->sr |= MCF_UART_RxRDY;
  234 + if (s->fifo_len == 4)
  235 + s->sr |= MCF_UART_FFULL;
  236 +
  237 + mcf_uart_update(s);
  238 +}
  239 +
  240 +static void mcf_uart_event(void *opaque, int event)
  241 +{
  242 + mcf_uart_state *s = (mcf_uart_state *)opaque;
  243 +
  244 + switch (event) {
  245 + case CHR_EVENT_BREAK:
  246 + s->isr |= MCF_UART_DBINT;
  247 + mcf_uart_push_byte(s, 0);
  248 + break;
  249 + default:
  250 + break;
  251 + }
  252 +}
  253 +
  254 +static int mcf_uart_can_receive(void *opaque)
  255 +{
  256 + mcf_uart_state *s = (mcf_uart_state *)opaque;
  257 +
  258 + return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0;
  259 +}
  260 +
  261 +static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
  262 +{
  263 + mcf_uart_state *s = (mcf_uart_state *)opaque;
  264 +
  265 + mcf_uart_push_byte(s, buf[0]);
  266 +}
  267 +
  268 +void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
  269 +{
  270 + mcf_uart_state *s;
  271 +
  272 + s = qemu_mallocz(sizeof(mcf_uart_state));
  273 + s->chr = chr;
  274 + s->irq = irq;
  275 + if (chr) {
  276 + qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
  277 + mcf_uart_event, s);
  278 + }
  279 + mcf_uart_reset(s);
  280 + return s;
  281 +}
  282 +
  283 +
  284 +static CPUReadMemoryFunc *mcf_uart_readfn[] = {
  285 + mcf_uart_read,
  286 + mcf_uart_read,
  287 + mcf_uart_read
  288 +};
  289 +
  290 +static CPUWriteMemoryFunc *mcf_uart_writefn[] = {
  291 + mcf_uart_write,
  292 + mcf_uart_write,
  293 + mcf_uart_write
  294 +};
  295 +
  296 +void mcf_uart_mm_init(target_phys_addr_t base, qemu_irq irq,
  297 + CharDriverState *chr)
  298 +{
  299 + mcf_uart_state *s;
  300 + int iomemtype;
  301 +
  302 + s = mcf_uart_init(irq, chr);
  303 + iomemtype = cpu_register_io_memory(0, mcf_uart_readfn,
  304 + mcf_uart_writefn, s);
  305 + cpu_register_physical_memory(base, 0x40, iomemtype);
  306 +}
... ...
target-m68k/cpu.h
... ... @@ -59,6 +59,10 @@ typedef struct CPUM68KState {
59 59 uint32_t pc;
60 60 uint32_t sr;
61 61  
  62 + /* SSP and USP. The current_sp is stored in aregs[7], the other here. */
  63 + int current_sp;
  64 + uint32_t sp[2];
  65 +
62 66 /* Condition flags. */
63 67 uint32_t cc_op;
64 68 uint32_t cc_dest;
... ... @@ -92,6 +96,7 @@ typedef struct CPUM68KState {
92 96 uint32_t vbr;
93 97 uint32_t mbar;
94 98 uint32_t rambar0;
  99 + uint32_t cacr;
95 100  
96 101 uint32_t features;
97 102  
... ... @@ -151,6 +156,12 @@ enum {
151 156 #define SR_S 0x2000
152 157 #define SR_T 0x8000
153 158  
  159 +#define M68K_SSP 0
  160 +#define M68K_USP 1
  161 +
  162 +/* CACR fields are implementation defined, but some bits are common. */
  163 +#define M68K_CACR_EUSP 0x10
  164 +
154 165 #define MACSR_PAV0 0x100
155 166 #define MACSR_OMC 0x080
156 167 #define MACSR_SU 0x040
... ... @@ -167,6 +178,7 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name);
167 178  
168 179 void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector);
169 180 void m68k_set_macsr(CPUM68KState *env, uint32_t val);
  181 +void m68k_switch_sp(CPUM68KState *env);
170 182  
171 183 #define M68K_FPCR_PREC (1 << 6)
172 184  
... ... @@ -179,6 +191,7 @@ enum m68k_features {
179 191 M68K_FEATURE_CF_FPU,
180 192 M68K_FEATURE_CF_MAC,
181 193 M68K_FEATURE_CF_EMAC,
  194 + M68K_FEATURE_USP,
182 195 M68K_FEATURE_EXT_FULL, /* 68020+ full extension word. */
183 196 M68K_FEATURE_WORD_INDEX /* word sized address index registers. */
184 197 };
... ...
target-m68k/helper.c
... ... @@ -28,6 +28,7 @@
28 28  
29 29 enum m68k_cpuid {
30 30 M68K_CPUID_M5206,
  31 + M68K_CPUID_M5208,
31 32 M68K_CPUID_CFV4E,
32 33 M68K_CPUID_ANY,
33 34 };
... ... @@ -39,6 +40,7 @@ struct m68k_def_t {
39 40  
40 41 static m68k_def_t m68k_cpu_defs[] = {
41 42 {"m5206", M68K_CPUID_M5206},
  43 + {"m5208", M68K_CPUID_M5208},
42 44 {"cfv4e", M68K_CPUID_CFV4E},
43 45 {"any", M68K_CPUID_ANY},
44 46 {NULL, 0},
... ... @@ -64,12 +66,18 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
64 66 case M68K_CPUID_M5206:
65 67 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
66 68 break;
  69 + case M68K_CPUID_M5208:
  70 + m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
  71 + m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
  72 + m68k_set_feature(env, M68K_FEATURE_USP);
  73 + break;
67 74 case M68K_CPUID_CFV4E:
68 75 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
69 76 m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
70 77 m68k_set_feature(env, M68K_FEATURE_CF_ISA_C);
71 78 m68k_set_feature(env, M68K_FEATURE_CF_FPU);
72 79 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
  80 + m68k_set_feature(env, M68K_FEATURE_USP);
73 81 break;
74 82 case M68K_CPUID_ANY:
75 83 m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
... ... @@ -79,6 +87,7 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
79 87 /* MAC and EMAC are mututally exclusive, so pick EMAC.
80 88 It's mostly backwards compatible. */
81 89 m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
  90 + m68k_set_feature(env, M68K_FEATURE_USP);
82 91 m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
83 92 break;
84 93 }
... ... @@ -215,7 +224,11 @@ void helper_movec(CPUM68KState *env, int reg, uint32_t val)
215 224 {
216 225 switch (reg) {
217 226 case 0x02: /* CACR */
218   - /* Ignored. */
  227 + env->cacr = val;
  228 + m68k_switch_sp(env);
  229 + break;
  230 + case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
  231 + /* TODO: Implement Access Control Registers. */
219 232 break;
220 233 case 0x801: /* VBR */
221 234 env->vbr = val;
... ... @@ -261,6 +274,17 @@ void m68k_set_macsr(CPUM68KState *env, uint32_t val)
261 274 env->macsr = val;
262 275 }
263 276  
  277 +void m68k_switch_sp(CPUM68KState *env)
  278 +{
  279 + int new_sp;
  280 +
  281 + env->sp[env->current_sp] = env->aregs[7];
  282 + new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
  283 + ? M68K_SSP : M68K_USP;
  284 + env->aregs[7] = env->sp[new_sp];
  285 + env->current_sp = new_sp;
  286 +}
  287 +
264 288 /* MMU */
265 289  
266 290 /* TODO: This will need fixing once the MMU is implemented. */
... ...
target-m68k/op.c
... ... @@ -478,6 +478,13 @@ OP(fp_result)
478 478 FORCE_RET();
479 479 }
480 480  
  481 +OP(set_sr)
  482 +{
  483 + env->sr = get_op(PARAM1);
  484 + m68k_switch_sp(env);
  485 + FORCE_RET();
  486 +}
  487 +
481 488 OP(jmp)
482 489 {
483 490 GOTO_LABEL_PARAM(1);
... ...
target-m68k/op_helper.c
... ... @@ -87,6 +87,7 @@ static void do_rte(void)
87 87 env->pc = ldl_kernel(sp + 4);
88 88 sp |= (fmt >> 28) & 3;
89 89 env->sr = fmt & 0xffff;
  90 + m68k_switch_sp(env);
90 91 env->aregs[7] = sp + 8;
91 92 }
92 93  
... ... @@ -128,9 +129,6 @@ void do_interrupt(int is_hw)
128 129 }
129 130 }
130 131  
131   - /* TODO: Implement USP. */
132   - sp = env->aregs[7];
133   -
134 132 vector = env->exception_index << 2;
135 133  
136 134 fmt |= 0x40000000;
... ... @@ -138,6 +136,15 @@ void do_interrupt(int is_hw)
138 136 fmt |= vector << 16;
139 137 fmt |= env->sr;
140 138  
  139 + env->sr |= SR_S;
  140 + if (is_hw) {
  141 + env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
  142 + env->sr &= ~SR_M;
  143 + }
  144 + m68k_switch_sp(env);
  145 +
  146 + sp = env->aregs[7];
  147 +
141 148 /* ??? This could cause MMU faults. */
142 149 sp &= ~3;
143 150 sp -= 4;
... ... @@ -145,11 +152,6 @@ void do_interrupt(int is_hw)
145 152 sp -= 4;
146 153 stl_kernel(sp, fmt);
147 154 env->aregs[7] = sp;
148   - env->sr |= SR_S;
149   - if (is_hw) {
150   - env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
151   - env->sr &= ~SR_M;
152   - }
153 155 /* Jump to vector. */
154 156 env->pc = ldl_kernel(env->vbr + vector);
155 157 }
... ...
target-m68k/translate.c
... ... @@ -1345,7 +1345,7 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
1345 1345 gen_op_logic_cc(gen_im32(val & 0xf));
1346 1346 gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
1347 1347 if (!ccr_only) {
1348   - gen_op_mov32(QREG_SR, gen_im32(val & 0xff00));
  1348 + gen_op_set_sr(gen_im32(val & 0xff00));
1349 1349 }
1350 1350 }
1351 1351  
... ... @@ -1365,7 +1365,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
1365 1365 gen_op_and32(src1, src1, gen_im32(1));
1366 1366 gen_op_update_xflag_tst(src1);
1367 1367 if (!ccr_only) {
1368   - gen_op_and32(QREG_SR, reg, gen_im32(0xff00));
  1368 + gen_op_set_sr(reg);
1369 1369 }
1370 1370 }
1371 1371 else if ((insn & 0x3f) == 0x3c)
... ... @@ -2797,8 +2797,8 @@ void register_m68k_insns (CPUM68KState *env)
2797 2797 INSN(trap, 4e40, fff0, CF_ISA_A);
2798 2798 INSN(link, 4e50, fff8, CF_ISA_A);
2799 2799 INSN(unlk, 4e58, fff8, CF_ISA_A);
2800   - INSN(move_to_usp, 4e60, fff8, CF_ISA_B);
2801   - INSN(move_from_usp, 4e68, fff8, CF_ISA_B);
  2800 + INSN(move_to_usp, 4e60, fff8, USP);
  2801 + INSN(move_from_usp, 4e68, fff8, USP);
2802 2802 INSN(nop, 4e71, ffff, CF_ISA_A);
2803 2803 INSN(stop, 4e72, ffff, CF_ISA_A);
2804 2804 INSN(rte, 4e73, ffff, CF_ISA_A);
... ... @@ -3261,6 +3261,7 @@ void cpu_reset(CPUM68KState *env)
3261 3261 #if !defined (CONFIG_USER_ONLY)
3262 3262 env->sr = 0x2700;
3263 3263 #endif
  3264 + m68k_switch_sp(env);
3264 3265 /* ??? FP regs should be initialized to NaN. */
3265 3266 env->cc_op = CC_OP_FLAGS;
3266 3267 /* TODO: We should set PC from the interrupt vector. */
... ...
... ... @@ -6972,6 +6972,7 @@ void register_machines(void)
6972 6972 #elif defined(TARGET_ALPHA)
6973 6973 /* XXX: TODO */
6974 6974 #elif defined(TARGET_M68K)
  6975 + qemu_register_machine(&mcf5208evb_machine);
6975 6976 qemu_register_machine(&an5206_machine);
6976 6977 #else
6977 6978 #error unsupported CPU
... ...
... ... @@ -1593,12 +1593,25 @@ void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
1593 1593  
1594 1594 #include "hw/pxa.h"
1595 1595  
  1596 +/* mcf_uart.c */
  1597 +uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr);
  1598 +void mcf_uart_write(void *opaque, target_phys_addr_t addr, uint32_t val);
  1599 +void *mcf_uart_init(qemu_irq irq, CharDriverState *chr);
  1600 +void mcf_uart_mm_init(target_phys_addr_t base, qemu_irq irq,
  1601 + CharDriverState *chr);
  1602 +
  1603 +/* mcf_intc.c */
  1604 +qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env);
  1605 +
1596 1606 /* mcf5206.c */
1597 1607 qemu_irq *mcf5206_init(uint32_t base, CPUState *env);
1598 1608  
1599 1609 /* an5206.c */
1600 1610 extern QEMUMachine an5206_machine;
1601 1611  
  1612 +/* mcf5208.c */
  1613 +extern QEMUMachine mcf5208evb_machine;
  1614 +
1602 1615 #include "gdbstub.h"
1603 1616  
1604 1617 #endif /* defined(QEMU_TOOL) */
... ...