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

📄 eepro100.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
 ****************************************************************************/#define EEPROM_CS       0x02#define EEPROM_SK       0x01#define EEPROM_DI       0x04#define EEPROM_DO       0x08static uint16_t eepro100_read_eeprom(EEPRO100State * s){    uint16_t val;    memcpy(&val, &s->mem[SCBeeprom], sizeof(val));    if (eeprom93xx_read(s->eeprom)) {        val |= EEPROM_DO;    } else {        val &= ~EEPROM_DO;    }    return val;}static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val){    logout("write val=0x%02x\n", val);    /* mask unwriteable bits */    //~ val = SET_MASKED(val, 0x31, eeprom->value);    int eecs = ((val & EEPROM_CS) != 0);    int eesk = ((val & EEPROM_SK) != 0);    int eedi = ((val & EEPROM_DI) != 0);    eeprom93xx_write(eeprom, eecs, eesk, eedi);}static void eepro100_write_pointer(EEPRO100State * s, uint32_t val){    s->pointer = le32_to_cpu(val);    logout("val=0x%08x\n", val);}/***************************************************************************** * * MDI emulation. * ****************************************************************************/#if defined(DEBUG_EEPRO100)static const char *mdi_op_name[] = {    "opcode 0",    "write",    "read",    "opcode 3"};static const char *mdi_reg_name[] = {    "Control",    "Status",    "PHY Identification (Word 1)",    "PHY Identification (Word 2)",    "Auto-Negotiation Advertisement",    "Auto-Negotiation Link Partner Ability",    "Auto-Negotiation Expansion"};#endif                          /* DEBUG_EEPRO100 */static uint32_t eepro100_read_mdi(EEPRO100State * s){    uint32_t val;    memcpy(&val, &s->mem[0x10], sizeof(val));#ifdef DEBUG_EEPRO100    uint8_t raiseint = (val & BIT(29)) >> 29;    uint8_t opcode = (val & BITS(27, 26)) >> 26;    uint8_t phy = (val & BITS(25, 21)) >> 21;    uint8_t reg = (val & BITS(20, 16)) >> 16;    uint16_t data = (val & BITS(15, 0));#endif    /* Emulation takes no time to finish MDI transaction. */    val |= BIT(28);    TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",                      val, raiseint, mdi_op_name[opcode], phy,                      mdi_reg_name[reg], data));    return val;}//~ #define BITS(val, upper, lower) (val & ???)static void eepro100_write_mdi(EEPRO100State * s, uint32_t val){    uint8_t raiseint = (val & BIT(29)) >> 29;    uint8_t opcode = (val & BITS(27, 26)) >> 26;    uint8_t phy = (val & BITS(25, 21)) >> 21;    uint8_t reg = (val & BITS(20, 16)) >> 16;    uint16_t data = (val & BITS(15, 0));    if (phy != 1) {        /* Unsupported PHY address. */        //~ logout("phy must be 1 but is %u\n", phy);        data = 0;    } else if (opcode != 1 && opcode != 2) {        /* Unsupported opcode. */        logout("opcode must be 1 or 2 but is %u\n", opcode);        data = 0;    } else if (reg > 6) {        /* Unsupported register. */        logout("register must be 0...6 but is %u\n", reg);        data = 0;    } else {        TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",                          val, raiseint, mdi_op_name[opcode], phy,                          mdi_reg_name[reg], data));        if (opcode == 1) {            /* MDI write */            switch (reg) {            case 0:            /* Control Register */                if (data & 0x8000) {                    /* Reset status and control registers to default. */                    s->mdimem[0] = eepro100_mdi_default[0];                    s->mdimem[1] = eepro100_mdi_default[1];                    data = s->mdimem[reg];                } else {                    /* Restart Auto Configuration = Normal Operation */                    data &= ~0x0200;                }                break;            case 1:            /* Status Register */                missing("not writable");                data = s->mdimem[reg];                break;            case 2:            /* PHY Identification Register (Word 1) */            case 3:            /* PHY Identification Register (Word 2) */                missing("not implemented");                break;            case 4:            /* Auto-Negotiation Advertisement Register */            case 5:            /* Auto-Negotiation Link Partner Ability Register */                break;            case 6:            /* Auto-Negotiation Expansion Register */            default:                missing("not implemented");            }            s->mdimem[reg] = data;        } else if (opcode == 2) {            /* MDI read */            switch (reg) {            case 0:            /* Control Register */                if (data & 0x8000) {                    /* Reset status and control registers to default. */                    s->mdimem[0] = eepro100_mdi_default[0];                    s->mdimem[1] = eepro100_mdi_default[1];                }                break;            case 1:            /* Status Register */                s->mdimem[reg] |= 0x0020;                break;            case 2:            /* PHY Identification Register (Word 1) */            case 3:            /* PHY Identification Register (Word 2) */            case 4:            /* Auto-Negotiation Advertisement Register */                break;            case 5:            /* Auto-Negotiation Link Partner Ability Register */                s->mdimem[reg] = 0x41fe;                break;            case 6:            /* Auto-Negotiation Expansion Register */                s->mdimem[reg] = 0x0001;                break;            }            data = s->mdimem[reg];        }        /* Emulation takes no time to finish MDI transaction.         * Set MDI bit in SCB status register. */        s->mem[SCBAck] |= 0x08;        val |= BIT(28);        if (raiseint) {            eepro100_mdi_interrupt(s);        }    }    val = (val & 0xffff0000) + data;    memcpy(&s->mem[0x10], &val, sizeof(val));}/***************************************************************************** * * Port emulation. * ****************************************************************************/#define PORT_SOFTWARE_RESET     0#define PORT_SELFTEST           1#define PORT_SELECTIVE_RESET    2#define PORT_DUMP               3#define PORT_SELECTION_MASK     3typedef struct {    uint32_t st_sign;           /* Self Test Signature */    uint32_t st_result;         /* Self Test Results */} eepro100_selftest_t;static uint32_t eepro100_read_port(EEPRO100State * s){    return 0;}static void eepro100_write_port(EEPRO100State * s, uint32_t val){    val = le32_to_cpu(val);    uint32_t address = (val & ~PORT_SELECTION_MASK);    uint8_t selection = (val & PORT_SELECTION_MASK);    switch (selection) {    case PORT_SOFTWARE_RESET:        nic_reset(s);        break;    case PORT_SELFTEST:        logout("selftest address=0x%08x\n", address);        eepro100_selftest_t data;        cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data));        data.st_sign = 0xffffffff;        data.st_result = 0;        cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data));        break;    case PORT_SELECTIVE_RESET:        logout("selective reset, selftest address=0x%08x\n", address);        nic_selective_reset(s);        break;    default:        logout("val=0x%08x\n", val);        missing("unknown port selection");    }}/***************************************************************************** * * General hardware emulation. * ****************************************************************************/static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr){    uint8_t val;    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&val, &s->mem[addr], sizeof(val));    }    switch (addr) {    case SCBStatus:        //~ val = eepro100_read_status(s);        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case SCBAck:        //~ val = eepro100_read_status(s);        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case SCBCmd:        logout("addr=%s val=0x%02x\n", regname(addr), val);        //~ val = eepro100_read_command(s);        break;    case SCBIntmask:        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case SCBPort + 3:        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case SCBeeprom:        val = eepro100_read_eeprom(s);        break;    case 0x1b:                 /* PMDR (power management driver register) */        val = 0;        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case 0x1d:                 /* general status register */        /* 100 Mbps full duplex, valid link */        val = 0x07;        logout("addr=General Status val=%02x\n", val);        break;    default:        logout("addr=%s val=0x%02x\n", regname(addr), val);        missing("unknown byte read");    }    return val;}static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr){    uint16_t val;    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&val, &s->mem[addr], sizeof(val));    }    logout("addr=%s val=0x%04x\n", regname(addr), val);    switch (addr) {    case SCBStatus:        //~ val = eepro100_read_status(s);        break;    case SCBeeprom:        val = eepro100_read_eeprom(s);        break;    default:        logout("addr=%s val=0x%04x\n", regname(addr), val);        missing("unknown word read");    }    return val;}static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr){    uint32_t val;    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&val, &s->mem[addr], sizeof(val));    }    switch (addr) {    case SCBStatus:        //~ val = eepro100_read_status(s);        logout("addr=%s val=0x%08x\n", regname(addr), val);        break;    case SCBPointer:        //~ val = eepro100_read_pointer(s);        logout("addr=%s val=0x%08x\n", regname(addr), val);        break;    case SCBPort:        val = eepro100_read_port(s);        logout("addr=%s val=0x%08x\n", regname(addr), val);        break;    case SCBCtrlMDI:        val = eepro100_read_mdi(s);        break;    default:        logout("addr=%s val=0x%08x\n", regname(addr), val);        missing("unknown longword read");    }    return val;}static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val){    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&s->mem[addr], &val, sizeof(val));    }    logout("addr=%s val=0x%02x\n", regname(addr), val);    switch (addr) {    case SCBStatus:        //~ eepro100_write_status(s, val);        break;    case SCBAck:        eepro100_acknowledge(s);        break;    case SCBCmd:        eepro100_write_command(s, val);        break;    case SCBIntmask:        if (val & BIT(1)) {            eepro100_swi_interrupt(s);        }        eepro100_interrupt(s, 0);        break;    case SCBPort + 3:    case SCBFlow:    case SCBFlow + 1:    case SCBFlow + 2:    case SCBFlow + 3:        logout("addr=%s val=0x%02x\n", regname(addr), val);        break;    case SCBeeprom:        eepro100_write_eeprom(s->eeprom, val);        break;    default:        logout("addr=%s val=0x%02x\n", regname(addr), val);        missing("unknown byte write");    }}static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val){    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&s->mem[addr], &val, sizeof(val));    }    logout("addr=%s val=0x%04x\n", regname(addr), val);    switch (addr) {    case SCBStatus:        //~ eepro100_write_status(s, val);        eepro100_acknowledge(s);        break;    case SCBCmd:        eepro100_write_command(s, val);        eepro100_write1(s, SCBIntmask, val >> 8);        break;    case SCBeeprom:        eepro100_write_eeprom(s->eeprom, val);        break;    default:        logout("addr=%s val=0x%04x\n", regname(addr), val);        missing("unknown word write");    }}static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val){    if (addr <= sizeof(s->mem) - sizeof(val)) {        memcpy(&s->mem[addr], &val, sizeof(val));    }    switch (addr) {    case SCBPointer:        eepro100_write_pointer(s, val);        break;    case SCBPort:        logout("addr=%s val=0x%08x\n", regname(addr), val);        eepro100_write_port(s, val);        break;    case SCBCtrlMDI:        eepro100_write_mdi(s, val);        break;    default:        logout("addr=%s val=0x%08x\n", regname(addr), val);        missing("unknown longword write");    }}static uint32_t ioport_read1(void *opaque, uint32_t addr){    EEPRO100State *s = opaque;    //~ logout("addr=%s\n", regname(addr));    return eepro100_read1(s, addr - s->region[1]);}static uint32_t ioport_read2(void *opaque, uint32_t addr){    EEPRO100State *s = opaque;    return eepro100_read2(s, addr - s->region[1]);}static uint32_t ioport_read4(void *opaque, uint32_t addr){    EEPRO100State *s = opaque;    return eepro100_read4(s, addr - s->region[1]);}static void ioport_write1(void *opaque, uint32_t addr, uint32_t val){    EEPRO100State *s = opaque;    //~ logout("addr=%s val=0x%02x\n", regname(addr), val);    eepro100_write1(s, addr - s->region[1], val);}static void ioport_write2(void *opaque, uint32_t addr, uint32_t val){    EEPRO100State *s = opaque;    eepro100_write2(s, addr - s->region[1], val);}static void ioport_write4(void *opaque, uint32_t addr, uint32_t val){    EEPRO100State *s = opaque;    eepro100_write4(s, addr - s->region[1], val);}

⌨️ 快捷键说明

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