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

📄 locore.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
	.ident  "@(#)locore.s 1.1 92/07/30 SMI"/* * Copyright (c) 1986 by Sun Microsystems, Inc. */#include "assym.s"#include <sys/errno.h>#include <sys/param.h>#include <machine/asm_linkage.h>#include <machine/reg.h>#include <machine/mmu.h>#include <machine/psl.h>#include <machine/pte.h>#include <machine/enable.h>#include <machine/cpu.h>#include <machine/trap.h>#include <machine/eeprom.h>#include "../../debug/debug.h"/* * The debug stack. This must be the first thing in the data * segment (other than an sccs string) so that we don't stomp * on anything important. We get a red zone below this stack * for free when the text is write protected. */#define	STACK_SIZE	0x8000	.seg	"data"	.global _estack	.skip	STACK_SIZE_estack:				! end (top) of debugger stackfpuregs:	.skip	33*4			! %f0 - %f31 plus %fsr	.global _cache_cache:	.word	0	.global	_kadblock_kadblock:	.word	0			! mutex for kadb's trap()_kadbcpu:	.word	0			! ordinal of cpu holding above lock/* * The number of windows, set by fiximp when machine is booted. */	.global _nwindows/* * The parent callback routine. */        .global _release_parent_release_parent:        .word   0	.seg	"text"/* * Trap vector macros. */#define TRAP(H) \	b (H); mov %psr,%l0; nop; nop;/* * The constant in the last expression must be (nwindows-1). * See fiximp() below. */#define WIN_TRAP(H) \	mov %psr,%l0;  mov %wim,%l3;  b (H);  mov 7,%l6;#define SYS_TRAP(T) \	mov %psr,%l0;  sethi %hi(T),%l3;  b sys_trap;  or %l3,%lo(T),%l3;#define BAD_TRAP	SYS_TRAP(_fault);/* * Trap vector table. * This must be the first text in the boot image. * * When a trap is taken, we vector to DEBUGSTART+(TT*16) and we have * the following state: *	2) traps are disabled *	3) the previous state of PSR_S is in PSR_PS *	4) the CWP has been decremented into the trap window *	5) the previous pc and npc is in %l1 and %l2 respectively. * * Registers: *	%l0 - %psr immediately after trap *	%l1 - trapped pc *	%l2 - trapped npc *	%l3 - trap handler pointer (sys_trap only) *		or current %wim (win_trap only) *	%l6 - NW-1, for wim calculations (win_trap only) * * Note: DEBUGGER receives control at vector 0 (trap). */	.seg	"text"	.align 4	.global _our_die_routine	.global _start, _scb_start:_scb:	TRAP(enter);				! 00	BAD_TRAP;				! 01 text fault	BAD_TRAP;				! 02 unimp instruction	BAD_TRAP;				! 03 priv instruction	TRAP(_fp_disabled);			! 04 fp disabled	WIN_TRAP(_window_overflow);		! 05	WIN_TRAP(_window_underflow);		! 06	BAD_TRAP;				! 07 alignment	BAD_TRAP;				! 08 fp exception	SYS_TRAP(_fault);			! 09 data fault	BAD_TRAP;				! 0A tag_overflow	BAD_TRAP; BAD_TRAP;			! 0B - 0C	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 0D - 10	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 11 - 14 int 1-4	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 15 - 18 int 5-8	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 19 - 1C int 9-12	BAD_TRAP; BAD_TRAP;			! 1D - 1E int 13-14	SYS_TRAP(_level15);			! 1F int 15	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 20 - 23	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 24 - 27	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 28 - 2B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 2C - 2F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 30 - 34	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 34 - 37	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 38 - 3B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 3C - 3F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 40 - 44	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 44 - 47	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 48 - 4B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 4C - 4F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 50 - 53	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 54 - 57	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 58 - 5B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 5C - 5F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 60 - 64	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 64 - 67	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 68 - 6B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 6C - 6F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 70 - 74	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 74 - 77	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP;	! 78 - 7B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F	!	! software traps	!	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 80 - 83	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 84 - 87	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 88 - 8B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 8C - 8F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 90 - 93	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 94 - 97	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 98 - 9B	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 9C - 9F	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! A0 - A3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! A4 - A7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! A8 - AB	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! AC - AF	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! B0 - B3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! B4 - B7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! B8 - BB	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! BC - BF	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! C0 - C3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! C4 - C7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! C8 - CB	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! CC - CF	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! D0 - D3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! D4 - D7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! D8 - DB	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! DC - DF	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! E0 - E3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! E4 - E7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! E8 - EB	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! EC - EF	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! F0 - F3	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! F4 - F7	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! F8 - FB	BAD_TRAP;				! FC 	TRAP(_trap);				! FD enter debugger	TRAP(_trap);				! FE breakpoint	BAD_TRAP;				! PROM breakpoint trap/* * Debugger vector table. * Must follow trap table. */dvec:	b,a	enter			! dv_entry	.word	_trap			! dv_trap	.word	_pagesused		! dv_pages	.word	_scbsync		! dv_scbsync	.word	0/* * Debugger entry point. * First we must figure out if we are running in correctly adjusted * addresses. If so, we must have been called by debugged code * and thus we just want to call the command interpreter. If not, * then we continue to run in the wrong adddress. All of the code * must be carefully written to be position independent, since * we are linked for running out of high addresses, but we get control * running in low addresses. We depend on the boot stack for work space. */enter:	mov	%o0, %o1		! o0 might be romp: pass it as o1 later	mov	%o2, %l1		! save parents callback routine	mov	%o7, %o5		! save o7acall:	call	lea			! %o7 = physical(acall)	sethi	%hi(acall), %o3		! %o3 = virtual(acall)lea:	or	%o3, %lo(acall), %o3	!	cmp	%o3, %o7		! compare to see if virtual == physical	set	_start, %o2		! %o2 = virtual(_start)	sub	%o3, %o2, %o4		! %o4 = acall - _start	sub	%o7, %o4, %o0		! %o0 = physical(start)	bne	init			! if != then not relocated yet	mov	%o5, %o7		! restore o7	!	! Enter debugger by doing a software trap.	! We ASSUME that the software trap we have set up is still there.	!	t	TRAPBRKNO-1	nop	retl	nop	!	! We have not been relocated yet.	!init:	mov	%psr, %g1	bclr	PSR_PIL, %g1		! PIL = 15	bset	(15 << 8), %g1	mov	%g1, %psr	nop; nop; nop	!	! Initialize the "cache" variable.	! Must be done before call to early_startup().	! XXX-This allows for having either ROSS modules	! *or* Viking modules.  Since Viking is documented to have	! an IMPL of "4", but doesnt (and may never), this	! method is chosen.  If a third module type is added	! we must have the Viking IMPL clearly defined/implemented	! in the HW.	!	set	_cache, %g1	sub	%g1, %o2, %g1			add	%g1, %o0, %g1		! current address of _cache	lda	[%g0]ASI_MOD, %o3	! Get MCR	srl	%o3, 28, %o4		! Get IMPL bits	cmp	%o4, 0x1		! Are we ROSS?	bz,a	0f			! Yes	st	%o4, [%g1]		! CACHE_VAC	!	! Not ROSS, so must be viking.  Do we have E$?	!	mov	CACHE_PAC_E, %o4		btst	CPU_VIK_MB, %o3		! MB bit set?	bz,a	0f			! No, Viking/E$	st	%o4, [%g1]		! CACHE_PAC_E	mov	CACHE_PAC, %o4		! Viking/NE	st	%o4, [%g1]		! CACHE_PAC	!	! Preserve the romp across the call to early_startup().	! Save it in %l0: since we're going to reset the world later,	! we can trash our caller's registers.	!0:	mov	%o1, %l0	set	_early_startup, %o3	! get offset of early_startup()	sub	%o3, %o2, %o4		!  from _start	add	%o4, %o0, %o4		! add to _start's current address	jmpl	%o4, %o7		! call early_startup(real)	nop	set     jmpstart, %g1		! now that it is relocated, jump to it	jmp     %g1	nopjmpstart:	!	! PHEW! Now we are running with correct addresses	! and can use non-position-independent code.	!	! Save romp.	!	set	_romp, %o0	st	%l0, [%o0]	sethi	%hi(_kadblock), %o0	! be sure that the trap mutex is clear	stb	%g0, [%o0 + %lo(_kadblock)]	!	! Save parent callback routine	!	set 	_release_parent, %o0	st	%l1, [%o0]	!	! Save monitor's level14 clock interrupt vector code and trap #0.	!	mov     %tbr, %l4               ! save monitor's tbr	bclr    0xfff, %l4              ! remove tt	or      %l4, TT(T_INT_LEVEL_14), %l4	set     _scb, %l5	or      %l5, TT(T_INT_LEVEL_14), %l5	ldd	[%l4], %o0	std	%o0, [%l5]	ldd	[%l4+8], %o0	std	%o0, [%l5+8]	bclr    0xfff, %l4              ! remove tt	or      %l4, TT(T_SYSCALL), %l4	bclr    0xfff, %l5	or      %l5, TT(T_SYSCALL), %l5	ldd	[%l4], %o0	std	%o0, [%l5]	ldd	[%l4+8], %o0	std	%o0, [%l5+8]	bclr    0xfff, %l4              ! remove tt	or      %l4, TT(ST_MON_BREAKPOINT+T_SOFTWARE_TRAP), %l4	bclr    0xfff, %l5	or      %l5, TT(ST_MON_BREAKPOINT+T_SOFTWARE_TRAP), %l5	ldd	[%l4], %o0	std	%o0, [%l5]	ldd	[%l4+8], %o0	std	%o0, [%l5+8]	!	! Take over the world. Save the current stack pointer, as	! we're going to need it for a little while longer.	!	mov	%sp, %g2	set	_scb, %g1		! setup kadb tbr	mov 	%g1, %tbr	nop; nop; nop	mov	0x2, %wim	mov 	%psr, %g1	bclr 	PSR_CWP, %g1	mov 	%g1, %psr	nop; nop; nop;			! psr delay	sub	%g2, SA(MINFRAME), %sp	!	! Fix the implementation dependent parameters.	!fiximp:	!	! Find out how many windows we have and set the global variable.	! We must be in window 0 for this to work.	!	set	_nwindows, %g2	save				! CWP is now (nwindows - 1)	mov	%psr, %g1	and	%g1, PSR_CWP, %g1	inc	%g1	st	%g1, [%g2]	restore	!	! Fix the number of windows in the trap vectors.	! The last byte of the window handler trap vectors must be equal to	! the number of windows in the implementation minus one.	!	dec	%g1			! last byte of trap vectors get NW-1	set	_scb, %g2	add	%g2, (5 << 4), %g2	! window overflow trap handler offset	stb	%g1, [%g2 + 15]		! write last byte of trap vector	add	%g2, 16, %g2		! now get window underflow trap	stb	%g1, [%g2 + 15]		! write last byte of trap vector	!	! Call startup to do the rest of the startup work.	!	call	_startup	nop	!	! call main to enter the debugger	!	call	_main	nop	mov	%psr, %g1	bclr	PSR_PIL, %g1		! PIL = 14	bset	(14 << 8), %g1	mov	%g1, %psr	nop;nop;nop	t	TRAPBRKNO-1	!	! In the unlikely event we get here, return to the monitor.	!	set	_romp, %g1	ld	[%g1], %g2	ld	[%g2 + EXIT_TO_MON], %g1	jmp	%g1	clr	%o0/* * exitto(addr) * int *addr; */	ENTRY(_exitto)	save	%sp, -SA(MINFRAME), %sp	set	1, %o1        sethi   %hi(_use_kern_tbr), %o0        st      %o1, [%o0 + %lo(_use_kern_tbr)]        set     _release_parent, %g1    ! call back boot's release function        ld      [%g1], %g1        tst     %g1        be      dont_kill_parent        ! only callback if function exists        nop        jmpl    %g1, %o7                ! pass return addr in %o0 for        add     %o7, 8, %o0             ! romp->op_chain() functiondont_kill_parent: 	set 	_our_die_routine, %o2	! pass our release func to callee	set	dvec, %o1		! pass dvec address to callee	set	_romp, %o0		! pass the romp to callee	jmpl	%i0, %o7		! register-indirect call	ld	[%o0], %o0	ret	restore/* * This is where breakpoint traps go. * We assume we are in the normal condition after a trap. */	ENTRY(trap)#ifdef	MULTIPROCESSOR	!	! get current mid	!	set	RMMU_CTL_REG, %l3	! get contents of MCR	lda	[%l3]ASI_MOD, %l5	! ROSS mid found in MCR	!	! Need to check our processor type now.	! Since only ROSS is scheduled to be MP, if not	! ROSS, skip the lock mechanism.	! XXX-Well, not quite.  Will handle the case of	! MP Viking/E$, for bringup/debug purposes.	! Wont worry about Viking/NE MP.	!	sethi	%hi(_cache), %l3	ld	[%l3 + %lo(_cache)], %l3	cmp	%l3, CACHE_PAC		! Is it Viking/NE?	bz	skip_lock		! Yes, so not MP	nop				!     Ignore the locking mechanism	cmp	%l3, CACHE_PAC_E	! Is it Viking/E$?	bnz,a	0f			! No, must be ROSS	srl	%l5, 0xf, %l3		! lose uninteresting bits	set	MXCC_PORT, %l3		! Viking/E$ mid found in	lda	[%l3]ASI_MXCC, %l5	!     Mbus Port Address Reg	srl	%l5, 24, %l5		! MID is 8..11	b	tryhard	sethi	%hi(_kadblock), %l30:	and	%l3, 0xf, %l5		! MID is 8..11        !        ! Try the lock.        !        sethi   %hi(_kadblock), %l3tryhard:         ldstub  [%l3 + %lo(_kadblock)], %l4        btst    %l4, %g0                ! zero?        beq     gotit                   ! yes --> come on in.        nop        !        ! The lock is held.  Check to see if it is held by the same        ! cpu that is trying it now.        !        sethi   %hi(_kadbcpu), %l4        ld      [%l4 + %lo(_kadbcpu)], %l4        cmp     %l5, %l4                ! same cpu?        beq     gotit                   ! yes --> come on in        nop        !        ! The lock is held by another cpu.  Spin here until it looks        ! clear.        !tryeasy:        ldub    [%l3 + %lo(_kadblock)], %l4        btst    %l4, %g0                ! look clear?        beq     tryhard                 ! yes --> try the hard way        nop        ba      tryeasy                 ! otherwise, spin here.        nopgotit:        sethi   %hi(_kadbcpu), %l3        st      %l5, [%l3 + %lo(_kadbcpu)]skip_lock:#endif	MULTIPROCESSOR	!	! dump the whole cpu state (all windows) on the stack.	!	set	_regsave, %l3	st	%l0, [%l3 + R_PSR]	st	%l1, [%l3 + R_PC]	st	%l2, [%l3 + R_NPC]	mov	%wim, %l4	st	%l4, [%l3 + R_WIM]	mov	%g0, %wim		! zero wim so that we can move around	mov	%tbr, %l4	st	%l4, [%l3 + R_TBR]	mov	%y, %l4	st	%l4, [%l3 + R_Y]	st	%g1, [%l3 + R_G1]	st	%g2, [%l3 + R_G2]	st	%g3, [%l3 + R_G3]	st	%g4, [%l3 + R_G4]	st	%g5, [%l3 + R_G5]	st	%g6, [%l3 + R_G6]	st	%g7, [%l3 + R_G7]	add	%l3, R_WINDOW, %g7	sethi	%hi(_nwindows), %g6	ld	[%g6 + %lo(_nwindows)], %g6	bclr	PSR_CWP, %l0		! go to window 0	mov	%l0, %psr	nop; nop; nop;			! psr delay1:	st	%l0, [%g7 + 0*4]	! save locals	st	%l1, [%g7 + 1*4]	st	%l2, [%g7 + 2*4]	st	%l3, [%g7 + 3*4]	st	%l4, [%g7 + 4*4]	st	%l5, [%g7 + 5*4]	st	%l6, [%g7 + 6*4]	st	%l7, [%g7 + 7*4]	st	%i0, [%g7 + 8*4]	! save ins	st	%i1, [%g7 + 9*4]	st	%i2, [%g7 + 10*4]	st	%i3, [%g7 + 11*4]	st	%i4, [%g7 + 12*4]	st	%i5, [%g7 + 13*4]	st	%i6, [%g7 + 14*4]	st	%i7, [%g7 + 15*4]	add	%g7, WINDOWSIZE, %g7	subcc	%g6, 1, %g6		! all windows done?	bnz	1b	restore				! delay slot, increment CWP	!	! Back in window 0.	!	set	_regsave, %g2		! need to get back to state of entering	ld	[%g2 + R_WIM], %g1	mov	%g1, %wim	ld	[%g2 + R_PSR], %g1	bclr	PSR_PIL, %g1		! PIL = 14	bset	(14 << 8), %g1	mov     %g1, %psr		! go back to orig window	nop;nop;nop	!	! Now we must make sure all the window stuff goes to memory.	! Flush all register windows to the stack.	! But wait! If we trapped into the invalid window, we can't just	! save because we'll slip under the %wim tripwire.	! Do one restore first, so subsequent saves are guaranteed	! to flush the registers. (Don't worry about the restore	! triggering a window underflow, since if we're in a trap	! window the next window up has to be OK.)	! Do all this while still using the kernel %tbr: let it worry	! about user windows and user stack faults.	!	restore	mov	%psr, %g1		! get new CWP	wr	%g1, PSR_ET, %psr	! enable traps	nop;nop;nop	save	%sp, -SA(MINFRAME), %sp	! now we're back in the trap window	mov	%sp, %g3	mov	%fp, %g4	sethi	%hi(_nwindows), %g7	ld	[%g7 + %lo(_nwindows)], %g7	sub	%g7, 2, %g6		! %g6 = NWINDOW - 21:	deccc	%g6			! all windows done?	bnz	1b	save	%sp, -WINDOWSIZE, %sp	sub	%g7, 2, %g6		! %g6 = NWINDOW - 22:

⌨️ 快捷键说明

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