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

📄 pcnet.c

📁 xen 3.2.2 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    for (i = 0,checksum = 0; i < 16; i++)        checksum += s->prom[i];    *(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);    s->bcr[BCR_MSRDA] = 0x0005;    s->bcr[BCR_MSWRA] = 0x0005;    s->bcr[BCR_MC   ] = 0x0002;    s->bcr[BCR_LNKST] = 0x00c0;    s->bcr[BCR_LED1 ] = 0x0084;    s->bcr[BCR_LED2 ] = 0x0088;    s->bcr[BCR_LED3 ] = 0x0090;    s->bcr[BCR_FDC  ] = 0x0000;    s->bcr[BCR_BSBC ] = 0x9001;    s->bcr[BCR_EECAS] = 0x0002;    s->bcr[BCR_SWS  ] = 0x0200;    s->bcr[BCR_PLAT ] = 0xff06;    pcnet_s_reset(s);}static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val){    PCNetState *s = opaque;#ifdef PCNET_DEBUG    printf("pcnet_aprom_writeb addr=0x%08x val=0x%02x\n", addr, val);#endif        /* Check APROMWE bit to enable write access */    if (pcnet_bcr_readw(s,2) & 0x80)        s->prom[addr & 15] = val;}       static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr){    PCNetState *s = opaque;    uint32_t val = s->prom[addr &= 15];#ifdef PCNET_DEBUG    printf("pcnet_aprom_readb addr=0x%08x val=0x%02x\n", addr, val);#endif    return val;}static void pcnet_ioport_writew(void *opaque, uint32_t addr, uint32_t val){    PCNetState *s = opaque;    pcnet_poll_timer(s);#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_writew addr=0x%08x val=0x%04x\n", addr, val);#endif    if (!BCR_DWIO(s)) {        switch (addr & 0x0f) {        case 0x00: /* RDP */            pcnet_csr_writew(s, s->rap, val);            break;        case 0x02:            s->rap = val & 0x7f;            break;        case 0x06:            pcnet_bcr_writew(s, s->rap, val);            break;        }    }    pcnet_update_irq(s);}static uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr){    PCNetState *s = opaque;    uint32_t val = -1;    pcnet_poll_timer(s);    if (!BCR_DWIO(s)) {        switch (addr & 0x0f) {        case 0x00: /* RDP */            val = pcnet_csr_readw(s, s->rap);            break;        case 0x02:            val = s->rap;            break;        case 0x04:            pcnet_s_reset(s);            val = 0;            break;        case 0x06:            val = pcnet_bcr_readw(s, s->rap);            break;        }    }    pcnet_update_irq(s);#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_readw addr=0x%08x val=0x%04x\n", addr, val & 0xffff);#endif    return val;}static void pcnet_ioport_writel(void *opaque, uint32_t addr, uint32_t val){    PCNetState *s = opaque;    pcnet_poll_timer(s);#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_writel addr=0x%08x val=0x%08x\n", addr, val);#endif    if (BCR_DWIO(s)) {        switch (addr & 0x0f) {        case 0x00: /* RDP */            pcnet_csr_writew(s, s->rap, val & 0xffff);            break;        case 0x04:            s->rap = val & 0x7f;            break;        case 0x0c:            pcnet_bcr_writew(s, s->rap, val & 0xffff);            break;        }    } else    if ((addr & 0x0f) == 0) {        /* switch device to dword i/o mode */        pcnet_bcr_writew(s, BCR_BSBC, pcnet_bcr_readw(s, BCR_BSBC) | 0x0080);#ifdef PCNET_DEBUG_IO        printf("device switched into dword i/o mode\n");#endif            }    pcnet_update_irq(s);}static uint32_t pcnet_ioport_readl(void *opaque, uint32_t addr){    PCNetState *s = opaque;    uint32_t val = -1;    pcnet_poll_timer(s);    if (BCR_DWIO(s)) {          switch (addr & 0x0f) {        case 0x00: /* RDP */            val = pcnet_csr_readw(s, s->rap);            break;        case 0x04:            val = s->rap;            break;        case 0x08:            pcnet_s_reset(s);            val = 0;            break;        case 0x0c:            val = pcnet_bcr_readw(s, s->rap);            break;        }    }    pcnet_update_irq(s);#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_readl addr=0x%08x val=0x%08x\n", addr, val);#endif    return val;}static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,                              uint32_t addr, uint32_t size, int type){    PCNetState *d = (PCNetState *)pci_dev;#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_map addr=0x%04x size=0x%04x\n", addr, size);#endif    register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);    register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);        register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);    register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);    register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);    register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);}static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    PCNetState *d = opaque;#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_writeb addr=0x%08x val=0x%02x\n", addr, val);#endif    if (!(addr & 0x10))        pcnet_aprom_writeb(d, addr & 0x0f, val);}static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr) {    PCNetState *d = opaque;    uint32_t val = -1;    if (!(addr & 0x10))        val = pcnet_aprom_readb(d, addr & 0x0f);#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_readb addr=0x%08x val=0x%02x\n", addr, val & 0xff);#endif    return val;}static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val){    PCNetState *d = opaque;#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_writew addr=0x%08x val=0x%04x\n", addr, val);#endif    if (addr & 0x10)        pcnet_ioport_writew(d, addr & 0x0f, val);    else {        addr &= 0x0f;        pcnet_aprom_writeb(d, addr, val & 0xff);        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);    }}static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr) {    PCNetState *d = opaque;    uint32_t val = -1;    if (addr & 0x10)        val = pcnet_ioport_readw(d, addr & 0x0f);    else {        addr &= 0x0f;        val = pcnet_aprom_readb(d, addr+1);        val <<= 8;        val |= pcnet_aprom_readb(d, addr);    }#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_readw addr=0x%08x val = 0x%04x\n", addr, val & 0xffff);#endif    return val;}static void pcnet_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    PCNetState *d = opaque;#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_writel addr=0x%08x val=0x%08x\n", addr, val);#endif    if (addr & 0x10)        pcnet_ioport_writel(d, addr & 0x0f, val);    else {        addr &= 0x0f;        pcnet_aprom_writeb(d, addr, val & 0xff);        pcnet_aprom_writeb(d, addr+1, (val & 0xff00) >> 8);        pcnet_aprom_writeb(d, addr+2, (val & 0xff0000) >> 16);        pcnet_aprom_writeb(d, addr+3, (val & 0xff000000) >> 24);    }}static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) {    PCNetState *d = opaque;    uint32_t val;    if (addr & 0x10)        val = pcnet_ioport_readl(d, addr & 0x0f);    else {        addr &= 0x0f;        val = pcnet_aprom_readb(d, addr+3);        val <<= 8;        val |= pcnet_aprom_readb(d, addr+2);        val <<= 8;        val |= pcnet_aprom_readb(d, addr+1);        val <<= 8;        val |= pcnet_aprom_readb(d, addr);    }#ifdef PCNET_DEBUG_IO    printf("pcnet_mmio_readl addr=0x%08x val=0x%08x\n", addr, val);#endif    return val;}static void pcnet_save(QEMUFile *f, void *opaque){    PCNetState *s = opaque;    unsigned int i;    if (s->pci_dev)        pci_device_save(s->pci_dev, f);    qemu_put_be32s(f, &s->rap);    qemu_put_be32s(f, &s->isr);    qemu_put_be32s(f, &s->lnkst);    qemu_put_be32s(f, &s->rdra);    qemu_put_be32s(f, &s->tdra);    qemu_put_buffer(f, s->prom, 16);    for (i = 0; i < 128; i++)        qemu_put_be16s(f, &s->csr[i]);    for (i = 0; i < 32; i++)        qemu_put_be16s(f, &s->bcr[i]);    qemu_put_be64s(f, &s->timer);    qemu_put_be32s(f, &s->xmit_pos);    qemu_put_be32s(f, &s->recv_pos);    qemu_put_buffer(f, s->buffer, 4096);    qemu_put_be32s(f, &s->tx_busy);    qemu_put_timer(f, s->poll_timer);}static int pcnet_load(QEMUFile *f, void *opaque, int version_id){    PCNetState *s = opaque;    int i, ret;    if (version_id != 2)        return -EINVAL;    if (s->pci_dev) {        ret = pci_device_load(s->pci_dev, f);        if (ret < 0)            return ret;    }    qemu_get_be32s(f, &s->rap);    qemu_get_be32s(f, &s->isr);    qemu_get_be32s(f, &s->lnkst);    qemu_get_be32s(f, &s->rdra);    qemu_get_be32s(f, &s->tdra);    qemu_get_buffer(f, s->prom, 16);    for (i = 0; i < 128; i++)        qemu_get_be16s(f, &s->csr[i]);    for (i = 0; i < 32; i++)        qemu_get_be16s(f, &s->bcr[i]);    qemu_get_be64s(f, &s->timer);    qemu_get_be32s(f, &s->xmit_pos);    qemu_get_be32s(f, &s->recv_pos);    qemu_get_buffer(f, s->buffer, 4096);    qemu_get_be32s(f, &s->tx_busy);    qemu_get_timer(f, s->poll_timer);    return 0;}static void pcnet_common_init(PCNetState *d, NICInfo *nd, const char *info_str){    int instance;    d->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, d);    d->nd = nd;    d->vc = qemu_new_vlan_client(nd->vlan, pcnet_receive,                                  pcnet_can_receive, d);    snprintf(d->vc->info_str, sizeof(d->vc->info_str),             "pcnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",             d->nd->macaddr[0],             d->nd->macaddr[1],             d->nd->macaddr[2],             d->nd->macaddr[3],             d->nd->macaddr[4],             d->nd->macaddr[5]);    pcnet_h_reset(d);    instance = pci_bus_num(d->dev.bus) << 8 | d->dev.devfn;    register_savevm("pcnet", instance, 2, pcnet_save, pcnet_load, d);}/* PCI interface */static CPUWriteMemoryFunc *pcnet_mmio_write[] = {    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,    (CPUWriteMemoryFunc *)&pcnet_mmio_writel};static CPUReadMemoryFunc *pcnet_mmio_read[] = {    (CPUReadMemoryFunc *)&pcnet_mmio_readb,    (CPUReadMemoryFunc *)&pcnet_mmio_readw,    (CPUReadMemoryFunc *)&pcnet_mmio_readl};static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,                             uint32_t addr, uint32_t size, int type){    PCNetState *d = (PCNetState *)pci_dev;#ifdef PCNET_DEBUG_IO    printf("pcnet_ioport_map addr=0x%08x 0x%08x\n", addr, size);#endif    cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);}static void pcnet_pci_set_irq_cb(void *opaque, int isr){    PCNetState *s = opaque;    pci_set_irq(&s->dev, 0, isr);}static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,                                      uint8_t *buf, int len, int do_bswap){    cpu_physical_memory_write(addr, buf, len);}static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,                                     uint8_t *buf, int len, int do_bswap){    cpu_physical_memory_read(addr, buf, len);}void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn){    PCNetState *d;    uint8_t *pci_conf;#if 0    printf("sizeof(RMD)=%d, sizeof(TMD)=%d\n",         sizeof(struct pcnet_RMD), sizeof(struct pcnet_TMD));#endif    d = (PCNetState *)pci_register_device(bus, "PCNet", sizeof(PCNetState),                                          devfn, NULL, NULL);                                              pci_conf = d->dev.config;        *(uint16_t *)&pci_conf[0x00] = cpu_to_le16(0x1022);    *(uint16_t *)&pci_conf[0x02] = cpu_to_le16(0x2000);        *(uint16_t *)&pci_conf[0x04] = cpu_to_le16(0x0007);     *(uint16_t *)&pci_conf[0x06] = cpu_to_le16(0x0280);    pci_conf[0x08] = 0x10;    pci_conf[0x09] = 0x00;    pci_conf[0x0a] = 0x00; // ethernet network controller     pci_conf[0x0b] = 0x02;    pci_conf[0x0e] = 0x00; // header_type        *(uint32_t *)&pci_conf[0x10] = cpu_to_le32(0x00000001);    *(uint32_t *)&pci_conf[0x14] = cpu_to_le32(0x00000000);        pci_conf[0x3d] = 1; // interrupt pin 0    pci_conf[0x3e] = 0x06;    pci_conf[0x3f] = 0xff;    /* Handler for memory-mapped I/O */    d->mmio_index =      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);    pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,                            PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);                               pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,                            PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);                               d->set_irq_cb = pcnet_pci_set_irq_cb;    d->phys_mem_read = pci_physical_memory_read;    d->phys_mem_write = pci_physical_memory_write;    d->pci_dev = &d->dev;    pcnet_common_init(d, nd, "pcnet");}/* SPARC32 interface */#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64) // Avoid compile failurestatic CPUReadMemoryFunc *lance_mem_read[3] = {    (CPUReadMemoryFunc *)&pcnet_ioport_readw,    (CPUReadMemoryFunc *)&pcnet_ioport_readw,    (CPUReadMemoryFunc *)&pcnet_ioport_readw,};static CPUWriteMemoryFunc *lance_mem_write[3] = {    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,    (CPUWriteMemoryFunc *)&pcnet_ioport_writew,};static void pcnet_sparc_set_irq_cb(void *opaque, int isr){    PCNetState *s = opaque;    ledma_set_irq(s->dma_opaque, isr);}void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque){    PCNetState *d;    int lance_io_memory;    d = qemu_mallocz(sizeof(PCNetState));    if (!d)        return NULL;    lance_io_memory =        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);    d->dma_opaque = dma_opaque;    cpu_register_physical_memory(leaddr, 4, lance_io_memory);    d->set_irq_cb = pcnet_sparc_set_irq_cb;    d->phys_mem_read = ledma_memory_read;    d->phys_mem_write = ledma_memory_write;    pcnet_common_init(d, nd, "lance");    return d;}#endif /* TARGET_SPARC */

⌨️ 快捷键说明

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