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"
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user