liufei_learning--脚踏实地,戒骄戒躁!

每天叫醒自己的是闹钟,而让自己起床的是梦想!

S3C2440裸机驱动--2440slib.s

//===================================================================
// File Name : 2440slib.h
// Function  : TQ2440 
// Version   : 1.0
//===================================================================

#ifndef __2440slib_h__
#define __2440slib_h__

#ifdef __cplusplus
extern "C" {
#endif

int SET_IF(void);    //设置CPSR的I位(IRQ)和F位(FIQ),禁止I和F中断,并返回当前的CPSR_CXSF
void WR_IF(int cpsrValue); //写值到CPSR
void CLR_IF(void);     //;把中断位清零,即允许IRQ中断和FIQ中断

void EnterCritical(U32 *pSave);  //!用内存单元r0存储CPSR	
void ExitCritical(U32 *pSave);   //!把当前SPSR的内容保存到寄存器r0中

void MMU_EnableICache(void);  //使能指令Cache
void MMU_DisableICache(void); //禁止指令Cache
void MMU_EnableDCache(void);  //当地址Cache数据Cache分开时,使能数据Cache;
                              //当地址Cache数据Cache统一时,使能整个Cache;
void MMU_DisableDCache(void); // 当地址Cache数据Cache分开时,禁止数据Cache;
                              //当地址Cache数据Cache统一时,禁止整个Cache 
                     
void MMU_EnableAlignFault(void);  //使能地址对齐检查功能
void MMU_DisableAlignFault(void); //禁止地址对齐检查功能
void MMU_EnableMMU(void);         //使能MMU
void MMU_DisableMMU(void);        //禁止MMU
void MMU_SetTTBase(U32 base);    //写地址转化表基地址(页表基地址)到C2

//MMU将整个存储空间分成16个域(domain),每个域具有相同的访问属性
//C3用于设置域的属性
void MMU_SetDomain(U32 domain);  //设置域属性

void MMU_SetFastBusMode(void);  //GCLK=HCLK  快速总线模式
void MMU_SetAsyncBusMode(void); //GCLK=FCLK @(FCLK>=HCLK) 异步总线模式

void MMU_InvalidateIDCache(void); //使无效整个统一的cache,或者使无效整个数据cache和指令cache
void MMU_InvalidateICache(void);  //使无效整个指令cache
void MMU_InvalidateICacheMVA(U32 mva); //使无效指令cache的某块mva,并把数据(虚拟地址)写到C7
void MMU_PrefetchICacheMVA(U32 mva);  //预取指令cache中的某块mva,并把数据(虚拟地址)写到C7 

void MMU_InvalidateDCache(void); //使无效整个数据cache-
void MMU_InvalidateDCacheMVA(U32 mva); //使无效数据cache的某块mva,并把数据(虚拟地址)写到C7

void MMU_CleanDCacheMVA(U32 mva); //清空数据cache中的某块mva,并把数据(虚拟地址)写到C7
void MMU_CleanInvalidateDCacheMVA(U32 mva); //清空并无效数据Cache中的某块mva,并把数据(虚拟地址)写到C7
void MMU_CleanDCacheIndex(U32 index);  //清空数据cache中的某块Index,并把组号组内序号写到C7中
void MMU_CleanInvalidateDCacheIndex(U32 index);	  //清空并无效数据cache中的某块index,并把组号组内序号写到C7中

//等待中断激活,使ARM进入节能状态,停止执行等待中断激活。
//当异常中断IRQ或FIQ发生后,该MCR指令进入IRQ或FIQ中断处理程序执行。
void MMU_WaitForInterrupt(void);

//快表操作
void MMU_InvalidateTLB(void); //使无效整个统一的cache或者使无效整个数据cache和指令cache
void MMU_InvalidateITLB(void); //使无效整个指令cache-
void MMU_InvalidateITLBMVA(U32 mva); //使无效指令cache的单个地址变换条目mva,并把虚拟地址返回到C8
void MMU_InvalidateDTLB(void);  //使无效整个数据cache-
void MMU_InvalidateDTLBMVA(U32 mva); //  使无效数据cache的单个地址变换条目mva,并把虚拟地址返回到C8

void MMU_SetDCacheLockdownBase(U32 base); //锁数据cache
void MMU_SetICacheLockdownBase(U32 base); //锁指令cache

void MMU_SetDTLBLockdown(U32 baseVictim); // 锁数据快表
void MMU_SetITLBLockdown(U32 baseVictim); // 锁指令快表

void MMU_SetProcessId(U32 pid); // 获得进程标识符

#ifdef __cplusplus
}
#endif

