Exemplo n.º 1
0
static void
ser_write(void *opaque, hwaddr addr,
          uint64_t val64, unsigned int size)
{
    struct etrax_serial *s = opaque;
    uint32_t value = val64;
    unsigned char ch = val64;
    D(CPUCRISState *env = s->env);

    D(qemu_log("%s " TARGET_FMT_plx "=%x\n",  __func__, addr, value));
    addr >>= 2;
    switch (addr)
    {
        case RW_DOUT:
            qemu_chr_fe_write(s->chr, &ch, 1);
            s->regs[R_INTR] |= 3;
            s->pending_tx = 1;
            s->regs[addr] = value;
            break;
        case RW_ACK_INTR:
            if (s->pending_tx) {
                value &= ~1;
                s->pending_tx = 0;
                D(qemu_log("fixedup value=%x r_intr=%x\n",
                           value, s->regs[R_INTR]));
            }
            s->regs[addr] = value;
            s->regs[R_INTR] &= ~value;
            D(printf("r_intr=%x\n", s->regs[R_INTR]));
            break;
        default:
            s->regs[addr] = value;
            break;
    }
    ser_update_irq(s);
}
Exemplo n.º 2
0
static void
tdk_write(struct PHY *phy, unsigned int req, unsigned int data)
{
    int regnum;

    regnum = req & 0x1f;
    DPHY(qemu_log("%s reg[%d] = %x\n", __func__, regnum, data));
    switch (regnum) {
    default:
        phy->regs[regnum] = data;
        break;
    }

    /* Unconditionally clear regs[BMCR][BMCR_RESET] */
    phy->regs[0] &= ~0x8000;
}
Exemplo n.º 3
0
void helper_put(uint32_t id, uint32_t ctrl, uint32_t data)
{
    int test = ctrl & STREAM_TEST;
    int atomic = ctrl & STREAM_ATOMIC;
    int control = ctrl & STREAM_CONTROL;
    int nonblock = ctrl & STREAM_NONBLOCK;
    int exception = ctrl & STREAM_EXCEPTION;

    qemu_log("Unhandled stream put to stream-id=%d data=%x %s%s%s%s%s\n",
             id, data,
             test ? "t" : "",
             nonblock ? "n" : "",
             exception ? "e" : "",
             control ? "c" : "",
             atomic ? "a" : "");
}
Exemplo n.º 4
0
uint32_t HELPER(retw)(uint32_t pc)
{
    int n = (env->regs[0] >> 30) & 0x3;
    int m = 0;
    uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
    uint32_t windowstart = env->sregs[WINDOW_START];
    uint32_t ret_pc = 0;

    if (windowstart & windowstart_bit(windowbase - 1, env)) {
        m = 1;
    } else if (windowstart & windowstart_bit(windowbase - 2, env)) {
        m = 2;
    } else if (windowstart & windowstart_bit(windowbase - 3, env)) {
        m = 3;
    }

    if (n == 0 || (m != 0 && m != n) ||
            ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) != 0) {
        qemu_log("Illegal retw instruction(pc = %08x), "
                "PS = %08x, m = %d, n = %d\n",
                pc, env->sregs[PS], m, n);
        HELPER(exception_cause)(pc, ILLEGAL_INSTRUCTION_CAUSE);
    } else {
        int owb = windowbase;

        ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);

        rotate_window(-n);
        if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) {
            env->sregs[WINDOW_START] &= ~windowstart_bit(owb, env);
        } else {
            /* window underflow */
            env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
                (windowbase << PS_OWB_SHIFT) | PS_EXCM;
            env->sregs[EPC1] = env->pc = pc;

            if (n == 1) {
                HELPER(exception)(EXC_WINDOW_UNDERFLOW4);
            } else if (n == 2) {
                HELPER(exception)(EXC_WINDOW_UNDERFLOW8);
            } else if (n == 3) {
                HELPER(exception)(EXC_WINDOW_UNDERFLOW12);
            }
        }
    }
    return ret_pc;
}
Exemplo n.º 5
0
int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    XtensaCPU *cpu = XTENSA_CPU(cs);
    CPUXtensaState *env = &cpu->env;
    uint32_t tmp;
    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;

    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
        return 0;
    }

    tmp = ldl_p(mem_buf);

    switch (reg->type) {
    case 9: /*pc*/
        env->pc = tmp;
        break;

    case 1: /*ar*/
        env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
        xtensa_sync_window_from_phys(env);
        break;

    case 2: /*SR*/
        env->sregs[reg->targno & 0xff] = tmp;
        break;

    case 3: /*UR*/
        env->uregs[reg->targno & 0xff] = tmp;
        break;

    case 4: /*f*/
        env->fregs[reg->targno & 0x0f] = make_float32(tmp);
        break;

    case 8: /*a*/
        env->regs[reg->targno & 0x0f] = tmp;
        break;

    default:
        qemu_log("%s to reg %d of unsupported type %d\n",
                 __func__, n, reg->type);
        return 0;
    }

    return 4;
}
Exemplo n.º 6
0
uint32_t helper_get(uint32_t id, uint32_t ctrl)
{
    int test = ctrl & STREAM_TEST;
    int atomic = ctrl & STREAM_ATOMIC;
    int control = ctrl & STREAM_CONTROL;
    int nonblock = ctrl & STREAM_NONBLOCK;
    int exception = ctrl & STREAM_EXCEPTION;

    qemu_log("Unhandled stream get from stream-id=%d %s%s%s%s%s\n",
             id,
             test ? "t" : "",
             nonblock ? "n" : "",
             exception ? "e" : "",
             control ? "c" : "",
             atomic ? "a" : "");
    return 0xdead0000 | id;
}
Exemplo n.º 7
0
static void xtensa_set_irq(void *opaque, int irq, int active)
{
    CPUXtensaState *env = opaque;

    if (irq >= env->config->ninterrupt) {
        qemu_log("%s: bad IRQ %d\n", __func__, irq);
    } else {
        uint32_t irq_bit = 1 << irq;

        if (active) {
            env->sregs[INTSET] |= irq_bit;
        } else if (env->config->interrupt[irq].inttype == INTTYPE_LEVEL) {
            env->sregs[INTSET] &= ~irq_bit;
        }

        check_interrupts(env);
    }
}
Exemplo n.º 8
0
/* CPUClass::reset() */
static void s390_cpu_reset(CPUState *s)
{
    S390CPU *cpu = S390_CPU(s);
    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
    CPUS390XState *env = &cpu->env;

    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        log_cpu_state(env, 0);
    }

    scc->parent_reset(s);

    memset(env, 0, offsetof(CPUS390XState, breakpoints));
    /* FIXME: reset vector? */
    tlb_flush(env, 1);
    s390_add_running_cpu(env);
}
Exemplo n.º 9
0
void cpu_reset(CPUM68KState *env)
{
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        log_cpu_state(env, 0);
    }

    memset(env, 0, offsetof(CPUM68KState, breakpoints));
