Merge branch 'for-upstream' of git://git.serverraum.org/git/mw/qemu-lm32
* 'for-upstream' of git://git.serverraum.org/git/mw/qemu-lm32: milkymist: new interrupt map milkymist_uart: support new core version lm32: add missing qemu_init_vcpu() call
This commit is contained in:
		
						commit
						53e621704c
					
				@ -5,15 +5,14 @@
 | 
				
			|||||||
#include "qdev-addr.h"
 | 
					#include "qdev-addr.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline DeviceState *milkymist_uart_create(target_phys_addr_t base,
 | 
					static inline DeviceState *milkymist_uart_create(target_phys_addr_t base,
 | 
				
			||||||
        qemu_irq rx_irq, qemu_irq tx_irq)
 | 
					        qemu_irq irq)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DeviceState *dev;
 | 
					    DeviceState *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dev = qdev_create(NULL, "milkymist-uart");
 | 
					    dev = qdev_create(NULL, "milkymist-uart");
 | 
				
			||||||
    qdev_init_nofail(dev);
 | 
					    qdev_init_nofail(dev);
 | 
				
			||||||
    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
 | 
					    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
 | 
				
			||||||
    sysbus_connect_irq(sysbus_from_qdev(dev), 0, rx_irq);
 | 
					    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
 | 
				
			||||||
    sysbus_connect_irq(sysbus_from_qdev(dev), 1, tx_irq);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return dev;
 | 
					    return dev;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -30,19 +30,53 @@
 | 
				
			|||||||
enum {
 | 
					enum {
 | 
				
			||||||
    R_RXTX = 0,
 | 
					    R_RXTX = 0,
 | 
				
			||||||
    R_DIV,
 | 
					    R_DIV,
 | 
				
			||||||
 | 
					    R_STAT,
 | 
				
			||||||
 | 
					    R_CTRL,
 | 
				
			||||||
 | 
					    R_DBG,
 | 
				
			||||||
    R_MAX
 | 
					    R_MAX
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    STAT_THRE   = (1<<0),
 | 
				
			||||||
 | 
					    STAT_RX_EVT = (1<<1),
 | 
				
			||||||
 | 
					    STAT_TX_EVT = (1<<2),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    CTRL_RX_IRQ_EN = (1<<0),
 | 
				
			||||||
 | 
					    CTRL_TX_IRQ_EN = (1<<1),
 | 
				
