#include "omap.h"
#include "arm-misc.h"
#include "irq.h"
-#include "console.h"
+#include "ui/console.h"
#include "boards.h"
#include "i2c.h"
#include "devices.h"
#include "flash.h"
#include "hw.h"
#include "bt.h"
+#include "loader.h"
+#include "blockdev.h"
+#include "sysbus.h"
+#include "exec/address-spaces.h"
/* Nokia N8x0 support */
struct n800_s {
- struct omap_mpu_state_s *cpu;
+ struct omap_mpu_state_s *mpu;
struct rfbi_chip_s blizzard;
struct {
uint32_t (*txrx)(void *opaque, uint32_t value, int len);
uWireSlave *chip;
} ts;
- i2c_bus *i2c;
int keymap[0x80];
- i2c_slave *kbd;
+ DeviceState *kbd;
- TUSBState *usb;
+ DeviceState *usb;
void *retu;
void *tahvo;
- void *nand;
+ DeviceState *nand;
};
/* GPIO pins */
static void n8x0_gpio_setup(struct n800_s *s)
{
- qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);
- omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);
+ qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->mpu->mmc, 1);
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_MMC_CS_GPIO, mmc_cs[0]);
- qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);
+ qemu_irq_lower(qdev_get_gpio_in(s->mpu->gpio, N800_BAT_COVER_GPIO));
}
#define MAEMO_CAL_HEADER(...) \
static void n8x0_nand_setup(struct n800_s *s)
{
char *otp_region;
-
- /* Either ec40xx or ec48xx are OK for the ID */
- omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
- onenand_base_unmap,
- (s->nand = onenand_init(0xec4800, 1,
- omap2_gpio_in_get(s->cpu->gpif,
- N8X0_ONENAND_GPIO)[0])));
+ DriveInfo *dinfo;
+
+ s->nand = qdev_create(NULL, "onenand");
+ qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
+ /* Either 0x40 or 0x48 are OK for the device ID */
+ qdev_prop_set_uint16(s->nand, "device_id", 0x48);
+ qdev_prop_set_uint16(s->nand, "version_id", 0);
+ qdev_prop_set_int32(s->nand, "shift", 1);
+ dinfo = drive_get(IF_MTD, 0, 0);
+ if (dinfo && dinfo->bdrv) {
+ qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+ }
+ qdev_init_nofail(s->nand);
+ sysbus_connect_irq(sysbus_from_qdev(s->nand), 0,
+ qdev_get_gpio_in(s->mpu->gpio, N8X0_ONENAND_GPIO));
+ omap_gpmc_attach(s->mpu->gpmc, N8X0_ONENAND_CS,
+ sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0));
otp_region = onenand_raw_otp(s->nand);
memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
/* XXX: in theory should also update the OOB for both pages */
}
+static qemu_irq n8x0_system_powerdown;
+
+static void n8x0_powerdown_req(Notifier *n, void *opaque)
+{
+ qemu_irq_raise(n8x0_system_powerdown);
+}
+
+static Notifier n8x0_system_powerdown_notifier = {
+ .notify = n8x0_powerdown_req
+};
+
static void n8x0_i2c_setup(struct n800_s *s)
{
DeviceState *dev;
- qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];
-
- /* Attach the CPU on one end of our I2C bus. */
- s->i2c = omap_i2c_bus(s->cpu->i2c[0]);
+ qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
+ i2c_bus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
/* Attach a menelaus PM chip */
- dev = i2c_create_slave(s->i2c, "twl92230", N8X0_MENELAUS_ADDR);
- qdev_connect_gpio_out(dev, 3, s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]);
+ dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
+ qdev_connect_gpio_out(dev, 3,
+ qdev_get_gpio_in(s->mpu->ih[0],
+ OMAP_INT_24XX_SYS_NIRQ));
+
+ n8x0_system_powerdown = qdev_get_gpio_in(dev, 3);
+ qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
/* Attach a TMP105 PM chip (A0 wired to ground) */
- dev = i2c_create_slave(s->i2c, "tmp105", N8X0_TMP105_ADDR);
+ dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
qdev_connect_gpio_out(dev, 0, tmp_irq);
}
/* XXX: are the three pins inverted inside the chip between the
* tsc and the cpu (N4111)? */
- qemu_irq penirq = 0; /* NC */
- qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];
- qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];
+ qemu_irq penirq = NULL; /* NC */
+ qemu_irq kbirq = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_KP_IRQ_GPIO);
+ qemu_irq dav = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_TS_GPIO);
s->ts.chip = tsc2301_init(penirq, kbirq, dav);
s->ts.opaque = s->ts.chip->opaque;
static void n810_tsc_setup(struct n800_s *s)
{
- qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];
+ qemu_irq pintdav = qdev_get_gpio_in(s->mpu->gpio, N810_TSC_TS_GPIO);
s->ts.opaque = tsc2005_init(pintdav);
s->ts.txrx = tsc2005_txrx;
static void n810_kbd_setup(struct n800_s *s)
{
- qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];
- DeviceState *dev;
+ qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
int i;
for (i = 0; i < 0x80; i ++)
/* Attach the LM8322 keyboard to the I2C bus,
* should happen in n8x0_i2c_setup and s->kbd be initialised here. */
- dev = i2c_create_slave(s->i2c, "lm8323", N810_LM8323_ADDR);
- qdev_connect_gpio_out(dev, 0, kbd_irq);
+ s->kbd = i2c_create_slave(omap_i2c_bus(s->mpu->i2c[0]),
+ "lm8323", N810_LM8323_ADDR);
+ qdev_connect_gpio_out(s->kbd, 0, kbd_irq);
}
/* LCD MIPI DBI-C controller (URAL) */
static void *mipid_init(void)
{
- struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
+ struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s));
s->id = 0x838f03;
mipid_reset(s);
void *tsc = s->ts.opaque;
void *mipid = mipid_init();
- omap_mcspi_attach(s->cpu->mcspi[0], s->ts.txrx, tsc, 0);
- omap_mcspi_attach(s->cpu->mcspi[0], mipid_txrx, mipid, 1);
+ omap_mcspi_attach(s->mpu->mcspi[0], s->ts.txrx, tsc, 0);
+ omap_mcspi_attach(s->mpu->mcspi[0], mipid_txrx, mipid, 1);
}
/* This task is normally performed by the bootloader. If we're loading
chip->write(chip->opaque, 1, 0x01); /* Input Data Format */
chip->write(chip->opaque, 1, 0x01); /* Data Source Select */
- fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
+ fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
/* Display Memory Data Port */
chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
- free(fb_blank);
+ g_free(fb_blank);
}
static void n8x0_dss_setup(struct n800_s *s)
{
- s->blizzard.opaque = s1d13745_init(0);
+ s->blizzard.opaque = s1d13745_init(NULL);
s->blizzard.block = s1d13745_write_block;
s->blizzard.write = s1d13745_write;
s->blizzard.read = s1d13745_read;
- omap_rfbi_attach(s->cpu->dss, 0, &s->blizzard);
+ omap_rfbi_attach(s->mpu->dss, 0, &s->blizzard);
}
static void n8x0_cbus_setup(struct n800_s *s)
{
- qemu_irq dat_out = omap2_gpio_in_get(s->cpu->gpif, N8X0_CBUS_DAT_GPIO)[0];
- qemu_irq retu_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_RETU_GPIO)[0];
- qemu_irq tahvo_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TAHVO_GPIO)[0];
+ qemu_irq dat_out = qdev_get_gpio_in(s->mpu->gpio, N8X0_CBUS_DAT_GPIO);
+ qemu_irq retu_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_RETU_GPIO);
+ qemu_irq tahvo_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TAHVO_GPIO);
CBus *cbus = cbus_init(dat_out);
- omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_CLK_GPIO, cbus->clk);
- omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_DAT_GPIO, cbus->dat);
- omap2_gpio_out_set(s->cpu->gpif, N8X0_CBUS_SEL_GPIO, cbus->sel);
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
static void n8x0_uart_setup(struct n800_s *s)
{
CharDriverState *radio = uart_hci_init(
- omap2_gpio_in_get(s->cpu->gpif,
- N8X0_BT_HOST_WKUP_GPIO)[0]);
+ qdev_get_gpio_in(s->mpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
- omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_RESET_GPIO,
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
csrhci_pins_get(radio)[csrhci_pin_reset]);
- omap2_gpio_out_set(s->cpu->gpif, N8X0_BT_WKUP_GPIO,
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_WKUP_GPIO,
csrhci_pins_get(radio)[csrhci_pin_wakeup]);
- omap_uart_attach(s->cpu->uart[BT_UART], radio);
-}
-
-static void n8x0_usb_power_cb(void *opaque, int line, int level)
-{
- struct n800_s *s = opaque;
-
- tusb6010_power(s->usb, level);
+ omap_uart_attach(s->mpu->uart[BT_UART], radio);
}
static void n8x0_usb_setup(struct n800_s *s)
{
- qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
- qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
- TUSBState *tusb = tusb6010_init(tusb_irq);
-
+ SysBusDevice *dev;
+ s->usb = qdev_create(NULL, "tusb6010");
+ dev = sysbus_from_qdev(s->usb);
+ qdev_init_nofail(s->usb);
+ sysbus_connect_irq(dev, 0,
+ qdev_get_gpio_in(s->mpu->gpio, N8X0_TUSB_INT_GPIO));
/* Using the NOR interface */
- omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
- tusb6010_async_io(tusb), 0, 0, tusb);
- omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
- tusb6010_sync_io(tusb), 0, 0, tusb);
-
- s->usb = tusb;
- omap2_gpio_out_set(s->cpu->gpif, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
+ omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_ASYNC_CS,
+ sysbus_mmio_get_region(dev, 0));
+ omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_SYNC_CS,
+ sysbus_mmio_get_region(dev, 1));
+ qdev_connect_gpio_out(s->mpu->gpio, N8X0_TUSB_ENABLE_GPIO,
+ qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
}
/* Setup done before the main bootloader starts by some early setup code
n800_dss_init(&s->blizzard);
/* CPU setup */
- s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
- s->cpu->env->GE = 0x5;
+ s->mpu->cpu->env.GE = 0x5;
/* If the machine has a slided keyboard, open it */
if (s->kbd)
- qemu_irq_raise(omap2_gpio_in_get(s->cpu->gpif, N810_SLIDE_GPIO)[0]);
+ qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
}
#define OMAP_TAG_NOKIA_BT 0x4e01
"headphone", N8X0_HEADPHONE_GPIO,
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
},
- { 0 }
+ { NULL }
}, n810_gpiosw_info[] = {
{
"gps_reset", N810_GPS_RESET_GPIO,
"slide", N810_SLIDE_GPIO,
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
},
- { 0 }
+ { NULL }
};
static struct omap_partition_info_s {
{ 0x00280000, 0x00200000, 0x3, "initfs" },
{ 0x00480000, 0x0fb80000, 0x3, "rootfs" },
- { 0, 0, 0, 0 }
+ { 0, 0, 0, NULL }
}, n810_part_info[] = {
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
{ 0x00020000, 0x00060000, 0x0, "config" },
{ 0x002a0000, 0x00400000, 0x0, "initfs" },
{ 0x006a0000, 0x0f960000, 0x0, "rootfs" },
- { 0, 0, 0, 0 }
+ { 0, 0, 0, NULL }
};
static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
stw_raw(w ++, 24); /* u16 len */
strcpy((void *) w, "hw-build"); /* char component[12] */
w += 6;
- strcpy((void *) w, "QEMU " QEMU_VERSION); /* char version[12] */
+ strcpy((void *) w, "QEMU ");
+ pstrcat((void *) w, 12, qemu_get_version()); /* char version[12] */
w += 6;
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
return (void *) w - p;
}
-static int n800_atag_setup(struct arm_boot_info *info, void *p)
+static int n800_atag_setup(const struct arm_boot_info *info, void *p)
{
return n8x0_atag_setup(p, 800);
}
-static int n810_atag_setup(struct arm_boot_info *info, void *p)
+static int n810_atag_setup(const struct arm_boot_info *info, void *p)
{
return n8x0_atag_setup(p, 810);
}
-static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
- const char *kernel_filename,
- const char *kernel_cmdline, const char *initrd_filename,
- const char *cpu_model, struct arm_boot_info *binfo, int model)
+static void n8x0_init(QEMUMachineInitArgs *args,
+ struct arm_boot_info *binfo, int model)
{
- struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
+ MemoryRegion *sysmem = get_system_memory();
+ struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
int sdram_size = binfo->ram_size;
DisplayState *ds;
- s->cpu = omap2420_mpu_init(sdram_size, cpu_model);
+ s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);
/* Setup peripherals
*
n8x0_dss_setup(s);
n8x0_cbus_setup(s);
n8x0_uart_setup(s);
- if (usb_enabled)
+ if (usb_enabled(false)) {
n8x0_usb_setup(s);
+ }
- /* Setup initial (reset) machine state */
-
- /* Start at the OneNAND bootloader. */
- s->cpu->env->regs[15] = 0;
-
- if (kernel_filename) {
+ if (args->kernel_filename) {
/* Or at the linux loader. */
- binfo->kernel_filename = kernel_filename;
- binfo->kernel_cmdline = kernel_cmdline;
- binfo->initrd_filename = initrd_filename;
- arm_load_kernel(s->cpu->env, binfo);
+ binfo->kernel_filename = args->kernel_filename;
+ binfo->kernel_cmdline = args->kernel_cmdline;
+ binfo->initrd_filename = args->initrd_filename;
+ arm_load_kernel(s->mpu->cpu, binfo);
qemu_register_reset(n8x0_boot_init, s);
- n8x0_boot_init(s);
}
- if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) {
+ if (option_rom[0].name &&
+ (args->boot_device[0] == 'n' || !args->kernel_filename)) {
int rom_size;
uint8_t nolo_tags[0x10000];
/* No, wait, better start at the ROM. */
- s->cpu->env->regs[15] = OMAP2_Q2_BASE + 0x400000;
+ s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
/* This is intended for loading the `secondary.bin' program from
* Nokia images (the NOLO bootloader). The entry point seems
*
* The code above is for loading the `zImage' file from Nokia
* images. */
- rom_size = load_image_targphys(option_rom[0],
+ rom_size = load_image_targphys(option_rom[0].name,
OMAP2_Q2_BASE + 0x400000,
sdram_size - 0x400000);
printf("%i bytes of image loaded\n", rom_size);
size until the guest activates the display. */
ds = get_displaystate();
ds->surface = qemu_resize_displaysurface(ds, 800, 480);
- dpy_resize(ds);
+ dpy_gfx_resize(ds);
}
static struct arm_boot_info n800_binfo = {
.atag_board = n810_atag_setup,
};
-static void n800_init(ram_addr_t ram_size,
- const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
+static void n800_init(QEMUMachineInitArgs *args)
{
- return n8x0_init(ram_size, boot_device,
- kernel_filename, kernel_cmdline, initrd_filename,
- cpu_model, &n800_binfo, 800);
+ return n8x0_init(args, &n800_binfo, 800);
}
-static void n810_init(ram_addr_t ram_size,
- const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
+static void n810_init(QEMUMachineInitArgs *args)
{
- return n8x0_init(ram_size, boot_device,
- kernel_filename, kernel_cmdline, initrd_filename,
- cpu_model, &n810_binfo, 810);
+ return n8x0_init(args, &n810_binfo, 810);
}
static QEMUMachine n800_machine = {