Esempio n. 1
0
static unsigned long sun4u_load_kernel(const char *kernel_filename,
                                       const char *initrd_filename,
                                       ram_addr_t RAM_size, long *initrd_size)
{
    int linux_boot;
    unsigned int i;
    long kernel_size;

    linux_boot = (kernel_filename != NULL);

    kernel_size = 0;
    if (linux_boot) {
        int bswap_needed;

#ifdef BSWAP_NEEDED
        bswap_needed = 1;
#else
        bswap_needed = 0;
#endif
        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL,
                               1, ELF_MACHINE, 0);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                    RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
                                    TARGET_PAGE_SIZE);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              KERNEL_LOAD_ADDR,
                                              RAM_size - KERNEL_LOAD_ADDR);
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                    kernel_filename);
            exit(1);
        }

        /* load initrd */
        *initrd_size = 0;
        if (initrd_filename) {
            *initrd_size = load_image_targphys(initrd_filename,
                                               INITRD_LOAD_ADDR,
                                               RAM_size - INITRD_LOAD_ADDR);
            if (*initrd_size < 0) {
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                        initrd_filename);
                exit(1);
            }
        }
        if (*initrd_size > 0) {
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
                if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
                    stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
                    stl_phys(KERNEL_LOAD_ADDR + i + 20, *initrd_size);
                    break;
                }
            }
        }
    }
    return kernel_size;
}
Esempio n. 2
0
/* Send an MSI-X message */
void msix_notify(PCIDevice *dev, unsigned vector)
{
    uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE;
    uint64_t address;
    uint32_t data;

    if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
        return;
    if (msix_is_masked(dev, vector)) {
        msix_set_pending(dev, vector);
        return;
    }

#ifdef KVM_CAP_IRQCHIP
    if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) {
        kvm_set_irq(dev->msix_irq_entries[vector].gsi, 1, NULL);
        return;
    }
