Пример #1
0
void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
{
    CharDriverState *chr;

    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);

    if (chr == NULL) {
        error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
                   qtest_chrdev);
        return;
    }

    qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
    qemu_chr_fe_set_echo(chr, true);

    inbuf = g_string_new("");

    if (qtest_log) {
        if (strcmp(qtest_log, "none") != 0) {
            qtest_log_fp = fopen(qtest_log, "w+");
        }
    } else {
        qtest_log_fp = stderr;
    }

    qtest_chr = chr;
}
Пример #2
0
int qtest_init(void)
{
    CharDriverState *chr;

    g_assert(qtest_chrdev != NULL);

    configure_icount("0");
    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);

    qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
    qemu_chr_fe_set_echo(chr, true);

    inbuf = g_string_new("");

    if (qtest_log) {
        if (strcmp(qtest_log, "none") != 0) {
            qtest_log_fp = fopen(qtest_log, "w+");
        }
    } else {
        qtest_log_fp = stderr;
    }

    qtest_chr = chr;

    return 0;
}
Пример #3
0
void altera_juart_create(int uart, const hwaddr addr, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *bus;
    Chardev *chr;
    const char chr_name[] = "juart";
    char label[ARRAY_SIZE(chr_name) + 1];

    dev = qdev_create(NULL, TYPE_ALTERA_JUART);

    if (uart >= MAX_SERIAL_PORTS) {
        hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",
                 uart, MAX_SERIAL_PORTS);
    }

    chr = serial_hds[uart];
    if (!chr) {
        snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, uart);
        chr = qemu_chr_new(label, "null");
        if (!(chr)) {
            hw_error("Can't assign serial port to altera juart%d.\n", uart);
        }
    }

    qdev_prop_set_chr(dev, "chardev", chr);
    bus = SYS_BUS_DEVICE(dev);
    qdev_init_nofail(dev);

    if (addr != (hwaddr)-1) {
        sysbus_mmio_map(bus, 0, addr);
    }

    sysbus_connect_irq(bus, 0, irq);
}
Пример #4
0
static int con_init(struct XenDevice *xendev)
{
    struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
    char *type, *dom, label[32];
    int ret = 0;
    const char *output;

    /* setup */
    dom = xs_get_domain_path(xenstore, con->xendev.dom);
    snprintf(con->console, sizeof(con->console), "%s/console", dom);
    free(dom);

    type = xenstore_read_str(con->console, "type");
    if (!type || strcmp(type, "ioemu") != 0) {
	xen_be_printf(xendev, 1, "not for me (type=%s)\n", type);
        ret = -1;
        goto out;
    }

    output = xenstore_read_str(con->console, "output");

    /* no Xen override, use qemu output device */
    if (output == NULL) {
        con->chr = serial_hds[con->xendev.dev];
    } else {
        snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
        con->chr = qemu_chr_new(label, output, NULL);
    }

    xenstore_store_pv_console_info(con->xendev.dev, con->chr);

out:
    g_free(type);
    return ret;
}
Пример #5
0
void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq)
{
    DeviceState *dev;
    SysBusDevice *bus;
    CharDriverState *chr;
    const char chr_name[] = "serial";
    char label[ARRAY_SIZE(chr_name) + 1];

    dev = qdev_create(NULL, "imx-serial");

    if (uart >= MAX_SERIAL_PORTS) {
        hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",
                 uart, MAX_SERIAL_PORTS);
    }
    chr = serial_hds[uart];
    if (!chr) {
        snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, uart);
        chr = qemu_chr_new(label, "null", NULL);
        if (!(chr)) {
            hw_error("Can't assign serial port to imx-uart%d.\n", uart);
        }
    }

    qdev_prop_set_chr(dev, "chardev", chr);
    bus = sysbus_from_qdev(dev);
    qdev_init_nofail(dev);
    if (addr != (target_phys_addr_t)-1) {
        sysbus_mmio_map(bus, 0, addr);
    }
    sysbus_connect_irq(bus, 0, irq);

}
Пример #6
0
static USBDevice *usb_serial_init(USBBus *bus, const char *filename)
{
    USBDevice *dev;
    CharDriverState *cdrv;
    uint32_t vendorid = 0, productid = 0;
    char label[32];
    static int index;

    while (*filename && *filename != ':') {
        const char *p;
        char *e;
        if (strstart(filename, "vendorid=", &p)) {
            vendorid = strtol(p, &e, 16);
            if (e == p || (*e && *e != ',' && *e != ':')) {
                error_report("bogus vendor ID %s", p);
                return NULL;
            }
            filename = e;
        } else if (strstart(filename, "productid=", &p)) {
            productid = strtol(p, &e, 16);
            if (e == p || (*e && *e != ',' && *e != ':')) {
                error_report("bogus product ID %s", p);
                return NULL;
            }
            filename = e;
        } else {
            error_report("unrecognized serial USB option %s", filename);
            return NULL;
        }
        while(*filename == ',')
            filename++;
    }
    if (!*filename) {
        error_report("character device specification needed");
        return NULL;
    }
    filename++;

    snprintf(label, sizeof(label), "usbserial%d", index++);
    cdrv = qemu_chr_new(label, filename, NULL);
    if (!cdrv)
        return NULL;

    dev = usb_create(bus, "usb-serial");
    if (!dev) {
        return NULL;
    }
    qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
    if (vendorid)
        qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid);
    if (productid)
        qdev_prop_set_uint16(&dev->qdev, "productid", productid);
    qdev_init_nofail(&dev->qdev);

    return dev;
}
Пример #7
0
static void test_server_create_chr(TestServer *server, const gchar *opt)
{
    gchar *chr_path;

    chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
    server->chr = qemu_chr_new(server->chr_name, chr_path, NULL);
    g_free(chr_path);

    qemu_chr_add_handlers(server->chr, chr_can_read, chr_read,
                          chr_event, server);
}
Пример #8
0
int main(int argc, char **argv)
{
    QTestState *s = NULL;
    CharDriverState *chr = NULL;
    const char *hugefs = 0;
    char *socket_path = 0;
    char *qemu_cmd = 0;
    char *chr_path = 0;
    int ret;

    g_test_init(&argc, &argv, NULL);

    module_call_init(MODULE_INIT_QOM);

    hugefs = init_hugepagefs();
    if (!hugefs) {
        return 0;
    }

    socket_path = g_strdup_printf("/tmp/vhost-%d.sock", getpid());

    /* create char dev and add read handlers */
    qemu_add_opts(&qemu_chardev_opts);
    chr_path = g_strdup_printf("unix:%s,server,nowait", socket_path);
    chr = qemu_chr_new("chr0", chr_path, NULL);
    g_free(chr_path);
    qemu_chr_add_handlers(chr, chr_can_read, chr_read, NULL, chr);

    /* run the main loop thread so the chardev may operate */
    data_mutex = _mutex_new();
    data_cond = _cond_new();
    _thread_new(NULL, thread_function, NULL);

    qemu_cmd = g_strdup_printf(QEMU_CMD, hugefs, socket_path);
    s = qtest_start(qemu_cmd);
    g_free(qemu_cmd);

    qtest_add_func("/vhost-user/read-guest-mem", read_guest_mem);

    ret = g_test_run();

    if (s) {
        qtest_quit(s);
    }

    /* cleanup */
    unlink(socket_path);
    g_free(socket_path);
    _cond_free(data_cond);
    _mutex_free(data_mutex);

    return ret;
}
Пример #9
0
static void test_server_create_chr(TestServer *server, const gchar *opt)
{
    gchar *chr_path;
    Chardev *chr;

    chr_path = g_strdup_printf("unix:%s%s", server->socket_path, opt);
    chr = qemu_chr_new(server->chr_name, chr_path);
    g_free(chr_path);

    qemu_chr_fe_init(&server->chr, chr, &error_abort);
    qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read,
                             chr_event, NULL, server, NULL, true);
}
Пример #10
0
static USBDevice *usb_braille_init(USBBus *bus, const char *unused)
{
    USBDevice *dev;
    CharDriverState *cdrv;

    cdrv = qemu_chr_new("braille", "braille", NULL);
    if (!cdrv)
        return NULL;

    dev = usb_create(bus, "usb-braille");
    qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
    return dev;
}
Пример #11
0
struct omap_uart_s *omap_uart_init(hwaddr base,
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
                qemu_irq txdma, qemu_irq rxdma,
                const char *label, CharDriverState *chr)
{
    struct omap_uart_s *s = g_new0(struct omap_uart_s, 1);

    s->base = base;
    s->fclk = fclk;
    s->irq = irq;
    s->serial = serial_mm_init(get_system_memory(), base, 2, irq,
                               omap_clk_getrate(fclk)/16,
                               chr ?: qemu_chr_new(label, "null"),
                               DEVICE_NATIVE_ENDIAN);
    return s;
}
Пример #12
0
static void char_stdio_test_subprocess(void)
{
    Chardev *chr;
    CharBackend be;
    int ret;

    chr = qemu_chr_new("label", "stdio");
    g_assert_nonnull(chr);

    qemu_chr_fe_init(&be, chr, &error_abort);
    qemu_chr_fe_set_open(&be, true);
    ret = qemu_chr_fe_write(&be, (void *)"buf", 4);
    g_assert_cmpint(ret, ==, 4);

    qemu_chr_fe_deinit(&be, true);
}
Пример #13
0
void qtest_init(const char *qtest_chrdev, const char *qtest_log)
{
    CharDriverState *chr;

    chr = qemu_chr_new("qtest", qtest_chrdev, NULL);

    qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
    qemu_chr_fe_set_echo(chr, true);

    inbuf = g_string_new("");

    if (qtest_log) {
        if (strcmp(qtest_log, "none") != 0) {
            qtest_log_fp = fopen(qtest_log, "w+");
        }
    } else {
        qtest_log_fp = stderr;
    }

    qtest_chr = chr;
}
Пример #14
0
static void lx_init(const LxBoardDesc *board,
        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)
{
#ifdef TARGET_WORDS_BIGENDIAN
    int be = 1;
#else
    int be = 0;
#endif
    MemoryRegion *system_memory = get_system_memory();
    CPUXtensaState *env = NULL;
    MemoryRegion *ram, *rom, *system_io;
    DriveInfo *dinfo;
    pflash_t *flash = NULL;
    int n;

    if (!cpu_model) {
        cpu_model = "dc232b";
    }

    for (n = 0; n < smp_cpus; n++) {
        env = cpu_init(cpu_model);
        if (!env) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        env->sregs[PRID] = n;
        qemu_register_reset(lx60_reset, env);
        /* Need MMU initialized prior to ELF loading,
         * so that ELF gets loaded into virtual addresses
         */
        cpu_state_reset(env);
    }

    ram = g_malloc(sizeof(*ram));
    memory_region_init_ram(ram, "lx60.dram", ram_size);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(system_memory, 0, ram);

    system_io = g_malloc(sizeof(*system_io));
    memory_region_init(system_io, "lx60.io", 224 * 1024 * 1024);
    memory_region_add_subregion(system_memory, 0xf0000000, system_io);
    lx60_fpga_init(system_io, 0x0d020000);
    if (nd_table[0].vlan) {
        lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
                xtensa_get_extint(env, 1), nd_table);
    }

    if (!serial_hds[0]) {
        serial_hds[0] = qemu_chr_new("serial0", "null", NULL);
    }

    serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0),
            115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    if (dinfo) {
        flash = pflash_cfi01_register(0xf8000000,
                NULL, "lx60.io.flash", board->flash_size,
                dinfo->bdrv, board->flash_sector_size,
                board->flash_size / board->flash_sector_size,
                4, 0x0000, 0x0000, 0x0000, 0x0000, be);
        if (flash == NULL) {
            fprintf(stderr, "Unable to mount pflash\n");
            exit(1);
        }
    }

    /* Use presence of kernel file name as 'boot from SRAM' switch. */
    if (kernel_filename) {
        rom = g_malloc(sizeof(*rom));
        memory_region_init_ram(rom, "lx60.sram", board->sram_size);
        vmstate_register_ram_global(rom);
        memory_region_add_subregion(system_memory, 0xfe000000, rom);

        /* Put kernel bootparameters to the end of that SRAM */
        if (kernel_cmdline) {
            size_t cmdline_size = strlen(kernel_cmdline) + 1;
            size_t bp_size = sizeof(BpTag[4]) + cmdline_size;
            uint32_t tagptr = (0xfe000000 + board->sram_size - bp_size) & ~0xff;

            env->regs[2] = tagptr;

            tagptr = put_tag(tagptr, 0x7b0b, 0, NULL);
            if (cmdline_size > 1) {
                tagptr = put_tag(tagptr, 0x1001,
                        cmdline_size, kernel_cmdline);
            }
            tagptr = put_tag(tagptr, 0x7e0b, 0, NULL);
        }
        uint64_t elf_entry;
        uint64_t elf_lowaddr;
        int success = load_elf(kernel_filename, translate_phys_addr, env,
                &elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
        if (success > 0) {
            env->pc = elf_entry;
        }
    } else {
        if (flash) {
            MemoryRegion *flash_mr = pflash_cfi01_get_memory(flash);
            MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));

            memory_region_init_alias(flash_io, "lx60.flash",
                    flash_mr, 0, board->flash_size);
            memory_region_add_subregion(system_memory, 0xfe000000,
                    flash_io);
        }
    }
}
Пример #15
0
static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine)
{
#ifdef TARGET_WORDS_BIGENDIAN
    int be = 1;
#else
    int be = 0;
#endif
    MemoryRegion *system_memory = get_system_memory();
    XtensaCPU *cpu = NULL;
    CPUXtensaState *env = NULL;
    MemoryRegion *system_io;
    DriveInfo *dinfo;
    pflash_t *flash = NULL;
    QemuOpts *machine_opts = qemu_get_machine_opts();
    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
    const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
    const unsigned system_io_size = 224 * 1024 * 1024;
    int n;

    for (n = 0; n < smp_cpus; n++) {
        cpu = XTENSA_CPU(cpu_create(machine->cpu_type));
        env = &cpu->env;

        env->sregs[PRID] = n;
        qemu_register_reset(xtfpga_reset, cpu);
        /* Need MMU initialized prior to ELF loading,
         * so that ELF gets loaded into virtual addresses
         */
        cpu_reset(CPU(cpu));
    }

    if (env) {
        XtensaMemory sysram = env->config->sysram;

        sysram.location[0].size = machine->ram_size;
        xtensa_create_memory_regions(&env->config->instrom, "xtensa.instrom",
                                     system_memory);
        xtensa_create_memory_regions(&env->config->instram, "xtensa.instram",
                                     system_memory);
        xtensa_create_memory_regions(&env->config->datarom, "xtensa.datarom",
                                     system_memory);
        xtensa_create_memory_regions(&env->config->dataram, "xtensa.dataram",
                                     system_memory);
        xtensa_create_memory_regions(&sysram, "xtensa.sysram",
                                     system_memory);
    }

    system_io = g_malloc(sizeof(*system_io));
    memory_region_init_io(system_io, NULL, &xtfpga_io_ops, NULL, "xtfpga.io",
                          system_io_size);
    memory_region_add_subregion(system_memory, board->io[0], system_io);
    if (board->io[1]) {
        MemoryRegion *io = g_malloc(sizeof(*io));

        memory_region_init_alias(io, NULL, "xtfpga.io.cached",
                                 system_io, 0, system_io_size);
        memory_region_add_subregion(system_memory, board->io[1], io);
    }
    xtfpga_fpga_init(system_io, 0x0d020000);
    if (nd_table[0].used) {
        xtfpga_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
                xtensa_get_extint(env, 1), nd_table);
    }

    if (!serial_hds[0]) {
        serial_hds[0] = qemu_chr_new("serial0", "null");
    }

    serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0),
            115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    if (dinfo) {
        flash = xtfpga_flash_init(system_io, board, dinfo, be);
    }

    /* Use presence of kernel file name as 'boot from SRAM' switch. */
    if (kernel_filename) {
        uint32_t entry_point = env->pc;
        size_t bp_size = 3 * get_tag_size(0); /* first/last and memory tags */
        uint32_t tagptr = env->config->sysrom.location[0].addr +
            board->sram_size;
        uint32_t cur_tagptr;
        BpMemInfo memory_location = {
            .type = tswap32(MEMORY_TYPE_CONVENTIONAL),
            .start = tswap32(env->config->sysram.location[0].addr),
            .end = tswap32(env->config->sysram.location[0].addr +
                           machine->ram_size),
        };
        uint32_t lowmem_end = machine->ram_size < 0x08000000 ?
            machine->ram_size : 0x08000000;
        uint32_t cur_lowmem = QEMU_ALIGN_UP(lowmem_end / 2, 4096);

        lowmem_end += env->config->sysram.location[0].addr;
        cur_lowmem += env->config->sysram.location[0].addr;

        xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom",
                                     system_memory);

        if (kernel_cmdline) {
            bp_size += get_tag_size(strlen(kernel_cmdline) + 1);
        }
        if (dtb_filename) {
            bp_size += get_tag_size(sizeof(uint32_t));
        }
        if (initrd_filename) {
            bp_size += get_tag_size(sizeof(BpMemInfo));
        }

        /* Put kernel bootparameters to the end of that SRAM */
        tagptr = (tagptr - bp_size) & ~0xff;
        cur_tagptr = put_tag(tagptr, BP_TAG_FIRST, 0, NULL);
        cur_tagptr = put_tag(cur_tagptr, BP_TAG_MEMORY,
                             sizeof(memory_location), &memory_location);

        if (kernel_cmdline) {
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_COMMAND_LINE,
                                 strlen(kernel_cmdline) + 1, kernel_cmdline);
        }