			||||||
 | 
					    CTRL_THRU_EN   = (1<<2),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    DBG_BREAK_EN = (1<<0),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct MilkymistUartState {
 | 
					struct MilkymistUartState {
 | 
				
			||||||
    SysBusDevice busdev;
 | 
					    SysBusDevice busdev;
 | 
				
			||||||
    CharDriverState *chr;
 | 
					    CharDriverState *chr;
 | 
				
			||||||
    qemu_irq rx_irq;
 | 
					    qemu_irq irq;
 | 
				
			||||||
    qemu_irq tx_irq;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t regs[R_MAX];
 | 
					    uint32_t regs[R_MAX];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
typedef struct MilkymistUartState MilkymistUartState;
 | 
					typedef struct MilkymistUartState MilkymistUartState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void uart_update_irq(MilkymistUartState *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int rx_event = s->regs[R_STAT] & STAT_RX_EVT;
 | 
				
			||||||
 | 
					    int tx_event = s->regs[R_STAT] & STAT_TX_EVT;
 | 
				
			||||||
 | 
					    int rx_irq_en = s->regs[R_CTRL] & CTRL_RX_IRQ_EN;
 | 
				
			||||||
 | 
					    int tx_irq_en = s->regs[R_CTRL] & CTRL_TX_IRQ_EN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((rx_irq_en && rx_event) || (tx_irq_en && tx_event)) {
 | 
				
			||||||
 | 
					        trace_milkymist_uart_raise_irq();
 | 
				
			||||||
 | 
					        qemu_irq_raise(s->irq);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        trace_milkymist_uart_lower_irq();
 | 
				
			||||||
 | 
					        qemu_irq_lower(s->irq);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t uart_read(void *opaque, target_phys_addr_t addr)
 | 
					static uint32_t uart_read(void *opaque, target_phys_addr_t addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    MilkymistUartState *s = opaque;
 | 
					    MilkymistUartState *s = opaque;
 | 
				
			||||||
@ -51,7 +85,12 @@ static uint32_t uart_read(void *opaque, target_phys_addr_t addr)
 | 
				
			|||||||
    addr >>= 2;
 | 
					    addr >>= 2;
 | 
				
			||||||
    switch (addr) {
 | 
					    switch (addr) {
 | 
				
			||||||
    case R_RXTX:
 | 
					    case R_RXTX:
 | 
				
			||||||
 | 
					        r = s->regs[addr];
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
    case R_DIV:
 | 
					    case R_DIV:
 | 
				
			||||||
 | 
					    case R_STAT:
 | 
				
			||||||
 | 
					    case R_CTRL:
 | 
				
			||||||
 | 
					    case R_DBG:
 | 
				
			||||||
        r = s->regs[addr];
 | 
					        r = s->regs[addr];
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,18 +118,26 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 | 
				
			|||||||
        if (s->chr) {
 | 
					        if (s->chr) {
 | 
				
			||||||
            qemu_chr_fe_write(s->chr, &ch, 1);
 | 
					            qemu_chr_fe_write(s->chr, &ch, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        trace_milkymist_uart_pulse_irq_tx();
 | 
					        s->regs[R_STAT] |= STAT_TX_EVT;
 | 
				
			||||||
        qemu_irq_pulse(s->tx_irq);
 | 
					 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case R_DIV:
 | 
					    case R_DIV:
 | 
				
			||||||
 | 
					    case R_CTRL:
 | 
				
			||||||
 | 
					    case R_DBG:
 | 
				
			||||||
        s->regs[addr] = value;
 | 
					        s->regs[addr] = value;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case R_STAT:
 | 
				
			||||||
 | 
					        /* write one to clear bits */
 | 
				
			||||||
 | 
					        s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT));
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        error_report("milkymist_uart: write access to unknown register 0x"
 | 
					        error_report("milkymist_uart: write access to unknown register 0x"
 | 
				
			||||||
                TARGET_FMT_plx, addr << 2);
 | 
					                TARGET_FMT_plx, addr << 2);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uart_update_irq(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static CPUReadMemoryFunc * const uart_read_fn[] = {
 | 
					static CPUReadMemoryFunc * const uart_read_fn[] = {
 | 
				
			||||||
@ -109,14 +156,19 @@ static void uart_rx(void *opaque, const uint8_t *buf, int size)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    MilkymistUartState *s = opaque;
 | 
					    MilkymistUartState *s = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(!(s->regs[R_STAT] & STAT_RX_EVT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s->regs[R_STAT] |= STAT_RX_EVT;
 | 
				
			||||||
    s->regs[R_RXTX] = *buf;
 | 
					    s->regs[R_RXTX] = *buf;
 | 
				
			||||||
    trace_milkymist_uart_pulse_irq_rx();
 | 
					
 | 
				
			||||||
    qemu_irq_pulse(s->rx_irq);
 | 
					    uart_update_irq(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int uart_can_rx(void *opaque)
 | 
					static int uart_can_rx(void *opaque)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return 1;
 | 
					    MilkymistUartState *s = opaque;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return !(s->regs[R_STAT] & STAT_RX_EVT);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void uart_event(void *opaque, int event)
 | 
					static void uart_event(void *opaque, int event)
 | 
				
			||||||
@ -131,6 +183,9 @@ static void milkymist_uart_reset(DeviceState *d)
 | 
				
			|||||||
    for (i = 0; i < R_MAX; i++) {
 | 
					    for (i = 0; i < R_MAX; i++) {
 | 
				
			||||||
        s->regs[i] = 0;
 | 
					        s->regs[i] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* THRE is always set */
 | 
				
			||||||
 | 
					    s->regs[R_STAT] = STAT_THRE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int milkymist_uart_init(SysBusDevice *dev)
 | 
					static int milkymist_uart_init(SysBusDevice *dev)
 | 
				
			||||||
@ -138,8 +193,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
 | 
				
			|||||||
    MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
 | 
					    MilkymistUartState *s = FROM_SYSBUS(typeof(*s), dev);
 | 
				
			||||||
    int uart_regs;
 | 
					    int uart_regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sysbus_init_irq(dev, &s->rx_irq);
 | 
					    sysbus_init_irq(dev, &s->irq);
 | 
				
			||||||
    sysbus_init_irq(dev, &s->tx_irq);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uart_regs = cpu_register_io_memory(uart_read_fn, uart_write_fn, s,
 | 
					    uart_regs = cpu_register_io_memory(uart_read_fn, uart_write_fn, s,
 | 
				
			||||||
            DEVICE_NATIVE_ENDIAN);
 | 
					            DEVICE_NATIVE_ENDIAN);
 | 
				
			||||||
 | 
				
			|||||||
@ -146,17 +146,17 @@ milkymist_init(ram_addr_t ram_size_not_used,
 | 
				
			|||||||
        exit(1);
 | 
					        exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    milkymist_uart_create(0x60000000, irq[0], irq[1]);
 | 
					    milkymist_uart_create(0x60000000, irq[0]);
 | 
				
			||||||
    milkymist_sysctl_create(0x60001000, irq[2], irq[3], irq[4],
 | 
					    milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
 | 
				
			||||||
            80000000, 0x10014d31, 0x0000041f, 0x00000001);
 | 
					            80000000, 0x10014d31, 0x0000041f, 0x00000001);
 | 
				
			||||||
    milkymist_hpdmc_create(0x60002000);
 | 
					    milkymist_hpdmc_create(0x60002000);
 | 
				
			||||||
    milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
 | 
					    milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
 | 
				
			||||||
    milkymist_memcard_create(0x60004000);
 | 
					    milkymist_memcard_create(0x60004000);
 | 
				
			||||||
    milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]);
 | 
					    milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]);
 | 
				
			||||||
    milkymist_pfpu_create(0x60006000, irq[9]);
 | 
					    milkymist_pfpu_create(0x60006000, irq[8]);
 | 
				
			||||||
    milkymist_tmu2_create(0x60007000, irq[10]);
 | 
					    milkymist_tmu2_create(0x60007000, irq[9]);
 | 
				
			||||||
    milkymist_minimac2_create(0x60008000, 0x30000000, irq[11], irq[12]);
 | 
					    milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]);
 | 
				
			||||||
    milkymist_softusb_create(0x6000f000, irq[17],
 | 
					    milkymist_softusb_create(0x6000f000, irq[15],
 | 
				
			||||||
            0x20000000, 0x1000, 0x20020000, 0x2000);
 | 
					            0x20000000, 0x1000, 0x20020000, 0x2000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* make sure juart isn't the first chardev */
 | 
					    /* make sure juart isn't the first chardev */
 | 
				
			||||||
 | 
				
			|||||||
@ -218,6 +218,7 @@ CPUState *cpu_lm32_init(const char *cpu_model)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cpu_exec_init(env);
 | 
					    cpu_exec_init(env);
 | 
				
			||||||
    cpu_reset(env);
 | 
					    cpu_reset(env);
 | 
				
			||||||
 | 
					    qemu_init_vcpu(env);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!tcg_initialized) {
 | 
					    if (!tcg_initialized) {
 | 
				
			||||||
        tcg_initialized = 1;
 | 
					        tcg_initialized = 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -445,8 +445,8 @@ milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
 | 
				
			|||||||
# hw/milkymist-uart.c
 | 
					# hw/milkymist-uart.c
 | 
				
			||||||
milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
					milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
				
			||||||
milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
					milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
				
			||||||
milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
 | 
					milkymist_uart_raise_irq(void) "Raise IRQ"
 | 
				
			||||||
milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
 | 
					milkymist_uart_lower_irq(void) "Lower IRQ"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# hw/milkymist-vgafb.c
 | 
					# hw/milkymist-vgafb.c
 | 
				
			||||||
milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
					milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user