arch/powerpc/kernel/head_booke.h

Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/head_booke.h

File Facts

System
Linux kernel
Corpus path
arch/powerpc/kernel/head_booke.h
Extension
.h
Size
18475 bytes
Lines
527
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __HEAD_BOOKE_H__
#define __HEAD_BOOKE_H__

#include <asm/ptrace.h>	/* for STACK_FRAME_REGS_MARKER */
#include <asm/kvm_asm.h>
#include <asm/kvm_booke_hv_asm.h>
#include <asm/thread_info.h>	/* for THREAD_SHIFT */

#ifdef __ASSEMBLER__

/*
 * Macros used for common Book-e exception handling
 */

#define SET_IVOR(vector_number, vector_label)		\
		li	r26,vector_label@l; 		\
		mtspr	SPRN_IVOR##vector_number,r26;	\
		sync

#if (THREAD_SHIFT < 15)
#define ALLOC_STACK_FRAME(reg, val)			\
	addi reg,reg,val
#else
#define ALLOC_STACK_FRAME(reg, val)			\
	addis	reg,reg,val@ha;				\
	addi	reg,reg,val@l
#endif

/*
 * Macro used to get to thread save registers.
 * Note that entries 0-3 are used for the prolog code, and the remaining
 * entries are available for specific exception use in the event a handler
 * requires more than 4 scratch registers.
 */
#define THREAD_NORMSAVE(offset)	(THREAD_NORMSAVES + (offset * 4))

#ifdef CONFIG_PPC_E500
#define BOOKE_CLEAR_BTB(reg)									\
START_BTB_FLUSH_SECTION								\
	BTB_FLUSH(reg)									\
END_BTB_FLUSH_SECTION
#else
#define BOOKE_CLEAR_BTB(reg)
#endif


#define NORMAL_EXCEPTION_PROLOG(trapno, intno)						     \
	mtspr	SPRN_SPRG_WSCRATCH0, r10;	/* save one register */	     \
	mfspr	r10, SPRN_SPRG_THREAD;					     \
	stw	r11, THREAD_NORMSAVE(0)(r10);				     \
	stw	r13, THREAD_NORMSAVE(2)(r10);				     \
	mfcr	r13;			/* save CR in r13 for now	   */\
	mfspr	r11, SPRN_SRR1;		                                     \
	DO_KVM	BOOKE_INTERRUPT_##intno SPRN_SRR1;			     \
	andi.	r11, r11, MSR_PR;	/* check whether user or kernel    */\
	LOAD_REG_IMMEDIATE(r11, MSR_KERNEL);				\
	mtmsr	r11;							\
	mr	r11, r1;						     \
	beq	1f;							     \
	BOOKE_CLEAR_BTB(r11)						\
	/* if from user, start at top of this thread's kernel stack */       \
	lwz	r11, TASK_STACK - THREAD(r10);				     \
	ALLOC_STACK_FRAME(r11, THREAD_SIZE);				     \
1 :	subi	r11, r11, INT_FRAME_SIZE; /* Allocate exception frame */     \
	stw	r13, _CCR(r11);		/* save various registers */	     \
	stw	r12,GPR12(r11);						     \
	stw	r9,GPR9(r11);						     \
	mfspr	r13, SPRN_SPRG_RSCRATCH0;				     \
	stw	r13, GPR10(r11);					     \
	lwz	r12, THREAD_NORMSAVE(0)(r10);				     \
	stw	r12,GPR11(r11);						     \
	lwz	r13, THREAD_NORMSAVE(2)(r10); /* restore r13 */		     \
	mflr	r10;							     \
	stw	r10,_LINK(r11);						     \
	mfspr	r12,SPRN_SRR0;						     \
	stw	r1, GPR1(r11);						     \
	mfspr	r9,SPRN_SRR1;						     \
	stw	r1, 0(r11);						     \
	mr	r1, r11;						     \
	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
	COMMON_EXCEPTION_PROLOG_END trapno

.macro COMMON_EXCEPTION_PROLOG_END trapno
	stw	r0,GPR0(r1)
	lis	r10, STACK_FRAME_REGS_MARKER@ha	/* exception frame marker */
	addi	r10, r10, STACK_FRAME_REGS_MARKER@l
	stw	r10, STACK_INT_FRAME_MARKER(r1)
	li	r10, \trapno
	stw	r10,_TRAP(r1)
	SAVE_GPRS(3, 8, r1)

Annotation

Implementation Notes