⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsi53c895a.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 4 页
字号:
    case 0x06: /* SDID */        if ((val & 0xf) != (s->ssid & 0xf))            BADF("Destination ID does not match SSID\n");        s->sdid = val & 0xf;        break;    case 0x07: /* GPREG0 */        break;    case 0x08: /* SFBR */        /* The CPU is not allowed to write to this register.  However the           SCRIPTS register move instructions are.  */        s->sfbr = val;        break;    case 0x0c: case 0x0d: case 0x0e: case 0x0f:        /* Linux writes to these readonly registers on startup.  */        return;    CASE_SET_REG32(dsa, 0x10)    case 0x14: /* ISTAT0 */        s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);        if (val & LSI_ISTAT0_ABRT) {            lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);        }        if (val & LSI_ISTAT0_INTF) {            s->istat0 &= ~LSI_ISTAT0_INTF;            lsi_update_irq(s);        }        if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {            DPRINTF("Woken by SIGP\n");            s->waiting = 0;            s->dsp = s->dnad;            lsi_execute_script(s);        }        if (val & LSI_ISTAT0_SRST) {            lsi_soft_reset(s);        }    case 0x16: /* MBOX0 */        s->mbox0 = val;    case 0x17: /* MBOX1 */        s->mbox1 = val;    case 0x1b: /* CTEST3 */        s->ctest3 = val & 0x0f;        break;    CASE_SET_REG32(temp, 0x1c)    case 0x21: /* CTEST4 */        if (val & 7) {           BADF("Unimplemented CTEST4-FBL 0x%x\n", val);        }        s->ctest4 = val;        break;    case 0x22: /* CTEST5 */        if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {            BADF("CTEST5 DMA increment not implemented\n");        }        s->ctest5 = val;        break;    case 0x2c: /* DSPS[0:7] */        s->dsp &= 0xffffff00;        s->dsp |= val;        break;    case 0x2d: /* DSPS[8:15] */        s->dsp &= 0xffff00ff;        s->dsp |= val << 8;        break;    case 0x2e: /* DSPS[16:23] */        s->dsp &= 0xff00ffff;        s->dsp |= val << 16;        break;    case 0x2f: /* DSPS[14:31] */        s->dsp &= 0x00ffffff;        s->dsp |= val << 24;        if ((s->dmode & LSI_DMODE_MAN) == 0            && (s->istat1 & LSI_ISTAT1_SRUN) == 0)            lsi_execute_script(s);        break;    CASE_SET_REG32(dsps, 0x30)    CASE_SET_REG32(scratch[0], 0x34)    case 0x38: /* DMODE */        if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {            BADF("IO mappings not implemented\n");        }        s->dmode = val;        break;    case 0x39: /* DIEN */        s->dien = val;        lsi_update_irq(s);        break;    case 0x3b: /* DCNTL */        s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);        if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)            lsi_execute_script(s);        break;    case 0x40: /* SIEN0 */        s->sien0 = val;        lsi_update_irq(s);        break;    case 0x41: /* SIEN1 */        s->sien1 = val;        lsi_update_irq(s);        break;    case 0x47: /* GPCNTL0 */        break;    case 0x48: /* STIME0 */        s->stime0 = val;        break;    case 0x49: /* STIME1 */        if (val & 0xf) {            DPRINTF("General purpose timer not implemented\n");            /* ??? Raising the interrupt immediately seems to be sufficient               to keep the FreeBSD driver happy.  */            lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);        }        break;    case 0x4a: /* RESPID0 */        s->respid0 = val;        break;    case 0x4b: /* RESPID1 */        s->respid1 = val;        break;    case 0x4d: /* STEST1 */        s->stest1 = val;        break;    case 0x4e: /* STEST2 */        if (val & 1) {            BADF("Low level mode not implemented\n");        }        s->stest2 = val;        break;    case 0x4f: /* STEST3 */        if (val & 0x41) {            BADF("SCSI FIFO test mode not implemented\n");        }        s->stest3 = val;        break;    case 0x56: /* CCNTL0 */        s->ccntl0 = val;        break;    case 0x57: /* CCNTL1 */        s->ccntl1 = val;        break;    CASE_SET_REG32(mmrs, 0xa0)    CASE_SET_REG32(mmws, 0xa4)    CASE_SET_REG32(sfs, 0xa8)    CASE_SET_REG32(drs, 0xac)    CASE_SET_REG32(sbms, 0xb0)    CASE_SET_REG32(dmbs, 0xb4)    CASE_SET_REG32(dnad64, 0xb8)    CASE_SET_REG32(pmjad1, 0xc0)    CASE_SET_REG32(pmjad2, 0xc4)    CASE_SET_REG32(rbc, 0xc8)    CASE_SET_REG32(ua, 0xcc)    CASE_SET_REG32(ia, 0xd4)    CASE_SET_REG32(sbc, 0xd8)    CASE_SET_REG32(csbc, 0xdc)    default:        if (offset >= 0x5c && offset < 0xa0) {            int n;            int shift;            n = (offset - 0x58) >> 2;            shift = (offset & 3) * 8;            s->scratch[n] &= ~(0xff << shift);            s->scratch[n] |= (val & 0xff) << shift;        } else {            BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val);        }    }#undef CASE_SET_REG32}static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    lsi_reg_writeb(s, addr & 0xff, val);}static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    addr &= 0xff;    lsi_reg_writeb(s, addr, val & 0xff);    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);}static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    addr &= 0xff;    lsi_reg_writeb(s, addr, val & 0xff);    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);    lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);}static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    return lsi_reg_readb(s, addr & 0xff);}static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0xff;    val = lsi_reg_readb(s, addr);    val |= lsi_reg_readb(s, addr + 1) << 8;    return val;}static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0xff;    val = lsi_reg_readb(s, addr);    val |= lsi_reg_readb(s, addr + 1) << 8;    val |= lsi_reg_readb(s, addr + 2) << 16;    val |= lsi_reg_readb(s, addr + 3) << 24;    return val;}static CPUReadMemoryFunc *lsi_mmio_readfn[3] = {    lsi_mmio_readb,    lsi_mmio_readw,    lsi_mmio_readl,};static CPUWriteMemoryFunc *lsi_mmio_writefn[3] = {    lsi_mmio_writeb,    lsi_mmio_writew,    lsi_mmio_writel,};static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    uint32_t newval;    int shift;    addr &= 0x1fff;    newval = s->script_ram[addr >> 2];    shift = (addr & 3) * 8;    newval &= ~(0xff << shift);    newval |= val << shift;    s->script_ram[addr >> 2] = newval;}static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    uint32_t newval;    addr &= 0x1fff;    newval = s->script_ram[addr >> 2];    if (addr & 2) {        newval = (newval & 0xffff) | (val << 16);    } else {        newval = (newval & 0xffff0000) | val;    }    s->script_ram[addr >> 2] = newval;}static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    addr &= 0x1fff;    s->script_ram[addr >> 2] = val;}static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0x1fff;    val = s->script_ram[addr >> 2];    val >>= (addr & 3) * 8;    return val & 0xff;}static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0x1fff;    val = s->script_ram[addr >> 2];    if (addr & 2)        val >>= 16;    return le16_to_cpu(val);}static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr){    LSIState *s = (LSIState *)opaque;    addr &= 0x1fff;    return le32_to_cpu(s->script_ram[addr >> 2]);}static CPUReadMemoryFunc *lsi_ram_readfn[3] = {    lsi_ram_readb,    lsi_ram_readw,    lsi_ram_readl,};static CPUWriteMemoryFunc *lsi_ram_writefn[3] = {    lsi_ram_writeb,    lsi_ram_writew,    lsi_ram_writel,};static uint32_t lsi_io_readb(void *opaque, uint32_t addr){    LSIState *s = (LSIState *)opaque;    return lsi_reg_readb(s, addr & 0xff);}static uint32_t lsi_io_readw(void *opaque, uint32_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0xff;    val = lsi_reg_readb(s, addr);    val |= lsi_reg_readb(s, addr + 1) << 8;    return val;}static uint32_t lsi_io_readl(void *opaque, uint32_t addr){    LSIState *s = (LSIState *)opaque;    uint32_t val;    addr &= 0xff;    val = lsi_reg_readb(s, addr);    val |= lsi_reg_readb(s, addr + 1) << 8;    val |= lsi_reg_readb(s, addr + 2) << 16;    val |= lsi_reg_readb(s, addr + 3) << 24;    return val;}static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    lsi_reg_writeb(s, addr & 0xff, val);}static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    addr &= 0xff;    lsi_reg_writeb(s, addr, val & 0xff);    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);}static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val){    LSIState *s = (LSIState *)opaque;    addr &= 0xff;    lsi_reg_writeb(s, addr, val & 0xff);    lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);    lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);    lsi_reg_writeb(s, addr + 2, (val >> 24) & 0xff);}static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,                            uint32_t addr, uint32_t size, int type){    LSIState *s = (LSIState *)pci_dev;    DPRINTF("Mapping IO at %08x\n", addr);    register_ioport_write(addr, 256, 1, lsi_io_writeb, s);    register_ioport_read(addr, 256, 1, lsi_io_readb, s);    register_ioport_write(addr, 256, 2, lsi_io_writew, s);    register_ioport_read(addr, 256, 2, lsi_io_readw, s);    register_ioport_write(addr, 256, 4, lsi_io_writel, s);    register_ioport_read(addr, 256, 4, lsi_io_readl, s);}static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,                             uint32_t addr, uint32_t size, int type){    LSIState *s = (LSIState *)pci_dev;    DPRINTF("Mapping ram at %08x\n", addr);    s->script_ram_base = addr;    cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);}static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num,                              uint32_t addr, uint32_t size, int type){    LSIState *s = (LSIState *)pci_dev;    DPRINTF("Mapping registers at %08x\n", addr);    cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr);}void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id){    LSIState *s = (LSIState *)opaque;    if (id < 0) {        for (id = 0; id < LSI_MAX_DEVS; id++) {            if (s->scsi_dev[id] == NULL)                break;        }    }    if (id >= LSI_MAX_DEVS) {        BADF("Bad Device ID %d\n", id);        return;    }    if (s->scsi_dev[id]) {        DPRINTF("Destroying device %d\n", id);        scsi_disk_destroy(s->scsi_dev[id]);    }    DPRINTF("Attaching block device %d\n", id);    s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);}void *lsi_scsi_init(PCIBus *bus, int devfn){    LSIState *s;    s = (LSIState *)pci_register_device(bus, "LSI53C895A SCSI HBA",                                        sizeof(*s), devfn, NULL, NULL);    if (s == NULL) {        fprintf(stderr, "lsi-scsi: Failed to register PCI device\n");        return NULL;    }    s->pci_dev.config[0x00] = 0x00;    s->pci_dev.config[0x01] = 0x10;    s->pci_dev.config[0x02] = 0x12;    s->pci_dev.config[0x03] = 0x00;    s->pci_dev.config[0x0b] = 0x01;    s->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */    s->mmio_io_addr = cpu_register_io_memory(0, lsi_mmio_readfn,                                             lsi_mmio_writefn, s);    s->ram_io_addr = cpu_register_io_memory(0, lsi_ram_readfn,                                            lsi_ram_writefn, s);    pci_register_io_region((struct PCIDevice *)s, 0, 256,                           PCI_ADDRESS_SPACE_IO, lsi_io_mapfunc);    pci_register_io_region((struct PCIDevice *)s, 1, 0x400,                           PCI_ADDRESS_SPACE_MEM, lsi_mmio_mapfunc);    pci_register_io_region((struct PCIDevice *)s, 2, 0x2000,                           PCI_ADDRESS_SPACE_MEM, lsi_ram_mapfunc);    s->queue = qemu_malloc(sizeof(lsi_queue));    s->queue_len = 1;    s->active_commands = 0;    lsi_soft_reset(s);    return s;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -