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

📄 machdep.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ident "@(#)machdep.c	1.1 7/30/92"/* * Copyright (c) 1990 by Sun Microsystems, Inc. */#include <sys/param.h>#include <sys/errno.h>#include <sys/vmmac.h>#include <sun/openprom.h>#include <machine/buserr.h>#include <machine/mmu.h>#include <machine/cpu.h>#include <machine/pte.h>#include <machine/enable.h>#include <machine/scb.h>#include <machine/psl.h>#include <machine/trap.h>#include <machine/clock.h>#include <machine/intreg.h>#include <machine/eeprom.h>#include <machine/asm_linkage.h>#include <machine/reg.h>#include <machine/frame.h>#include <machine/vm_hat.h>#include "allregs.h"#include "../../debug/debug.h"#include <debug/debugger.h>extern int errno;int istrap = 0;int scbsyncdone = 0;/* * The next group of variables and routines handle the * Open Boot Prom devinfo or property information. * * These machine-dependent quantities are set from the prom properties. * For the time being, set these to "large, safe" values. * XXX - does this all want to be packaged in a header file? */extern void fiximp();extern	int print_cpu_done;/* * properties tchotchkes */#define GETPROPLEN	prom_getproplen#define GETPROP		prom_getprop#define NEXT		prom_nextnode#define CHILD		prom_childnodeextern int getprop();int debug_props = 0;		/* Turn on to enable debugging message */#ifdef	MULTIPROCESSOR#define	CPUTOMID(x)	((x) | 0x8)#define	MIDTOCPU(x)	((x) & 0x3)int cpus_enabled[NCPU];#ifdef	PROM_IDLECPUS_WORKSextern int prom_idlecpu();extern int prom_resumecpu();unsigned cpus_nodeid[NCPU];#endif	/* PROM_IDLECPUS_WORKS */#endif	MULTIPROCESSOR/* * Open proms give us romp as a variable */struct sunromvec *romp = (struct sunromvec *)0xFFE81000;int fake_bpt;			/* place for a fake breakpoint at startup */jmp_buf debugregs;		/* context for debugger */jmp_buf mainregs;		/* context for debuggee */jmp_buf_ptr curregs;		/* pointer to saved context for each process */struct allregs regsave; 	/* temp save area--align to double */struct scb *mon_tbr, *our_tbr;	/* storage for %tbr's */int use_kern_tbr = 0;extern char start[], estack[], etext[], edata[], end[];extern int exit();extern struct scb *gettbr();extern int cache;/* * Definitions for registers in jmp_buf */#define	JB_PC	0#define	JB_SP	1#define	CALL(func)	(*(int (*)())((int)(func) - (int)start + (int)real))#define	RELOC(adr)	((adr) - (char *)start + real)extern setcontext(), getsegmap(), setsegmap(), getpgmap(), setpgmap();void Setpgmap();/* * get_rom_l2_ptr: *  return the physical address in the current context of the pte  *  that would map virtual address 'vaddr' for 'size' bytes.  *  We are only setup to use level-2 (256KB) mappings. If a level-0 *  or level-1 mapping already exists then do not need to do anything. */#define UPTPE_NULL (union ptpe *)NULLunion ptpe *get_l2_ptr(vaddr)u_int vaddr;{	union ptpe ct, rp, l1;		ct.ptpe_int = mmu_getctp();	rp.ptpe_int = ldphys(ct.ptp.PageTablePointer << MMU_STD_PTPSHIFT);		switch (rp.ptp.EntryType) {			      case MMU_ET_PTE: /* pte in context table */		return (UPTPE_NULL);			      case MMU_ET_PTP: /* ptp in context table */		l1.ptpe_int = 			ldphys((rp.ptp.PageTablePointer << MMU_STD_PTPSHIFT) |				     MMU_L1_INDEX(vaddr) << 2);				switch (l1.ptp.EntryType) {					      case MMU_ET_PTE: /* pte in level-1 table */			return (UPTPE_NULL);					      case MMU_ET_PTP: /* ptp in level-1 table */			return ((union ptpe *)((l1.ptp.PageTablePointer <<				MMU_STD_PTPSHIFT) |				MMU_L2_INDEX(vaddr) << 2));		}	}}/* * This routine is called before we are relocated to the correct address, * so everything is done via funny macros when dealing w/ globals. * Also, we have a candidate for "worst abuse of preprocessor" award: * MONSTART and MONEND are actually defined using romp, but _romp * isn't set yet.  Call our sunromvec argument "romp" so that the global * variable is hidden in this function and the correct value is used. */early_startup(real, romp)	register char *real;	register struct sunromvec *romp;{	register u_int cnt, i;	register int *from, *to;	register int lastpmsav, lastpgsav;	caddr_t	 vstart;	int too_big = 0;	/* number of level-3 tables required by the debugger */#define NDBGL3PTS (mmu_btop(DEBUGSIZE)/MMU_NPTE_THREE)	/*(void) CALL(setcontext)(0); - remove? */	/*	 * Find the top of physical memory and take as many pages as we need.	 * We assume the physmem chunks are in ascending order and the last	 * chunk is big enough to hold us. (It actually doesn't matter if	 * the pages are in order; we handle that gracefully.) We reserve	 * an extra page for our own level-3 page tables. We can't use level-2	 * page tables since that would require us to be 256KB aligned which	 * could be more wasteful of memory than just grabbing a page here.	 *	 * It seems that in allocating the extra page for the level-3 	 * page tables we run into a problem with the PROM virtual address	 * allocation with sbrk.  Do we need this extra page here???	 * Right now have worked around in sbrk.	 * Cant call sbrk here, so if need page, need workaround.	 */	cnt = mmu_btopr(end - start) + 1;	/* XXX */	vstart = (caddr_t)(*romp->op2_alloc)((int)start, mmu_ptob(cnt));	if ((u_int)vstart != (u_int)start)		too_big = 1;	/*	 * Copy program up to correct address	 */	for (to = (int *)start, from = (int *)real; to < (int *)edata; )		*to++ = *from++;	for (to = (int *)edata; to < (int *)end; ++to)		*to = 0;	/*	 * Now we can reference global variables,	 * save page count and monitor's nmi routine address.	 * Dont need this information on OBP.	 */	lastpg = 0;	pagesused = 0;	mon_tbr = gettbr();	if (too_big) {		printf("kadb: size %x exceeded available memory\n",			mmu_ptob(cnt));	}}/* * Startup code after relocation. */startup(){	register int i;	register int pg;	/*	 * Set our implementation parameters from prom properties.	 */	fiximp();	/*	 * Fix up old scb.	 */	kadbscbsync();	spl13();		/* we can take nmi's now */	/*	 * Now make text (and dvec) read only,	 * this also sets a stack redzone	 */#ifdef later	for (i = (int)start; i < (int)etext; i += MMU_PAGESIZE) {		pg = getpgmap(i);		Setpgmap(i, (pg & ~PG_PROT) | PG_KR);	}#endif	mmu_flushall();}scbsync(){	kadbscbsync();	scbsyncdone = 1;}kadbscbsync(){	register struct scb *tbr;	register int otbr_pg;	extern trapvec tcode;	tbr = gettbr();	otbr_pg = getpgmap(tbr);	Setpgmap(tbr, (otbr_pg & ~PG_PROT) | PG_KW);	tbr->user_trap[TRAPBRKNO-1] = tcode;	tbr->user_trap[TRAPBRKNO] = tcode;	Setpgmap(tbr, otbr_pg);	if (scbstop) {		/*		 * We're running interactively. Trap into the debugger		 * so the user can look around before continuing.		 * We use trap TRAPBRKNO-1: "enter debugger"		 */		scbstop = 0;		asm_trap(TRAPBRKNO-1);	}}/* * Sys_trap trap handlers. *//* * level15 (memory error) interrupt. */level15(){	/*	 * For now, the memory error regs are not mapped into the debugger,	 * so we just print a message.	 */	printf("memory error\n");}/* * Miscellanous fault error handler */fault(trap, trappc, trapnpc)	register int trap;	register int trappc;	register int trapnpc;{	register int ondebug_stack;	register u_int *pc;	register u_int realpc;	ondebug_stack = (getsp() > (int)etext && getsp() < (int)estack);	if (trap == T_DATA_FAULT && nofault && ondebug_stack) {		jmp_buf_ptr sav = nofault;		nofault = NULL;		_longjmp(sav, 1);		/*NOTREACHED*/	}	traceback(getsp());	/*	 * If we are on the debugger stack and	 * abort_jmp is set, do a longjmp to it.	 */	if (abort_jmp && ondebug_stack) {		printf("abort jump: trap %x sp %x pc %x npc %x\n",			trap, getsp(), trappc, trapnpc);		printf("etext %x estack %x edata %x nofault %x\n",			etext, estack, edata, nofault);		_longjmp(abort_jmp, 1);		/*NOTREACHED*/	}	/*	 * Ok, the user faulted while not in the	 * debugger. Enter the main cmd loop	 * so that the user can look around...	 */	/*	 * There is a problem here since we really need to tell cmd()	 * the current registers.  We would like to call cmd() in locore	 * but the interface is not really set up to handle this (yet?)	 */	printf("fault and calling cmd: trap %x sp %x pc %x npc %x\n",	    trap, getsp(), trappc, trapnpc);	cmd();	/* error not resolved, enter debugger */}long trap_window[25];static jmp_buf_ptr saved_jb;static jmp_buf jb;extern int debugging;/* * Peekc is so named to avoid a naming conflict * with adb which has a variable named peekc */intPeekc(addr)	char *addr;{	u_char val;	saved_jb = nofault;	nofault = jb;	errno = 0;	if (!_setjmp(jb)) {		val = *addr;		/* if we get here, it worked */		nofault = saved_jb;		return ((int)val);	}	/* a fault occured */	nofault = saved_jb;	errno = EFAULT;	return (-1);}shortpeek(addr)	short *addr;{	short val;	saved_jb = nofault;	nofault = jb;	errno = 0;	if (!_setjmp(jb)) {		val = *addr;		/* if we get here, it worked */		nofault = saved_jb;		return (val);	}	/* a fault occured */	nofault = saved_jb;	errno = EFAULT;	return (-1);}longpeekl(addr)	long *addr;{	long val;	saved_jb = nofault;	nofault = jb;	errno = 0;	if (!_setjmp(jb)) {		val = *addr;		/* if we get here, it worked */		nofault = saved_jb;		return (val);	}	/* a fault occured */	nofault = saved_jb;	errno = EFAULT;	return (-1);}intpokec(addr, val)	char *addr;	char val;{	saved_jb = nofault;	nofault = jb;	errno = 0;	if (!_setjmp(jb)) {		*addr = val;		/* if we get here, it worked */		nofault = saved_jb;		return (0);	}	/* a fault occured */	nofault = saved_jb;	errno = EFAULT;	return (-1);}intpokel(addr, val)	long *addr;	long val;{	saved_jb = nofault;	nofault = jb;	errno = 0;	if (!_setjmp(jb)) {		*addr = val;		/* if we get here, it worked */		nofault = saved_jb;		return (0);	}	/* a fault occured */	nofault = saved_jb;	errno = EFAULT;	return (-1);}poketext(addr, val)	int *addr;	int val;{	int pg = 0;	pg = getpgmap((int)addr);	if (PTE_ETYPE(pg) != MMU_ET_PTE) {		if (debugging > 2)			printf("poketext: invalid page map %X at %X\n",			    pg, addr);		goto err;	}	if ((pg & PTE_CE_MASK) && 		!((cache == CACHE_PAC) || (cache == CACHE_PAC_E))) {		vac_pageflush(addr);		if (btop(addr + sizeof (int) - 1) != btop(addr))			vac_pageflush(addr + sizeof (int) - 1);	}

⌨️ 快捷键说明

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