diff options
author | Markus Armbruster <armbru@redhat.com> | 2021-05-03 10:40:33 +0200 |
---|---|---|
committer | Markus Armbruster <armbru@redhat.com> | 2021-05-12 18:20:25 +0200 |
commit | 9d49bcf6992a2ba77f79d2512e23b8ca26d72f6a (patch) | |
tree | 0d3adfe1d417577ef0c78894d47a4956f318cb2f /hw | |
parent | 09ec85176e4095be15f233ebc870d5680123f024 (diff) |
Drop the deprecated lm32 target
Target lm32 was deprecated in commit d8498005122, v5.2.0. See there
for rationale.
Some of its code lives on in device models derived from milkymist
ones: hw/char/digic-uart.c and hw/display/bcm2835_fb.c.
Cc: Michael Walle <michael@walle.cc>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210503084034.3804963-2-armbru@redhat.com>
Acked-by: Michael Walle <michael@walle.cc>
[Trivial conflicts resolved, reST markup fixed]
Diffstat (limited to 'hw')
45 files changed, 0 insertions, 5898 deletions
diff --git a/hw/Kconfig b/hw/Kconfig index 559b7636f4..10a48d1492 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -47,7 +47,6 @@ source avr/Kconfig source cris/Kconfig source hppa/Kconfig source i386/Kconfig -source lm32/Kconfig source m68k/Kconfig source microblaze/Kconfig source mips/Kconfig diff --git a/hw/audio/meson.build b/hw/audio/meson.build index 32c42bdebe..e48a9fc73d 100644 --- a/hw/audio/meson.build +++ b/hw/audio/meson.build @@ -7,7 +7,6 @@ softmmu_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c')) softmmu_ss.add(when: 'CONFIG_GUS', if_true: files('gus.c', 'gusemu_hal.c', 'gusemu_mixer.c')) softmmu_ss.add(when: 'CONFIG_HDA', if_true: files('intel-hda.c', 'hda-codec.c')) softmmu_ss.add(when: 'CONFIG_MARVELL_88W8618', if_true: files('marvell_88w8618.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-ac97.c')) softmmu_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c')) softmmu_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c')) softmmu_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c')) diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c deleted file mode 100644 index 7d2e057038..0000000000 --- a/hw/audio/milkymist-ac97.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * QEMU model of the Milkymist System Controller. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/ac97.pdf - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "audio/audio.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -enum { - R_AC97_CTRL = 0, - R_AC97_ADDR, - R_AC97_DATAOUT, - R_AC97_DATAIN, - R_D_CTRL, - R_D_ADDR, - R_D_REMAINING, - R_RESERVED, - R_U_CTRL, - R_U_ADDR, - R_U_REMAINING, - R_MAX -}; - -enum { - AC97_CTRL_RQEN = (1<<0), - AC97_CTRL_WRITE = (1<<1), -}; - -enum { - CTRL_EN = (1<<0), -}; - -#define TYPE_MILKYMIST_AC97 "milkymist-ac97" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistAC97State, MILKYMIST_AC97) - -struct MilkymistAC97State { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - - QEMUSoundCard card; - SWVoiceIn *voice_in; - SWVoiceOut *voice_out; - - uint32_t regs[R_MAX]; - - qemu_irq crrequest_irq; - qemu_irq crreply_irq; - qemu_irq dmar_irq; - qemu_irq dmaw_irq; -}; - -static void update_voices(MilkymistAC97State *s) -{ - if (s->regs[R_D_CTRL] & CTRL_EN) { - AUD_set_active_out(s->voice_out, 1); - } else { - AUD_set_active_out(s->voice_out, 0); - } - - if (s->regs[R_U_CTRL] & CTRL_EN) { - AUD_set_active_in(s->voice_in, 1); - } else { - AUD_set_active_in(s->voice_in, 0); - } -} - -static uint64_t ac97_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistAC97State *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_AC97_CTRL: - case R_AC97_ADDR: - case R_AC97_DATAOUT: - case R_AC97_DATAIN: - case R_D_CTRL: - case R_D_ADDR: - case R_D_REMAINING: - case R_U_CTRL: - case R_U_ADDR: - case R_U_REMAINING: - r = s->regs[addr]; - break; - - default: - error_report("milkymist_ac97: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_ac97_memory_read(addr << 2, r); - - return r; -} - -static void ac97_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistAC97State *s = opaque; - - trace_milkymist_ac97_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_AC97_CTRL: - /* always raise an IRQ according to the direction */ - if (value & AC97_CTRL_RQEN) { - if (value & AC97_CTRL_WRITE) { - trace_milkymist_ac97_pulse_irq_crrequest(); - qemu_irq_pulse(s->crrequest_irq); - } else { - trace_milkymist_ac97_pulse_irq_crreply(); - qemu_irq_pulse(s->crreply_irq); - } - } - - /* RQEN is self clearing */ - s->regs[addr] = value & ~AC97_CTRL_RQEN; - break; - case R_D_CTRL: - case R_U_CTRL: - s->regs[addr] = value; - update_voices(s); - break; - case R_AC97_ADDR: - case R_AC97_DATAOUT: - case R_AC97_DATAIN: - case R_D_ADDR: - case R_D_REMAINING: - case R_U_ADDR: - case R_U_REMAINING: - s->regs[addr] = value; - break; - - default: - error_report("milkymist_ac97: write access to unknown register 0x" - TARGET_FMT_plx, addr); - break; - } - -} - -static const MemoryRegionOps ac97_mmio_ops = { - .read = ac97_read, - .write = ac97_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void ac97_in_cb(void *opaque, int avail_b) -{ - MilkymistAC97State *s = opaque; - uint8_t buf[4096]; - uint32_t remaining = s->regs[R_U_REMAINING]; - int temp = MIN(remaining, avail_b); - uint32_t addr = s->regs[R_U_ADDR]; - int transferred = 0; - - trace_milkymist_ac97_in_cb(avail_b, remaining); - - /* prevent from raising an IRQ */ - if (temp == 0) { - return; - } - - while (temp) { - int acquired, to_copy; - - to_copy = MIN(temp, sizeof(buf)); - acquired = AUD_read(s->voice_in, buf, to_copy); - if (!acquired) { - break; - } - - cpu_physical_memory_write(addr, buf, acquired); - - temp -= acquired; - addr += acquired; - transferred += acquired; - } - - trace_milkymist_ac97_in_cb_transferred(transferred); - - s->regs[R_U_ADDR] = addr; - s->regs[R_U_REMAINING] -= transferred; - - if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) { - trace_milkymist_ac97_pulse_irq_dmaw(); - qemu_irq_pulse(s->dmaw_irq); - } -} - -static void ac97_out_cb(void *opaque, int free_b) -{ - MilkymistAC97State *s = opaque; - uint8_t buf[4096]; - uint32_t remaining = s->regs[R_D_REMAINING]; - int temp = MIN(remaining, free_b); - uint32_t addr = s->regs[R_D_ADDR]; - int transferred = 0; - - trace_milkymist_ac97_out_cb(free_b, remaining); - - /* prevent from raising an IRQ */ - if (temp == 0) { - return; - } - - while (temp) { - int copied, to_copy; - - to_copy = MIN(temp, sizeof(buf)); - cpu_physical_memory_read(addr, buf, to_copy); - copied = AUD_write(s->voice_out, buf, to_copy); - if (!copied) { - break; - } - temp -= copied; - addr += copied; - transferred += copied; - } - - trace_milkymist_ac97_out_cb_transferred(transferred); - - s->regs[R_D_ADDR] = addr; - s->regs[R_D_REMAINING] -= transferred; - - if ((s->regs[R_D_CTRL] & CTRL_EN) && (s->regs[R_D_REMAINING] == 0)) { - trace_milkymist_ac97_pulse_irq_dmar(); - qemu_irq_pulse(s->dmar_irq); - } -} - -static void milkymist_ac97_reset(DeviceState *d) -{ - MilkymistAC97State *s = MILKYMIST_AC97(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - AUD_set_active_in(s->voice_in, 0); - AUD_set_active_out(s->voice_out, 0); -} - -static int ac97_post_load(void *opaque, int version_id) -{ - MilkymistAC97State *s = opaque; - - update_voices(s); - - return 0; -} - -static void milkymist_ac97_init(Object *obj) -{ - MilkymistAC97State *s = MILKYMIST_AC97(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - sysbus_init_irq(dev, &s->crrequest_irq); - sysbus_init_irq(dev, &s->crreply_irq); - sysbus_init_irq(dev, &s->dmar_irq); - sysbus_init_irq(dev, &s->dmaw_irq); - - memory_region_init_io(&s->regs_region, obj, &ac97_mmio_ops, s, - "milkymist-ac97", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); -} - -static void milkymist_ac97_realize(DeviceState *dev, Error **errp) -{ - MilkymistAC97State *s = MILKYMIST_AC97(dev); - struct audsettings as; - - AUD_register_card("Milkymist AC'97", &s->card); - - as.freq = 48000; - as.nchannels = 2; - as.fmt = AUDIO_FORMAT_S16; - as.endianness = 1; - - s->voice_in = AUD_open_in(&s->card, s->voice_in, - "mm_ac97.in", s, ac97_in_cb, &as); - s->voice_out = AUD_open_out(&s->card, s->voice_out, - "mm_ac97.out", s, ac97_out_cb, &as); -} - -static const VMStateDescription vmstate_milkymist_ac97 = { - .name = "milkymist-ac97", - .version_id = 1, - .minimum_version_id = 1, - .post_load = ac97_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_ac97_properties[] = { - DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_ac97_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_ac97_realize; - dc->reset = milkymist_ac97_reset; - dc->vmsd = &vmstate_milkymist_ac97; - device_class_set_props(dc, milkymist_ac97_properties); -} - -static const TypeInfo milkymist_ac97_info = { - .name = TYPE_MILKYMIST_AC97, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistAC97State), - .instance_init = milkymist_ac97_init, - .class_init = milkymist_ac97_class_init, -}; - -static void milkymist_ac97_register_types(void) -{ - type_register_static(&milkymist_ac97_info); -} - -type_init(milkymist_ac97_register_types) diff --git a/hw/audio/trace-events b/hw/audio/trace-events index 60556b4a97..432e10712f 100644 --- a/hw/audio/trace-events +++ b/hw/audio/trace-events @@ -6,18 +6,6 @@ cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x" cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x" cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x" -# milkymist-ac97.c -milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request" -milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply" -milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write" -milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read" -milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u" -milkymist_ac97_in_cb_transferred(int transferred) "transferred %d" -milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u" -milkymist_ac97_out_cb_transferred(int transferred) "transferred %d" - # hda-codec.c hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run %d" hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st %s, %d x %s @ %d Hz" diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c deleted file mode 100644 index ce30279650..0000000000 --- a/hw/char/lm32_juart.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * LatticeMico32 JTAG UART model. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "qemu/module.h" -#include "trace.h" -#include "chardev/char-fe.h" - -#include "hw/char/lm32_juart.h" -#include "hw/qdev-properties.h" -#include "hw/qdev-properties-system.h" -#include "qom/object.h" - -enum { - LM32_JUART_MIN_SAVE_VERSION = 0, - LM32_JUART_CURRENT_SAVE_VERSION = 0, - LM32_JUART_MAX_SAVE_VERSION = 0, -}; - -enum { - JTX_FULL = (1<<8), -}; - -enum { - JRX_FULL = (1<<8), -}; - -OBJECT_DECLARE_SIMPLE_TYPE(LM32JuartState, LM32_JUART) - -struct LM32JuartState { - SysBusDevice parent_obj; - - CharBackend chr; - - uint32_t jtx; - uint32_t jrx; -}; - -uint32_t lm32_juart_get_jtx(DeviceState *d) -{ - LM32JuartState *s = LM32_JUART(d); - - trace_lm32_juart_get_jtx(s->jtx); - return s->jtx; -} - -uint32_t lm32_juart_get_jrx(DeviceState *d) -{ - LM32JuartState *s = LM32_JUART(d); - - trace_lm32_juart_get_jrx(s->jrx); - return s->jrx; -} - -void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx) -{ - LM32JuartState *s = LM32_JUART(d); - unsigned char ch = jtx & 0xff; - - trace_lm32_juart_set_jtx(s->jtx); - - s->jtx = jtx; - /* XXX this blocks entire thread. Rewrite to use - * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(&s->chr, &ch, 1); -} - -void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx) -{ - LM32JuartState *s = LM32_JUART(d); - - trace_lm32_juart_set_jrx(s->jrx); - s->jrx &= ~JRX_FULL; -} - -static void juart_rx(void *opaque, const uint8_t *buf, int size) -{ - LM32JuartState *s = opaque; - - s->jrx = *buf | JRX_FULL; -} - -static int juart_can_rx(void *opaque) -{ - LM32JuartState *s = opaque; - - return !(s->jrx & JRX_FULL); -} - -static void juart_event(void *opaque, QEMUChrEvent event) -{ -} - -static void juart_reset(DeviceState *d) -{ - LM32JuartState *s = LM32_JUART(d); - - s->jtx = 0; - s->jrx = 0; -} - -static void lm32_juart_realize(DeviceState *dev, Error **errp) -{ - LM32JuartState *s = LM32_JUART(dev); - - qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx, - juart_event, NULL, s, NULL, true); -} - -static const VMStateDescription vmstate_lm32_juart = { - .name = "lm32-juart", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32(jtx, LM32JuartState), - VMSTATE_UINT32(jrx, LM32JuartState), - VMSTATE_END_OF_LIST() - } -}; - -static Property lm32_juart_properties[] = { - DEFINE_PROP_CHR("chardev", LM32JuartState, chr), - DEFINE_PROP_END_OF_LIST(), -}; - -static void lm32_juart_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->reset = juart_reset; - dc->vmsd = &vmstate_lm32_juart; - device_class_set_props(dc, lm32_juart_properties); - dc->realize = lm32_juart_realize; -} - -static const TypeInfo lm32_juart_info = { - .name = TYPE_LM32_JUART, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(LM32JuartState), - .class_init = lm32_juart_class_init, -}; - -static void lm32_juart_register_types(void) -{ - type_register_static(&lm32_juart_info); -} - -type_init(lm32_juart_register_types) diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c deleted file mode 100644 index d8e0331311..0000000000 --- a/hw/char/lm32_uart.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * QEMU model of the LatticeMico32 UART block. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://www.latticesemi.com/documents/mico32uart.pdf - */ - - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/qdev-properties.h" -#include "hw/qdev-properties-system.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "chardev/char-fe.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -enum { - R_RXTX = 0, - R_IER, - R_IIR, - R_LCR, - R_MCR, - R_LSR, - R_MSR, - R_DIV, - R_MAX -}; - -enum { - IER_RBRI = (1<<0), - IER_THRI = (1<<1), - IER_RLSI = (1<<2), - IER_MSI = (1<<3), -}; - -enum { - IIR_STAT = (1<<0), - IIR_ID0 = (1<<1), - IIR_ID1 = (1<<2), -}; - -enum { - LCR_WLS0 = (1<<0), - LCR_WLS1 = (1<<1), - LCR_STB = (1<<2), - LCR_PEN = (1<<3), - LCR_EPS = (1<<4), - LCR_SP = (1<<5), - LCR_SB = (1<<6), -}; - -enum { - MCR_DTR = (1<<0), - MCR_RTS = (1<<1), -}; - -enum { - LSR_DR = (1<<0), - LSR_OE = (1<<1), - LSR_PE = (1<<2), - LSR_FE = (1<<3), - LSR_BI = (1<<4), - LSR_THRE = (1<<5), - LSR_TEMT = (1<<6), -}; - -enum { - MSR_DCTS = (1<<0), - MSR_DDSR = (1<<1), - MSR_TERI = (1<<2), - MSR_DDCD = (1<<3), - MSR_CTS = (1<<4), - MSR_DSR = (1<<5), - MSR_RI = (1<<6), - MSR_DCD = (1<<7), -}; - -#define TYPE_LM32_UART "lm32-uart" -OBJECT_DECLARE_SIMPLE_TYPE(LM32UartState, LM32_UART) - -struct LM32UartState { - SysBusDevice parent_obj; - - MemoryRegion iomem; - CharBackend chr; - qemu_irq irq; - - uint32_t regs[R_MAX]; -}; - -static void uart_update_irq(LM32UartState *s) -{ - unsigned int irq; - - if ((s->regs[R_LSR] & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) - && (s->regs[R_IER] & IER_RLSI)) { - irq = 1; - s->regs[R_IIR] = IIR_ID1 | IIR_ID0; - } else if ((s->regs[R_LSR] & LSR_DR) && (s->regs[R_IER] & IER_RBRI)) { - irq = 1; - s->regs[R_IIR] = IIR_ID1; - } else if ((s->regs[R_LSR] & LSR_THRE) && (s->regs[R_IER] & IER_THRI)) { - irq = 1; - s->regs[R_IIR] = IIR_ID0; - } else if ((s->regs[R_MSR] & 0x0f) && (s->regs[R_IER] & IER_MSI)) { - irq = 1; - s->regs[R_IIR] = 0; - } else { - irq = 0; - s->regs[R_IIR] = IIR_STAT; - } - - trace_lm32_uart_irq_state(irq); - qemu_set_irq(s->irq, irq); -} - -static uint64_t uart_read(void *opaque, hwaddr addr, - unsigned size) -{ - LM32UartState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_RXTX: - r = s->regs[R_RXTX]; - s->regs[R_LSR] &= ~LSR_DR; - uart_update_irq(s); - qemu_chr_fe_accept_input(&s->chr); - break; - case R_IIR: - case R_LSR: - case R_MSR: - r = s->regs[addr]; - break; - case R_IER: - case R_LCR: - case R_MCR: - case R_DIV: - error_report("lm32_uart: read access to write only register 0x" - TARGET_FMT_plx, addr << 2); - break; - default: - error_report("lm32_uart: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_lm32_uart_memory_read(addr << 2, r); - return r; -} - -static void uart_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - LM32UartState *s = opaque; - unsigned char ch = value; - - trace_lm32_uart_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_RXTX: - /* XXX this blocks entire thread. Rewrite to use - * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(&s->chr, &ch, 1); - break; - case R_IER: - case R_LCR: - case R_MCR: - case R_DIV: - s->regs[addr] = value; - break; - case R_IIR: - case R_LSR: - case R_MSR: - error_report("lm32_uart: write access to read only register 0x" - TARGET_FMT_plx, addr << 2); - break; - default: - error_report("lm32_uart: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - uart_update_irq(s); -} - -static const MemoryRegionOps uart_ops = { - .read = uart_read, - .write = uart_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, -}; - -static void uart_rx(void *opaque, const uint8_t *buf, int size) -{ - LM32UartState *s = opaque; - - if (s->regs[R_LSR] & LSR_DR) { - s->regs[R_LSR] |= LSR_OE; - } - - s->regs[R_LSR] |= LSR_DR; - s->regs[R_RXTX] = *buf; - - uart_update_irq(s); -} - -static int uart_can_rx(void *opaque) -{ - LM32UartState *s = opaque; - - return !(s->regs[R_LSR] & LSR_DR); -} - -static void uart_event(void *opaque, QEMUChrEvent event) -{ -} - -static void uart_reset(DeviceState *d) -{ - LM32UartState *s = LM32_UART(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - /* defaults */ - s->regs[R_LSR] = LSR_THRE | LSR_TEMT; -} - -static void lm32_uart_init(Object *obj) -{ - LM32UartState *s = LM32_UART(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - sysbus_init_irq(dev, &s->irq); - - memory_region_init_io(&s->iomem, obj, &uart_ops, s, - "uart", R_MAX * 4); - sysbus_init_mmio(dev, &s->iomem); -} - -static void lm32_uart_realize(DeviceState *dev, Error **errp) -{ - LM32UartState *s = LM32_UART(dev); - - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, NULL, s, NULL, true); -} - -static const VMStateDescription vmstate_lm32_uart = { - .name = "lm32-uart", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, LM32UartState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static Property lm32_uart_properties[] = { - DEFINE_PROP_CHR("chardev", LM32UartState, chr), - DEFINE_PROP_END_OF_LIST(), -}; - -static void lm32_uart_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->reset = uart_reset; - dc->vmsd = &vmstate_lm32_uart; - device_class_set_props(dc, lm32_uart_properties); - dc->realize = lm32_uart_realize; -} - -static const TypeInfo lm32_uart_info = { - .name = TYPE_LM32_UART, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(LM32UartState), - .instance_init = lm32_uart_init, - .class_init = lm32_uart_class_init, -}; - -static void lm32_uart_register_types(void) -{ - type_register_static(&lm32_uart_info); -} - -type_init(lm32_uart_register_types) diff --git a/hw/char/meson.build b/hw/char/meson.build index da5bb8b762..31bf506398 100644 --- a/hw/char/meson.build +++ b/hw/char/meson.build @@ -8,9 +8,6 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_serial.c')) softmmu_ss.add(when: 'CONFIG_IPACK', if_true: files('ipoctal232.c')) softmmu_ss.add(when: 'CONFIG_ISA_BUS', if_true: files('parallel-isa.c')) softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugcon.c')) -softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_juart.c')) -softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_uart.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-uart.c')) softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_uart.c')) softmmu_ss.add(when: 'CONFIG_PARALLEL', if_true: files('parallel.c')) softmmu_ss.add(when: 'CONFIG_PL011', if_true: files('pl011.c')) diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c deleted file mode 100644 index cb1b3470ad..0000000000 --- a/hw/char/milkymist-uart.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * QEMU model of the Milkymist UART block. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/uart.pdf - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/qdev-properties.h" -#include "hw/qdev-properties-system.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "chardev/char-fe.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -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), -}; - -#define TYPE_MILKYMIST_UART "milkymist-uart" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistUartState, MILKYMIST_UART) - -struct MilkymistUartState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - CharBackend chr; - qemu_irq irq; - - uint32_t regs[R_MAX]; -}; - -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 uint64_t uart_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistUartState *s = opaque; - uint32_t r = 0; - - 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; - - default: - error_report("milkymist_uart: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_uart_memory_read(addr << 2, r); - - return r; -} - -static void uart_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistUartState *s = opaque; - unsigned char ch = value; - - trace_milkymist_uart_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_RXTX: - qemu_chr_fe_write_all(&s->chr, &ch, 1); - 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)); - qemu_chr_fe_accept_input(&s->chr); - break; - - default: - error_report("milkymist_uart: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - uart_update_irq(s); -} - -static const MemoryRegionOps uart_mmio_ops = { - .read = uart_read, - .write = uart_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -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; - - uart_update_irq(s); -} - -static int uart_can_rx(void *opaque) -{ - MilkymistUartState *s = opaque; - - return !(s->regs[R_STAT] & STAT_RX_EVT); -} - -static void uart_event(void *opaque, QEMUChrEvent event) -{ -} - -static void milkymist_uart_reset(DeviceState *d) -{ - MilkymistUartState *s = MILKYMIST_UART(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - /* THRE is always set */ - s->regs[R_STAT] = STAT_THRE; -} - -static void milkymist_uart_realize(DeviceState *dev, Error **errp) -{ - MilkymistUartState *s = MILKYMIST_UART(dev); - - qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx, - uart_event, NULL, s, NULL, true); -} - -static void milkymist_uart_init(Object *obj) -{ - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - MilkymistUartState *s = MILKYMIST_UART(obj); - - sysbus_init_irq(sbd, &s->irq); - - memory_region_init_io(&s->regs_region, OBJECT(s), &uart_mmio_ops, s, - "milkymist-uart", R_MAX * 4); - sysbus_init_mmio(sbd, &s->regs_region); -} - -static const VMStateDescription vmstate_milkymist_uart = { - .name = "milkymist-uart", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistUartState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_uart_properties[] = { - DEFINE_PROP_CHR("chardev", MilkymistUartState, chr), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_uart_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_uart_realize; - dc->reset = milkymist_uart_reset; - dc->vmsd = &vmstate_milkymist_uart; - device_class_set_props(dc, milkymist_uart_properties); -} - -static const TypeInfo milkymist_uart_info = { - .name = TYPE_MILKYMIST_UART, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistUartState), - .instance_init = milkymist_uart_init, - .class_init = milkymist_uart_class_init, -}; - -static void milkymist_uart_register_types(void) -{ - type_register_static(&milkymist_uart_info); -} - -type_init(milkymist_uart_register_types) diff --git a/hw/char/trace-events b/hw/char/trace-events index 76d52938ea..76d303b953 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -35,23 +35,6 @@ grlib_apbuart_event(int event) "event:%d" grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x" grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64 -# lm32_juart.c -lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x" -lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x" -lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x" -lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x" - -# lm32_uart.c -lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -lm32_uart_irq_state(int level) "irq state %d" - -# milkymist-uart.c -milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_uart_raise_irq(void) "Raise IRQ" -milkymist_uart_lower_irq(void) "Lower IRQ" - # escc.c escc_put_queue(char channel, int b) "channel %c put: 0x%02x" escc_get_queue(char channel, int val) "channel %c get 0x%02x" diff --git a/hw/display/Kconfig b/hw/display/Kconfig index ca46b5830e..a2306b67d8 100644 --- a/hw/display/Kconfig +++ b/hw/display/Kconfig @@ -72,10 +72,6 @@ config BLIZZARD config FRAMEBUFFER bool -config MILKYMIST_TMU2 - bool - depends on OPENGL && X11 - config SM501 bool select I2C diff --git a/hw/display/meson.build b/hw/display/meson.build index 612cd6582d..aaf797c5e9 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -48,7 +48,6 @@ endif softmmu_ss.add(when: 'CONFIG_DPCD', if_true: files('dpcd.c')) softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dp.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-vgafb.c')) softmmu_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c')) softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c')) @@ -94,7 +93,6 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA') hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss} endif -specific_ss.add(when: [x11, opengl, 'CONFIG_MILKYMIST_TMU2'], if_true: files('milkymist-tmu2.c')) specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c')) modules += { 'hw-display': hw_display_modules } diff --git a/hw/display/milkymist-tmu2.c b/hw/display/milkymist-tmu2.c deleted file mode 100644 index 02a28c807b..0000000000 --- a/hw/display/milkymist-tmu2.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * QEMU model of the Milkymist texture mapping unit. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * Copyright (c) 2010 Sebastien Bourdeauducq - * <sebastien.bourdeauducq@lekernel.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/tmu2.pdf - * - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qapi/error.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qapi/error.h" -#include "hw/display/milkymist_tmu2.h" - -#include <X11/Xlib.h> -#include <epoxy/gl.h> -#include <epoxy/glx.h> -#include "qom/object.h" - -enum { - R_CTL = 0, - R_HMESHLAST, - R_VMESHLAST, - R_BRIGHTNESS, - R_CHROMAKEY, - R_VERTICESADDR, - R_TEXFBUF, - R_TEXHRES, - R_TEXVRES, - R_TEXHMASK, - R_TEXVMASK, - R_DSTFBUF, - R_DSTHRES, - R_DSTVRES, - R_DSTHOFFSET, - R_DSTVOFFSET, - R_DSTSQUAREW, - R_DSTSQUAREH, - R_ALPHA, - R_MAX -}; - -enum { - CTL_START_BUSY = (1<<0), - CTL_CHROMAKEY = (1<<1), -}; - -enum { - MAX_BRIGHTNESS = 63, - MAX_ALPHA = 63, -}; - -enum { - MESH_MAXSIZE = 128, -}; - -struct vertex { - int x; - int y; -} QEMU_PACKED; - -#define TYPE_MILKYMIST_TMU2 "milkymist-tmu2" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistTMU2State, MILKYMIST_TMU2) - -struct MilkymistTMU2State { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - Chardev *chr; - qemu_irq irq; - - uint32_t regs[R_MAX]; - - Display *dpy; - GLXFBConfig glx_fb_config; - GLXContext glx_context; -}; - -static const int glx_fbconfig_attr[] = { - GLX_GREEN_SIZE, 5, - GLX_GREEN_SIZE, 6, - GLX_BLUE_SIZE, 5, - None -}; - -static int tmu2_glx_init(MilkymistTMU2State *s) -{ - GLXFBConfig *configs; - int nelements; - - s->dpy = XOpenDisplay(NULL); /* FIXME: call XCloseDisplay() */ - if (s->dpy == NULL) { - return 1; - } - - configs = glXChooseFBConfig(s->dpy, 0, glx_fbconfig_attr, &nelements); - if (configs == NULL) { - return 1; - } - - s->glx_fb_config = *configs; - XFree(configs); - - /* FIXME: call glXDestroyContext() */ - s->glx_context = glXCreateNewContext(s->dpy, s->glx_fb_config, - GLX_RGBA_TYPE, NULL, 1); - if (s->glx_context == NULL) { - return 1; - } - - return 0; -} - -static void tmu2_gl_map(struct vertex *mesh, int texhres, int texvres, - int hmeshlast, int vmeshlast, int ho, int vo, int sw, int sh) -{ - int x, y; - int x0, y0, x1, y1; - int u0, v0, u1, v1, u2, v2, u3, v3; - double xscale = 1.0 / ((double)(64 * texhres)); - double yscale = 1.0 / ((double)(64 * texvres)); - - glLoadIdentity(); - glTranslatef(ho, vo, 0); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - - for (y = 0; y < vmeshlast; y++) { - y0 = y * sh; - y1 = y0 + sh; - for (x = 0; x < hmeshlast; x++) { - x0 = x * sw; - x1 = x0 + sw; - - u0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].x); - v0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].y); - u1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].x); - v1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].y); - u2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].x); - v2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].y); - u3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].x); - v3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].y); - - glTexCoord2d(((double)u0) * xscale, ((double)v0) * yscale); - glVertex3i(x0, y0, 0); - glTexCoord2d(((double)u1) * xscale, ((double)v1) * yscale); - glVertex3i(x1, y0, 0); - glTexCoord2d(((double)u2) * xscale, ((double)v2) * yscale); - glVertex3i(x1, y1, 0); - glTexCoord2d(((double)u3) * xscale, ((double)v3) * yscale); - glVertex3i(x0, y1, 0); - } - } - - glEnd(); -} - -static void tmu2_start(MilkymistTMU2State *s) -{ - int pbuffer_attrib[6] = { - GLX_PBUFFER_WIDTH, - 0, - GLX_PBUFFER_HEIGHT, - 0, - GLX_PRESERVED_CONTENTS, - True - }; - - GLXPbuffer pbuffer; - GLuint texture; - void *fb; - hwaddr fb_len; - void *mesh; - hwaddr mesh_len; - float m; - - trace_milkymist_tmu2_start(); - - /* Create and set up a suitable OpenGL context */ - pbuffer_attrib[1] = s->regs[R_DSTHRES]; - pbuffer_attrib[3] = s->regs[R_DSTVRES]; - pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib); - glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context); - - /* Fixup endianness. TODO: would it work on BE hosts? */ - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - glPixelStorei(GL_PACK_SWAP_BYTES, 1); - - /* Row alignment */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 2); - glPixelStorei(GL_PACK_ALIGNMENT, 2); - - /* Read the QEMU source framebuffer into an OpenGL texture */ - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - fb_len = 2ULL * s->regs[R_TEXHRES] * s->regs[R_TEXVRES]; - fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, false); - if (fb == NULL) { - glDeleteTextures(1, &texture); - glXMakeContextCurrent(s->dpy, None, None, NULL); - glXDestroyPbuffer(s->dpy, pbuffer); - return; - } - glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES], - 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb); - cpu_physical_memory_unmap(fb, fb_len, 0, fb_len); - - /* Set up texturing options */ - /* WARNING: - * Many cases of TMU2 masking are not supported by OpenGL. - * We only implement the most common ones: - * - full bilinear filtering vs. nearest texel - * - texture clamping vs. texture wrapping - */ - if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - } - if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - - /* Translucency and decay */ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f; - glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f); - - /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */ - fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES]; - fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, false); - if (fb == NULL) { - glDeleteTextures(1, &texture); - glXMakeContextCurrent(s->dpy, None, None, NULL); - glXDestroyPbuffer(s->dpy, pbuffer); - return; - } - - glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, fb); - cpu_physical_memory_unmap(fb, fb_len, 0, fb_len); - glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - - /* Map the texture */ - mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex); - mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, false); - if (mesh == NULL) { - glDeleteTextures(1, &texture); - glXMakeContextCurrent(s->dpy, None, None, NULL); - glXDestroyPbuffer(s->dpy, pbuffer); - return; - } - - tmu2_gl_map((struct vertex *)mesh, - s->regs[R_TEXHRES], s->regs[R_TEXVRES], - s->regs[R_HMESHLAST], s->regs[R_VMESHLAST], - s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET], - s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]); - cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len); - - /* Write back the OpenGL framebuffer to the QEMU framebuffer */ - fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES]; - fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, true); - if (fb == NULL) { - glDeleteTextures(1, &texture); - glXMakeContextCurrent(s->dpy, None, None, NULL); - glXDestroyPbuffer(s->dpy, pbuffer); - return; - } - - glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB, - GL_UNSIGNED_SHORT_5_6_5, fb); - cpu_physical_memory_unmap(fb, fb_len, 1, fb_len); - - /* Free OpenGL allocs */ - glDeleteTextures(1, &texture); - glXMakeContextCurrent(s->dpy, None, None, NULL); - glXDestroyPbuffer(s->dpy, pbuffer); - - s->regs[R_CTL] &= ~CTL_START_BUSY; - - trace_milkymist_tmu2_pulse_irq(); - qemu_irq_pulse(s->irq); -} - -static uint64_t tmu2_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistTMU2State *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_CTL: - case R_HMESHLAST: - case R_VMESHLAST: - case R_BRIGHTNESS: - case R_CHROMAKEY: - case R_VERTICESADDR: - case R_TEXFBUF: - case R_TEXHRES: - case R_TEXVRES: - case R_TEXHMASK: - case R_TEXVMASK: - case R_DSTFBUF: - case R_DSTHRES: - case R_DSTVRES: - case R_DSTHOFFSET: - case R_DSTVOFFSET: - case R_DSTSQUAREW: - case R_DSTSQUAREH: - case R_ALPHA: - r = s->regs[addr]; - break; - - default: - error_report("milkymist_tmu2: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_tmu2_memory_read(addr << 2, r); - - return r; -} - -static void tmu2_check_registers(MilkymistTMU2State *s) -{ - if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) { - error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS); - } - - if (s->regs[R_ALPHA] > MAX_ALPHA) { - error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA); - } - - if (s->regs[R_VERTICESADDR] & 0x07) { - error_report("milkymist_tmu2: vertex mesh address has to be 64-bit " - "aligned"); - } - - if (s->regs[R_TEXFBUF] & 0x01) { - error_report("milkymist_tmu2: texture buffer address has to be " - "16-bit aligned"); - } -} - -static void tmu2_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistTMU2State *s = opaque; - - trace_milkymist_tmu2_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_CTL: - s->regs[addr] = value; - if (value & CTL_START_BUSY) { - tmu2_start(s); - } - break; - case R_BRIGHTNESS: - case R_HMESHLAST: - case R_VMESHLAST: - case R_CHROMAKEY: - case R_VERTICESADDR: - case R_TEXFBUF: - case R_TEXHRES: - case R_TEXVRES: - case R_TEXHMASK: - case R_TEXVMASK: - case R_DSTFBUF: - case R_DSTHRES: - case R_DSTVRES: - case R_DSTHOFFSET: - case R_DSTVOFFSET: - case R_DSTSQUAREW: - case R_DSTSQUAREH: - case R_ALPHA: - s->regs[addr] = value; - break; - - default: - error_report("milkymist_tmu2: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - tmu2_check_registers(s); -} - -static const MemoryRegionOps tmu2_mmio_ops = { - .read = tmu2_read, - .write = tmu2_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_tmu2_reset(DeviceState *d) -{ - MilkymistTMU2State *s = MILKYMIST_TMU2(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } -} - -static void milkymist_tmu2_init(Object *obj) -{ - MilkymistTMU2State *s = MILKYMIST_TMU2(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - sysbus_init_irq(dev, &s->irq); - - memory_region_init_io(&s->regs_region, obj, &tmu2_mmio_ops, s, - "milkymist-tmu2", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); -} - -static void milkymist_tmu2_realize(DeviceState *dev, Error **errp) -{ - MilkymistTMU2State *s = MILKYMIST_TMU2(dev); - - if (tmu2_glx_init(s)) { - error_setg(errp, "tmu2_glx_init failed"); - } -} - -static const VMStateDescription vmstate_milkymist_tmu2 = { - .name = "milkymist-tmu2", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistTMU2State, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static void milkymist_tmu2_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_tmu2_realize; - dc->reset = milkymist_tmu2_reset; - dc->vmsd = &vmstate_milkymist_tmu2; -} - -static const TypeInfo milkymist_tmu2_info = { - .name = TYPE_MILKYMIST_TMU2, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistTMU2State), - .instance_init = milkymist_tmu2_init, - .class_init = milkymist_tmu2_class_init, -}; - -static void milkymist_tmu2_register_types(void) -{ - type_register_static(&milkymist_tmu2_info); -} - -type_init(milkymist_tmu2_register_types) - -DeviceState *milkymist_tmu2_create(hwaddr base, qemu_irq irq) -{ - DeviceState *dev; - Display *d; - GLXFBConfig *configs; - int nelements; - int ver_major, ver_minor; - - /* check that GLX will work */ - d = XOpenDisplay(NULL); - if (d == NULL) { - return NULL; - } - - if (!glXQueryVersion(d, &ver_major, &ver_minor)) { - /* - * Yeah, sometimes getting the GLX version can fail. - * Isn't X beautiful? - */ - XCloseDisplay(d); - return NULL; - } - - if ((ver_major < 1) || ((ver_major == 1) && (ver_minor < 3))) { - printf("Your GLX version is %d.%d," - "but TMU emulation needs at least 1.3. TMU disabled.\n", - ver_major, ver_minor); - XCloseDisplay(d); - return NULL; - } - - configs = glXChooseFBConfig(d, 0, glx_fbconfig_attr, &nelements); - if (configs == NULL) { - XCloseDisplay(d); - return NULL; - } - - XFree(configs); - XCloseDisplay(d); - - dev = qdev_new(TYPE_MILKYMIST_TMU2); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - - return dev; -} diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c deleted file mode 100644 index e2c587e2df..0000000000 --- a/hw/display/milkymist-vgafb.c +++ /dev/null @@ -1,360 +0,0 @@ - -/* - * QEMU model of the Milkymist VGA framebuffer. - * - * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/vgafb.pdf - */ - -#include "qemu/osdep.h" -#include "hw/hw.h" -#include "hw/qdev-properties.h" -#include "hw/sysbus.h" -#include "trace.h" -#include "ui/console.h" -#include "framebuffer.h" -#include "ui/pixel_ops.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -#define BITS 8 -#include "migration/vmstate.h" -#include "milkymist-vgafb_template.h" -#define BITS 15 -#include "milkymist-vgafb_template.h" -#define BITS 16 -#include "milkymist-vgafb_template.h" -#define BITS 24 -#include "milkymist-vgafb_template.h" -#define BITS 32 -#include "milkymist-vgafb_template.h" - -enum { - R_CTRL = 0, - R_HRES, - R_HSYNC_START, - R_HSYNC_END, - R_HSCAN, - R_VRES, - R_VSYNC_START, - R_VSYNC_END, - R_VSCAN, - R_BASEADDRESS, - R_BASEADDRESS_ACT, - R_BURST_COUNT, - R_DDC, - R_SOURCE_CLOCK, - R_MAX -}; - -enum { - CTRL_RESET = (1<<0), -}; - -#define TYPE_MILKYMIST_VGAFB "milkymist-vgafb" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistVgafbState, MILKYMIST_VGAFB) - -struct MilkymistVgafbState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - MemoryRegionSection fbsection; - QemuConsole *con; - - int invalidate; - uint32_t fb_offset; - uint32_t fb_mask; - - uint32_t regs[R_MAX]; -}; - -static int vgafb_enabled(MilkymistVgafbState *s) -{ - return !(s->regs[R_CTRL] & CTRL_RESET); -} - -static void vgafb_update_display(void *opaque) -{ - MilkymistVgafbState *s = opaque; - SysBusDevice *sbd; - DisplaySurface *surface = qemu_console_surface(s->con); - int src_width; - int first = 0; - int last = 0; - drawfn fn; - - if (!vgafb_enabled(s)) { - return; - } - - sbd = SYS_BUS_DEVICE(s); - int dest_width = s->regs[R_HRES]; - - switch (surface_bits_per_pixel(surface)) { - case 0: - return; - case 8: - fn = draw_line_8; - break; - case 15: - fn = draw_line_15; - dest_width *= 2; - break; - case 16: - fn = draw_line_16; - dest_width *= 2; - break; - case 24: - fn = draw_line_24; - dest_width *= 3; - break; - case 32: - fn = draw_line_32; - dest_width *= 4; - break; - default: - hw_error("milkymist_vgafb: bad color depth\n"); - break; - } - - src_width = s->regs[R_HRES] * 2; - if (s->invalidate) { - framebuffer_update_memory_section(&s->fbsection, - sysbus_address_space(sbd), - s->regs[R_BASEADDRESS] + s->fb_offset, - s->regs[R_VRES], src_width); - } - - framebuffer_update_display(surface, &s->fbsection, - s->regs[R_HRES], - s->regs[R_VRES], - src_width, - dest_width, - 0, - s->invalidate, - fn, - NULL, - &first, &last); - - if (first >= 0) { - dpy_gfx_update(s->con, 0, first, s->regs[R_HRES], last - first + 1); - } - s->invalidate = 0; -} - -static void vgafb_invalidate_display(void *opaque) -{ - MilkymistVgafbState *s = opaque; - s->invalidate = 1; -} - -static void vgafb_resize(MilkymistVgafbState *s) -{ - if (!vgafb_enabled(s)) { - return; - } - - qemu_console_resize(s->con, s->regs[R_HRES], s->regs[R_VRES]); - s->invalidate = 1; -} - -static uint64_t vgafb_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistVgafbState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_CTRL: - case R_HRES: - case R_HSYNC_START: - case R_HSYNC_END: - case R_HSCAN: - case R_VRES: - case R_VSYNC_START: - case R_VSYNC_END: - case R_VSCAN: - case R_BASEADDRESS: - case R_BURST_COUNT: - case R_DDC: - case R_SOURCE_CLOCK: - r = s->regs[addr]; - break; - case R_BASEADDRESS_ACT: - r = s->regs[R_BASEADDRESS]; - break; - - default: - error_report("milkymist_vgafb: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_vgafb_memory_read(addr << 2, r); - - return r; -} - -static void vgafb_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistVgafbState *s = opaque; - - trace_milkymist_vgafb_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_CTRL: - s->regs[addr] = value; - vgafb_resize(s); - break; - case R_HSYNC_START: - case R_HSYNC_END: - case R_HSCAN: - case R_VSYNC_START: - case R_VSYNC_END: - case R_VSCAN: - case R_BURST_COUNT: - case R_DDC: - case R_SOURCE_CLOCK: - s->regs[addr] = value; - break; - case R_BASEADDRESS: - if (value & 0x1f) { - error_report("milkymist_vgafb: framebuffer base address have to " - "be 32 byte aligned"); - break; - } - s->regs[addr] = value & s->fb_mask; - s->invalidate = 1; - break; - case R_HRES: - case R_VRES: - s->regs[addr] = value; - vgafb_resize(s); - break; - case R_BASEADDRESS_ACT: - error_report("milkymist_vgafb: write to read-only register 0x" - TARGET_FMT_plx, addr << 2); - break; - - default: - error_report("milkymist_vgafb: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } -} - -static const MemoryRegionOps vgafb_mmio_ops = { - .read = vgafb_read, - .write = vgafb_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_vgafb_reset(DeviceState *d) -{ - MilkymistVgafbState *s = MILKYMIST_VGAFB(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - /* defaults */ - s->regs[R_CTRL] = CTRL_RESET; - s->regs[R_HRES] = 640; - s->regs[R_VRES] = 480; - s->regs[R_BASEADDRESS] = 0; -} - -static const GraphicHwOps vgafb_ops = { - .invalidate = vgafb_invalidate_display, - .gfx_update = vgafb_update_display, -}; - -static void milkymist_vgafb_init(Object *obj) -{ - MilkymistVgafbState *s = MILKYMIST_VGAFB(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s, - "milkymist-vgafb", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); -} - -static void milkymist_vgafb_realize(DeviceState *dev, Error **errp) -{ - MilkymistVgafbState *s = MILKYMIST_VGAFB(dev); - - s->con = graphic_console_init(dev, 0, &vgafb_ops, s); -} - -static int vgafb_post_load(void *opaque, int version_id) -{ - vgafb_invalidate_display(opaque); - return 0; -} - -static const VMStateDescription vmstate_milkymist_vgafb = { - .name = "milkymist-vgafb", - .version_id = 1, - .minimum_version_id = 1, - .post_load = vgafb_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_vgafb_properties[] = { - DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0), - DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_vgafb_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->reset = milkymist_vgafb_reset; - dc->vmsd = &vmstate_milkymist_vgafb; - device_class_set_props(dc, milkymist_vgafb_properties); - dc->realize = milkymist_vgafb_realize; -} - -static const TypeInfo milkymist_vgafb_info = { - .name = TYPE_MILKYMIST_VGAFB, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistVgafbState), - .instance_init = milkymist_vgafb_init, - .class_init = milkymist_vgafb_class_init, -}; - -static void milkymist_vgafb_register_types(void) -{ - type_register_static(&milkymist_vgafb_info); -} - -type_init(milkymist_vgafb_register_types) diff --git a/hw/display/milkymist-vgafb_template.h b/hw/display/milkymist-vgafb_template.h deleted file mode 100644 index 96137f9709..0000000000 --- a/hw/display/milkymist-vgafb_template.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * QEMU model of the Milkymist VGA framebuffer. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#if BITS == 8 -#define COPY_PIXEL(to, r, g, b) \ - do { \ - *to = rgb_to_pixel8(r, g, b); \ - to += 1; \ - } while (0) -#elif BITS == 15 -#define COPY_PIXEL(to, r, g, b) \ - do { \ - *(uint16_t *)to = rgb_to_pixel15(r, g, b); \ - to += 2; \ - } while (0) -#elif BITS == 16 -#define COPY_PIXEL(to, r, g, b) \ - do { \ - *(uint16_t *)to = rgb_to_pixel16(r, g, b); \ - to += 2; \ - } while (0) -#elif BITS == 24 -#define COPY_PIXEL(to, r, g, b) \ - do { \ - uint32_t tmp = rgb_to_pixel24(r, g, b); \ - *(to++) = tmp & 0xff; \ - *(to++) = (tmp >> 8) & 0xff; \ - *(to++) = (tmp >> 16) & 0xff; \ - } while (0) -#elif BITS == 32 -#define COPY_PIXEL(to, r, g, b) \ - do { \ - *(uint32_t *)to = rgb_to_pixel32(r, g, b); \ - to += 4; \ - } while (0) -#else -#error unknown bit depth -#endif - -static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s, - int width, int deststep) -{ - uint16_t rgb565; - uint8_t r, g, b; - - while (width--) { - rgb565 = lduw_be_p(s); - r = ((rgb565 >> 11) & 0x1f) << 3; - g = ((rgb565 >> 5) & 0x3f) << 2; - b = ((rgb565 >> 0) & 0x1f) << 3; - COPY_PIXEL(d, r, g, b); - s += 2; - } -} - -#undef BITS -#undef COPY_PIXEL diff --git a/hw/display/trace-events b/hw/display/trace-events index 957b8ba994..9fccca18a1 100644 --- a/hw/display/trace-events +++ b/hw/display/trace-events @@ -13,16 +13,6 @@ xenfb_input_connected(void *xendev, int abs_pointer_wanted) "%p abs %d" g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x" g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x" -# milkymist-tmu2.c -milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_tmu2_start(void) "Start TMU" -milkymist_tmu2_pulse_irq(void) "Pulse IRQ" - -# milkymist-vgafb.c -milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" - # vmware_vga.c vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x" vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x" diff --git a/hw/input/meson.build b/hw/input/meson.build index 0042c3f0dc..8deb011d4a 100644 --- a/hw/input/meson.build +++ b/hw/input/meson.build @@ -13,7 +13,6 @@ softmmu_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c') softmmu_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: files('virtio-input-host.c')) softmmu_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-softusb.c')) softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c')) softmmu_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c')) softmmu_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c')) diff --git a/hw/input/milkymist-softusb.c b/hw/input/milkymist-softusb.c deleted file mode 100644 index d885c708d7..0000000000 --- a/hw/input/milkymist-softusb.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * QEMU model of the Milkymist SoftUSB block. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * not available yet - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "ui/console.h" -#include "hw/input/hid.h" -#include "hw/irq.h" -#include "hw/qdev-properties.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -enum { - R_CTRL = 0, - R_MAX -}; - -enum { - CTRL_RESET = (1<<0), -}; - -#define COMLOC_DEBUG_PRODUCE 0x1000 -#define COMLOC_DEBUG_BASE 0x1001 -#define COMLOC_MEVT_PRODUCE 0x1101 -#define COMLOC_MEVT_BASE 0x1102 -#define COMLOC_KEVT_PRODUCE 0x1142 -#define COMLOC_KEVT_BASE 0x1143 - -#define TYPE_MILKYMIST_SOFTUSB "milkymist-softusb" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistSoftUsbState, MILKYMIST_SOFTUSB) - -struct MilkymistSoftUsbState { - SysBusDevice parent_obj; - - HIDState hid_kbd; - HIDState hid_mouse; - - MemoryRegion regs_region; - MemoryRegion pmem; - MemoryRegion dmem; - qemu_irq irq; - - void *pmem_ptr; - void *dmem_ptr; - - /* device properties */ - uint32_t pmem_size; - uint32_t dmem_size; - - /* device registers */ - uint32_t regs[R_MAX]; - - /* mouse state */ - uint8_t mouse_hid_buffer[4]; - - /* keyboard state */ - uint8_t kbd_hid_buffer[8]; -}; - -static uint64_t softusb_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistSoftUsbState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_CTRL: - r = s->regs[addr]; - break; - - default: - error_report("milkymist_softusb: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_softusb_memory_read(addr << 2, r); - - return r; -} - -static void -softusb_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistSoftUsbState *s = opaque; - - trace_milkymist_softusb_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_CTRL: - s->regs[addr] = value; - break; - - default: - error_report("milkymist_softusb: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } -} - -static const MemoryRegionOps softusb_mmio_ops = { - .read = softusb_read, - .write = softusb_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, -}; - -static inline void softusb_read_dmem(MilkymistSoftUsbState *s, - uint32_t offset, uint8_t *buf, uint32_t len) -{ - if (offset + len >= s->dmem_size) { - error_report("milkymist_softusb: read dmem out of bounds " - "at offset 0x%x, len %d", offset, len); - memset(buf, 0, len); - return; - } - - memcpy(buf, s->dmem_ptr + offset, len); -} - -static inline void softusb_write_dmem(MilkymistSoftUsbState *s, - uint32_t offset, uint8_t *buf, uint32_t len) -{ - if (offset + len >= s->dmem_size) { - error_report("milkymist_softusb: write dmem out of bounds " - "at offset 0x%x, len %d", offset, len); - return; - } - - memcpy(s->dmem_ptr + offset, buf, len); -} - -static void softusb_mouse_changed(MilkymistSoftUsbState *s) -{ - uint8_t m; - - softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1); - trace_milkymist_softusb_mevt(m); - softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4); - m = (m + 1) & 0xf; - softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1); - - trace_milkymist_softusb_pulse_irq(); - qemu_irq_pulse(s->irq); -} - -static void softusb_kbd_changed(MilkymistSoftUsbState *s) -{ - uint8_t m; - - softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1); - trace_milkymist_softusb_kevt(m); - softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8); - m = (m + 1) & 0x7; - softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1); - - trace_milkymist_softusb_pulse_irq(); - qemu_irq_pulse(s->irq); -} - -static void softusb_kbd_hid_datain(HIDState *hs) -{ - MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd); - int len; - - /* if device is in reset, do nothing */ - if (s->regs[R_CTRL] & CTRL_RESET) { - return; - } - - while (hid_has_events(hs)) { - len = hid_keyboard_poll(hs, s->kbd_hid_buffer, - sizeof(s->kbd_hid_buffer)); - - if (len == 8) { - softusb_kbd_changed(s); - } - } -} - -static void softusb_mouse_hid_datain(HIDState *hs) -{ - MilkymistSoftUsbState *s = - container_of(hs, MilkymistSoftUsbState, hid_mouse); - int len; - - /* if device is in reset, do nothing */ - if (s->regs[R_CTRL] & CTRL_RESET) { - return; - } - - while (hid_has_events(hs)) { - len = hid_pointer_poll(hs, s->mouse_hid_buffer, - sizeof(s->mouse_hid_buffer)); - - if (len == 4) { - softusb_mouse_changed(s); - } - } -} - -static void milkymist_softusb_reset(DeviceState *d) -{ - MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer)); - memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer)); - - hid_reset(&s->hid_kbd); - hid_reset(&s->hid_mouse); - - /* defaults */ - s->regs[R_CTRL] = CTRL_RESET; -} - -static void milkymist_softusb_realize(DeviceState *dev, Error **errp) -{ - MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - - sysbus_init_irq(sbd, &s->irq); - - memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s, - "milkymist-softusb", R_MAX * 4); - sysbus_init_mmio(sbd, &s->regs_region); - - /* register pmem and dmem */ - memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem", - s->pmem_size, &error_fatal); - vmstate_register_ram_global(&s->pmem); - s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem); - sysbus_init_mmio(sbd, &s->pmem); - memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem", - s->dmem_size, &error_fatal); - vmstate_register_ram_global(&s->dmem); - s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem); - sysbus_init_mmio(sbd, &s->dmem); - - hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain); - hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain); -} - -static const VMStateDescription vmstate_milkymist_softusb = { - .name = "milkymist-softusb", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX), - VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState), - VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState), - VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState), - VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_softusb_properties[] = { - DEFINE_PROP_UINT32("pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000), - DEFINE_PROP_UINT32("dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_softusb_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_softusb_realize; - dc->reset = milkymist_softusb_reset; - dc->vmsd = &vmstate_milkymist_softusb; - device_class_set_props(dc, milkymist_softusb_properties); -} - -static const TypeInfo milkymist_softusb_info = { - .name = TYPE_MILKYMIST_SOFTUSB, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistSoftUsbState), - .class_init = milkymist_softusb_class_init, -}; - -static void milkymist_softusb_register_types(void) -{ - type_register_static(&milkymist_softusb_info); -} - -type_init(milkymist_softusb_register_types) diff --git a/hw/input/trace-events b/hw/input/trace-events index 1dd8ad6018..33741e74f5 100644 --- a/hw/input/trace-events +++ b/hw/input/trace-events @@ -44,13 +44,6 @@ ps2_mouse_reset(void *opaque) "%p" ps2_kbd_init(void *s) "%p" ps2_mouse_init(void *s) "%p" -# milkymist-softusb.c -milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_softusb_mevt(uint8_t m) "m %d" -milkymist_softusb_kevt(uint8_t m) "m %d" -milkymist_softusb_pulse_irq(void) "Pulse IRQ" - # hid.c hid_kbd_queue_full(void) "queue full" hid_kbd_queue_empty(void) "queue empty" diff --git a/hw/intc/lm32_pic.c b/hw/intc/lm32_pic.c deleted file mode 100644 index 991a90bc99..0000000000 --- a/hw/intc/lm32_pic.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * LatticeMico32 CPU interrupt controller logic. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" - -#include "migration/vmstate.h" -#include "monitor/monitor.h" -#include "qemu/module.h" -#include "hw/sysbus.h" -#include "trace.h" -#include "hw/lm32/lm32_pic.h" -#include "hw/intc/intc.h" -#include "hw/irq.h" -#include "qom/object.h" - -#define TYPE_LM32_PIC "lm32-pic" -OBJECT_DECLARE_SIMPLE_TYPE(LM32PicState, LM32_PIC) - -struct LM32PicState { - SysBusDevice parent_obj; - - qemu_irq parent_irq; - uint32_t im; /* interrupt mask */ - uint32_t ip; /* interrupt pending */ - uint32_t irq_state; - - /* statistics */ - uint64_t stats_irq_count[32]; -}; - -static void update_irq(LM32PicState *s) -{ - s->ip |= s->irq_state; - - if (s->ip & s->im) { - trace_lm32_pic_raise_irq(); - qemu_irq_raise(s->parent_irq); - } else { - trace_lm32_pic_lower_irq(); - qemu_irq_lower(s->parent_irq); - } -} - -static void irq_handler(void *opaque, int irq, int level) -{ - LM32PicState *s = opaque; - - assert(irq < 32); - trace_lm32_pic_interrupt(irq, level); - - if (level) { - s->irq_state |= (1 << irq); - s->stats_irq_count[irq]++; - } else { - s->irq_state &= ~(1 << irq); - } - - update_irq(s); -} - -void lm32_pic_set_im(DeviceState *d, uint32_t im) -{ - LM32PicState *s = LM32_PIC(d); - - trace_lm32_pic_set_im(im); - s->im = im; - - update_irq(s); -} - -void lm32_pic_set_ip(DeviceState *d, uint32_t ip) -{ - LM32PicState *s = LM32_PIC(d); - - trace_lm32_pic_set_ip(ip); - - /* ack interrupt */ - s->ip &= ~ip; - - update_irq(s); -} - -uint32_t lm32_pic_get_im(DeviceState *d) -{ - LM32PicState *s = LM32_PIC(d); - - trace_lm32_pic_get_im(s->im); - return s->im; -} - -uint32_t lm32_pic_get_ip(DeviceState *d) -{ - LM32PicState *s = LM32_PIC(d); - - trace_lm32_pic_get_ip(s->ip); - return s->ip; -} - -static void pic_reset(DeviceState *d) -{ - LM32PicState *s = LM32_PIC(d); - int i; - - s->im = 0; - s->ip = 0; - s->irq_state = 0; - for (i = 0; i < 32; i++) { - s->stats_irq_count[i] = 0; - } -} - -static bool lm32_get_statistics(InterruptStatsProvider *obj, - uint64_t **irq_counts, unsigned int *nb_irqs) -{ - LM32PicState *s = LM32_PIC(obj); - *irq_counts = s->stats_irq_count; - *nb_irqs = ARRAY_SIZE(s->stats_irq_count); - return true; -} - -static void lm32_print_info(InterruptStatsProvider *obj, Monitor *mon) -{ - LM32PicState *s = LM32_PIC(obj); - monitor_printf(mon, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n", - s->im, s->ip, s->irq_state); -} - -static void lm32_pic_init(Object *obj) -{ - DeviceState *dev = DEVICE(obj); - LM32PicState *s = LM32_PIC(obj); - SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - - qdev_init_gpio_in(dev, irq_handler, 32); - sysbus_init_irq(sbd, &s->parent_irq); -} - -static const VMStateDescription vmstate_lm32_pic = { - .name = "lm32-pic", - .version_id = 2, - .minimum_version_id = 2, - .fields = (VMStateField[]) { - VMSTATE_UINT32(im, LM32PicState), - VMSTATE_UINT32(ip, LM32PicState), - VMSTATE_UINT32(irq_state, LM32PicState), - VMSTATE_UINT64_ARRAY(stats_irq_count, LM32PicState, 32), - VMSTATE_END_OF_LIST() - } -}; - -static void lm32_pic_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); - - dc->reset = pic_reset; - dc->vmsd = &vmstate_lm32_pic; - ic->get_statistics = lm32_get_statistics; - ic->print_info = lm32_print_info; -} - -static const TypeInfo lm32_pic_info = { - .name = TYPE_LM32_PIC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(LM32PicState), - .instance_init = lm32_pic_init, - .class_init = lm32_pic_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_INTERRUPT_STATS_PROVIDER }, - { } - }, -}; - -static void lm32_pic_register_types(void) -{ - type_register_static(&lm32_pic_info); -} - -type_init(lm32_pic_register_types) diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 1c299039f6..cc7a140f3f 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -14,7 +14,6 @@ softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c')) softmmu_ss.add(when: 'CONFIG_I8259', if_true: files('i8259_common.c', 'i8259.c')) softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_avic.c', 'imx_gpcv2.c')) softmmu_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic_common.c')) -softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_pic.c')) softmmu_ss.add(when: 'CONFIG_OPENPIC', if_true: files('openpic.c')) softmmu_ss.add(when: 'CONFIG_PL190', if_true: files('pl190.c')) softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_intc.c')) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index c9ab17234b..626bb554b2 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -51,15 +51,6 @@ grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d" grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64 grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x" -# lm32_pic.c -lm32_pic_raise_irq(void) "Raise CPU interrupt" -lm32_pic_lower_irq(void) "Lower CPU interrupt" -lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d" -lm32_pic_set_im(uint32_t im) "im 0x%08x" -lm32_pic_set_ip(uint32_t ip) "ip 0x%08x" -lm32_pic_get_im(uint32_t im) "im 0x%08x" -lm32_pic_get_ip(uint32_t ip) "ip 0x%08x" - # xics.c xics_icp_check_ipi(int server, uint8_t mfrr) "CPU %d can take IPI mfrr=0x%x" xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR 0x%"PRIx32"->0x%"PRIx32 diff --git a/hw/lm32/Kconfig b/hw/lm32/Kconfig deleted file mode 100644 index 8ac94205d7..0000000000 --- a/hw/lm32/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -config LM32_DEVICES - bool - select PTIMER - -config MILKYMIST - bool - # FIXME: disabling it results in compile-time errors - select MILKYMIST_TMU2 if OPENGL && X11 - select PFLASH_CFI01 - select FRAMEBUFFER - select SD - select USB_OHCI - select LM32_DEVICES - -config LM32_EVR - bool - select LM32_DEVICES - select PFLASH_CFI02 diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h deleted file mode 100644 index 7b4f6255b9..0000000000 --- a/hw/lm32/lm32.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef HW_LM32_H -#define HW_LM32_H - -#include "hw/char/lm32_juart.h" -#include "hw/qdev-properties.h" -#include "qapi/error.h" - -static inline DeviceState *lm32_pic_init(qemu_irq cpu_irq) -{ - DeviceState *dev; - SysBusDevice *d; - - dev = qdev_new("lm32-pic"); - d = SYS_BUS_DEVICE(dev); - sysbus_realize_and_unref(d, &error_fatal); - sysbus_connect_irq(d, 0, cpu_irq); - - return dev; -} - -static inline DeviceState *lm32_juart_init(Chardev *chr) -{ - DeviceState *dev; - - dev = qdev_new(TYPE_LM32_JUART); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - - return dev; -} - -static inline DeviceState *lm32_uart_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new("lm32-uart"); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - return dev; -} - -#endif diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c deleted file mode 100644 index 2961e4c2b4..0000000000 --- a/hw/lm32/lm32_boards.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * QEMU models for LatticeMico32 uclinux and evr32 boards. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "qemu/cutils.h" -#include "qemu/error-report.h" -#include "cpu.h" -#include "hw/sysbus.h" -#include "hw/irq.h" -#include "hw/block/flash.h" -#include "hw/boards.h" -#include "hw/loader.h" -#include "elf.h" -#include "lm32_hwsetup.h" -#include "lm32.h" -#include "sysemu/reset.h" -#include "sysemu/sysemu.h" - -typedef struct { - LM32CPU *cpu; - hwaddr bootstrap_pc; - hwaddr flash_base; - hwaddr hwsetup_base; - hwaddr initrd_base; - size_t initrd_size; - hwaddr cmdline_base; -} ResetInfo; - -static void cpu_irq_handler(void *opaque, int irq, int level) -{ - LM32CPU *cpu = opaque; - CPUState *cs = CPU(cpu); - - if (level) { - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } -} - -static void main_cpu_reset(void *opaque) -{ - ResetInfo *reset_info = opaque; - CPULM32State *env = &reset_info->cpu->env; - - cpu_reset(CPU(reset_info->cpu)); - - /* init defaults */ - env->pc = (uint32_t)reset_info->bootstrap_pc; - env->regs[R_R1] = (uint32_t)reset_info->hwsetup_base; - env->regs[R_R2] = (uint32_t)reset_info->cmdline_base; - env->regs[R_R3] = (uint32_t)reset_info->initrd_base; - env->regs[R_R4] = (uint32_t)(reset_info->initrd_base + - reset_info->initrd_size); - env->eba = reset_info->flash_base; - env->deba = reset_info->flash_base; -} - -static void lm32_evr_init(MachineState *machine) -{ - MachineClass *mc = MACHINE_GET_CLASS(machine); - const char *kernel_filename = machine->kernel_filename; - LM32CPU *cpu; - CPULM32State *env; - DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - qemu_irq irq[32]; - ResetInfo *reset_info; - int i; - - if (machine->ram_size != mc->default_ram_size) { - char *sz = size_to_str(mc->default_ram_size); - error_report("Invalid RAM size, should be %s", sz); - g_free(sz); - exit(EXIT_FAILURE); - } - - /* memory map */ - hwaddr flash_base = 0x04000000; - size_t flash_sector_size = 256 * KiB; - size_t flash_size = 32 * MiB; - hwaddr ram_base = 0x08000000; - hwaddr timer0_base = 0x80002000; - hwaddr uart0_base = 0x80006000; - hwaddr timer1_base = 0x8000a000; - int uart0_irq = 0; - int timer0_irq = 1; - int timer1_irq = 3; - - reset_info = g_malloc0(sizeof(ResetInfo)); - - cpu = LM32_CPU(cpu_create(machine->cpu_type)); - - env = &cpu->env; - reset_info->cpu = cpu; - - reset_info->flash_base = flash_base; - - memory_region_add_subregion(address_space_mem, ram_base, machine->ram); - - dinfo = drive_get(IF_PFLASH, 0, 0); - /* Spansion S29NS128P */ - pflash_cfi02_register(flash_base, "lm32_evr.flash", flash_size, - dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, - flash_sector_size, - 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); - - /* create irq lines */ - env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0)); - for (i = 0; i < 32; i++) { - irq[i] = qdev_get_gpio_in(env->pic_state, i); - } - - lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0)); - sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]); - sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]); - - /* make sure juart isn't the first chardev */ - env->juart_state = lm32_juart_init(serial_hd(1)); - - reset_info->bootstrap_pc = flash_base; - - if (kernel_filename) { - uint64_t entry; - int kernel_size; - - kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, - &entry, NULL, NULL, NULL, - 1, EM_LATTICEMICO32, 0, 0); - reset_info->bootstrap_pc = entry; - - if (kernel_size < 0) { - kernel_size = load_image_targphys(kernel_filename, ram_base, - machine->ram_size); - reset_info->bootstrap_pc = ram_base; - } - - if (kernel_size < 0) { - error_report("could not load kernel '%s'", kernel_filename); - exit(1); - } - } - - qemu_register_reset(main_cpu_reset, reset_info); -} - -static void lm32_uclinux_init(MachineState *machine) -{ - MachineClass *mc = MACHINE_GET_CLASS(machine); - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; - LM32CPU *cpu; - CPULM32State *env; - DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - qemu_irq irq[32]; - HWSetup *hw; - ResetInfo *reset_info; - int i; - - if (machine->ram_size != mc->default_ram_size) { - char *sz = size_to_str(mc->default_ram_size); - error_report("Invalid RAM size, should be %s", sz); - g_free(sz); - exit(EXIT_FAILURE); - } - - /* memory map */ - hwaddr flash_base = 0x04000000; - size_t flash_sector_size = 256 * KiB; - size_t flash_size = 32 * MiB; - hwaddr ram_base = 0x08000000; - hwaddr uart0_base = 0x80000000; - hwaddr timer0_base = 0x80002000; - hwaddr timer1_base = 0x80010000; - hwaddr timer2_base = 0x80012000; - int uart0_irq = 0; - int timer0_irq = 1; - int timer1_irq = 20; - int timer2_irq = 21; - hwaddr hwsetup_base = 0x0bffe000; - hwaddr cmdline_base = 0x0bfff000; - hwaddr initrd_base = 0x08400000; - size_t initrd_max = 0x01000000; - - reset_info = g_malloc0(sizeof(ResetInfo)); - - cpu = LM32_CPU(cpu_create(machine->cpu_type)); - - env = &cpu->env; - reset_info->cpu = cpu; - - reset_info->flash_base = flash_base; - - memory_region_add_subregion(address_space_mem, ram_base, machine->ram); - - dinfo = drive_get(IF_PFLASH, 0, 0); - /* Spansion S29NS128P */ - pflash_cfi02_register(flash_base, "lm32_uclinux.flash", flash_size, - dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, - flash_sector_size, - 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1); - - /* create irq lines */ - env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, env, 0)); - for (i = 0; i < 32; i++) { - irq[i] = qdev_get_gpio_in(env->pic_state, i); - } - - lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0)); - sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]); - sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]); - sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]); - - /* make sure juart isn't the first chardev */ - env->juart_state = lm32_juart_init(serial_hd(1)); - - reset_info->bootstrap_pc = flash_base; - - if (kernel_filename) { - uint64_t entry; - int kernel_size; - - kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, - &entry, NULL, NULL, NULL, - 1, EM_LATTICEMICO32, 0, 0); - reset_info->bootstrap_pc = entry; - - if (kernel_size < 0) { - kernel_size = load_image_targphys(kernel_filename, ram_base, - machine->ram_size); - reset_info->bootstrap_pc = ram_base; - } - - if (kernel_size < 0) { - error_report("could not load kernel '%s'", kernel_filename); - exit(1); - } - } - - /* generate a rom with the hardware description */ - hw = hwsetup_init(); - hwsetup_add_cpu(hw, "LM32", 75000000); - hwsetup_add_flash(hw, "flash", flash_base, flash_size); - hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, machine->ram_size); - hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq); - hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq); - hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq); - hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq); - hwsetup_add_trailer(hw); - hwsetup_create_rom(hw, hwsetup_base); - hwsetup_free(hw); - - reset_info->hwsetup_base = hwsetup_base; - - if (kernel_cmdline && strlen(kernel_cmdline)) { - pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, - kernel_cmdline); - reset_info->cmdline_base = cmdline_base; - } - - if (initrd_filename) { - size_t initrd_size; - initrd_size = load_image_targphys(initrd_filename, initrd_base, - initrd_max); - reset_info->initrd_base = initrd_base; - reset_info->initrd_size = initrd_size; - } - - qemu_register_reset(main_cpu_reset, reset_info); -} - -static void lm32_evr_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "LatticeMico32 EVR32 eval system"; - mc->init = lm32_evr_init; - mc->is_default = true; - mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full"); - mc->default_ram_size = 64 * MiB; - mc->default_ram_id = "lm32_evr.sdram"; -} - -static const TypeInfo lm32_evr_type = { - .name = MACHINE_TYPE_NAME("lm32-evr"), - .parent = TYPE_MACHINE, - .class_init = lm32_evr_class_init, -}; - -static void lm32_uclinux_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "lm32 platform for uClinux and u-boot by Theobroma Systems"; - mc->init = lm32_uclinux_init; - mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full"); - mc->default_ram_size = 64 * MiB; - mc->default_ram_id = "lm32_uclinux.sdram"; -} - -static const TypeInfo lm32_uclinux_type = { - .name = MACHINE_TYPE_NAME("lm32-uclinux"), - .parent = TYPE_MACHINE, - .class_init = lm32_uclinux_class_init, -}; - -static void lm32_machine_init(void) -{ - type_register_static(&lm32_evr_type); - type_register_static(&lm32_uclinux_type); -} - -type_init(lm32_machine_init) diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h deleted file mode 100644 index e6cd30ad68..0000000000 --- a/hw/lm32/lm32_hwsetup.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * LatticeMico32 hwsetup helper functions. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * These are helper functions for creating the hardware description blob used - * in the Theobroma's uClinux port. - */ - -#ifndef QEMU_HW_LM32_HWSETUP_H -#define QEMU_HW_LM32_HWSETUP_H - -#include "qemu/cutils.h" -#include "hw/loader.h" - -typedef struct { - void *data; - void *ptr; -} HWSetup; - -enum hwsetup_tag { - HWSETUP_TAG_EOL = 0, - HWSETUP_TAG_CPU = 1, - HWSETUP_TAG_ASRAM = 2, - HWSETUP_TAG_FLASH = 3, - HWSETUP_TAG_SDRAM = 4, - HWSETUP_TAG_OCM = 5, - HWSETUP_TAG_DDR_SDRAM = 6, - HWSETUP_TAG_DDR2_SDRAM = 7, - HWSETUP_TAG_TIMER = 8, - HWSETUP_TAG_UART = 9, - HWSETUP_TAG_GPIO = 10, - HWSETUP_TAG_TRISPEEDMAC = 11, - HWSETUP_TAG_I2CM = 12, - HWSETUP_TAG_LEDS = 13, - HWSETUP_TAG_7SEG = 14, - HWSETUP_TAG_SPI_S = 15, - HWSETUP_TAG_SPI_M = 16, -}; - -static inline HWSetup *hwsetup_init(void) -{ - HWSetup *hw; - - hw = g_malloc(sizeof(HWSetup)); - hw->data = g_malloc0(TARGET_PAGE_SIZE); - hw->ptr = hw->data; - - return hw; -} - -static inline void hwsetup_free(HWSetup *hw) -{ - g_free(hw->data); - g_free(hw); -} - -static inline void hwsetup_create_rom(HWSetup *hw, - hwaddr base) -{ - rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE, - TARGET_PAGE_SIZE, base, NULL, NULL, NULL, NULL, true); -} - -static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u) -{ - stb_p(hw->ptr, u); - hw->ptr += 1; -} - -static inline void hwsetup_add_u32(HWSetup *hw, uint32_t u) -{ - stl_p(hw->ptr, u); - hw->ptr += 4; -} - -static inline void hwsetup_add_tag(HWSetup *hw, enum hwsetup_tag t) -{ - stl_p(hw->ptr, t); - hw->ptr += 4; -} - -static inline void hwsetup_add_str(HWSetup *hw, const char *str) -{ - pstrcpy(hw->ptr, 32, str); - hw->ptr += 32; -} - -static inline void hwsetup_add_trailer(HWSetup *hw) -{ - hwsetup_add_u32(hw, 8); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_EOL); -} - -static inline void hwsetup_add_cpu(HWSetup *hw, - const char *name, uint32_t frequency) -{ - hwsetup_add_u32(hw, 44); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_CPU); - hwsetup_add_str(hw, name); - hwsetup_add_u32(hw, frequency); -} - -static inline void hwsetup_add_flash(HWSetup *hw, - const char *name, uint32_t base, uint32_t size) -{ - hwsetup_add_u32(hw, 52); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_FLASH); - hwsetup_add_str(hw, name); - hwsetup_add_u32(hw, base); - hwsetup_add_u32(hw, size); - hwsetup_add_u8(hw, 8); /* read latency */ - hwsetup_add_u8(hw, 8); /* write latency */ - hwsetup_add_u8(hw, 25); /* address width */ - hwsetup_add_u8(hw, 32); /* data width */ -} - -static inline void hwsetup_add_ddr_sdram(HWSetup *hw, - const char *name, uint32_t base, uint32_t size) -{ - hwsetup_add_u32(hw, 48); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_DDR_SDRAM); - hwsetup_add_str(hw, name); - hwsetup_add_u32(hw, base); - hwsetup_add_u32(hw, size); -} - -static inline void hwsetup_add_timer(HWSetup *hw, - const char *name, uint32_t base, uint32_t irq) -{ - hwsetup_add_u32(hw, 56); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_TIMER); - hwsetup_add_str(hw, name); - hwsetup_add_u32(hw, base); - hwsetup_add_u8(hw, 1); /* wr_tickcount */ - hwsetup_add_u8(hw, 1); /* rd_tickcount */ - hwsetup_add_u8(hw, 1); /* start_stop_control */ - hwsetup_add_u8(hw, 32); /* counter_width */ - hwsetup_add_u32(hw, 20); /* reload_ticks */ - hwsetup_add_u8(hw, irq); - hwsetup_add_u8(hw, 0); /* padding */ - hwsetup_add_u8(hw, 0); /* padding */ - hwsetup_add_u8(hw, 0); /* padding */ -} - -static inline void hwsetup_add_uart(HWSetup *hw, - const char *name, uint32_t base, uint32_t irq) -{ - hwsetup_add_u32(hw, 56); /* size */ - hwsetup_add_tag(hw, HWSETUP_TAG_UART); - hwsetup_add_str(hw, name); - hwsetup_add_u32(hw, base); - hwsetup_add_u32(hw, 115200); /* baudrate */ - hwsetup_add_u8(hw, 8); /* databits */ - hwsetup_add_u8(hw, 1); /* stopbits */ - hwsetup_add_u8(hw, 1); /* use_interrupt */ - hwsetup_add_u8(hw, 1); /* block_on_transmit */ - hwsetup_add_u8(hw, 1); /* block_on_receive */ - hwsetup_add_u8(hw, 4); /* rx_buffer_size */ - hwsetup_add_u8(hw, 4); /* tx_buffer_size */ - hwsetup_add_u8(hw, irq); -} - -#endif /* QEMU_HW_LM32_HWSETUP_H */ diff --git a/hw/lm32/meson.build b/hw/lm32/meson.build deleted file mode 100644 index 42d6f8db3d..0000000000 --- a/hw/lm32/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -lm32_ss = ss.source_set() -# LM32 boards -lm32_ss.add(when: 'CONFIG_LM32_EVR', if_true: files('lm32_boards.c')) -lm32_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist.c')) - -hw_arch += {'lm32': lm32_ss} diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h deleted file mode 100644 index 5dca5d52f5..0000000000 --- a/hw/lm32/milkymist-hw.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef QEMU_HW_MILKYMIST_HW_H -#define QEMU_HW_MILKYMIST_HW_H - -#include "hw/qdev-core.h" -#include "net/net.h" -#include "qapi/error.h" - -static inline DeviceState *milkymist_uart_create(hwaddr base, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-uart"); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - - return dev; -} - -static inline DeviceState *milkymist_hpdmc_create(hwaddr base) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-hpdmc"); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - - return dev; -} - -static inline DeviceState *milkymist_vgafb_create(hwaddr base, - uint32_t fb_offset, uint32_t fb_mask) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-vgafb"); - qdev_prop_set_uint32(dev, "fb_offset", fb_offset); - qdev_prop_set_uint32(dev, "fb_mask", fb_mask); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - - return dev; -} - -static inline DeviceState *milkymist_sysctl_create(hwaddr base, - qemu_irq gpio_irq, qemu_irq timer0_irq, qemu_irq timer1_irq, - uint32_t freq_hz, uint32_t system_id, uint32_t capabilities, - uint32_t gpio_strappings) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-sysctl"); - qdev_prop_set_uint32(dev, "frequency", freq_hz); - qdev_prop_set_uint32(dev, "systemid", system_id); - qdev_prop_set_uint32(dev, "capabilities", capabilities); - qdev_prop_set_uint32(dev, "gpio_strappings", gpio_strappings); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, gpio_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, timer0_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, timer1_irq); - - return dev; -} - -static inline DeviceState *milkymist_pfpu_create(hwaddr base, - qemu_irq irq) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-pfpu"); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -static inline DeviceState *milkymist_ac97_create(hwaddr base, - qemu_irq crrequest_irq, qemu_irq crreply_irq, qemu_irq dmar_irq, - qemu_irq dmaw_irq) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-ac97"); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, crrequest_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, crreply_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, dmar_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 3, dmaw_irq); - - return dev; -} - -static inline DeviceState *milkymist_minimac2_create(hwaddr base, - hwaddr buffers_base, qemu_irq rx_irq, qemu_irq tx_irq) -{ - DeviceState *dev; - - qemu_check_nic_model(&nd_table[0], "minimac2"); - dev = qdev_new("milkymist-minimac2"); - qdev_set_nic_properties(dev, &nd_table[0]); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, buffers_base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, rx_irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, tx_irq); - - return dev; -} - -static inline DeviceState *milkymist_softusb_create(hwaddr base, - qemu_irq irq, uint32_t pmem_base, uint32_t pmem_size, - uint32_t dmem_base, uint32_t dmem_size) -{ - DeviceState *dev; - - dev = qdev_new("milkymist-softusb"); - qdev_prop_set_uint32(dev, "pmem_size", pmem_size); - qdev_prop_set_uint32(dev, "dmem_size", dmem_size); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, pmem_base); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, dmem_base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - - return dev; -} - -#endif /* QEMU_HW_MILKYMIST_HW_H */ diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c deleted file mode 100644 index bef7855328..0000000000 --- a/hw/lm32/milkymist.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * QEMU model for the Milkymist board. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "qemu/error-report.h" -#include "qemu-common.h" -#include "qemu/datadir.h" -#include "cpu.h" -#include "hw/sysbus.h" -#include "hw/irq.h" -#include "hw/block/flash.h" -#include "sysemu/sysemu.h" -#include "sysemu/qtest.h" -#include "sysemu/reset.h" -#include "hw/boards.h" -#include "hw/loader.h" -#include "hw/qdev-properties.h" -#include "elf.h" -#include "milkymist-hw.h" -#include "hw/display/milkymist_tmu2.h" -#include "hw/sd/sd.h" -#include "lm32.h" -#include "qemu/cutils.h" - -#define BIOS_FILENAME "mmone-bios.bin" -#define BIOS_OFFSET 0x00860000 -#define BIOS_SIZE (512 * KiB) -#define KERNEL_LOAD_ADDR 0x40000000 - -typedef struct { - LM32CPU *cpu; - hwaddr bootstrap_pc; - hwaddr flash_base; - hwaddr initrd_base; - size_t initrd_size; - hwaddr cmdline_base; -} ResetInfo; - -static void cpu_irq_handler(void *opaque, int irq, int level) -{ - LM32CPU *cpu = opaque; - CPUState *cs = CPU(cpu); - - if (level) { - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } -} - -static void main_cpu_reset(void *opaque) -{ - ResetInfo *reset_info = opaque; - CPULM32State *env = &reset_info->cpu->env; - - cpu_reset(CPU(reset_info->cpu)); - - /* init defaults */ - env->pc = reset_info->bootstrap_pc; - env->regs[R_R1] = reset_info->cmdline_base; - env->regs[R_R2] = reset_info->initrd_base; - env->regs[R_R3] = reset_info->initrd_base + reset_info->initrd_size; - env->eba = reset_info->flash_base; - env->deba = reset_info->flash_base; -} - -static DeviceState *milkymist_memcard_create(hwaddr base) -{ - DeviceState *dev; - DriveInfo *dinfo; - - dev = qdev_new("milkymist-memcard"); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - - dinfo = drive_get_next(IF_SD); - if (dinfo) { - DeviceState *card; - - card = qdev_new(TYPE_SD_CARD); - qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo), - &error_fatal); - qdev_realize_and_unref(card, qdev_get_child_bus(dev, "sd-bus"), - &error_fatal); - } - - return dev; -} - -static void -milkymist_init(MachineState *machine) -{ - MachineClass *mc = MACHINE_GET_CLASS(machine); - const char *bios_name = machine->firmware ?: BIOS_FILENAME; - const char *kernel_filename = machine->kernel_filename; - const char *kernel_cmdline = machine->kernel_cmdline; - const char *initrd_filename = machine->initrd_filename; - LM32CPU *cpu; - CPULM32State *env; - int kernel_size; - DriveInfo *dinfo; - MemoryRegion *address_space_mem = get_system_memory(); - qemu_irq irq[32]; - int i; - char *bios_filename; - ResetInfo *reset_info; - - if (machine->ram_size != mc->default_ram_size) { - char *sz = size_to_str(mc->default_ram_size); - error_report("Invalid RAM size, should be %s", sz); - g_free(sz); - exit(EXIT_FAILURE); - } - - /* memory map */ - hwaddr flash_base = 0x00000000; - size_t flash_sector_size = 128 * KiB; - size_t flash_size = 32 * MiB; - hwaddr sdram_base = 0x40000000; - - hwaddr initrd_base = sdram_base + 0x1002000; - hwaddr cmdline_base = sdram_base + 0x1000000; - size_t initrd_max = machine->ram_size - 0x1002000; - - reset_info = g_malloc0(sizeof(ResetInfo)); - - cpu = LM32_CPU(cpu_create(machine->cpu_type)); - - env = &cpu->env; - reset_info->cpu = cpu; - - cpu_lm32_set_phys_msb_ignore(env, 1); - - memory_region_add_subregion(address_space_mem, sdram_base, machine->ram); - - dinfo = drive_get(IF_PFLASH, 0, 0); - /* Numonyx JS28F256J3F105 */ - pflash_cfi01_register(flash_base, "milkymist.flash", flash_size, - dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, - flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1); - - /* create irq lines */ - env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0)); - for (i = 0; i < 32; i++) { - irq[i] = qdev_get_gpio_in(env->pic_state, i); - } - - /* load bios rom */ - bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - - if (bios_filename) { - if (load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE) < 0) { - error_report("could not load bios '%s'", bios_filename); - exit(1); - } - } - - reset_info->bootstrap_pc = BIOS_OFFSET; - - /* if no kernel is given no valid bios rom is a fatal error */ - if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) { - error_report("could not load Milkymist One bios '%s'", bios_name); - exit(1); - } - g_free(bios_filename); - - milkymist_uart_create(0x60000000, irq[0], serial_hd(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[4], irq[5], irq[6], irq[7]); - milkymist_pfpu_create(0x60006000, irq[8]); - if (machine->enable_graphics) { - 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 */ - env->juart_state = lm32_juart_init(serial_hd(1)); - - if (kernel_filename) { - uint64_t entry; - - /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, - &entry, NULL, NULL, NULL, - 1, EM_LATTICEMICO32, 0, 0); - reset_info->bootstrap_pc = entry; - - if (kernel_size < 0) { - kernel_size = load_image_targphys(kernel_filename, sdram_base, - machine->ram_size); - reset_info->bootstrap_pc = sdram_base; - } - - if (kernel_size < 0) { - error_report("could not load kernel '%s'", kernel_filename); - exit(1); - } - } - - if (kernel_cmdline && strlen(kernel_cmdline)) { - pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, - kernel_cmdline); - reset_info->cmdline_base = (uint32_t)cmdline_base; - } - - if (initrd_filename) { - size_t initrd_size; - initrd_size = load_image_targphys(initrd_filename, initrd_base, - initrd_max); - reset_info->initrd_base = (uint32_t)initrd_base; - reset_info->initrd_size = (uint32_t)initrd_size; - } - - qemu_register_reset(main_cpu_reset, reset_info); -} - -static void milkymist_machine_init(MachineClass *mc) -{ - mc->desc = "Milkymist One"; - mc->init = milkymist_init; - mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full"); - mc->default_ram_size = 128 * MiB; - mc->default_ram_id = "milkymist.sdram"; -} - -DEFINE_MACHINE("milkymist", milkymist_machine_init) diff --git a/hw/meson.build b/hw/meson.build index 503cbc974f..56ce810c4b 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -47,7 +47,6 @@ subdir('avr') subdir('cris') subdir('hppa') subdir('i386') -subdir('lm32') subdir('m68k') subdir('microblaze') subdir('mips') diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 1e7b8b064b..f934d79e29 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -63,7 +63,6 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files( 'imx_ccm.c', 'imx_rngc.c', )) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-hpdmc.c', 'milkymist-pfpu.c')) softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c')) softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files( 'npcm7xx_clk.c', diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c deleted file mode 100644 index 09a3875f02..0000000000 --- a/hw/misc/milkymist-hpdmc.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * QEMU model of the Milkymist High Performance Dynamic Memory Controller. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/hpdmc.pdf - */ - -#include "qemu/osdep.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -enum { - R_SYSTEM = 0, - R_BYPASS, - R_TIMING, - R_IODELAY, - R_MAX -}; - -enum { - IODELAY_DQSDELAY_RDY = (1<<5), - IODELAY_PLL1_LOCKED = (1<<6), - IODELAY_PLL2_LOCKED = (1<<7), -}; - -#define TYPE_MILKYMIST_HPDMC "milkymist-hpdmc" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistHpdmcState, MILKYMIST_HPDMC) - -struct MilkymistHpdmcState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - - uint32_t regs[R_MAX]; -}; - -static uint64_t hpdmc_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistHpdmcState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_SYSTEM: - case R_BYPASS: - case R_TIMING: - case R_IODELAY: - r = s->regs[addr]; - break; - - default: - error_report("milkymist_hpdmc: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_hpdmc_memory_read(addr << 2, r); - - return r; -} - -static void hpdmc_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistHpdmcState *s = opaque; - - trace_milkymist_hpdmc_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_SYSTEM: - case R_BYPASS: - case R_TIMING: - s->regs[addr] = value; - break; - case R_IODELAY: - /* ignore writes */ - break; - - default: - error_report("milkymist_hpdmc: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } -} - -static const MemoryRegionOps hpdmc_mmio_ops = { - .read = hpdmc_read, - .write = hpdmc_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_hpdmc_reset(DeviceState *d) -{ - MilkymistHpdmcState *s = MILKYMIST_HPDMC(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - /* defaults */ - s->regs[R_IODELAY] = IODELAY_DQSDELAY_RDY | IODELAY_PLL1_LOCKED - | IODELAY_PLL2_LOCKED; -} - -static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp) -{ - MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev); - - memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s, - "milkymist-hpdmc", R_MAX * 4); - sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region); -} - -static const VMStateDescription vmstate_milkymist_hpdmc = { - .name = "milkymist-hpdmc", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistHpdmcState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_hpdmc_realize; - dc->reset = milkymist_hpdmc_reset; - dc->vmsd = &vmstate_milkymist_hpdmc; -} - -static const TypeInfo milkymist_hpdmc_info = { - .name = TYPE_MILKYMIST_HPDMC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistHpdmcState), - .class_init = milkymist_hpdmc_class_init, -}; - -static void milkymist_hpdmc_register_types(void) -{ - type_register_static(&milkymist_hpdmc_info); -} - -type_init(milkymist_hpdmc_register_types) diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c deleted file mode 100644 index e4ee209c10..0000000000 --- a/hw/misc/milkymist-pfpu.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * QEMU model of the Milkymist programmable FPU. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/pfpu.pdf - * - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qemu/log.h" -#include "qemu/module.h" -#include "qemu/error-report.h" -#include <math.h> -#include "qom/object.h" - -/* #define TRACE_EXEC */ - -#ifdef TRACE_EXEC -# define D_EXEC(x) x -#else -# define D_EXEC(x) -#endif - -enum { - R_CTL = 0, - R_MESHBASE, - R_HMESHLAST, - R_VMESHLAST, - R_CODEPAGE, - R_VERTICES, - R_COLLISIONS, - R_STRAYWRITES, - R_LASTDMA, - R_PC, - R_DREGBASE, - R_CODEBASE, - R_MAX -}; - -enum { - CTL_START_BUSY = (1<<0), -}; - -enum { - OP_NOP = 0, - OP_FADD, - OP_FSUB, - OP_FMUL, - OP_FABS, - OP_F2I, - OP_I2F, - OP_VECTOUT, - OP_SIN, - OP_COS, - OP_ABOVE, - OP_EQUAL, - OP_COPY, - OP_IF, - OP_TSIGN, - OP_QUAKE, -}; - -enum { - GPR_X = 0, - GPR_Y = 1, - GPR_FLAGS = 2, -}; - -enum { - LATENCY_FADD = 5, - LATENCY_FSUB = 5, - LATENCY_FMUL = 7, - LATENCY_FABS = 2, - LATENCY_F2I = 2, - LATENCY_I2F = 3, - LATENCY_VECTOUT = 0, - LATENCY_SIN = 4, - LATENCY_COS = 4, - LATENCY_ABOVE = 2, - LATENCY_EQUAL = 2, - LATENCY_COPY = 2, - LATENCY_IF = 2, - LATENCY_TSIGN = 2, - LATENCY_QUAKE = 2, - MAX_LATENCY = 7 -}; - -#define GPR_BEGIN 0x100 -#define GPR_END 0x17f -#define MICROCODE_BEGIN 0x200 -#define MICROCODE_END 0x3ff -#define MICROCODE_WORDS 2048 - -#define REINTERPRET_CAST(type, val) (*((type *)&(val))) - -#ifdef TRACE_EXEC -static const char *opcode_to_str[] = { - "NOP", "FADD", "FSUB", "FMUL", "FABS", "F2I", "I2F", "VECTOUT", - "SIN", "COS", "ABOVE", "EQUAL", "COPY", "IF", "TSIGN", "QUAKE", -}; -#endif - -#define TYPE_MILKYMIST_PFPU "milkymist-pfpu" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistPFPUState, MILKYMIST_PFPU) - -struct MilkymistPFPUState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - Chardev *chr; - qemu_irq irq; - - uint32_t regs[R_MAX]; - uint32_t gp_regs[128]; - uint32_t microcode[MICROCODE_WORDS]; - - int output_queue_pos; - uint32_t output_queue[MAX_LATENCY]; -}; - -static inline uint32_t -get_dma_address(uint32_t base, uint32_t x, uint32_t y) -{ - return base + 8 * (128 * y + x); -} - -static inline void -output_queue_insert(MilkymistPFPUState *s, uint32_t val, int pos) -{ - s->output_queue[(s->output_queue_pos + pos) % MAX_LATENCY] = val; -} - -static inline uint32_t -output_queue_remove(MilkymistPFPUState *s) -{ - return s->output_queue[s->output_queue_pos]; -} - -static inline void -output_queue_advance(MilkymistPFPUState *s) -{ - s->output_queue[s->output_queue_pos] = 0; - s->output_queue_pos = (s->output_queue_pos + 1) % MAX_LATENCY; -} - -static int pfpu_decode_insn(MilkymistPFPUState *s) -{ - uint32_t pc = s->regs[R_PC]; - uint32_t insn = s->microcode[pc]; - uint32_t reg_a = (insn >> 18) & 0x7f; - uint32_t reg_b = (insn >> 11) & 0x7f; - uint32_t op = (insn >> 7) & 0xf; - uint32_t reg_d = insn & 0x7f; - uint32_t r = 0; - int latency = 0; - - switch (op) { - case OP_NOP: - break; - case OP_FADD: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = a + b; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_FADD; - D_EXEC(qemu_log("ADD a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_FSUB: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = a - b; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_FSUB; - D_EXEC(qemu_log("SUB a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_FMUL: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = a * b; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_FMUL; - D_EXEC(qemu_log("MUL a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_FABS: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float t = fabsf(a); - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_FABS; - D_EXEC(qemu_log("ABS a=%f t=%f, r=%08x\n", a, t, r)); - } break; - case OP_F2I: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - int32_t t = a; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_F2I; - D_EXEC(qemu_log("F2I a=%f t=%d, r=%08x\n", a, t, r)); - } break; - case OP_I2F: - { - int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]); - float t = a; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_I2F; - D_EXEC(qemu_log("I2F a=%08x t=%f, r=%08x\n", a, t, r)); - } break; - case OP_VECTOUT: - { - uint32_t a = cpu_to_be32(s->gp_regs[reg_a]); - uint32_t b = cpu_to_be32(s->gp_regs[reg_b]); - hwaddr dma_ptr = - get_dma_address(s->regs[R_MESHBASE], - s->gp_regs[GPR_X], s->gp_regs[GPR_Y]); - cpu_physical_memory_write(dma_ptr, &a, 4); - cpu_physical_memory_write(dma_ptr + 4, &b, 4); - s->regs[R_LASTDMA] = dma_ptr + 4; - D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr)); - trace_milkymist_pfpu_vectout(a, b, dma_ptr); - } break; - case OP_SIN: - { - int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]); - float t = sinf(a * (1.0f / (M_PI * 4096.0f))); - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_SIN; - D_EXEC(qemu_log("SIN a=%d t=%f, r=%08x\n", a, t, r)); - } break; - case OP_COS: - { - int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]); - float t = cosf(a * (1.0f / (M_PI * 4096.0f))); - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_COS; - D_EXEC(qemu_log("COS a=%d t=%f, r=%08x\n", a, t, r)); - } break; - case OP_ABOVE: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = (a > b) ? 1.0f : 0.0f; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_ABOVE; - D_EXEC(qemu_log("ABOVE a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_EQUAL: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = (a == b) ? 1.0f : 0.0f; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_EQUAL; - D_EXEC(qemu_log("EQUAL a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_COPY: - { - r = s->gp_regs[reg_a]; - latency = LATENCY_COPY; - D_EXEC(qemu_log("COPY")); - } break; - case OP_IF: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - uint32_t f = s->gp_regs[GPR_FLAGS]; - float t = (f != 0) ? a : b; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_IF; - D_EXEC(qemu_log("IF f=%u a=%f b=%f t=%f, r=%08x\n", f, a, b, t, r)); - } break; - case OP_TSIGN: - { - float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]); - float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]); - float t = (b < 0) ? -a : a; - r = REINTERPRET_CAST(uint32_t, t); - latency = LATENCY_TSIGN; - D_EXEC(qemu_log("TSIGN a=%f b=%f t=%f, r=%08x\n", a, b, t, r)); - } break; - case OP_QUAKE: - { - uint32_t a = s->gp_regs[reg_a]; - r = 0x5f3759df - (a >> 1); - latency = LATENCY_QUAKE; - D_EXEC(qemu_log("QUAKE a=%d r=%08x\n", a, r)); - } break; - - default: - error_report("milkymist_pfpu: unknown opcode %d", op); - break; - } - - if (!reg_d) { - D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d>\n", - s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency, - s->regs[R_PC] + latency)); - } else { - D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d> -> R%03d\n", - s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency, - s->regs[R_PC] + latency, reg_d)); - } - - if (op == OP_VECTOUT) { - return 0; - } - - /* store output for this cycle */ - if (reg_d) { - uint32_t val = output_queue_remove(s); - D_EXEC(qemu_log("R%03d <- 0x%08x\n", reg_d, val)); - s->gp_regs[reg_d] = val; - } - - output_queue_advance(s); - - /* store op output */ - if (op != OP_NOP) { - output_queue_insert(s, r, latency-1); - } - - /* advance PC */ - s->regs[R_PC]++; - - return 1; -}; - -static void pfpu_start(MilkymistPFPUState *s) -{ - int x, y; - int i; - - for (y = 0; y <= s->regs[R_VMESHLAST]; y++) { - for (x = 0; x <= s->regs[R_HMESHLAST]; x++) { - D_EXEC(qemu_log("\nprocessing x=%d y=%d\n", x, y)); - - /* set current position */ - s->gp_regs[GPR_X] = x; - s->gp_regs[GPR_Y] = y; - - /* run microcode on this position */ - i = 0; - while (pfpu_decode_insn(s)) { - /* decode at most MICROCODE_WORDS instructions */ - if (++i >= MICROCODE_WORDS) { - error_report("milkymist_pfpu: too many instructions " - "executed in microcode. No VECTOUT?"); - break; - } - } - - /* reset pc for next run */ - s->regs[R_PC] = 0; - } - } - - s->regs[R_VERTICES] = x * y; - - trace_milkymist_pfpu_pulse_irq(); - qemu_irq_pulse(s->irq); -} - -static inline int get_microcode_address(MilkymistPFPUState *s, uint32_t addr) -{ - return (512 * s->regs[R_CODEPAGE]) + addr - MICROCODE_BEGIN; -} - -static uint64_t pfpu_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistPFPUState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_CTL: - case R_MESHBASE: - case R_HMESHLAST: - case R_VMESHLAST: - case R_CODEPAGE: - case R_VERTICES: - case R_COLLISIONS: - case R_STRAYWRITES: - case R_LASTDMA: - case R_PC: - case R_DREGBASE: - case R_CODEBASE: - r = s->regs[addr]; - break; - case GPR_BEGIN ... GPR_END: - r = s->gp_regs[addr - GPR_BEGIN]; - break; - case MICROCODE_BEGIN ... MICROCODE_END: - r = s->microcode[get_microcode_address(s, addr)]; - break; - - default: - error_report("milkymist_pfpu: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_pfpu_memory_read(addr << 2, r); - - return r; -} - -static void pfpu_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistPFPUState *s = opaque; - - trace_milkymist_pfpu_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_CTL: - if (value & CTL_START_BUSY) { - pfpu_start(s); - } - break; - case R_MESHBASE: - case R_HMESHLAST: - case R_VMESHLAST: - case R_CODEPAGE: - case R_VERTICES: - case R_COLLISIONS: - case R_STRAYWRITES: - case R_LASTDMA: - case R_PC: - case R_DREGBASE: - case R_CODEBASE: - s->regs[addr] = value; - break; - case GPR_BEGIN ... GPR_END: - s->gp_regs[addr - GPR_BEGIN] = value; - break; - case MICROCODE_BEGIN ... MICROCODE_END: - s->microcode[get_microcode_address(s, addr)] = value; - break; - - default: - error_report("milkymist_pfpu: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } -} - -static const MemoryRegionOps pfpu_mmio_ops = { - .read = pfpu_read, - .write = pfpu_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_pfpu_reset(DeviceState *d) -{ - MilkymistPFPUState *s = MILKYMIST_PFPU(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - for (i = 0; i < 128; i++) { - s->gp_regs[i] = 0; - } - for (i = 0; i < MICROCODE_WORDS; i++) { - s->microcode[i] = 0; - } - s->output_queue_pos = 0; - for (i = 0; i < MAX_LATENCY; i++) { - s->output_queue[i] = 0; - } -} - -static void milkymist_pfpu_realize(DeviceState *dev, Error **errp) -{ - MilkymistPFPUState *s = MILKYMIST_PFPU(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - - sysbus_init_irq(sbd, &s->irq); - - memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s, - "milkymist-pfpu", MICROCODE_END * 4); - sysbus_init_mmio(sbd, &s->regs_region); -} - -static const VMStateDescription vmstate_milkymist_pfpu = { - .name = "milkymist-pfpu", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistPFPUState, R_MAX), - VMSTATE_UINT32_ARRAY(gp_regs, MilkymistPFPUState, 128), - VMSTATE_UINT32_ARRAY(microcode, MilkymistPFPUState, MICROCODE_WORDS), - VMSTATE_INT32(output_queue_pos, MilkymistPFPUState), - VMSTATE_UINT32_ARRAY(output_queue, MilkymistPFPUState, MAX_LATENCY), - VMSTATE_END_OF_LIST() - } -}; - -static void milkymist_pfpu_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_pfpu_realize; - dc->reset = milkymist_pfpu_reset; - dc->vmsd = &vmstate_milkymist_pfpu; -} - -static const TypeInfo milkymist_pfpu_info = { - .name = TYPE_MILKYMIST_PFPU, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistPFPUState), - .class_init = milkymist_pfpu_class_init, -}; - -static void milkymist_pfpu_register_types(void) -{ - type_register_static(&milkymist_pfpu_info); -} - -type_init(milkymist_pfpu_register_types) diff --git a/hw/misc/trace-events b/hw/misc/trace-events index d0a89eb059..0752217636 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -67,16 +67,6 @@ slavio_sysctrl_mem_readl(uint32_t ret) "Read system control 0x%08x" slavio_led_mem_writew(uint32_t val) "Write diagnostic LED 0x%04x" slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x" -# milkymist-hpdmc.c -milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=0x%08x value=0x%08x" -milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=0x%08x value=0x%08x" - -# milkymist-pfpu.c -milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a 0x%08x b 0x%08x dma_ptr 0x%08x" -milkymist_pfpu_pulse_irq(void) "Pulse IRQ" - # aspeed_scu.c aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32 diff --git a/hw/net/meson.build b/hw/net/meson.build index af0749c42b..bdf71f1f40 100644 --- a/hw/net/meson.build +++ b/hw/net/meson.build @@ -39,7 +39,6 @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c')) softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c')) softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c')) -specific_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-minimac2.c')) specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_llan.c')) specific_ss.add(when: 'CONFIG_XILINX_ETHLITE', if_true: files('xilinx_ethlite.c')) diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c deleted file mode 100644 index 5826944fd5..0000000000 --- a/hw/net/milkymist-minimac2.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * QEMU model of the Milkymist minimac2 block. - * - * Copyright (c) 2011 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * not available yet - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qom/object.h" -#include "cpu.h" /* FIXME: why does this use TARGET_PAGE_ALIGN? */ -#include "hw/irq.h" -#include "hw/qdev-properties.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "net/net.h" -#include "qemu/log.h" -#include "qemu/module.h" -#include "qemu/error-report.h" - -#include <zlib.h> - -enum { - R_SETUP = 0, - R_MDIO, - R_STATE0, - R_COUNT0, - R_STATE1, - R_COUNT1, - R_TXCOUNT, - R_MAX -}; - -enum { - SETUP_PHY_RST = (1<<0), -}; - -enum { - MDIO_DO = (1<<0), - MDIO_DI = (1<<1), - MDIO_OE = (1<<2), - MDIO_CLK = (1<<3), -}; - -enum { - STATE_EMPTY = 0, - STATE_LOADED = 1, - STATE_PENDING = 2, -}; - -enum { - MDIO_OP_WRITE = 1, - MDIO_OP_READ = 2, -}; - -enum mdio_state { - MDIO_STATE_IDLE, - MDIO_STATE_READING, - MDIO_STATE_WRITING, -}; - -enum { - R_PHY_ID1 = 2, - R_PHY_ID2 = 3, - R_PHY_MAX = 32 -}; - -#define MINIMAC2_MTU 1530 -#define MINIMAC2_BUFFER_SIZE 2048 - -struct MilkymistMinimac2MdioState { - int last_clk; - int count; - uint32_t data; - uint16_t data_out; - int state; - - uint8_t phy_addr; - uint8_t reg_addr; -}; -typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState; - -#define TYPE_MILKYMIST_MINIMAC2 "milkymist-minimac2" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistMinimac2State, MILKYMIST_MINIMAC2) - -struct MilkymistMinimac2State { - SysBusDevice parent_obj; - - NICState *nic; - NICConf conf; - char *phy_model; - MemoryRegion buffers; - MemoryRegion regs_region; - - qemu_irq rx_irq; - qemu_irq tx_irq; - - uint32_t regs[R_MAX]; - - MilkymistMinimac2MdioState mdio; - - uint16_t phy_regs[R_PHY_MAX]; - - uint8_t *rx0_buf; - uint8_t *rx1_buf; - uint8_t *tx_buf; -}; - -static const uint8_t preamble_sfd[] = { - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5 -}; - -static void minimac2_mdio_write_reg(MilkymistMinimac2State *s, - uint8_t phy_addr, uint8_t reg_addr, uint16_t value) -{ - trace_milkymist_minimac2_mdio_write(phy_addr, reg_addr, value); - - /* nop */ -} - -static uint16_t minimac2_mdio_read_reg(MilkymistMinimac2State *s, - uint8_t phy_addr, uint8_t reg_addr) -{ - uint16_t r = s->phy_regs[reg_addr]; - - trace_milkymist_minimac2_mdio_read(phy_addr, reg_addr, r); - - return r; -} - -static void minimac2_update_mdio(MilkymistMinimac2State *s) -{ - MilkymistMinimac2MdioState *m = &s->mdio; - - /* detect rising clk edge */ - if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) { - /* shift data in */ - int bit = ((s->regs[R_MDIO] & MDIO_DO) - && (s->regs[R_MDIO] & MDIO_OE)) ? 1 : 0; - m->data = (m->data << 1) | bit; - - /* check for sync */ - if (m->data == 0xffffffff) { - m->count = 32; - } - - if (m->count == 16) { - uint8_t start = (m->data >> 14) & 0x3; - uint8_t op = (m->data >> 12) & 0x3; - uint8_t ta = (m->data) & 0x3; - - if (start == 1 && op == MDIO_OP_WRITE && ta == 2) { - m->state = MDIO_STATE_WRITING; - } else if (start == 1 && op == MDIO_OP_READ && (ta & 1) == 0) { - m->state = MDIO_STATE_READING; - } else { - m->state = MDIO_STATE_IDLE; - } - - if (m->state != MDIO_STATE_IDLE) { - m->phy_addr = (m->data >> 7) & 0x1f; - m->reg_addr = (m->data >> 2) & 0x1f; - } - - if (m->state == MDIO_STATE_READING) { - m->data_out = minimac2_mdio_read_reg(s, m->phy_addr, - m->reg_addr); - } - } - - if (m->count < 16 && m->state == MDIO_STATE_READING) { - int bit = (m->data_out & 0x8000) ? 1 : 0; - m->data_out <<= 1; - - if (bit) { - s->regs[R_MDIO] |= MDIO_DI; - } else { - s->regs[R_MDIO] &= ~MDIO_DI; - } - } - - if (m->count == 0 && m->state) { - if (m->state == MDIO_STATE_WRITING) { - uint16_t data = m->data & 0xffff; - minimac2_mdio_write_reg(s, m->phy_addr, m->reg_addr, data); - } - m->state = MDIO_STATE_IDLE; - } - m->count--; - } - - m->last_clk = (s->regs[R_MDIO] & MDIO_CLK) ? 1 : 0; -} - -static size_t assemble_frame(uint8_t *buf, size_t size, - const uint8_t *payload, size_t payload_size) -{ - uint32_t crc; - - if (size < payload_size + 12) { - qemu_log_mask(LOG_GUEST_ERROR, "milkymist_minimac2: frame too big " - "(%zd bytes)\n", payload_size); - return 0; - } - - /* prepend preamble and sfd */ - memcpy(buf, preamble_sfd, 8); - - /* now copy the payload */ - memcpy(buf + 8, payload, payload_size); - - /* pad frame if needed */ - if (payload_size < 60) { - memset(buf + payload_size + 8, 0, 60 - payload_size); - payload_size = 60; - } - - /* append fcs */ - crc = cpu_to_le32(crc32(0, buf + 8, payload_size)); - memcpy(buf + payload_size + 8, &crc, 4); - - return payload_size + 12; -} - -static void minimac2_tx(MilkymistMinimac2State *s) -{ - uint32_t txcount = s->regs[R_TXCOUNT]; - uint8_t *buf = s->tx_buf; - - if (txcount < 64) { - error_report("milkymist_minimac2: ethernet frame too small (%u < %u)", - txcount, 64); - goto err; - } - - if (txcount > MINIMAC2_MTU) { - error_report("milkymist_minimac2: MTU exceeded (%u > %u)", - txcount, MINIMAC2_MTU); - goto err; - } - - if (memcmp(buf, preamble_sfd, 8) != 0) { - error_report("milkymist_minimac2: frame doesn't contain the preamble " - "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); - goto err; - } - - trace_milkymist_minimac2_tx_frame(txcount - 12); - - /* send packet, skipping preamble and sfd */ - qemu_send_packet_raw(qemu_get_queue(s->nic), buf + 8, txcount - 12); - - s->regs[R_TXCOUNT] = 0; - -err: - trace_milkymist_minimac2_pulse_irq_tx(); - qemu_irq_pulse(s->tx_irq); -} - -static void update_rx_interrupt(MilkymistMinimac2State *s) -{ - if (s->regs[R_STATE0] == STATE_PENDING - || s->regs[R_STATE1] == STATE_PENDING) { - trace_milkymist_minimac2_raise_irq_rx(); - qemu_irq_raise(s->rx_irq); - } else { - trace_milkymist_minimac2_lower_irq_rx(); - qemu_irq_lower(s->rx_irq); - } -} - -static ssize_t minimac2_rx(NetClientState *nc, const uint8_t *buf, size_t size) -{ - MilkymistMinimac2State *s = qemu_get_nic_opaque(nc); - - uint32_t r_count; - uint32_t r_state; - uint8_t *rx_buf; - - size_t frame_size; - - trace_milkymist_minimac2_rx_frame(buf, size); - - /* choose appropriate slot */ - if (s->regs[R_STATE0] == STATE_LOADED) { - r_count = R_COUNT0; - r_state = R_STATE0; - rx_buf = s->rx0_buf; - } else if (s->regs[R_STATE1] == STATE_LOADED) { - r_count = R_COUNT1; - r_state = R_STATE1; - rx_buf = s->rx1_buf; - } else { - return 0; - } - - /* assemble frame */ - frame_size = assemble_frame(rx_buf, MINIMAC2_BUFFER_SIZE, buf, size); - - if (frame_size == 0) { - return size; - } - - trace_milkymist_minimac2_rx_transfer(rx_buf, frame_size); - - /* update slot */ - s->regs[r_count] = frame_size; - s->regs[r_state] = STATE_PENDING; - - update_rx_interrupt(s); - - return size; -} - -static uint64_t -minimac2_read(void *opaque, hwaddr addr, unsigned size) -{ - MilkymistMinimac2State *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_SETUP: - case R_MDIO: - case R_STATE0: - case R_COUNT0: - case R_STATE1: - case R_COUNT1: - case R_TXCOUNT: - r = s->regs[addr]; - break; - - default: - qemu_log_mask(LOG_GUEST_ERROR, - "milkymist_minimac2_rd%d: 0x%" HWADDR_PRIx "\n", - size, addr << 2); - break; - } - - trace_milkymist_minimac2_memory_read(addr << 2, r); - - return r; -} - -static int minimac2_can_rx(MilkymistMinimac2State *s) -{ - if (s->regs[R_STATE0] == STATE_LOADED) { - return 1; - } - if (s->regs[R_STATE1] == STATE_LOADED) { - return 1; - } - - return 0; -} - -static void -minimac2_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistMinimac2State *s = opaque; - - trace_milkymist_minimac2_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_MDIO: - { - /* MDIO_DI is read only */ - int mdio_di = (s->regs[R_MDIO] & MDIO_DI); - s->regs[R_MDIO] = value; - if (mdio_di) { - s->regs[R_MDIO] |= mdio_di; - } else { - s->regs[R_MDIO] &= ~mdio_di; - } - - minimac2_update_mdio(s); - } break; - case R_TXCOUNT: - s->regs[addr] = value; - if (value > 0) { - minimac2_tx(s); - } - break; - case R_STATE0: - case R_STATE1: - s->regs[addr] = value; - update_rx_interrupt(s); - if (minimac2_can_rx(s)) { - qemu_flush_queued_packets(qemu_get_queue(s->nic)); - } - break; - case R_SETUP: - case R_COUNT0: - case R_COUNT1: - s->regs[addr] = value; - break; - - default: - qemu_log_mask(LOG_GUEST_ERROR, - "milkymist_minimac2_wr%d: 0x%" HWADDR_PRIx - " = 0x%" PRIx64 "\n", - size, addr << 2, value); - break; - } -} - -static const MemoryRegionOps minimac2_ops = { - .read = minimac2_read, - .write = minimac2_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_minimac2_reset(DeviceState *d) -{ - MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - for (i = 0; i < R_PHY_MAX; i++) { - s->phy_regs[i] = 0; - } - - /* defaults */ - s->phy_regs[R_PHY_ID1] = 0x0022; /* Micrel KSZ8001L */ - s->phy_regs[R_PHY_ID2] = 0x161a; -} - -static NetClientInfo net_milkymist_minimac2_info = { - .type = NET_CLIENT_DRIVER_NIC, - .size = sizeof(NICState), - .receive = minimac2_rx, -}; - -static void milkymist_minimac2_realize(DeviceState *dev, Error **errp) -{ - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev); - size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE); - - sysbus_init_irq(sbd, &s->rx_irq); - sysbus_init_irq(sbd, &s->tx_irq); - - memory_region_init_io(&s->regs_region, OBJECT(dev), &minimac2_ops, s, - "milkymist-minimac2", R_MAX * 4); - sysbus_init_mmio(sbd, &s->regs_region); - - /* register buffers memory */ - memory_region_init_ram_nomigrate(&s->buffers, OBJECT(dev), "milkymist-minimac2.buffers", - buffers_size, &error_fatal); - vmstate_register_ram_global(&s->buffers); - s->rx0_buf = memory_region_get_ram_ptr(&s->buffers); - s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE; - s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE; - - sysbus_init_mmio(sbd, &s->buffers); - - qemu_macaddr_default_if_unset(&s->conf.macaddr); - s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf, - object_get_typename(OBJECT(dev)), dev->id, s); - qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); -} - -static const VMStateDescription vmstate_milkymist_minimac2_mdio = { - .name = "milkymist-minimac2-mdio", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_INT32(last_clk, MilkymistMinimac2MdioState), - VMSTATE_INT32(count, MilkymistMinimac2MdioState), - VMSTATE_UINT32(data, MilkymistMinimac2MdioState), - VMSTATE_UINT16(data_out, MilkymistMinimac2MdioState), - VMSTATE_INT32(state, MilkymistMinimac2MdioState), - VMSTATE_UINT8(phy_addr, MilkymistMinimac2MdioState), - VMSTATE_UINT8(reg_addr, MilkymistMinimac2MdioState), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription vmstate_milkymist_minimac2 = { - .name = "milkymist-minimac2", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistMinimac2State, R_MAX), - VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimac2State, R_PHY_MAX), - VMSTATE_STRUCT(mdio, MilkymistMinimac2State, 0, - vmstate_milkymist_minimac2_mdio, MilkymistMinimac2MdioState), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_minimac2_properties[] = { - DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf), - DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_minimac2_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_minimac2_realize; - dc->reset = milkymist_minimac2_reset; - dc->vmsd = &vmstate_milkymist_minimac2; - device_class_set_props(dc, milkymist_minimac2_properties); -} - -static const TypeInfo milkymist_minimac2_info = { - .name = TYPE_MILKYMIST_MINIMAC2, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistMinimac2State), - .class_init = milkymist_minimac2_class_init, -}; - -static void milkymist_minimac2_register_types(void) -{ - type_register_static(&milkymist_minimac2_info); -} - -type_init(milkymist_minimac2_register_types) diff --git a/hw/net/trace-events b/hw/net/trace-events index baf25ffa7e..314e21fa99 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -19,18 +19,6 @@ mdio_bitbang(bool mdc, bool mdio, int state, uint16_t cnt, unsigned int drive) " lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x" lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x" -# milkymist-minimac2.c -milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr 0x%02x addr 0x%02x value 0x%04x" -milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr 0x%02x addr 0x%02x value 0x%04x" -milkymist_minimac2_tx_frame(uint32_t length) "length %u" -milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u" -milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d" -milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX" -milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX" -milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX" - # mipsnet.c mipsnet_send(uint32_t size) "sending len=%u" mipsnet_receive(uint32_t size) "receiving len=%u" diff --git a/hw/sd/meson.build b/hw/sd/meson.build index 9c29691e13..f1ce357a3b 100644 --- a/hw/sd/meson.build +++ b/hw/sd/meson.build @@ -4,7 +4,6 @@ softmmu_ss.add(when: 'CONFIG_SDHCI', if_true: files('sdhci.c')) softmmu_ss.add(when: 'CONFIG_SDHCI_PCI', if_true: files('sdhci-pci.c')) softmmu_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-memcard.c')) softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_mmc.c')) softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_mmci.c')) softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c')) diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c deleted file mode 100644 index a1235aa46c..0000000000 --- a/hw/sd/milkymist-memcard.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * QEMU model of the Milkymist SD Card Controller. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/memcard.pdf - */ - -#include "qemu/osdep.h" -#include "qemu/log.h" -#include "qemu/module.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qapi/error.h" -#include "sysemu/block-backend.h" -#include "sysemu/blockdev.h" -#include "hw/qdev-properties.h" -#include "hw/sd/sd.h" -#include "qom/object.h" - -enum { - ENABLE_CMD_TX = (1<<0), - ENABLE_CMD_RX = (1<<1), - ENABLE_DAT_TX = (1<<2), - ENABLE_DAT_RX = (1<<3), -}; - -enum { - PENDING_CMD_TX = (1<<0), - PENDING_CMD_RX = (1<<1), - PENDING_DAT_TX = (1<<2), - PENDING_DAT_RX = (1<<3), -}; - -enum { - START_CMD_TX = (1<<0), - START_DAT_RX = (1<<1), -}; - -enum { - R_CLK2XDIV = 0, - R_ENABLE, - R_PENDING, - R_START, - R_CMD, - R_DAT, - R_MAX -}; - -#define TYPE_MILKYMIST_MEMCARD "milkymist-memcard" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistMemcardState, MILKYMIST_MEMCARD) - -#define TYPE_MILKYMIST_SDBUS "milkymist-sdbus" - -struct MilkymistMemcardState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - SDBus sdbus; - - int command_write_ptr; - int response_read_ptr; - int response_len; - int ignore_next_cmd; - int enabled; - uint8_t command[6]; - uint8_t response[17]; - uint32_t regs[R_MAX]; -}; - -static void update_pending_bits(MilkymistMemcardState *s) -{ - /* transmits are instantaneous, thus tx pending bits are never set */ - s->regs[R_PENDING] = 0; - /* if rx is enabled the corresponding pending bits are always set */ - if (s->regs[R_ENABLE] & ENABLE_CMD_RX) { - s->regs[R_PENDING] |= PENDING_CMD_RX; - } - if (s->regs[R_ENABLE] & ENABLE_DAT_RX) { - s->regs[R_PENDING] |= PENDING_DAT_RX; - } -} - -static void memcard_sd_command(MilkymistMemcardState *s) -{ - SDRequest req; - - req.cmd = s->command[0] & 0x3f; - req.arg = ldl_be_p(s->command + 1); - req.crc = s->command[5]; - - s->response[0] = req.cmd; - s->response_len = sdbus_do_command(&s->sdbus, &req, s->response + 1); - s->response_read_ptr = 0; - - if (s->response_len == 16) { - /* R2 response */ - s->response[0] = 0x3f; - s->response_len += 1; - } else if (s->response_len == 4) { - /* no crc calculation, insert dummy byte */ - s->response[5] = 0; - s->response_len += 2; - } - - if (req.cmd == 0) { - /* next write is a dummy byte to clock the initialization of the sd - * card */ - s->ignore_next_cmd = 1; - } -} - -static uint64_t memcard_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistMemcardState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_CMD: - if (!s->enabled) { - r = 0xff; - } else { - r = s->response[s->response_read_ptr++]; - if (s->response_read_ptr > s->response_len) { - qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: " - "read more cmd bytes than available: clipping\n"); - s->response_read_ptr = 0; - } - } - break; - case R_DAT: - if (!s->enabled) { - r = 0xffffffff; - } else { - sdbus_read_data(&s->sdbus, &r, sizeof(r)); - be32_to_cpus(&r); - } - break; - case R_CLK2XDIV: - case R_ENABLE: - case R_PENDING: - case R_START: - r = s->regs[addr]; - break; - - default: - qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " - "read access to unknown register 0x%" HWADDR_PRIx "\n", - addr << 2); - break; - } - - trace_milkymist_memcard_memory_read(addr << 2, r); - - return r; -} - -static void memcard_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistMemcardState *s = opaque; - uint32_t val32; - - trace_milkymist_memcard_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_PENDING: - /* clear rx pending bits */ - s->regs[R_PENDING] &= ~(value & (PENDING_CMD_RX | PENDING_DAT_RX)); - update_pending_bits(s); - break; - case R_CMD: - if (!s->enabled) { - break; - } - if (s->ignore_next_cmd) { - s->ignore_next_cmd = 0; - break; - } - s->command[s->command_write_ptr] = value & 0xff; - s->command_write_ptr = (s->command_write_ptr + 1) % 6; - if (s->command_write_ptr == 0) { - memcard_sd_command(s); - } - break; - case R_DAT: - if (!s->enabled) { - break; - } - val32 = cpu_to_be32(value); - sdbus_write_data(&s->sdbus, &val32, sizeof(val32)); - break; - case R_ENABLE: - s->regs[addr] = value; - update_pending_bits(s); - break; - case R_CLK2XDIV: - case R_START: - s->regs[addr] = value; - break; - - default: - qemu_log_mask(LOG_UNIMP, "milkymist_memcard: " - "write access to unknown register 0x%" HWADDR_PRIx " " - "(value 0x%" PRIx64 ")\n", addr << 2, value); - break; - } -} - -static const MemoryRegionOps memcard_mmio_ops = { - .read = memcard_read, - .write = memcard_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void milkymist_memcard_reset(DeviceState *d) -{ - MilkymistMemcardState *s = MILKYMIST_MEMCARD(d); - int i; - - s->command_write_ptr = 0; - s->response_read_ptr = 0; - s->response_len = 0; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } -} - -static void milkymist_memcard_set_readonly(DeviceState *dev, bool level) -{ - qemu_log_mask(LOG_UNIMP, - "milkymist_memcard: read-only mode not supported\n"); -} - -static void milkymist_memcard_set_inserted(DeviceState *dev, bool level) -{ - MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev); - - s->enabled = !!level; -} - -static void milkymist_memcard_init(Object *obj) -{ - MilkymistMemcardState *s = MILKYMIST_MEMCARD(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s, - "milkymist-memcard", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); - - qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, - DEVICE(obj), "sd-bus"); -} - -static const VMStateDescription vmstate_milkymist_memcard = { - .name = "milkymist-memcard", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_INT32(command_write_ptr, MilkymistMemcardState), - VMSTATE_INT32(response_read_ptr, MilkymistMemcardState), - VMSTATE_INT32(response_len, MilkymistMemcardState), - VMSTATE_INT32(ignore_next_cmd, MilkymistMemcardState), - VMSTATE_INT32(enabled, MilkymistMemcardState), - VMSTATE_UINT8_ARRAY(command, MilkymistMemcardState, 6), - VMSTATE_UINT8_ARRAY(response, MilkymistMemcardState, 17), - VMSTATE_UINT32_ARRAY(regs, MilkymistMemcardState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static void milkymist_memcard_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->reset = milkymist_memcard_reset; - dc->vmsd = &vmstate_milkymist_memcard; - /* Reason: output IRQs should be wired up */ - dc->user_creatable = false; -} - -static const TypeInfo milkymist_memcard_info = { - .name = TYPE_MILKYMIST_MEMCARD, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistMemcardState), - .instance_init = milkymist_memcard_init, - .class_init = milkymist_memcard_class_init, -}; - -static void milkymist_sdbus_class_init(ObjectClass *klass, void *data) -{ - SDBusClass *sbc = SD_BUS_CLASS(klass); - - sbc->set_inserted = milkymist_memcard_set_inserted; - sbc->set_readonly = milkymist_memcard_set_readonly; -} - -static const TypeInfo milkymist_sdbus_info = { - .name = TYPE_MILKYMIST_SDBUS, - .parent = TYPE_SD_BUS, - .instance_size = sizeof(SDBus), - .class_init = milkymist_sdbus_class_init, -}; - -static void milkymist_memcard_register_types(void) -{ - type_register_static(&milkymist_memcard_info); - type_register_static(&milkymist_sdbus_info); -} - -type_init(milkymist_memcard_register_types) diff --git a/hw/sd/trace-events b/hw/sd/trace-events index 4140e48540..e185d07a1d 100644 --- a/hw/sd/trace-events +++ b/hw/sd/trace-events @@ -55,10 +55,6 @@ sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t length) "%s %20s/ CMD%02d len %" PRIu32 sdcard_set_voltage(uint16_t millivolts) "%u mV" -# milkymist-memcard.c -milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" - # pxa2xx_mmci.c pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x" pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x" diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c deleted file mode 100644 index eeaf0ada5f..0000000000 --- a/hw/timer/lm32_timer.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * QEMU model of the LatticeMico32 timer block. - * - * Copyright (c) 2010 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://www.latticesemi.com/documents/mico32timer.pdf - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qemu/timer.h" -#include "hw/ptimer.h" -#include "hw/qdev-properties.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -#define DEFAULT_FREQUENCY (50*1000000) - -enum { - R_SR = 0, - R_CR, - R_PERIOD, - R_SNAPSHOT, - R_MAX -}; - -enum { - SR_TO = (1 << 0), - SR_RUN = (1 << 1), -}; - -enum { - CR_ITO = (1 << 0), - CR_CONT = (1 << 1), - CR_START = (1 << 2), - CR_STOP = (1 << 3), -}; - -#define TYPE_LM32_TIMER "lm32-timer" -OBJECT_DECLARE_SIMPLE_TYPE(LM32TimerState, LM32_TIMER) - -struct LM32TimerState { - SysBusDevice parent_obj; - - MemoryRegion iomem; - - ptimer_state *ptimer; - - qemu_irq irq; - uint32_t freq_hz; - - uint32_t regs[R_MAX]; -}; - -static void timer_update_irq(LM32TimerState *s) -{ - int state = (s->regs[R_SR] & SR_TO) && (s->regs[R_CR] & CR_ITO); - - trace_lm32_timer_irq_state(state); - qemu_set_irq(s->irq, state); -} - -static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size) -{ - LM32TimerState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_SR: - case R_CR: - case R_PERIOD: - r = s->regs[addr]; - break; - case R_SNAPSHOT: - r = (uint32_t)ptimer_get_count(s->ptimer); - break; - default: - error_report("lm32_timer: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_lm32_timer_memory_read(addr << 2, r); - return r; -} - -static void timer_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - LM32TimerState *s = opaque; - - trace_lm32_timer_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_SR: - s->regs[R_SR] &= ~SR_TO; - break; - case R_CR: - ptimer_transaction_begin(s->ptimer); - s->regs[R_CR] = value; - if (s->regs[R_CR] & CR_START) { - ptimer_run(s->ptimer, 1); - } - if (s->regs[R_CR] & CR_STOP) { - ptimer_stop(s->ptimer); - } - ptimer_transaction_commit(s->ptimer); - break; - case R_PERIOD: - s->regs[R_PERIOD] = value; - ptimer_transaction_begin(s->ptimer); - ptimer_set_count(s->ptimer, value); - ptimer_transaction_commit(s->ptimer); - break; - case R_SNAPSHOT: - error_report("lm32_timer: write access to read only register 0x" - TARGET_FMT_plx, addr << 2); - break; - default: - error_report("lm32_timer: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - timer_update_irq(s); -} - -static const MemoryRegionOps timer_ops = { - .read = timer_read, - .write = timer_write, - .endianness = DEVICE_NATIVE_ENDIAN, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, -}; - -static void timer_hit(void *opaque) -{ - LM32TimerState *s = opaque; - - trace_lm32_timer_hit(); - - s->regs[R_SR] |= SR_TO; - - if (s->regs[R_CR] & CR_CONT) { - ptimer_set_count(s->ptimer, s->regs[R_PERIOD]); - ptimer_run(s->ptimer, 1); - } - timer_update_irq(s); -} - -static void timer_reset(DeviceState *d) -{ - LM32TimerState *s = LM32_TIMER(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - ptimer_transaction_begin(s->ptimer); - ptimer_stop(s->ptimer); - ptimer_transaction_commit(s->ptimer); -} - -static void lm32_timer_init(Object *obj) -{ - LM32TimerState *s = LM32_TIMER(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - sysbus_init_irq(dev, &s->irq); - - memory_region_init_io(&s->iomem, obj, &timer_ops, s, - "timer", R_MAX * 4); - sysbus_init_mmio(dev, &s->iomem); -} - -static void lm32_timer_realize(DeviceState *dev, Error **errp) -{ - LM32TimerState *s = LM32_TIMER(dev); - - s->ptimer = ptimer_init(timer_hit, s, PTIMER_POLICY_DEFAULT); - - ptimer_transaction_begin(s->ptimer); - ptimer_set_freq(s->ptimer, s->freq_hz); - ptimer_transaction_commit(s->ptimer); -} - -static const VMStateDescription vmstate_lm32_timer = { - .name = "lm32-timer", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_PTIMER(ptimer, LM32TimerState), - VMSTATE_UINT32(freq_hz, LM32TimerState), - VMSTATE_UINT32_ARRAY(regs, LM32TimerState, R_MAX), - VMSTATE_END_OF_LIST() - } -}; - -static Property lm32_timer_properties[] = { - DEFINE_PROP_UINT32("frequency", LM32TimerState, freq_hz, DEFAULT_FREQUENCY), - DEFINE_PROP_END_OF_LIST(), -}; - -static void lm32_timer_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = lm32_timer_realize; - dc->reset = timer_reset; - dc->vmsd = &vmstate_lm32_timer; - device_class_set_props(dc, lm32_timer_properties); -} - -static const TypeInfo lm32_timer_info = { - .name = TYPE_LM32_TIMER, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(LM32TimerState), - .instance_init = lm32_timer_init, - .class_init = lm32_timer_class_init, -}; - -static void lm32_timer_register_types(void) -{ - type_register_static(&lm32_timer_info); -} - -type_init(lm32_timer_register_types) diff --git a/hw/timer/meson.build b/hw/timer/meson.build index 598d058506..f2081d261a 100644 --- a/hw/timer/meson.build +++ b/hw/timer/meson.build @@ -19,8 +19,6 @@ softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c')) softmmu_ss.add(when: 'CONFIG_I8254', if_true: files('i8254_common.c', 'i8254.c')) softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c')) softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c')) -softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_timer.c')) -softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-sysctl.c')) softmmu_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gictimer.c')) softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-timer.c')) softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_timer.c')) diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c deleted file mode 100644 index 9ecea63861..0000000000 --- a/hw/timer/milkymist-sysctl.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * QEMU model of the Milkymist System Controller. - * - * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * - * Specification available at: - * http://milkymist.walle.cc/socdoc/sysctl.pdf - */ - -#include "qemu/osdep.h" -#include "hw/irq.h" -#include "hw/sysbus.h" -#include "migration/vmstate.h" -#include "trace.h" -#include "qemu/timer.h" -#include "sysemu/runstate.h" -#include "hw/ptimer.h" -#include "hw/qdev-properties.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -enum { - CTRL_ENABLE = (1<<0), - CTRL_AUTORESTART = (1<<1), -}; - -enum { - ICAP_READY = (1<<0), -}; - -enum { - R_GPIO_IN = 0, - R_GPIO_OUT, - R_GPIO_INTEN, - R_TIMER0_CONTROL = 4, - R_TIMER0_COMPARE, - R_TIMER0_COUNTER, - R_TIMER1_CONTROL = 8, - R_TIMER1_COMPARE, - R_TIMER1_COUNTER, - R_ICAP = 16, - R_DBG_SCRATCHPAD = 20, - R_DBG_WRITE_LOCK, - R_CLK_FREQUENCY = 29, - R_CAPABILITIES, - R_SYSTEM_ID, - R_MAX -}; - -#define TYPE_MILKYMIST_SYSCTL "milkymist-sysctl" -OBJECT_DECLARE_SIMPLE_TYPE(MilkymistSysctlState, MILKYMIST_SYSCTL) - -struct MilkymistSysctlState { - SysBusDevice parent_obj; - - MemoryRegion regs_region; - - ptimer_state *ptimer0; - ptimer_state *ptimer1; - - uint32_t freq_hz; - uint32_t capabilities; - uint32_t systemid; - uint32_t strappings; - - uint32_t regs[R_MAX]; - - qemu_irq gpio_irq; - qemu_irq timer0_irq; - qemu_irq timer1_irq; -}; - -static void sysctl_icap_write(MilkymistSysctlState *s, uint32_t value) -{ - trace_milkymist_sysctl_icap_write(value); - switch (value & 0xffff) { - case 0x000e: - qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); - break; - } -} - -static uint64_t sysctl_read(void *opaque, hwaddr addr, - unsigned size) -{ - MilkymistSysctlState *s = opaque; - uint32_t r = 0; - - addr >>= 2; - switch (addr) { - case R_TIMER0_COUNTER: - r = (uint32_t)ptimer_get_count(s->ptimer0); - /* milkymist timer counts up */ - r = s->regs[R_TIMER0_COMPARE] - r; - break; - case R_TIMER1_COUNTER: - r = (uint32_t)ptimer_get_count(s->ptimer1); - /* milkymist timer counts up */ - r = s->regs[R_TIMER1_COMPARE] - r; - break; - case R_GPIO_IN: - case R_GPIO_OUT: - case R_GPIO_INTEN: - case R_TIMER0_CONTROL: - case R_TIMER0_COMPARE: - case R_TIMER1_CONTROL: - case R_TIMER1_COMPARE: - case R_ICAP: - case R_DBG_SCRATCHPAD: - case R_DBG_WRITE_LOCK: - case R_CLK_FREQUENCY: - case R_CAPABILITIES: - case R_SYSTEM_ID: - r = s->regs[addr]; - break; - - default: - error_report("milkymist_sysctl: read access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } - - trace_milkymist_sysctl_memory_read(addr << 2, r); - - return r; -} - -static void sysctl_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - MilkymistSysctlState *s = opaque; - - trace_milkymist_sysctl_memory_write(addr, value); - - addr >>= 2; - switch (addr) { - case R_GPIO_OUT: - case R_GPIO_INTEN: - case R_TIMER0_COUNTER: - case R_TIMER1_COUNTER: - case R_DBG_SCRATCHPAD: - s->regs[addr] = value; - break; - case R_TIMER0_COMPARE: - ptimer_transaction_begin(s->ptimer0); - ptimer_set_limit(s->ptimer0, value, 0); - s->regs[addr] = value; - ptimer_transaction_commit(s->ptimer0); - break; - case R_TIMER1_COMPARE: - ptimer_transaction_begin(s->ptimer1); - ptimer_set_limit(s->ptimer1, value, 0); - s->regs[addr] = value; - ptimer_transaction_commit(s->ptimer1); - break; - case R_TIMER0_CONTROL: - ptimer_transaction_begin(s->ptimer0); - s->regs[addr] = value; - if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) { - trace_milkymist_sysctl_start_timer0(); - ptimer_set_count(s->ptimer0, - s->regs[R_TIMER0_COMPARE] - s->regs[R_TIMER0_COUNTER]); - ptimer_run(s->ptimer0, 0); - } else { - trace_milkymist_sysctl_stop_timer0(); - ptimer_stop(s->ptimer0); - } - ptimer_transaction_commit(s->ptimer0); - break; - case R_TIMER1_CONTROL: - ptimer_transaction_begin(s->ptimer1); - s->regs[addr] = value; - if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) { - trace_milkymist_sysctl_start_timer1(); - ptimer_set_count(s->ptimer1, - s->regs[R_TIMER1_COMPARE] - s->regs[R_TIMER1_COUNTER]); - ptimer_run(s->ptimer1, 0); - } else { - trace_milkymist_sysctl_stop_timer1(); - ptimer_stop(s->ptimer1); - } - ptimer_transaction_commit(s->ptimer1); - break; - case R_ICAP: - sysctl_icap_write(s, value); - break; - case R_DBG_WRITE_LOCK: - s->regs[addr] = 1; - break; - case R_SYSTEM_ID: - qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); - break; - - case R_GPIO_IN: - case R_CLK_FREQUENCY: - case R_CAPABILITIES: - error_report("milkymist_sysctl: write to read-only register 0x" - TARGET_FMT_plx, addr << 2); - break; - - default: - error_report("milkymist_sysctl: write access to unknown register 0x" - TARGET_FMT_plx, addr << 2); - break; - } -} - -static const MemoryRegionOps sysctl_mmio_ops = { - .read = sysctl_read, - .write = sysctl_write, - .valid = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void timer0_hit(void *opaque) -{ - MilkymistSysctlState *s = opaque; - - if (!(s->regs[R_TIMER0_CONTROL] & CTRL_AUTORESTART)) { - s->regs[R_TIMER0_CONTROL] &= ~CTRL_ENABLE; - trace_milkymist_sysctl_stop_timer0(); - ptimer_stop(s->ptimer0); - } - - trace_milkymist_sysctl_pulse_irq_timer0(); - qemu_irq_pulse(s->timer0_irq); -} - -static void timer1_hit(void *opaque) -{ - MilkymistSysctlState *s = opaque; - - if (!(s->regs[R_TIMER1_CONTROL] & CTRL_AUTORESTART)) { - s->regs[R_TIMER1_CONTROL] &= ~CTRL_ENABLE; - trace_milkymist_sysctl_stop_timer1(); - ptimer_stop(s->ptimer1); - } - - trace_milkymist_sysctl_pulse_irq_timer1(); - qemu_irq_pulse(s->timer1_irq); -} - -static void milkymist_sysctl_reset(DeviceState *d) -{ - MilkymistSysctlState *s = MILKYMIST_SYSCTL(d); - int i; - - for (i = 0; i < R_MAX; i++) { - s->regs[i] = 0; - } - - ptimer_transaction_begin(s->ptimer0); - ptimer_stop(s->ptimer0); - ptimer_transaction_commit(s->ptimer0); - ptimer_transaction_begin(s->ptimer1); - ptimer_stop(s->ptimer1); - ptimer_transaction_commit(s->ptimer1); - - /* defaults */ - s->regs[R_ICAP] = ICAP_READY; - s->regs[R_SYSTEM_ID] = s->systemid; - s->regs[R_CLK_FREQUENCY] = s->freq_hz; - s->regs[R_CAPABILITIES] = s->capabilities; - s->regs[R_GPIO_IN] = s->strappings; -} - -static void milkymist_sysctl_init(Object *obj) -{ - MilkymistSysctlState *s = MILKYMIST_SYSCTL(obj); - SysBusDevice *dev = SYS_BUS_DEVICE(obj); - - sysbus_init_irq(dev, &s->gpio_irq); - sysbus_init_irq(dev, &s->timer0_irq); - sysbus_init_irq(dev, &s->timer1_irq); - - memory_region_init_io(&s->regs_region, obj, &sysctl_mmio_ops, s, - "milkymist-sysctl", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); -} - -static void milkymist_sysctl_realize(DeviceState *dev, Error **errp) -{ - MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev); - - s->ptimer0 = ptimer_init(timer0_hit, s, PTIMER_POLICY_DEFAULT); - s->ptimer1 = ptimer_init(timer1_hit, s, PTIMER_POLICY_DEFAULT); - - ptimer_transaction_begin(s->ptimer0); - ptimer_set_freq(s->ptimer0, s->freq_hz); - ptimer_transaction_commit(s->ptimer0); - ptimer_transaction_begin(s->ptimer1); - ptimer_set_freq(s->ptimer1, s->freq_hz); - ptimer_transaction_commit(s->ptimer1); -} - -static const VMStateDescription vmstate_milkymist_sysctl = { - .name = "milkymist-sysctl", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, MilkymistSysctlState, R_MAX), - VMSTATE_PTIMER(ptimer0, MilkymistSysctlState), - VMSTATE_PTIMER(ptimer1, MilkymistSysctlState), - VMSTATE_END_OF_LIST() - } -}; - -static Property milkymist_sysctl_properties[] = { - DEFINE_PROP_UINT32("frequency", MilkymistSysctlState, - freq_hz, 80000000), - DEFINE_PROP_UINT32("capabilities", MilkymistSysctlState, - capabilities, 0x00000000), - DEFINE_PROP_UINT32("systemid", MilkymistSysctlState, - systemid, 0x10014d31), - DEFINE_PROP_UINT32("gpio_strappings", MilkymistSysctlState, - strappings, 0x00000001), - DEFINE_PROP_END_OF_LIST(), -}; - -static void milkymist_sysctl_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = milkymist_sysctl_realize; - dc->reset = milkymist_sysctl_reset; - dc->vmsd = &vmstate_milkymist_sysctl; - device_class_set_props(dc, milkymist_sysctl_properties); -} - -static const TypeInfo milkymist_sysctl_info = { - .name = TYPE_MILKYMIST_SYSCTL, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(MilkymistSysctlState), - .instance_init = milkymist_sysctl_init, - .class_init = milkymist_sysctl_class_init, -}; - -static void milkymist_sysctl_register_types(void) -{ - type_register_static(&milkymist_sysctl_info); -} - -type_init(milkymist_sysctl_register_types) diff --git a/hw/timer/trace-events b/hw/timer/trace-events index f8b9db25c2..029fb56280 100644 --- a/hw/timer/trace-events +++ b/hw/timer/trace-events @@ -24,23 +24,6 @@ grlib_gptimer_hit(int id) "timer:%d HIT" grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x" grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x" -# lm32_timer.c -lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -lm32_timer_hit(void) "timer hit" -lm32_timer_irq_state(int level) "irq state %d" - -# milkymist-sysctl.c -milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x" -milkymist_sysctl_icap_write(uint32_t value) "value 0x%08x" -milkymist_sysctl_start_timer0(void) "Start timer0" -milkymist_sysctl_stop_timer0(void) "Stop timer0" -milkymist_sysctl_start_timer1(void) "Start timer1" -milkymist_sysctl_stop_timer1(void) "Stop timer1" -milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0" -milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1" - # aspeed_timer.c aspeed_timer_ctrl_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d" aspeed_timer_ctrl_external_clock(uint8_t i, bool enable) "Timer %" PRIu8 ": %d" diff --git a/hw/usb/quirks-ftdi-ids.h b/hw/usb/quirks-ftdi-ids.h index 57c12ef662..01aca55ca7 100644 --- a/hw/usb/quirks-ftdi-ids.h +++ b/hw/usb/quirks-ftdi-ids.h @@ -1222,12 +1222,6 @@ #define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D /* - * Milkymist One JTAG/Serial - */ -#define QIHARDWARE_VID 0x20B7 -#define MILKYMISTONE_JTAGSERIAL_PID 0x0713 - -/* * CTI GmbH RS485 Converter http://www.cti-lean.com/ */ /* USB-485-Mini*/ diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h index 50ef2f9c2e..c3e595f40b 100644 --- a/hw/usb/quirks.h +++ b/hw/usb/quirks.h @@ -904,7 +904,6 @@ static const struct usb_device_id usbredir_ftdi_serial_ids[] = { { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, - { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID) }, { USB_DEVICE(ST_VID, ST_STMCLT1030_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID) }, |