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

📄 eepro100.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/* * QEMU i8255x (PRO100) emulation * * Copyright (c) 2006-2007 Stefan Weil * * Portions of the code are copies from grub / etherboot eepro100.c * and linux e100.c. * * 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 * * Tested features (i82559): *      PXE boot (i386) no valid link *      Linux networking (i386) ok * * Untested: *      non-i386 platforms *      Windows networking * * References: * * Intel 8255x 10/100 Mbps Ethernet Controller Family * Open Source Software Developer Manual */#if defined(TARGET_I386)# warning "PXE boot still not working!"#endif#include <assert.h>#include <stddef.h>             /* offsetof */#include "hw.h"#include "pci.h"#include "net.h"#include "eeprom93xx.h"/* Common declarations for all PCI devices. */#define PCI_VENDOR_ID           0x00    /* 16 bits */#define PCI_DEVICE_ID           0x02    /* 16 bits */#define PCI_COMMAND             0x04    /* 16 bits */#define PCI_STATUS              0x06    /* 16 bits */#define PCI_REVISION_ID         0x08    /* 8 bits  */#define PCI_CLASS_CODE          0x0b    /* 8 bits */#define PCI_SUBCLASS_CODE       0x0a    /* 8 bits */#define PCI_HEADER_TYPE         0x0e    /* 8 bits */#define PCI_BASE_ADDRESS_0      0x10    /* 32 bits */#define PCI_BASE_ADDRESS_1      0x14    /* 32 bits */#define PCI_BASE_ADDRESS_2      0x18    /* 32 bits */#define PCI_BASE_ADDRESS_3      0x1c    /* 32 bits */#define PCI_BASE_ADDRESS_4      0x20    /* 32 bits */#define PCI_BASE_ADDRESS_5      0x24    /* 32 bits */#define PCI_CONFIG_8(offset, value) \    (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))#define KiB 1024/* debug EEPRO100 card *///~ #define DEBUG_EEPRO100#ifdef DEBUG_EEPRO100#define logout(fmt, args...) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ##args)#else#define logout(fmt, args...) ((void)0)#endif/* Set flags to 0 to disable debug output. */#define MDI     0#define TRACE(flag, command) ((flag) ? (command) : (void)0)#define missing(text)       assert(!"feature is missing in this emulation: " text)#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 EEPROM_SIZE     64#define PCI_MEM_SIZE            (4 * KiB)#define PCI_IO_SIZE             64#define PCI_FLASH_SIZE          (128 * KiB)#define BIT(n) (1 << (n))#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)/* The SCB accepts the following controls for the Tx and Rx units: */#define  CU_NOP         0x0000  /* No operation. */#define  CU_START       0x0010  /* CU start. */#define  CU_RESUME      0x0020  /* CU resume. */#define  CU_STATSADDR   0x0040  /* Load dump counters address. */#define  CU_SHOWSTATS   0x0050  /* Dump statistical counters. */#define  CU_CMD_BASE    0x0060  /* Load CU base address. */#define  CU_DUMPSTATS   0x0070  /* Dump and reset statistical counters. */#define  CU_SRESUME     0x00a0  /* CU static resume. */#define  RU_NOP         0x0000#define  RX_START       0x0001#define  RX_RESUME      0x0002#define  RX_ABORT       0x0004#define  RX_ADDR_LOAD   0x0006#define  RX_RESUMENR    0x0007#define INT_MASK        0x0100#define DRVR_INT        0x0200  /* Driver generated interrupt. */typedef unsigned char bool;/* Offsets to the various registers.   All accesses need not be longword aligned. */enum speedo_offsets {    SCBStatus = 0,    SCBAck = 1,    SCBCmd = 2,                 /* Rx/Command Unit command and status. */    SCBIntmask = 3,    SCBPointer = 4,             /* General purpose pointer. */    SCBPort = 8,                /* Misc. commands and operands.  */    SCBflash = 12, SCBeeprom = 14,      /* EEPROM and flash memory control. */    SCBCtrlMDI = 16,            /* MDI interface control. */    SCBEarlyRx = 20,            /* Early receive byte count. */    SCBFlow = 24,};/* A speedo3 transmit buffer descriptor with two buffers... */typedef struct {    uint16_t status;    uint16_t command;    uint32_t link;              /* void * */    uint32_t tx_desc_addr;      /* transmit buffer decsriptor array address. */    uint16_t tcb_bytes;         /* transmit command block byte count (in lower 14 bits */    uint8_t tx_threshold;       /* transmit threshold */    uint8_t tbd_count;          /* TBD number */    //~ /* This constitutes two "TBD" entries: hdr and data */    //~ uint32_t tx_buf_addr0;  /* void *, header of frame to be transmitted.  */    //~ int32_t  tx_buf_size0;  /* Length of Tx hdr. */    //~ uint32_t tx_buf_addr1;  /* void *, data to be transmitted.  */    //~ int32_t  tx_buf_size1;  /* Length of Tx data. */} eepro100_tx_t;/* Receive frame descriptor. */typedef struct {    int16_t status;    uint16_t command;    uint32_t link;              /* struct RxFD * */    uint32_t rx_buf_addr;       /* void * */    uint16_t count;    uint16_t size;    char packet[MAX_ETH_FRAME_SIZE + 4];} eepro100_rx_t;typedef struct {    uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions,        tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,        tx_multiple_collisions, tx_total_collisions;    uint32_t rx_good_frames, rx_crc_errors, rx_alignment_errors,        rx_resource_errors, rx_overrun_errors, rx_cdt_errors,        rx_short_frame_errors;    uint32_t fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;    uint16_t xmt_tco_frames, rcv_tco_frames;    uint32_t complete;} eepro100_stats_t;typedef enum {    cu_idle = 0,    cu_suspended = 1,    cu_active = 2,    cu_lpq_active = 2,    cu_hqp_active = 3} cu_state_t;typedef enum {    ru_idle = 0,    ru_suspended = 1,    ru_no_resources = 2,    ru_ready = 4} ru_state_t;#if defined(__BIG_ENDIAN_BITFIELD)#define X(a,b)	b,a#else#define X(a,b)	a,b#endiftypedef struct {#if 1    uint8_t cmd;    uint32_t start;    uint32_t stop;    uint8_t boundary;    uint8_t tsr;    uint8_t tpsr;    uint16_t tcnt;    uint16_t rcnt;    uint32_t rsar;    uint8_t rsr;    uint8_t rxcr;    uint8_t isr;    uint8_t dcfg;    uint8_t imr;    uint8_t phys[6];            /* mac address */    uint8_t curpag;    uint8_t mult[8];            /* multicast mask array */    int mmio_index;    PCIDevice *pci_dev;    VLANClientState *vc;#endif    uint8_t scb_stat;           /* SCB stat/ack byte */    uint8_t int_stat;           /* PCI interrupt status */    uint32_t region[3];         /* PCI region addresses */    uint8_t macaddr[6];    uint32_t statcounter[19];    uint16_t mdimem[32];    eeprom_t *eeprom;    uint32_t device;            /* device variant */    uint32_t pointer;    /* (cu_base + cu_offset) address the next command block in the command block list. */    uint32_t cu_base;           /* CU base address */    uint32_t cu_offset;         /* CU address offset */    /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */    uint32_t ru_base;           /* RU base address */    uint32_t ru_offset;         /* RU address offset */    uint32_t statsaddr;         /* pointer to eepro100_stats_t */    eepro100_stats_t statistics;        /* statistical counters */#if 0    uint16_t status;#endif    /* Configuration bytes. */    uint8_t configuration[22];    /* Data in mem is always in the byte order of the controller (le). */    uint8_t mem[PCI_MEM_SIZE];} EEPRO100State;/* Default values for MDI (PHY) registers */static const uint16_t eepro100_mdi_default[] = {    /* MDI Registers 0 - 6, 7 */    0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,    /* MDI Registers 8 - 15 */    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,    /* MDI Registers 16 - 31 */    0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};/* Readonly mask for MDI (PHY) registers */static const uint16_t eepro100_mdi_mask[] = {    0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,    0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,    0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};#define POLYNOMIAL 0x04c11db6/* From FreeBSD *//* XXX: optimize */static int compute_mcast_idx(const uint8_t * ep){    uint32_t crc;    int carry, i, j;    uint8_t b;    crc = 0xffffffff;    for (i = 0; i < 6; i++) {        b = *ep++;        for (j = 0; j < 8; j++) {            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);            crc <<= 1;            b >>= 1;            if (carry)                crc = ((crc ^ POLYNOMIAL) | carry);        }    }    return (crc >> 26);}#if defined(DEBUG_EEPRO100)static const char *nic_dump(const uint8_t * buf, unsigned size){    static char dump[3 * 16 + 1];    char *p = &dump[0];    if (size > 16)        size = 16;    while (size-- > 0) {        p += sprintf(p, " %02x", *buf++);    }    return dump;}#endif                          /* DEBUG_EEPRO100 */enum scb_stat_ack {    stat_ack_not_ours = 0x00,    stat_ack_sw_gen = 0x04,    stat_ack_rnr = 0x10,    stat_ack_cu_idle = 0x20,    stat_ack_frame_rx = 0x40,    stat_ack_cu_cmd_done = 0x80,    stat_ack_not_present = 0xFF,    stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),    stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),};static void disable_interrupt(EEPRO100State * s){    if (s->int_stat) {        logout("interrupt disabled\n");        qemu_irq_lower(s->pci_dev->irq[0]);        s->int_stat = 0;    }}static void enable_interrupt(EEPRO100State * s){    if (!s->int_stat) {        logout("interrupt enabled\n");        qemu_irq_raise(s->pci_dev->irq[0]);        s->int_stat = 1;    }}static void eepro100_acknowledge(EEPRO100State * s){    s->scb_stat &= ~s->mem[SCBAck];    s->mem[SCBAck] = s->scb_stat;    if (s->scb_stat == 0) {        disable_interrupt(s);    }}static void eepro100_interrupt(EEPRO100State * s, uint8_t stat){    uint8_t mask = ~s->mem[SCBIntmask];    s->mem[SCBAck] |= stat;    stat = s->scb_stat = s->mem[SCBAck];    stat &= (mask | 0x0f);    //~ stat &= (~s->mem[SCBIntmask] | 0x0xf);    if (stat && (mask & 0x01)) {        /* SCB mask and SCB Bit M do not disable interrupt. */        enable_interrupt(s);    } else if (s->int_stat) {        disable_interrupt(s);    }}static void eepro100_cx_interrupt(EEPRO100State * s){    /* CU completed action command. */    /* Transmit not ok (82557 only, not in emulation). */    eepro100_interrupt(s, 0x80);}static void eepro100_cna_interrupt(EEPRO100State * s){    /* CU left the active state. */    eepro100_interrupt(s, 0x20);}static void eepro100_fr_interrupt(EEPRO100State * s){    /* RU received a complete frame. */    eepro100_interrupt(s, 0x40);}#if 0static void eepro100_rnr_interrupt(EEPRO100State * s){    /* RU is not ready. */    eepro100_interrupt(s, 0x10);}#endifstatic void eepro100_mdi_interrupt(EEPRO100State * s){    /* MDI completed read or write cycle. */    eepro100_interrupt(s, 0x08);}static void eepro100_swi_interrupt(EEPRO100State * s){    /* Software has requested an interrupt. */    eepro100_interrupt(s, 0x04);}#if 0static void eepro100_fcp_interrupt(EEPRO100State * s){    /* Flow control pause interrupt (82558 and later). */    eepro100_interrupt(s, 0x01);}#endifstatic void pci_reset(EEPRO100State * s){    uint32_t device = s->device;    uint8_t *pci_conf = s->pci_dev->config;    logout("%p\n", s);    /* PCI Vendor ID */    PCI_CONFIG_16(PCI_VENDOR_ID, 0x8086);    /* PCI Device ID */    PCI_CONFIG_16(PCI_DEVICE_ID, 0x1209);    /* PCI Command */    PCI_CONFIG_16(PCI_COMMAND, 0x0000);    /* PCI Status */    PCI_CONFIG_16(PCI_STATUS, 0x2800);    /* PCI Revision ID */    PCI_CONFIG_8(PCI_REVISION_ID, 0x08);    /* PCI Class Code */    PCI_CONFIG_8(0x09, 0x00);    PCI_CONFIG_8(PCI_SUBCLASS_CODE, 0x00);      // ethernet network controller    PCI_CONFIG_8(PCI_CLASS_CODE, 0x02); // network controller    /* PCI Cache Line Size */    /* check cache line size!!! */    //~ PCI_CONFIG_8(0x0c, 0x00);    /* PCI Latency Timer */    PCI_CONFIG_8(0x0d, 0x20);   // latency timer = 32 clocks    /* PCI Header Type */    /* BIST (built-in self test) */#if defined(TARGET_I386)// !!! workaround for buggy bios//~ #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0#endif#if 0    /* PCI Base Address Registers */    /* CSR Memory Mapped Base Address */    PCI_CONFIG_32(PCI_BASE_ADDRESS_0,                  PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_MEM_PREFETCH);    /* CSR I/O Mapped Base Address */

⌨️ 快捷键说明

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