Пример #1
0
Nios2CPU *cpu_nios2_init(const char *cpu_model)
{
    Nios2CPU *cpu;
    int i;

    cpu = NIOS2_CPU(object_new(TYPE_NIOS2_CPU));

    cpu->env.reset_addr = RESET_ADDRESS;
    cpu->env.exception_addr = EXCEPTION_ADDRESS;
    cpu->env.fast_tlb_miss_addr = FAST_TLB_MISS_ADDRESS;

    cpu_reset(CPU(cpu));
    qemu_init_vcpu(&cpu->env);

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

    for (i = 0; i < NUM_CORE_REGS; i++) {
        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
                                      offsetof(CPUNios2State, regs[i]),
                                      regnames[i]);
    }

#define GEN_HELPER 2
#include "helper.h"

  return cpu;
}
Пример #2
0
void nios2_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                          int flags)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    CPUNios2State *env = &cpu->env;
    int i;

    if (!env || !f) {
        return;
    }

    cpu_fprintf(f, "IN: PC=%x %s\n",
                env->regs[R_PC], lookup_symbol(env->regs[R_PC]));

    for (i = 0; i < NUM_CORE_REGS; i++) {
        cpu_fprintf(f, "%9s=%8.8x ", regnames[i], env->regs[i]);
        if ((i + 1) % 4 == 0) {
            cpu_fprintf(f, "\n");
        }
    }
    cpu_fprintf(f, " mmu write: VPN=%05X PID %02X TLBACC %08X\n",
                env->mmu.pteaddr_wr & CR_PTEADDR_VPN_MASK,
                (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4,
                env->mmu.tlbacc_wr);
    cpu_fprintf(f, "\n\n");
}
Пример #3
0
static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    CPUNios2State *env = &cpu->env;

    env->regs[R_PC] = value;
}
Пример #4
0
static void altera_iic_realize(DeviceState *dev, Error **errp)
{
    struct AlteraIIC *pv = ALTERA_IIC(dev);
    Error *err = NULL;

    pv->cpu = NIOS2_CPU(object_property_get_link(OBJECT(dev), "cpu", &err));
    if (!pv->cpu) {
        error_setg(errp, "altera,iic: CPU link not found: %s",
                   error_get_pretty(err));
        return;
    }
}
Пример #5
0
static void nios2_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    Nios2CPU *cpu = NIOS2_CPU(obj);
    CPUNios2State *env = &cpu->env;

    cs->env_ptr = env;

#if !defined(CONFIG_USER_ONLY)
    mmu_init(env);
#endif
}
Пример #6
0
static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    CPUNios2State *env = &cpu->env;

    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
        (env->regs[CR_STATUS] & CR_STATUS_PIE)) {
        cs->exception_index = EXCP_IRQ;
        nios2_cpu_do_interrupt(cs);
        return true;
    }
    return false;
}
Пример #7
0
static void nios2_generic_nommu_init(MachineState *machine)
{
    Nios2CPU *cpu;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *phys_tcm = g_new(MemoryRegion, 1);
    MemoryRegion *phys_tcm_alias = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
    MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);
    ram_addr_t tcm_base = 0x0;
    ram_addr_t tcm_size = 0x1000;    /* 1 kiB, but QEMU limit is 4 kiB */
    ram_addr_t ram_base = 0x10000000;
    ram_addr_t ram_size = 0x08000000;

    /* Physical TCM (tb_ram_1k) with alias at 0xc0000000 */
    memory_region_init_ram(phys_tcm, NULL, "nios2.tcm", tcm_size,
                           &error_abort);
    memory_region_init_alias(phys_tcm_alias, NULL, "nios2.tcm.alias",
                             phys_tcm, 0, tcm_size);
    memory_region_add_subregion(address_space_mem, tcm_base, phys_tcm);
    memory_region_add_subregion(address_space_mem, 0xc0000000 + tcm_base,
                                phys_tcm_alias);

    /* Physical DRAM with alias at 0xc0000000 */
    memory_region_init_ram(phys_ram, NULL, "nios2.ram", ram_size,
                           &error_abort);
    memory_region_init_alias(phys_ram_alias, NULL, "nios2.ram.alias",
                             phys_ram, 0, ram_size);
    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
    memory_region_add_subregion(address_space_mem, 0xc0000000 + ram_base,
                                phys_ram_alias);

    cpu = NIOS2_CPU(cpu_create(TYPE_NIOS2_CPU));

    /* Remove MMU */
    cpu->mmu_present = false;

    /* Reset vector is the first 32 bytes of RAM.  */
    cpu->reset_addr = ram_base;

    /* The interrupt vector comes right after reset.  */
    cpu->exception_addr = ram_base + 0x20;

    /*
     * The linker script does have a TLB miss memory region declared,
     * but this should never be used with no MMU.
     */
    cpu->fast_tlb_miss_addr = 0x7fff400;

    nios2_load_kernel(cpu, ram_base, ram_size, machine->initrd_filename,
                      BINARY_DEVICE_TREE_FILE, NULL);
}
Пример #8
0
static int nios2_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    CPUClass *cc = CPU_GET_CLASS(cs);
    CPUNios2State *env = &cpu->env;

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

    if (n < 32) {            /* GP regs */
        env->regs[n] = ldl_p(mem_buf);
    } else if (n == 32) {    /* PC */
        env->regs[R_PC] = ldl_p(mem_buf);
    } else if (n < 49) {     /* Status regs */
        env->regs[n - 1] = ldl_p(mem_buf);
    }

    return 4;
}
Пример #9
0
static int nios2_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    Nios2CPU *cpu = NIOS2_CPU(cs);
    CPUClass *cc = CPU_GET_CLASS(cs);
    CPUNios2State *env = &cpu->env;

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

    if (n < 32) {          /* GP regs */
        return gdb_get_reg32(mem_buf, env->regs[n]);
    } else if (n == 32) {    /* PC */
        return gdb_get_reg32(mem_buf, env->regs[R_PC]);
    } else if (n < 49) {     /* Status regs */
        return gdb_get_reg32(mem_buf, env->regs[n - 1]);
    }

    /* Invalid regs */
    return 0;
}
Пример #10
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
}