#endif   //__2440slib_h__

;=====================================================================
; File Name : 2440slib.s
; Function  : TQ2440  (Assembly)
; Revision  : 1.0
;=====================================================================

;Interrupt, FIQ/IRQ disable
NOINT  EQU 0xc0    ; 1100 0000  //1100 0000=CPSR[6]-FIQ中断禁止位,CPSR[7]-IRQ中断禁止位

;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
   GBLL    THUMBCODE	;//定义一个全局逻辑变量THUMBCODE
   [ {CONFIG} = 16		;//if(CONFIG == 16) {
THUMBCODE SETL  {TRUE}	;//	THUMBCODE = TRUE;
	 CODE32				;//}
   |					;//else {
THUMBCODE SETL  {FALSE}	;//	THUMBCODE = FALSE;给逻辑变量赋值
   ]					;//}

   MACRO				;//定义宏
     MOV_PC_LR			;//宏名
     [ THUMBCODE		;//if(THUMBCODE) {
       bx lr			;//	bx = lr;跳转到Thumbcode模式
     |					;//} else {
       mov pc,lr		;//	pc = lr;
     ]					;//}
   MEND					;//宏定义结束
   
   PRESERVE8
   AREA |C$code|, CODE, READONLY  ;//定义一个代码段,名为C$code,只读
   EXPORT	EnterCritical          ;//声明一个符号,可以被其它文件引用,符号的名称为
EnterCritical                       ;//EnterCritical,相当于下面一段程序为EnterCritical函数
	mrs	r1, cpsr		;//mrs用于将程序状态寄存器的内容传送到通用寄存器中.即r1<-cprs
	str	r1, [r0]		;//r1的值存储到[r0]上
	orr	r1, r1, #NOINT	;//逻辑位"或".r1=r1 or NOINT(0x0c)
	msr	cpsr_cxsf, r1	;//msr用于将操作数的内容传送到程序状态寄存器的特定域中.cpsr_cxsf<-r1
	MOV_PC_LR			;//执行上面的宏
;restore cpsr, r0 = address to restore cpsr	
	EXPORT	ExitCritical			;//声明一个ExitCritical符号,可以被其它文件引用
ExitCritical				;//相当于ExitCritical函数
	ldr	r1, [r0]			;//r1<-[r0]
	msr	cpsr_cxsf, r1		;//cpsr_cxsg<-r1
	MOV_PC_LR				;//执行上面的宏
;这里的cxsf表示从低到高分别占用的4个8bit的数据域-
;指令中有时还有出现cpsr_cf, cpsr_all, cpsr_c等,这里:-
;c 指CPSR中的control field ( PSR[7:0])-
;f 指flag field (PSR[31:24])-
;x 指 extend field (PSR[15:8])-
;s 指status field ( PSR[23:16])-
;其中cpsr的位表示为:-
;31 30 29 28 ---   7   6   -   4     3     2     1     0-
;N   Z   C   V         I   F       M4 M3 M2    M1    M0

;==============-	
;==============
; CPSR I,F bit
;==============
;int SET_IF(void);
;The return value is current CPSR.
	EXPORT	SET_IF
SET_IF						;//相当于函数SET_IF
    ;This function works only if the processor is in previliged mode.
   mrs r0,cpsr				;//r0<-cpsr
   mov r1,r0				;//r1 = r0
   orr r1,r1,#NOINT			;//r1=r1 or NOINT(0x0c)
   msr cpsr_cxsf,r1			;//cpsr_cxsf<-r1
   MOV_PC_LR				;//执行上面的宏

;//置位IRQ和FIQ控制位,禁止中断
;void WR_IF(int cpsrValue);
   EXPORT WR_IF						;//声明一个WR_IF符号,可以被其它文件引用
WR_IF						;//相当于函数WR_IF
    ;This function works only if the processor is in previliged mode.
   msr cpsr_cxsf,r0			;//cpsr_cxsf<-r0
   MOV_PC_LR				;//执行上面的宏