#endif

    address = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR);
    address = (address << 32) | pci_get_long(table_entry + MSIX_MSG_ADDR);
    data = pci_get_long(table_entry + MSIX_MSG_DATA);
    stl_phys(address, data);
}
Esempio n. 3
0
File: r2d.c Progetto: agocke/qemu
static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
              const char *boot_device,
	      const char *kernel_filename, const char *kernel_cmdline,
	      const char *initrd_filename, const char *cpu_model)
{
    CPUState *env;
    struct SH7750State *s;
    ram_addr_t sdram_addr, sm501_vga_ram_addr;
    qemu_irq *irq;
    PCIBus *pci;
    int i;

    if (!cpu_model)
        cpu_model = "SH7751R";

    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Allocate memory space */
    sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
    cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
    /* Register peripherals */
    s = sh7750_init(env);
    irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
    pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);

    sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
    sm501_init(0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
	       serial_hds[2]);

    /* onboard CF (True IDE mode, Master only). */
    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
        drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);

    /* NIC: rtl8139 on-board, and 2 slots. */
    pci_nic_init(pci, &nd_table[0], 2 << 3, "rtl8139");
    for (i = 1; i < nb_nics; i++)
        pci_nic_init(pci, &nd_table[i], -1, "ne2k_pci");

    /* Todo: register on board registers */
    {
      int kernel_size;
      /* initialization which should be done by firmware */
      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */

      kernel_size = load_image(kernel_filename, phys_ram_base);

      if (kernel_size < 0) {
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
        exit(1);
      }

      env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
    }
}
Esempio n. 4
0
static void bcm2835_mbox_write(void *opaque, hwaddr offset,
                               uint64_t value, unsigned size)
{
    BCM2835MboxState *s = opaque;
    hwaddr childaddr;
    uint8_t ch;

    offset &= 0xff;

    switch (offset) {
    case MAIL0_SENDER:
        break;

    case MAIL0_CONFIG:
        s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQEN;
        s->mbox[0].config |= value & ARM_MC_IHAVEDATAIRQEN;
        break;

    case 0xa0 ... 0xac: /* MAIL1_WRITE */
        if (s->mbox[1].status & ARM_MS_FULL) {
            /* Mailbox full */
            qemu_log_mask(LOG_GUEST_ERROR, "%s: mailbox full\n", __func__);
        } else {
            ch = value & 0xf;
            if (ch < MBOX_CHAN_COUNT) {
                childaddr = ch << MBOX_AS_CHAN_SHIFT;
                if (ldl_phys(&s->mbox_as, childaddr + MBOX_AS_PENDING)) {
                    /* Child busy, push delayed. Push it in the arm->vc mbox */
                    mbox_push(&s->mbox[1], value);
                } else {
                    /* Push it directly to the child device */
                    stl_phys(&s->mbox_as, childaddr, value);
                }
            } else {
                /* Invalid channel number */
                qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid channel %u\n",
                              __func__, ch);
            }
        }
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
                      __func__, offset);
        return;
    }

    bcm2835_mbox_update(s);
}
Esempio n. 5
0
uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    uint64_t ret = 0;

    if (p == env->lock_addr) {
        int32_t old = ldl_phys(p);
        if (old == (int32_t)env->lock_value) {
            stl_phys(p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}
Esempio n. 6
0
uint64_t helper_stl_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) {
        int32_t old = ldl_phys(cs->as, p);
        if (old == (int32_t)env->lock_value) {
            stl_phys(cs->as, p, v);
            ret = 1;
        }
    }
    env->lock_addr = -1;

    return ret;
}
Esempio n. 7
0
/* Send an MSI-X message */
void msix_notify(PCIDevice *dev, unsigned vector)
{
    uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE;
    uint64_t address;
    uint32_t data;

    if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector])
        return;
    if (msix_is_masked(dev, vector)) {
        msix_set_pending(dev, vector);
        return;
    }

    address = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR);
    address = (address << 32) | pci_get_long(table_entry + MSIX_MSG_ADDR);
    data = pci_get_long(table_entry + MSIX_MSG_DATA);
    stl_phys(address, data);
}
Esempio n. 8
0
static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
{
    hwaddr pa;
    pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
    stl_phys(pa, val);
}
Esempio n. 9
0
static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
{
    target_phys_addr_t pa;
    pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
    stl_phys(pa, val);
}
Esempio n. 10
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);
}
Esempio n. 11
0
void helper_stl_phys(uint64_t p, uint64_t v)
{
    stl_phys(p, v);
}
Esempio n. 12
0
void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = CPU(alpha_env_get_cpu(env));
    stl_phys(cs->as, p, v);
}
Esempio n. 13
0
static void r2d_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;
    struct SH7750State *s;
    ram_addr_t sdram_addr;
    qemu_irq *irq;
    PCIBus *pci;
    DriveInfo *dinfo;
    int i;

    if (!cpu_model)
        cpu_model = "SH7751R";

    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Allocate memory space */
    sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
    cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
    /* Register peripherals */
    s = sh7750_init(env);
    irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
    pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);

    sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);

    /* onboard CF (True IDE mode, Master only). */
    if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL)
	mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
		      dinfo, NULL);

    /* NIC: rtl8139 on-board, and 2 slots. */
    for (i = 0; i < nb_nics; i++)
        pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL);

    /* Todo: register on board registers */
    if (kernel_filename) {
      int kernel_size;
      /* initialization which should be done by firmware */
      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */

      if (kernel_cmdline) {
          kernel_size = load_image_targphys(kernel_filename,
				   SDRAM_BASE + LINUX_LOAD_OFFSET,
				   SDRAM_SIZE - LINUX_LOAD_OFFSET);
          env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
          pstrcpy_targphys("cmdline", SDRAM_BASE + 0x10100, 256, kernel_cmdline);
      } else {
          kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
      }

      if (kernel_size < 0) {
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
        exit(1);
      }
    }
}
Esempio n. 14
0
static void r2d_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;
    struct SH7750State *s;
    ram_addr_t sdram_addr;
    qemu_irq *irq;
    DriveInfo *dinfo;
    int i;

    if (!cpu_model)
        cpu_model = "SH7751R";

    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }

    /* Allocate memory space */
    sdram_addr = qemu_ram_alloc(NULL, "r2d.sdram", SDRAM_SIZE);
    cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
    /* Register peripherals */
    s = sh7750_init(env);
    irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
    sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);

    sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);

    /* onboard CF (True IDE mode, Master only). */
    dinfo = drive_get(IF_IDE, 0, 0);
    mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
                  dinfo, NULL);

    /* onboard flash memory */
    dinfo = drive_get(IF_PFLASH, 0, 0);
    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
                          dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                          FLASH_SIZE >> 16,
                          1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
                          0x555, 0x2aa, 0);

    /* NIC: rtl8139 on-board, and 2 slots. */
    for (i = 0; i < nb_nics; i++)
        pci_nic_init_nofail(&nd_table[i], "rtl8139", i==0 ? "2" : NULL);

    /* USB keyboard */
    usbdevice_create("keyboard");

    /* Todo: register on board registers */
    memset(&boot_params, 0, sizeof(boot_params));

    if (kernel_filename) {
        int kernel_size;

        kernel_size = load_image_targphys(kernel_filename,
                                          SDRAM_BASE + LINUX_LOAD_OFFSET,
                                          INITRD_LOAD_OFFSET - LINUX_LOAD_OFFSET);
        if (kernel_size < 0) {
          fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
          exit(1);
        }

        /* initialization which should be done by firmware */
        stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
        stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
        env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */
    }

    if (initrd_filename) {
        int initrd_size;

        initrd_size = load_image_targphys(initrd_filename,
                                          SDRAM_BASE + INITRD_LOAD_OFFSET,
                                          SDRAM_SIZE - INITRD_LOAD_OFFSET);

        if (initrd_size < 0) {
          fprintf(stderr, "qemu: could not load initrd '%s'\n", initrd_filename);
          exit(1);
        }

        /* initialization which should be done by firmware */
        boot_params.loader_type = 1;
        boot_params.initrd_start = INITRD_LOAD_OFFSET;
        boot_params.initrd_size = initrd_size;
    }

    if (kernel_cmdline) {
        strncpy(boot_params.kernel_cmdline, kernel_cmdline,
                sizeof(boot_params.kernel_cmdline));
    }

    rom_add_blob_fixed("boot_params", &boot_params, sizeof(boot_params),
                       SDRAM_BASE + BOOT_PARAMS_OFFSET);
}
Esempio n. 15
0
static void sun4uv_init(ram_addr_t RAM_size, int vga_ram_size,
                        const char *boot_devices,
                        const char *kernel_filename, const char *kernel_cmdline,
                        const char *initrd_filename, const char *cpu_model,
                        const struct hwdef *hwdef)
{
    CPUState *env;
    char buf[1024];
    m48t59_t *nvram;
    int ret, linux_boot;
    unsigned int i;
    ram_addr_t ram_offset, prom_offset, vga_ram_offset;
    long initrd_size, kernel_size;
    PCIBus *pci_bus, *pci_bus2, *pci_bus3;
    QEMUBH *bh;
    qemu_irq *irq;
    int drive_index;
    BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
    BlockDriverState *fd[MAX_FD];
    void *fw_cfg;
    ResetData *reset_info;

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */
    if (!cpu_model)
        cpu_model = hwdef->default_cpu_model;

    env = cpu_init(cpu_model);
    if (!env) {
        fprintf(stderr, "Unable to find Sparc CPU definition\n");
        exit(1);
    }
    bh = qemu_bh_new(tick_irq, env);
    env->tick = ptimer_init(bh);
    ptimer_set_period(env->tick, 1ULL);

    bh = qemu_bh_new(stick_irq, env);
    env->stick = ptimer_init(bh);
    ptimer_set_period(env->stick, 1ULL);

    bh = qemu_bh_new(hstick_irq, env);
    env->hstick = ptimer_init(bh);
    ptimer_set_period(env->hstick, 1ULL);

    reset_info = qemu_mallocz(sizeof(ResetData));
    reset_info->env = env;
    reset_info->reset_addr = hwdef->prom_addr + 0x40ULL;
    qemu_register_reset(main_cpu_reset, reset_info);
    main_cpu_reset(reset_info);
    // Override warm reset address with cold start address
    env->pc = hwdef->prom_addr + 0x20ULL;
    env->npc = env->pc + 4;

    /* allocate RAM */
    ram_offset = qemu_ram_alloc(RAM_size);
    cpu_register_physical_memory(0, RAM_size, ram_offset);

    prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
    cpu_register_physical_memory(hwdef->prom_addr,
                                 (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
                                 TARGET_PAGE_MASK,
                                 prom_offset | IO_MEM_ROM);

    if (bios_name == NULL)
        bios_name = PROM_FILENAME;
    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
    ret = load_elf(buf, hwdef->prom_addr - PROM_VADDR, NULL, NULL, NULL);
    if (ret < 0) {
        ret = load_image_targphys(buf, hwdef->prom_addr,
                                  (PROM_SIZE_MAX + TARGET_PAGE_SIZE) &
                                  TARGET_PAGE_MASK);
        if (ret < 0) {
            fprintf(stderr, "qemu: could not load prom '%s'\n",
                    buf);
            exit(1);
        }
    }

    kernel_size = 0;
    initrd_size = 0;
    if (linux_boot) {
        /* XXX: put correct offset */
        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
        if (kernel_size < 0)
            kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                    ram_size - KERNEL_LOAD_ADDR);
        if (kernel_size < 0)
            kernel_size = load_image_targphys(kernel_filename,
                                              KERNEL_LOAD_ADDR,
                                              ram_size - KERNEL_LOAD_ADDR);
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                    kernel_filename);
            exit(1);
        }

        /* load initrd */
        if (initrd_filename) {
            initrd_size = load_image_targphys(initrd_filename,
                                              INITRD_LOAD_ADDR,
                                              ram_size - INITRD_LOAD_ADDR);
            if (initrd_size < 0) {
                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                        initrd_filename);
                exit(1);
            }
        }
        if (initrd_size > 0) {
            for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
                if (ldl_phys(KERNEL_LOAD_ADDR + i) == 0x48647253) { // HdrS
                    stl_phys(KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
                    stl_phys(KERNEL_LOAD_ADDR + i + 20, initrd_size);
                    break;
                }
            }
        }
    }
    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, &pci_bus2,
                           &pci_bus3);
    isa_mem_base = VGA_BASE;
    vga_ram_offset = qemu_ram_alloc(vga_ram_size);
    pci_vga_init(pci_bus, phys_ram_base + vga_ram_offset,
                 vga_ram_offset, vga_ram_size,
                 0, 0);

    // XXX Should be pci_bus3
    pci_ebus_init(pci_bus, -1);

    i = 0;
    if (hwdef->console_serial_base) {
        serial_mm_init(hwdef->console_serial_base, 0, NULL, 115200,
                       serial_hds[i], 1);
        i++;
    }
    for(; i < MAX_SERIAL_PORTS; i++) {
        if (serial_hds[i]) {
            serial_init(serial_io[i], NULL/*serial_irq[i]*/, 115200,
                        serial_hds[i]);
        }
    }

    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
        if (parallel_hds[i]) {
            parallel_init(parallel_io[i], NULL/*parallel_irq[i]*/,
                          parallel_hds[i]);
        }
    }

    for(i = 0; i < nb_nics; i++)
        pci_nic_init(pci_bus, &nd_table[i], -1, "ne2k_pci");

    irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
        fprintf(stderr, "qemu: too many IDE bus\n");
        exit(1);
    }
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
        drive_index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS,
                                      i % MAX_IDE_DEVS);
       if (drive_index != -1)
           hd[i] = drives_table[drive_index].bdrv;
       else
           hd[i] = NULL;
    }

    pci_cmd646_ide_init(pci_bus, hd, 1);

    /* FIXME: wire up interrupts.  */
    i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
    for(i = 0; i < MAX_FD; i++) {
        drive_index = drive_get_index(IF_FLOPPY, 0, i);
       if (drive_index != -1)
           fd[i] = drives_table[drive_index].bdrv;
       else
           fd[i] = NULL;
    }
    floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
    nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
                           KERNEL_LOAD_ADDR, kernel_size,
                           kernel_cmdline,
                           INITRD_LOAD_ADDR, initrd_size,
                           /* XXX: need an option to load a NVRAM image */
                           0,
                           graphic_width, graphic_height, graphic_depth,
                           (uint8_t *)&nd_table[0].macaddr);

    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
    fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
}
Esempio n. 16
0
void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
{
    CPUState *cs = ENV_GET_CPU(env);
    stl_phys(cs->as, p, v);
}