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

📄 head.s

📁 优龙2410linux2.6.8内核源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
	.ascii	"HdrS"	.word	LINUX_VERSION_CODE	.half	0x0203		/* HdrS version */root_flags:	.half	1root_dev:	.half	0ram_flags:	.half	0sparc_ramdisk_image:	.word	0sparc_ramdisk_size:	.word	0	.word	reboot_command	.word	0, 0, 0	.word	_end/* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in * %g7 and at prom_vector_p. And also quickly check whether we are on * a v0, v2, or v3 prom. */gokernel:		/* Ok, it's nice to know, as early as possible, if we		 * are already mapped where we expect to be in virtual		 * memory.  The Solaris /boot elf format bootloader		 * will peek into our elf header and load us where		 * we want to be, otherwise we have to re-map.		 *		 * Some boot loaders don't place the jmp'rs address		 * in %o7, so we do a pc-relative call to a local		 * label, then see what %o7 has.		 */		mov	%o7, %g4		! Save %o7		/* Jump to it, and pray... */current_pc:		call	1f		 nop1:		mov	%o7, %g3		tst	%o0		be	no_sun4u_here		 mov	%g4, %o7		/* Previous %o7. */			mov	%o0, %l0		! stash away romvec		mov	%o0, %g7		! put it here too		mov	%o1, %l1		! stash away debug_vec too		/* Ok, let's check out our run time program counter. */		set	current_pc, %g5		cmp	%g3, %g5		be	already_mapped		 nop 		/* %l6 will hold the offset we have to subtract		 * from absolute symbols in order to access areas		 * in our own image.  If already mapped this is		 * just plain zero, else it is KERNBASE.		 */		set	KERNBASE, %l6		b	copy_prom_lvl14		 nopalready_mapped:		mov	0, %l6		/* Copy over the Prom's level 14 clock handler. */copy_prom_lvl14:#if 1		/* DJHR		 * preserve our linked/calculated instructions		 */		set	lvl14_save, %g1		set	t_irq14, %g3		sub	%g1, %l6, %g1		! translate to physical		sub	%g3, %l6, %g3		! translate to physical		ldd	[%g3], %g4		std	%g4, [%g1]		ldd	[%g3+8], %g4		std	%g4, [%g1+8]#endif		rd	%tbr, %g1		andn	%g1, 0xfff, %g1		! proms trap table base		or	%g0, (0x1e<<4), %g2	! offset to lvl14 intr		or	%g1, %g2, %g2		set	t_irq14, %g3		sub	%g3, %l6, %g3		ldd	[%g2], %g4		std	%g4, [%g3]		ldd	[%g2 + 0x8], %g4		std	%g4, [%g3 + 0x8]	! Copy proms handler/* Must determine whether we are on a sun4c MMU, SRMMU, or SUN4/400 MUTANT * MMU so we can remap ourselves properly.  DON'T TOUCH %l0 thru %l5 in these * remapping routines, we need their values afterwards! */		/* Now check whether we are already mapped, if we		 * are we can skip all this garbage coming up.		 */copy_prom_done:		cmp	%l6, 0		be	go_to_highmem		! this will be a nop then		 nop		set	LOAD_ADDR, %g6		cmp	%g7, %g6		bne	remap_not_a_sun4	! This is not a Sun4		 nop		or	%g0, 0x1, %g1		lduba	[%g1] ASI_CONTROL, %g1	! Only safe to try on Sun4.		subcc	%g1, 0x24, %g0		! Is this a mutant Sun4/400???		be	sun4_mutant_remap	! Ugh, it is...		 nop		b	sun4_normal_remap	! regular sun4, 2 level mmu		 nopremap_not_a_sun4:		lda	[%g0] ASI_M_MMUREGS, %g1 ! same as ASI_PTE on sun4c		and	%g1, 0x1, %g1		! Test SRMMU Enable bit ;-)		cmp	%g1, 0x0		be	sun4c_remap		! A sun4c MMU or normal Sun4		 nopsrmmu_remap:		/* First, check for a viking (TI) module. */		set	0x40000000, %g2		rd	%psr, %g3		and	%g2, %g3, %g3		subcc	%g3, 0x0, %g0		bz	srmmu_nviking		 nop		/* Figure out what kind of viking we are on.		 * We need to know if we have to play with the		 * AC bit and disable traps or not.		 */		/* I've only seen MicroSparc's on SparcClassics with this		 * bit set.		 */		set	0x800, %g2		lda	[%g0] ASI_M_MMUREGS, %g3	! peek in the control reg		and	%g2, %g3, %g3		subcc	%g3, 0x0, %g0		bnz	srmmu_nviking			! is in mbus mode		 nop				rd	%psr, %g3			! DO NOT TOUCH %g3		andn	%g3, PSR_ET, %g2		wr	%g2, 0x0, %psr		WRITE_PAUSE				/* Get context table pointer, then convert to		 * a physical address, which is 36 bits.		 */		set	AC_M_CTPR, %g4		lda	[%g4] ASI_M_MMUREGS, %g4		sll	%g4, 0x4, %g4			! We use this below							! DO NOT TOUCH %g4		/* Set the AC bit in the Viking's MMU control reg. */		lda	[%g0] ASI_M_MMUREGS, %g5	! DO NOT TOUCH %g5		set	0x8000, %g6			! AC bit mask		or	%g5, %g6, %g6			! Or it in...		sta	%g6, [%g0] ASI_M_MMUREGS	! Close your eyes...		/* Grrr, why does it seem like every other load/store		 * on the sun4m is in some ASI space...		 * Fine with me, let's get the pointer to the level 1		 * page table directory and fetch its entry.		 */		lda	[%g4] ASI_M_BYPASS, %o1		! This is a level 1 ptr		srl	%o1, 0x4, %o1			! Clear low 4 bits		sll	%o1, 0x8, %o1			! Make physical				/* Ok, pull in the PTD. */		lda	[%o1] ASI_M_BYPASS, %o2		! This is the 0x0 16MB pgd		/* Calculate to KERNBASE entry. */		add	%o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3				/* Poke the entry into the calculated address. */		sta	%o2, [%o3] ASI_M_BYPASS		/* I don't get it Sun, if you engineered all these		 * boot loaders and the PROM (thank you for the debugging		 * features btw) why did you not have them load kernel		 * images up in high address space, since this is necessary		 * for ABI compliance anyways?  Does this low-mapping provide		 * enhanced interoperability?		 *		 * "The PROM is the computer."		 */		/* Ok, restore the MMU control register we saved in %g5 */		sta	%g5, [%g0] ASI_M_MMUREGS	! POW... ouch		/* Turn traps back on.  We saved it in %g3 earlier. */		wr	%g3, 0x0, %psr			! tick tock, tick tock		/* Now we burn precious CPU cycles due to bad engineering. */		WRITE_PAUSE		/* Wow, all that just to move a 32-bit value from one		 * place to another...  Jump to high memory.		 */		b	go_to_highmem		 nop		/* This works on viking's in Mbus mode and all		 * other MBUS modules.  It is virtually the same as		 * the above madness sans turning traps off and flipping		 * the AC bit.		 */srmmu_nviking:		set	AC_M_CTPR, %g1		lda	[%g1] ASI_M_MMUREGS, %g1	! get ctx table ptr		sll	%g1, 0x4, %g1			! make physical addr		lda	[%g1] ASI_M_BYPASS, %g1		! ptr to level 1 pg_table		srl	%g1, 0x4, %g1		sll	%g1, 0x8, %g1			! make phys addr for l1 tbl		lda	[%g1] ASI_M_BYPASS, %g2		! get level1 entry for 0x0		add	%g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3		sta	%g2, [%g3] ASI_M_BYPASS		! place at KERNBASE entry		b	go_to_highmem		 nop					! wheee....		/* This remaps the kernel on Sun4/4xx machines		 * that have the Sun Mutant Three Level MMU.		 * It's like a platypus, Sun didn't have the		 * SRMMU in conception so they kludged the three		 * level logic in the regular Sun4 MMU probably.		 *		 * Basically, you take each entry in the top level		 * directory that maps the low 3MB starting at		 * address zero and put the mapping in the KERNBASE		 * slots.  These top level pgd's are called regmaps.		 */sun4_mutant_remap:		or	%g0, %g0, %g3		! source base		sethi	%hi(KERNBASE), %g4	! destination base		or	%g4, %lo(KERNBASE), %g4		sethi	%hi(0x300000), %g5		or	%g5, %lo(0x300000), %g5	! upper bound 3MB		or	%g0, 0x1, %l6		sll	%l6, 24, %l6		! Regmap mapping size		add	%g3, 0x2, %g3		! Base magic		add	%g4, 0x2, %g4		! Base magic		/* Main remapping loop on Sun4-Mutant-MMU.		 * "I am not an animal..." -Famous Mutant Person		 */sun4_mutant_loop:		lduha	[%g3] ASI_REGMAP, %g2	! Get lower entry		stha	%g2, [%g4] ASI_REGMAP	! Store in high entry		add	%g4, %l6, %g4		! Move up high memory ptr		subcc	%g3, %g5, %g0		! Reached our limit?		blu	sun4_mutant_loop	! Nope, loop again		 add	%g3, %l6, %g3		! delay, Move up low ptr		b	go_to_highmem		! Jump to high memory.		 nop		/* The following is for non-4/4xx sun4 MMU's. */sun4_normal_remap:		mov	0, %g3			! source base		set	KERNBASE, %g4		! destination base		set	0x300000, %g5		! upper bound 3MB		mov	1, %l6		sll	%l6, 18, %l6		! sun4 mmu segmap sizesun4_normal_loop:		lduha	[%g3] ASI_SEGMAP, %g6	! load phys_seg		stha	%g6, [%g4] ASI_SEGMAP	! stort new virt mapping		add	%g3, %l6, %g3		! increment source pointer		subcc	%g3, %g5, %g0		! reached limit?		blu	sun4_normal_loop	! nope, loop again		 add	%g4, %l6, %g4		! delay, increment dest ptr		b	go_to_highmem		 nop		/* The following works for Sun4c MMU's */sun4c_remap:		mov	0, %g3			! source base		set	KERNBASE, %g4		! destination base		set	0x300000, %g5		! upper bound 3MB		mov	1, %l6		sll	%l6, 18, %l6		! sun4c mmu segmap sizesun4c_remap_loop:		lda	[%g3] ASI_SEGMAP, %g6	! load phys_seg		sta	%g6, [%g4] ASI_SEGMAP   ! store new virt mapping		add	%g3, %l6, %g3		! Increment source ptr		subcc	%g3, %g5, %g0		! Reached limit?		bl	sun4c_remap_loop	! Nope, loop again		 add	%g4, %l6, %g4		! delay, Increment dest ptr/* Now do a non-relative jump so that PC is in high-memory */go_to_highmem:		set	execute_in_high_mem, %g1		jmpl	%g1, %g0		 nop/* The code above should be at beginning and we have to take care about * short jumps, as branching to .text.init section from .text is usually * impossible */		__INIT/* Acquire boot time privileged register values, this will help debugging. * I figure out and store nwindows and nwindowsm1 later on. */execute_in_high_mem:		mov	%l0, %o0		! put back romvec		mov	%l1, %o1		! and debug_vec		sethi	%hi(prom_vector_p), %g1		st	%o0, [%g1 + %lo(prom_vector_p)]		sethi	%hi(linux_dbvec), %g1		st	%o1, [%g1 + %lo(linux_dbvec)]		ld	[%o0 + 0x4], %o3		and	%o3, 0x3, %o5			! get the version		cmp	%o3, 0x2			! a v2 prom?		be	found_version		 nop		/* paul@sfe.com.au */		cmp	%o3, 0x3			! a v3 prom?		be	found_version		 nop/* Old sun4's pass our load address into %o0 instead of the prom * pointer. On sun4's you have to hard code the romvec pointer into * your code. Sun probably still does that because they don't even * trust their own "OpenBoot" specifications. */		set	LOAD_ADDR, %g6		cmp	%o0, %g6		! an old sun4?		be	sun4_init		 nopfound_version:#ifdef CONFIG_SUN4/* For people who try sun4 kernels, even if Configure.help advises them. */		ld	[%g7 + 0x68], %o1		set	sun4cdm_notsup, %o0		call	%o1		 nop		b	halt_me		 nop#endif/* Get the machine type via the mysterious romvec node operations. */		add	%g7, 0x1c, %l1				ld	[%l1], %l0		ld	[%l0], %l0		call 	%l0		 or	%g0, %g0, %o0		! next_node(0) = first_node		or	%o0, %g0, %g6		sethi	%hi(cputypvar), %o1	! First node has cpu-arch		or	%o1, %lo(cputypvar), %o1		sethi	%hi(cputypval), %o2	! information, the string		or	%o2, %lo(cputypval), %o2		ld	[%l1], %l0		! 'compatibility' tells		ld	[%l0 + 0xc], %l0	! that we want 'sun4x' where		call	%l0			! x is one of '', 'c', 'm',		 nop				! 'd' or 'e'. %o2 holds pointer						! to a buf where above string						! will get stored by the prom.		subcc	%o0, %g0, %g0		bpos	got_prop		! Got the property		 nop		or	%g6, %g0, %o0		sethi	%hi(cputypvar_sun4m), %o1		or	%o1, %lo(cputypvar_sun4m), %o1		sethi	%hi(cputypval), %o2		or	%o2, %lo(cputypval), %o2		ld	[%l1], %l0		ld	[%l0 + 0xc], %l0		call	%l0		 nopgot_prop:		set	cputypval, %o2		ldub	[%o2 + 0x4], %l1		cmp	%l1, ' '		be	1f		 cmp	%l1, 'c'		be	1f		 cmp	%l1, 'm'		be	1f		 cmp	%l1, 's'		be	1f		 cmp	%l1, 'd'		be	1f		 cmp	%l1, 'e'		be	no_sun4e_here		! Could be a sun4e.		 nop		b	no_sun4u_here		! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))		 nop1:		set	cputypval, %l1		ldub	[%l1 + 0x4], %l1		cmp	%l1, 'm'		! Test for sun4d, sun4e ?		be	sun4m_init		 cmp	%l1, 's'		! Treat sun4s as sun4m		be	sun4m_init		 cmp	%l1, 'd'		! Let us see how the beast will die		be	sun4d_init		 nop		/* Jump into mmu context zero. */		set	AC_CONTEXT, %g1		stba	%g0, [%g1] ASI_CONTROL		b	sun4c_continue_boot		 nop/* CPUID in bootbus can be found at PA 0xff0140000 */#define SUN4D_BOOTBUS_CPUID     0xf0140000sun4d_init:	/* Need to patch call to handler_irq */	set	patch_handler_irq, %g4	set	sun4d_handler_irq, %g5	sethi	%hi(0x40000000), %g3		! call	sub	%g5, %g4, %g5	srl	%g5, 2, %g5	or	%g5, %g3, %g5	st	%g5, [%g4]#ifdef CONFIG_SMP	/* Get our CPU id out of bootbus */	set     SUN4D_BOOTBUS_CPUID, %g3	lduba   [%g3] ASI_M_CTL, %g3	and     %g3, 0xf8, %g3

⌨️ 快捷键说明

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