;//清零IRQ和FIQ控制位,使能中断
;void CLR_IF(void);
   EXPORT  CLR_IF					;//声明一个CLR_IF符号,可以被其它文件引用
CLR_IF						;//相当于函数CLR_IF
    ;This function works only if the processor is in previliged mode.
   mrs r0,cpsr				;//r0<-cpsr
   bic r0,r0,#NOINT			;//位清0.r0=r0 and (not NOINT)
   msr cpsr_cxsf,r0			;//cpsr_cxsf<-r0
   MOV_PC_LR				;//执行上面的宏
   
   	EXPORT	outportw
outportw	strh	r0, [r1]	;//半字.r1[15:0]<-r0[15:0]
	MOV_PC_LR

	EXPORT	inportw
inportw	ldrh	r0, [r0]		;//半字.
	MOV_PC_LR


;====================================
; MMU Cache/TLB/etc on/off functions
;====================================
R1_I	EQU	(1<<12)		;//Cache分开时,1 使能指令Cache,0 禁止使能Cache
R1_C	EQU	(1<<2)		;//禁止/使能数据Cache或整个Cache,1使能  不含Cache返回0,不能禁止Cache返回1
R1_A	EQU	(1<<1)		;//是否支持内存访问时地址对齐检查系统,1使能
R1_M    EQU	(1)			;//禁止/使能MMU 1使能
R1_iA	EQU	(1<<31)		;//R1_iA = 0b100 0000 0000 0000 0000 0000 0000 0000
R1_nF   EQU	(1<<30)		;//R1_nF = 0b10 0000 0000 0000 0000 0000 0000 0000

;==========================================================
;//MCR指令将ARM处理器的寄存器中的数据传送到协处理器寄存器中
;//MRC指令将协处理器的寄存器中的数值传送到ARM处理器的寄存器中
;==========================================================
;//禁止/使能指令cache
;void MMU_EnableICache(void)
   EXPORT MMU_EnableICache
MMU_EnableICache
   mrc p15,0,r0,c1,c0,0	;//将arm下寄存器r0传送给协处理器寄存器c1
   orr r0,r0,#R1_I		;//r0= r0 or R1_I
   mcr p15,0,r0,c1,c0,0	;//将协处理器寄存器c1传送给arm下寄存器r0
   MOV_PC_LR
   
;R1_I EQU (1<<12) 
;R1_C EQU (1<<2) 
;R1_A EQU (1<<1)
;void MMU_DisableICache(void)
   EXPORT MMU_DisableICache
MMU_DisableICache
   mrc p15,0,r0,c1,c0,0
   bic r0,r0,#R1_I
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;void MMU_EnableDCache(void)
   EXPORT MMU_EnableDCache
MMU_EnableDCache
   mrc p15,0,r0,c1,c0,0
   orr r0,r0,#R1_C
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;禁止数据cache或禁止整个cache,具体查看数据cache和指令cache是否分离
;其中mrc是协处理器命令。用于读取协处理器中的寄存器的数据到ARM处理器的寄存器里面。
;mrc  p15,0,r0,c1,c0,0 这句话的意思应该是读协处理器中的寄存器到ARM处理器的r0里面
; bic  r0,r0,#R1_C 其中有如下定义R1_C    EQU     (1<<2)
;则此句话是将MMU寄存器中的第2位清零,用于禁止数据cache
;mcr  p15,0,r0,c1,c0,0写回到协处理器MMU寄存器 
;MOV_PC_LR 程序返回
;void MMU_DisableDCache(void)
   EXPORT MMU_DisableDCache
MMU_DisableDCache
   mrc p15,0,r0,c1,c0,0;CP15协处理器寄存器到ARM寄存器r0
   bic r0,r0,#R1_C
   mcr p15,0,r0,c1,c0,0;ARM寄存器r0到协处理器CP15寄存器中
   MOV_PC_LR

;void MMU_EnableAlignFault(void)
   EXPORT MMU_EnableAlignFault
MMU_EnableAlignFault
   mrc p15,0,r0,c1,c0,0
   orr r0,r0,#R1_A
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;void MMU_DisableAlignFault(void)
   EXPORT MMU_DisableAlignFault