#if !defined (CONFIG_USER_ONLY)
    env->sr = 0x2700;
#endif
    m68k_switch_sp(env);
    /* ??? FP regs should be initialized to NaN.  */
    env->cc_op = CC_OP_FLAGS;
    /* TODO: We should set PC from the interrupt vector.  */
    env->pc = 0;
    tlb_flush(env, 1);
}
Exemplo n.º 10
0
/* 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));
}
Exemplo n.º 11
0
void cpu_reset(CPUAVR32State *env)
{
   if (qemu_loglevel_mask(CPU_LOG_RESET)) {
      qemu_log("CPU Reset\n");
      log_cpu_state(env, 0);
   }

   memset(env, 0, offsetof(CPUAVR32State, breakpoints));

#if defined (CONFIG_USER_ONLY)
   env->sreg.sr = AVR32_SR_M_MASK & (AVR32_SR_M_APP << AVR32_SR_M_OFFSET);
   /* SN: TBD - Should we enable interrupts??  */
#else
   /* Supervisor mode with interrupts disabled.  */
   env->sreg.sr = (AVR32_SR_M_MASK & (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)) | AVR32_SR_GM_MASK | AVR32_SR_EM_MASK;
#endif
   tlb_flush(env, 1);
}
Exemplo n.º 12
0
/* CPUClass::reset() */
static void mips_cpu_reset(CPUState *s)
{
    MIPSCPU *cpu = MIPS_CPU(s);
    MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
    CPUMIPSState *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);
    }

    mcc->parent_reset(s);

    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
    tlb_flush(env, 1);

    cpu_state_reset(env);
}
Exemplo n.º 13
0
static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
{
    SiFivePLICState *plic = opaque;

    /* writes must be 4 byte words */
    if ((addr & 0x3) != 0) {
        goto err;
    }

    if (addr >= plic->priority_base && /* 4 bytes per source */
        addr < plic->priority_base + (plic->num_sources << 2))
    {
        uint32_t irq = (addr - plic->priority_base) >> 2;
        if (RISCV_DEBUG_PLIC) {
            qemu_log("plic: read priority: irq=%d priority=%d\n",
                irq, plic->source_priority[irq]);
        }
        return plic->source_priority[irq];
    } else if (addr >= plic->pending_base && /* 1 bit per source */
Exemplo n.º 14
0
void cpu_reset(CPUSPARCState *env)
{
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        log_cpu_state(env, 0);
    }

    tlb_flush(env, 1);
    env->cwp = 0;
#ifndef TARGET_SPARC64
    env->wim = 1;
#endif
    env->regwptr = env->regbase + (env->cwp * 16);
    CC_OP = CC_OP_FLAGS;
#if defined(CONFIG_USER_ONLY)
#ifdef TARGET_SPARC64
    env->cleanwin = env->nwindows - 2;
    env->cansave = env->nwindows - 2;
    env->pstate = PS_RMO | PS_PEF | PS_IE;
    env->asi = 0x82; /* Primary no-fault */
#endif
#else
#if !defined(TARGET_SPARC64)
    env->psret = 0;
    env->psrs = 1;
    env->psrps = 1;
#endif
#ifdef TARGET_SPARC64
    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
    env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
    env->tl = env->maxtl;
    cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
    env->lsu = 0;
#else
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
    env->mmuregs[0] |= env->def->mmu_bm;
#endif
    env->pc = 0;
    env->npc = env->pc + 4;
#endif
    env->cache_control = 0;
}
Exemplo n.º 15
0
static void serial_receive(void *opaque, const uint8_t *buf, int size)
{
    struct etrax_serial *s = opaque;
    int i;

    /* Got a byte.  */
    if (s->rx_fifo_len >= 16) {
        qemu_log("WARNING: UART dropped char.\n");
        return;
    }

    for (i = 0; i < size; i++) { 
        s->rx_fifo[s->rx_fifo_pos] = buf[i];
        s->rx_fifo_pos++;
        s->rx_fifo_pos &= 15;
        s->rx_fifo_len++;
    }

    ser_update_irq(s);
}
Exemplo n.º 16
0
static void openrisc_sim_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;
   OpenRISCCPU *cpu = NULL;
    MemoryRegion *ram;
    int n;

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

    for (n = 0; n < smp_cpus; n++) {
        cpu = cpu_openrisc_init(cpu_model);
        if (cpu == NULL) {
            qemu_log("Unable to find CPU defineition!\n");
            exit(1);
        }
        qemu_register_reset(main_cpu_reset, cpu);
        main_cpu_reset(cpu);
    }

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

    cpu_openrisc_pic_init(cpu);
    cpu_openrisc_clock_init(cpu);

    serial_mm_init(get_system_memory(), 0x90000000, 0, cpu->env.irq[2],
                   115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    if (nd_table[0].used) {
        openrisc_sim_net_init(get_system_memory(), 0x92000000,
                              0x92000400, cpu->env.irq[4], nd_table);
    }

    cpu_openrisc_load_kernel(ram_size, kernel_filename, cpu);
}
Exemplo n.º 17
0
uint32_t helper_subkc(uint32_t a, uint32_t b, uint32_t k, uint32_t c)
{
    uint32_t d, cf = 1, ncf;

    if (c)
        cf = env->sregs[SR_MSR] >> 31; 
    assert(cf == 0 || cf == 1);
    d = b + ~a + cf;

    if (!k) {
        ncf = compute_carry(b, ~a, cf);
        assert(ncf == 0 || ncf == 1);
        if (ncf)
            env->sregs[SR_MSR] |= MSR_C | MSR_CC;
        else
            env->sregs[SR_MSR] &= ~(MSR_C | MSR_CC);
    }
    D(qemu_log("%x = %x + %x cf=%d ncf=%d k=%d c=%d\n",
               d, a, b, cf, ncf, k, c));
    return d;
}
Exemplo n.º 18
0
void tlb_fill(CPUXtensaState *env,
        target_ulong vaddr, int is_write, int mmu_idx, uintptr_t retaddr)
{
    uint32_t paddr;
    uint32_t page_size;
    unsigned access;
    int ret = xtensa_get_physical_addr(env, true, vaddr, is_write, mmu_idx,
            &paddr, &page_size, &access);

    qemu_log("%s(%08x, %d, %d) -> %08x, ret = %d\n", __func__,
            vaddr, is_write, mmu_idx, paddr, ret);

    if (ret == 0) {
        tlb_set_page(env,
                vaddr & TARGET_PAGE_MASK,
                paddr & TARGET_PAGE_MASK,
                access, mmu_idx, page_size);
    } else {
        cpu_restore_state(env, retaddr);
        HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr);
    }
}
Exemplo n.º 19
0
int xtensa_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    XtensaCPU *cpu = XTENSA_CPU(cs);
    CPUXtensaState *env = &cpu->env;
    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;

    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
        return 0;
    }

    switch (reg->type) {
    case 9: /*pc*/
        return gdb_get_reg32(mem_buf, env->pc);

    case 1: /*ar*/
        xtensa_sync_phys_from_window(env);
        return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
                                                     % env->config->nareg]);

    case 2: /*SR*/
        return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);

    case 3: /*UR*/
        return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);

    case 4: /*f*/
        return gdb_get_reg32(mem_buf, float32_val(env->fregs[reg->targno
                                                             & 0x0f]));

    case 8: /*a*/
        return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);

    default:
        qemu_log("%s from reg %d of unsupported type %d\n",
                 __func__, n, reg->type);
        return 0;
    }
}
Exemplo n.º 20
0
static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
{
    struct xlx_uartlite *s = opaque;
    uint32_t r = 0;
    addr >>= 2;
    switch (addr)
    {
        case R_RX:
            r = s->rx_fifo[(s->rx_fifo_pos - s->rx_fifo_len) & 7];
            if (s->rx_fifo_len)
                s->rx_fifo_len--;
            uart_update_status(s);
            uart_update_irq(s);
            break;

        default:
            if (addr < ARRAY_SIZE(s->regs))
                r = s->regs[addr];
            DUART(qemu_log("%s addr=%x v=%x\n", __func__, addr, r));
            break;
    }
    return r;
}
Exemplo n.º 21
0
/* CPUClass::reset() */
static void nios2_cpu_reset(CPUState *cs)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
    CPUNios2State *env = &cpu->env;

    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", cs->cpu_index);
        log_cpu_state(cs, 0);
    }

    ncc->parent_reset(cs);

    memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
    env->regs[R_PC] = cpu->reset_addr;

