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

📄 e1000.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidset_icr(E1000State *s, int index, uint32_t val){    DBGOUT(INTERRUPT, "set_icr %x\n", val);    set_interrupt_cause(s, 0, s->mac_reg[ICR] & ~val);}static voidset_imc(E1000State *s, int index, uint32_t val){    s->mac_reg[IMS] &= ~val;    set_ics(s, 0, 0);}static voidset_ims(E1000State *s, int index, uint32_t val){    s->mac_reg[IMS] |= val;    set_ics(s, 0, 0);}#define getreg(x)	[x] = mac_readregstatic uint32_t (*macreg_readops[])(E1000State *, int) = {    getreg(PBA),	getreg(RCTL),	getreg(TDH),	getreg(TXDCTL),    getreg(WUFC),	getreg(TDT),	getreg(CTRL),	getreg(LEDCTL),    getreg(MANC),	getreg(MDIC),	getreg(SWSM),	getreg(STATUS),    getreg(TORL),	getreg(TOTL),	getreg(IMS),	getreg(TCTL),    getreg(RDH),	getreg(RDT),    [TOTH] = mac_read_clr8,	[TORH] = mac_read_clr8,	[GPRC] = mac_read_clr4,    [GPTC] = mac_read_clr4,	[TPR] = mac_read_clr4,	[TPT] = mac_read_clr4,    [ICR] = mac_icr_read,	[EECD] = get_eecd,	[EERD] = flash_eerd_read,    [CRCERRS ... MPC] = &mac_readreg,    [RA ... RA+31] = &mac_readreg,    [MTA ... MTA+127] = &mac_readreg,};enum { NREADOPS = sizeof(macreg_readops) / sizeof(*macreg_readops) };#define putreg(x)	[x] = mac_writeregstatic void (*macreg_writeops[])(E1000State *, int, uint32_t) = {    putreg(PBA),	putreg(EERD),	putreg(SWSM),	putreg(WUFC),    putreg(TDBAL),	putreg(TDBAH),	putreg(TXDCTL),	putreg(RDBAH),    putreg(RDBAL),	putreg(LEDCTL),    [TDLEN] = set_dlen,	[RDLEN] = set_dlen,	[TCTL] = set_tctl,    [TDT] = set_tctl,	[MDIC] = set_mdic,	[ICS] = set_ics,    [TDH] = set_16bit,	[RDH] = set_16bit,	[RDT] = set_rdt,    [IMC] = set_imc,	[IMS] = set_ims,	[ICR] = set_icr,    [EECD] = set_eecd,	[RCTL] = set_rx_control,    [RA ... RA+31] = &mac_writereg,    [MTA ... MTA+127] = &mac_writereg,};enum { NWRITEOPS = sizeof(macreg_writeops) / sizeof(*macreg_writeops) };static voide1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val){    E1000State *s = opaque;    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;    if (index < NWRITEOPS && macreg_writeops[index])        macreg_writeops[index](s, index, le32_to_cpu(val));    else if (index < NREADOPS && macreg_readops[index])        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);    else        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",               index<<2, val);}static voide1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val){    // emulate hw without byte enables: no RMW    e1000_mmio_writel(opaque, addr & ~3,                      cpu_to_le32(le16_to_cpu(val & 0xffff) << (8*(addr & 3))));}static voide1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val){    // emulate hw without byte enables: no RMW    e1000_mmio_writel(opaque, addr & ~3,                      cpu_to_le32((val & 0xff)  << (8*(addr & 3))));}static uint32_te1000_mmio_readl(void *opaque, target_phys_addr_t addr){    E1000State *s = opaque;    unsigned int index = ((addr - s->mmio_base) & 0x1ffff) >> 2;    if (index < NREADOPS && macreg_readops[index])        return cpu_to_le32(macreg_readops[index](s, index));    DBGOUT(UNKNOWN, "MMIO unknown read addr=0x%08x\n", index<<2);    return 0;}static uint32_te1000_mmio_readb(void *opaque, target_phys_addr_t addr){    return (le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>            (8 * (addr & 3))) & 0xff;}static uint32_te1000_mmio_readw(void *opaque, target_phys_addr_t addr){    return cpu_to_le16((le32_to_cpu(e1000_mmio_readl(opaque, addr & ~3)) >>                        (8 * (addr & 3))) & 0xffff);}int mac_regtosave[] = {    CTRL,	EECD,	EERD,	GPRC,	GPTC,	ICR,	ICS,	IMC,	IMS,    LEDCTL,	MANC,	MDIC,	MPC,	PBA,	RCTL,	RDBAH,	RDBAL,	RDH,    RDLEN,	RDT,	STATUS,	SWSM,	TCTL,	TDBAH,	TDBAL,	TDH,	TDLEN,    TDT,	TORH,	TORL,	TOTH,	TOTL,	TPR,	TPT,	TXDCTL,	WUFC,};enum { MAC_NSAVE = sizeof mac_regtosave/sizeof *mac_regtosave };struct {    int size;    int array0;} mac_regarraystosave[] = { {32, RA}, {128, MTA} };enum { MAC_NARRAYS = sizeof mac_regarraystosave/sizeof *mac_regarraystosave };static voidnic_save(QEMUFile *f, void *opaque){    E1000State *s = (E1000State *)opaque;    int i, j;    pci_device_save(&s->dev, f);    qemu_put_be32s(f, &s->instance);    qemu_put_be32s(f, &s->mmio_base);    qemu_put_be32s(f, &s->rxbuf_size);    qemu_put_be32s(f, &s->rxbuf_min_shift);    qemu_put_be32s(f, &s->eecd_state.val_in);    qemu_put_be16s(f, &s->eecd_state.bitnum_in);    qemu_put_be16s(f, &s->eecd_state.bitnum_out);    qemu_put_be16s(f, &s->eecd_state.reading);    qemu_put_be32s(f, &s->eecd_state.old_eecd);    qemu_put_8s(f, &s->tx.ipcss);    qemu_put_8s(f, &s->tx.ipcso);    qemu_put_be16s(f, &s->tx.ipcse);    qemu_put_8s(f, &s->tx.tucss);    qemu_put_8s(f, &s->tx.tucso);    qemu_put_be16s(f, &s->tx.tucse);    qemu_put_be32s(f, &s->tx.paylen);    qemu_put_8s(f, &s->tx.hdr_len);    qemu_put_be16s(f, &s->tx.mss);    qemu_put_be16s(f, &s->tx.size);    qemu_put_be16s(f, &s->tx.tso_frames);    qemu_put_8s(f, &s->tx.sum_needed);    qemu_put_8s(f, &s->tx.ip);    qemu_put_8s(f, &s->tx.tcp);    qemu_put_buffer(f, s->tx.header, sizeof s->tx.header);    qemu_put_buffer(f, s->tx.data, sizeof s->tx.data);    for (i = 0; i < 64; i++)        qemu_put_be16s(f, s->eeprom_data + i);    for (i = 0; i < 0x20; i++)        qemu_put_be16s(f, s->phy_reg + i);    for (i = 0; i < MAC_NSAVE; i++)        qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]);    for (i = 0; i < MAC_NARRAYS; i++)        for (j = 0; j < mac_regarraystosave[i].size; j++)            qemu_put_be32s(f,                           s->mac_reg + mac_regarraystosave[i].array0 + j);}static intnic_load(QEMUFile *f, void *opaque, int version_id){    E1000State *s = (E1000State *)opaque;    int i, j, ret;    if ((ret = pci_device_load(&s->dev, f)) < 0)        return ret;    qemu_get_be32s(f, &s->instance);    qemu_get_be32s(f, &s->mmio_base);    qemu_get_be32s(f, &s->rxbuf_size);    qemu_get_be32s(f, &s->rxbuf_min_shift);    qemu_get_be32s(f, &s->eecd_state.val_in);    qemu_get_be16s(f, &s->eecd_state.bitnum_in);    qemu_get_be16s(f, &s->eecd_state.bitnum_out);    qemu_get_be16s(f, &s->eecd_state.reading);    qemu_get_be32s(f, &s->eecd_state.old_eecd);    qemu_get_8s(f, &s->tx.ipcss);    qemu_get_8s(f, &s->tx.ipcso);    qemu_get_be16s(f, &s->tx.ipcse);    qemu_get_8s(f, &s->tx.tucss);    qemu_get_8s(f, &s->tx.tucso);    qemu_get_be16s(f, &s->tx.tucse);    qemu_get_be32s(f, &s->tx.paylen);    qemu_get_8s(f, &s->tx.hdr_len);    qemu_get_be16s(f, &s->tx.mss);    qemu_get_be16s(f, &s->tx.size);    qemu_get_be16s(f, &s->tx.tso_frames);    qemu_get_8s(f, &s->tx.sum_needed);    qemu_get_8s(f, &s->tx.ip);    qemu_get_8s(f, &s->tx.tcp);    qemu_get_buffer(f, s->tx.header, sizeof s->tx.header);    qemu_get_buffer(f, s->tx.data, sizeof s->tx.data);    for (i = 0; i < 64; i++)        qemu_get_be16s(f, s->eeprom_data + i);    for (i = 0; i < 0x20; i++)        qemu_get_be16s(f, s->phy_reg + i);    for (i = 0; i < MAC_NSAVE; i++)        qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]);    for (i = 0; i < MAC_NARRAYS; i++)        for (j = 0; j < mac_regarraystosave[i].size; j++)            qemu_get_be32s(f,                           s->mac_reg + mac_regarraystosave[i].array0 + j);    return 0;}static uint16_t e1000_eeprom_template[64] = {    0x0000, 0x0000, 0x0000, 0x0000,      0xffff, 0x0000,      0x0000, 0x0000,    0x3000, 0x1000, 0x6403, E1000_DEVID, 0x8086, E1000_DEVID, 0x8086, 0x3040,    0x0008, 0x2000, 0x7e14, 0x0048,      0x1000, 0x00d8,      0x0000, 0x2700,    0x6cc9, 0x3150, 0x0722, 0x040b,      0x0984, 0x0000,      0xc000, 0x0706,    0x1008, 0x0000, 0x0f04, 0x7fff,      0x4d01, 0xffff,      0xffff, 0xffff,    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,    0x0100, 0x4000, 0x121c, 0xffff,      0xffff, 0xffff,      0xffff, 0xffff,    0xffff, 0xffff, 0xffff, 0xffff,      0xffff, 0xffff,      0xffff, 0x0000,};static uint16_t phy_reg_init[] = {    [PHY_CTRL] = 0x1140,			[PHY_STATUS] = 0x796d, // link initially up    [PHY_ID1] = 0x141,				[PHY_ID2] = PHY_ID2_INIT,    [PHY_1000T_CTRL] = 0x0e00,			[M88E1000_PHY_SPEC_CTRL] = 0x360,    [M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,	[PHY_AUTONEG_ADV] = 0xde1,    [PHY_LP_ABILITY] = 0x1e0,			[PHY_1000T_STATUS] = 0x3c00,};static uint32_t mac_reg_init[] = {    [PBA] =     0x00100030,    [LEDCTL] =  0x602,    [CTRL] =    E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN0 |                E1000_CTRL_SPD_1000 | E1000_CTRL_SLU,    [STATUS] =  0x80000000 | E1000_STATUS_GIO_MASTER_ENABLE |                E1000_STATUS_ASDV | E1000_STATUS_MTXCKOK |                E1000_STATUS_SPEED_1000 | E1000_STATUS_FD |                E1000_STATUS_LU,    [MANC] =    E1000_MANC_EN_MNG2HOST | E1000_MANC_RCV_TCO_EN |                E1000_MANC_ARP_EN | E1000_MANC_0298_EN |                E1000_MANC_RMCP_EN,};/* PCI interface */static CPUWriteMemoryFunc *e1000_mmio_write[] = {    e1000_mmio_writeb,	e1000_mmio_writew,	e1000_mmio_writel};static CPUReadMemoryFunc *e1000_mmio_read[] = {    e1000_mmio_readb,	e1000_mmio_readw,	e1000_mmio_readl};static voide1000_mmio_map(PCIDevice *pci_dev, int region_num,                uint32_t addr, uint32_t size, int type){    E1000State *d = (E1000State *)pci_dev;    DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size);    d->mmio_base = addr;    cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);}voidpci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn){    E1000State *d;    uint8_t *pci_conf;    static int instance;    uint16_t checksum = 0;    char *info_str = "e1000";    int i;    d = (E1000State *)pci_register_device(bus, "e1000",                sizeof(E1000State), devfn, NULL, NULL);    pci_conf = d->dev.config;    memset(pci_conf, 0, 256);    *(uint16_t *)(pci_conf+0x00) = cpu_to_le16(0x8086);    *(uint16_t *)(pci_conf+0x02) = cpu_to_le16(E1000_DEVID);    *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407);    *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010);    pci_conf[0x08] = 0x03;    pci_conf[0x0a] = 0x00; // ethernet network controller    pci_conf[0x0b] = 0x02;    pci_conf[0x0c] = 0x10;    pci_conf[0x3d] = 1; // interrupt pin 0    d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read,            e1000_mmio_write, d);    pci_register_io_region((PCIDevice *)d, 0, PNPMMIO_SIZE,                           PCI_ADDRESS_SPACE_MEM, e1000_mmio_map);    pci_register_io_region((PCIDevice *)d, 1, IOPORT_SIZE,                           PCI_ADDRESS_SPACE_IO, ioport_map);    d->instance = instance++;    d->nd = nd;    memmove(d->eeprom_data, e1000_eeprom_template,        sizeof e1000_eeprom_template);    for (i = 0; i < 3; i++)        d->eeprom_data[i] = (nd->macaddr[2*i+1]<<8) | nd->macaddr[2*i];    for (i = 0; i < EEPROM_CHECKSUM_REG; i++)        checksum += d->eeprom_data[i];    checksum = (uint16_t) EEPROM_SUM - checksum;    d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;    memset(d->phy_reg, 0, sizeof d->phy_reg);    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);    memset(d->mac_reg, 0, sizeof d->mac_reg);    memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);    d->rxbuf_min_shift = 1;    memset(&d->tx, 0, sizeof d->tx);    d->vc = qemu_new_vlan_client(nd->vlan, e1000_receive,                                 e1000_can_receive, d);    snprintf(d->vc->info_str, sizeof(d->vc->info_str),             "%s macaddr=%02x:%02x:%02x:%02x:%02x:%02x", info_str,             d->nd->macaddr[0], d->nd->macaddr[1], d->nd->macaddr[2],             d->nd->macaddr[3], d->nd->macaddr[4], d->nd->macaddr[5]);    register_savevm(info_str, d->instance, 1, nic_save, nic_load, d);}

⌨️ 快捷键说明

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