diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2011-10-08 15:40:08 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-10-08 15:40:08 +0000 |
commit | 53e621704c9734d68fcae52d89ff00680df53044 (patch) | |
tree | 5d0df45382fd56599ad8bd78eedb9844cfa0282d | |
parent | 211685040f4e579f83a3ed8b3aa7a3f363ad384f (diff) | |
parent | 779277cab4ab748dea3dfc8c8e035c7a40523e1b (diff) |
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
-rw-r--r-- | hw/milkymist-hw.h | 5 | ||||
-rw-r--r-- | hw/milkymist-uart.c | 72 | ||||
-rw-r--r-- | hw/milkymist.c | 14 | ||||
-rw-r--r-- | target-lm32/helper.c | 1 | ||||
-rw-r--r-- | trace-events | 4 |
5 files changed, 75 insertions, 21 deletions
diff --git a/hw/milkymist-hw.h b/hw/milkymist-hw.h index 20de68ecce..9f358a7d69 100644 --- a/hw/milkymist-hw.h +++ b/hw/milkymist-hw.h @@ -5,15 +5,14 @@ #include "qdev-addr.h" static inline DeviceState *milkymist_uart_create(target_phys_addr_t base, - qemu_irq rx_irq, qemu_irq tx_irq) + qemu_irq irq) { DeviceState *dev; dev = qdev_create(NULL, "milkymist-uart"); qdev_init_nofail(dev); 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), 1, tx_irq); + sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq); return dev; } diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c index e8e309de7c..d836462e4b 100644 --- a/hw/milkymist-uart.c +++ b/hw/milkymist-uart.c @@ -30,19 +30,53 @@ enum { R_RXTX = 0, R_DIV, + R_STAT, + R_CTRL, + R_DBG, 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 { SysBusDevice busdev; CharDriverState *chr; - qemu_irq rx_irq; - qemu_irq tx_irq; + qemu_irq irq; uint32_t regs[R_MAX]; }; 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) { MilkymistUartState *s = opaque; @@ -51,7 +85,12 @@ static uint32_t uart_read(void *opaque, target_phys_addr_t addr) addr >>= 2; switch (addr) { case R_RXTX: + r = s->regs[addr]; + break; case R_DIV: + case R_STAT: + case R_CTRL: + case R_DBG: r = s->regs[addr]; break; @@ -79,18 +118,26 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value) if (s->chr) { qemu_chr_fe_write(s->chr, &ch, 1); } - trace_milkymist_uart_pulse_irq_tx(); - qemu_irq_pulse(s->tx_irq); + s->regs[R_STAT] |= STAT_TX_EVT; break; case R_DIV: + case R_CTRL: + case R_DBG: s->regs[addr] = value; break; + case R_STAT: + /* write one to clear bits */ + s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT)); + break; + default: error_report("milkymist_uart: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } + + uart_update_irq(s); } 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; + assert(!(s->regs[R_STAT] & STAT_RX_EVT)); + + s->regs[R_STAT] |= STAT_RX_EVT; 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) { - return 1; + MilkymistUartState *s = opaque; + + return !(s->regs[R_STAT] & STAT_RX_EVT); } 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++) { s->regs[i] = 0; } + + /* THRE is always set */ + s->regs[R_STAT] = STAT_THRE; } 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); int uart_regs; - sysbus_init_irq(dev, &s->rx_irq); - sysbus_init_irq(dev, &s->tx_irq); + sysbus_init_irq(dev, &s->irq); uart_regs = cpu_register_io_memory(uart_read_fn, uart_write_fn, s, DEVICE_NATIVE_ENDIAN); diff --git a/hw/milkymist.c b/hw/milkymist.c index bca0a58d8c..b7a8c1c256 100644 --- a/hw/milkymist.c +++ b/hw/milkymist.c @@ -146,17 +146,17 @@ milkymist_init(ram_addr_t ram_size_not_used, exit(1); } - milkymist_uart_create(0x60000000, irq[0], irq[1]); - milkymist_sysctl_create(0x60001000, irq[2], irq[3], irq[4], + milkymist_uart_create(0x60000000, irq[0]); + milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3], 80000000, 0x10014d31, 0x0000041f, 0x00000001); milkymist_hpdmc_create(0x60002000); milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff); milkymist_memcard_create(0x60004000); - milkymist_ac97_create(0x60005000, irq[5], irq[6], irq[7], irq[8]); - milkymist_pfpu_create(0x60006000, irq[9]); - milkymist_tmu2_create(0x60007000, irq[10]); - milkymist_minimac2_create(0x60008000, 0x30000000, irq[11], irq[12]); - milkymist_softusb_create(0x6000f000, irq[17], + milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]); + milkymist_pfpu_create(0x60006000, irq[8]); + milkymist_tmu2_create(0x60007000, irq[9]); + milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]); + milkymist_softusb_create(0x6000f000, irq[15], 0x20000000, 0x1000, 0x20020000, 0x2000); /* make sure juart isn't the first chardev */ diff --git a/target-lm32/helper.c b/target-lm32/helper.c index 014fd8de06..fc0b444d81 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -218,6 +218,7 @@ CPUState *cpu_lm32_init(const char *cpu_model) cpu_exec_init(env); cpu_reset(env); + qemu_init_vcpu(env); if (!tcg_initialized) { tcg_initialized = 1; diff --git a/trace-events b/trace-events index 9528c04fed..63d8c8ed75 100644 --- a/trace-events +++ b/trace-events @@ -445,8 +445,8 @@ milkymist_tmu2_pulse_irq(void) "Pulse IRQ" # hw/milkymist-uart.c 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_pulse_irq_rx(void) "Pulse IRQ RX" -milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX" +milkymist_uart_raise_irq(void) "Raise IRQ" +milkymist_uart_lower_irq(void) "Lower IRQ" # hw/milkymist-vgafb.c milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x" |