MCF5208 emulation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2924 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									62ea5b0bd3
								
							
						
					
					
						commit
						20dcee9483
					
				@ -467,7 +467,7 @@ ifeq ($(TARGET_BASE_ARCH), sh4)
 | 
			
		||||
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
 | 
			
		||||
endif
 | 
			
		||||
ifeq ($(TARGET_BASE_ARCH), m68k)
 | 
			
		||||
VL_OBJS+= an5206.o mcf5206.o ptimer.o
 | 
			
		||||
VL_OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o
 | 
			
		||||
VL_OBJS+= m68k-semi.o
 | 
			
		||||
endif
 | 
			
		||||
ifdef CONFIG_GDBSTUB
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,9 @@ static void an5206_init(int ram_size, int vga_ram_size, int boot_device,
 | 
			
		||||
    env = cpu_init();
 | 
			
		||||
    if (!cpu_model)
 | 
			
		||||
        cpu_model = "m5206";
 | 
			
		||||
    cpu_m68k_set_model(env, cpu_model);
 | 
			
		||||
    if (cpu_m68k_set_model(env, cpu_model)) {
 | 
			
		||||
        cpu_abort(env, "Unable to find m68k CPU definition\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Initialize CPU registers.  */
 | 
			
		||||
    env->vbr = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										289
									
								
								hw/mcf5206.c
									
									
									
									
									
								
							
							
						
						
									
										289
									
								
								hw/mcf5206.c
									
									
									
									
									
								
							@ -139,285 +139,12 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* UART */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t mr[2];
 | 
			
		||||
    uint8_t sr;
 | 
			
		||||
    uint8_t isr;
 | 
			
		||||
    uint8_t imr;
 | 
			
		||||
    uint8_t bg1;
 | 
			
		||||
    uint8_t bg2;
 | 
			
		||||
    uint8_t fifo[4];
 | 
			
		||||
    uint8_t tb;
 | 
			
		||||
    int current_mr;
 | 
			
		||||
    int fifo_len;
 | 
			
		||||
    int tx_enabled;
 | 
			
		||||
    int rx_enabled;
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
} m5206_uart_state;
 | 
			
		||||
 | 
			
		||||
/* UART Status Register bits.  */
 | 
			
		||||
#define M5206_UART_RxRDY  0x01
 | 
			
		||||
#define M5206_UART_FFULL  0x02
 | 
			
		||||
#define M5206_UART_TxRDY  0x04
 | 
			
		||||
#define M5206_UART_TxEMP  0x08
 | 
			
		||||
#define M5206_UART_OE     0x10
 | 
			
		||||
#define M5206_UART_PE     0x20
 | 
			
		||||
#define M5206_UART_FE     0x40
 | 
			
		||||
#define M5206_UART_RB     0x80
 | 
			
		||||
 | 
			
		||||
/* Interrupt flags.  */
 | 
			
		||||
#define M5206_UART_TxINT  0x01
 | 
			
		||||
#define M5206_UART_RxINT  0x02
 | 
			
		||||
#define M5206_UART_DBINT  0x04
 | 
			
		||||
#define M5206_UART_COSINT 0x80
 | 
			
		||||
 | 
			
		||||
/* UMR1 flags.  */
 | 
			
		||||
#define M5206_UART_BC0    0x01
 | 
			
		||||
#define M5206_UART_BC1    0x02
 | 
			
		||||
#define M5206_UART_PT     0x04
 | 
			
		||||
#define M5206_UART_PM0    0x08
 | 
			
		||||
#define M5206_UART_PM1    0x10
 | 
			
		||||
#define M5206_UART_ERR    0x20
 | 
			
		||||
#define M5206_UART_RxIRQ  0x40
 | 
			
		||||
#define M5206_UART_RxRTS  0x80
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_update(m5206_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    s->isr &= ~(M5206_UART_TxINT | M5206_UART_RxINT);
 | 
			
		||||
    if (s->sr & M5206_UART_TxRDY)
 | 
			
		||||
        s->isr |= M5206_UART_TxINT;
 | 
			
		||||
    if ((s->sr & ((s->mr[0] & M5206_UART_RxIRQ)
 | 
			
		||||
                  ? M5206_UART_FFULL : M5206_UART_RxRDY)) != 0)
 | 
			
		||||
        s->isr |= M5206_UART_RxINT;
 | 
			
		||||
 | 
			
		||||
    qemu_set_irq(s->irq, (s->isr & s->imr) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t m5206_uart_read(m5206_uart_state *s, uint32_t addr)
 | 
			
		||||
{
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        return s->mr[s->current_mr];
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        return s->sr;
 | 
			
		||||
    case 0x0c:
 | 
			
		||||
        {
 | 
			
		||||
            uint8_t val;
 | 
			
		||||
            int i;
 | 
			
		||||
 | 
			
		||||
            if (s->fifo_len == 0)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            val = s->fifo[0];
 | 
			
		||||
            s->fifo_len--;
 | 
			
		||||
            for (i = 0; i < s->fifo_len; i++)
 | 
			
		||||
                s->fifo[i] = s->fifo[i + 1];
 | 
			
		||||
            s->sr &= ~M5206_UART_FFULL;
 | 
			
		||||
            if (s->fifo_len == 0)
 | 
			
		||||
                s->sr &= ~M5206_UART_RxRDY;
 | 
			
		||||
            m5206_uart_update(s);
 | 
			
		||||
            return val;
 | 
			
		||||
        }
 | 
			
		||||
    case 0x10:
 | 
			
		||||
        /* TODO: Implement IPCR.  */
 | 
			
		||||
        return 0;
 | 
			
		||||
    case 0x14:
 | 
			
		||||
        return s->isr;
 | 
			
		||||
    case 0x18:
 | 
			
		||||
        return s->bg1;
 | 
			
		||||
    case 0x1c:
 | 
			
		||||
        return s->bg2;
 | 
			
		||||
    default:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Update TxRDY flag and set data if present and enabled.  */
 | 
			
		||||
static void m5206_uart_do_tx(m5206_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    if (s->tx_enabled && (s->sr & M5206_UART_TxEMP) == 0) {
 | 
			
		||||
        if (s->chr)
 | 
			
		||||
            qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
 | 
			
		||||
        s->sr |= M5206_UART_TxEMP;
 | 
			
		||||
    }
 | 
			
		||||
    if (s->tx_enabled) {
 | 
			
		||||
        s->sr |= M5206_UART_TxRDY;
 | 
			
		||||
    } else {
 | 
			
		||||
        s->sr &= ~M5206_UART_TxRDY;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_do_command(m5206_uart_state *s, uint8_t cmd)
 | 
			
		||||
{
 | 
			
		||||
    /* Misc command.  */
 | 
			
		||||
    switch ((cmd >> 4) & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Reset mode register pointer.  */
 | 
			
		||||
        s->current_mr = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case 2: /* Reset receiver.  */
 | 
			
		||||
        s->rx_enabled = 0;
 | 
			
		||||
        s->fifo_len = 0;
 | 
			
		||||
        s->sr &= ~(M5206_UART_RxRDY | M5206_UART_FFULL);
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reset transmitter.  */
 | 
			
		||||
        s->tx_enabled = 0;
 | 
			
		||||
        s->sr |= M5206_UART_TxEMP;
 | 
			
		||||
        s->sr &= ~M5206_UART_TxRDY;
 | 
			
		||||
        break;
 | 
			
		||||
    case 4: /* Reset error status.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 5: /* Reset break-change interrupt.  */
 | 
			
		||||
        s->isr &= ~M5206_UART_DBINT;
 | 
			
		||||
        break;
 | 
			
		||||
    case 6: /* Start break.  */
 | 
			
		||||
    case 7: /* Stop break.  */
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Transmitter command.  */
 | 
			
		||||
    switch ((cmd >> 2) & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Enable.  */
 | 
			
		||||
        s->tx_enabled = 1;
 | 
			
		||||
        m5206_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 2: /* Disable.  */
 | 
			
		||||
        s->tx_enabled = 0;
 | 
			
		||||
        m5206_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reserved.  */
 | 
			
		||||
        fprintf(stderr, "m5206_uart: Bad TX command\n");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Receiver command.  */
 | 
			
		||||
    switch (cmd & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Enable.  */
 | 
			
		||||
        s->rx_enabled = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        s->rx_enabled = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reserved.  */
 | 
			
		||||
        fprintf(stderr, "m5206_uart: Bad RX command\n");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_write(m5206_uart_state *s, uint32_t addr, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        s->mr[s->current_mr] = val;
 | 
			
		||||
        s->current_mr = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        /* CSR is ignored.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x08: /* Command Register.  */
 | 
			
		||||
        m5206_do_command(s, val);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0c: /* Transmit Buffer.  */
 | 
			
		||||
        s->sr &= ~M5206_UART_TxEMP;
 | 
			
		||||
        s->tb = val;
 | 
			
		||||
        m5206_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x10:
 | 
			
		||||
        /* ACR is ignored.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x14:
 | 
			
		||||
        s->imr = val;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    m5206_uart_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_reset(m5206_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    s->fifo_len = 0;
 | 
			
		||||
    s->mr[0] = 0;
 | 
			
		||||
    s->mr[1] = 0;
 | 
			
		||||
    s->sr = M5206_UART_TxEMP;
 | 
			
		||||
    s->tx_enabled = 0;
 | 
			
		||||
    s->rx_enabled = 0;
 | 
			
		||||
    s->isr = 0;
 | 
			
		||||
    s->imr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_push_byte(m5206_uart_state *s, uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    /* Break events overwrite the last byte if the fifo is full.  */
 | 
			
		||||
    if (s->fifo_len == 4)
 | 
			
		||||
        s->fifo_len--;
 | 
			
		||||
 | 
			
		||||
    s->fifo[s->fifo_len] = data;
 | 
			
		||||
    s->fifo_len++;
 | 
			
		||||
    s->sr |= M5206_UART_RxRDY;
 | 
			
		||||
    if (s->fifo_len == 4)
 | 
			
		||||
        s->sr |= M5206_UART_FFULL;
 | 
			
		||||
 | 
			
		||||
    m5206_uart_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_event(void *opaque, int event)
 | 
			
		||||
{
 | 
			
		||||
    m5206_uart_state *s = (m5206_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    switch (event) {
 | 
			
		||||
    case CHR_EVENT_BREAK:
 | 
			
		||||
        s->isr |= M5206_UART_DBINT;
 | 
			
		||||
        m5206_uart_push_byte(s, 0);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int m5206_uart_can_receive(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    m5206_uart_state *s = (m5206_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    return s->rx_enabled && (s->sr & M5206_UART_FFULL) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5206_uart_receive(void *opaque, const uint8_t *buf, int size)
 | 
			
		||||
{
 | 
			
		||||
    m5206_uart_state *s = (m5206_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    m5206_uart_push_byte(s, buf[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static m5206_uart_state *m5206_uart_init(qemu_irq irq, CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
    m5206_uart_state *s;
 | 
			
		||||
 | 
			
		||||
    s = qemu_mallocz(sizeof(m5206_uart_state));
 | 
			
		||||
    s->chr = chr;
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    if (chr) {
 | 
			
		||||
        qemu_chr_add_handlers(chr, m5206_uart_can_receive, m5206_uart_receive,
 | 
			
		||||
                              m5206_uart_event, s);
 | 
			
		||||
    }
 | 
			
		||||
    m5206_uart_reset(s);
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* System Integration Module.  */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    CPUState *env;
 | 
			
		||||
    m5206_timer_state *timer[2];
 | 
			
		||||
    m5206_uart_state *uart[2];
 | 
			
		||||
    void *uart[2];
 | 
			
		||||
    uint8_t scr;
 | 
			
		||||
    uint8_t icr[14];
 | 
			
		||||
    uint16_t imr; /* 1 == interrupt is masked.  */
 | 
			
		||||
@ -540,9 +267,9 @@ static uint32_t m5206_mbar_read(m5206_mbar_state *s, uint32_t offset)
 | 
			
		||||
    } else if (offset >= 0x120 && offset < 0x140) {
 | 
			
		||||
        return m5206_timer_read(s->timer[1], offset - 0x120);
 | 
			
		||||
    } else if (offset >= 0x140 && offset < 0x160) {
 | 
			
		||||
        return m5206_uart_read(s->uart[0], offset - 0x140);
 | 
			
		||||
        return mcf_uart_read(s->uart[0], offset - 0x140);
 | 
			
		||||
    } else if (offset >= 0x180 && offset < 0x1a0) {
 | 
			
		||||
        return m5206_uart_read(s->uart[1], offset - 0x180);
 | 
			
		||||
        return mcf_uart_read(s->uart[1], offset - 0x180);
 | 
			
		||||
    }
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case 0x03: return s->scr;
 | 
			
		||||
@ -580,10 +307,10 @@ static void m5206_mbar_write(m5206_mbar_state *s, uint32_t offset,
 | 
			
		||||
        m5206_timer_write(s->timer[1], offset - 0x120, value);
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (offset >= 0x140 && offset < 0x160) {
 | 
			
		||||
        m5206_uart_write(s->uart[0], offset - 0x140, value);
 | 
			
		||||
        mcf_uart_write(s->uart[0], offset - 0x140, value);
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (offset >= 0x180 && offset < 0x1a0) {
 | 
			
		||||
        m5206_uart_write(s->uart[1], offset - 0x180, value);
 | 
			
		||||
        mcf_uart_write(s->uart[1], offset - 0x180, value);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
@ -798,13 +525,13 @@ qemu_irq *mcf5206_init(uint32_t base, CPUState *env)
 | 
			
		||||
    s = (m5206_mbar_state *)qemu_mallocz(sizeof(m5206_mbar_state));
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, m5206_mbar_readfn,
 | 
			
		||||
                                       m5206_mbar_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x00000fff, iomemtype);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
 | 
			
		||||
 | 
			
		||||
    pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
 | 
			
		||||
    s->timer[0] = m5206_timer_init(pic[9]);
 | 
			
		||||
    s->timer[1] = m5206_timer_init(pic[10]);
 | 
			
		||||
    s->uart[0] = m5206_uart_init(pic[12], serial_hds[0]);
 | 
			
		||||
    s->uart[1] = m5206_uart_init(pic[13], serial_hds[1]);
 | 
			
		||||
    s->uart[0] = mcf_uart_init(pic[12], serial_hds[0]);
 | 
			
		||||
    s->uart[1] = mcf_uart_init(pic[13], serial_hds[1]);
 | 
			
		||||
    s->env = env;
 | 
			
		||||
 | 
			
		||||
    m5206_mbar_reset(s);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										285
									
								
								hw/mcf5208.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								hw/mcf5208.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,285 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * Motorola ColdFire MCF5208 SoC emulation.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007 CodeSourcery.
 | 
			
		||||
 *
 | 
			
		||||
 * This code is licenced under the GPL
 | 
			
		||||
 */
 | 
			
		||||
#include "vl.h"
 | 
			
		||||
 | 
			
		||||
#define SYS_FREQ 66000000
 | 
			
		||||
 | 
			
		||||
#define PCSR_EN         0x0001
 | 
			
		||||
#define PCSR_RLD        0x0002
 | 
			
		||||
#define PCSR_PIF        0x0004
 | 
			
		||||
#define PCSR_PIE        0x0008
 | 
			
		||||
#define PCSR_OVW        0x0010
 | 
			
		||||
#define PCSR_DBG        0x0020
 | 
			
		||||
#define PCSR_DOZE       0x0040
 | 
			
		||||
#define PCSR_PRE_SHIFT  8
 | 
			
		||||
#define PCSR_PRE_MASK   0x0f00
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    ptimer_state *timer;
 | 
			
		||||
    uint16_t pcsr;
 | 
			
		||||
    uint16_t pmr;
 | 
			
		||||
    uint16_t pcntr;
 | 
			
		||||
} m5208_timer_state;
 | 
			
		||||
 | 
			
		||||
static void m5208_timer_update(m5208_timer_state *s)
 | 
			
		||||
{
 | 
			
		||||
    if ((s->pcsr & (PCSR_PIE | PCSR_PIF)) == (PCSR_PIE | PCSR_PIF))
 | 
			
		||||
        qemu_irq_raise(s->irq);
 | 
			
		||||
    else
 | 
			
		||||
        qemu_irq_lower(s->irq);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5208_timer_write(m5208_timer_state *s, int offset,
 | 
			
		||||
                              uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    int prescale;
 | 
			
		||||
    int limit;
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case 0:
 | 
			
		||||
        /* The PIF bit is set-to-clear.  */
 | 
			
		||||
        if (value & PCSR_PIF) {
 | 
			
		||||
            s->pcsr &= ~PCSR_PIF;
 | 
			
		||||
            value &= ~PCSR_PIF;
 | 
			
		||||
        }
 | 
			
		||||
        /* Avoid frobbing the timer if we're just twiddling IRQ bits. */
 | 
			
		||||
        if (((s->pcsr ^ value) & ~PCSR_PIE) == 0) {
 | 
			
		||||
            s->pcsr = value;
 | 
			
		||||
            m5208_timer_update(s);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (s->pcsr & PCSR_EN)
 | 
			
		||||
            ptimer_stop(s->timer);
 | 
			
		||||
 | 
			
		||||
        s->pcsr = value;
 | 
			
		||||
 | 
			
		||||
        prescale = 1 << ((s->pcsr & PCSR_PRE_MASK) >> PCSR_PRE_SHIFT);
 | 
			
		||||
        ptimer_set_freq(s->timer, (SYS_FREQ / 2) / prescale);
 | 
			
		||||
        if (s->pcsr & PCSR_RLD)
 | 
			
		||||
            limit = 0xffff;
 | 
			
		||||
        else
 | 
			
		||||
            limit = s->pmr;
 | 
			
		||||
        ptimer_set_limit(s->timer, limit, 0);
 | 
			
		||||
 | 
			
		||||
        if (s->pcsr & PCSR_EN)
 | 
			
		||||
            ptimer_run(s->timer, 0);
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        s->pmr = value;
 | 
			
		||||
        s->pcsr &= ~PCSR_PIF;
 | 
			
		||||
        if (s->pcsr & PCSR_RLD)
 | 
			
		||||
            value = 0xffff;
 | 
			
		||||
        ptimer_set_limit(s->timer, value, s->pcsr & PCSR_OVW);
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        /* Should never happen.  */
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
    m5208_timer_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5208_timer_trigger(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    m5208_timer_state *s = (m5208_timer_state *)opaque;
 | 
			
		||||
    s->pcsr |= PCSR_PIF;
 | 
			
		||||
    m5208_timer_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    m5208_timer_state timer[2];
 | 
			
		||||
} m5208_sys_state;
 | 
			
		||||
 | 
			
		||||
static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    m5208_sys_state *s = (m5208_sys_state *)opaque;
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    /* PIT0 */
 | 
			
		||||
    case 0xfc080000:
 | 
			
		||||
        return s->timer[0].pcsr;
 | 
			
		||||
    case 0xfc080002:
 | 
			
		||||
        return s->timer[0].pmr;
 | 
			
		||||
    case 0xfc080004:
 | 
			
		||||
        return ptimer_get_count(s->timer[0].timer);
 | 
			
		||||
    /* PIT1 */
 | 
			
		||||
    case 0xfc084000:
 | 
			
		||||
        return s->timer[1].pcsr;
 | 
			
		||||
    case 0xfc084002:
 | 
			
		||||
        return s->timer[1].pmr;
 | 
			
		||||
    case 0xfc084004:
 | 
			
		||||
        return ptimer_get_count(s->timer[1].timer);
 | 
			
		||||
 | 
			
		||||
    /* SDRAM Controller.  */
 | 
			
		||||
    case 0xfc0a8110: /* SDCS0 */
 | 
			
		||||
        {
 | 
			
		||||
            int n;
 | 
			
		||||
            for (n = 0; n < 32; n++) {
 | 
			
		||||
                if (ram_size < (2u << n))
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            return (n - 1)  | 0x40000000;
 | 
			
		||||
        }
 | 
			
		||||
    case 0xfc0a8114: /* SDCS1 */
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        cpu_abort(cpu_single_env, "m5208_sys_read: Bad offset 0x%x\n",
 | 
			
		||||
                  (int)addr);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
 | 
			
		||||
                            uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    m5208_sys_state *s = (m5208_sys_state *)opaque;
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    /* PIT0 */
 | 
			
		||||
    case 0xfc080000:
 | 
			
		||||
    case 0xfc080002:
 | 
			
		||||
    case 0xfc080004:
 | 
			
		||||
        m5208_timer_write(&s->timer[0], addr & 0xf, value);
 | 
			
		||||
        return;
 | 
			
		||||
    /* PIT1 */
 | 
			
		||||
    case 0xfc084000:
 | 
			
		||||
    case 0xfc084002:
 | 
			
		||||
    case 0xfc084004:
 | 
			
		||||
        m5208_timer_write(&s->timer[1], addr & 0xf, value);
 | 
			
		||||
        return;
 | 
			
		||||
    default:
 | 
			
		||||
        cpu_abort(cpu_single_env, "m5208_sys_write: Bad offset 0x%x\n",
 | 
			
		||||
                  (int)addr);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CPUReadMemoryFunc *m5208_sys_readfn[] = {
 | 
			
		||||
   m5208_sys_read,
 | 
			
		||||
   m5208_sys_read,
 | 
			
		||||
   m5208_sys_read
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static CPUWriteMemoryFunc *m5208_sys_writefn[] = {
 | 
			
		||||
   m5208_sys_write,
 | 
			
		||||
   m5208_sys_write,
 | 
			
		||||
   m5208_sys_write
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mcf5208_sys_init(qemu_irq *pic)
 | 
			
		||||
{
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
    m5208_sys_state *s;
 | 
			
		||||
    QEMUBH *bh;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    s = (m5208_sys_state *)qemu_mallocz(sizeof(m5208_sys_state));
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, m5208_sys_readfn,
 | 
			
		||||
                                       m5208_sys_writefn, s);
 | 
			
		||||
    /* SDRAMC.  */
 | 
			
		||||
    cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
 | 
			
		||||
    /* Timers.  */
 | 
			
		||||
    for (i = 0; i < 2; i++) {
 | 
			
		||||
        bh = qemu_bh_new(m5208_timer_trigger, &s->timer[i]);
 | 
			
		||||
        s->timer[i].timer = ptimer_init(bh);
 | 
			
		||||
        cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
 | 
			
		||||
                                     iomemtype);
 | 
			
		||||
        s->timer[i].irq = pic[4 + i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf5208evb_init(int ram_size, int vga_ram_size, int boot_device,
 | 
			
		||||
                     DisplayState *ds, const char **fd_filename, int snapshot,
 | 
			
		||||
                     const char *kernel_filename, const char *kernel_cmdline,
 | 
			
		||||
                     const char *initrd_filename, const char *cpu_model)
 | 
			
		||||
{
 | 
			
		||||
    CPUState *env;
 | 
			
		||||
    int kernel_size;
 | 
			
		||||
    uint64_t elf_entry;
 | 
			
		||||
    target_ulong entry;
 | 
			
		||||
    qemu_irq *pic;
 | 
			
		||||
 | 
			
		||||
    env = cpu_init();
 | 
			
		||||
    if (!cpu_model)
 | 
			
		||||
        cpu_model = "m5208";
 | 
			
		||||
    if (cpu_m68k_set_model(env, cpu_model)) {
 | 
			
		||||
        cpu_abort(env, "Unable to find m68k CPU definition\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Initialize CPU registers.  */
 | 
			
		||||
    env->vbr = 0;
 | 
			
		||||
    /* TODO: Configure BARs.  */
 | 
			
		||||
 | 
			
		||||
    /* DRAM at 0x20000000 */
 | 
			
		||||
    cpu_register_physical_memory(0x40000000, ram_size,
 | 
			
		||||
        qemu_ram_alloc(ram_size) | IO_MEM_RAM);
 | 
			
		||||
 | 
			
		||||
    /* Internal SRAM.  */
 | 
			
		||||
    cpu_register_physical_memory(0x80000000, 16384,
 | 
			
		||||
        qemu_ram_alloc(16384) | IO_MEM_RAM);
 | 
			
		||||
 | 
			
		||||
    /* Internal peripherals.  */
 | 
			
		||||
    pic = mcf_intc_init(0xfc048000, env);
 | 
			
		||||
 | 
			
		||||
    mcf_uart_mm_init(0xfc060000, pic[26], serial_hds[0]);
 | 
			
		||||
    mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
 | 
			
		||||
    mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
 | 
			
		||||
 | 
			
		||||
    mcf5208_sys_init(pic);
 | 
			
		||||
 | 
			
		||||
    /*  0xfc000000 SCM.  */
 | 
			
		||||
    /*  0xfc004000 XBS.  */
 | 
			
		||||
    /*  0xfc008000 FlexBus CS.  */
 | 
			
		||||
    /*  0xfc030000 FEC.  */
 | 
			
		||||
    /*  0xfc040000 SCM + Power management.  */
 | 
			
		||||
    /*  0xfc044000 eDMA.  */
 | 
			
		||||
    /* 0xfc048000 INTC.  */
 | 
			
		||||
    /*  0xfc058000 I2C.  */
 | 
			
		||||
    /*  0xfc05c000 QSPI.  */
 | 
			
		||||
    /* 0xfc060000 UART0.  */
 | 
			
		||||
    /* 0xfc064000 UART0.  */
 | 
			
		||||
    /* 0xfc068000 UART0.  */
 | 
			
		||||
    /*  0xfc070000 DMA timers.  */
 | 
			
		||||
    /* 0xfc080000 PIT0.  */
 | 
			
		||||
    /* 0xfc084000 PIT1.  */
 | 
			
		||||
    /*  0xfc088000 EPORT.  */
 | 
			
		||||
    /*  0xfc08c000 Watchdog.  */
 | 
			
		||||
    /*  0xfc090000 clock module.  */
 | 
			
		||||
    /*  0xfc0a0000 CCM + reset.  */
 | 
			
		||||
    /*  0xfc0a4000 GPIO.  */
 | 
			
		||||
    /* 0xfc0a8000 SDRAM controller.  */
 | 
			
		||||
 | 
			
		||||
    /* Load kernel.  */
 | 
			
		||||
    if (!kernel_filename) {
 | 
			
		||||
        fprintf(stderr, "Kernel image must be specified\n");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
 | 
			
		||||
    entry = elf_entry;
 | 
			
		||||
    if (kernel_size < 0) {
 | 
			
		||||
        kernel_size = load_uboot(kernel_filename, &entry, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    if (kernel_size < 0) {
 | 
			
		||||
        kernel_size = load_image(kernel_filename, phys_ram_base);
 | 
			
		||||
        entry = 0x20000000;
 | 
			
		||||
    }
 | 
			
		||||
    if (kernel_size < 0) {
 | 
			
		||||
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    env->pc = entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QEMUMachine mcf5208evb_machine = {
 | 
			
		||||
    "mcf5208evb",
 | 
			
		||||
    "MCF5206EVB",
 | 
			
		||||
    mcf5208evb_init,
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										156
									
								
								hw/mcf_intc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								hw/mcf_intc.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,156 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * ColdFire Interrupt Controller emulation.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007 CodeSourcery.
 | 
			
		||||
 *
 | 
			
		||||
 * This code is licenced under the GPL
 | 
			
		||||
 */
 | 
			
		||||
#include "vl.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint64_t ipr;
 | 
			
		||||
    uint64_t imr;
 | 
			
		||||
    uint64_t ifr;
 | 
			
		||||
    uint64_t enabled;
 | 
			
		||||
    uint8_t icr[64];
 | 
			
		||||
    CPUState *env;
 | 
			
		||||
    int active_vector;
 | 
			
		||||
} mcf_intc_state;
 | 
			
		||||
 | 
			
		||||
static void mcf_intc_update(mcf_intc_state *s)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t active;
 | 
			
		||||
    int i;
 | 
			
		||||
    int best;
 | 
			
		||||
    int best_level;
 | 
			
		||||
 | 
			
		||||
    active = (s->ipr | s->ifr) & s->enabled & ~s->imr;
 | 
			
		||||
    best_level = 0;
 | 
			
		||||
    best = 64;
 | 
			
		||||
    if (active) {
 | 
			
		||||
        for (i = 0; i < 64; i++) {
 | 
			
		||||
            if ((active & 1) != 0 && s->icr[i] >= best_level) {
 | 
			
		||||
                best_level = s->icr[i];
 | 
			
		||||
                best = i;
 | 
			
		||||
            }
 | 
			
		||||
            active >>= 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    s->active_vector = ((best == 64) ? 24 : (best + 64));
 | 
			
		||||
    m68k_set_irq_level(s->env, best_level, s->active_vector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t mcf_intc_read(void *opaque, target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    int offset;
 | 
			
		||||
    mcf_intc_state *s = (mcf_intc_state *)opaque;
 | 
			
		||||
    offset = addr & 0xff;
 | 
			
		||||
    if (offset >= 0x40 && offset < 0x80) {
 | 
			
		||||
        return s->icr[offset - 0x40];
 | 
			
		||||
    }
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        return (uint32_t)(s->ipr >> 32);
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        return (uint32_t)s->ipr;
 | 
			
		||||
    case 0x08:
 | 
			
		||||
        return (uint32_t)(s->imr >> 32);
 | 
			
		||||
    case 0x0c:
 | 
			
		||||
        return (uint32_t)s->imr;
 | 
			
		||||
    case 0x10:
 | 
			
		||||
        return (uint32_t)(s->ifr >> 32);
 | 
			
		||||
    case 0x14:
 | 
			
		||||
        return (uint32_t)s->ifr;
 | 
			
		||||
    case 0xe0: /* SWIACK.  */
 | 
			
		||||
        return s->active_vector;
 | 
			
		||||
    case 0xe1: case 0xe2: case 0xe3: case 0xe4:
 | 
			
		||||
    case 0xe5: case 0xe6: case 0xe7:
 | 
			
		||||
        /* LnIACK */
 | 
			
		||||
        cpu_abort(cpu_single_env, "mcf_intc_read: LnIACK not implemented\n");
 | 
			
		||||
    default:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_intc_write(void *opaque, target_phys_addr_t addr, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    int offset;
 | 
			
		||||
    mcf_intc_state *s = (mcf_intc_state *)opaque;
 | 
			
		||||
    offset = addr & 0xff;
 | 
			
		||||
    if (offset >= 0x40 && offset < 0x80) {
 | 
			
		||||
        int n = offset - 0x40;
 | 
			
		||||
        s->icr[n] = val;
 | 
			
		||||
        if (val == 0)
 | 
			
		||||
            s->enabled &= ~(1ull << n);
 | 
			
		||||
        else
 | 
			
		||||
            s->enabled |= (1ull << n);
 | 
			
		||||
        mcf_intc_update(s);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    switch (offset) {
 | 
			
		||||
    case 0x00: case 0x04:
 | 
			
		||||
        /* Ignore IPR writes.  */
 | 
			
		||||
        return;
 | 
			
		||||
    case 0x08:
 | 
			
		||||
        s->imr = (s->imr & 0xffffffff) | ((uint64_t)val << 32);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0c:
 | 
			
		||||
        s->imr = (s->imr & 0xffffffff00000000ull) | (uint32_t)val;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        cpu_abort(cpu_single_env, "mcf_intc_write: Bad write offset %d\n",
 | 
			
		||||
                  offset);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    mcf_intc_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_intc_set_irq(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    mcf_intc_state *s = (mcf_intc_state *)opaque;
 | 
			
		||||
    if (irq >= 64)
 | 
			
		||||
        return;
 | 
			
		||||
    if (level)
 | 
			
		||||
        s->ipr |= 1ull << irq;
 | 
			
		||||
    else
 | 
			
		||||
        s->ipr &= ~(1ull << irq);
 | 
			
		||||
    mcf_intc_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_intc_reset(mcf_intc_state *s)
 | 
			
		||||
{
 | 
			
		||||
    s->imr = ~0ull;
 | 
			
		||||
    s->ipr = 0;
 | 
			
		||||
    s->ifr = 0;
 | 
			
		||||
    s->enabled = 0;
 | 
			
		||||
    memset(s->icr, 0, 64);
 | 
			
		||||
    s->active_vector = 24;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CPUReadMemoryFunc *mcf_intc_readfn[] = {
 | 
			
		||||
   mcf_intc_read,
 | 
			
		||||
   mcf_intc_read,
 | 
			
		||||
   mcf_intc_read
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static CPUWriteMemoryFunc *mcf_intc_writefn[] = {
 | 
			
		||||
   mcf_intc_write,
 | 
			
		||||
   mcf_intc_write,
 | 
			
		||||
   mcf_intc_write
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env)
 | 
			
		||||
{
 | 
			
		||||
    mcf_intc_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    s = qemu_mallocz(sizeof(mcf_intc_state));
 | 
			
		||||
    s->env = env;
 | 
			
		||||
    mcf_intc_reset(s);
 | 
			
		||||
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, mcf_intc_readfn,
 | 
			
		||||
                                       mcf_intc_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x100, iomemtype);
 | 
			
		||||
 | 
			
		||||
    return qemu_allocate_irqs(mcf_intc_set_irq, s, 64);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										306
									
								
								hw/mcf_uart.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								hw/mcf_uart.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,306 @@
 | 
			
		||||
/* 
 | 
			
		||||
 * ColdFire UART emulation.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2007 CodeSourcery.
 | 
			
		||||
 *
 | 
			
		||||
 * This code is licenced under the GPL
 | 
			
		||||
 */
 | 
			
		||||
#include "vl.h"
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t mr[2];
 | 
			
		||||
    uint8_t sr;
 | 
			
		||||
    uint8_t isr;
 | 
			
		||||
    uint8_t imr;
 | 
			
		||||
    uint8_t bg1;
 | 
			
		||||
    uint8_t bg2;
 | 
			
		||||
    uint8_t fifo[4];
 | 
			
		||||
    uint8_t tb;
 | 
			
		||||
    int current_mr;
 | 
			
		||||
    int fifo_len;
 | 
			
		||||
    int tx_enabled;
 | 
			
		||||
    int rx_enabled;
 | 
			
		||||
    qemu_irq irq;
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
} mcf_uart_state;
 | 
			
		||||
 | 
			
		||||
/* UART Status Register bits.  */
 | 
			
		||||
#define MCF_UART_RxRDY  0x01
 | 
			
		||||
#define MCF_UART_FFULL  0x02
 | 
			
		||||
#define MCF_UART_TxRDY  0x04
 | 
			
		||||
#define MCF_UART_TxEMP  0x08
 | 
			
		||||
#define MCF_UART_OE     0x10
 | 
			
		||||
#define MCF_UART_PE     0x20
 | 
			
		||||
#define MCF_UART_FE     0x40
 | 
			
		||||
#define MCF_UART_RB     0x80
 | 
			
		||||
 | 
			
		||||
/* Interrupt flags.  */
 | 
			
		||||
#define MCF_UART_TxINT  0x01
 | 
			
		||||
#define MCF_UART_RxINT  0x02
 | 
			
		||||
#define MCF_UART_DBINT  0x04
 | 
			
		||||
#define MCF_UART_COSINT 0x80
 | 
			
		||||
 | 
			
		||||
/* UMR1 flags.  */
 | 
			
		||||
#define MCF_UART_BC0    0x01
 | 
			
		||||
#define MCF_UART_BC1    0x02
 | 
			
		||||
#define MCF_UART_PT     0x04
 | 
			
		||||
#define MCF_UART_PM0    0x08
 | 
			
		||||
#define MCF_UART_PM1    0x10
 | 
			
		||||
#define MCF_UART_ERR    0x20
 | 
			
		||||
#define MCF_UART_RxIRQ  0x40
 | 
			
		||||
#define MCF_UART_RxRTS  0x80
 | 
			
		||||
 | 
			
		||||
static void mcf_uart_update(mcf_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    s->isr &= ~(MCF_UART_TxINT | MCF_UART_RxINT);
 | 
			
		||||
    if (s->sr & MCF_UART_TxRDY)
 | 
			
		||||
        s->isr |= MCF_UART_TxINT;
 | 
			
		||||
    if ((s->sr & ((s->mr[0] & MCF_UART_RxIRQ)
 | 
			
		||||
                  ? MCF_UART_FFULL : MCF_UART_RxRDY)) != 0)
 | 
			
		||||
        s->isr |= MCF_UART_RxINT;
 | 
			
		||||
 | 
			
		||||
    qemu_set_irq(s->irq, (s->isr & s->imr) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s = (mcf_uart_state *)opaque;
 | 
			
		||||
    switch (addr & 0x3f) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        return s->mr[s->current_mr];
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        return s->sr;
 | 
			
		||||
    case 0x0c:
 | 
			
		||||
        {
 | 
			
		||||
            uint8_t val;
 | 
			
		||||
            int i;
 | 
			
		||||
 | 
			
		||||
            if (s->fifo_len == 0)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            val = s->fifo[0];
 | 
			
		||||
            s->fifo_len--;
 | 
			
		||||
            for (i = 0; i < s->fifo_len; i++)
 | 
			
		||||
                s->fifo[i] = s->fifo[i + 1];
 | 
			
		||||
            s->sr &= ~MCF_UART_FFULL;
 | 
			
		||||
            if (s->fifo_len == 0)
 | 
			
		||||
                s->sr &= ~MCF_UART_RxRDY;
 | 
			
		||||
            mcf_uart_update(s);
 | 
			
		||||
            return val;
 | 
			
		||||
        }
 | 
			
		||||
    case 0x10:
 | 
			
		||||
        /* TODO: Implement IPCR.  */
 | 
			
		||||
        return 0;
 | 
			
		||||
    case 0x14:
 | 
			
		||||
        return s->isr;
 | 
			
		||||
    case 0x18:
 | 
			
		||||
        return s->bg1;
 | 
			
		||||
    case 0x1c:
 | 
			
		||||
        return s->bg2;
 | 
			
		||||
    default:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Update TxRDY flag and set data if present and enabled.  */
 | 
			
		||||
static void mcf_uart_do_tx(mcf_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) {
 | 
			
		||||
        if (s->chr)
 | 
			
		||||
            qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
 | 
			
		||||
        s->sr |= MCF_UART_TxEMP;
 | 
			
		||||
    }
 | 
			
		||||
    if (s->tx_enabled) {
 | 
			
		||||
        s->sr |= MCF_UART_TxRDY;
 | 
			
		||||
    } else {
 | 
			
		||||
        s->sr &= ~MCF_UART_TxRDY;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_do_command(mcf_uart_state *s, uint8_t cmd)
 | 
			
		||||
{
 | 
			
		||||
    /* Misc command.  */
 | 
			
		||||
    switch ((cmd >> 4) & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Reset mode register pointer.  */
 | 
			
		||||
        s->current_mr = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case 2: /* Reset receiver.  */
 | 
			
		||||
        s->rx_enabled = 0;
 | 
			
		||||
        s->fifo_len = 0;
 | 
			
		||||
        s->sr &= ~(MCF_UART_RxRDY | MCF_UART_FFULL);
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reset transmitter.  */
 | 
			
		||||
        s->tx_enabled = 0;
 | 
			
		||||
        s->sr |= MCF_UART_TxEMP;
 | 
			
		||||
        s->sr &= ~MCF_UART_TxRDY;
 | 
			
		||||
        break;
 | 
			
		||||
    case 4: /* Reset error status.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 5: /* Reset break-change interrupt.  */
 | 
			
		||||
        s->isr &= ~MCF_UART_DBINT;
 | 
			
		||||
        break;
 | 
			
		||||
    case 6: /* Start break.  */
 | 
			
		||||
    case 7: /* Stop break.  */
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Transmitter command.  */
 | 
			
		||||
    switch ((cmd >> 2) & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Enable.  */
 | 
			
		||||
        s->tx_enabled = 1;
 | 
			
		||||
        mcf_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 2: /* Disable.  */
 | 
			
		||||
        s->tx_enabled = 0;
 | 
			
		||||
        mcf_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reserved.  */
 | 
			
		||||
        fprintf(stderr, "mcf_uart: Bad TX command\n");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Receiver command.  */
 | 
			
		||||
    switch (cmd & 3) {
 | 
			
		||||
    case 0: /* No-op.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 1: /* Enable.  */
 | 
			
		||||
        s->rx_enabled = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        s->rx_enabled = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    case 3: /* Reserved.  */
 | 
			
		||||
        fprintf(stderr, "mcf_uart: Bad RX command\n");
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mcf_uart_write(void *opaque, target_phys_addr_t addr, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s = (mcf_uart_state *)opaque;
 | 
			
		||||
    switch (addr & 0x3f) {
 | 
			
		||||
    case 0x00:
 | 
			
		||||
        s->mr[s->current_mr] = val;
 | 
			
		||||
        s->current_mr = 1;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04:
 | 
			
		||||
        /* CSR is ignored.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x08: /* Command Register.  */
 | 
			
		||||
        mcf_do_command(s, val);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0c: /* Transmit Buffer.  */
 | 
			
		||||
        s->sr &= ~MCF_UART_TxEMP;
 | 
			
		||||
        s->tb = val;
 | 
			
		||||
        mcf_uart_do_tx(s);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x10:
 | 
			
		||||
        /* ACR is ignored.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x14:
 | 
			
		||||
        s->imr = val;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    mcf_uart_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_uart_reset(mcf_uart_state *s)
 | 
			
		||||
{
 | 
			
		||||
    s->fifo_len = 0;
 | 
			
		||||
    s->mr[0] = 0;
 | 
			
		||||
    s->mr[1] = 0;
 | 
			
		||||
    s->sr = MCF_UART_TxEMP;
 | 
			
		||||
    s->tx_enabled = 0;
 | 
			
		||||
    s->rx_enabled = 0;
 | 
			
		||||
    s->isr = 0;
 | 
			
		||||
    s->imr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_uart_push_byte(mcf_uart_state *s, uint8_t data)
 | 
			
		||||
{
 | 
			
		||||
    /* Break events overwrite the last byte if the fifo is full.  */
 | 
			
		||||
    if (s->fifo_len == 4)
 | 
			
		||||
        s->fifo_len--;
 | 
			
		||||
 | 
			
		||||
    s->fifo[s->fifo_len] = data;
 | 
			
		||||
    s->fifo_len++;
 | 
			
		||||
    s->sr |= MCF_UART_RxRDY;
 | 
			
		||||
    if (s->fifo_len == 4)
 | 
			
		||||
        s->sr |= MCF_UART_FFULL;
 | 
			
		||||
 | 
			
		||||
    mcf_uart_update(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_uart_event(void *opaque, int event)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s = (mcf_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    switch (event) {
 | 
			
		||||
    case CHR_EVENT_BREAK:
 | 
			
		||||
        s->isr |= MCF_UART_DBINT;
 | 
			
		||||
        mcf_uart_push_byte(s, 0);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int mcf_uart_can_receive(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s = (mcf_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s = (mcf_uart_state *)opaque;
 | 
			
		||||
 | 
			
		||||
    mcf_uart_push_byte(s, buf[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s;
 | 
			
		||||
 | 
			
		||||
    s = qemu_mallocz(sizeof(mcf_uart_state));
 | 
			
		||||
    s->chr = chr;
 | 
			
		||||
    s->irq = irq;
 | 
			
		||||
    if (chr) {
 | 
			
		||||
        qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
 | 
			
		||||
                              mcf_uart_event, s);
 | 
			
		||||
    }
 | 
			
		||||
    mcf_uart_reset(s);
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static CPUReadMemoryFunc *mcf_uart_readfn[] = {
 | 
			
		||||
   mcf_uart_read,
 | 
			
		||||
   mcf_uart_read,
 | 
			
		||||
   mcf_uart_read
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static CPUWriteMemoryFunc *mcf_uart_writefn[] = {
 | 
			
		||||
   mcf_uart_write,
 | 
			
		||||
   mcf_uart_write,
 | 
			
		||||
   mcf_uart_write
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void mcf_uart_mm_init(target_phys_addr_t base, qemu_irq irq,
 | 
			
		||||
                      CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
    mcf_uart_state *s;
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    s = mcf_uart_init(irq, chr);
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, mcf_uart_readfn,
 | 
			
		||||
                                       mcf_uart_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x40, iomemtype);
 | 
			
		||||
}
 | 
			
		||||
@ -59,6 +59,10 @@ typedef struct CPUM68KState {
 | 
			
		||||
    uint32_t pc;
 | 
			
		||||
    uint32_t sr;
 | 
			
		||||
 | 
			
		||||
    /* SSP and USP.  The current_sp is stored in aregs[7], the other here.  */
 | 
			
		||||
    int current_sp;
 | 
			
		||||
    uint32_t sp[2];
 | 
			
		||||
 | 
			
		||||
    /* Condition flags.  */
 | 
			
		||||
    uint32_t cc_op;
 | 
			
		||||
    uint32_t cc_dest;
 | 
			
		||||
@ -92,6 +96,7 @@ typedef struct CPUM68KState {
 | 
			
		||||
    uint32_t vbr;
 | 
			
		||||
    uint32_t mbar;
 | 
			
		||||
    uint32_t rambar0;
 | 
			
		||||
    uint32_t cacr;
 | 
			
		||||
 | 
			
		||||
    uint32_t features;
 | 
			
		||||
 | 
			
		||||
@ -151,6 +156,12 @@ enum {
 | 
			
		||||
#define SR_S  0x2000
 | 
			
		||||
#define SR_T  0x8000
 | 
			
		||||
 | 
			
		||||
#define M68K_SSP    0
 | 
			
		||||
#define M68K_USP    1
 | 
			
		||||
 | 
			
		||||
/* CACR fields are implementation defined, but some bits are common.  */
 | 
			
		||||
#define M68K_CACR_EUSP  0x10
 | 
			
		||||
 | 
			
		||||
#define MACSR_PAV0  0x100
 | 
			
		||||
#define MACSR_OMC   0x080
 | 
			
		||||
#define MACSR_SU    0x040
 | 
			
		||||
@ -167,6 +178,7 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name);
 | 
			
		||||
 | 
			
		||||
void m68k_set_irq_level(CPUM68KState *env, int level, uint8_t vector);
 | 
			
		||||
void m68k_set_macsr(CPUM68KState *env, uint32_t val);
 | 
			
		||||
void m68k_switch_sp(CPUM68KState *env);
 | 
			
		||||
 | 
			
		||||
#define M68K_FPCR_PREC (1 << 6)
 | 
			
		||||
 | 
			
		||||
@ -179,6 +191,7 @@ enum m68k_features {
 | 
			
		||||
    M68K_FEATURE_CF_FPU,
 | 
			
		||||
    M68K_FEATURE_CF_MAC,
 | 
			
		||||
    M68K_FEATURE_CF_EMAC,
 | 
			
		||||
    M68K_FEATURE_USP,
 | 
			
		||||
    M68K_FEATURE_EXT_FULL, /* 68020+ full extension word.  */
 | 
			
		||||
    M68K_FEATURE_WORD_INDEX /* word sized address index registers.  */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@
 | 
			
		||||
 | 
			
		||||
enum m68k_cpuid {
 | 
			
		||||
    M68K_CPUID_M5206,
 | 
			
		||||
    M68K_CPUID_M5208,
 | 
			
		||||
    M68K_CPUID_CFV4E,
 | 
			
		||||
    M68K_CPUID_ANY,
 | 
			
		||||
};
 | 
			
		||||
@ -39,6 +40,7 @@ struct m68k_def_t {
 | 
			
		||||
 | 
			
		||||
static m68k_def_t m68k_cpu_defs[] = {
 | 
			
		||||
    {"m5206", M68K_CPUID_M5206}, 
 | 
			
		||||
    {"m5208", M68K_CPUID_M5208}, 
 | 
			
		||||
    {"cfv4e", M68K_CPUID_CFV4E},
 | 
			
		||||
    {"any", M68K_CPUID_ANY},
 | 
			
		||||
    {NULL, 0}, 
 | 
			
		||||
@ -64,12 +66,18 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
 | 
			
		||||
    case M68K_CPUID_M5206:
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 | 
			
		||||
        break;
 | 
			
		||||
    case M68K_CPUID_M5208:
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_USP);
 | 
			
		||||
        break;
 | 
			
		||||
    case M68K_CPUID_CFV4E:
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_B);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_C);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_FPU);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_USP);
 | 
			
		||||
        break;
 | 
			
		||||
    case M68K_CPUID_ANY:
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
 | 
			
		||||
@ -79,6 +87,7 @@ int cpu_m68k_set_model(CPUM68KState *env, const char * name)
 | 
			
		||||
        /* MAC and EMAC are mututally exclusive, so pick EMAC.
 | 
			
		||||
           It's mostly backwards compatible.  */
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_USP);
 | 
			
		||||
        m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
@ -215,7 +224,11 @@ void helper_movec(CPUM68KState *env, int reg, uint32_t val)
 | 
			
		||||
{
 | 
			
		||||
    switch (reg) {
 | 
			
		||||
    case 0x02: /* CACR */
 | 
			
		||||
        /* Ignored.  */
 | 
			
		||||
        env->cacr = val;
 | 
			
		||||
        m68k_switch_sp(env);
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x04: case 0x05: case 0x06: case 0x07: /* ACR[0-3] */
 | 
			
		||||
        /* TODO: Implement Access Control Registers.  */
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x801: /* VBR */
 | 
			
		||||
        env->vbr = val;
 | 
			
		||||
@ -261,6 +274,17 @@ void m68k_set_macsr(CPUM68KState *env, uint32_t val)
 | 
			
		||||
    env->macsr = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void m68k_switch_sp(CPUM68KState *env)
 | 
			
		||||
{
 | 
			
		||||
    int new_sp;
 | 
			
		||||
 | 
			
		||||
    env->sp[env->current_sp] = env->aregs[7];
 | 
			
		||||
    new_sp = (env->sr & SR_S && env->cacr & M68K_CACR_EUSP)
 | 
			
		||||
             ? M68K_SSP : M68K_USP;
 | 
			
		||||
    env->aregs[7] = env->sp[new_sp];
 | 
			
		||||
    env->current_sp = new_sp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* MMU */
 | 
			
		||||
 | 
			
		||||
/* TODO: This will need fixing once the MMU is implemented.  */
 | 
			
		||||
 | 
			
		||||
@ -478,6 +478,13 @@ OP(fp_result)
 | 
			
		||||
    FORCE_RET();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OP(set_sr)
 | 
			
		||||
{
 | 
			
		||||
    env->sr = get_op(PARAM1);
 | 
			
		||||
    m68k_switch_sp(env);
 | 
			
		||||
    FORCE_RET();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OP(jmp)
 | 
			
		||||
{
 | 
			
		||||
    GOTO_LABEL_PARAM(1);
 | 
			
		||||
 | 
			
		||||
@ -87,6 +87,7 @@ static void do_rte(void)
 | 
			
		||||
    env->pc = ldl_kernel(sp + 4);
 | 
			
		||||
    sp |= (fmt >> 28) & 3;
 | 
			
		||||
    env->sr = fmt & 0xffff;
 | 
			
		||||
    m68k_switch_sp(env);
 | 
			
		||||
    env->aregs[7] = sp + 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -128,9 +129,6 @@ void do_interrupt(int is_hw)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* TODO: Implement USP.  */
 | 
			
		||||
    sp = env->aregs[7];
 | 
			
		||||
 | 
			
		||||
    vector = env->exception_index << 2;
 | 
			
		||||
 | 
			
		||||
    fmt |= 0x40000000;
 | 
			
		||||
@ -138,6 +136,15 @@ void do_interrupt(int is_hw)
 | 
			
		||||
    fmt |= vector << 16;
 | 
			
		||||
    fmt |= env->sr;
 | 
			
		||||
 | 
			
		||||
    env->sr |= SR_S;
 | 
			
		||||
    if (is_hw) {
 | 
			
		||||
        env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
 | 
			
		||||
        env->sr &= ~SR_M;
 | 
			
		||||
    }
 | 
			
		||||
    m68k_switch_sp(env);
 | 
			
		||||
 | 
			
		||||
    sp = env->aregs[7];
 | 
			
		||||
 | 
			
		||||
    /* ??? This could cause MMU faults.  */
 | 
			
		||||
    sp &= ~3;
 | 
			
		||||
    sp -= 4;
 | 
			
		||||
@ -145,11 +152,6 @@ void do_interrupt(int is_hw)
 | 
			
		||||
    sp -= 4;
 | 
			
		||||
    stl_kernel(sp, fmt);
 | 
			
		||||
    env->aregs[7] = sp;
 | 
			
		||||
    env->sr |= SR_S;
 | 
			
		||||
    if (is_hw) {
 | 
			
		||||
        env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT);
 | 
			
		||||
        env->sr &= ~SR_M;
 | 
			
		||||
    }
 | 
			
		||||
    /* Jump to vector.  */
 | 
			
		||||
    env->pc = ldl_kernel(env->vbr + vector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1345,7 +1345,7 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
 | 
			
		||||
    gen_op_logic_cc(gen_im32(val & 0xf));
 | 
			
		||||
    gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));
 | 
			
		||||
    if (!ccr_only) {
 | 
			
		||||
        gen_op_mov32(QREG_SR, gen_im32(val & 0xff00));
 | 
			
		||||
        gen_op_set_sr(gen_im32(val & 0xff00));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1365,7 +1365,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
 | 
			
		||||
        gen_op_and32(src1, src1, gen_im32(1));
 | 
			
		||||
        gen_op_update_xflag_tst(src1);
 | 
			
		||||
        if (!ccr_only) {
 | 
			
		||||
            gen_op_and32(QREG_SR, reg, gen_im32(0xff00));
 | 
			
		||||
            gen_op_set_sr(reg);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    else if ((insn & 0x3f) == 0x3c)
 | 
			
		||||
@ -2797,8 +2797,8 @@ void register_m68k_insns (CPUM68KState *env)
 | 
			
		||||
    INSN(trap,      4e40, fff0, CF_ISA_A);
 | 
			
		||||
    INSN(link,      4e50, fff8, CF_ISA_A);
 | 
			
		||||
    INSN(unlk,      4e58, fff8, CF_ISA_A);
 | 
			
		||||
    INSN(move_to_usp, 4e60, fff8, CF_ISA_B);
 | 
			
		||||
    INSN(move_from_usp, 4e68, fff8, CF_ISA_B);
 | 
			
		||||
    INSN(move_to_usp, 4e60, fff8, USP);
 | 
			
		||||
    INSN(move_from_usp, 4e68, fff8, USP);
 | 
			
		||||
    INSN(nop,       4e71, ffff, CF_ISA_A);
 | 
			
		||||
    INSN(stop,      4e72, ffff, CF_ISA_A);
 | 
			
		||||
    INSN(rte,       4e73, ffff, CF_ISA_A);
 | 
			
		||||
@ -3261,6 +3261,7 @@ void cpu_reset(CPUM68KState *env)
 | 
			
		||||
#if !defined (CONFIG_USER_ONLY)
 | 
			
		||||
    env->sr = 0x2700;
 | 
			
		||||
#endif
 | 
			
		||||
    m68k_switch_sp(env);
 | 
			
		||||
    /* ??? FP regs should be initialized to NaN.  */
 | 
			
		||||
    env->cc_op = CC_OP_FLAGS;
 | 
			
		||||
    /* TODO: We should set PC from the interrupt vector.  */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								vl.c
									
									
									
									
									
								
							@ -6972,6 +6972,7 @@ void register_machines(void)
 | 
			
		||||
#elif defined(TARGET_ALPHA)
 | 
			
		||||
    /* XXX: TODO */
 | 
			
		||||
#elif defined(TARGET_M68K)
 | 
			
		||||
    qemu_register_machine(&mcf5208evb_machine);
 | 
			
		||||
    qemu_register_machine(&an5206_machine);
 | 
			
		||||
#else
 | 
			
		||||
#error unsupported CPU
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								vl.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								vl.h
									
									
									
									
									
								
							@ -1593,12 +1593,25 @@ void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
 | 
			
		||||
 | 
			
		||||
#include "hw/pxa.h"
 | 
			
		||||
 | 
			
		||||
/* mcf_uart.c */
 | 
			
		||||
uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr);
 | 
			
		||||
void mcf_uart_write(void *opaque, target_phys_addr_t addr, uint32_t val);
 | 
			
		||||
void *mcf_uart_init(qemu_irq irq, CharDriverState *chr);
 | 
			
		||||
void mcf_uart_mm_init(target_phys_addr_t base, qemu_irq irq,
 | 
			
		||||
                      CharDriverState *chr);
 | 
			
		||||
 | 
			
		||||
/* mcf_intc.c */
 | 
			
		||||
qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env);
 | 
			
		||||
 | 
			
		||||
/* mcf5206.c */
 | 
			
		||||
qemu_irq *mcf5206_init(uint32_t base, CPUState *env);
 | 
			
		||||
 | 
			
		||||
/* an5206.c */
 | 
			
		||||
extern QEMUMachine an5206_machine;
 | 
			
		||||
 | 
			
		||||
/* mcf5208.c */
 | 
			
		||||
extern QEMUMachine mcf5208evb_machine;
 | 
			
		||||
 | 
			
		||||
#include "gdbstub.h"
 | 
			
		||||
 | 
			
		||||
#endif /* defined(QEMU_TOOL) */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user