#if defined(CONFIG_USER_ONLY)
    /* Start in user mode with interrupts enabled. */
    env->regs[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
#else
    env->regs[CR_STATUS] = 0;
#endif
}
Exemplo n.º 22
0
void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
{
    HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);

    switch (a1 & 0xf00) {
    case 0x000:
        env->psw.mask &= ~PSW_MASK_ASC;
        env->psw.mask |= PSW_ASC_PRIMARY;
        break;
    case 0x100:
        env->psw.mask &= ~PSW_MASK_ASC;
        env->psw.mask |= PSW_ASC_SECONDARY;
        break;
    case 0x300:
        env->psw.mask &= ~PSW_MASK_ASC;
        env->psw.mask |= PSW_ASC_HOME;
        break;
    default:
        qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
        program_interrupt(env, PGM_SPECIFICATION, 2);
        break;
    }
}
Exemplo n.º 23
0
/* CPUClass::reset() */
static void m68k_cpu_reset(CPUState *s)
{
    M68kCPU *cpu = M68K_CPU(s);
    M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
    CPUM68KState *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);
    }

    mcc->parent_reset(s);

    memset(env, 0, offsetof(CPUM68KState, breakpoints));
#if !defined(CONFIG_USER_ONLY)
    env->sr = 0x2700;
