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

📄 e100.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * QEMU E100(i82557) ethernet card emulation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * * Copyright (c) 2006-2007 Stefan Weil * Copyright (c) 2006-2007 Zhang Xin(xing.z.zhang@intel.com) * * Support OS: *      x86 linux and windows *      PAE linux and windows *      x86_64 linux and windows *      IA64 linux and windows * * Untested: *      Big-endian machine * * References: * * Intel 8255x 10/100 Mbps Ethernet Controller Family * Open Source Software Developer Manual */#include <assert.h>#include "vl.h"enum{    E100_PCI_VENDOR_ID = 0x00,        /* 16 bits */    E100_PCI_DEVICE_ID = 0x02,        /* 16 bits */    E100_PCI_COMMAND = 0x04,        /* 16 bits */    E100_PCI_STATUS = 0x06,            /* 16 bits */    E100_PCI_REVISION_ID = 0x08,    /* 8 bits */    E100_PCI_CLASS_CODE = 0x0b,        /* 8 bits */    E100_PCI_SUBCLASS_CODE = 0x0a,    /* 8 bits */    E100_PCI_HEADER_TYPE = 0x0e,    /* 8 bits */    E100_PCI_BASE_ADDRESS_0 = 0x10,    /* 32 bits */    E100_PCI_BASE_ADDRESS_1 = 0x14,    /* 32 bits */    E100_PCI_BASE_ADDRESS_2 = 0x18,    /* 32 bits */    E100_PCI_BASE_ADDRESS_3 = 0x1c,    /* 32 bits */    E100_PCI_BASE_ADDRESS_4 = 0x20,    /* 32 bits */    E100_PCI_BASE_ADDRESS_5 = 0x24    /* 32 bits */}PCI_CONFIGURE_SPACE;#define PCI_CONFIG_8(offset, value) \    (*(uint8_t *)&pci_conf[offset] = (value))#define PCI_CONFIG_16(offset, value) \    (*(uint16_t *)&pci_conf[offset] = cpu_to_le16(value))#define PCI_CONFIG_32(offset, value) \    (*(uint32_t *)&pci_conf[offset] = cpu_to_le32(value))// Alias for Control/Status register read/write#define CSR_STATUS  scb_status#define CSR_CMD scb_cmd#define CSR_POINTER scb_pointer#define CSR_PORT port#define CSR_EEPROM eeprom_ctrl#define CSR_MDI mdi_ctrl#define CSR_PM pm_reg#define CSR(class, field)   \    (s->pci_mem.csr.class.u.field)#define CSR_VAL(class)  \    (s->pci_mem.csr.class.val)#define CSR_READ(x, type)    \    ({  \        type t; \        memcpy(&t, &s->pci_mem.mem[x], sizeof(type)); \        t;  \     })#define CSR_WRITE(x, val, type)    \    ({  \        type t = val; \        memcpy(&s->pci_mem.mem[x], &t, sizeof(type)); \     })#define SET_CU_STATE(val)    \    (CSR(CSR_STATUS, cus) = val)#define GET_CU_STATE    \    (CSR(CSR_STATUS, cus))#define SET_RU_STATE(val)    \    (CSR(CSR_STATUS, rus) = val)#define GET_RU_STATE    \    (CSR(CSR_STATUS, rus))#define KiB 1024#define EEPROM_SIZE     64#define BIT(n) (1U << (n))/* debug E100 card *///#define DEBUG_E100#ifdef DEBUG_E100#define logout(fmt, args...) fprintf(stderr, "EE100\t%-28s" fmt, __func__, ##args)#else#define logout(fmt, args...) ((void)0)#endif#define MAX_ETH_FRAME_SIZE 1514/* This driver supports several different devices which are declared here. */#define i82551          0x82551#define i82557B         0x82557b#define i82557C         0x82557c#define i82558B         0x82558b#define i82559C         0x82559c#define i82559ER        0x82559e#define i82562          0x82562#define PCI_MEM_SIZE            (4 * KiB)#define PCI_IO_SIZE             (64)#define PCI_FLASH_SIZE          (128 * KiB)enum{    OP_READ,    OP_WRITE,} OPERTAION_DIRECTION;/* The SCB accepts the following controls for the Tx and Rx units: */enum{    CU_NOP = 0x0000,        /* No operation */    CU_START = 0x0010,        /* CU start     */    CU_RESUME = 0x0020,        /* CU resume    */    CU_STATSADDR = 0x0040,    /* Load dump counters address */    CU_SHOWSTATS = 0x0050,    /* Dump statistical counters */    CU_CMD_BASE = 0x0060,    /* Load CU base address */    CU_DUMPSTATS = 0x0070,    /* Dump and reset statistical counters */    CU_S_RESUME = 0x00a0    /* CU static resume */}CONTROL_UNIT_COMMAND;enum{    RU_NOP = 0x0000,    RU_START = 0x0001,    RU_RESUME = 0x0002,    RU_DMA_REDIRECT = 0x0003,    RU_ABORT = 0x0004,    RU_LOAD_HDS = 0x0005,    RU_ADDR_LOAD = 0x0006,    RU_RESUMENR = 0x0007,}RECEIVE_UNIT_COMMAND;/* SCB status word descriptions */enum{    CU_IDLE = 0,    CU_SUSPENDED = 1,    CU_LPQ_ACTIVE = 2,    CU_HQP_ACTIVE = 3} CONTROL_UINT_STATE;enum{    RU_IDLE = 0,    RU_SUSPENDED = 1,    RU_NO_RESOURCES =2,    RU_READY = 4} RECEIVE_UNIT_STATE;enum{    PORT_SOFTWARE_RESET = 0,    PORT_SELF_TEST = 1,    PORT_SELECTIVE_RESET = 2,    PORT_DUMP = 3,    PORT_DUMP_WAKE_UP = 7,}SCB_PORT_SELECTION_FUNCTION;enum{    CBL_NOP = 0,    CBL_IASETUP = 1,    CBL_CONFIGURE = 2,    CBL_MULTCAST_ADDR_SETUP = 3,    CBL_TRANSMIT = 4,    CBL_LOAD_MICROCODE = 5,    CBL_DUMP = 6,    CBL_DIAGNOSE = 7,}CBL_COMMAND;enum{    SCB_STATUS = 0,            /* SCB base + 0x00h, RU states + CU states + STAT/ACK */    SCB_ACK = 1,            /* SCB ack/stat */    SCB_CMD = 2,            /* RU command + CU command + S bit + M bit */    SCB_INTERRUPT_MASK = 3, /* Interrupts mask bits */    SCB_POINTER = 4,        /* SCB general pointer, depending on command type */    SCB_PORT = 8,            /* SCB port register */    SCB_EEPROM = 0xe,        /* SCB eeprom control register */    SCB_MDI =0x10,            /* SCB MDI control register */} CSR_OFFSETS;enum{    EEPROM_SK = 0x01,    EEPROM_CS = 0x02,    EEPROM_DI = 0x04,    EEPROM_DO = 0x08,} EEPROM_CONTROL_REGISTER;enum{    EEPROM_READ = 0x2,    EEPROM_WRITE = 0x1,    EEPROM_ERASE = 0x3,} EEPROM_OPCODE;enum{    MDI_WRITE = 0x1,    MDI_READ = 0x2,} MDI_OPCODE;enum{    INT_FCP = BIT(8),    INT_SWI = BIT(10),    INT_MDI = BIT(11),    INT_RNR = BIT(12),    INT_CNA = BIT(13),    INT_FR = BIT(14),    INT_CX_TNO = BIT(15),} E100_INTERRUPT;enum{    CSR_MEMORY_BASE,    CSR_IO_BASE,    FLASH_MEMORY_BASE,    REGION_NUM}E100_PCI_MEMORY_REGION;typedef struct {    uint32_t tx_good_frames,        // Good frames transmitted             tx_max_collisions,     // Fatal frames -- had max collisions             tx_late_collisions,    // Fatal frames -- had a late coll.             tx_underruns,          // Transmit underruns (fatal or re-transmit)             tx_lost_crs,           // Frames transmitted without CRS             tx_deferred,           // Deferred transmits             tx_single_collisions,  // Transmits that had 1 and only 1 coll.             tx_multiple_collisions,// Transmits that had multiple coll.             tx_total_collisions,   // Transmits that had 1+ collisions.             rx_good_frames,        // Good frames received             rx_crc_errors,         // Aligned frames that had a CRC error             rx_alignment_errors,   // Receives that had alignment errors             rx_resource_errors,    // Good frame dropped due to lack of resources             rx_overrun_errors,     // Overrun errors - bus was busy             rx_cdt_errors,         // Received frames that encountered coll.             rx_short_frame_errors, // Received frames that were to short             complete_word;         // A005h indicates dump cmd completion,                                    // A007h indicates dump and reset cmd completion.// TODO: Add specific field for i82558, i82559} __attribute__ ((packed)) e100_stats_t;#define EEPROM_I82557_ADDRBIT 6/* Below data is dumped from a real I82557 card */static const uint16_t eeprom_i82557[] ={    0x300, 0xe147, 0x2fa4, 0x203, 0x0, 0x201, 0x4701, 0x0, 0x7414, 0x6207,    0x4082, 0xb, 0x8086, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x128, 0x0, 0x0, 0x0, 0x0, 0x0,    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc374,};static const uint8_t e100_pci_configure[] ={    0x86, 0x80, 0x29, 0x12, 0x17, 0x00, 0x90, 0x02, 0x08, 0x00, 0x00, 0x02, 0x10, 0x20, 0x00, 0x00,    0x00, 0x00, 0x10, 0x50, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x80, 0x0b, 0x00,    0x00, 0x00, 0xf0, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0x08, 0x38,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0xfe,    0x00, 0x40, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,};typedef struct{#define OPCODE      0xb#define ADDR        0xc#define DATA        0xd#define NOP         0xe#define EEPROM_RESET_ALL      0xfe#define EEPROM_SELECT_RESET   0xff    uint8_t  start_bit;    uint8_t  opcode;    uint8_t  address;    uint16_t data;  //This must be 16 bit represents a register in eeprom    uint32_t val;    uint32_t val_len;    uint8_t  val_type;  // What data type is in DI. opcode?address?data?    uint8_t cs;    uint8_t sk;    // This two fileds only be reset when device init    uint16_t addr_len;    uint16_t contents[256]; // 256 is enough to all device(i82557 ... i82559)} eeprom_t;// Control/Status register structuretypedef struct{    /* SCB status word */    union    {        uint16_t val;        struct        {            uint8_t rs1:2;  // Reserved            uint8_t rus:4;  // RU status            uint8_t cus:2;  // CU status            uint8_t stat_ack; // Stat/ACK        }u;    }scb_status;    /* SCB command word */    union    {        uint16_t val;        struct        {            uint8_t ru_cmd:3;   // RU command            uint8_t rs1:1;      // Reserved            uint8_t cu_cmd:4;   // CU command            uint8_t m:1;        // Interrup mask bit(1:mask all interrupt)            uint8_t si:1;       // Use for software cause interrupt            uint8_t simb:6;     // Specific interrupt mask bit        }u;    }scb_cmd;    /* SCB general pointer */    union    {        uint32_t val;        struct        {            uint32_t scb_ptr;        }u;    }scb_pointer;    /* Port interface */    union    {        uint32_t val;        struct        {            uint8_t opcode:4;   // Op code for function selection            uint32_t ptr:28;    // Result pointer        }u;    }port;    uint16_t rs1;               // Reserved    /* EEPROM control register */    union    {        uint16_t val;        struct        {            uint8_t eesk:1;      // Serial clock            uint8_t eecs:1;      // Chip select            uint8_t eedi:1;      // Serial data in            uint8_t eedo:1;      // Serial data out            uint8_t rs1:4;       // Reserved            uint8_t data;        }u;    }eeprom_ctrl;    /* MDI control register */    union    {        uint32_t val;

⌨️ 快捷键说明

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