Exemplo n.º 1
0
Arquivo: cpu.c Projeto: Annovae/qemu
/* CPUClass::reset() */
static void openrisc_cpu_reset(CPUState *s)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(s);
    OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);

    occ->parent_reset(s);

    memset(&cpu->env, 0, offsetof(CPUOpenRISCState, breakpoints));

    tlb_flush(&cpu->env, 1);
    /*tb_flush(&cpu->env);    FIXME: Do we need it?  */

    cpu->env.pc = 0x100;
    cpu->env.sr = SR_FO | SR_SM;
    cpu->env.exception_index = -1;

    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
    cpu->env.cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S;
    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2));
    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2));

#ifndef CONFIG_USER_ONLY
    cpu->env.picmr = 0x00000000;
    cpu->env.picsr = 0x00000000;

    cpu->env.ttmr = 0x00000000;
    cpu->env.ttcr = 0x00000000;
#endif
}
Exemplo n.º 2
0
int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUClass *cc = CPU_GET_CLASS(cs);
    CPUOpenRISCState *env = &cpu->env;
    uint32_t tmp;

    if (n > cc->gdb_num_core_regs) {
        return 0;
    }

    tmp = ldl_p(mem_buf);

    if (n < 32) {
        env->gpr[n] = tmp;
    } else {
        switch (n) {
        case 32: /* PPC */
            env->ppc = tmp;
            break;

        case 33: /* NPC */
            env->npc = tmp;
            break;

        case 34: /* SR */
            env->sr = tmp;
            break;

        default:
            break;
        }
    }
    return 4;
}
Exemplo n.º 3
0
Arquivo: cpu.c Projeto: Annovae/qemu
static void or1200_initfn(Object *obj)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);

    set_feature(cpu, OPENRISC_FEATURE_OB32S);
    set_feature(cpu, OPENRISC_FEATURE_OF32S);
}
Exemplo n.º 4
0
bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int idx = -1;

    if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) {
        idx = EXCP_INT;
    }
    if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) {
        idx = EXCP_TICK;
    }

	// Here's where we set our custom interrupt; I can trace execution to here in GDB,
	// but FreeRTOS doesn't know what to do with this interrupt so it freaks out - DRM
    if ((interrupt_request & CPU_INTERRUPT_CUSTOM) && (env->sr & SR_IEE)) {
        idx = EXCP_CUSTOM;
    }
    if (idx >= 0) {
        cs->exception_index = idx;
        openrisc_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}
Exemplo n.º 5
0
bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int idx = -1;

    if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) {
        idx = EXCP_INT;
    }
    if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) {
        idx = EXCP_TICK;
    }

    // Set up custom interrupts -- make sure to disable the interrupt here,
    // or it will get thrown multiple times
    if ((interrupt_request & CPU_INTERRUPT_FFS_WRITE) && (env->sr & SR_IEE)) {
        idx = EXCP_FFS_WRITE;
        cs->interrupt_request &= ~(CPU_INTERRUPT_FFS_WRITE);
    }

    if ((interrupt_request & CPU_INTERRUPT_FFS_ACK) && (env->sr & SR_IEE)) {
        idx = EXCP_FFS_ACK;
        cs->interrupt_request &= ~(CPU_INTERRUPT_FFS_ACK);
    }
    if (idx >= 0) {
        cs->exception_index = idx;
        openrisc_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}
Exemplo n.º 6
0
void openrisc_cpu_do_interrupt(CPUState *cs)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
#ifndef CONFIG_USER_ONLY
    if (env->flags & D_FLAG) { /* Delay Slot insn */
        env->flags &= ~D_FLAG;
        env->sr |= SR_DSX;
        if (env->exception_index == EXCP_TICK    ||
            env->exception_index == EXCP_INT     ||
            env->exception_index == EXCP_SYSCALL ||
            env->exception_index == EXCP_FPE) {
            env->epcr = env->jmp_pc;
        } else {
            env->epcr = env->pc - 4;
        }
    } else {
        if (env->exception_index == EXCP_TICK    ||
            env->exception_index == EXCP_INT     ||
            env->exception_index == EXCP_SYSCALL ||
            env->exception_index == EXCP_FPE) {
            env->epcr = env->npc;
        } else {
            env->epcr = env->pc;
        }
    }

    /* For machine-state changed between user-mode and supervisor mode,
       we need flush TLB when we enter&exit EXCP.  */
    tlb_flush(env, 1);

    env->esr = env->sr;
    env->sr &= ~SR_DME;
    env->sr &= ~SR_IME;
    env->sr |= SR_SM;
    env->sr &= ~SR_IEE;
    env->sr &= ~SR_TEE;
    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;

    if (env->exception_index > 0 && env->exception_index < EXCP_NR) {
        env->pc = (env->exception_index << 8);
    } else {
        cpu_abort(env, "Unhandled exception 0x%x\n", env->exception_index);
    }