#endif
    m68k_switch_sp(env);
    /* ??? FP regs should be initialized to NaN.  */
    env->cc_op = CC_OP_FLAGS;
    /* TODO: We should set PC from the interrupt vector.  */
    env->pc = 0;
    tlb_flush(env, 1);
}
Exemplo n.º 24
0
void helper_debug(CPUMBState *env)
{
    int i;

    qemu_log("PC=%8.8x\n", env->sregs[SR_PC]);
    qemu_log("rmsr=%x resr=%x rear=%x debug[%x] imm=%x iflags=%x\n",
             env->sregs[SR_MSR], env->sregs[SR_ESR], env->sregs[SR_EAR],
             env->debug, env->imm, env->iflags);
    qemu_log("btaken=%d btarget=%x mode=%s(saved=%s) eip=%d ie=%d\n",
             env->btaken, env->btarget,
             (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
             (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel",
             (env->sregs[SR_MSR] & MSR_EIP),
             (env->sregs[SR_MSR] & MSR_IE));
    for (i = 0; i < 32; i++) {
        qemu_log("r%2.2d=%8.8x ", i, env->regs[i]);
        if ((i + 1) % 4 == 0)
            qemu_log("\n");
    }
    qemu_log("\n\n");
}
Exemplo n.º 25
0
/* generate intermediate code for basic block 'tb'.  */
static void gen_intermediate_code_internal(
    CPUNios2State *env, TranslationBlock *tb, int search_pc)
{
    DisasContext dc1, *dc = &dc1;
    int num_insns;
    int max_insns;
    uint32_t next_page_start;
    int j, lj = -1;
    uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    /* Initialize DC */
    dc->env    = env;
    dc->cpu_R  = cpu_R;
    dc->is_jmp = DISAS_NEXT;
    dc->pc     = tb->pc;
    dc->tb     = tb;

    /* Dump the CPU state to the log */
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        qemu_log("--------------\n");
        log_cpu_state(env, 0);
    }

    /* Set up instruction counts */
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0) {
        max_insns = CF_COUNT_MASK;
    }
    next_page_start = (tb->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;

    gen_icount_start();
    do {
        /* Mark instruction start with associated PC */
        if (search_pc) {
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j) {
                    gen_opc_instr_start[lj++] = 0;
                }
            }
            gen_opc_pc[lj] = dc->pc;
            gen_opc_instr_start[lj] = 1;
            gen_opc_icount[lj] = num_insns;
        }

        LOG_DIS("%8.8x:\t", dc->pc);

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
            gen_io_start();
        }

        /* Decode an instruction */
        handle_instruction(dc);

        dc->pc += 4;
        num_insns++;

        /* Translation stops when a conditional branch is encountered.
         * Otherwise the subsequent code could get translated several times.
         * Also stop translation when a page boundary is reached.  This
         * ensures prefetch aborts occur at the right place.  */
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
             !env->singlestep_enabled &&
             !singlestep &&
             dc->pc < next_page_start &&
             num_insns < max_insns);

    if (tb->cflags & CF_LAST_IO) {
        gen_io_end();
    }

    /* Indicate where the next block should start */
    switch (dc->is_jmp) {
    case DISAS_NEXT:
        /* Save the current PC back into the CPU register */
        tcg_gen_movi_tl(cpu_R[R_PC], dc->pc);
        tcg_gen_exit_tb(0);
        break;

    default:
    case DISAS_JUMP:
    case DISAS_UPDATE:
        /* The jump will already have updated the PC register */
        tcg_gen_exit_tb(0);
        break;

    case DISAS_TB_JUMP:
        /* nothing more to generate */
        break;
    }

    /* End off the block */
    gen_icount_end(tb, num_insns);
    *gen_opc_ptr = INDEX_op_end;

    /* Mark instruction starts for the final generated instruction */
    if (search_pc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j) {
            gen_opc_instr_start[lj++] = 0;
        }
    } else {
        tb->size = dc->pc - tb->pc;
        tb->icount = num_insns;
    }

