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

📄 head.s

📁 microwindows移植到S3C44B0的源码
💻 S
📖 第 1 页 / 共 4 页
字号:
/* *  arch/ppc64/kernel/head.S * *  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. * *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com * *  This file contains the low-level support and setup for the *  PowerPC-64 platform, including trap and interrupt dispatch. * *  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. */#define SECONDARY_PROCESSORS#include "ppc_asm.h"#include "ppc_defs.h"#include <asm/processor.h>#include <asm/page.h>#include <linux/config.h>#include <asm/mmu.h>// #include <asm/paca.h>#ifdef CONFIG_PPC_ISERIES#define DO_SOFT_DISABLE#endif/* * hcall interface to pSeries LPAR */#define HSC .long 0x44000022#define H_SET_ASR		0x30/* * We layout physical memory as follows: * 0x0000 - 0x00ff : Secondary processor spin code * 0x0100 - 0x2fff : pSeries Interrupt prologs * 0x3000 - 0x3fff : Interrupt support * 0x4000 - 0x4fff : NACA * 0x5000 - 0x5fff : Initial segment table * 0x6000          : iSeries and common interrupt prologs *//* *   SPRG Usage * *   Register          Definition * *   SPRG0             reserved for hypervisor *   SPRG1             temp - used to save gpr *   SPRG2             temp - used to save gpr *   SPRG3             virt addr of paca *//* * Entering into this code we make the following assumptions: *  For pSeries: *   1. The MMU is off & open firmware is running in real mode. *   2. The kernel is entered at __start * *  For iSeries: *   1. The MMU is on (as it always is for iSeries) *   2. The kernel is entered at SystemReset_Iseries */	.text	.globl  _stext_stext:_STATIC(__start)	b .__start_initialization_pSeries	/* At offset 0x20, there is a pointer to iSeries LPAR data.	 * This is required by the hypervisor */	. = 0x20	.llong hvReleaseData-KERNELBASE	/* At offset 0x28 and 0x30 are offsets to the msChunks	 * array (used by the iSeries LPAR debugger to do translation	 * between physical addresses and absolute addresses) and	 * to the pidhash table (also used by the debugger) */	.llong msChunks-KERNELBASE	.llong pidhash-KERNELBASE	/* Offset 0x38 - Pointer to start of embedded System.map */	.globl	embedded_sysmap_startembedded_sysmap_start:	.llong	0	/* Offset 0x40 - Pointer to end of embedded System.map */	.globl	embedded_sysmap_endembedded_sysmap_end:	.llong	0	/* Secondary processors spin on this value until it goes to 1. */	.globl  __secondary_hold_spinloop__secondary_hold_spinloop:	.llong  0x0	/* Secondary processors write this value with their cpu # */	/* after they enter the spin loop immediatly below.       */	.globl  __secondary_hold_acknowledge__secondary_hold_acknowledge:	.llong  0x0	. = 0x60/* * The following code is used on pSeries to hold secondary processors * in a spin loop after they have been freed from OpenFirmware, but * before the bulk of the kernel has been relocated.  This code * is relocated to physical address 0x60 before prom_init is run. * All of it must fit below the first exception vector at 0x100. */_GLOBAL(__secondary_hold)	/* Grab our linux cpu number */	mr      r24,r3	/* Tell the master cpu we're here */	/* Relocation is off & we are located at an address less */	/* than 0x100, so only need to grab low order offset.    */	std     r24,__secondary_hold_acknowledge@l(0)	/* All secondary cpu's wait here until told to start. */100:    ld      r4,__secondary_hold_spinloop@l(0)	cmpdi   0,r4,1	bne     100b#ifdef CONFIG_HMT	b	.hmt_init#else#ifdef CONFIG_SMP	mr      r3,r24	b       .pseries_secondary_smp_init#else	BUG_OPCODE#endif#endif/* * The following macros define the code that appears as * the prologue to each of the exception handlers.  They * are split into two parts to allow a single kernel binary * to be used for pSeries, and iSeries. *//* * We make as much of the exception code common between native Pseries * and Iseries LPAR implementations as possible. *//* * This is the start of the interrupt handlers for Pseries * This code runs with relocation off. */#define EX_SRR0		0#define EX_SRR1		8#define EX_R20		16#define EX_R21		24#define EX_R22		32#define EX_R23		40#define EX_DAR		48#define EX_DSISR	56#define EX_CCR   	60#define EX_TRAP   	60#define EXCEPTION_PROLOG_PSERIES(n,label)                                \	mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg   */ \	mtspr   SPRG1,r21;              /* save r21                   */ \	mfspr   r20,SPRG3;              /* get paca virt addr         */ \	ld      r21,PACAEXCSP(r20);     /* get exception stack ptr    */ \	addi    r21,r21,EXC_FRAME_SIZE; /* make exception frame       */ \	std	r22,EX_R22(r21);	/* Save r22 in exc. frame     */ \	li	r22,n;                  /* Save the ex # in exc. frame*/ \	stw	r22,EX_TRAP(r21);	/*                            */ \	std	r23,EX_R23(r21);	/* Save r23 in exc. frame     */ \	mfspr   r22,SRR0;               /* EA of interrupted instr    */ \	std	r22,EX_SRR0(r21);	/* Save SRR0 in exc. frame    */ \	mfspr   r23,SRR1;               /* machine state at interrupt */ \	std	r23,EX_SRR1(r21);	/* Save SRR1 in exc. frame    */ \	clrrdi  r22,r20,60;             /* Get 0xc part of the vaddr  */ \	ori	r22,r22,(label)@l;      /* add in the vaddr offset    */ \		                        /*   assumes *_common < 16b   */ \	mfmsr   r23;                                                     \	rotldi  r23,r23,4;                                               \	ori     r23,r23,0x30B;          /* Set IR, DR, SF, ISF, HV    */ \	rotldi  r23,r23,60;             /* for generic handlers       */ \	mtspr   SRR0,r22;                                                \	mtspr   SRR1,r23;                                                \	mfcr    r23;                    /* save CR in r23             */ \	rfid/* * This is the start of the interrupt handlers for i_series * This code runs with relocation on. */#define EXCEPTION_PROLOG_ISERIES(n)	                                      \	mtspr	SPRG2,r20;		    /* use SPRG2 as scratch reg    */ \	mtspr   SPRG1,r21;                  /* save r21                    */ \	mfspr	r20,SPRG3;		    /* get Paca                    */ \	ld      r21,PACAEXCSP(r20);         /* get exception stack ptr     */ \	addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame        */ \	std	r22,EX_R22(r21);	    /* save r22 on exception frame */ \	li	r22,n;                      /* Save the ex # in exc. frame */ \	stw	r22,EX_TRAP(r21);	    /*                             */ \	std	r23,EX_R23(r21);	    /* Save r23 in exc. frame      */ \	ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca      */ \	std	r22,EX_SRR0(r21);	    /* save SRR0 in exc. frame     */ \	ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca      */ \	std	r23,EX_SRR1(r21);	    /* save SRR1 in exc. frame     */ \	mfcr    r23;                        /* save CR in r23              *//* * The common exception prolog is used for all except a few exceptions * such as a segment miss on a kernel address.  We have to be prepared * to take another exception from the point where we first touch the * kernel stack onwards. * * On entry r20 points to the paca and r21 points to the exception * frame on entry, r23 contains the saved CR, and relocation is on. */#define EXCEPTION_PROLOG_COMMON                                           \	mfspr	r22,SPRG2;		/* Save r20 in exc. frame      */ \	std	r22,EX_R20(r21);	                                  \	mfspr	r22,SPRG1;		/* Save r21 in exc. frame      */ \	std	r22,EX_R21(r21);	                                  \	mfspr   r22,DAR;                /* Save DAR in exc. frame      */ \	std	r22,EX_DAR(r21);	                                  \	std     r21,PACAEXCSP(r20);     /* update exception stack ptr  */ \		                        /*   iff no protection flt     */ \	mfspr	r22,DSISR;		/* Save DSISR in exc. frame    */ \	stw	r22,EX_DSISR(r21);	                                  \	ld	r22,EX_SRR1(r21);	/* Get SRR1 from exc. frame    */ \	andi.   r22,r22,MSR_PR;         /* Set CR for later branch     */ \	mr      r22,r1;                 /* Save r1                     */ \	subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */ \	beq-    1f;                                                       \	ld      r1,PACAKSAVE(r20);      /* kernel stack to use         */ \1:      std     r22,GPR1(r1);           /* save r1 in stackframe       */ \	std     r22,0(r1);              /* make stack chain pointer    */ \	std     r23,_CCR(r1);           /* save CR in stackframe       */ \	ld	r22,EX_R20(r21);	/* move r20 to stackframe      */ \	std	r22,GPR20(r1);		                                  \	ld	r23,EX_R21(r21);	/* move r21 to stackframe      */ \	std	r23,GPR21(r1);		                                  \	ld	r22,EX_R22(r21);	/* move r22 to stackframe      */ \	std	r22,GPR22(r1);		                                  \	ld	r23,EX_R23(r21);	/* move r23 to stackframe      */ \	std	r23,GPR23(r1);		                                  \	mflr    r22;                    /* save LR in stackframe       */ \	std     r22,_LINK(r1);                                            \	mfctr   r23;                    /* save CTR in stackframe      */ \	std     r23,_CTR(r1);                                             \	mfspr   r22,XER;                /* save XER in stackframe      */ \	std     r22,_XER(r1);                                             \	ld	r23,EX_DAR(r21);	/* move DAR to stackframe      */ \	std	r23,_DAR(r1);		                                  \	lwz     r22,EX_DSISR(r21);	/* move DSISR to stackframe    */ \	std	r22,_DSISR(r1);		                                  \	lbz	r22,PACAPROCENABLED(r20);                                 \	std	r22,SOFTE(r1);		                                  \	ld	r22,EX_SRR0(r21);	/* get SRR0 from exc. frame    */ \	ld	r23,EX_SRR1(r21);	/* get SRR1 from exc. frame    */ \	addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame     */ \	std     r21,PACAEXCSP(r20);                                       \	SAVE_GPR(0, r1);                /* save r0 in stackframe       */ \	SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \	SAVE_4GPRS(10, r1);                                               \	ld      r2,PACATOC(r20);	                                  \	ld      r13,PACACURRENT(r20)/* * Note: code which follows this uses cr0.eq (set if from kernel), * r1, r22 (SRR0), and r23 (SRR1). *//* * Exception vectors. */#define STD_EXCEPTION_PSERIES(n, label )	\	. = n;					\	.globl label##_Pseries;			\label##_Pseries:				\	EXCEPTION_PROLOG_PSERIES( n, label##_common )#define STD_EXCEPTION_ISERIES( n, label )	\	.globl label##_Iseries;			\label##_Iseries:				\	EXCEPTION_PROLOG_ISERIES( n );          \	b	label##_common#define MASKABLE_EXCEPTION_ISERIES( n, label )	\	.globl label##_Iseries;			\label##_Iseries:				\	EXCEPTION_PROLOG_ISERIES( n );		\	lbz	r22,PACAPROFENABLED(r20);	\	cmpi	0,r22,0;			\	bne-	label##_Iseries_profile;	\label##_Iseries_prof_ret:			\	lbz	r22,PACAPROCENABLED(r20);	\	cmpi	0,r22,0;			\	beq-	label##_Iseries_masked;		\	b	label##_common;			\label##_Iseries_profile:			\	std	r24,48(r21);			\	std	r25,56(r21);			\	mflr	r24;				\	bl	do_profile;			\	mtlr	r24;				\	ld	r24,48(r21);			\	ld	r25,56(r21);			\	b	label##_Iseries_prof_ret#define STD_EXCEPTION_COMMON( trap, label, hdlr )	\	.globl label##_common;			\label##_common:					\	EXCEPTION_PROLOG_COMMON;		\	addi	r3,r1,STACK_FRAME_OVERHEAD;	\	li	r20,0;				\	li	r6,trap;			\	bl      .save_remaining_regs;           \	bl      hdlr;                           \	b       .ret_from_except/* * Start of pSeries system interrupt routines */	. = 0x100	.globl __start_interupts__start_interupts:	STD_EXCEPTION_PSERIES( 0x100, SystemReset )	STD_EXCEPTION_PSERIES( 0x200, MachineCheck )	STD_EXCEPTION_PSERIES( 0x300, DataAccess )	STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB )	STD_EXCEPTION_PSERIES( 0x400, InstructionAccess )	STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB )	STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt )	STD_EXCEPTION_PSERIES( 0x600, Alignment )	STD_EXCEPTION_PSERIES( 0x700, ProgramCheck )	STD_EXCEPTION_PSERIES( 0x800, FPUnavailable )	STD_EXCEPTION_PSERIES( 0x900, Decrementer )	STD_EXCEPTION_PSERIES( 0xa00, Trap_0a )	STD_EXCEPTION_PSERIES( 0xb00, Trap_0b )	STD_EXCEPTION_PSERIES( 0xc00, SystemCall )	STD_EXCEPTION_PSERIES( 0xd00, SingleStep )	STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )	STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor )	STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )	/* Space for the naca.  Architected to be located at real address	 * 0x4000.  Various tools rely on this location being fixed.	 * The first dword of the Naca is required by iSeries LPAR to	 * point to itVpdAreas.  On pSeries native, this value is not used.	 */	. = 0x4000	.globl __end_interupts	.globl __start_naca__end_interupts:__start_naca:	.llong itVpdAreas	.llong 0x0	.llong 0x0	.llong paca	/*	 * Space for the initial segment table	 * For LPAR, the hypervisor must fill in at least one entry	 * before we get control (with relocate on)	 */	. = 0x5000	.globl __end_naca	.globl __start_stab__end_naca:__start_stab:	. = 0x6000	.globl __end_stab__end_stab:	/*	 * The iSeries LPAR map is at this fixed address	 * so that the HvReleaseData structure can address	 * it with a 32-bit offset.	 *	 * The VSID values below are dependent on the	 * VSID generation algorithm.  See include/asm/mmu_context.h.	 */	.llong	1		/* # ESIDs to be mapped by hypervisor         */	.llong	1		/* # memory ranges to be mapped by hypervisor */	.llong	5		/* Page # of segment table within load area   */	.llong	0		/* Reserved */	.llong  0		/* Reserved */	.llong  0		/* Reserved */	.llong	0		/* Reserved */	.llong	0		/* Reserved */	.llong	0x0c00000000	/* ESID to map (Kernel at EA = 0xC000000000000000) */	.llong	0x06a99b4b14    /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */	.llong	8192		/* # pages to map (32 MB) */	.llong	0		/* Offset from start of loadarea to start of map */	.llong	0x0006a99b4b140000	/* VPN of first page to map */	. = 0x6100/***  ISeries-LPAR interrupt handlers ***/	STD_EXCEPTION_ISERIES( 0x200, MachineCheck )	STD_EXCEPTION_ISERIES( 0x300, DataAccess )	STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )	STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )	STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )	MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )	STD_EXCEPTION_ISERIES( 0x600, Alignment )	STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )	STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )	MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )	STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )	STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )	STD_EXCEPTION_ISERIES( 0xc00, SystemCall )	STD_EXCEPTION_ISERIES( 0xd00, SingleStep )	STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )	STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )	.globl SystemReset_IseriesSystemReset_Iseries:	mfspr	25,SPRG3		/* Get paca address */	lhz	r24,PACAPACAINDEX(r25)	/* Get processor # */	cmpi	0,r24,0			/* Are we processor 0? */	beq	.__start_initialization_iSeries	/* Start up the first processor */	mfspr	r4,CTRLF	li	r5,RUNLATCH		/* Turn off the run light */	andc	r4,r4,r5	mtspr	CTRLT,r41:	HMT_LOW#ifdef CONFIG_SMP	lbz	r23,PACAPROCSTART(r25)	/* Test if this processor					 * should start */	sync	LOADADDR(r3,current_set)	sldi	r28,r24,4		/* get current_set[cpu#] */	ldx	r3,r3,r28	addi	r1,r3,TASK_UNION_SIZE	subi	r1,r1,STACK_FRAME_OVERHEAD	cmpi	0,r23,0	beq	iseries_secondary_smp_loop	/* Loop until told to go */#ifdef SECONDARY_PROCESSORS	bne	.__secondary_start		/* Loop until told to go */#endifiseries_secondary_smp_loop:	/* Let the Hypervisor know we are alive */	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */	lis	r3,0x8002	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */#else /* CONFIG_SMP */	/* Yield the processor.  This is required for non-SMP kernels	   which are running on multi-threaded machines. */	lis	r3,0x8000	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */	li	r4,0			/* "yield timed" */	li	r5,-1			/* "yield forever" */

⌨️ 快捷键说明

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