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

📄 eepro100.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/***********************************************************//* PCI EEPRO100 definitions */typedef struct PCIEEPRO100State {    PCIDevice dev;    EEPRO100State eepro100;} PCIEEPRO100State;static void pci_map(PCIDevice * pci_dev, int region_num,                    uint32_t addr, uint32_t size, int type){    PCIEEPRO100State *d = (PCIEEPRO100State *) pci_dev;    EEPRO100State *s = &d->eepro100;    logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",           region_num, addr, size, type);    assert(region_num == 1);    register_ioport_write(addr, size, 1, ioport_write1, s);    register_ioport_read(addr, size, 1, ioport_read1, s);    register_ioport_write(addr, size, 2, ioport_write2, s);    register_ioport_read(addr, size, 2, ioport_read2, s);    register_ioport_write(addr, size, 4, ioport_write4, s);    register_ioport_read(addr, size, 4, ioport_read4, s);    s->region[region_num] = addr;}static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);    eepro100_write1(s, addr, val);}static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);    eepro100_write2(s, addr, val);}static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);    eepro100_write4(s, addr, val);}static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s\n", regname(addr));    return eepro100_read1(s, addr);}static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s\n", regname(addr));    return eepro100_read2(s, addr);}static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr){    EEPRO100State *s = opaque;    addr -= s->region[0];    //~ logout("addr=%s\n", regname(addr));    return eepro100_read4(s, addr);}static CPUWriteMemoryFunc *pci_mmio_write[] = {    pci_mmio_writeb,    pci_mmio_writew,    pci_mmio_writel};static CPUReadMemoryFunc *pci_mmio_read[] = {    pci_mmio_readb,    pci_mmio_readw,    pci_mmio_readl};static void pci_mmio_map(PCIDevice * pci_dev, int region_num,                         uint32_t addr, uint32_t size, int type){    PCIEEPRO100State *d = (PCIEEPRO100State *) pci_dev;    logout("region %d, addr=0x%08x, size=0x%08x, type=%d\n",           region_num, addr, size, type);    if (region_num == 0) {        /* Map control / status registers. */        cpu_register_physical_memory(addr, size, d->eepro100.mmio_index);        d->eepro100.region[region_num] = addr;    }}static int nic_can_receive(void *opaque){    EEPRO100State *s = opaque;    logout("%p\n", s);    return get_ru_state(s) == ru_ready;    //~ return !eepro100_buffer_full(s);}#define MIN_BUF_SIZE 60static void nic_receive(void *opaque, const uint8_t * buf, int size){    /* TODO:     * - Magic packets should set bit 30 in power management driver register.     * - Interesting packets should set bit 29 in power management driver register.     */    EEPRO100State *s = opaque;    uint16_t rfd_status = 0xa000;    static const uint8_t broadcast_macaddr[6] =        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    /* TODO: check multiple IA bit. */    assert(!(s->configuration[20] & BIT(6)));    if (s->configuration[8] & 0x80) {        /* CSMA is disabled. */        logout("%p received while CSMA is disabled\n", s);        return;    } else if (size < 64 && (s->configuration[7] & 1)) {        /* Short frame and configuration byte 7/0 (discard short receive) set:         * Short frame is discarded */        logout("%p received short frame (%d byte)\n", s, size);        s->statistics.rx_short_frame_errors++;        //~ return;    } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {        /* Long frame and configuration byte 18/3 (long receive ok) not set:         * Long frames are discarded. */        logout("%p received long frame (%d byte), ignored\n", s, size);        return;    } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!        /* Frame matches individual address. */        /* TODO: check configuration byte 15/4 (ignore U/L). */        logout("%p received frame for me, len=%d\n", s, size);    } else if (memcmp(buf, broadcast_macaddr, 6) == 0) {        /* Broadcast frame. */        logout("%p received broadcast, len=%d\n", s, size);        rfd_status |= 0x0002;    } else if (buf[0] & 0x01) { // !!!        /* Multicast frame. */        logout("%p received multicast, len=%d\n", s, size);        /* TODO: check multicast all bit. */        assert(!(s->configuration[21] & BIT(3)));        int mcast_idx = compute_mcast_idx(buf);        if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {            return;        }        rfd_status |= 0x0002;    } else if (s->configuration[15] & 1) {        /* Promiscuous: receive all. */        logout("%p received frame in promiscuous mode, len=%d\n", s, size);        rfd_status |= 0x0004;    } else {        logout("%p received frame, ignored, len=%d,%s\n", s, size,               nic_dump(buf, size));        return;    }    if (get_ru_state(s) != ru_ready) {        /* No ressources available. */        logout("no ressources, state=%u\n", get_ru_state(s));        s->statistics.rx_resource_errors++;        //~ assert(!"no ressources");        return;    }    //~ !!!//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}    eepro100_rx_t rx;    cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,                             offsetof(eepro100_rx_t, packet));    uint16_t rfd_command = le16_to_cpu(rx.command);    uint16_t rfd_size = le16_to_cpu(rx.size);    assert(size <= rfd_size);    if (size < 64) {        rfd_status |= 0x0080;    }    logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n", rfd_command,           rx.link, rx.rx_buf_addr, rfd_size);    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),             rfd_status);    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);    /* Early receive interrupt not supported. */    //~ eepro100_er_interrupt(s);    /* Receive CRC Transfer not supported. */    assert(!(s->configuration[18] & 4));    /* TODO: check stripping enable bit. */    //~ assert(!(s->configuration[17] & 1));    cpu_physical_memory_write(s->ru_base + s->ru_offset +                              offsetof(eepro100_rx_t, packet), buf, size);    s->statistics.rx_good_frames++;    eepro100_fr_interrupt(s);    s->ru_offset = le32_to_cpu(rx.link);    if (rfd_command & 0x8000) {        /* EL bit is set, so this was the last frame. */        assert(0);    }    if (rfd_command & 0x4000) {        /* S bit is set. */        set_ru_state(s, ru_suspended);    }}static int nic_load(QEMUFile * f, void *opaque, int version_id){    EEPRO100State *s = (EEPRO100State *) opaque;    int i;    int ret;    if (version_id > 3)        return -EINVAL;    if (s->pci_dev && version_id >= 3) {        ret = pci_device_load(s->pci_dev, f);        if (ret < 0)            return ret;    }    if (version_id >= 2) {        qemu_get_8s(f, &s->rxcr);    } else {        s->rxcr = 0x0c;    }    qemu_get_8s(f, &s->cmd);    qemu_get_be32s(f, &s->start);    qemu_get_be32s(f, &s->stop);    qemu_get_8s(f, &s->boundary);    qemu_get_8s(f, &s->tsr);    qemu_get_8s(f, &s->tpsr);    qemu_get_be16s(f, &s->tcnt);    qemu_get_be16s(f, &s->rcnt);    qemu_get_be32s(f, &s->rsar);    qemu_get_8s(f, &s->rsr);    qemu_get_8s(f, &s->isr);    qemu_get_8s(f, &s->dcfg);    qemu_get_8s(f, &s->imr);    qemu_get_buffer(f, s->phys, 6);    qemu_get_8s(f, &s->curpag);    qemu_get_buffer(f, s->mult, 8);    qemu_get_buffer(f, s->mem, sizeof(s->mem));    /* Restore all members of struct between scv_stat and mem */    qemu_get_8s(f, &s->scb_stat);    qemu_get_8s(f, &s->int_stat);    for (i = 0; i < 3; i++)        qemu_get_be32s(f, &s->region[i]);    qemu_get_buffer(f, s->macaddr, 6);    for (i = 0; i < 19; i++)        qemu_get_be32s(f, &s->statcounter[i]);    for (i = 0; i < 32; i++)        qemu_get_be16s(f, &s->mdimem[i]);    /* The eeprom should be saved and restored by its own routines */    qemu_get_be32s(f, &s->device);    qemu_get_be32s(f, &s->pointer);    qemu_get_be32s(f, &s->cu_base);    qemu_get_be32s(f, &s->cu_offset);    qemu_get_be32s(f, &s->ru_base);    qemu_get_be32s(f, &s->ru_offset);    qemu_get_be32s(f, &s->statsaddr);    /* Restore epro100_stats_t statistics */    qemu_get_be32s(f, &s->statistics.tx_good_frames);    qemu_get_be32s(f, &s->statistics.tx_max_collisions);    qemu_get_be32s(f, &s->statistics.tx_late_collisions);    qemu_get_be32s(f, &s->statistics.tx_underruns);    qemu_get_be32s(f, &s->statistics.tx_lost_crs);    qemu_get_be32s(f, &s->statistics.tx_deferred);    qemu_get_be32s(f, &s->statistics.tx_single_collisions);    qemu_get_be32s(f, &s->statistics.tx_multiple_collisions);    qemu_get_be32s(f, &s->statistics.tx_total_collisions);    qemu_get_be32s(f, &s->statistics.rx_good_frames);    qemu_get_be32s(f, &s->statistics.rx_crc_errors);    qemu_get_be32s(f, &s->statistics.rx_alignment_errors);    qemu_get_be32s(f, &s->statistics.rx_resource_errors);    qemu_get_be32s(f, &s->statistics.rx_overrun_errors);    qemu_get_be32s(f, &s->statistics.rx_cdt_errors);    qemu_get_be32s(f, &s->statistics.rx_short_frame_errors);    qemu_get_be32s(f, &s->statistics.fc_xmt_pause);    qemu_get_be32s(f, &s->statistics.fc_rcv_pause);    qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported);    qemu_get_be16s(f, &s->statistics.xmt_tco_frames);    qemu_get_be16s(f, &s->statistics.rcv_tco_frames);    qemu_get_be32s(f, &s->statistics.complete);#if 0    qemu_get_be16s(f, &s->status);#endif    /* Configuration bytes. */    qemu_get_buffer(f, s->configuration, sizeof(s->configuration));    return 0;}static void nic_save(QEMUFile * f, void *opaque){    EEPRO100State *s = (EEPRO100State *) opaque;    int i;    if (s->pci_dev)        pci_device_save(s->pci_dev, f);    qemu_put_8s(f, &s->rxcr);    qemu_put_8s(f, &s->cmd);    qemu_put_be32s(f, &s->start);    qemu_put_be32s(f, &s->stop);    qemu_put_8s(f, &s->boundary);    qemu_put_8s(f, &s->tsr);    qemu_put_8s(f, &s->tpsr);    qemu_put_be16s(f, &s->tcnt);    qemu_put_be16s(f, &s->rcnt);    qemu_put_be32s(f, &s->rsar);    qemu_put_8s(f, &s->rsr);    qemu_put_8s(f, &s->isr);    qemu_put_8s(f, &s->dcfg);    qemu_put_8s(f, &s->imr);    qemu_put_buffer(f, s->phys, 6);    qemu_put_8s(f, &s->curpag);    qemu_put_buffer(f, s->mult, 8);    qemu_put_buffer(f, s->mem, sizeof(s->mem));    /* Save all members of struct between scv_stat and mem */    qemu_put_8s(f, &s->scb_stat);    qemu_put_8s(f, &s->int_stat);    for (i = 0; i < 3; i++)        qemu_put_be32s(f, &s->region[i]);    qemu_put_buffer(f, s->macaddr, 6);    for (i = 0; i < 19; i++)        qemu_put_be32s(f, &s->statcounter[i]);    for (i = 0; i < 32; i++)        qemu_put_be16s(f, &s->mdimem[i]);    /* The eeprom should be saved and restored by its own routines */    qemu_put_be32s(f, &s->device);    qemu_put_be32s(f, &s->pointer);    qemu_put_be32s(f, &s->cu_base);    qemu_put_be32s(f, &s->cu_offset);    qemu_put_be32s(f, &s->ru_base);    qemu_put_be32s(f, &s->ru_offset);    qemu_put_be32s(f, &s->statsaddr);    /* Save epro100_stats_t statistics */    qemu_put_be32s(f, &s->statistics.tx_good_frames);    qemu_put_be32s(f, &s->statistics.tx_max_collisions);    qemu_put_be32s(f, &s->statistics.tx_late_collisions);    qemu_put_be32s(f, &s->statistics.tx_underruns);    qemu_put_be32s(f, &s->statistics.tx_lost_crs);    qemu_put_be32s(f, &s->statistics.tx_deferred);    qemu_put_be32s(f, &s->statistics.tx_single_collisions);    qemu_put_be32s(f, &s->statistics.tx_multiple_collisions);    qemu_put_be32s(f, &s->statistics.tx_total_collisions);    qemu_put_be32s(f, &s->statistics.rx_good_frames);    qemu_put_be32s(f, &s->statistics.rx_crc_errors);    qemu_put_be32s(f, &s->statistics.rx_alignment_errors);    qemu_put_be32s(f, &s->statistics.rx_resource_errors);    qemu_put_be32s(f, &s->statistics.rx_overrun_errors);    qemu_put_be32s(f, &s->statistics.rx_cdt_errors);    qemu_put_be32s(f, &s->statistics.rx_short_frame_errors);    qemu_put_be32s(f, &s->statistics.fc_xmt_pause);    qemu_put_be32s(f, &s->statistics.fc_rcv_pause);    qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported);    qemu_put_be16s(f, &s->statistics.xmt_tco_frames);    qemu_put_be16s(f, &s->statistics.rcv_tco_frames);    qemu_put_be32s(f, &s->statistics.complete);#if 0    qemu_put_be16s(f, &s->status);#endif    /* Configuration bytes. */    qemu_put_buffer(f, s->configuration, sizeof(s->configuration));}static void nic_init(PCIBus * bus, NICInfo * nd,                     const char *name, uint32_t device){    PCIEEPRO100State *d;    EEPRO100State *s;    logout("\n");    d = (PCIEEPRO100State *) pci_register_device(bus, name,                                                 sizeof(PCIEEPRO100State), -1,                                                 NULL, NULL);    s = &d->eepro100;    s->device = device;    s->pci_dev = &d->dev;    pci_reset(s);    /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,     * i82559 and later support 64 or 256 word EEPROM. */    s->eeprom = eeprom93xx_new(EEPROM_SIZE);    /* Handler for memory-mapped I/O */    d->eepro100.mmio_index =        cpu_register_io_memory(0, pci_mmio_read, pci_mmio_write, s);    pci_register_io_region(&d->dev, 0, PCI_MEM_SIZE,                           PCI_ADDRESS_SPACE_MEM |                           PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_mmio_map);    pci_register_io_region(&d->dev, 1, PCI_IO_SIZE, PCI_ADDRESS_SPACE_IO,                           pci_map);    pci_register_io_region(&d->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,                           pci_mmio_map);    memcpy(s->macaddr, nd->macaddr, 6);    logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));    assert(s->region[1] == 0);    nic_reset(s);    s->vc = qemu_new_vlan_client(nd->vlan, nic_receive, nic_can_receive, s);    snprintf(s->vc->info_str, sizeof(s->vc->info_str),             "eepro100 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",             s->macaddr[0],             s->macaddr[1],             s->macaddr[2], s->macaddr[3], s->macaddr[4], s->macaddr[5]);    qemu_register_reset(nic_reset, s);    /* XXX: instance number ? */    register_savevm(name, 0, 3, nic_save, nic_load, s);}void pci_i82551_init(PCIBus * bus, NICInfo * nd, int devfn){    nic_init(bus, nd, "i82551", i82551);    //~ uint8_t *pci_conf = d->dev.config;}void pci_i82557b_init(PCIBus * bus, NICInfo * nd, int devfn){    nic_init(bus, nd, "i82557b", i82557B);}void pci_i82559er_init(PCIBus * bus, NICInfo * nd, int devfn){    nic_init(bus, nd, "i82559er", i82559ER);}/* eof */

⌨️ 快捷键说明

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