LM32CPU *cpu_lm32_init(const char *cpu_model) { LM32CPU *cpu; CPULM32State *env; const LM32Def *def; static int tcg_initialized; def = cpu_lm32_find_by_name(cpu_model); if (!def) { return NULL; } cpu = LM32_CPU(object_new(TYPE_LM32_CPU)); env = &cpu->env; env->features = def->features; env->num_bps = def->num_breakpoints; env->num_wps = def->num_watchpoints; env->cfg = cfg_by_def(def); qemu_init_vcpu(env); if (tcg_enabled() && !tcg_initialized) { tcg_initialized = 1; lm32_translate_init(); } return cpu; }
void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { LM32CPU *cpu = LM32_CPU(cs); CPULM32State *env = &cpu->env; int i; if (!env || !f) { return; } cpu_fprintf(f, "IN: PC=%x %s\n", env->pc, lookup_symbol(env->pc)); cpu_fprintf(f, "ie=%8.8x (IE=%x EIE=%x BIE=%x) im=%8.8x ip=%8.8x\n", env->ie, (env->ie & IE_IE) ? 1 : 0, (env->ie & IE_EIE) ? 1 : 0, (env->ie & IE_BIE) ? 1 : 0, lm32_pic_get_im(env->pic_state), lm32_pic_get_ip(env->pic_state)); cpu_fprintf(f, "eba=%8.8x deba=%8.8x\n", env->eba, env->deba); for (i = 0; i < 32; i++) { cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]); if ((i + 1) % 4 == 0) { cpu_fprintf(f, "\n"); } } cpu_fprintf(f, "\n\n"); }
static void lm32_cpu_initfn(Object *obj) { LM32CPU *cpu = LM32_CPU(obj); CPULM32State *env = &cpu->env; cpu_exec_init(env); env->flags = 0; cpu_reset(CPU(cpu)); }
static void lm32_cpu_realizefn(DeviceState *dev, Error **errp) { LM32CPU *cpu = LM32_CPU(dev); LM32CPUClass *lcc = LM32_CPU_GET_CLASS(dev); cpu_reset(CPU(cpu)); qemu_init_vcpu(&cpu->env); lcc->parent_realize(dev, errp); }
/* CPUClass::reset() */ static void lm32_cpu_reset(CPUState *s) { LM32CPU *cpu = LM32_CPU(s); LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu); CPULM32State *env = &cpu->env; lcc->parent_reset(s); /* reset cpu state */ memset(env, 0, offsetof(CPULM32State, breakpoints)); tlb_flush(env, 1); }
static void lm32_cpu_initfn(Object *obj) { CPUState *cs = CPU(obj); LM32CPU *cpu = LM32_CPU(obj); CPULM32State *env = &cpu->env; static bool tcg_initialized; cs->env_ptr = env; cpu_exec_init(env); env->flags = 0; if (tcg_enabled() && !tcg_initialized) { tcg_initialized = true; lm32_translate_init(); } }
/* CPUClass::reset() */ static void lm32_cpu_reset(CPUState *s) { LM32CPU *cpu = LM32_CPU(s); LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu); CPULM32State *env = &cpu->env; if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); log_cpu_state(env, 0); } lcc->parent_reset(s); tlb_flush(env, 1); /* reset cpu state */ memset(env, 0, offsetof(CPULM32State, breakpoints)); }
void lm32_cpu_do_interrupt(CPUState *cs) { LM32CPU *cpu = LM32_CPU(cs); CPULM32State *env = &cpu->env; qemu_log_mask(CPU_LOG_INT, "exception at pc=%x type=%x\n", env->pc, env->exception_index); switch (env->exception_index) { case EXCP_INSN_BUS_ERROR: case EXCP_DATA_BUS_ERROR: case EXCP_DIVIDE_BY_ZERO: case EXCP_IRQ: case EXCP_SYSTEMCALL: /* non-debug exceptions */ env->regs[R_EA] = env->pc; env->ie |= (env->ie & IE_IE) ? IE_EIE : 0; env->ie &= ~IE_IE; if (env->dc & DC_RE) { env->pc = env->deba + (env->exception_index * 32); } else { env->pc = env->eba + (env->exception_index * 32); } log_cpu_state_mask(CPU_LOG_INT, env, 0); break; case EXCP_BREAKPOINT: case EXCP_WATCHPOINT: /* debug exceptions */ env->regs[R_BA] = env->pc; env->ie |= (env->ie & IE_IE) ? IE_BIE : 0; env->ie &= ~IE_IE; env->pc = env->deba + (env->exception_index * 32); log_cpu_state_mask(CPU_LOG_INT, env, 0); break; default: cpu_abort(env, "unhandled exception type=%d\n", env->exception_index); break; } }
LM32CPU *cpu_lm32_init(const char *cpu_model) { LM32CPU *cpu; CPULM32State *env; const LM32Def *def; def = cpu_lm32_find_by_name(cpu_model); if (!def) { return NULL; } cpu = LM32_CPU(object_new(TYPE_LM32_CPU)); env = &cpu->env; env->features = def->features; env->num_bps = def->num_breakpoints; env->num_wps = def->num_watchpoints; env->cfg = cfg_by_def(def); object_property_set_bool(OBJECT(cpu), true, "realized", NULL); return cpu; }
static void milkymist_init(MachineState *machine) { const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; LM32CPU *cpu; CPULM32State *env; int kernel_size; DriveInfo *dinfo; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *phys_sdram = g_new(MemoryRegion, 1); qemu_irq irq[32]; int i; char *bios_filename; ResetInfo *reset_info; /* memory map */ hwaddr flash_base = 0x00000000; size_t flash_sector_size = 128 * KiB; size_t flash_size = 32 * MiB; hwaddr sdram_base = 0x40000000; size_t sdram_size = 128 * MiB; hwaddr initrd_base = sdram_base + 0x1002000; hwaddr cmdline_base = sdram_base + 0x1000000; size_t initrd_max = sdram_size - 0x1002000; reset_info = g_malloc0(sizeof(ResetInfo)); cpu = LM32_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; reset_info->cpu = cpu; cpu_lm32_set_phys_msb_ignore(env, 1); memory_region_allocate_system_memory(phys_sdram, NULL, "milkymist.sdram", sdram_size); memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram); dinfo = drive_get(IF_PFLASH, 0, 0); /* Numonyx JS28F256J3F105 */ pflash_cfi01_register(flash_base, "milkymist.flash", flash_size, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1); /* create irq lines */ env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); } /* load bios rom */ if (bios_name == NULL) { bios_name = BIOS_FILENAME; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (bios_filename) { if (load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE) < 0) { error_report("could not load bios '%s'", bios_filename); exit(1); } } reset_info->bootstrap_pc = BIOS_OFFSET; /* if no kernel is given no valid bios rom is a fatal error */ if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) { error_report("could not load Milkymist One bios '%s'", bios_name); exit(1); } g_free(bios_filename); milkymist_uart_create(0x60000000, irq[0], serial_hd(0)); milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3], 80000000, 0x10014d31, 0x0000041f, 0x00000001); milkymist_hpdmc_create(0x60002000); milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff); milkymist_memcard_create(0x60004000); milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]); milkymist_pfpu_create(0x60006000, irq[8]); if (machine->enable_graphics) { milkymist_tmu2_create(0x60007000, irq[9]); } milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]); milkymist_softusb_create(0x6000f000, irq[15], 0x20000000, 0x1000, 0x20020000, 0x2000); /* make sure juart isn't the first chardev */ env->juart_state = lm32_juart_init(serial_hd(1)); if (kernel_filename) { uint64_t entry; /* Boots a kernel elf binary. */ kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, sdram_base, sdram_size); reset_info->bootstrap_pc = sdram_base; } if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); exit(1); } } if (kernel_cmdline && strlen(kernel_cmdline)) { pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); reset_info->cmdline_base = (uint32_t)cmdline_base; } if (initrd_filename) { size_t initrd_size; initrd_size = load_image_targphys(initrd_filename, initrd_base, initrd_max); reset_info->initrd_base = (uint32_t)initrd_base; reset_info->initrd_size = (uint32_t)initrd_size; } qemu_register_reset(main_cpu_reset, reset_info); }
static void lm32_cpu_set_pc(CPUState *cs, vaddr value) { LM32CPU *cpu = LM32_CPU(cs); cpu->env.pc = value; }