Example #1
0
static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
{
    VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);
    SubchDev *sch = dev->sch;
    uint64_t indicators;

    if (vector >= 128) {
        return;
    }

    if (vector < VIRTIO_PCI_QUEUE_MAX) {
        if (!dev->indicators) {
            return;
        }
        indicators = ldq_phys(dev->indicators);
        indicators |= 1ULL << vector;
        stq_phys(dev->indicators, indicators);
    } else {
        if (!dev->indicators2) {
            return;
        }
        vector = 0;
        indicators = ldq_phys(dev->indicators2);
        indicators |= 1ULL << vector;
        stq_phys(dev->indicators2, indicators);
    }

    css_conditional_io_interrupt(sch);

}
Example #2
0
uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    uint64_t ret = 0;

    if (p == env->lock_addr) {
        uint64_t old = ldq_phys(p);
        if (old == env->lock_value) {
            stq_phys(p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}
Example #3
0
uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    uint64_t ret = 0;

    if (p == env->lock_addr) {
        uint64_t old = ldq_phys(cs->as, p);
        if (old == env->lock_value) {
            stq_phys(cs->as, p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}
Example #4
0
static void ppc_radix64_set_rc(PowerPCCPU *cpu, int rwx, uint64_t pte,
                               hwaddr pte_addr, int *prot)
{
    CPUState *cs = CPU(cpu);
    uint64_t npte;

    npte = pte | R_PTE_R; /* Always set reference bit */

    if (rwx == 1) { /* Store/Write */
        npte |= R_PTE_C; /* Set change bit */
    } else {
        /*
         * Treat the page as read-only for now, so that a later write
         * will pass through this function again to set the C bit.
         */
        *prot &= ~PAGE_WRITE;
    }

    if (pte ^ npte) { /* If pte has changed then write it back */
        stq_phys(cs->as, pte_addr, npte);
    }
}
Example #5
0
void do_smm_enter(X86CPU *cpu)
{
    CPUX86State *env = &cpu->env;
    CPUState *cs = CPU(cpu);
    target_ulong sm_state;
    SegmentCache *dt;
    int i, offset;

    qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);

    env->hflags |= HF_SMM_MASK;
    cpu_smm_update(env);

    sm_state = env->smbase + 0x8000;

#ifdef TARGET_X86_64
    for (i = 0; i < 6; i++) {
        dt = &env->segs[i];
        offset = 0x7e00 + i * 16;
        stw_phys(cs->as, sm_state + offset, dt->selector);
        stw_phys(cs->as, sm_state + offset + 2, (dt->flags >> 8) & 0xf0ff);
        stl_phys(cs->as, sm_state + offset + 4, dt->limit);
        stq_phys(cs->as, sm_state + offset + 8, dt->base);
    }

    stq_phys(cs->as, sm_state + 0x7e68, env->gdt.base);
    stl_phys(cs->as, sm_state + 0x7e64, env->gdt.limit);

    stw_phys(cs->as, sm_state + 0x7e70, env->ldt.selector);
    stq_phys(cs->as, sm_state + 0x7e78, env->ldt.base);
    stl_phys(cs->as, sm_state + 0x7e74, env->ldt.limit);
    stw_phys(cs->as, sm_state + 0x7e72, (env->ldt.flags >> 8) & 0xf0ff);

    stq_phys(cs->as, sm_state + 0x7e88, env->idt.base);
    stl_phys(cs->as, sm_state + 0x7e84, env->idt.limit);

    stw_phys(cs->as, sm_state + 0x7e90, env->tr.selector);
    stq_phys(cs->as, sm_state + 0x7e98, env->tr.base);
    stl_phys(cs->as, sm_state + 0x7e94, env->tr.limit);
    stw_phys(cs->as, sm_state + 0x7e92, (env->tr.flags >> 8) & 0xf0ff);

    stq_phys(cs->as, sm_state + 0x7ed0, env->efer);

    stq_phys(cs->as, sm_state + 0x7ff8, env->regs[R_EAX]);
    stq_phys(cs->as, sm_state + 0x7ff0, env->regs[R_ECX]);
    stq_phys(cs->as, sm_state + 0x7fe8, env->regs[R_EDX]);
    stq_phys(cs->as, sm_state + 0x7fe0, env->regs[R_EBX]);
    stq_phys(cs->as, sm_state + 0x7fd8, env->regs[R_ESP]);
    stq_phys(cs->as, sm_state + 0x7fd0, env->regs[R_EBP]);
    stq_phys(cs->as, sm_state + 0x7fc8, env->regs[R_ESI]);
    stq_phys(cs->as, sm_state + 0x7fc0, env->regs[R_EDI]);
    for (i = 8; i < 16; i++) {
        stq_phys(cs->as, sm_state + 0x7ff8 - i * 8, env->regs[i]);
    }
    stq_phys(cs->as, sm_state + 0x7f78, env->eip);
    stl_phys(cs->as, sm_state + 0x7f70, cpu_compute_eflags(env));
    stl_phys(cs->as, sm_state + 0x7f68, env->dr[6]);
    stl_phys(cs->as, sm_state + 0x7f60, env->dr[7]);

    stl_phys(cs->as, sm_state + 0x7f48, env->cr[4]);
    stl_phys(cs->as, sm_state + 0x7f50, env->cr[3]);
    stl_phys(cs->as, sm_state + 0x7f58, env->cr[0]);

    stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
    stl_phys(cs->as, sm_state + 0x7f00, env->smbase);
#else
    stl_phys(cs->as, sm_state + 0x7ffc, env->cr[0]);
    stl_phys(cs->as, sm_state + 0x7ff8, env->cr[3]);
    stl_phys(cs->as, sm_state + 0x7ff4, cpu_compute_eflags(env));
    stl_phys(cs->as, sm_state + 0x7ff0, env->eip);
    stl_phys(cs->as, sm_state + 0x7fec, env->regs[R_EDI]);
    stl_phys(cs->as, sm_state + 0x7fe8, env->regs[R_ESI]);
    stl_phys(cs->as, sm_state + 0x7fe4, env->regs[R_EBP]);
    stl_phys(cs->as, sm_state + 0x7fe0, env->regs[R_ESP]);
    stl_phys(cs->as, sm_state + 0x7fdc, env->regs[R_EBX]);
    stl_phys(cs->as, sm_state + 0x7fd8, env->regs[R_EDX]);
    stl_phys(cs->as, sm_state + 0x7fd4, env->regs[R_ECX]);
    stl_phys(cs->as, sm_state + 0x7fd0, env->regs[R_EAX]);
    stl_phys(cs->as, sm_state + 0x7fcc, env->dr[6]);
    stl_phys(cs->as, sm_state + 0x7fc8, env->dr[7]);

    stl_phys(cs->as, sm_state + 0x7fc4, env->tr.selector);
    stl_phys(cs->as, sm_state + 0x7f64, env->tr.base);
    stl_phys(cs->as, sm_state + 0x7f60, env->tr.limit);
    stl_phys(cs->as, sm_state + 0x7f5c, (env->tr.flags >> 8) & 0xf0ff);

    stl_phys(cs->as, sm_state + 0x7fc0, env->ldt.selector);
    stl_phys(cs->as, sm_state + 0x7f80, env->ldt.base);
    stl_phys(cs->as, sm_state + 0x7f7c, env->ldt.limit);
    stl_phys(cs->as, sm_state + 0x7f78, (env->ldt.flags >> 8) & 0xf0ff);

    stl_phys(cs->as, sm_state + 0x7f74, env->gdt.base);
    stl_phys(cs->as, sm_state + 0x7f70, env->gdt.limit);

    stl_phys(cs->as, sm_state + 0x7f58, env->idt.base);
    stl_phys(cs->as, sm_state + 0x7f54, env->idt.limit);

    for (i = 0; i < 6; i++) {
        dt = &env->segs[i];
        if (i < 3) {
            offset = 0x7f84 + i * 12;
        } else {
            offset = 0x7f2c + (i - 3) * 12;
        }
        stl_phys(cs->as, sm_state + 0x7fa8 + i * 4, dt->selector);
        stl_phys(cs->as, sm_state + offset + 8, dt->base);
        stl_phys(cs->as, sm_state + offset + 4, dt->limit);
        stl_phys(cs->as, sm_state + offset, (dt->flags >> 8) & 0xf0ff);
    }
    stl_phys(cs->as, sm_state + 0x7f14, env->cr[4]);

    stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
    stl_phys(cs->as, sm_state + 0x7ef8, env->smbase);
#endif
    /* init SMM cpu state */

#ifdef TARGET_X86_64
    cpu_load_efer(env, 0);
#endif
    cpu_load_eflags(env, 0, ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C |
                              DF_MASK));
    env->eip = 0x00008000;
    cpu_x86_update_cr0(env,
                       env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
                                      CR0_PG_MASK));
    cpu_x86_update_cr4(env, 0);
    env->dr[7] = 0x00000400;

    cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
                           0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffffffff,
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
                           DESC_A_MASK);
}
/* PC hardware initialisation */
static void s390_init(ram_addr_t ram_size,
                      const char *boot_device,
                      const char *kernel_filename,
                      const char *kernel_cmdline,
                      const char *initrd_filename,
                      const char *cpu_model)
{
    CPUState *env = NULL;
    ram_addr_t ram_addr;
    ram_addr_t kernel_size = 0;
    ram_addr_t initrd_offset;
    ram_addr_t initrd_size = 0;
    int i;

    /* XXX we only work on KVM for now */

    if (!kvm_enabled()) {
        fprintf(stderr, "The S390 target only works with KVM enabled\n");
        exit(1);
    }

    /* get a BUS */
    s390_bus = s390_virtio_bus_init(&ram_size);

    /* allocate RAM */
    ram_addr = qemu_ram_alloc(NULL, "s390.ram", ram_size);
    cpu_register_physical_memory(0, ram_size, ram_addr);

    /* init CPUs */
    if (cpu_model == NULL) {
        cpu_model = "host";
    }

    ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus);

    for (i = 0; i < smp_cpus; i++) {
        CPUState *tmp_env;

        tmp_env = cpu_init(cpu_model);
        if (!env) {
            env = tmp_env;
        }
        ipi_states[i] = tmp_env;
        tmp_env->halted = 1;
        tmp_env->exception_index = EXCP_HLT;
    }

    env->halted = 0;
    env->exception_index = 0;

    if (kernel_filename) {
        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));

        if (lduw_phys(KERN_IMAGE_START) != 0x0dd0) {
            fprintf(stderr, "Specified image is not an s390 boot image\n");
            exit(1);
        }

        env->psw.addr = KERN_IMAGE_START;
        env->psw.mask = 0x0000000180000000ULL;
    } else {
        ram_addr_t bios_size = 0;
        char *bios_filename;

        /* Load zipl bootloader */
        if (bios_name == NULL) {
            bios_name = ZIPL_FILENAME;
        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
        bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));
        qemu_free(bios_filename);

        if ((long)bios_size < 0) {
            hw_error("could not load bootloader '%s'\n", bios_name);
        }

        if (bios_size > 4096) {
            hw_error("stage1 bootloader is > 4k\n");
        }

        env->psw.addr = ZIPL_START;
        env->psw.mask = 0x0000000180000000ULL;
    }

    if (initrd_filename) {
        initrd_offset = INITRD_START;
        while (kernel_size + 0x100000 > initrd_offset) {
            initrd_offset += 0x100000;
        }
        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));

        stq_phys(INITRD_PARM_START, initrd_offset);
        stq_phys(INITRD_PARM_SIZE, initrd_size);
    }

    if (kernel_cmdline) {
        cpu_physical_memory_rw(KERN_PARM_AREA, (uint8_t *)kernel_cmdline,
                               strlen(kernel_cmdline), 1);
    }

    /* Create VirtIO network adapters */
    for(i = 0; i < nb_nics; i++) {
        NICInfo *nd = &nd_table[i];
        DeviceState *dev;

        if (!nd->model) {
            nd->model = qemu_strdup("virtio");
        }

        if (strcmp(nd->model, "virtio")) {
            fprintf(stderr, "S390 only supports VirtIO nics\n");
            exit(1);
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
    }

    /* Create VirtIO disk drives */
    for(i = 0; i < MAX_BLK_DEVS; i++) {
        DriveInfo *dinfo;
        DeviceState *dev;

        dinfo = drive_get(IF_IDE, 0, i);
        if (!dinfo) {
            continue;
        }

        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);
        qdev_init_nofail(dev);
    }
}
Example #7
0
void helper_stq_phys(uint64_t p, uint64_t v)
{
    stq_phys(p, v);
}
Example #8
0
void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    stq_phys(cs->as, p, v);
}
Example #9
0
void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = ENV_GET_CPU(env);
    stq_phys(cs->as, p, v);
}