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

📄 machdep.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	$Id: machdep.c,v 1.14 2003/08/10 11:15:24 pefo Exp $ *//* * Copyright (c) 2000 Opsycon AB  (http://www.opsycon.se) *  * 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 Open System Consulting 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. * *//* * Pmon architecture dependent (and possibly cpu type dependent) code. */#include <stdio.h>#include <termio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <errno.h>#ifdef _KERNEL#undef _KERNEL#include <sys/ioctl.h>#define _KERNEL#else#include <sys/ioctl.h>#endif#include <machine/cpu.h>#include <machine/pte.h>#include <machine/frame.h>#include <machine/regnum.h>#include <machine/trap.h>#include <pmon.h>extern int errno;extern u_int8_t end[];extern void CPU_GetTLB(int, struct tlbdata *);/* *  CPU type markers. */#define CPU_ALL	0x0003		/* Belongs to mask */#define	CPU_7	0x0001		/* RM7000 */#define	CPU_5	0x0002		/* R5000 */#define	CPU_41	0x0004		/* R4100 */#define	F_FMT	0x1000		/* Field uses format */struct RegMap {	char	width;	char	bit;	short	flags;	const char * const name;	union {		const char * const fmt;/* XXX Tell me why i must cast initializers for the next union? */		const char * const *vn;	} fe;};int md_tlb(int, char **);static void dsp_rregs __P((int *));static void dsp_fregs __P((int *));static int cputype;/* *  Special trap handlers. */register_t on_bus_error;register_t on_acc_error;u_int64_t  on_acc_data;/* *  Return a ascii version of the processor type. */const char *md_cpuname(){/* XXX make more sophisticated dealing with rev numbers and 52x0 more precisely */	/* Handle the SandCraft SR71000 */	if (((md_cputype() >> 8) & 0xffff) == 0x0504) {		cputype = CPU_7;		return ("SR71000");	}	/* Handle the BCM2150 */	if (((md_cputype() >> 8) & 0xffff) == 0x0401) {		cputype = CPU_7;		return ("BCM1250");	}	switch((md_cputype() >> 8) & 0xff) {	case MIPS_E9000:		cputype = CPU_7;		return("E9000");	case MIPS_RM7000:		cputype = CPU_7;		return("RM7000");	case MIPS_RM52X0:		cputype = CPU_5;		return("RM52x0");	default:		return("unidentified");	}}/* *  Check for any special exception handling. */intmd_check_exception_handler(struct trapframe *frame){	switch((frame->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) {        case T_BUS_ERR_LD_ST:		if (on_bus_error != 0) {			md_setpc(frame, on_bus_error);			on_bus_error = 0;			return 1;		}	case T_TLB_LD_MISS:	case T_ADDR_ERR_LD:	case T_ADDR_ERR_ST:		if (on_acc_error != 0) {			md_setpc(frame, on_acc_error);			on_acc_error = 0;			return 1;		}		break;	default:		break;	}	return 0;}/* *  Dump out exception info for an unscheduled exception */voidmd_dumpexc(struct trapframe *tf){	int w = 100;        printf("\r\nException Cause=%s, SR=%p, PC=%p\r\n",                md_getexcname(tf), (int)md_getsr(tf), md_getpc(tf));	printf("CONTEXT=%llp, XCONTEXT=%llp\r\n", tf->context, tf->xcontext);	printf("BADVADDR=%llp, ENTHI=%llp\r\n", tf->badvaddr, tf->enthi);	printf("ENTLO0=%llp, ENTLO1=%llp\r\n\r\n", tf->entlo0, tf->entlo1);	dsp_rregs(&w);	printf("\r\n");	md_do_stacktrace(0, 0, 0, 0);}/* *  Set PC to a new value. */voidmd_setpc(struct trapframe *tf, register_t pc){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->pc = pc;}/* *  This function clears all client registers for launch. */voidmd_clreg(struct trapframe *tf){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	md_fpsave(tf);}/* *  This function sets the client stack pointer. */voidmd_setsp(struct trapframe *tf, register_t sp){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->sp = sp;}/* *  This function sets the client sr to the given value. */voidmd_setsr(struct trapframe *tf, register_t sr){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->sr = sr;}/* *  This function returns the value of the clients sr. */register_tmd_getsr(struct trapframe *tf){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	return(tf->sr);}/* *  This function sets the client sr to do a trace. */voidmd_settrace(){}/* *  This function sets the client sr to do a trace. */voidmd_setlr(struct trapframe *tf, register_t lr){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->ra = lr;}/* *  This function returns true if the address range given is *  invalid for load, eg will overwrite PMON or its working *  areas or other protected memory areas or load into *  existing memory. */intmd_valid_load_addr(first_addr, last_addr)	paddr_t first_addr;	paddr_t last_addr;{/* XXX This needs to be reworked!!! */#if 0	first_addr = CACHED_TO_PHYS(first_addr);	last_addr = CACHED_TO_PHYS(last_addr);	if((first_addr < (paddr_t)CACHED_TO_PHYS(end)) ||	   (last_addr > (paddr_t)memtop)) {		return(1);	}#endif	return(0);} /* *  This function sets the SP to the new value given if it's *  non zero. The old value of sp is returned. */register_tmd_adjstack(struct trapframe *tf, register_t newsp){	register_t oldsp;	if (tf == NULL)		tf = cpuinfotab[whatcpu];	oldsp = tf->sp;	if(newsp != 0) {		tf->sp = newsp;	}	return(oldsp);}/* *  This function sets the arguments to client code so *  the client sees the arguments as if it was called *  with the arguments. */voidmd_setargs(struct trapframe *tf, register_t a1, register_t a2,		register_t a3, register_t a4){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->a0 = a1;	tf->a1 = a2;	tf->a2 = a3;	tf->a3 = a4;}voidmd_setentry(struct trapframe *tf, register_t pc){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	tf->pc = pc;}/* *  This function returns the PC value that is supposed *  to be used at restore to client state. Do not confuse *  with the value of the exception PC. (Diff on some arches). */void *md_getpc(struct trapframe *tf){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	return((void *)(int)tf->pc);}/* *  This function is called from exception(). It's purpose *  is to decode the exception and return the exception *  type to the caller for further processing. */intmd_exc_type(struct trapframe *frame){	switch((frame->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) {	case T_BREAK:	case T_TRAP:		return(EXC_BPT);	case T_IWATCH:	case T_DWATCH:		return(EXC_WTCH);	case T_INT:	case T_TLB_MOD:	case T_TLB_LD_MISS:	case T_TLB_ST_MISS:	case T_ADDR_ERR_LD:	case T_ADDR_ERR_ST:	case T_BUS_ERR_IFETCH:	case T_BUS_ERR_LD_ST:	case T_SYSCALL:	case T_RES_INST:	case T_COP_UNUSABLE:	case T_OVFLOW:	case T_FPE:		return(EXC_BAD);	case T_VCEI:	case T_VCED:		return(EXC_BAD);	}	return(EXC_BAD);}/* *  This function returns the value of the RA reg */register_tmd_getlink(struct trapframe *tf){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	return(tf->ra);}/* *  This function returns a pointer from the value of the *  PC reg when an exception have been taken. */void *md_get_excpc(struct trapframe *tf){	if (tf == NULL)		tf = cpuinfotab[whatcpu];	return((void *)(int)tf->pc);}const char *md_getexcname(struct trapframe *tf){	switch((tf->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) {	case T_INT:		return("interrupt pending");

⌨️ 快捷键说明

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