#endif

    env->exception_index = -1;
}
Exemplo n.º 7
0
static void openrisc_sim_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    const char *kernel_filename = machine->kernel_filename;
    OpenRISCCPU *cpu = NULL;
    MemoryRegion *ram;
    qemu_irq *cpu_irqs[2];
    qemu_irq serial_irq;
    int n;

    for (n = 0; n < smp_cpus; n++) {
        cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
        if (cpu == NULL) {
            fprintf(stderr, "Unable to find CPU definition!\n");
            exit(1);
        }
        cpu_openrisc_pic_init(cpu);
        cpu_irqs[n] = (qemu_irq *) cpu->env.irq;

        cpu_openrisc_clock_init(cpu);

        qemu_register_reset(main_cpu_reset, cpu);
    }

    ram = g_malloc(sizeof(*ram));
    memory_region_init_ram(ram, NULL, "openrisc.ram", ram_size, &error_fatal);
    memory_region_add_subregion(get_system_memory(), 0, ram);

    if (nd_table[0].used) {
        openrisc_sim_net_init(0x92000000, 0x92000400, smp_cpus,
                              cpu_irqs, 4, nd_table);
    }

    if (smp_cpus > 1) {
        openrisc_sim_ompic_init(0x98000000, smp_cpus, cpu_irqs, 1);

        serial_irq = qemu_irq_split(cpu_irqs[0][2], cpu_irqs[1][2]);
    } else {
        serial_irq = cpu_irqs[0][2];
    }

    serial_mm_init(get_system_memory(), 0x90000000, 0, serial_irq,
                   115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);

    openrisc_load_kernel(ram_size, kernel_filename);
}
Exemplo n.º 8
0
Arquivo: cpu.c Projeto: Annovae/qemu
static void openrisc_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    OpenRISCCPU *cpu = OPENRISC_CPU(obj);
    static int inited;

    cs->env_ptr = &cpu->env;
    cpu_exec_init(&cpu->env);

#ifndef CONFIG_USER_ONLY
    cpu_openrisc_mmu_init(cpu);
#endif

    if (tcg_enabled() && !inited) {
        inited = 1;
        openrisc_translate_init();
    }
}
Exemplo n.º 9
0
bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int idx = -1;

    if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->sr & SR_IEE)) {
        idx = EXCP_INT;
    }
    if ((interrupt_request & CPU_INTERRUPT_TIMER) && (env->sr & SR_TEE)) {
        idx = EXCP_TICK;
    }
    if (idx >= 0) {
        cs->exception_index = idx;
        openrisc_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}
Exemplo n.º 10
0
void openrisc_cpu_do_interrupt(CPUState *cs)
{
#ifndef CONFIG_USER_ONLY
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;

    env->epcr = env->pc;
    if (env->flags & D_FLAG) {
        env->flags &= ~D_FLAG;
        env->sr |= SR_DSX;
        env->epcr -= 4;
    }
    if (cs->exception_index == EXCP_SYSCALL) {
        env->epcr += 4;
    }

    /* For machine-state changed between user-mode and supervisor mode,
       we need flush TLB when we enter&exit EXCP.  */
    tlb_flush(cs, 1);

    env->esr = env->sr;
    env->sr &= ~SR_DME;
    env->sr &= ~SR_IME;
    env->sr |= SR_SM;
    env->sr &= ~SR_IEE;
    env->sr &= ~SR_TEE;
    env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
    env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;

    if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
#ifdef OR32_ARCH_DEFAULT
        env->pc = (cs->exception_index << 8);
#else
        env->pc = 0x100000 + (cs->exception_index << 8);
#endif
        //printf("pc = 0x%x\n", env->pc);
    } else {
        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
    }
#endif

    cs->exception_index = -1;
}
Exemplo n.º 11
0
int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUClass *cc = CPU_GET_CLASS(cs);
    CPUOpenRISCState *env = &cpu->env;
    uint32_t tmp;

    if (n > cc->gdb_num_core_regs) {
        return 0;
    }

    tmp = ldl_p(mem_buf);

    if (n < 32) {
        env->gpr[n] = tmp;
    } else {
        switch (n) {
        case 32: /* PPC */
            env->ppc = tmp;
            break;

        case 33: /* NPC (equals PC) */
            /* If setting PC to something different,
               also clear delayed branch status.  */
            if (env->pc != tmp) {
                env->pc = tmp;
                env->dflag = 0;
            }
            break;

        case 34: /* SR */
            cpu_set_sr(env, tmp);
            break;

        default:
            break;
        }
    }
    return 4;
}
Exemplo n.º 12
0
int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;

    if (n < 32) {
        return gdb_get_reg32(mem_buf, env->gpr[n]);
    } else {
        switch (n) {
        case 32:    /* PPC */
            return gdb_get_reg32(mem_buf, env->ppc);

        case 33:    /* NPC */
            return gdb_get_reg32(mem_buf, env->npc);

        case 34:    /* SR */
            return gdb_get_reg32(mem_buf, env->sr);

        default:
            break;
        }
    }
    return 0;
}
Exemplo n.º 13
0
Arquivo: cpu.c Projeto: Annovae/qemu
static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);

    cpu->env.pc = value;
}