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

📄 mipsnet.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
字号:
#include "hw.h"#include "mips.h"#include "net.h"#include "isa.h"//#define DEBUG_MIPSNET_SEND//#define DEBUG_MIPSNET_RECEIVE//#define DEBUG_MIPSNET_DATA//#define DEBUG_MIPSNET_IRQ/* MIPSnet register offsets */#define MIPSNET_DEV_ID		0x00# define MIPSNET_DEV_ID_STRING	"MIPSNET0"#define MIPSNET_BUSY		0x08#define MIPSNET_RX_DATA_COUNT	0x0c#define MIPSNET_TX_DATA_COUNT	0x10#define MIPSNET_INT_CTL		0x14# define MIPSNET_INTCTL_TXDONE		0x00000001# define MIPSNET_INTCTL_RXDONE		0x00000002# define MIPSNET_INTCTL_TESTBIT		0x80000000#define MIPSNET_INTERRUPT_INFO	0x18#define MIPSNET_RX_DATA_BUFFER	0x1c#define MIPSNET_TX_DATA_BUFFER	0x20#define MAX_ETH_FRAME_SIZE	1514typedef struct MIPSnetState {    uint32_t busy;    uint32_t rx_count;    uint32_t rx_read;    uint32_t tx_count;    uint32_t tx_written;    uint32_t intctl;    uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];    uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];    qemu_irq irq;    VLANClientState *vc;    NICInfo *nd;} MIPSnetState;static void mipsnet_reset(MIPSnetState *s){    s->busy = 1;    s->rx_count = 0;    s->rx_read = 0;    s->tx_count = 0;    s->tx_written = 0;    s->intctl = 0;    memset(s->rx_buffer, 0, MAX_ETH_FRAME_SIZE);    memset(s->tx_buffer, 0, MAX_ETH_FRAME_SIZE);}static void mipsnet_update_irq(MIPSnetState *s){    int isr = !!s->intctl;#ifdef DEBUG_MIPSNET_IRQ    printf("mipsnet: Set IRQ to %d (%02x)\n", isr, s->intctl);#endif    qemu_set_irq(s->irq, isr);}static int mipsnet_buffer_full(MIPSnetState *s){    if (s->rx_count >= MAX_ETH_FRAME_SIZE)        return 1;    return 0;}static int mipsnet_can_receive(void *opaque){    MIPSnetState *s = opaque;    if (s->busy)        return 0;    return !mipsnet_buffer_full(s);}static void mipsnet_receive(void *opaque, const uint8_t *buf, int size){    MIPSnetState *s = opaque;#ifdef DEBUG_MIPSNET_RECEIVE    printf("mipsnet: receiving len=%d\n", size);#endif    if (!mipsnet_can_receive(opaque))        return;    s->busy = 1;    /* Just accept everything. */    /* Write packet data. */    memcpy(s->rx_buffer, buf, size);    s->rx_count = size;    s->rx_read = 0;    /* Now we can signal we have received something. */    s->intctl |= MIPSNET_INTCTL_RXDONE;    mipsnet_update_irq(s);}static uint32_t mipsnet_ioport_read(void *opaque, uint32_t addr){    MIPSnetState *s = opaque;    int ret = 0;    const char *devid = MIPSNET_DEV_ID_STRING;    addr &= 0x3f;    switch (addr) {    case MIPSNET_DEV_ID:	ret = *((uint32_t *)&devid);        break;    case MIPSNET_DEV_ID + 4:	ret = *((uint32_t *)(&devid + 4));        break;    case MIPSNET_BUSY:	ret = s->busy;        break;    case MIPSNET_RX_DATA_COUNT:	ret = s->rx_count;        break;    case MIPSNET_TX_DATA_COUNT:	ret = s->tx_count;        break;    case MIPSNET_INT_CTL:	ret = s->intctl;        s->intctl &= ~MIPSNET_INTCTL_TESTBIT;        break;    case MIPSNET_INTERRUPT_INFO:        /* XXX: This seems to be a per-VPE interrupt number. */	ret = 0;        break;    case MIPSNET_RX_DATA_BUFFER:        if (s->rx_count) {            s->rx_count--;            ret = s->rx_buffer[s->rx_read++];        }        break;    /* Reads as zero. */    case MIPSNET_TX_DATA_BUFFER:    default:        break;    }#ifdef DEBUG_MIPSNET_DATA    printf("mipsnet: read addr=0x%02x val=0x%02x\n", addr, ret);#endif    return ret;}static void mipsnet_ioport_write(void *opaque, uint32_t addr, uint32_t val){    MIPSnetState *s = opaque;    addr &= 0x3f;#ifdef DEBUG_MIPSNET_DATA    printf("mipsnet: write addr=0x%02x val=0x%02x\n", addr, val);#endif    switch (addr) {    case MIPSNET_TX_DATA_COUNT:	s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0;        s->tx_written = 0;        break;    case MIPSNET_INT_CTL:        if (val & MIPSNET_INTCTL_TXDONE) {            s->intctl &= ~MIPSNET_INTCTL_TXDONE;        } else if (val & MIPSNET_INTCTL_RXDONE) {            s->intctl &= ~MIPSNET_INTCTL_RXDONE;        } else if (val & MIPSNET_INTCTL_TESTBIT) {            mipsnet_reset(s);            s->intctl |= MIPSNET_INTCTL_TESTBIT;        } else if (!val) {            /* ACK testbit interrupt, flag was cleared on read. */        }        s->busy = !!s->intctl;        mipsnet_update_irq(s);        break;    case MIPSNET_TX_DATA_BUFFER:        s->tx_buffer[s->tx_written++] = val;        if (s->tx_written == s->tx_count) {            /* Send buffer. */#ifdef DEBUG_MIPSNET_SEND            printf("mipsnet: sending len=%d\n", s->tx_count);#endif            qemu_send_packet(s->vc, s->tx_buffer, s->tx_count);            s->tx_count = s->tx_written = 0;            s->intctl |= MIPSNET_INTCTL_TXDONE;            s->busy = 1;            mipsnet_update_irq(s);        }        break;    /* Read-only registers */    case MIPSNET_DEV_ID:    case MIPSNET_BUSY:    case MIPSNET_RX_DATA_COUNT:    case MIPSNET_INTERRUPT_INFO:    case MIPSNET_RX_DATA_BUFFER:    default:        break;    }}static void mipsnet_save(QEMUFile *f, void *opaque){    MIPSnetState *s = opaque;    qemu_put_be32s(f, &s->busy);    qemu_put_be32s(f, &s->rx_count);    qemu_put_be32s(f, &s->rx_read);    qemu_put_be32s(f, &s->tx_count);    qemu_put_be32s(f, &s->tx_written);    qemu_put_be32s(f, &s->intctl);    qemu_put_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);    qemu_put_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);}static int mipsnet_load(QEMUFile *f, void *opaque, int version_id){    MIPSnetState *s = opaque;    if (version_id > 0)        return -EINVAL;    qemu_get_be32s(f, &s->busy);    qemu_get_be32s(f, &s->rx_count);    qemu_get_be32s(f, &s->rx_read);    qemu_get_be32s(f, &s->tx_count);    qemu_get_be32s(f, &s->tx_written);    qemu_get_be32s(f, &s->intctl);    qemu_get_buffer(f, s->rx_buffer, MAX_ETH_FRAME_SIZE);    qemu_get_buffer(f, s->tx_buffer, MAX_ETH_FRAME_SIZE);    return 0;}void mipsnet_init (int base, qemu_irq irq, NICInfo *nd){    MIPSnetState *s;    s = qemu_mallocz(sizeof(MIPSnetState));    if (!s)        return;    register_ioport_write(base, 36, 1, mipsnet_ioport_write, s);    register_ioport_read(base, 36, 1, mipsnet_ioport_read, s);    register_ioport_write(base, 36, 2, mipsnet_ioport_write, s);    register_ioport_read(base, 36, 2, mipsnet_ioport_read, s);    register_ioport_write(base, 36, 4, mipsnet_ioport_write, s);    register_ioport_read(base, 36, 4, mipsnet_ioport_read, s);    s->irq = irq;    s->nd = nd;    if (nd && nd->vlan) {        s->vc = qemu_new_vlan_client(nd->vlan, mipsnet_receive,                                     mipsnet_can_receive, s);    } else {        s->vc = NULL;    }    snprintf(s->vc->info_str, sizeof(s->vc->info_str),             "mipsnet macaddr=%02x:%02x:%02x:%02x:%02x:%02x",              s->nd->macaddr[0],              s->nd->macaddr[1],              s->nd->macaddr[2],              s->nd->macaddr[3],              s->nd->macaddr[4],              s->nd->macaddr[5]);    mipsnet_reset(s);    register_savevm("mipsnet", 0, 0, mipsnet_save, mipsnet_load, s);}

⌨️ 快捷键说明

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