#ifdef CONFIG_FDT
        if (dtb_filename) {
            int fdt_size;
            void *fdt = load_device_tree(dtb_filename, &fdt_size);
            uint32_t dtb_addr = tswap32(cur_lowmem);

            if (!fdt) {
                error_report("could not load DTB '%s'", dtb_filename);
                exit(EXIT_FAILURE);
            }

            cpu_physical_memory_write(cur_lowmem, fdt, fdt_size);
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_FDT,
                                 sizeof(dtb_addr), &dtb_addr);
            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + fdt_size, 4096);
        }
#else
        if (dtb_filename) {
            error_report("could not load DTB '%s': "
                         "FDT support is not configured in QEMU",
                         dtb_filename);
            exit(EXIT_FAILURE);
        }
#endif
        if (initrd_filename) {
            BpMemInfo initrd_location = { 0 };
            int initrd_size = load_ramdisk(initrd_filename, cur_lowmem,
                                           lowmem_end - cur_lowmem);

            if (initrd_size < 0) {
                initrd_size = load_image_targphys(initrd_filename,
                                                  cur_lowmem,
                                                  lowmem_end - cur_lowmem);
            }
            if (initrd_size < 0) {
                error_report("could not load initrd '%s'", initrd_filename);
                exit(EXIT_FAILURE);
            }
            initrd_location.start = tswap32(cur_lowmem);
            initrd_location.end = tswap32(cur_lowmem + initrd_size);
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_INITRD,
                                 sizeof(initrd_location), &initrd_location);
            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + initrd_size, 4096);
        }
        cur_tagptr = put_tag(cur_tagptr, BP_TAG_LAST, 0, NULL);
        env->regs[2] = tagptr;

        uint64_t elf_entry;
        uint64_t elf_lowaddr;
        int success = load_elf(kernel_filename, translate_phys_addr, cpu,
                &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0, 0);
        if (success > 0) {
            entry_point = elf_entry;
        } else {
            hwaddr ep;
            int is_linux;
            success = load_uimage(kernel_filename, &ep, NULL, &is_linux,
                                  translate_phys_addr, cpu);
            if (success > 0 && is_linux) {
                entry_point = ep;
            } else {
                error_report("could not load kernel '%s'",
                             kernel_filename);
                exit(EXIT_FAILURE);
            }
        }
        if (entry_point != env->pc) {
            uint8_t boot[] = {
#ifdef TARGET_WORDS_BIGENDIAN
                0x60, 0x00, 0x08,       /* j    1f */
                0x00,                   /* .literal_position */
                0x00, 0x00, 0x00, 0x00, /* .literal entry_pc */
                0x00, 0x00, 0x00, 0x00, /* .literal entry_a2 */
                                        /* 1: */
                0x10, 0xff, 0xfe,       /* l32r a0, entry_pc */
                0x12, 0xff, 0xfe,       /* l32r a2, entry_a2 */
                0x0a, 0x00, 0x00,       /* jx   a0 */
#else
                0x06, 0x02, 0x00,       /* j    1f */
                0x00,                   /* .literal_position */
                0x00, 0x00, 0x00, 0x00, /* .literal entry_pc */
                0x00, 0x00, 0x00, 0x00, /* .literal entry_a2 */
                                        /* 1: */
                0x01, 0xfe, 0xff,       /* l32r a0, entry_pc */
                0x21, 0xfe, 0xff,       /* l32r a2, entry_a2 */
                0xa0, 0x00, 0x00,       /* jx   a0 */
#endif
            };
            uint32_t entry_pc = tswap32(entry_point);
            uint32_t entry_a2 = tswap32(tagptr);

            memcpy(boot + 4, &entry_pc, sizeof(entry_pc));
            memcpy(boot + 8, &entry_a2, sizeof(entry_a2));
            cpu_physical_memory_write(env->pc, boot, sizeof(boot));
        }
    } else {
        if (flash) {
            MemoryRegion *flash_mr = pflash_cfi01_get_memory(flash);
            MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));
            uint32_t size = env->config->sysrom.location[0].size;

            if (board->flash->size - board->flash->boot_base < size) {
                size = board->flash->size - board->flash->boot_base;
            }

            memory_region_init_alias(flash_io, NULL, "xtfpga.flash",
                                     flash_mr, board->flash->boot_base, size);
            memory_region_add_subregion(system_memory,
                                        env->config->sysrom.location[0].addr,
                                        flash_io);
        } else {
            xtensa_create_memory_regions(&env->config->sysrom, "xtensa.sysrom",
                                         system_memory);
        }
    }
}
Пример #16
0
static void boston_mach_init(MachineState *machine)
{
    DeviceState *dev;
    BostonState *s;
    Error *err = NULL;
    const char *cpu_model;
    MemoryRegion *flash, *ddr, *ddr_low_alias, *lcd, *platreg;
    MemoryRegion *sys_mem = get_system_memory();
    XilinxPCIEHost *pcie2;
    PCIDevice *ahci;
    DriveInfo *hd[6];
    Chardev *chr;
    int fw_size, fit_err;
    bool is_64b;

    if ((machine->ram_size % G_BYTE) ||
        (machine->ram_size > (2 * G_BYTE))) {
        error_report("Memory size must be 1GB or 2GB");
        exit(1);
    }

    cpu_model = machine->cpu_model ?: "I6400";

    dev = qdev_create(NULL, TYPE_MIPS_BOSTON);
    qdev_init_nofail(dev);

    s = BOSTON(dev);
    s->mach = machine;
    s->cps = g_new0(MIPSCPSState, 1);

    if (!cpu_supports_cps_smp(cpu_model)) {
        error_report("Boston requires CPUs which support CPS");
        exit(1);
    }

    is_64b = cpu_supports_isa(cpu_model, ISA_MIPS64);

    object_initialize(s->cps, sizeof(MIPSCPSState), TYPE_MIPS_CPS);
    qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());

    object_property_set_str(OBJECT(s->cps), cpu_model, "cpu-model", &err);
    object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err);
    object_property_set_bool(OBJECT(s->cps), true, "realized", &err);

    if (err != NULL) {
        error_report("%s", error_get_pretty(err));
        exit(1);
    }

    sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);

    flash =  g_new(MemoryRegion, 1);
    memory_region_init_rom_device(flash, NULL, &boston_flash_ops, s,
                                  "boston.flash", 128 * M_BYTE, &err);
    memory_region_add_subregion_overlap(sys_mem, 0x18000000, flash, 0);

    ddr = g_new(MemoryRegion, 1);
    memory_region_allocate_system_memory(ddr, NULL, "boston.ddr",
                                         machine->ram_size);
    memory_region_add_subregion_overlap(sys_mem, 0x80000000, ddr, 0);

    ddr_low_alias = g_new(MemoryRegion, 1);
    memory_region_init_alias(ddr_low_alias, NULL, "boston_low.ddr",
                             ddr, 0, MIN(machine->ram_size, (256 * M_BYTE)));
    memory_region_add_subregion_overlap(sys_mem, 0, ddr_low_alias, 0);

    xilinx_pcie_init(sys_mem, 0,
                     0x10000000, 32 * M_BYTE,
                     0x40000000, 1 * G_BYTE,
                     get_cps_irq(s->cps, 2), false);

    xilinx_pcie_init(sys_mem, 1,
                     0x12000000, 32 * M_BYTE,
                     0x20000000, 512 * M_BYTE,
                     get_cps_irq(s->cps, 1), false);

    pcie2 = xilinx_pcie_init(sys_mem, 2,
                             0x14000000, 32 * M_BYTE,
                             0x16000000, 1 * M_BYTE,
                             get_cps_irq(s->cps, 0), true);

    platreg = g_new(MemoryRegion, 1);
    memory_region_init_io(platreg, NULL, &boston_platreg_ops, s,
                          "boston-platregs", 0x1000);
    memory_region_add_subregion_overlap(sys_mem, 0x17ffd000, platreg, 0);

    if (!serial_hds[0]) {
        serial_hds[0] = qemu_chr_new("serial0", "null");
    }

    s->uart = serial_mm_init(sys_mem, 0x17ffe000, 2,
                             get_cps_irq(s->cps, 3), 10000000,
                             serial_hds[0], DEVICE_NATIVE_ENDIAN);

    lcd = g_new(MemoryRegion, 1);
    memory_region_init_io(lcd, NULL, &boston_lcd_ops, s, "boston-lcd", 0x8);
    memory_region_add_subregion_overlap(sys_mem, 0x17fff000, lcd, 0);

    chr = qemu_chr_new("lcd", "vc:320x240");
    qemu_chr_fe_init(&s->lcd_display, chr, NULL);
    qemu_chr_fe_set_handlers(&s->lcd_display, NULL, NULL,
                             boston_lcd_event, s, NULL, true);

    ahci = pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
                                           PCI_DEVFN(0, 0),
                                           true, TYPE_ICH9_AHCI);
    g_assert(ARRAY_SIZE(hd) == ICH_AHCI(ahci)->ahci.ports);
    ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
    ahci_ide_create_devs(ahci, hd);

    if (machine->firmware) {
        fw_size = load_image_targphys(machine->firmware,
                                      0x1fc00000, 4 * M_BYTE);
        if (fw_size == -1) {
            error_printf("unable to load firmware image '%s'\n",
                          machine->firmware);
            exit(1);
        }
    } else if (machine->kernel_filename) {
        fit_err = load_fit(&boston_fit_loader, machine->kernel_filename, s);
        if (fit_err) {
            error_printf("unable to load FIT image\n");
            exit(1);
        }

        gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c00000,
                     s->kernel_entry, s->fdt_base, is_64b);
    } else if (!qtest_enabled()) {
        error_printf("Please provide either a -kernel or -bios argument\n");
        exit(1);
    }
}
Пример #17
0
static void riscv_board_init(QEMUMachineInitArgs *args)
{
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
    MemoryRegion *system_memory = get_system_memory();
    MemoryRegion *main_mem = g_new(MemoryRegion, 1);
    RISCVCPU *cpu;
    CPURISCVState *env;
    int i;
#ifdef CONFIG_RISCV_HTIF
    DriveInfo *htifbd_drive;
    char *htifbd_fname; // htif block device filename
#endif

    DeviceState *dev = qdev_create(NULL, TYPE_RISCV_BOARD);

    object_property_set_bool(OBJECT(dev), true, "realized", NULL);

    /* Make sure the first 3 serial ports are associated with a device. */
    for(i = 0; i < 3; i++) {
        if (!serial_hds[i]) {
            char label[32];
            snprintf(label, sizeof(label), "serial%d", i);
            serial_hds[i] = qemu_chr_new(label, "null", NULL);
        }
    }

    /* init CPUs */
    if (cpu_model == NULL) {
        cpu_model = "riscv-generic";
    }

    for (i = 0; i < smp_cpus; i++) {
        cpu = cpu_riscv_init(cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        env = &cpu->env;

        /* Init internal devices */
        cpu_riscv_irq_init_cpu(env);
        cpu_riscv_clock_init(env);
        qemu_register_reset(main_cpu_reset, cpu);
    }
    cpu = RISCV_CPU(first_cpu);
    env = &cpu->env;

    /* register system main memory (actual RAM) */
    memory_region_init_ram(main_mem, NULL, "riscv_board.ram", ram_size);
    vmstate_register_ram_global(main_mem);
    memory_region_add_subregion(system_memory, 0x0, main_mem);

    if (kernel_filename) {
        /* Write a small bootloader to the flash location. */
        loaderparams.ram_size = ram_size;
        loaderparams.kernel_filename = kernel_filename;
        loaderparams.kernel_cmdline = kernel_cmdline;
        loaderparams.initrd_filename = initrd_filename;
        load_kernel();
    }

    // write memory amount in MiB to 0x0
    stl_p(memory_region_get_ram_ptr(main_mem), loaderparams.ram_size >> 20);

#ifdef CONFIG_RISCV_HTIF
    serial_mm_init(system_memory, 0x3f8, 0, env->irq[4], 1843200/16, serial_hds[0],
        DEVICE_NATIVE_ENDIAN);

    // setup HTIF Block Device if one is specified as -hda FILENAME
    htifbd_drive = drive_get_by_index(IF_IDE, 0);
    if (NULL == htifbd_drive) {
        htifbd_fname = NULL;
    } else {
        htifbd_fname = (*(htifbd_drive->bdrv)).filename;
    }

    // add htif device 0x400 - 0x410
    htif_mm_init(system_memory, 0x400, env->irq[0], main_mem, htifbd_fname);
#else
    // add serial device 0x3f8-0x3ff
    serial_mm_init(system_memory, 0x3f8, 0, env->irq[1], 1843200/16, serial_hds[0],
        DEVICE_NATIVE_ENDIAN);

    /* Create MMIO transports, to which virtio backends created by the
     * user are automatically connected as needed.  If no backend is
     * present, the transport simply remains harmlessly idle.
     * Each memory-mapped region is 0x200 bytes in size.
     */
    sysbus_create_simple("virtio-mmio", 0x400, env->irq[2]);
    sysbus_create_simple("virtio-mmio", 0x600, env->irq[3]);
    sysbus_create_simple("virtio-mmio", 0x800, env->irq[4]);
#endif

    /* Init internal devices */
    cpu_riscv_irq_init_cpu(env);
    cpu_riscv_clock_init(env);
}
Пример #18
0
    .endianness = DEVICE_NATIVE_ENDIAN,
};

struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
                struct omap_target_agent_s *ta,
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
                qemu_irq txdma, qemu_irq rxdma,
                const char *label, CharDriverState *chr)
{
    hwaddr base = omap_l4_attach(ta, 0, NULL);
    struct omap_uart_s *s = omap_uart_init(base, irq,
                    fclk, iclk, txdma, rxdma, label, chr);

    memory_region_init_io(&s->iomem, &omap_uart_ops, s, "omap.uart", 0x100);

    s->ta = ta;

    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);

    return s;
}

void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
{
    /* TODO: Should reuse or destroy current s->serial */
    s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
                               omap_clk_getrate(s->fclk) / 16,
                               chr ?: qemu_chr_new("null", "null", NULL),
                               DEVICE_NATIVE_ENDIAN);
}
Пример #19
0
static void riscv_sifive_board_init(MachineState *args)
{
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
    MemoryRegion *system_memory = get_system_memory();
    MemoryRegion *main_mem = g_new(MemoryRegion, 1);
    RISCVCPU *cpu;
    CPURISCVState *env;
    int i;
    DeviceState *dev = qdev_create(NULL, TYPE_RISCV_SIFIVE_BOARD);
    object_property_set_bool(OBJECT(dev), true, "realized", NULL);

    /* Make sure the first 3 serial ports are associated with a device. */
    for (i = 0; i < 3; i++) {
        if (!serial_hds[i]) {
            char label[32];
            snprintf(label, sizeof(label), "serial%d", i);
            serial_hds[i] = qemu_chr_new(label, "null", NULL);
        }
    }

    /* init CPUs */
    if (cpu_model == NULL) {
        cpu_model = "any";
    }

    for (i = 0; i < smp_cpus; i++) {
        cpu = cpu_riscv_init(cpu_model);
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find CPU definition\n");
            exit(1);
        }
        env = &cpu->env;

        /* Init internal devices */
        cpu_riscv_irq_init_cpu(env);
        cpu_riscv_clock_init(env);
        qemu_register_reset(main_cpu_reset, cpu);
    }
    cpu = RISCV_CPU(first_cpu);
    env = &cpu->env;

    /* register system main memory (actual RAM) */
    memory_region_init_ram(main_mem, NULL, "riscv_sifive_board.ram", 2147483648ll +
                           ram_size, &error_fatal);
    /* for phys mem size check in page table walk */
    env->memsize = ram_size;
    vmstate_register_ram_global(main_mem);
    memory_region_add_subregion(system_memory, 0x0, main_mem);

    if (kernel_filename) {
        loaderparams.ram_size = ram_size;
        loaderparams.kernel_filename = kernel_filename;
        loaderparams.kernel_cmdline = kernel_cmdline;
        loaderparams.initrd_filename = initrd_filename;
        load_kernel();
    }

    uint32_t reset_vec[8] = {
        0x297 + 0x80000000 - 0x1000, /* reset vector */
        0x00028067,                  /* jump to DRAM_BASE */
        0x00000000,                  /* reserved */
        0x0,                         /* config string pointer */
        0, 0, 0, 0                   /* trap vector */
    };
    reset_vec[3] = 0x1000 + sizeof(reset_vec); /* config string pointer */

    /* part one of config string - before memory size specified */
    const char *config_string1 = "platform {\n"
                                 "  vendor ucb;\n"
                                 "  arch spike;\n"
                                 "};\n"
                                 "plic { \n"
                                 "  interface \"plic\"; \n"
                                 "  ndevs 2; \n"
                                 "  priority { mem { 0x60000000 0x60000fff; }; }; \n"
                                 "  pending  { mem { 0x60001000 0x6000107f; }; }; \n"
                                 "  0 { \n"
                                 "    0 { \n"
                                 "      m { \n"
                                 "        ie  { mem { 0x60002000 0x6000207f; }; }; \n"
                                 "        ctl { mem { 0x60200000 0x60200007; }; }; \n"
                                 "      }; \n"
                                 "      s { \n"
                                 "        ie  { mem { 0x60002080 0x600020ff; }; }; \n"
                                 "        ctl { mem { 0x60201000 0x60201007; }; }; \n"
                                 "      }; \n"
                                 "    }; \n"
                                 "  }; \n"
                                 "}; \n"
                                 "rtc {\n"
                                 "  addr 0x" "40000000" ";\n"
                                 "};\n"
                                 "uart {\n"
                                 "  addr 0x40002000;\n"
                                 "};\n"
                                 "ram {\n"
                                 "  0 {\n"
                                 "    addr 0x" "80000000" ";\n"
                                 "    size 0x";


    /* part two of config string - after memory size specified */
    const char *config_string2 =  ";\n"
                                  "  };\n"
                                  "};\n"
                                  "core {\n"
                                  "  0" " {\n"
                                  "    " "0 {\n"
                                  "      isa " "rv64imafd" ";\n"
                                  "      timecmp 0x" "40000008" ";\n"
                                  "      ipi 0x" "40001000" ";\n"
                                  "    };\n"
                                  "  };\n"
                                  "};\n";

    /* build config string with supplied memory size */
    uint64_t rsz = ram_size;
    char *ramsize_as_hex_str = malloc(17);
    sprintf(ramsize_as_hex_str, "%016" PRIx64, rsz);
    char *config_string = malloc(strlen(config_string1) +
                                 strlen(ramsize_as_hex_str) +
                                 strlen(config_string2) + 1);
    config_string[0] = 0;
    strcat(config_string, config_string1);
    strcat(config_string, ramsize_as_hex_str);
    strcat(config_string, config_string2);

    /* copy in the reset vec and configstring */
    int q;
    for (q = 0; q < sizeof(reset_vec) / sizeof(reset_vec[0]); q++) {
        stl_p(memory_region_get_ram_ptr(main_mem) + 0x1000 + q * 4,
              reset_vec[q]);
    }

    int confstrlen = strlen(config_string);
    for (q = 0; q < confstrlen; q++) {
        stb_p(memory_region_get_ram_ptr(main_mem) + reset_vec[3] + q,
              config_string[q]);
    }

    sifive_uart_create(0x40002000, serial_hds[0]);

    /* timer device at 0x40000000, as specified in the config string above */
    timer_mm_init(system_memory, 0x40000000, env);

    /* TODO: VIRTIO */
}
Пример #20
0
static void fsl_imx6_realize(DeviceState *dev, Error **errp)
{
    FslIMX6State *s = FSL_IMX6(dev);
    uint16_t i;
    Error *err = NULL;

    for (i = 0; i < smp_cpus; i++) {

        /* On uniprocessor, the CBAR is set to 0 */
        if (smp_cpus > 1) {
            object_property_set_int(OBJECT(&s->cpu[i]), FSL_IMX6_A9MPCORE_ADDR,
                                    "reset-cbar", &error_abort);
        }

        /* All CPU but CPU 0 start in power off mode */
        if (i) {
            object_property_set_bool(OBJECT(&s->cpu[i]), true,
                                     "start-powered-off", &error_abort);
        }

        object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
    }

    object_property_set_int(OBJECT(&s->a9mpcore), smp_cpus, "num-cpu",
                            &error_abort);

    object_property_set_int(OBJECT(&s->a9mpcore),
                            FSL_IMX6_MAX_IRQ + GIC_INTERNAL, "num-irq",
                            &error_abort);

    object_property_set_bool(OBJECT(&s->a9mpcore), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->a9mpcore), 0, FSL_IMX6_A9MPCORE_ADDR);

    for (i = 0; i < smp_cpus; i++) {
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i,
                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_IRQ));
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->a9mpcore), i + smp_cpus,
                           qdev_get_gpio_in(DEVICE(&s->cpu[i]), ARM_CPU_FIQ));
    }

    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6_CCM_ADDR);

    object_property_set_bool(OBJECT(&s->src), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6_SRC_ADDR);

    /* Initialize all UARTs */
    for (i = 0; i < FSL_IMX6_NUM_UARTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } serial_table[FSL_IMX6_NUM_UARTS] = {
            { FSL_IMX6_UART1_ADDR, FSL_IMX6_UART1_IRQ },
            { FSL_IMX6_UART2_ADDR, FSL_IMX6_UART2_IRQ },
            { FSL_IMX6_UART3_ADDR, FSL_IMX6_UART3_IRQ },
            { FSL_IMX6_UART4_ADDR, FSL_IMX6_UART4_IRQ },
            { FSL_IMX6_UART5_ADDR, FSL_IMX6_UART5_IRQ },
        };

        if (i < MAX_SERIAL_PORTS) {
            Chardev *chr;

            chr = serial_hds[i];

            if (!chr) {
                char *label = g_strdup_printf("imx6.uart%d", i + 1);
                chr = qemu_chr_new(label, "null");
                g_free(label);
                serial_hds[i] = chr;
            }

            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
        }

        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            serial_table[i].irq));
    }

    s->gpt.ccm = IMX_CCM(&s->ccm);

    object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX6_GPT_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                        FSL_IMX6_GPT_IRQ));

    /* Initialize all EPIT timers */
    for (i = 0; i < FSL_IMX6_NUM_EPITS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } epit_table[FSL_IMX6_NUM_EPITS] = {
            { FSL_IMX6_EPIT1_ADDR, FSL_IMX6_EPIT1_IRQ },
            { FSL_IMX6_EPIT2_ADDR, FSL_IMX6_EPIT2_IRQ },
        };

        s->epit[i].ccm = IMX_CCM(&s->ccm);

        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            epit_table[i].irq));
    }

    /* Initialize all I2C */
    for (i = 0; i < FSL_IMX6_NUM_I2CS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } i2c_table[FSL_IMX6_NUM_I2CS] = {
            { FSL_IMX6_I2C1_ADDR, FSL_IMX6_I2C1_IRQ },
            { FSL_IMX6_I2C2_ADDR, FSL_IMX6_I2C2_IRQ },
            { FSL_IMX6_I2C3_ADDR, FSL_IMX6_I2C3_IRQ }
        };

        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            i2c_table[i].irq));
    }

    /* Initialize all GPIOs */
    for (i = 0; i < FSL_IMX6_NUM_GPIOS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq_low;
            unsigned int irq_high;
        } gpio_table[FSL_IMX6_NUM_GPIOS] = {
            {
                FSL_IMX6_GPIO1_ADDR,
                FSL_IMX6_GPIO1_LOW_IRQ,
                FSL_IMX6_GPIO1_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO2_ADDR,
                FSL_IMX6_GPIO2_LOW_IRQ,
                FSL_IMX6_GPIO2_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO3_ADDR,
                FSL_IMX6_GPIO3_LOW_IRQ,
                FSL_IMX6_GPIO3_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO4_ADDR,
                FSL_IMX6_GPIO4_LOW_IRQ,
                FSL_IMX6_GPIO4_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO5_ADDR,
                FSL_IMX6_GPIO5_LOW_IRQ,
                FSL_IMX6_GPIO5_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO6_ADDR,
                FSL_IMX6_GPIO6_LOW_IRQ,
                FSL_IMX6_GPIO6_HIGH_IRQ
            },
            {
                FSL_IMX6_GPIO7_ADDR,
                FSL_IMX6_GPIO7_LOW_IRQ,
                FSL_IMX6_GPIO7_HIGH_IRQ
            },
        };

        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-edge-sel",
                                 &error_abort);
        object_property_set_bool(OBJECT(&s->gpio[i]), true, "has-upper-pin-irq",
                                 &error_abort);
        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            gpio_table[i].irq_low));
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            gpio_table[i].irq_high));
    }

    /* Initialize all SDHC */
    for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } esdhc_table[FSL_IMX6_NUM_ESDHCS] = {
            { FSL_IMX6_uSDHC1_ADDR, FSL_IMX6_uSDHC1_IRQ },
            { FSL_IMX6_uSDHC2_ADDR, FSL_IMX6_uSDHC2_IRQ },
            { FSL_IMX6_uSDHC3_ADDR, FSL_IMX6_uSDHC3_IRQ },
            { FSL_IMX6_uSDHC4_ADDR, FSL_IMX6_uSDHC4_IRQ },
        };

        /* UHS-I SDIO3.0 SDR104 1.8V ADMA */
        object_property_set_uint(OBJECT(&s->esdhc[i]), 3, "sd-spec-version",
                                 &err);
        object_property_set_uint(OBJECT(&s->esdhc[i]), IMX6_ESDHC_CAPABILITIES,
                                 "capareg", &err);
        object_property_set_bool(OBJECT(&s->esdhc[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->esdhc[i]), 0, esdhc_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->esdhc[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            esdhc_table[i].irq));
    }

    /* Initialize all ECSPI */
    for (i = 0; i < FSL_IMX6_NUM_ECSPIS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } spi_table[FSL_IMX6_NUM_ECSPIS] = {
            { FSL_IMX6_eCSPI1_ADDR, FSL_IMX6_ECSPI1_IRQ },
            { FSL_IMX6_eCSPI2_ADDR, FSL_IMX6_ECSPI2_IRQ },
            { FSL_IMX6_eCSPI3_ADDR, FSL_IMX6_ECSPI3_IRQ },
            { FSL_IMX6_eCSPI4_ADDR, FSL_IMX6_ECSPI4_IRQ },
            { FSL_IMX6_eCSPI5_ADDR, FSL_IMX6_ECSPI5_IRQ },
        };

        /* Initialize the SPI */
        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                            spi_table[i].irq));
    }

    qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
    object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth), 0, FSL_IMX6_ENET_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 0,
                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                        FSL_IMX6_ENET_MAC_IRQ));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth), 1,
                       qdev_get_gpio_in(DEVICE(&s->a9mpcore),
                                        FSL_IMX6_ENET_MAC_1588_IRQ));

    /* ROM memory */
    memory_region_init_rom(&s->rom, NULL, "imx6.rom",
                           FSL_IMX6_ROM_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX6_ROM_ADDR,
                                &s->rom);

    /* CAAM memory */
    memory_region_init_rom(&s->caam, NULL, "imx6.caam",
                           FSL_IMX6_CAAM_MEM_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX6_CAAM_MEM_ADDR,
                                &s->caam);

    /* OCRAM memory */
    memory_region_init_ram(&s->ocram, NULL, "imx6.ocram", FSL_IMX6_OCRAM_SIZE,
                           &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ADDR,
                                &s->ocram);

    /* internal OCRAM (256 KB) is aliased over 1 MB */
    memory_region_init_alias(&s->ocram_alias, NULL, "imx6.ocram_alias",
                             &s->ocram, 0, FSL_IMX6_OCRAM_ALIAS_SIZE);
    memory_region_add_subregion(get_system_memory(), FSL_IMX6_OCRAM_ALIAS_ADDR,
                                &s->ocram_alias);
}
Пример #21
0
static void lx_init(const LxBoardDesc *board, MachineState *machine)
{
#ifdef TARGET_WORDS_BIGENDIAN
    int be = 1;
#else
    int be = 0;
#endif
    MemoryRegion *system_memory = get_system_memory();
    XtensaCPU *cpu = NULL;
    CPUXtensaState *env = NULL;
    MemoryRegion *ram, *rom, *system_io;
    DriveInfo *dinfo;
    pflash_t *flash = NULL;
    QemuOpts *machine_opts = qemu_get_machine_opts();
    const char *cpu_model = machine->cpu_model;
    const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
    const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
    const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
    const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
    int n;

    if (!cpu_model) {
        cpu_model = XTENSA_DEFAULT_CPU_MODEL;
    }

    for (n = 0; n < smp_cpus; n++) {
        cpu = cpu_xtensa_init(cpu_model);
        if (cpu == NULL) {
            error_report("unable to find CPU definition '%s'",
                         cpu_model);
            exit(EXIT_FAILURE);
        }
        env = &cpu->env;

        env->sregs[PRID] = n;
        qemu_register_reset(lx60_reset, cpu);
        /* Need MMU initialized prior to ELF loading,
         * so that ELF gets loaded into virtual addresses
         */
        cpu_reset(CPU(cpu));
    }

    ram = g_malloc(sizeof(*ram));
    memory_region_init_ram(ram, NULL, "lx60.dram", machine->ram_size,
                           &error_fatal);
    vmstate_register_ram_global(ram);
    memory_region_add_subregion(system_memory, 0, ram);

    system_io = g_malloc(sizeof(*system_io));
    memory_region_init_io(system_io, NULL, &lx60_io_ops, NULL, "lx60.io",
                          224 * 1024 * 1024);
    memory_region_add_subregion(system_memory, 0xf0000000, system_io);
    lx60_fpga_init(system_io, 0x0d020000);
    if (nd_table[0].used) {
        lx60_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000,
                xtensa_get_extint(env, 1), nd_table);
    }

    if (!serial_hds[0]) {
        serial_hds[0] = qemu_chr_new("serial0", "null", NULL);
    }

    serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0),
            115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    dinfo = drive_get(IF_PFLASH, 0, 0);
    if (dinfo) {
        flash = xtfpga_flash_init(system_io, board, dinfo, be);
    }

    /* Use presence of kernel file name as 'boot from SRAM' switch. */
    if (kernel_filename) {
        uint32_t entry_point = env->pc;
        size_t bp_size = 3 * get_tag_size(0); /* first/last and memory tags */
        uint32_t tagptr = 0xfe000000 + board->sram_size;
        uint32_t cur_tagptr;
        BpMemInfo memory_location = {
            .type = tswap32(MEMORY_TYPE_CONVENTIONAL),
            .start = tswap32(0),
            .end = tswap32(machine->ram_size),
        };
        uint32_t lowmem_end = machine->ram_size < 0x08000000 ?
            machine->ram_size : 0x08000000;
        uint32_t cur_lowmem = QEMU_ALIGN_UP(lowmem_end / 2, 4096);

        rom = g_malloc(sizeof(*rom));
        memory_region_init_ram(rom, NULL, "lx60.sram", board->sram_size,
                               &error_fatal);
        vmstate_register_ram_global(rom);
        memory_region_add_subregion(system_memory, 0xfe000000, rom);

        if (kernel_cmdline) {
            bp_size += get_tag_size(strlen(kernel_cmdline) + 1);
        }
        if (dtb_filename) {
            bp_size += get_tag_size(sizeof(uint32_t));
        }
        if (initrd_filename) {
            bp_size += get_tag_size(sizeof(BpMemInfo));
        }

        /* Put kernel bootparameters to the end of that SRAM */
        tagptr = (tagptr - bp_size) & ~0xff;
        cur_tagptr = put_tag(tagptr, BP_TAG_FIRST, 0, NULL);
        cur_tagptr = put_tag(cur_tagptr, BP_TAG_MEMORY,
                             sizeof(memory_location), &memory_location);

        if (kernel_cmdline) {
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_COMMAND_LINE,
                                 strlen(kernel_cmdline) + 1, kernel_cmdline);
        }
        if (dtb_filename) {
            int fdt_size;
            void *fdt = load_device_tree(dtb_filename, &fdt_size);
            uint32_t dtb_addr = tswap32(cur_lowmem);

            if (!fdt) {
                error_report("could not load DTB '%s'", dtb_filename);
                exit(EXIT_FAILURE);
            }

            cpu_physical_memory_write(cur_lowmem, fdt, fdt_size);
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_FDT,
                                 sizeof(dtb_addr), &dtb_addr);
            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + fdt_size, 4096);
        }
        if (initrd_filename) {
            BpMemInfo initrd_location = { 0 };
            int initrd_size = load_ramdisk(initrd_filename, cur_lowmem,
                                           lowmem_end - cur_lowmem);

            if (initrd_size < 0) {
                initrd_size = load_image_targphys(initrd_filename,
                                                  cur_lowmem,
                                                  lowmem_end - cur_lowmem);
            }
            if (initrd_size < 0) {
                error_report("could not load initrd '%s'", initrd_filename);
                exit(EXIT_FAILURE);
            }
            initrd_location.start = tswap32(cur_lowmem);
            initrd_location.end = tswap32(cur_lowmem + initrd_size);
            cur_tagptr = put_tag(cur_tagptr, BP_TAG_INITRD,
                                 sizeof(initrd_location), &initrd_location);
            cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + initrd_size, 4096);
        }
        cur_tagptr = put_tag(cur_tagptr, BP_TAG_LAST, 0, NULL);
        env->regs[2] = tagptr;

        uint64_t elf_entry;
        uint64_t elf_lowaddr;
        int success = load_elf(kernel_filename, translate_phys_addr, cpu,
                &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0, 0);
        if (success > 0) {
            entry_point = elf_entry;
        } else {
            hwaddr ep;
            int is_linux;
            success = load_uimage(kernel_filename, &ep, NULL, &is_linux,
                                  translate_phys_addr, cpu);
            if (success > 0 && is_linux) {
                entry_point = ep;
            } else {
                error_report("could not load kernel '%s'",
                             kernel_filename);
                exit(EXIT_FAILURE);
            }
        }
        if (entry_point != env->pc) {
            static const uint8_t jx_a0[] = {
#ifdef TARGET_WORDS_BIGENDIAN
                0x0a, 0, 0,
#else
                0xa0, 0, 0,
#endif
            };
            env->regs[0] = entry_point;
            cpu_physical_memory_write(env->pc, jx_a0, sizeof(jx_a0));
        }
    } else {
        if (flash) {
            MemoryRegion *flash_mr = pflash_cfi01_get_memory(flash);
            MemoryRegion *flash_io = g_malloc(sizeof(*flash_io));

            memory_region_init_alias(flash_io, NULL, "lx60.flash",
                    flash_mr, board->flash_boot_base,
                    board->flash_size - board->flash_boot_base < 0x02000000 ?
                    board->flash_size - board->flash_boot_base : 0x02000000);
            memory_region_add_subregion(system_memory, 0xfe000000,
                    flash_io);
        }
    }
}
Пример #22
0
    .endianness = DEVICE_NATIVE_ENDIAN,
};

struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
                struct omap_target_agent_s *ta,
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
                qemu_irq txdma, qemu_irq rxdma,
                const char *label, CharDriverState *chr)
{
    hwaddr base = omap_l4_attach(ta, 0, NULL);
    struct omap_uart_s *s = omap_uart_init(base, irq,
                    fclk, iclk, txdma, rxdma, label, chr);

    memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap.uart", 0x100);

    s->ta = ta;

    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);

    return s;
}

void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
{
    /* TODO: Should reuse or destroy current s->serial */
    s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
                               omap_clk_getrate(s->fclk) / 16,
                               chr ?: qemu_chr_new("null", "null"),
                               DEVICE_NATIVE_ENDIAN);
}
Пример #23
0
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
{
    BCM2835PeripheralState *s = BCM2835_PERIPHERALS(dev);
    Object *obj;
    MemoryRegion *ram;
    Error *err = NULL;
    uint32_t ram_size, vcram_size;
    CharDriverState *chr;
    int n;

    obj = object_property_get_link(OBJECT(dev), "ram", &err);
    if (obj == NULL) {
        error_setg(errp, "%s: required ram link not found: %s",
                   __func__, error_get_pretty(err));
        return;
    }

    ram = MEMORY_REGION(obj);
    ram_size = memory_region_size(ram);

    /* Map peripherals and RAM into the GPU address space. */
    memory_region_init_alias(&s->peri_mr_alias, OBJECT(s),
                             "bcm2835-peripherals", &s->peri_mr, 0,
                             memory_region_size(&s->peri_mr));

    memory_region_add_subregion_overlap(&s->gpu_bus_mr, BCM2835_VC_PERI_BASE,
                                        &s->peri_mr_alias, 1);

    /* RAM is aliased four times (different cache configurations) on the GPU */
    for (n = 0; n < 4; n++) {
        memory_region_init_alias(&s->ram_alias[n], OBJECT(s),
                                 "bcm2835-gpu-ram-alias[*]", ram, 0, ram_size);
        memory_region_add_subregion_overlap(&s->gpu_bus_mr, (hwaddr)n << 30,
                                            &s->ram_alias[n], 0);
    }

    /* Interrupt Controller */
    object_property_set_bool(OBJECT(&s->ic), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, ARMCTRL_IC_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ic), 0));
    sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));

    /* UART0 */
    object_property_set_bool(OBJECT(s->uart0), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, UART0_OFFSET,
                                sysbus_mmio_get_region(s->uart0, 0));
    sysbus_connect_irq(s->uart0, 0,
        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
                               INTERRUPT_UART));

    /* AUX / UART1 */
    /* TODO: don't call qemu_char_get_next_serial() here, instead set
     * chardev properties for each uart at the board level, once pl011
     * (uart0) has been updated to avoid qemu_char_get_next_serial()
     */
    chr = qemu_char_get_next_serial();
    if (chr == NULL) {
        chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
    }
    qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);

    object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, UART1_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->aux), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->aux), 0,
        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
                               INTERRUPT_AUX));

    /* Mailboxes */
    object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, ARMCTRL_0_SBM_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mboxes), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->mboxes), 0,
        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
                               INTERRUPT_ARM_MAILBOX));

    /* Framebuffer */
    vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size",
                                                   &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size,
                            "vcram-base", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->fb), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB << MBOX_AS_CHAN_SHIFT,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->fb), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,
                       qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));

    /* Property channel */
    object_property_set_bool(OBJECT(&s->property), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->mbox_mr,
                MBOX_CHAN_PROPERTY << MBOX_AS_CHAN_SHIFT,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->property), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0,
                      qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPERTY));

    /* Extended Mass Media Controller */
    object_property_set_int(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capareg",
                            &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->sdhci), true, "pending-insert-quirk",
                             &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, EMMC_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
        qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
                               INTERRUPT_ARASANSDIO));
    object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->sdhci), "sd-bus",
                              &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    /* DMA Channels */
    object_property_set_bool(OBJECT(&s->dma), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    memory_region_add_subregion(&s->peri_mr, DMA_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 0));
    memory_region_add_subregion(&s->peri_mr, DMA15_OFFSET,
                sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 1));

    for (n = 0; n <= 12; n++) {
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), n,
                           qdev_get_gpio_in_named(DEVICE(&s->ic),
                                                  BCM2835_IC_GPU_IRQ,
                                                  INTERRUPT_DMA0 + n));
    }
}
Пример #24
0
static void fsl_imx25_realize(DeviceState *dev, Error **errp)
{
    FslIMX25State *s = FSL_IMX25(dev);
    uint8_t i;
    Error *err = NULL;

    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));

    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);

    /* Initialize all UARTs */
    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } serial_table[FSL_IMX25_NUM_UARTS] = {
            { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ },
            { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ },
            { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ },
            { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ },
            { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ }
        };

        if (i < MAX_SERIAL_PORTS) {
            CharDriverState *chr;

            chr = serial_hds[i];

            if (!chr) {
                char label[20];
                snprintf(label, sizeof(label), "imx31.uart%d", i);
                chr = qemu_chr_new(label, "null", NULL);
            }

            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
        }

        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            serial_table[i].irq));
    }

    /* Initialize all GPT timers */
    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } gpt_table[FSL_IMX25_NUM_GPTS] = {
            { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ },
            { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ },
            { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ },
            { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
        };

        s->gpt[i].ccm = DEVICE(&s->ccm);

        object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            gpt_table[i].irq));
    }

    /* Initialize all EPIT timers */
    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } epit_table[FSL_IMX25_NUM_EPITS] = {
            { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ },
            { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
        };

        s->epit[i].ccm = DEVICE(&s->ccm);

        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            epit_table[i].irq));
    }

    qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
    object_property_set_bool(OBJECT(&s->fec), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));


    /* Initialize all I2C */
    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } i2c_table[FSL_IMX25_NUM_I2CS] = {
            { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ },
            { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ },
            { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ }
        };

        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            i2c_table[i].irq));
    }

    /* Initialize all GPIOs */
    for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } gpio_table[FSL_IMX25_NUM_GPIOS] = {
            { FSL_IMX25_GPIO1_ADDR, FSL_IMX25_GPIO1_IRQ },
            { FSL_IMX25_GPIO2_ADDR, FSL_IMX25_GPIO2_IRQ },
            { FSL_IMX25_GPIO3_ADDR, FSL_IMX25_GPIO3_IRQ },
            { FSL_IMX25_GPIO4_ADDR, FSL_IMX25_GPIO4_IRQ }
        };

        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
        /* Connect GPIO IRQ to PIC */
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            gpio_table[i].irq));
    }

    /* initialize 2 x 16 KB ROM */
    memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
                                  "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
                                &s->rom[0]);
    memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
                                  "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
                                &s->rom[1]);

    /* initialize internal RAM (128 KB) */
    memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE,
                           &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
                                &s->iram);
    vmstate_register_ram_global(&s->iram);

    /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */
    memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias",
                             &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE);
    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR,
                                &s->iram_alias);
}
Пример #25
0
static void fsl_imx31_realize(DeviceState *dev, Error **errp)
{
    FslIMX31State *s = FSL_IMX31(dev);
    uint16_t i;
    Error *err = NULL;

    object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX31_AVIC_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));

    object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX31_CCM_ADDR);

    /* Initialize all UARTS */
    for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } serial_table[FSL_IMX31_NUM_UARTS] = {
            { FSL_IMX31_UART1_ADDR, FSL_IMX31_UART1_IRQ },
            { FSL_IMX31_UART2_ADDR, FSL_IMX31_UART2_IRQ },
        };

        if (i < MAX_SERIAL_PORTS) {
            CharDriverState *chr;

            chr = serial_hds[i];

            if (!chr) {
                char label[20];
                snprintf(label, sizeof(label), "imx31.uart%d", i);
                chr = qemu_chr_new(label, "null", NULL);
            }

            qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
        }

        object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            serial_table[i].irq));
    }

    s->gpt.ccm = IMX_CCM(&s->ccm);

    object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX31_GPT_ADDR);
    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX31_GPT_IRQ));

    /* Initialize all EPIT timers */
    for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } epit_table[FSL_IMX31_NUM_EPITS] = {
            { FSL_IMX31_EPIT1_ADDR, FSL_IMX31_EPIT1_IRQ },
            { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
        };

        s->epit[i].ccm = IMX_CCM(&s->ccm);

        object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }

        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            epit_table[i].irq));
    }

    /* Initialize all I2C */
    for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } i2c_table[FSL_IMX31_NUM_I2CS] = {
            { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ },
            { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ },
            { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ }
        };

        /* Initialize the I2C */
        object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        /* Map I2C memory */
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
        /* Connect I2C IRQ to PIC */
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            i2c_table[i].irq));
    }

    /* Initialize all GPIOs */
    for (i = 0; i < FSL_IMX31_NUM_GPIOS; i++) {
        static const struct {
            hwaddr addr;
            unsigned int irq;
        } gpio_table[FSL_IMX31_NUM_GPIOS] = {
            { FSL_IMX31_GPIO1_ADDR, FSL_IMX31_GPIO1_IRQ },
            { FSL_IMX31_GPIO2_ADDR, FSL_IMX31_GPIO2_IRQ },
            { FSL_IMX31_GPIO3_ADDR, FSL_IMX31_GPIO3_IRQ }
        };

        object_property_set_bool(OBJECT(&s->gpio[i]), false, "has-edge-sel",
                                 &error_abort);
        object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
        if (err) {
            error_propagate(errp, err);
            return;
        }
        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
        /* Connect GPIO IRQ to PIC */
        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
                           qdev_get_gpio_in(DEVICE(&s->avic),
                                            gpio_table[i].irq));
    }

    /* On a real system, the first 16k is a `secure boot rom' */
    memory_region_init_rom(&s->secure_rom, NULL, "imx31.secure_rom",
                           FSL_IMX31_SECURE_ROM_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR,
                                &s->secure_rom);

    /* There is also a 16k ROM */
    memory_region_init_rom(&s->rom, NULL, "imx31.rom",
                           FSL_IMX31_ROM_SIZE, &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR,
                                &s->rom);

    /* initialize internal RAM (16 KB) */
    memory_region_init_ram(&s->iram, NULL, "imx31.iram", FSL_IMX31_IRAM_SIZE,
                           &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }
    memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR,
                                &s->iram);
    vmstate_register_ram_global(&s->iram);

    /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */
    memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias",
                             &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE);
    memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR,
                                &s->iram_alias);
}