#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "cpu.h"
#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
+#include "migration/vmstate.h"
+#include "hw/arm/boot.h"
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/char/serial.h"
+#include "hw/hw.h"
#include "qemu/timer.h"
#include "hw/ptimer.h"
+#include "hw/qdev-properties.h"
#include "hw/block/flash.h"
#include "ui/console.h"
#include "hw/i2c/i2c.h"
+#include "hw/irq.h"
#include "hw/audio/wm8750.h"
#include "sysemu/block-backend.h"
+#include "sysemu/runstate.h"
+#include "sysemu/dma.h"
#include "exec/address-spaces.h"
#include "ui/pixel_ops.h"
+#include "qemu/cutils.h"
+#include "qom/object.h"
#define MP_MISC_BASE 0x80002000
#define MP_MISC_SIZE 0x00001000
} mv88w8618_rx_desc;
#define TYPE_MV88W8618_ETH "mv88w8618_eth"
-#define MV88W8618_ETH(obj) \
- OBJECT_CHECK(mv88w8618_eth_state, (obj), TYPE_MV88W8618_ETH)
+OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_eth_state, MV88W8618_ETH)
-typedef struct mv88w8618_eth_state {
+struct mv88w8618_eth_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
MemoryRegion iomem;
qemu_irq irq;
+ MemoryRegion *dma_mr;
+ AddressSpace dma_as;
uint32_t smir;
uint32_t icr;
uint32_t imr;
uint32_t cur_rx[4];
NICState *nic;
NICConf conf;
-} mv88w8618_eth_state;
+};
-static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
+static void eth_rx_desc_put(AddressSpace *dma_as, uint32_t addr,
+ mv88w8618_rx_desc *desc)
{
cpu_to_le32s(&desc->cmdstat);
cpu_to_le16s(&desc->bytes);
cpu_to_le16s(&desc->buffer_size);
cpu_to_le32s(&desc->buffer);
cpu_to_le32s(&desc->next);
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
+ dma_memory_write(dma_as, addr, desc, sizeof(*desc));
}
-static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
+static void eth_rx_desc_get(AddressSpace *dma_as, uint32_t addr,
+ mv88w8618_rx_desc *desc)
{
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
+ dma_memory_read(dma_as, addr, desc, sizeof(*desc));
le32_to_cpus(&desc->cmdstat);
le16_to_cpus(&desc->bytes);
le16_to_cpus(&desc->buffer_size);
continue;
}
do {
- eth_rx_desc_get(desc_addr, &desc);
+ eth_rx_desc_get(&s->dma_as, desc_addr, &desc);
if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) {
- cpu_physical_memory_write(desc.buffer + s->vlan_header,
+ dma_memory_write(&s->dma_as, desc.buffer + s->vlan_header,
buf, size);
desc.bytes = size + s->vlan_header;
desc.cmdstat &= ~MP_ETH_RX_OWN;
if (s->icr & s->imr) {
qemu_irq_raise(s->irq);
}
- eth_rx_desc_put(desc_addr, &desc);
+ eth_rx_desc_put(&s->dma_as, desc_addr, &desc);
return size;
}
desc_addr = desc.next;
return size;
}
-static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
+static void eth_tx_desc_put(AddressSpace *dma_as, uint32_t addr,
+ mv88w8618_tx_desc *desc)
{
cpu_to_le32s(&desc->cmdstat);
cpu_to_le16s(&desc->res);
cpu_to_le16s(&desc->bytes);
cpu_to_le32s(&desc->buffer);
cpu_to_le32s(&desc->next);
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
+ dma_memory_write(dma_as, addr, desc, sizeof(*desc));
}
-static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
+static void eth_tx_desc_get(AddressSpace *dma_as, uint32_t addr,
+ mv88w8618_tx_desc *desc)
{
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
+ dma_memory_read(dma_as, addr, desc, sizeof(*desc));
le32_to_cpus(&desc->cmdstat);
le16_to_cpus(&desc->res);
le16_to_cpus(&desc->bytes);
int len;
do {
- eth_tx_desc_get(desc_addr, &desc);
+ eth_tx_desc_get(&s->dma_as, desc_addr, &desc);
next_desc = desc.next;
if (desc.cmdstat & MP_ETH_TX_OWN) {
len = desc.bytes;
if (len < 2048) {
- cpu_physical_memory_read(desc.buffer, buf, len);
+ dma_memory_read(&s->dma_as, desc.buffer, buf, len);
qemu_send_packet(qemu_get_queue(s->nic), buf, len);
}
desc.cmdstat &= ~MP_ETH_TX_OWN;
s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
- eth_tx_desc_put(desc_addr, &desc);
+ eth_tx_desc_put(&s->dma_as, desc_addr, &desc);
}
desc_addr = next_desc;
} while (desc_addr != s->tx_queue[queue_index]);
{
mv88w8618_eth_state *s = MV88W8618_ETH(dev);
+ if (!s->dma_mr) {
+ error_setg(errp, TYPE_MV88W8618_ETH " 'dma-memory' link not set");
+ return;
+ }
+
+ address_space_init(&s->dma_as, s->dma_mr, "emac-dma");
s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
}
static Property mv88w8618_eth_properties[] = {
DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
+ DEFINE_PROP_LINK("dma-memory", mv88w8618_eth_state, dma_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &mv88w8618_eth_vmsd;
- dc->props = mv88w8618_eth_properties;
+ device_class_set_props(dc, mv88w8618_eth_properties);
dc->realize = mv88w8618_eth_realize;
}
#define MP_LCD_TEXTCOLOR 0xe0e0ff /* RRGGBB */
#define TYPE_MUSICPAL_LCD "musicpal_lcd"
-#define MUSICPAL_LCD(obj) \
- OBJECT_CHECK(musicpal_lcd_state, (obj), TYPE_MUSICPAL_LCD)
+OBJECT_DECLARE_SIMPLE_TYPE(musicpal_lcd_state, MUSICPAL_LCD)
-typedef struct musicpal_lcd_state {
+struct musicpal_lcd_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
uint32_t page_off;
QemuConsole *con;
uint8_t video_ram[128*64/8];
-} musicpal_lcd_state;
+};
static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
{
#define MP_PIC_ENABLE_CLR 0x0C
#define TYPE_MV88W8618_PIC "mv88w8618_pic"
-#define MV88W8618_PIC(obj) \
- OBJECT_CHECK(mv88w8618_pic_state, (obj), TYPE_MV88W8618_PIC)
+OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_pic_state, MV88W8618_PIC)
-typedef struct mv88w8618_pic_state {
+struct mv88w8618_pic_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
uint32_t level;
uint32_t enabled;
qemu_irq parent_irq;
-} mv88w8618_pic_state;
+};
static void mv88w8618_pic_update(mv88w8618_pic_state *s)
{
} mv88w8618_timer_state;
#define TYPE_MV88W8618_PIT "mv88w8618_pit"
-#define MV88W8618_PIT(obj) \
- OBJECT_CHECK(mv88w8618_pit_state, (obj), TYPE_MV88W8618_PIT)
+OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_pit_state, MV88W8618_PIT)
-typedef struct mv88w8618_pit_state {
+struct mv88w8618_pit_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
MemoryRegion iomem;
mv88w8618_timer_state timer[4];
-} mv88w8618_pit_state;
+};
static void mv88w8618_timer_tick(void *opaque)
{
static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
uint32_t freq)
{
- QEMUBH *bh;
-
sysbus_init_irq(dev, &s->irq);
s->freq = freq;
- bh = qemu_bh_new(mv88w8618_timer_tick, s);
- s->ptimer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
+ s->ptimer = ptimer_init(mv88w8618_timer_tick, s, PTIMER_POLICY_DEFAULT);
}
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
case MP_PIT_TIMER1_LENGTH ... MP_PIT_TIMER4_LENGTH:
t = &s->timer[offset >> 2];
t->limit = value;
+ ptimer_transaction_begin(t->ptimer);
if (t->limit > 0) {
ptimer_set_limit(t->ptimer, t->limit, 1);
} else {
ptimer_stop(t->ptimer);
}
+ ptimer_transaction_commit(t->ptimer);
break;
case MP_PIT_CONTROL:
for (i = 0; i < 4; i++) {
t = &s->timer[i];
+ ptimer_transaction_begin(t->ptimer);
if (value & 0xf && t->limit > 0) {
ptimer_set_limit(t->ptimer, t->limit, 0);
ptimer_set_freq(t->ptimer, t->freq);
} else {
ptimer_stop(t->ptimer);
}
+ ptimer_transaction_commit(t->ptimer);
value >>= 4;
}
break;
int i;
for (i = 0; i < 4; i++) {
- ptimer_stop(s->timer[i].ptimer);
- s->timer[i].limit = 0;
+ mv88w8618_timer_state *t = &s->timer[i];
+ ptimer_transaction_begin(t->ptimer);
+ ptimer_stop(t->ptimer);
+ ptimer_transaction_commit(t->ptimer);
+ t->limit = 0;
}
}
#define MP_FLASHCFG_CFGR0 0x04
#define TYPE_MV88W8618_FLASHCFG "mv88w8618_flashcfg"
-#define MV88W8618_FLASHCFG(obj) \
- OBJECT_CHECK(mv88w8618_flashcfg_state, (obj), TYPE_MV88W8618_FLASHCFG)
+OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_flashcfg_state, MV88W8618_FLASHCFG)
-typedef struct mv88w8618_flashcfg_state {
+struct mv88w8618_flashcfg_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
MemoryRegion iomem;
uint32_t cfgr0;
-} mv88w8618_flashcfg_state;
+};
static uint64_t mv88w8618_flashcfg_read(void *opaque,
hwaddr offset,
#define MP_BOARD_REVISION 0x31
-typedef struct {
+struct MusicPalMiscState {
SysBusDevice parent_obj;
MemoryRegion iomem;
-} MusicPalMiscState;
+};
#define TYPE_MUSICPAL_MISC "musicpal-misc"
-#define MUSICPAL_MISC(obj) \
- OBJECT_CHECK(MusicPalMiscState, (obj), TYPE_MUSICPAL_MISC)
+OBJECT_DECLARE_SIMPLE_TYPE(MusicPalMiscState, MUSICPAL_MISC)
static uint64_t musicpal_misc_read(void *opaque, hwaddr offset,
unsigned size)
#define MP_OE_LCD_BRIGHTNESS 0x0007
#define TYPE_MUSICPAL_GPIO "musicpal_gpio"
-#define MUSICPAL_GPIO(obj) \
- OBJECT_CHECK(musicpal_gpio_state, (obj), TYPE_MUSICPAL_GPIO)
+OBJECT_DECLARE_SIMPLE_TYPE(musicpal_gpio_state, MUSICPAL_GPIO)
-typedef struct musicpal_gpio_state {
+struct musicpal_gpio_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
uint32_t isr;
qemu_irq irq;
qemu_irq out[5]; /* 3 brightness out + 2 lcd (data and clock ) */
-} musicpal_gpio_state;
+};
static void musicpal_gpio_brightness_update(musicpal_gpio_state *s) {
int i;
#define MP_KEY_BTN_NAVIGATION (1 << 7)
#define TYPE_MUSICPAL_KEY "musicpal_key"
-#define MUSICPAL_KEY(obj) \
- OBJECT_CHECK(musicpal_key_state, (obj), TYPE_MUSICPAL_KEY)
+OBJECT_DECLARE_SIMPLE_TYPE(musicpal_key_state, MUSICPAL_KEY)
-typedef struct musicpal_key_state {
+struct musicpal_key_state {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
uint32_t kbd_extended;
uint32_t pressed_keys;
qemu_irq out[8];
-} musicpal_key_state;
+};
static void musicpal_key_event(void *opaque, int keycode)
{
static void musicpal_init(MachineState *machine)
{
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
ARMCPU *cpu;
qemu_irq pic[32];
DeviceState *dev;
DeviceState *i2c_dev;
DeviceState *lcd_dev;
DeviceState *key_dev;
- DeviceState *wm8750_dev;
+ I2CSlave *wm8750_dev;
SysBusDevice *s;
I2CBus *i2c;
int i;
unsigned long flash_size;
DriveInfo *dinfo;
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
MemoryRegion *sram = g_new(MemoryRegion, 1);
+ /* For now we use a fixed - the original - RAM size */
+ 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);
+ }
+
cpu = ARM_CPU(cpu_create(machine->cpu_type));
- /* For now we use a fixed - the original - RAM size */
- memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
- MP_RAM_DEFAULT_SIZE);
- memory_region_add_subregion(address_space_mem, 0, ram);
+ memory_region_add_subregion(address_space_mem, 0, machine->ram);
memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,
&error_fatal);
pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],
pic[MP_TIMER4_IRQ], NULL);
- if (serial_hd(0)) {
- serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
- 1825000, serial_hd(0), DEVICE_NATIVE_ENDIAN);
- }
- if (serial_hd(1)) {
- serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
- 1825000, serial_hd(1), DEVICE_NATIVE_ENDIAN);
- }
+ serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
+ 1825000, serial_hd(0), DEVICE_NATIVE_ENDIAN);
+ serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
+ 1825000, serial_hd(1), DEVICE_NATIVE_ENDIAN);
/* Register flash */
dinfo = drive_get(IF_PFLASH, 0, 0);
* 0xFF800000 (if there is 8 MB flash). So remap flash access if the
* image is smaller than 32 MB.
*/
-#ifdef TARGET_WORDS_BIGENDIAN
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+ pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
"musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
- MP_FLASH_SIZE_MAX / flash_size,
- 2, 0x00BF, 0x236D, 0x0000, 0x0000,
- 0x5555, 0x2AAA, 1);
-#else
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
- "musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
+ blk, 0x10000,
MP_FLASH_SIZE_MAX / flash_size,
2, 0x00BF, 0x236D, 0x0000, 0x0000,
0x5555, 0x2AAA, 0);
-#endif
-
}
sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);
qemu_check_nic_model(&nd_table[0], "mv88w8618");
- dev = qdev_create(NULL, TYPE_MV88W8618_ETH);
+ dev = qdev_new(TYPE_MV88W8618_ETH);
qdev_set_nic_properties(dev, &nd_table[0]);
- qdev_init_nofail(dev);
+ object_property_set_link(OBJECT(dev), "dma-memory",
+ OBJECT(get_system_memory()), &error_fatal);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MP_ETH_BASE);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[MP_ETH_IRQ]);
qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));
}
- wm8750_dev = i2c_create_slave(i2c, TYPE_WM8750, MP_WM_ADDR);
- dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO);
+ wm8750_dev = i2c_slave_create_simple(i2c, TYPE_WM8750, MP_WM_ADDR);
+ dev = qdev_new(TYPE_MV88W8618_AUDIO);
s = SYS_BUS_DEVICE(dev);
- object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev),
- "wm8750", NULL);
- qdev_init_nofail(dev);
+ object_property_set_link(OBJECT(dev), "wm8750", OBJECT(wm8750_dev),
+ NULL);
+ sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE;
- musicpal_binfo.kernel_filename = kernel_filename;
- musicpal_binfo.kernel_cmdline = kernel_cmdline;
- musicpal_binfo.initrd_filename = initrd_filename;
- arm_load_kernel(cpu, &musicpal_binfo);
+ arm_load_kernel(cpu, machine, &musicpal_binfo);
}
static void musicpal_machine_init(MachineClass *mc)
mc->init = musicpal_init;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
+ mc->default_ram_size = MP_RAM_DEFAULT_SIZE;
+ mc->default_ram_id = "musicpal.ram";
}
DEFINE_MACHINE("musicpal", musicpal_machine_init)