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

📄 esp.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            switch(format) {            case 0:                len = cdrom_read_toc(nb_sectors, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                s->ti_size = len;                break;            case 1:                /* multi session : only a single session defined */                memset(buf, 0, 12);                buf[1] = 0x0a;                buf[2] = 0x01;                buf[3] = 0x01;                s->ti_size = 12;                break;            case 2:                len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track);                if (len < 0)                    goto error_cmd;                s->ti_size = len;                break;            default:            error_cmd:                DPRINTF("Read TOC error\n");                // XXX error handling                break;            }	    s->ti_dir = 1;            break;        }    default:	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);	break;    }    s->rregs[4] = STAT_IN | STAT_TC | STAT_DI;    s->rregs[5] = INTR_BS | INTR_FC;    s->rregs[6] = SEQ_CD;    s->espdmaregs[0] |= DMA_INTR;    pic_set_irq(s->irq, 1);}static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len){    uint32_t dmaptr, dmalen;    dmalen = s->wregs[0] | (s->wregs[1] << 8);    DPRINTF("Transfer status len %d\n", dmalen);    if (s->dma) {	dmaptr = iommu_translate(s->espdmaregs[1]);	DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r');	cpu_physical_memory_write(dmaptr, buf, len);	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;	s->rregs[5] = INTR_BS | INTR_FC;	s->rregs[6] = SEQ_CD;    } else {	memcpy(s->ti_buf, buf, len);	s->ti_size = dmalen;	s->ti_rptr = 0;	s->ti_wptr = 0;	s->rregs[7] = dmalen;    }    s->espdmaregs[0] |= DMA_INTR;    pic_set_irq(s->irq, 1);}static const uint8_t okbuf[] = {0, 0};static void handle_ti(ESPState *s){    uint32_t dmaptr, dmalen;    unsigned int i;    dmalen = s->wregs[0] | (s->wregs[1] << 8);    DPRINTF("Transfer Information len %d\n", dmalen);    if (s->dma) {	dmaptr = iommu_translate(s->espdmaregs[1]);	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr);	for (i = 0; i < s->ti_size; i++) {	    dmaptr = iommu_translate(s->espdmaregs[1] + i);	    if (s->ti_dir)		cpu_physical_memory_write(dmaptr, &s->ti_buf[i], 1);	    else		cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1);	}        if (s->dma_cb) {            s->dma_cb(s, s->espdmaregs[1], dmalen);            s->dma_cb = NULL;        }	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;	s->rregs[5] = INTR_BS;	s->rregs[6] = 0;	s->espdmaregs[0] |= DMA_INTR;    } else {	s->ti_size = dmalen;	s->ti_rptr = 0;	s->ti_wptr = 0;	s->rregs[7] = dmalen;    }	    pic_set_irq(s->irq, 1);}static void esp_reset(void *opaque){    ESPState *s = opaque;    memset(s->rregs, 0, ESP_MAXREG);    memset(s->wregs, 0, ESP_MAXREG);    s->rregs[0x0e] = 0x4; // Indicate fas100a    memset(s->espdmaregs, 0, ESPDMA_REGS * 4);    s->ti_size = 0;    s->ti_rptr = 0;    s->ti_wptr = 0;    s->ti_dir = 0;    s->dma = 0;    s->dma_cb = NULL;}static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr){    ESPState *s = opaque;    uint32_t saddr;    saddr = (addr & ESP_MAXREG) >> 2;    DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]);    switch (saddr) {    case 2:	// FIFO	if (s->ti_size > 0) {	    s->ti_size--;	    s->rregs[saddr] = s->ti_buf[s->ti_rptr++];	    pic_set_irq(s->irq, 1);	}	if (s->ti_size == 0) {            s->ti_rptr = 0;            s->ti_wptr = 0;        }	break;    case 5:        // interrupt        // Clear status bits except TC        s->rregs[4] &= STAT_TC;        pic_set_irq(s->irq, 0);	s->espdmaregs[0] &= ~DMA_INTR;        break;    default:	break;    }    return s->rregs[saddr];}static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    ESPState *s = opaque;    uint32_t saddr;    saddr = (addr & ESP_MAXREG) >> 2;    DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], val);    switch (saddr) {    case 0:    case 1:        s->rregs[saddr] = val;        break;    case 2:	// FIFO	s->ti_size++;	s->ti_buf[s->ti_wptr++] = val & 0xff;	break;    case 3:        s->rregs[saddr] = val;	// Command	if (val & 0x80) {	    s->dma = 1;	} else {	    s->dma = 0;	}	switch(val & 0x7f) {	case 0:	    DPRINTF("NOP (%2.2x)\n", val);	    break;	case 1:	    DPRINTF("Flush FIFO (%2.2x)\n", val);            //s->ti_size = 0;	    s->rregs[5] = INTR_FC;	    s->rregs[6] = 0;	    break;	case 2:	    DPRINTF("Chip reset (%2.2x)\n", val);	    esp_reset(s);	    break;	case 3:	    DPRINTF("Bus reset (%2.2x)\n", val);	    s->rregs[5] = INTR_RST;            if (!(s->wregs[8] & 0x40)) {                s->espdmaregs[0] |= DMA_INTR;                pic_set_irq(s->irq, 1);            }	    break;	case 0x10:	    handle_ti(s);	    break;	case 0x11:	    DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);	    dma_write(s, okbuf, 2);	    break;	case 0x12:	    DPRINTF("Message Accepted (%2.2x)\n", val);	    dma_write(s, okbuf, 2);	    s->rregs[5] = INTR_DC;	    s->rregs[6] = 0;	    break;	case 0x1a:	    DPRINTF("Set ATN (%2.2x)\n", val);	    break;	case 0x42:	    handle_satn(s);	    break;	case 0x43:	    DPRINTF("Set ATN & stop (%2.2x)\n", val);	    handle_satn(s);	    break;	default:	    DPRINTF("Unhandled ESP command (%2.2x)\n", val);	    break;	}	break;    case 4 ... 7:	break;    case 8:        s->rregs[saddr] = val;        break;    case 9 ... 10:        break;    case 11:        s->rregs[saddr] = val & 0x15;        break;    case 12 ... 15:        s->rregs[saddr] = val;        break;    default:	break;    }    s->wregs[saddr] = val;}static CPUReadMemoryFunc *esp_mem_read[3] = {    esp_mem_readb,    esp_mem_readb,    esp_mem_readb,};static CPUWriteMemoryFunc *esp_mem_write[3] = {    esp_mem_writeb,    esp_mem_writeb,    esp_mem_writeb,};static uint32_t espdma_mem_readl(void *opaque, target_phys_addr_t addr){    ESPState *s = opaque;    uint32_t saddr;    saddr = (addr & ESPDMA_MAXADDR) >> 2;    DPRINTF("read dmareg[%d]: 0x%8.8x\n", saddr, s->espdmaregs[saddr]);    return s->espdmaregs[saddr];}static void espdma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    ESPState *s = opaque;    uint32_t saddr;    saddr = (addr & ESPDMA_MAXADDR) >> 2;    DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->espdmaregs[saddr], val);    switch (saddr) {    case 0:	if (!(val & DMA_INTREN))	    pic_set_irq(s->irq, 0);	if (val & 0x80) {            esp_reset(s);        } else if (val & 0x40) {            val &= ~0x40;        } else if (val == 0)            val = 0x40;        val &= 0x0fffffff;        val |= DMA_VER;	break;    case 1:        s->espdmaregs[0] = DMA_LOADED;        break;    default:	break;    }    s->espdmaregs[saddr] = val;}static CPUReadMemoryFunc *espdma_mem_read[3] = {    espdma_mem_readl,    espdma_mem_readl,    espdma_mem_readl,};static CPUWriteMemoryFunc *espdma_mem_write[3] = {    espdma_mem_writel,    espdma_mem_writel,    espdma_mem_writel,};static void esp_save(QEMUFile *f, void *opaque){    ESPState *s = opaque;    unsigned int i;    qemu_put_buffer(f, s->rregs, ESP_MAXREG);    qemu_put_buffer(f, s->wregs, ESP_MAXREG);    qemu_put_be32s(f, &s->irq);    for (i = 0; i < ESPDMA_REGS; i++)	qemu_put_be32s(f, &s->espdmaregs[i]);    qemu_put_be32s(f, &s->ti_size);    qemu_put_be32s(f, &s->ti_rptr);    qemu_put_be32s(f, &s->ti_wptr);    qemu_put_be32s(f, &s->ti_dir);    qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);    qemu_put_be32s(f, &s->dma);}static int esp_load(QEMUFile *f, void *opaque, int version_id){    ESPState *s = opaque;    unsigned int i;        if (version_id != 1)        return -EINVAL;    qemu_get_buffer(f, s->rregs, ESP_MAXREG);    qemu_get_buffer(f, s->wregs, ESP_MAXREG);    qemu_get_be32s(f, &s->irq);    for (i = 0; i < ESPDMA_REGS; i++)	qemu_get_be32s(f, &s->espdmaregs[i]);    qemu_get_be32s(f, &s->ti_size);    qemu_get_be32s(f, &s->ti_rptr);    qemu_get_be32s(f, &s->ti_wptr);    qemu_get_be32s(f, &s->ti_dir);    qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);    qemu_get_be32s(f, &s->dma);    return 0;}void esp_init(BlockDriverState **bd, int irq, uint32_t espaddr, uint32_t espdaddr){    ESPState *s;    int esp_io_memory, espdma_io_memory;    s = qemu_mallocz(sizeof(ESPState));    if (!s)        return;    s->bd = bd;    s->irq = irq;    esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);    cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory);    espdma_io_memory = cpu_register_io_memory(0, espdma_mem_read, espdma_mem_write, s);    cpu_register_physical_memory(espdaddr, 16, espdma_io_memory);    esp_reset(s);    register_savevm("esp", espaddr, 1, esp_save, esp_load, s);    qemu_register_reset(esp_reset, s);}

⌨️ 快捷键说明

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