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

📄 loadfn.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/* $Id: loadfn.c,v 1.9 2002/11/07 12:48:41 pefo Exp $ *//* * Copyright (c) 2001-2002 Opsycon AB  (www.opsycon.se / www.opsycon.com) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//* * S3 & LSI support functions */#include <stdio.h>#include <string.h>#include <pmon.h>#include "loadfn.h"#include "mod_debugger.h"#include "mod_load.h"#include "mod_symbols.h"static const char *dlerrs[] = {    "continue(!)",		/* DL_CONT */    "done(!)",			/* DL_DONE */    "bad char",			/* DL_BADCHAR */    "bad length",		/* DL_BADLEN */    "bad type",			/* DL_BADTYPE */    "bad checksum",		/* DL_BADSUM */    "out of symbol space",	/* DL_NOSYMSPACE */    "bad load address",		/* DL_BADADDR */    "i/o error"			/* DL_IOERR */};#define NERRS	(sizeof(dlerrs)/sizeof(dlerrs[0]))long	dl_entry;	/* entry address */long	dl_offset;	/* load offset */long	dl_minaddr;	/* minimum modified address */long	dl_maxaddr;	/* maximum modified address */int	dl_chksum;char const *dl_err (int code){    if (code >= DL_MAX)	return "unknown";    return dlerrs[code];}static __inline int overlap __P((u_long, u_long, u_long, u_long));static __inline intoverlap (as, ae, bs, be)    unsigned long as, ae, bs, be;{    return (ae > bs && be > as);}/* *  Check that virtual address is valid load range and set limits. */int dl_checksetloadaddr (void *vaddr, int size, int verbose){	unsigned long addr = (unsigned long)vaddr;	if (!dl_checkloadaddr(vaddr, size, verbose))		return (0);	if (addr < dl_minaddr)		dl_minaddr = addr;	if (addr + size > dl_maxaddr)		dl_maxaddr = addr + size;	return 1;}/* *  Check that virtual address is valid load range, don't  set limits. */int dl_checkloadaddr (void *vaddr, int size, int verbose){	unsigned long addr = (unsigned long)vaddr;	if (md_valid_load_addr(addr, addr + size)) {		if (verbose)			printf ("\nattempt to load into mappable region");		return 0;	}	return 1;}voiddl_initialise (unsigned long offset, int flags){#if NMOD_SYMBOLS > 0    if (!(flags & SFLAG))	clrsyms ();#endif#if NMOD_DEBUGGER > 0    if (!(flags & BFLAG))	clrbpts ();#endif    if (!(flags & EFLAG))	clrhndlrs ();    dl_minaddr = ~0;    dl_maxaddr = 0;    dl_chksum = 0;    dl_offset = offset;}#if NMOD_SYMBOLS > 0voiddl_setloadsyms (void){    defsyms (dl_minaddr, dl_maxaddr, (u_int32_t)md_getpc(NULL));}#endif#if NMOD_FASTLOAD > 0/* *  LSI Fastload format. */#define __ 64static const unsigned char etob[128] = {	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	__,	62,	__,	63,	__,	52,	53,	54,	55,	56,	57,	58,	59,	60,	61,	__,	__,	__,	__,	__,	__,	__,	0,	1,	2,	3,	4,	5,	6,	7,	8,	9,	10,	11,	12,	13,	14,	15,	16,	17,	18,	19,	20,	21,	22,	23,	24,	25,	__,	__,	__,	__,	__,	__,	26,	27,	28,	29,	30,	31,	32,	33,	34,	35,	36,	37,	38,	39,	40,	41,	42,	43,	44,	45,	46,	47,	48,	49,	50,	51,	__,	__,	__,	__,	__};#undef __long   		nextaddr;int             blkinx = 0;int             blksz = 0;/* *  getb64(vp,p,n) *      get a number of base-64 digits *      if n < 0 then don't add value to chksum. */static intgetb64 (unsigned long *vp, char *p, int n){    unsigned long   v, b;    unsigned i;    v = 0;    for (i = ((n < 0) ? 0 - n : n); i != 0; i--) {	b = etob[*p++ & 0x7f];	if (b == 64) {	    *vp = 0;	    return (0);	}	v = (v << 6) | b;    }    /* update 12 bit checksum */    switch (n) {    case 6:	dl_chksum += (v >> 24) & 0xfff;    case 4:	dl_chksum += (v >> 12) & 0xfff;    case 2:	dl_chksum += v & 0xfff;    }    *vp = v;    return (1);}/* *  getrec(p,curblk) *      get the next 4-byte record (if there's any left) */static __inline char *getrec __P((char *));static __inline char *getrec (curblk)     char           *curblk;{    char *p;    if (blkinx >= blksz)	return (0);    p = &curblk[blkinx];    blkinx += 4;    return (p);}/* *  dl_fastload(recbuf,offset,plen,flags) *      load a fast-mode record */intdl_fastload (char *recbuf, int recsize, int *plen, int flags){    char	    *rp;    int             i, len, s;#if NMOD_SYMBOLS > 0    int             j, c;    char            name[LINESZ];#endif    unsigned long   bdat, zcnt;    long   	    addr;    *plen = 0;    if (recsize % 4 != 0)	return (DL_BADLEN);    blksz = recsize;    blkinx = 0;    s = DL_CONT;    for (len = 0;;) {	if (!(rp = getrec (recbuf)))	    break;	if (rp[0] == '/') {	    switch (rp[1]) {	    case 'K':		/* klear checksum (sic) */		dl_chksum = 0;		break;	    case 'C':		/* compare checksum */		if (!getb64 (&zcnt, &rp[2], -2))		    return (DL_BADCHAR);		dl_chksum &= 0xfff;		if (!(flags & IFLAG) && zcnt != dl_chksum)		    return (DL_BADSUM);		dl_chksum = 0;		break;	    case 'Z':		/* zero fill */		if (!getb64 (&zcnt, &rp[2], 2))		    return (DL_BADCHAR);		zcnt *= 3;		if (flags & YFLAG) { /* symbols only? */		    nextaddr += zcnt;		    break;		}		if (!dl_checksetloadaddr ((void *)nextaddr, zcnt, flags & VFLAG))		    return (DL_BADADDR);		len += zcnt;		while (zcnt--)		    store_byte ((void *)(nextaddr++), 0);		break;	    case 'B':		/* byte */		if (!getb64 (&bdat, &rp[2], 2))		    return (DL_BADCHAR);		if (flags & YFLAG) { /* symbols only? */		    nextaddr++;		    break;		}		if (!dl_checksetloadaddr ((void *)nextaddr, 1, flags & VFLAG))		    return (DL_BADADDR);		store_byte ((void *)(nextaddr++), bdat);		len++;		break;	    case 'A':		/* address */		if (!getrec (recbuf)) /* get another 4 bytes */		    return (DL_BADLEN);		if (!getb64 (&addr, &rp[2], 6))		    return (DL_BADCHAR);#if 0 /*XXX Algor special format... */		if ((flags & TFLAG) && Gpr[R_A3] == 0) {		    memorysize -= addr;		    Gpr[R_SP] = clienttos ();		    nextaddr = memorysize + K0BASE;		    Gpr[R_A3] = nextaddr;		} else#endif		    nextaddr = addr + dl_offset;		break;	    case 'E':		/* end */		dl_entry = nextaddr;		s = DL_DONE;		break;#if NMOD_SYMBOLS > 0	    case 'S':		/* symbol */		i = 2; j = 0;		while (1) {		    c = rp[i++];		    /* dl_chksum += c; */		    if (c == ',')			break;		    name[j++] = c;		    if (i >= 4) {			if (!(rp = getrec (recbuf)))			    return (DL_BADLEN);			i = 0;		    }		}		name[j] = '\0';		if (flags & NFLAG) /* no symbols? */		    break;		if (!newsym (name, nextaddr))		    return (DL_NOSYMSPACE);		break;#endif /* NMOD_SYMBOLS */	    default:		return (DL_BADTYPE);	    }	} else {		/* 24 bits of data */	    if (!getb64 (&bdat, rp, 4))		return (DL_BADLEN);	    if (flags & YFLAG) {	/* symbols only? */		nextaddr += 3;		break;	    }	    if (!dl_checksetloadaddr ((void *)nextaddr, 3, flags & VFLAG))		return (DL_BADADDR);	    for (i = 16; i >= 0; i -= 8) {		store_byte ((void *)(nextaddr++), bdat >> i);	    }	    len += 3;	}    }    *plen = len;    return (s);}#endif /* NMOD_FASTLOAD */

⌨️ 快捷键说明

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