diff options
Diffstat (limited to 'hw/xtensa/xtfpga.c')
-rw-r--r-- | hw/xtensa/xtfpga.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 21094319a6..1d21162a27 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -45,6 +45,7 @@ #include "qemu/option.h" #include "bootparam.h" #include "xtensa_memory.h" +#include "hw/xtensa/mx_pic.h" typedef struct XtfpgaFlashDesc { hwaddr base; @@ -61,6 +62,7 @@ typedef struct XtfpgaBoardDesc { typedef struct XtfpgaFpgaState { MemoryRegion iomem; + uint32_t freq; uint32_t leds; uint32_t switches; } XtfpgaFpgaState; @@ -83,7 +85,7 @@ static uint64_t xtfpga_fpga_read(void *opaque, hwaddr addr, return 0x09272011; case 0x4: /*processor clock frequency, Hz*/ - return 10000000; + return s->freq; case 0x8: /*LEDs (off = 0, on = 1)*/ return s->leds; @@ -119,13 +121,14 @@ static const MemoryRegionOps xtfpga_fpga_ops = { }; static XtfpgaFpgaState *xtfpga_fpga_init(MemoryRegion *address_space, - hwaddr base) + hwaddr base, uint32_t freq) { XtfpgaFpgaState *s = g_malloc(sizeof(XtfpgaFpgaState)); memory_region_init_io(&s->iomem, NULL, &xtfpga_fpga_ops, s, - "xtfpga.fpga", 0x10000); + "xtfpga.fpga", 0x10000); memory_region_add_subregion(address_space, base, &s->iomem); + s->freq = freq; xtfpga_fpga_reset(s); qemu_register_reset(xtfpga_fpga_reset, s); return s; @@ -223,6 +226,8 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine) XtensaCPU *cpu = NULL; CPUXtensaState *env = NULL; MemoryRegion *system_io; + XtensaMxPic *mx_pic = NULL; + qemu_irq *extints; DriveInfo *dinfo; pflash_t *flash = NULL; QemuOpts *machine_opts = qemu_get_machine_opts(); @@ -231,19 +236,45 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine) 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 * MiB; + uint32_t freq = 10000000; int n; + if (smp_cpus > 1) { + mx_pic = xtensa_mx_pic_init(31); + qemu_register_reset(xtensa_mx_pic_reset, mx_pic); + } for (n = 0; n < smp_cpus; n++) { + CPUXtensaState *cenv = NULL; + cpu = XTENSA_CPU(cpu_create(machine->cpu_type)); - env = &cpu->env; + cenv = &cpu->env; + if (!env) { + env = cenv; + freq = env->config->clock_freq_khz * 1000; + } + + if (mx_pic) { + MemoryRegion *mx_eri; - env->sregs[PRID] = n; + mx_eri = xtensa_mx_pic_register_cpu(mx_pic, + xtensa_get_extints(cenv), + xtensa_get_runstall(cenv)); + memory_region_add_subregion(xtensa_get_er_region(cenv), + 0, mx_eri); + } + cenv->sregs[PRID] = n; + xtensa_select_static_vectors(cenv, n != 0); 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 (smp_cpus > 1) { + extints = xtensa_mx_pic_get_extints(mx_pic); + } else { + extints = xtensa_get_extints(env); + } if (env) { XtensaMemory sysram = env->config->sysram; @@ -272,14 +303,14 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine) system_io, 0, system_io_size); memory_region_add_subregion(system_memory, board->io[1], io); } - xtfpga_fpga_init(system_io, 0x0d020000); + xtfpga_fpga_init(system_io, 0x0d020000, freq); if (nd_table[0].used) { xtfpga_net_init(system_io, 0x0d030000, 0x0d030400, 0x0d800000, - xtensa_get_extint(env, 1), nd_table); + extints[1], nd_table); } - serial_mm_init(system_io, 0x0d050020, 2, xtensa_get_extint(env, 0), - 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN); + serial_mm_init(system_io, 0x0d050020, 2, extints[0], + 115200, serial_hd(0), DEVICE_NATIVE_ENDIAN); dinfo = drive_get(IF_PFLASH, 0, 0); if (dinfo) { @@ -568,7 +599,7 @@ static void xtfpga_lx60_class_init(ObjectClass *oc, void *data) mc->desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")"; mc->init = xtfpga_lx60_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE; mc->default_ram_size = 64 * MiB; } @@ -585,7 +616,7 @@ static void xtfpga_lx60_nommu_class_init(ObjectClass *oc, void *data) mc->desc = "lx60 noMMU EVB (" XTENSA_DEFAULT_CPU_NOMMU_MODEL ")"; mc->init = xtfpga_lx60_nommu_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE; mc->default_ram_size = 64 * MiB; } @@ -602,7 +633,7 @@ static void xtfpga_lx200_class_init(ObjectClass *oc, void *data) mc->desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")"; mc->init = xtfpga_lx200_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE; mc->default_ram_size = 96 * MiB; } @@ -619,7 +650,7 @@ static void xtfpga_lx200_nommu_class_init(ObjectClass *oc, void *data) mc->desc = "lx200 noMMU EVB (" XTENSA_DEFAULT_CPU_NOMMU_MODEL ")"; mc->init = xtfpga_lx200_nommu_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE; mc->default_ram_size = 96 * MiB; } @@ -636,7 +667,7 @@ static void xtfpga_ml605_class_init(ObjectClass *oc, void *data) mc->desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")"; mc->init = xtfpga_ml605_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE; mc->default_ram_size = 512 * MiB - XTFPGA_MMU_RESERVED_MEMORY_SIZE; } @@ -653,7 +684,7 @@ static void xtfpga_ml605_nommu_class_init(ObjectClass *oc, void *data) mc->desc = "ml605 noMMU EVB (" XTENSA_DEFAULT_CPU_NOMMU_MODEL ")"; mc->init = xtfpga_ml605_nommu_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE; mc->default_ram_size = 256 * MiB; } @@ -670,7 +701,7 @@ static void xtfpga_kc705_class_init(ObjectClass *oc, void *data) mc->desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")"; mc->init = xtfpga_kc705_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE; mc->default_ram_size = 1 * GiB - XTFPGA_MMU_RESERVED_MEMORY_SIZE; } @@ -687,7 +718,7 @@ static void xtfpga_kc705_nommu_class_init(ObjectClass *oc, void *data) mc->desc = "kc705 noMMU EVB (" XTENSA_DEFAULT_CPU_NOMMU_MODEL ")"; mc->init = xtfpga_kc705_nommu_init; - mc->max_cpus = 4; + mc->max_cpus = 32; mc->default_cpu_type = XTENSA_DEFAULT_CPU_NOMMU_TYPE; mc->default_ram_size = 256 * MiB; } |