MMU_DisableAlignFault
   mrc p15,0,r0,c1,c0,0
   bic r0,r0,#R1_A
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;===============================================================================
;//使能/禁止MMU
;//注意:使能/禁止MMU时
;//1、在使能MMU之前,要在内存中建立好页表,同时CP15中的各相关寄存器必须完成初始化。
;//2、如果使用的不是平板存储模式(物理地址和虚拟地址相等),在禁止/使能MMU时虚拟地
;//址和物理地址的对应关系会发生改变,这时应该清楚Cache中的当前地址变换条目。
;//3、如果完成禁止/使能MMU的代码的物理地址和虚拟地址不相同,则禁止/使能MMU时将造成
;//很大麻烦,因此强烈完成禁止/使能MMU的代码的物理地址和虚拟地址最好相同。
;===============================================================================
;void MMU_EnableMMU(void)
   EXPORT MMU_EnableMMU
MMU_EnableMMU
   mrc p15,0,r0,c1,c0,0
   orr r0,r0,#R1_M
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;void MMU_DisableMMU(void)
   EXPORT MMU_DisableMMU
MMU_DisableMMU
   mrc p15,0,r0,c1,c0,0
   bic r0,r0,#R1_M
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;void MMU_SetFastBusMode(void)
; FCLK:HCLK= 1:1
  EXPORT MMU_SetFastBusMode
MMU_SetFastBusMode
   mrc p15,0,r0,c1,c0,0
   bic r0,r0,#R1_iA:OR:R1_nF
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;void MMU_SetAsyncBusMode(void)
; FCLK:HCLK= 1:2
   EXPORT MMU_SetAsyncBusMode
MMU_SetAsyncBusMode
   mrc p15,0,r0,c1,c0,0
   orr r0,r0,#R1_nF:OR:R1_iA
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR

;================================================================================
;//C2用于保存页表的在内存中的基地址
;//页表中每一行对应一个虚地址页对应的实地址页的地址、该位的方位权限和该页的缓冲特性
;//通常把部分页表放在页表缓冲器TLB(translation lookaside buffer)中,换页表时,TLB要清空,因为。。。。
;//C8控制清空TLB
;//C10用于控制TLB中内容的锁定
;====================================================================================================
; Set TTBase
;=========================
;void MMU_SetTTBase(int base)
   EXPORT MMU_SetTTBase
MMU_SetTTBase
   ;ro=TTBase
   mcr p15,0,r0,c2,c0,0
   MOV_PC_LR

;=========================
; Set Domain
;=========================
;void MMU_SetDomain(int domain)
   EXPORT MMU_SetDomain
MMU_SetDomain
   ;ro=domain
   mcr p15,0,r0,c3,c0,0
   MOV_PC_LR

;=========================
; ICache/DCache functions
;=========================
;void MMU_InvalidateIDCache(void)
   EXPORT MMU_InvalidateIDCache
MMU_InvalidateIDCache
   mcr p15,0,r0,c7,c7,0
   MOV_PC_LR

;void MMU_InvalidateICache(void)
   EXPORT MMU_InvalidateICache
MMU_InvalidateICache
   mcr p15,0,r0,c7,c5,0
   MOV_PC_LR

;void MMU_InvalidateICacheMVA(U32 mva)
   EXPORT MMU_InvalidateICacheMVA
MMU_InvalidateICacheMVA
   ;r0=mva
   mcr p15,0,r0,c7,c5,1
   MOV_PC_LR

;void MMU_PrefetchICacheMVA(U32 mva)
   EXPORT MMU_PrefetchICacheMVA
MMU_PrefetchICacheMVA
   ;r0=mva
   mcr p15,0,r0,c7,c13,1
   MOV_PC_LR

;void MMU_InvalidateDCache(void)
   EXPORT MMU_InvalidateDCache
MMU_InvalidateDCache
   mcr p15,0,r0,c7,c6,0
   MOV_PC_LR

;void MMU_InvalidateDCacheMVA(U32 mva)
   EXPORT MMU_InvalidateDCacheMVA
MMU_InvalidateDCacheMVA
   ;r0=mva
   mcr p15,0,r0,c7,c6,1
   MOV_PC_LR

;void MMU_CleanDCacheMVA(U32 mva)
   EXPORT MMU_CleanDCacheMVA
MMU_CleanDCacheMVA
   ;r0=mva
   mcr p15,0,r0,c7,c10,1
   MOV_PC_LR

;void MMU_CleanInvalidateDCacheMVA(U32 mva)
   EXPORT MMU_CleanInvalidateDCacheMVA
