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

📄 main.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/* $Id: main.c,v 1.22 2003/08/30 14:55:57 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. * *  This code was created from code released to Public Domain *  by LSI Logic and Algorithmics UK. */ #include <stdio.h>#include <termio.h>#include <endian.h>#include <string.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <unistd.h>#include <stdlib.h>#ifdef _KERNEL#undef _KERNEL#include <sys/ioctl.h>#define _KERNEL#else#include <sys/ioctl.h>#endif#include <pmon.h>#include <exec.h>#include <file.h>#include "mod_debugger.h"#include "mod_symbols.h"#include "sd.h"#include "wd.h"extern void    *callvec;#include "cmd_hist.h"		/* Test if command history selected */#include "cmd_more.h"		/* Test if more command is selected */jmp_buf         jmpb;		/* non-local goto jump buffer */char            line[LINESZ + 1];	/* input line */struct termio	clntterm;	/* client terminal mode */struct termio	consterm;	/* console terminal mode */register_t	initial_sr;char            prnbuf[LINESZ + 8];	/* commonly used print buffer */int             repeating_cmd;unsigned int  	moresz = 10;static void autorun(char *);extern void __init(void);extern void _exit (int retval);extern void delay(int);#ifdef INETstatic voidpmon_intr (int dummy){    sigsetmask (0);    longjmp (jmpb, 1);}#endifFILE *logfp = stdout; #if NCMD_HIST == 0voidget_line(char *line, int how){	int i;	i = read (STDIN, line, LINESZ);	if(i > 0) {		i--;	}	line[i] = '\0';}#endif/* *  Main interactive command loop *  ----------------------------- * *  Clean up removing breakpoints etc and enter main command loop. *  Read commands from the keyboard and execute. When executing a *  command this is where <crtl-c> takes us back. */intpmon_main(){	char prompt[32];	if (setjmp(jmpb)) {		/* Bailing out, restore */		closelst(0);		ioctl(STDIN, TCSETAF, &consterm);		printf(" break!\r\n");	}#ifdef INET	signal (SIGINT, pmon_intr);#else	ioctl (STDIN, SETINTR, jmpb);#endif#if NMOD_DEBUGGER > 0	rm_bpts();#endif        	md_setsr(NULL, initial_sr);	/* XXX does this belong here? */	while(1) {		strncpy (prompt, getenv ("prompt"), sizeof(prompt));#if NCMD_HIST > 0		if (strchr(prompt, '!') != 0) {			char tmp[8], *p;			p = strchr(prompt, '!');			strdchr(p);	/* delete the bang */			sprintf(tmp, "%d", histno);			stristr(p, tmp);		}#endif		printf("%s", prompt);#if NCMD_HIST > 0		get_cmd(line);#else		get_line(line, 0);#endif		do_cmd(line);		console_state(1);	}	return(0);}/* *  Handle autoboot execution *  ------------------------- * *  Autoboot variable set. Countdown bootdelay to allow manual *  intervention. If CR is pressed skip counting. If var bootdelay *  is set use the value othervise default to 15 seconds. */static voidautorun(char *s){	char buf[LINESZ];	char *d;	unsigned int dly, lastt;	unsigned int cnt;	struct termio sav;	if(s != NULL  && strlen(s) != 0) {		d = getenv ("bootdelay");		if(!d || !atob (&dly, d, 10) || dly < 0 || dly > 99) {			dly = 15;		}		SBD_DISPLAY ("AUTO", CHKPNT_AUTO);		printf("Autoboot command: \"%.60s\"\n", s);		printf("Press <Enter> to execute or any other key to abort.\n");		ioctl (STDIN, CBREAK, &sav);		lastt = 0;		dly++;		do {#if defined(HAVE_TOD) && defined(DELAY_INACURATE)			time_t t;			t = tgt_gettime ();			if(t != lastt) {				printf ("\r%2d", --dly);				lastt = t;			}#else			delay(1000000);			printf ("\r%2d", --dly);#endif			ioctl (STDIN, FIONREAD, &cnt);		} while (dly != 0 && cnt == 0);		if(cnt > 0 && strchr("\n\r", getchar())) {			cnt = 0;		}		ioctl (STDIN, TCSETAF, &sav);		putchar ('\n');		if(cnt == 0) {			strcpy (buf, s);			do_cmd (buf);		}	}}/* *  PMON2000 entrypoint. Called after initial setup. */voiddbginit (char *adr){	int	memsize, freq;	char	fs[10], *fp;	char	*s;/*	splhigh();*/	memsize = totalmemsize;	if (!kmemtop)		kmemtop = (void *)memsize;	__init();	/* Do all constructor initialisation */	SBD_DISPLAY ("ENVI", CHKPNT_ENVI);	envinit ();#if defined(SMP)	/* Turn on caches unless opted out */	if (!getenv("nocache"))		md_cacheon();#endif	SBD_DISPLAY ("SBDD", CHKPNT_SBDD);	tgt_devinit();#ifdef INET	SBD_DISPLAY ("NETI", CHKPNT_NETI);	init_net (1);#endif#if NCMD_HIST > 0	SBD_DISPLAY ("HSTI", CHKPNT_HSTI);	histinit ();#endif#if NMOD_SYMBOLS > 0	SBD_DISPLAY ("SYMI", CHKPNT_SYMI);	syminit ();#endif#ifdef DEMO	SBD_DISPLAY ("DEMO", CHKPNT_DEMO);	demoinit ();#endif	SBD_DISPLAY ("SBDE", CHKPNT_SBDE);	initial_sr |= tgt_enable (tgt_getmachtype ());#ifdef SR_FR	Status = initial_sr & ~SR_FR; /* don't confuse naive clients */#endif	/* Set up initial console terminal state */	ioctl(STDIN, TCGETA, &consterm);	tgt_logo();	printf ("\nConfiguration [%s,%s", TARGETNAME,			BYTE_ORDER == BIG_ENDIAN ? "EB" : "EL");#ifdef SMP	printf (",SMP");#endif#ifdef INET	printf (",NET");#endif#if NSD > 0	printf (",SCSI");#endif#if NWD > 0	printf (",IDE");#endif	printf ("]\nVersion: %s.\n", vers);	printf ("Supported loaders [%s]\n", getExecString());	printf ("Supported filesystems [%s]\n", getFSString());	printf ("This software may be redistributed under the BSD copyright.\n");	tgt_machprint();	freq = tgt_pipefreq ();	sprintf(fs, "%d", freq);	fp = fs + strlen(fs) - 6;	fp[3] = '\0';	fp[2] = fp[1];	fp[1] = fp[0];	fp[0] = '.';	printf (" %s MHz", fs);	freq = tgt_cpufreq ();	sprintf(fs, "%d", freq);	fp = fs + strlen(fs) - 6;	fp[3] = '\0';	fp[2] = fp[1];	fp[1] = fp[0];	fp[0] = '.';	printf (" / Bus @ %s MHz\n", fs);	printf ("Memory size %3d MB.\n", memsize / (1024 * 1024));	tgt_memprint();#if defined(SMP)	tgt_smpstartup();#endif	printf ("\n");	md_clreg(NULL);	md_setpc(NULL, (int32_t) CLIENTPC);	md_setsp(NULL, tgt_clienttos ());	s = getenv ("autoboot");	autorun (s);}/* *  closelst(lst) -- Handle client state opens and terminal state. */voidcloselst(int lst){	switch (lst) {	case 0:		/* XXX Close all LU's opened by client */		break;	case 1:		break;	case 2:		/* reset client terminal state to consterm value */		clntterm = consterm;		break;	}}/* *  console_state(lst) -- switches between PMON2000 and client tty setting. */voidconsole_state(int lst){	switch (lst) {	case 1:		/* save client terminal state and set PMON default */		ioctl (STDIN, TCGETA, &clntterm);		ioctl (STDIN, TCSETAW, &consterm);		break;	case 2:		/* restore client terminal state */		ioctl (STDIN, TCSETAF, &clntterm);		break;	}}/************************************************************* *  dotik(rate,use_ret) */voiddotik (rate, use_ret)	int             rate, use_ret;{static	int             tik_cnt;static	const char      more_tiks[] = "|/-\\";static	const char     *more_tik;	tik_cnt -= rate;	if (tik_cnt > 0) {		return;	}	tik_cnt = 256000;	if (more_tik == 0) {		more_tik = more_tiks;	}	if (*more_tik == 0) {		more_tik = more_tiks;	}	if (use_ret) {		printf (" %c\r", *more_tik);	} else {		printf ("\b%c", *more_tik);	}	more_tik++;}#if NCMD_MORE == 0/* *  Allow usage of more printout even if more is not compiled in. */intmore (p, cnt, size)     char           *p;     int            *cnt, size;{ 	printf("%s\n", p);	return(0);}#endif/* *  Non direct command placeholder. Give info to user. */int no_cmd(ac, av)     int ac;     char *av[];{    printf("Not a direct command! Use 'h %s' for more information.\n", av[0]);    return (1);}/* *  Build argument area on 'clientstack' and set up clients *  argument registers in preparation for 'launch'. *  arg1 = argc, arg2 = argv, arg3 = envp, arg4 = callvector */voidinitstack (ac, av, addenv)    int ac;    char **av;    int addenv;{	char	**vsp, *ssp;	int	ec, stringlen, vectorlen, stacklen, i;	register_t nsp;	/*	 *  Calculate the amount of stack space needed to build args.	 */	stringlen = 0;	for (i = 0; i < ac; i++) {		stringlen += strlen(av[i]) + 1;	}	if (addenv) {		envsize (&ec, &stringlen);	}	else {		ec = 0;	}	stringlen = (stringlen + 3) & ~3;	/* Round to words */	vectorlen = (ac + ec + 2) * sizeof (char *);	stacklen = ((vectorlen + stringlen) + 7) & ~7;	/*	 *  Allocate stack and us md code to set args.	 */	nsp = md_adjstack(NULL, 0) - stacklen;	md_setargs(NULL, ac, nsp, nsp + (ac + 1) * sizeof(char *), (int)callvec);	/* put $sp below vectors, leaving 32 byte argsave */	md_adjstack(NULL, nsp - 32);	memset((void *)((int)nsp - 32), 0, 32);	/*	 * Build argument vector and strings on stack.	 * Vectors start at nsp; strings after vectors.	 */	vsp = (char **)(int)nsp;	ssp = (char *)((int)nsp + vectorlen);	for (i = 0; i < ac; i++) {		*vsp++ = ssp;		strcpy (ssp, av[i]);		ssp += strlen(av[i]) + 1;	}	*vsp++ = (char *)0;	/* build environment vector on stack */	if (ec) {		envbuild (vsp, ssp);	}	else {		*vsp++ = (char *)0;	}	/*	 * Finally set the link register to catch returning programs.	 */	md_setlr(NULL, (register_t)_exit);}

⌨️ 快捷键说明

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