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

📄 cpu_asm.s

📁 T-kernel 的extension源代码
💻 S
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	cpu_asm.S (memory) * *	SH7727-dependent functions */#define _in_asm_source_#include <machine.h>#include <tk/asm.h>#include <sys/sysinfo.h>#include <sys/memdef.h>#include "cpu_asm.h"/* * Call system program * ER CallSysProgInit( INT ac, UB *av[], FP entry ) */	.text	.balign	2	.globl	Csym(CallSysProgInit)	.type	Csym(CallSysProgInit), @functionCsym(CallSysProgInit):	mov.l	r8,  @-SP		// Save register	mov.l	r9,  @-SP	mov.l	r10, @-SP	mov.l	r11, @-SP	mov.l	r12, @-SP	mov.l	r13, @-SP	mov.l	r14, @-SP	sts.l	pr,  @-SP	jsr	@r6			// call entry(ac, av)	nop	lds.l	@SP+, pr		// Restore register	mov.l	@SP+, r14	mov.l	@SP+, r13	mov.l	@SP+, r12	mov.l	@SP+, r11	mov.l	@SP+, r10	mov.l	@SP+, r9	rts	mov.l	@SP+, r8/* ------------------------------------------------------------------------ *//* * Dedicated stack for page fault handler *	Used as virtual memory within page fault handler *	System stack cannot be used. */#define	PAGEFAULTHDR_STACKSZ	(3 * 1024)#define	PAGEFAULTHDR_STACKTOP	(pagefaulthdr_stack + PAGEFAULTHDR_STACKSZ)	.lcomm	pagefaulthdr_stack, PAGEFAULTHDR_STACKSZ/* * Page fault handler entry *	TA_ASM-format handler */	.text	.balign	2	.globl	Csym(asmPageFaultHdr)	.type	Csym(asmPageFaultHdr), @functionCsym(asmPageFaultHdr):	/* SR.BL=1, SR.RB=1, SR.I=15 */	mov.l	r0, @-ISP	// R0_BANK1 (Vector index + factor) Save	mov.l	r4, @-ISP	// R4_BANK1 Save	mov.l	SP, @-ISP		// For page fault handler only	mov.l	P_STACKTOP, r0		// Use stack.	mov.l	P_STACKLIMIT, r4	cmp/hi	r4, SP	bf	l_chgstk	cmp/hs	SP, r0	bt	l_nochgstk  l_chgstk:	mov	r0, SP  l_nochgstk:	stc.l	r4_bank, @-SP		// Save register	stc.l	r5_bank, @-SP	stc.l	r6_bank, @-SP	mov.l	P_EXPEVT, r7		// Obtain exception information.	mov.l	P_TEA, r0	mov.l	@r7, r4			// Save EXPEVT in r4_bank1.	mov.l	P_MMUCR, r7	ldc	r4, r4_bank		// r4_bank0 = EXPEVT	ldc.l	@r0+, r5_bank		// r5_bank0 = TEA	ldc.l	@r7+, r6_bank		// r6_bank0 = MMUCR	mov.l	P_SR_NOBLOCK, r7	// Reset exception block.	ldc	r7, sr			// Switch register banks.	/* SR.BL=0, SR.RB=0, SR.I=15 */	mov.l	r0, @-SP		// Save register	mov.l	r1, @-SP	mov.l	r2, @-SP	mov.l	r3, @-SP	mov.l	r7, @-SP	sts.l	mach, @-SP	sts.l	macl, @-SP	sts.l	pr, @-SP	mov.l	P_HDRENT, r0	jsr	@r0			// call PageFaultHdr(EXPEVT,TEA,MMUCR)	nop	ldc	r0, r0_bank		// Save return value in r0_bank1.	lds.l	@SP+, pr		// Restore register	lds.l	@SP+, macl	lds.l	@SP+, mach	mov.l	@SP+, r7	mov.l	@SP+, r3	mov.l	@SP+, r2	mov.l	@SP+, r1	mov.l	@SP+, r0	mov.l	@SP+, r6	mov.l	@SP+, r5	mov.l	P_SR_NOBL_RB, r4	// Switch register banks.	ldc	r4, sr	/* SR.BL=0, SR.RB=1, SR.I=15 */	ldc.l	@SP+, r4_bank		// R4_BANK0 Restore	mov.l	@ISP+, SP		// Turn back stack	tst	r0, r0	bf	l_enter_bms	mov.l	@ISP+, r4		// R4_BANK1 Restore	mov.l	@ISP+, r0		// R0_BANK1 Restore	trapa	#TRAP_RETINT		// ret_int()  l_enter_bms:	mov.l	P_SR_BLOCK, r0		// Exception block	ldc	r0, sr	/* SR.BL=1, SR.RB=1, SR.I=15 */	mov.l	P_DEFHDR, r7	mov.l	P_EXPEVT, r0	mov.l	@r7, r7	mov.l	r4, @r0			// Restore exception code in  EXPEVT.	mov.l	@ISP+, r4		// R4_BANK1 Restore	jmp	@r7			// To BMS default handler.	mov.l	@ISP+, r0		// R0_BANK1 Restore/* * Provisional page fault handler entry *	Used provisionally until T-Kernel starts. *	Switched to a regular page fault handler after T-Kernel startup. */	.text	.balign	2	.globl	Csym(asmTmpPageFaultHdr)	.type	Csym(asmTmpPageFaultHdr), @functionCsym(asmTmpPageFaultHdr):	/* SR.BL=1, SR.RB=1, SR.I=15 */	stc.l	r4_bank, @-ISP		// Save register	stc.l	r5_bank, @-ISP	stc.l	r6_bank, @-ISP	mov.l	SP, @-ISP		// For page fault handler only	mov.l	P_STACKTOP, SP		// Use stack.	mov.l	P_EXPEVT, r7		// Obtain exception information.	mov.l	P_TEA, r0	ldc.l	@r7+, r4_bank		// r4_bank0 = EXPEVT	mov.l	P_MMUCR, r7	ldc.l	@r0+, r5_bank		// r5_bank0 = TEA	ldc.l	@r7+, r6_bank		// r6_bank0 = MMUCR	mov.l	P_SR_NOBLOCK, r7	// Reset exception block.	ldc	r7, sr			// Switch register banks.	/* SR.BL=0, SR.RB=0, SR.I=15 */	mov.l	r0, @-SP		// Restore register	mov.l	r1, @-SP	mov.l	r2, @-SP	mov.l	r3, @-SP	mov.l	r7, @-SP	sts.l	mach, @-SP	sts.l	macl, @-SP	sts.l	pr, @-SP	mov.l	P_TMPHDR, r0	jsr	@r0		// call TmpPageFaultHdr(EXPEVT,TEA,MMUCR)	nop	lds.l	@SP+, pr		// Restore register	lds.l	@SP+, macl	lds.l	@SP+, mach	mov.l	@SP+, r7	mov.l	@SP+, r3	mov.l	@SP+, r2	mov.l	@SP+, r1	mov.l	@SP+, r0	mov.l	P_SR_BLOCK, r4		// Exception block	ldc	r4, sr			// Switch register banks.	/* SR.BL=1, SR.RB=1, SR.I=15 */	mov.l	@ISP+, SP		// Turn back stack	ldc.l	@ISP+, r6_bank		// Restore register	ldc.l	@ISP+, r5_bank	ldc.l	@ISP+, r4_bank	INT_RETURN asmTmpPageFaultHdr	/* Entry address of BMS default handler */	.comm	Csym(DefaultHandlerEntry), 4, 4		.balign	4  P_STACKTOP:	.long	PAGEFAULTHDR_STACKTOP  P_STACKLIMIT:	.long	pagefaulthdr_stack  P_EXPEVT:	.long	EXPEVT  P_TEA:	.long	TEA  P_MMUCR:	.long	MMUCR  P_DEFHDR:	.long	Csym(DefaultHandlerEntry)  P_HDRENT:	.long	Csym(PageFaultHdr)  P_TMPHDR:	.long	Csym(TmpPageFaultHdr)  P_SR_NOBLOCK:	.long	SR_MD | SR_I(15)  P_SR_NOBL_RB:	.long	SR_MD | SR_I(15) | SR_RB  P_SR_BLOCK:	.long	SR_MD | SR_I(15) | SR_RB | SR_BL/* * TLB miss exception handler *	All processing has to be performed without changing the exception block (SR.BL=1). */	.text	.balign	2	.globl	Csym(asmTLBMissHdr)	.type	Csym(asmTLBMissHdr), @functionCsym(asmTLBMissHdr):	/* SR.BL=1, SR.RB=1 */	mov.l	r0, @-ISP		// Save work register.	mov.l	r8, @-ISP	mov.l	r9, @-ISP	mov.l	T_PTEH, r7	mov	#-22, r0	mov.l	@r7, r8	mov	#10, r7	mov	r8, r9	shld	r0, r8			// r8 = Page directory index	shld	r7, r9	shld	r0, r9			// r9 = Page table index	mov	#NUM_PDIR_ENTRIES, r0	mov.l	T_TTB, r7	cmp/ge	r0, r8	bf	l_localspace	mov.l	T_SATB, r7  l_localspace:	mov.l	@r7, r0			// r0 = Page directory	movt	r7			// r7 = 1:Shared space 0:Unique space	tst	r0, r0			// If TTB or SATB is NULL, the address is invalid.	bt	l_notpresent	shll2	r8	mov.l	@(r0, r8), r0	mov.l	T_PBIT, r8	tst	r8, r0			// Check the existence of page table.	bt	l_notpresent	mov.l	T_PFAMSK, r8	and	r8, r0			// r0 = Page table	shll2	r9	add	r0, r9	mov.l	@r9, r0			// r0 = PTE	mov.l	T_PBIT, r8	tst	r8, r0			// Check the existence of page.	bt	l_notpresent	or	#PT_Accessed, r0	mov.l	r0, @r9			// Update access bit.  l_loadtlb:	mov.l	T_TLBMSK, r8	and	r8, r0			// Omit bits used by OS.	shll	r7			// Set shared bits.	add	#TLB_PageSize4K, r7	// Set page size 4KB (fixed)	or	r7, r0			// r0 = TLB loading value	mov.l	T_PTEL, r7	mov.l	r0, @r7	ldtlb				// Load into TLB.	mov.l	@ISP+, r9		// Restore work register.	mov.l	@ISP+, r8	mov.l	@ISP+, r0	rte	nop  l_notpresent:	bra	l_loadtlb	mov	#PTE_NONE, r0		// Invalid PTE		.balign	4  T_SATB:	.long	Csym(SATB)  T_TTB:	.long	TTB  T_PTEH:	.long	PTEH  T_PTEL:	.long	PTEL  T_PBIT:	.long	PT_Present  T_PFAMSK:	.long	PT_Address  T_TLBMSK:	.long	TLB_MASK/* * TLB exception handler for re-startup processing *	TLB TLB invalid exception (read) *	TLB TLB miss exception */	.text	.balign	2	.globl	Csym(warmBootTLBInvRHdr)	.globl	Csym(warmBootTLBMissHdr)	.type	Csym(warmBootTLBInvRHdr), @function	.type	Csym(warmBootTLBMissHdr), @functionCsym(warmBootTLBInvRHdr):	mov.l	@ISP+, r0	// R0  Restore	ldc.l	@ISP+, spc	// SPC Restore	ldc.l	@ISP+, ssr	// SSR Restore	mov.l	@ISP+, MDR	// MDR RestoreCsym(warmBootTLBMissHdr):	/* SR.BL=1, SR.RB=1 */	mov.l	r0, @-ISP		// Save register	mov.l	r8, @-ISP	mov.l	r9, @-ISP	mov.l	W_PTEH, r7	mov	#-22, r0	mov.l	@r7, r8	mov	#10, r7	mov	r8, r9	shld	r0, r8			// r8 = Page directory index	shld	r7, r9	shld	r0, r9			// r9 = Page table index	mov.l	W_TTB, r7	mov.l	@r7, r0			// r0 = Page directory	shll2	r8	mov.l	@(r0, r8), r0	mov.l	W_PFAMSK, r8	and	r8, r0			// r0 = Page table	shll2	r9	mov.l	W_TLBMSK, r7	mov.l	@(r0, r9), r0		// r0 = PTE	and	r7, r0			// Omit bits used by OS.	or	#TLB_PageSize4K|TLB_Share, r0	// Set shared page size.	mov.l	W_PTEL, r7	mov.l	r0, @r7	ldtlb				// Load into TLB.	mov.l	@ISP+, r9	mov.l	@ISP+, r8	mov.l	@ISP+, r0	rte	nop		.balign	4  W_PTEH:	.long	PTEH  W_PTEL:	.long	PTEL  W_TTB:	.long	TTB  W_PFAMSK:	.long	PT_Address  W_TLBMSK:	.long	TLB_MASK/* ------------------------------------------------------------------------ *//* * Switch logical spaces *	UW r2 = changeLogicalSpace( UW r5 = pteh ) *	For register r5, specify "pteh = lsid". *	To register r2, return PTEH before change. *	Registers r1, r2 and r5 are destroyed. The other registers are saved. */	.text	.balign	2	.type	changeLogicalSpace, @functionchangeLogicalSpace:	mov.l	S_PTEH, r1	mov.l	@r1, r2			// r2 = Save PTEH before change.	mov.l	r5, @r1			// Change PTEH	extu.b	r5, r5	mov	#NUM_PDIR_ENTRIES_SHIFT + 2, r1	shld	r1, r5	mov.l	S_UATB, r1	mov.l	@r1, r1	add	r1, r5	mov.l	S_TTB, r1	mov.l	r5, @r1			// Change TTB	rts	nop		.balign	4  S_UATB:	.long	Csym(UATB)  S_PTEH:	.long	PTEH  S_TTB:	.long	TTB/* ------------------------------------------------------------------------ *//* *	Cache-related * *	In cache control, the program itself needs to be a non-cache area. *	Therefore, run the program using a shadow image in P2 area. *//* * Flush memory cache (both instruction/data caches) *	void _ExtFlushCache( VP laddr, UW lsid ) *	Flush (write back) a page (4KB) that contains laddr and cancel it. *	Do not specify an invalid page (PTE.p=0). */	.text	.balign	2	.globl	Csym(_ExtFlushCache)	.type	Csym(_ExtFlushCache), @functionCsym(_ExtFlushCache):	sts.l	pr, @-SP	mov.l	C_PageMask, r0	and	r0, r4			// r4 = Page start address	stc	sr, r3			// r3 = SR Save	mov.l	C_SR_DisInt, r0	ldc	r0, sr	bsr	changeLogicalSpace	// Switch logical spaces	nop				// r2 = Save PTEH (logical space ID)	mov.l	C_GOTO_P2, r0	braf	r0			// Jump to P2 area.	nop	mov.l	C_CArray, r0	mov.l	C_PageSize, r1	mov.l	C_CTagMask, r6  fc_loop:	add	#-CACHE_LINESZ, r1	mov	r4, r7			// r4 = laddr	or	r1, r7			// r1 = ent	and	r6, r7			// (laddr | ent) & TagMask	mov.l	r7, @(r0, r1)		// Write back and cancel	tst	r1, r1	bf	fc_loop	bsr	changeLogicalSpace	// Turn back logical space.	mov	r2, r5	ldc	r3, sr			// Reset interrupt-disabled state (to original state)	lds.l	@SP+, pr	rts	nop		.balign	4  C_CArray:	.long	CACHE_ADR_TOP | CACHE_A  C_CTagMask:	.long	CACHE_TAG  C_PageSize:	.long	PAGESIZE  C_PageMask:	.long	~(PAGESIZE-1)  C_SR_DisInt:	.long	SR_MD | SR_I(15)  C_GOTO_P2:	.long	0x20000000/* ------------------------------------------------------------------------ *//* *	TLB-related *//* * Purge the whole TLB *	void PurgeAllTLB( void ) */	.text	.balign	2	.globl	Csym(PurgeAllTLB)	.type	Csym(PurgeAllTLB), @functionCsym(PurgeAllTLB):	stc	sr, r3			// r3 = SR Save	mov.l	T_SR_DisInt, r0	ldc	r0, sr			// Interrupt-disabled	mov	#MMUCR, r1	mov.l	@r1, r0	or	#MMU_TF, r0	mov.l	r0, @r1			// MMUCR TF=1	nop	ldc	r3, sr			// Reset interrupt-disabled state (to original state)	rts	nop/* * Load into TLB *	void _LoadTLB( VP laddr, UW lsid, UW pte, UW mmucr ) *	Laddr must be located at the start of page. *	The current logical space must match lsid. *	Called in interrupt-disabled state and used for TLB exception handler only. */	.text	.balign	2	.globl	Csym(_LoadTLB)	.type	Csym(_LoadTLB), @functionCsym(_LoadTLB):	mov.l	T_TLB_MASK, r0	mov.l	T_SharedSpace, r1	and	r6, r0			// r6 = pte	cmp/hs	r1, r4	bf/s	lt_localspace	or	#TLB_PageSize4K, r0	// Specify page size (fixed at 4KB).	or	#TLB_Share, r0		// Specify shared state.  lt_localspace:	or	r4, r5			// laddr | lsid	mov.l	T_MMU_Base, r1	mov.l	r7, @(MMUCR - MMU_Base, r1)	// Specify "MMUCR = RC".	mov.l	r5, @(PTEH  - MMU_Base, r1)	// PTEH = laddr | lsid	mov.l	r0, @(PTEL  - MMU_Base, r1)	// PTEL = pte	ldtlb	nop	rts	nop			.balign	4  T_MMU_Base:		.long	MMU_Base  T_TLB_MASK:		.long	TLB_MASK  T_SharedSpace:	.long	LOCALSPACE_END  T_SR_DisInt:		.long	SR_MD | SR_I(15)/* ------------------------------------------------------------------------ */

⌨️ 快捷键说明

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