MMU_CleanInvalidateDCacheMVA
   ;r0=mva
   mcr p15,0,r0,c7,c14,1
   MOV_PC_LR

;void MMU_CleanDCacheIndex(U32 index)
   EXPORT MMU_CleanDCacheIndex
MMU_CleanDCacheIndex
   ;r0=index
   mcr p15,0,r0,c7,c10,2
   MOV_PC_LR

;void MMU_CleanInvalidateDCacheIndex(U32 index)
   EXPORT MMU_CleanInvalidateDCacheIndex
MMU_CleanInvalidateDCacheIndex
   ;r0=index
   mcr p15,0,r0,c7,c14,2
   MOV_PC_LR

;void MMU_WaitForInterrupt(void)
   EXPORT MMU_WaitForInterrupt
MMU_WaitForInterrupt
   mcr p15,0,r0,c7,c0,4
   MOV_PC_LR

;==================================================================================================
; TLB functions快表TLB功能(C8)-
;C8控制控制清楚TLB的相关操作的。它是一个只写的寄存器。使用MRC指令读取该寄存器,将产生不可预知效果。
;指令具体格式如下:
;MCR P15,0,<Rd>,<C8>,<CRm>,<opcode_2>
;<CRm>,<opcode_2>的不同的组合决定指令执行的不同的操作。完成操作将产生的数据写到Rd,然后写到C8。
;===================================================================================================
;===============
; TLB functions
;===============
;voic MMU_InvalidateTLB(void)
   EXPORT MMU_InvalidateTLB
MMU_InvalidateTLB
   mcr p15,0,r0,c8,c7,0
   MOV_PC_LR

;void MMU_InvalidateITLB(void)
   EXPORT MMU_InvalidateITLB
MMU_InvalidateITLB
   mcr p15,0,r0,c8,c5,0
   MOV_PC_LR

;void MMU_InvalidateITLBMVA(U32 mva)
   EXPORT MMU_InvalidateITLBMVA
MMU_InvalidateITLBMVA
   ;ro=mva
   mcr p15,0,r0,c8,c5,1
   MOV_PC_LR

;void MMU_InvalidateDTLB(void)
	EXPORT MMU_InvalidateDTLB
MMU_InvalidateDTLB
	mcr p15,0,r0,c8,c6,0
	MOV_PC_LR

;void MMU_InvalidateDTLBMVA(U32 mva)
	EXPORT MMU_InvalidateDTLBMVA
MMU_InvalidateDTLBMVA
	;r0=mva
	mcr p15,0,r0,c8,c6,1
	MOV_PC_LR

;=================
; Cache lock down
;=================
;void MMU_SetDCacheLockdownBase(U32 base)
   EXPORT MMU_SetDCacheLockdownBase
MMU_SetDCacheLockdownBase
   ;r0= victim & lockdown base
   mcr p15,0,r0,c9,c0,0
   MOV_PC_LR

;void MMU_SetICacheLockdownBase(U32 base)
   EXPORT MMU_SetICacheLockdownBase
MMU_SetICacheLockdownBase
   ;r0= victim & lockdown base
   mcr p15,0,r0,c9,c0,1
   MOV_PC_LR

;=================
; TLB lock down
;=================
;void MMU_SetDTLBLockdown(U32 baseVictim)
   EXPORT MMU_SetDTLBLockdown
MMU_SetDTLBLockdown
   ;r0= baseVictim
   mcr p15,0,r0,c10,c0,0
   MOV_PC_LR

;void MMU_SetITLBLockdown(U32 baseVictim)
   EXPORT MMU_SetITLBLockdown
MMU_SetITLBLockdown
   ;r0= baseVictim
   mcr p15,0,r0,c10,c0,1
   MOV_PC_LR

;============
; Process ID
;============
;void MMU_SetProcessId(U32 pid)
   EXPORT MMU_SetProcessId
MMU_SetProcessId
   ;r0= pid
   mcr p15,0,r0,c13,c0,0
   MOV_PC_LR

   END



参考连接:


http://blog.163.com/anotherplace@126/blog/static/12826854420099611462382/ 

http://hi.baidu.com/yeshiliang1987/blog/item/0e8b028e9f9066f6503d9277.html 


            
阅读更多
个人分类: S3C2440裸机驱动
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