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

📄 if_xdssonic.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  camdump (csr); */  return 1;}/* * because the sonic is basically a 16 bit device it 'concatenates' * a higher buffer address to a 16 bit offset this can cause wrap * around problems near 64k boundaries !! */static intallocatebuffers (){    void *buf;    u_long p, lo, hi;#undef XDSLOWMEM#if defined(XDS)#ifdef XDSLOWMEM    rba = (char *)PHYS_TO_K1(0x07050000);#else    rba = (char *)PHYS_TO_K1(SRAM_NET);#endif    tba = rba + NRBA * RBASIZE;    buf = tba + NTDA * TBASIZE;#else    buf = malloc (SONICBUFSIZE, M_DEVBUF, 0);    if (!buf)      return (ENOBUFS);    rba = (char *) malloc (NRBA * RBASIZE, M_DEVBUF, 0);    if (!rba) {	free (buf, M_DEVBUF);	return (ENOBUFS);    }#endif#ifdef R4000    /* flush dirty data first */    if (IS_K0SEG (buf)) {	clean_dcache (buf, SONICBUFSIZE);	clean_dcache (rba, NRBA * RBASIZE);#ifdef XDS	clean_dcache (tba, NTDA * TBASIZE);#endif    }#endif    /* force into kseg1, and align correctly */    p = ((u_long) K0_TO_K1 (buf) + SONICALIGN - 1) & ~(SONICALIGN - 1);    /* RRA and CDA must fit inside 64k region */    if ((p ^ (p+RRASIZE+CDASIZE)) & ~0xffff)      p = (p+0x10000) & ~0xffff;    rra = (struct RXrsrc *)p; p += RRASIZE;    cda = (struct CDA *)p; p += CDASIZE;        /* RDA must fit inside 64k region */    if ((p ^ (p+RDASIZE)) & ~0xffff)      p = (p+0x10000) & ~0xffff;    rda = (struct RXpkt *)p; p += RDASIZE;        /* TDA must fit inside 64k region */    if ((p ^ (p+TDASIZE)) & ~0xffff)      p = (p+0x10000) & ~0xffff;    tda = (struct TXpkt *)p; p += TDASIZE;        /* check sanity of buffer addreseses */    lo = (u_long) K0_TO_K1 (buf);     hi = lo + SONICBUFSIZE;    if ((unsigned)rra < lo || (unsigned)rra >= hi ||	(unsigned)cda < lo || (unsigned)cda >= hi ||	(unsigned)rda < lo || (unsigned)rda >= hi ||	(unsigned)tda < lo || (unsigned)tda >= hi) {	log (LOG_ERR, "sonic descriptors out of range\n");	return ENOMEM;    }#ifdef notdefprintf ("rba = 0x%08x\n", rba);printf ("tba = 0x%08x\n", tba);printf ("rra = 0x%08x\n", rra);printf ("cda = 0x%08x\n", cda);printf ("rda = 0x%08x\n", rda);printf ("tda = 0x%08x\n", tda);#endif    /* return errno */    return 0;}static voidinitialise_tda (struct sn_softc *sn){  volatile struct sn_reg *csr = sn->sn_csr;  struct mtd *mtd;  int i;  bzero ((char *)tda, TDASIZE);  mtdfree = mtdhead = mtdtail = (struct mtd *)0;  for (i = 0; i < NTDA; i++) {    mtd = &mtda[i];    mtd->mtd_txp = &tda[i];    mtd_free(mtd);#ifdef XDS    mtd->mtd_tba = tba + i*TBASIZE;#endif     }  mtdnext = mtd_alloc ();    csr->s_utda = UPPER(tda); wbflush();  csr->s_ctda = LOWER(mtdnext->mtd_txp); wbflush();}static voidinitialise_rda (struct sn_softc *sn){  volatile struct sn_reg *csr = sn->sn_csr;  int i;      /* link the RDA's together into a circular list   */  bzero ((char *)rda, RDASIZE);  for (i = 0; i < (NRDA-1); i++) {    rda[i].rlink = LOWER(&rda[i+1]);    rda[i].in_use = ~0;  }  rda[NRDA-1].in_use = ~0;  rda[NRDA-1].rlink =  LOWER(&rda[0]) | EOL;  /* mark end of receive descriptor list */  sn->sn_lrxp = &rda[NRDA-1];  sn->sn_rxmark = 0;  csr->s_urda = UPPER(rda);  csr->s_crda = LOWER(rda);  wbflush();}static voidinitialise_rra (struct sn_softc *sn){  volatile struct sn_reg *csr = sn->sn_csr;  char *rb;  int i;again:  bzero ((char *)rra, RRASIZE);  csr->s_eobc = EOBC / 2;  csr->s_urra = UPPER(rra);  csr->s_rsa = LOWER(rra);  csr->s_rea = LOWER(&rra[NRRA]);  /*   * fill up SOME of the rra with buffers    */  for (i = 0, rb = rba; i < NRBA; i++, rb += RBASIZE) {    rra[i].buff_ptrhi = UPPER(rb);    rra[i].buff_ptrlo = LOWER(rb);#ifdef XDSSONICBUG    rra[i].buff_wchi = (RBASIZE / 4) >> 16;    rra[i].buff_wclo = (RBASIZE / 4);#else    rra[i].buff_wchi = (RBASIZE / 2) >> 16;    rra[i].buff_wclo = (RBASIZE / 2);#endif  }  sn->sn_rramark = NRBA;  csr->s_rrp = LOWER(rra);  csr->s_rwp = LOWER(&rra[sn->sn_rramark]);  wbflush();}/* * snwatch(): interface watchdog timer *  * Called if any Tx packets remain unsent after 5 seconds, * In all cases we just reset the chip, and any retransmission  * will be handled by higher level protocol timeouts. */static intsnwatch (int unit){    struct sn_softc *sn = &sn_softc[unit];    int s = splimp();        if (mtdhead && mtdhead != mtdnext) {	/* something still pending for transmit */	log (LOG_WARNING, "%s%d: Tx - %s\n",	     sn->sn_if.if_name, sn->sn_if.if_unit,	     (MASK(mtdhead->mtd_txp->status) == 0) ? "timeout" : "lost interrupt");	/* snrestart (sn); */        snclosedown (sn);    }    (void) splx (s);    return 0;}/* * sn_pullup(): reorganise part of an mbuf chain to satisfy SONIC. *  * It doesn't free mbufs that reduce to zero length.   * This is in case they are NFS mbufs which point to disk buffers. * and the buffers must not be released until after the packet has flown. */static struct mbuf *sn_pullup (n, len)    register struct mbuf *n;    register int len;{    register struct mbuf *m;    register int count;        /* check it will fit in an ordinary mbuf */    if (len > MLEN)      goto bad;    if ((n->m_flags & M_EXT) == 0) {	/* ordinary mbuf */	if (n->m_data + len > &n->m_dat[MLEN]) {	    /* not enough space: must realign buffer start */	    bcopy (n->m_data, n->m_dat, n->m_len);	    n->m_data = n->m_dat;	}    }    else {	/* external cluster (must be only user) */	if (mclrefcnt[mtocl(n->m_data)] != 1) {	    log (LOG_NOTICE, "snpullup: shared ext cluster\n");	    goto bad;	}	if (n->m_data + len > n->m_ext.ext_buf + n->m_ext.ext_size) {	    /* not enough space: must realign cluster start */#ifdef DEBUG	    if (len <= n->m_ext.ext_size) {		log (LOG_NOTICE, "snpullup: ext buf too small (%d < %d)\n",		     n->m_ext.ext_size, len);		goto bad;	    }#endif	    bcopy (n->m_data, n->m_ext.ext_buf, n->m_len);	    n->m_data = n->m_ext.ext_buf;	}    }    /* now ok to append in place */    m = n;    n = n->m_next;    len -= m->m_len;    while (len > 0 && n) {	count = MIN(len, n->m_len);	bcopy(mtod(n, caddr_t), mtod(m, caddr_t)+m->m_len, (unsigned)count);	len -= count;	m->m_len += count;	n->m_len -= count;	if (n->m_len)	  n->m_data += count;	else	  n = n->m_next;    }    return (m); bad:    m_freem(n);    return (0);}/* * Fillup a whole chain, so that each mbuf has a sensible minimum * length, to avoid transmit underflows. */static struct mbuf *sn_fillup (m, minlen)    register struct mbuf *m;    register int minlen;{    struct mbuf *m0 = 0;    register struct mbuf *mprev = (struct mbuf *)&m0;    while (m) {	if (m->m_len && m->m_len < minlen && m->m_next)	  m = sn_pullup (m, minlen);	mprev->m_next = m;	mprev = m;	m = m->m_next;    }    return m0;}#ifdef MIPSELstatic voidsnswapb (s, d, len)    u_char *s, *d;    int len;{    while (len > 0) {	*(unsigned int *)d = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];	d += 4;	s += 4;	len -= 4;    }}static struct mbuf *snswapm (m0)    struct mbuf *m0;{    struct mbuf *m;    caddr_t s;    for (m = m0; m; m = m->m_next) {	if ((m->m_flags & M_EXT) && mclrefcnt[mtocl(m->m_data)] != 1)	    /* external cluster (must be only user) */	    panic ("snswapm: shared ext cluster");	s = m->m_data;	if ((unsigned)s & 3) {	    /* buffer is unaligned: must align data in buffer */	    caddr_t dat, d;	    unsigned int msz;	    	    /* determine data buffer base and size */	    if (m->m_flags & M_EXT) {		dat = m->m_ext.ext_buf;		msz = m->m_ext.ext_size;	    } else if (m->m_flags & M_PKTHDR) {		dat = m->m_pktdat;		msz = MHLEN;	    } else {		dat = m->m_dat;		msz = MLEN;	    }	    /* round buffer base up to word boundary */	    d = (caddr_t) (((unsigned long)dat + 3) & ~3);	    /* can we shuffle the data down to start of buffer? */	    if (m->m_data > d)		m->m_data = d;	    else {		/* is there room after the current data? */		d = (caddr_t) (((unsigned long)m->m_data + m->m_len + 3) & ~3);		if (d + ((m->m_len + 3) & ~3) <= dat + msz)		    m->m_data = d;		else		    /* this shouldn't happen!! */		    panic ("snswapm");	    }	}	snswapb (s, m->m_data, m->m_len);    }    return m0;}#endif#ifdef XDSSONICBUG/* * compress buffer in SRAM after it has been received */static voidxds_compress_buffer (caddr_t addr, int len){    int words = (len + 3) >> 2;    unsigned int *sp, *dp;    /* ASSERT(IS_K1SEG(addr)); *//* printf ("xdr_compress_buffer (0x%08x, 0x%x)\n", addr, len); */    sp = dp = (unsigned int *)addr;    while (words-- > 0) {	*dp = *sp;	dp += 1;	sp += 2;    }#ifdef notdef    {	unsigned int *w;	int i;	w = (unsigned int *)addr;	words = (len + 3) >> 2;	for (i = 0; i < words; i++) {	    printf ("%04x ", w[i]);	    if ((i & 3) == 3)		printf ("\n");	}	if ((words & 3) != 0)	    printf ("\n");    }    #endif}/* * expand buffer in SRAM before it is sent */static voidxds_expand_buffer (caddr_t addr, int len){    int words = (len + 3) >> 2;    unsigned int *sp, *dp;    /* ASSERT(IS_K1SEG(addr)); *//* printf ("xds_expand_buffer (0x%08x, %d)\n", addr, len); */    sp = (unsigned int *)addr + words;    dp = sp + words;    while (words-- >= 0) {	*dp = *sp;	*(dp+1) = 0xdeaddead;	sp -= 1;	dp -= 2;    }}#endif#ifdef XDSstatic voidcopy_host_to_data (caddr_t sp, caddr_t dp, int len){    unsigned int *wp;    unsigned int w;    unsigned int soffset, doffset;    int shift;    soffset = (unsigned int)sp & 3;    doffset = (unsigned int)dp & 3;    if (doffset) {	/* first align dp */	wp = (unsigned int *)PHYS_TO_K1((unsigned int)dp & ~3);	w = *wp;	for (shift = 24 - 8*doffset; shift >= 0; shift -= 8) {	    w = (w & ~(0xff << shift)) | (*(unsigned char *)sp << shift);	    dp++;	    sp++;	    len--;	    if (len <= 0) {		*wp = w;		return;	    }			}	*wp = w;    }    if (soffset == doffset) {	/* read a word, write a word */	while (len >= 4) {	    *(unsigned int *)dp = *(unsigned int *)sp;	    sp += 4;	    dp += 4;	    len -= 4;	}    }    else {	/* read 4 bytes, write a word */	while (len >= 4) {	    w =  *(unsigned char *)(sp+0) << 24;	    w |= *(unsigned char *)(sp+1) << 16;	    w |= *(unsigned char *)(sp+2) <<  8;	    w |= *(unsigned char *)(sp+3);	    *(unsigned int *)dp = w;	    sp += 4;	    dp += 4;	    len -= 4;	}    }    if (len == 0)	return;    /* transfer last few bytes */    wp = (unsigned int *)dp;    w = *wp;    for (shift = 24; len > 0; shift -= 8) {	w = (w & ~(0xff << shift)) | (*(unsigned char *)sp << shift);	sp++;	dp++;	len--;    }    *wp = w;}static voidcopy_data_to_host (caddr_t sp, caddr_t dp, int len){    unsigned int *wp, w;    unsigned int soffset, doffset;    int shift;    soffset = (unsigned int)sp & 3;    doffset = (unsigned int)dp & 3;    if (soffset) {	/* first align sp */	w = *(unsigned int *)((unsigned int)sp & ~3);	for (shift = 24 - 8*soffset; shift >= 0; shift -= 8) {	    *dp = w >> shift;	    dp++;	    sp++;	    len--;	    if (len <= 0)		return;	}    }    if (soffset == doffset) {	/* read a word, write a word */	while (len >= 4) {	    *(unsigned int *)dp = *(unsigned int *)sp;	    sp += 4;	    dp += 4;	    len -= 4;	}    }    else {	/* read a word, write 4 bytes */	while (len >= 4) {	    w = *(unsigned int *)sp;	    *(unsigned char *)(dp+0) = w >> 24;	    *(unsigned char *)(dp+1) = w >> 16;	    *(unsigned char *)(dp+2) = w >> 8;	    *(unsigned char *)(dp+3) = w;	    sp += 4;	    dp += 4;	    len -= 4;	}    }    if (len == 0)	return;    /* transfer last few bytes */    w = *(unsigned int *)sp;    for (shift = 24; len > 0; shift -= 8) {	*dp = w >> shift;	sp++;	dp++;	len--;    }}#endif

⌨️ 快捷键说明

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