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

📄 head.s

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 S
📖 第 1 页 / 共 4 页
字号:
/* * BK Id: SCCS/s.head.S 1.34 12/02/01 11:35:27 benh *//* *  PowerPC version  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> *  Adapted for Power Macintosh by Paul Mackerras. *  Low-level exception handlers and MMU support *  rewritten by Paul Mackerras. *    Copyright (C) 1996 Paul Mackerras. *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). * *  This file contains the low-level support and setup for the *  PowerPC platform, including trap and interrupt dispatch. *  (The PPC 8xx embedded CPUs use head_8xx.S instead.) * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version *  2 of the License, or (at your option) any later version. *	 */#include <linux/config.h>#include "ppc_asm.h"#include <asm/processor.h>#include <asm/page.h>#include <asm/mmu.h>#include <asm/pgtable.h>#include <asm/cputable.h>#include <asm/cache.h>#ifdef CONFIG_APUS#include <asm/amigappc.h>#endif#ifdef CONFIG_PPC64BRIDGE#define LOAD_BAT(n, reg, RA, RB)	\	ld	RA,(n*32)+0(reg);	\	ld	RB,(n*32)+8(reg);	\	mtspr	IBAT##n##U,RA;		\	mtspr	IBAT##n##L,RB;		\	ld	RA,(n*32)+16(reg);	\	ld	RB,(n*32)+24(reg);	\	mtspr	DBAT##n##U,RA;		\	mtspr	DBAT##n##L,RB;		\	#else /* CONFIG_PPC64BRIDGE */	/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */#define LOAD_BAT(n, reg, RA, RB)	\	/* see the comment for clear_bats() -- Cort */ \	li	RA,0;			\	mtspr	IBAT##n##U,RA;		\	mtspr	DBAT##n##U,RA;		\	lwz	RA,(n*16)+0(reg);	\	lwz	RB,(n*16)+4(reg);	\	mtspr	IBAT##n##U,RA;		\	mtspr	IBAT##n##L,RB;		\	beq	1f;			\	lwz	RA,(n*16)+8(reg);	\	lwz	RB,(n*16)+12(reg);	\	mtspr	DBAT##n##U,RA;		\	mtspr	DBAT##n##L,RB;		\1:	#endif /* CONFIG_PPC64BRIDGE */	 	.text	.globl	_stext_stext:/* * _start is defined this way because the XCOFF loader in the OpenFirmware * on the powermac expects the entry point to be a procedure descriptor. */	.text	.globl	_start_start:	/* 	 * These are here for legacy reasons, the kernel used to	 * need to look like a coff function entry for the pmac	 * but we're always started by some kind of bootloader now.	 *  -- Cort	 */	nop	nop	nop/* PMAC * Enter here with the kernel text, data and bss loaded starting at * 0, running with virtual == physical mapping. * r5 points to the prom entry point (the client interface handler * address).  Address translation is turned on, with the prom * managing the hash table.  Interrupts are disabled.  The stack * pointer (r1) points to just below the end of the half-meg region * from 0x380000 - 0x400000, which is mapped in already. * * If we are booted from MacOS via BootX, we enter with the kernel * image loaded somewhere, and the following values in registers: *  r3: 'BooX' (0x426f6f58) *  r4: virtual address of boot_infos_t *  r5: 0 * * APUS *   r3: 'APUS' *   r4: physical address of memory base *   Linux/m68k style BootInfo structure at &_end. * * PREP * This is jumped to on prep systems right after the kernel is relocated * to its proper place in memory by the boot loader.  The expected layout * of the regs is:	 *   r3: ptr to residual data *   r4: initrd_start or if no initrd then 0 *   r5: initrd_end - unused if r4 is 0 *   r6: Start of command line string *   r7: End of command line string * * This just gets a minimal mmu environment setup so we can call * start_here() to do the real work. * -- Cort */		.globl	__start__start:/* * We have to do any OF calls before we map ourselves to KERNELBASE, * because OF may have I/O devices mapped into that area * (particularly on CHRP). */	mr	r31,r3			/* save parameters */	mr	r30,r4	mr	r29,r5	mr	r28,r6	mr	r27,r7	li	r24,0			/* cpu # *//* * early_init() does the early machine identification and does * the necessary low-level setup and clears the BSS *  -- Cort <cort@fsmlabs.com> */ 	bl	early_init#ifdef CONFIG_APUS/* On APUS the __va/__pa constants need to be set to the correct  * values before continuing.  */	mr	r4,r30	bl	fix_mem_constants#endif /* CONFIG_APUS */#ifndef CONFIG_GEMINI/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by early_init() */ 	bl	mmu_off__after_mmu_off:	bl	clear_bats	bl	flush_tlbs#endif#ifndef CONFIG_POWER4	/* POWER4 doesn't have BATs */	bl	initial_bats#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)	bl	setup_disp_bat#endif#else /* CONFIG_POWER4 *//* * Load up the SDR1 and segment register values now * since we don't have the BATs. */	bl	reloc_offset	addis	r4,r3,_SDR1@ha		/* get the value from _SDR1 */	lwz	r4,_SDR1@l(r4)		/* assume hash table below 4GB */	mtspr	SDR1,r4	slbia	lis	r5,0x2000		/* set pseudo-segment reg 12 */	ori	r5,r5,0x0ccc	mtsr	12,r5#endif /* CONFIG_POWER4 */#ifndef CONFIG_APUS/* * We need to run with _start at physical address 0. * On CHRP, we are loaded at 0x10000 since OF on CHRP uses * the exception vectors at 0 (and therefore this copy * overwrites OF's exception vectors with our own). * If the MMU is already turned on, we copy stuff to KERNELBASE, * otherwise we copy it to 0. */	bl	reloc_offset	mr	r26,r3	addis	r4,r3,KERNELBASE@h	/* current address of _start */	cmpwi	0,r4,0			/* are we already running at 0? */	bne	relocate_kernel#endif /* CONFIG_APUS *//* * we now have the 1st 16M of ram mapped with the bats. * prep needs the mmu to be turned on here, but pmac already has it on. * this shouldn't bother the pmac since it just gets turned on again * as we jump to our code at KERNELBASE. -- Cort * Actually no, pmac doesn't have it on any more. BootX enters with MMU * off, and in other cases, we now turn it off before changing BATs above. */turn_on_mmu:	mfmsr	r0	ori	r0,r0,MSR_DR|MSR_IR	mtspr	SRR1,r0	lis	r0,start_here@h	ori	r0,r0,start_here@l	mtspr	SRR0,r0	SYNC	RFI				/* enables MMU */#ifdef CONFIG_SMP	.globl	__secondary_hold__secondary_hold:	/* tell the master we're here */	stw	r3,4(0)100:	lwz	r4,0(0)	/* wait until we're told to start */	cmpw	0,r4,r3	bne	100b	/* our cpu # was at addr 0 - go */	mr	r24,r3			/* cpu # */	b	__secondary_start#endif/* * Exception entry code.  This code runs with address translation * turned off, i.e. using physical addresses. * We assume sprg3 has the physical address of the current * task's thread_struct. */#define EXCEPTION_PROLOG	\	mtspr	SPRG0,r20;	\	mtspr	SPRG1,r21;	\	mfcr	r20;		\	mfspr	r21,SPRG2;		/* exception stack to use from */ \	cmpwi	0,r21,0;		/* user mode or RTAS */ \	bne	1f;		\	tophys(r21,r1);			/* use tophys(kernel sp) otherwise */ \	subi	r21,r21,INT_FRAME_SIZE;	/* alloc exc. frame */\1:	CLR_TOP32(r21);		\	stw	r20,_CCR(r21);		/* save registers */ \	stw	r22,GPR22(r21);	\	stw	r23,GPR23(r21);	\	mfspr	r20,SPRG0;	\	stw	r20,GPR20(r21);	\	mfspr	r22,SPRG1;	\	stw	r22,GPR21(r21);	\	mflr	r20;		\	stw	r20,_LINK(r21);	\	mfctr	r22;		\	stw	r22,_CTR(r21);	\	mfspr	r20,XER;	\	stw	r20,_XER(r21);	\	mfspr	r22,SRR0;	\	mfspr	r23,SRR1;	\	stw	r0,GPR0(r21);	\	stw	r1,GPR1(r21);	\	stw	r2,GPR2(r21);	\	stw	r1,0(r21);	\	tovirt(r1,r21);			/* set new kernel sp */	\	SAVE_4GPRS(3, r21);	\	SAVE_GPR(7, r21);/* * Note: code which follows this uses cr0.eq (set if from kernel), * r21, r22 (SRR0), and r23 (SRR1). *//* * Exception vectors. */#define STD_EXCEPTION(n, label, hdlr)		\	. = n;					\label:						\	EXCEPTION_PROLOG;			\	addi	r3,r1,STACK_FRAME_OVERHEAD;	\	li	r20,MSR_KERNEL;			\	bl	transfer_to_handler; 		\i##n:						\	.long	hdlr;				\	.long	ret_from_except/* System reset */#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */#ifdef CONFIG_GEMINI	. = 0x100	b	__secondary_start_gemini#else /* CONFIG_GEMINI */	STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)#endif /* CONFIG_GEMINI */#else	STD_EXCEPTION(0x100, Reset, UnknownException)#endif/* Machine check */	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)/* Data access exception. */	. = 0x300#ifdef CONFIG_PPC64BRIDGE	b	DataAccessDataAccessCont:#elseDataAccess:	EXCEPTION_PROLOG#endif /* CONFIG_PPC64BRIDGE */	mfspr	r20,DSISR	andis.	r0,r20,0xa470		/* weird error? */	bne	1f			/* if not, try to put a PTE */	mfspr	r4,DAR			/* into the hash table */	rlwinm	r3,r20,32-15,21,21	/* DSISR_STORE -> _PAGE_RW */	bl	hash_page1:	stw	r20,_DSISR(r21)	mr	r5,r20	mfspr	r4,DAR	stw	r4,_DAR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handleri0x300:	.long	do_page_fault	.long	ret_from_except#ifdef CONFIG_PPC64BRIDGE/* SLB fault on data access. */	. = 0x380	b	DataSegmentDataSegmentCont:	mfspr	r4,DAR	stw	r4,_DAR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handler	.long	UnknownException	.long	ret_from_except#endif /* CONFIG_PPC64BRIDGE *//* Instruction access exception. */	. = 0x400#ifdef CONFIG_PPC64BRIDGE	b	InstructionAccessInstructionAccessCont:#elseInstructionAccess:	EXCEPTION_PROLOG#endif /* CONFIG_PPC64BRIDGE */	andis.	r0,r23,0x4000		/* no pte found? */	beq	1f			/* if so, try to put a PTE */	li	r3,0			/* into the hash table */	mr	r4,r22			/* SRR0 is fault address */	bl	hash_page1:	addi	r3,r1,STACK_FRAME_OVERHEAD	mr	r4,r22	mr	r5,r23	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handleri0x400:	.long	do_page_fault	.long	ret_from_except#ifdef CONFIG_PPC64BRIDGE/* SLB fault on instruction access. */	. = 0x480	b	InstructionSegmentInstructionSegmentCont:	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handler	.long	UnknownException	.long	ret_from_except#endif /* CONFIG_PPC64BRIDGE *//* External interrupt */	. = 0x500;HardwareInterrupt:	EXCEPTION_PROLOG;	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL#ifndef CONFIG_APUS	li	r4,0	bl	transfer_to_handler	.globl do_IRQ_interceptdo_IRQ_intercept:	.long	do_IRQ;	.long	ret_from_intercept#else	bl	apus_interrupt_entry#endif /* CONFIG_APUS *//* Alignment exception */	. = 0x600Alignment:	EXCEPTION_PROLOG	mfspr	r4,DAR	stw	r4,_DAR(r21)	mfspr	r5,DSISR	stw	r5,_DSISR(r21)	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handleri0x600:	.long	AlignmentException	.long	ret_from_except/* Program check exception */	. = 0x700ProgramCheck:	EXCEPTION_PROLOG	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */	bl	transfer_to_handleri0x700:	.long	ProgramCheckException	.long	ret_from_except/* Floating-point unavailable */	. = 0x800FPUnavailable:	EXCEPTION_PROLOG	bne	load_up_fpu		/* if from user, just load it up */	li	r20,MSR_KERNEL	bl	transfer_to_handler	/* if from kernel, take a trap */i0x800:	.long	KernelFP	.long	ret_from_except	. = 0x900Decrementer:	EXCEPTION_PROLOG	addi	r3,r1,STACK_FRAME_OVERHEAD	li	r20,MSR_KERNEL	bl	transfer_to_handler	.globl timer_interrupt_intercepttimer_interrupt_intercept:	.long	timer_interrupt	.long	ret_from_intercept	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)

⌨️ 快捷键说明

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