📄 lsi53c895a.c
字号:
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 + -