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

📄 e100.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
    CSR(CSR_CMD, simb) = 0x3f;    // Set PHY to 1    CSR_VAL(CSR_MDI) |= BIT(21);    /* Initialize EEDO bit to 1. Due to driver would detect dummy 0 at     * EEDO bit, so initialize it to 1 is safety a way.     */    CSR(CSR_EEPROM, eedo) = 1;    // no pending interrupts    s->scb_stat = 0;    return;}static void e100_software_reset(E100State *s){    memset(s->pci_mem.mem, 0x0, sizeof(s->pci_mem.mem));    // Clear multicast list    memset(s->mult_list, 0x0, sizeof(s->mult_list));    // Set MDI register to default value    memcpy(&s->mdimem[0], &e100_mdi_default[0], sizeof(s->mdimem));    s->is_multcast_enable = 1;    /* Clean FIFO buffer */    memset(s->pkt_buf, 0x0, sizeof(s->pkt_buf));    s->pkt_buf_len = 0;    memset(&s->statistics, 0x0, sizeof(s->statistics));    e100_selective_reset(s);    return;}static void e100_reset(void *opaque){    E100State *s = (E100State *) opaque;    logout("%p\n", s);    e100_software_reset(s);}static void e100_save(QEMUFile * f, void *opaque){    E100State *s = (E100State *)opaque;    int i;    pci_device_save(s->pci_dev, f);    qemu_put_be32s(f, &s->mmio_index);    qemu_put_8s(f, &s->scb_stat);    for(i = 0; i < REGION_NUM; i++) {        qemu_put_be32s(f, &s->region_base_addr[i]);    }    qemu_put_buffer(f, s->macaddr, 6);    for(i = 0; i < 32; i++) {        qemu_put_be16s(f, &s->mdimem[i]);    }    /* Save eeprom. */    qemu_put_8s(f, &s->eeprom.start_bit);    qemu_put_8s(f, &s->eeprom.opcode);    qemu_put_8s(f, &s->eeprom.address);    qemu_put_be16s(f, &s->eeprom.data);    qemu_put_be32s(f, &s->eeprom.val);    qemu_put_be32s(f, &s->eeprom.val);    qemu_put_be32s(f, &s->eeprom.val_len);    qemu_put_be32s(f, &s->eeprom.val_type);    qemu_put_8s(f, &s->eeprom.cs);    qemu_put_8s(f, &s->eeprom.sk);    qemu_put_be16s(f, &s->eeprom.addr_len);    for(i = 0; i < 256; i++) {        qemu_put_be16s(f, &s->eeprom.contents[i]);    }    qemu_put_be32s(f, &s->device);    qemu_put_buffer(f, s->mult_list, 8);    qemu_put_be32s(f, &s->is_multcast_enable);    qemu_put_be32s(f, &s->cu_base);    qemu_put_be32s(f, &s->cu_offset);    qemu_put_be32s(f, &s->cu_next);    qemu_put_be32s(f, &s->ru_base);    qemu_put_be32s(f, &s->ru_offset);    qemu_put_be32s(f, &s->statsaddr);    /* Save 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_short_frame_errors);    qemu_put_be32s(f, &s->statistics.complete_word);    qemu_put_buffer(f, (uint8_t*)(&s->config), sizeof(s->config));    qemu_put_buffer(f, s->pkt_buf, MAX_ETH_FRAME_SIZE+4);    qemu_put_be32s(f, &s->pkt_buf_len);    qemu_put_buffer(f, (uint8_t*)(&s->pci_mem), sizeof(s->pci_mem));}static int e100_load(QEMUFile * f, void *opaque, int version_id){    E100State *s = (E100State *)opaque;    int i, ret;    if (version_id > 3)        return -EINVAL;    ret = pci_device_load(s->pci_dev, f);    if (ret < 0)        return ret;    qemu_get_be32s(f, &s->mmio_index);    qemu_get_8s(f, &s->scb_stat);    for(i = 0; i < REGION_NUM; i++) {        qemu_get_be32s(f, &s->region_base_addr[i]);    }    qemu_get_buffer(f, s->macaddr, 6);    for(i = 0; i < 32; i++) {        qemu_get_be16s(f, &s->mdimem[i]);    }    /* Load eeprom. */    qemu_get_8s(f, &s->eeprom.start_bit);    qemu_get_8s(f, &s->eeprom.opcode);    qemu_get_8s(f, &s->eeprom.address);    qemu_get_be16s(f, &s->eeprom.data);    qemu_get_be32s(f, &s->eeprom.val);    qemu_get_be32s(f, &s->eeprom.val);    qemu_get_be32s(f, &s->eeprom.val_len);    qemu_get_be32s(f, &s->eeprom.val_type);    qemu_get_8s(f, &s->eeprom.cs);    qemu_get_8s(f, &s->eeprom.sk);    qemu_get_be16s(f, &s->eeprom.addr_len);    for(i = 0; i < 256; i++) {        qemu_get_be16s(f, &s->eeprom.contents[i]);    }    qemu_get_be32s(f, &s->device);    qemu_get_buffer(f, s->mult_list, 8);    qemu_get_be32s(f, &s->is_multcast_enable);    qemu_get_be32s(f, &s->cu_base);    qemu_get_be32s(f, &s->cu_offset);    qemu_get_be32s(f, &s->cu_next);    qemu_get_be32s(f, &s->ru_base);    qemu_get_be32s(f, &s->ru_offset);    qemu_get_be32s(f, &s->statsaddr);    /* Load 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_short_frame_errors);    qemu_get_be32s(f, &s->statistics.complete_word);    qemu_put_buffer(f, (uint8_t*)(&s->config), sizeof(s->config));    qemu_get_buffer(f, s->pkt_buf, MAX_ETH_FRAME_SIZE+4);    qemu_get_be32s(f, &s->pkt_buf_len);    qemu_get_buffer(f, (uint8_t*)(&s->pci_mem), sizeof(s->pci_mem));    return 0;}/* Interrupt functions */static void e100_interrupt(E100State *s, uint16_t int_type){    //TODO: Add another i8255x card supported mask bit    if ( !CSR(CSR_CMD,m) )    {        //Set bit in stat/ack, so driver can no what interrupt happen        CSR_VAL(CSR_STATUS) |= int_type;        s->scb_stat = CSR(CSR_STATUS, stat_ack);        /* SCB maske and SCB Bit M do not disable interrupt. */        logout("Trigger an interrupt(type = %s(%#x), SCB Status = %#x)\n",                INT_NAME(int_type), int_type, CSR_VAL(CSR_STATUS));        pci_set_irq(s->pci_dev, 0, 1);    }}static void e100_interrupt_ack(E100State * s, uint8_t ack){    /* Ignore acknowledege if driver write 0 to ack or     * according interrupt bit is not set     */    if ( !ack || !(s->scb_stat & ack) )    {        logout("Illegal interrupt ack(ack=%#x, SCB Stat/Ack=%#x), ignore it\n",                ack, s->scb_stat);        // Due to we do write operation before e100_execute(), so        // we must restore value of ack field here        CSR(CSR_STATUS, stat_ack) = s->scb_stat;        return;    }    s->scb_stat &= ~ack;    CSR(CSR_STATUS, stat_ack) = s->scb_stat;    logout("Interrupt ack(name=%s,val=%#x)\n", INT_NAME(({uint16_t bit = ack<<8;bit;})),ack);    if ( !s->scb_stat )    {        logout("All interrupts are acknowledeged, de-assert interrupt line\n");        pci_set_irq(s->pci_dev, 0, 0);    }}static void e100_self_test(uint32_t res_addr){    struct    {        uint32_t st_sign;           /* Self Test Signature */        uint32_t st_result;         /* Self Test Results */    } test_res;    test_res.st_sign = (uint32_t)-1;    test_res.st_result = 0; // Our self test always success    cpu_physical_memory_write(res_addr, (uint8_t *)&test_res, sizeof(test_res));    logout("Write self test result to %#x\n", res_addr);}static void scb_port_func(E100State *s, uint32_t val, int dir){#define PORT_SELECTION_MASK 0xfU    uint32_t sel = val & PORT_SELECTION_MASK;    switch ( sel )    {        case PORT_SOFTWARE_RESET:            logout("do PORT_SOFTWARE_RESET!\n");            e100_software_reset(s);            break;        case PORT_SELF_TEST:            e100_self_test(val & ~PORT_SELECTION_MASK);            logout("do PORT_SELF_TEST!\n");            break;        case PORT_SELECTIVE_RESET:            logout("do PORT_SELECTIVE_RESET!\n");            e100_selective_reset(s);            break;        case PORT_DUMP:            logout("do PORT_SOFTWARE_RESET!\n");            break;        case PORT_DUMP_WAKE_UP:            logout("do PORT_SOFTWARE_RESET!\n");            break;        default:            logout("Unkonw SCB port command(selection function = %#x)\n", sel);    }}static void e100_write_mdi(E100State *s, uint32_t val){    uint32_t ie = (val & 0x20000000) >> 29;    uint32_t opcode = (val & 0x0c000000) >> 26;    uint32_t phyaddr = (val & 0x03e00000) >> 21;    uint32_t regaddr = (val & 0x001f0000) >> 16;    uint32_t data = val & 0x0000ffff;    logout("Write MDI:\n"           "\topcode:%#x\n"           "\tphy address:%#x\n"           "\treg address:%#x\n"           "\tie:%#x\n"           "\tdata:%#x\n",           opcode, phyaddr, regaddr, ie, data);    /* We use default value --- PHY1     * If driver operate on other PHYs, do nothing and     * deceive it that the operation is finished     */    if ( phyaddr != 1 )    {        logout("Unsupport PHY address(phy = %#x)\n", phyaddr);        goto done;    }    // 1: MDI write    // 2: MDI read    if ( opcode != MDI_WRITE && opcode != MDI_READ )    {        logout("Invalid Opcode(opcode = %#x)\n", opcode);        return;    }    // Current only support MDI generic registers.    if ( regaddr > 6 )    {        logout("Invalid phy register index( phy register addr = %#x)\n", regaddr);    }    if ( opcode == MDI_WRITE )    {        // MDI write        switch ( regaddr )        {            case 0:    // Control Register                if ( data & 0x8000 ) // Reset                {                    /* Reset status and control registers to default. */                    s->mdimem[0] = e100_mdi_default[0];                    s->mdimem[1] = e100_mdi_default[1];                    data = s->mdimem[regaddr];                }                else                {                    /* Restart Auto Configuration = Normal Operation */                    data &= ~0x0200;                }                break;            case 1:    // Status Register                logout("Invalid write on readonly register(opcode = %#x)\n", opcode);                data = s->mdimem[regaddr];                break;            case 2:            case 3:            case 4:            case 5:            case 6:                break;        }        s->mdimem[regaddr] = data;        logout("MDI WRITE: reg = %#x, data = %#x\n", regaddr, data);    }    else if ( opcode == MDI_READ )    {        // MDI read        switch ( regaddr )        {            case 0: // Control Register                if ( data & 0x8000 ) // Reset                {                    /* Reset status and control registers to default. */                    s->mdimem[0] = e100_mdi_default[0];                    s->mdimem[1] = e100_mdi_default[1];                }                break;            case 1: // Status Register                // Auto Negotiation complete, set sticky bit to 1                s->mdimem[regaddr] |= 0x0026;                break;            case 2: // PHY Identification Register (Word 1)            case 3: // PHY Identification Register (Word 2)                break;            case 5: // Auto-Negotiation Link Partner Ability Register                s->mdimem[regaddr] = 0x41fe;                break;            case 6: // Auto-Negotiation Expansion Register                s->mdimem[regaddr] = 0x0001;                break;        }        data = s->mdimem[regaddr];        logout("MDI READ: reg = %#x, data = %#x\n", regaddr, data);    }    /* Emulation takes no time to finish MDI transaction.     * Set MDI bit in SCB status register. */done:    val |= BIT(28);    val = (val & 0xffff0000) + data;    CSR_WRITE(SCB_MDI, val, uint32_t);    if ( ie )        e100_interrupt(s, (uint16_t)INT_MDI);}static void scb_mdi_func(E100State *s, uint32_t val, int dir){    if ( dir == OP_READ )        // Do nothing, just tell driver we are ready        CSR_VAL(CSR_MDI) |= BIT(28);    else if ( dir == OP_WRITE )        e100_write_mdi(s, val);    else

⌨️ 快捷键说明

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