#ifdef DEBUG_DISAS
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        qemu_log("----------------\n");
        qemu_log("IN: %s\n", lookup_symbol(tb->pc));
        log_target_disas(tb->pc, dc->pc - tb->pc, 0);
        qemu_log("\nisize=%d osize=%td\n",
                 dc->pc - tb->pc, gen_opc_ptr - gen_opc_buf);
    }
#endif
}
Exemplo n.º 26
0
int cpu_mb_handle_mmu_fault (CPUMBState *env, target_ulong address, int rw,
                             int mmu_idx)
{
    unsigned int hit;
    unsigned int mmu_available;
    int r = 1;
    int prot;

    mmu_available = 0;
    if (env->pvr.regs[0] & PVR0_USE_MMU) {
        mmu_available = 1;
        if ((env->pvr.regs[0] & PVR0_PVR_FULL_MASK)
            && (env->pvr.regs[11] & PVR11_USE_MMU) != PVR11_USE_MMU) {
            mmu_available = 0;
        }
    }

    /* Translate if the MMU is available and enabled.  */
    if (mmu_available && (env->sregs[SR_MSR] & MSR_VM)) {
        target_ulong vaddr, paddr;
        struct microblaze_mmu_lookup lu;

        hit = mmu_translate(&env->mmu, &lu, address, rw, mmu_idx);
        if (hit) {
            vaddr = address & TARGET_PAGE_MASK;
            paddr = lu.paddr + vaddr - lu.vaddr;

            DMMU(qemu_log("MMU map mmu=%d v=%x p=%x prot=%x\n",
                     mmu_idx, vaddr, paddr, lu.prot));
            tlb_set_page(env, vaddr, paddr, lu.prot, mmu_idx, TARGET_PAGE_SIZE);
            r = 0;
        } else {
            env->sregs[SR_EAR] = address;
            DMMU(qemu_log("mmu=%d miss v=%x\n", mmu_idx, address));

            switch (lu.err) {
                case ERR_PROT:
                    env->sregs[SR_ESR] = rw == 2 ? 17 : 16;
                    env->sregs[SR_ESR] |= (rw == 1) << 10;
                    break;
                case ERR_MISS:
                    env->sregs[SR_ESR] = rw == 2 ? 19 : 18;
                    env->sregs[SR_ESR] |= (rw == 1) << 10;
                    break;
                default:
                    abort();
                    break;
            }

            if (env->exception_index == EXCP_MMU) {
                cpu_abort(env, "recursive faults\n");
            }

            /* TLB miss.  */
            env->exception_index = EXCP_MMU;
        }
    } else {
        /* MMU disabled or not available.  */
        address &= TARGET_PAGE_MASK;
        prot = PAGE_BITS;
        tlb_set_page(env, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
        r = 0;
    }
    return r;
}
Exemplo n.º 27
0
void do_interrupt(CPUMBState *env)
{
    uint32_t t;

    /* IMM flag cannot propagate across a branch and into the dslot.  */
    assert(!((env->iflags & D_FLAG) && (env->iflags & IMM_FLAG)));
    assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
/*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
    env->res_addr = RES_ADDR_NONE;
    switch (env->exception_index) {
        case EXCP_HW_EXCP:
            if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
                qemu_log("Exception raised on system without exceptions!\n");
                return;
            }

            env->regs[17] = env->sregs[SR_PC] + 4;
            env->sregs[SR_ESR] &= ~(1 << 12);

            /* Exception breaks branch + dslot sequence?  */
            if (env->iflags & D_FLAG) {
                env->sregs[SR_ESR] |= 1 << 12 ;
                env->sregs[SR_BTR] = env->btarget;
            }

            /* Disable the MMU.  */
            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
            env->sregs[SR_MSR] |= t;
            /* Exception in progress.  */
            env->sregs[SR_MSR] |= MSR_EIP;

            qemu_log_mask(CPU_LOG_INT,
                          "hw exception at pc=%x ear=%x esr=%x iflags=%x\n",
                          env->sregs[SR_PC], env->sregs[SR_EAR],
                          env->sregs[SR_ESR], env->iflags);
            log_cpu_state_mask(CPU_LOG_INT, env, 0);
            env->iflags &= ~(IMM_FLAG | D_FLAG);
            env->sregs[SR_PC] = 0x20;
            break;

        case EXCP_MMU:
            env->regs[17] = env->sregs[SR_PC];

            env->sregs[SR_ESR] &= ~(1 << 12);
            /* Exception breaks branch + dslot sequence?  */
            if (env->iflags & D_FLAG) {
                D(qemu_log("D_FLAG set at exception bimm=%d\n", env->bimm));
                env->sregs[SR_ESR] |= 1 << 12 ;
                env->sregs[SR_BTR] = env->btarget;

                /* Reexecute the branch.  */
                env->regs[17] -= 4;
                /* was the branch immprefixed?.  */
                if (env->bimm) {
                    qemu_log_mask(CPU_LOG_INT,
                                  "bimm exception at pc=%x iflags=%x\n",
                                  env->sregs[SR_PC], env->iflags);
                    env->regs[17] -= 4;
                    log_cpu_state_mask(CPU_LOG_INT, env, 0);
                }
            } else if (env->iflags & IMM_FLAG) {
                D(qemu_log("IMM_FLAG set at exception\n"));
                env->regs[17] -= 4;
            }

            /* Disable the MMU.  */
            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
            env->sregs[SR_MSR] |= t;
            /* Exception in progress.  */
            env->sregs[SR_MSR] |= MSR_EIP;

            qemu_log_mask(CPU_LOG_INT,
                          "exception at pc=%x ear=%x iflags=%x\n",
                          env->sregs[SR_PC], env->sregs[SR_EAR], env->iflags);
            log_cpu_state_mask(CPU_LOG_INT, env, 0);
            env->iflags &= ~(IMM_FLAG | D_FLAG);
            env->sregs[SR_PC] = 0x20;
            break;

        case EXCP_IRQ:
            assert(!(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP)));
            assert(env->sregs[SR_MSR] & MSR_IE);
            assert(!(env->iflags & D_FLAG));

            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;

#if 0
#include "disas.h"

/* Useful instrumentation when debugging interrupt issues in either
   the models or in sw.  */
            {
                const char *sym;

                sym = lookup_symbol(env->sregs[SR_PC]);
                if (sym
                    && (!strcmp("netif_rx", sym)
                        || !strcmp("process_backlog", sym))) {

                    qemu_log(
                         "interrupt at pc=%x msr=%x %x iflags=%x sym=%s\n",
                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags,
                         sym);

                    log_cpu_state(env, 0);
                }
            }
#endif
            qemu_log_mask(CPU_LOG_INT,
                         "interrupt at pc=%x msr=%x %x iflags=%x\n",
                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);

            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM \
                                    | MSR_UM | MSR_IE);
            env->sregs[SR_MSR] |= t;

            env->regs[14] = env->sregs[SR_PC];
            env->sregs[SR_PC] = 0x10;
            //log_cpu_state_mask(CPU_LOG_INT, env, 0);
            break;

        case EXCP_BREAK:
        case EXCP_HW_BREAK:
            assert(!(env->iflags & IMM_FLAG));
            assert(!(env->iflags & D_FLAG));
            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
            qemu_log_mask(CPU_LOG_INT,
                        "break at pc=%x msr=%x %x iflags=%x\n",
                        env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
            log_cpu_state_mask(CPU_LOG_INT, env, 0);
            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
            env->sregs[SR_MSR] |= t;
            env->sregs[SR_MSR] |= MSR_BIP;
            if (env->exception_index == EXCP_HW_BREAK) {
                env->regs[16] = env->sregs[SR_PC];
                env->sregs[SR_MSR] |= MSR_BIP;
                env->sregs[SR_PC] = 0x18;
            } else
                env->sregs[SR_PC] = env->btarget;
            break;
        default:
            cpu_abort(env, "unhandled exception type=%d\n",
                      env->exception_index);
            break;
    }
}
Exemplo n.º 28
0
void sparc_cpu_do_interrupt(CPUState *cs)
{
    SPARCCPU *cpu = SPARC_CPU(cs);
    CPUSPARCState *env = &cpu->env;
    int intno = cs->exception_index;
    trap_state *tsptr;

    /* Compute PSR before exposing state.  */
    if (env->cc_op != CC_OP_FLAGS) {
        cpu_get_psr(env);
    }

#ifdef DEBUG_PCALL
    if (qemu_loglevel_mask(CPU_LOG_INT)) {
        static int count;
        const char *name;

        if (intno < 0 || intno >= 0x180) {
            name = "Unknown";
        } else if (intno >= 0x100) {
            name = "Trap Instruction";
        } else if (intno >= 0xc0) {
            name = "Window Fill";
        } else if (intno >= 0x80) {
            name = "Window Spill";
        } else {
            name = excp_names[intno];
            if (!name) {
                name = "Unknown";
            }
        }

        qemu_log("%6d: %s (v=%04x)\n", count, name, intno);
        log_cpu_state(cs, 0);
#if 0
        {
            int i;
            uint8_t *ptr;

            qemu_log("       code=");
            ptr = (uint8_t *)env->pc;
            for (i = 0; i < 16; i++) {
                qemu_log(" %02x", ldub(ptr + i));
            }
            qemu_log("\n");
        }
#endif
        count++;
    }
#endif
#if !defined(CONFIG_USER_ONLY)
    if (env->tl >= env->maxtl) {
        cpu_abort(cs, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
                  " Error state", cs->exception_index, env->tl, env->maxtl);
        return;
    }
#endif
    if (env->tl < env->maxtl - 1) {
        env->tl++;
    } else {
        env->pstate |= PS_RED;
        if (env->tl < env->maxtl) {
            env->tl++;
        }
    }
    tsptr = cpu_tsptr(env);

    tsptr->tstate = (cpu_get_ccr(env) << 32) |
        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
        cpu_get_cwp64(env);
    tsptr->tpc = env->pc;
    tsptr->tnpc = env->npc;
    tsptr->tt = intno;

    switch (intno) {
    case TT_IVEC:
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
        break;
    case TT_TFAULT:
    case TT_DFAULT:
    case TT_TMISS ... TT_TMISS + 3:
    case TT_DMISS ... TT_DMISS + 3:
    case TT_DPROT ... TT_DPROT + 3:
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
        break;
    default:
        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
        break;
    }

    if (intno == TT_CLRWIN) {
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
    } else if ((intno & 0x1c0) == TT_SPILL) {
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
    } else if ((intno & 0x1c0) == TT_FILL) {
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
    }
    env->tbr &= ~0x7fffULL;
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
    env->pc = env->tbr;
    env->npc = env->pc + 4;
    cs->exception_index = -1;
}
Exemplo n.º 29
0
void cpu_unassigned_access(CPUNios2State *env1, target_phys_addr_t addr,
                           int is_write, int is_exec, int is_asi, int size)
{
    qemu_log("unassigned access to %08X\n", addr);
}
Exemplo n.º 30
0
/* NOTE: must be called outside the CPU execute loop */
void cpu_reset(CPUX86State *env)
{
    int i;

    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
    }

    memset(env, 0, offsetof(CPUX86State, breakpoints));

    tlb_flush(env, 1);

    env->old_exception = -1;

    /* init to reset state */

#ifdef CONFIG_SOFTMMU
    env->hflags |= HF_SOFTMMU_MASK;
#endif
    env->hflags2 |= HF2_GIF_MASK;

    cpu_x86_update_cr0(env, 0x60000010);
    env->a20_mask = ~0x0;
    env->smbase = 0x30000;

    env->idt.limit = 0xffff;
    env->gdt.limit = 0xffff;
    env->ldt.limit = 0xffff;
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
    env->tr.limit = 0xffff;
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);

    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
                           DESC_R_MASK | DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);

    env->eip = 0xfff0;
    env->regs[R_EDX] = env->cpuid_version;

    env->eflags = 0x2;

    /* FPU init */
    for(i = 0;i < 8; i++)
        env->fptags[i] = 1;
    env->fpuc = 0x37f;

    env->mxcsr = 0x1f80;

    memset(env->dr, 0, sizeof(env->dr));
    env->dr[6] = DR6_FIXED_1;
    env->dr[7] = DR7_FIXED_1;
    cpu_breakpoint_remove_all(env, BP_CPU);
    cpu_watchpoint_remove_all(env, BP_CPU);

    env->mcg_status = 0;
}