历史上的今天
今天是:2025年06月04日(星期三)
2018年06月04日 | S3C2440之MMU驱动代码模板(RealView MDK)
2018-06-04 来源:eefocus
好记心不如烂笔头,为方便以后查看代码及代码重复利用,这里贴出自己写的S3C2440 MMU代码库。使用友善MINI2440开发板,开发环境为RealView MDK 4.22。
该源码结构简单明了,原始工程下载地址:点击打开链接
Register 0, ID code register:
unsigned int MMU_ReadID(void)
{
unsigned int id;
__asm("mrc p15, 0, id, c0, c0, 0");
return id;
}
Register 0, cache type register:
unsigned int MMU_ReadCacheType(void)
{
unsigned int type;
__asm("mrc p15, 0, type, c0, c0, 1");
return type;
}
Register 1, control register:
void MMU_EnterFastBusMode(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(3<<30)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_EnterSyncMode(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(1<<31)
orr r0, r0, #(1<<30)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_EnterAsyncMode(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(11<<30)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_EnableICache(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<12)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_DisableICache(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(1<<12)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_EnableDCache(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<2)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_DisableDCache(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(1<<2)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_EnableAlignFault(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #(1<<1)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_DisableAlignFault(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(1<<1)
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_Enable(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1
mcr p15, 0, r0, c1, c0, 0
}
}
void MMU_Disable(void)
{
unsigned int r0;
__asm{
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #1
mcr p15, 0, r0, c1, c0, 0
}
}
Register 2, translation table base (TTB) register:
void MMU_SetTTB(void)
{
unsigned int r0 = (unsigned int)TTB;
__asm("mcr p15, 0, r0, c2, c0, 0");
}
Register 3, domain access control register:
void MMU_SetDomain(unsigned int domain)
{
__asm("mcr p15, 0, domain, c3, c0, 0");
}
Register 7, cache operations register:
void MMU_InvalidICacheDCache(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c7, c7, 0");
}
void MMU_InvalidICache(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c7, c5, 0");
}
void MMU_InvalidICacheSingleEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c7, c5, 1");
}
void MMU_PrefechICacheLine(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c7, c13, 1");
}
void MMU_InvalidDCache(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c7, c6, 0");
}
void MMU_InvalidDCacheSingleEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c7, c6, 1");
}
void MMU_CleanDCacheSingleEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c7, c10, 1");
}
void MMU_CleanInvalidDCacheEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c7, c14, 1");
}
void MMU_CleanDCacheSingleEntry2(unsigned int index)
{
__asm("mcr p15, 0, index, c7, c10, 2");
}
void MMU_CleanInvalidDCacheEntry2(unsigned int index)
{
__asm("mcr p15, 0, index, c7, c14, 2");
}
void MMU_DrainWriteBuffer(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c7, c10, 4");
}
void MMU_WaitForInterrupt(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c7, c0, 4");
}
Register 8, TLB operations register:
void MMU_InvalidAllTLB(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c8, c7, 0");
}
void MMU_InvalidITLB(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c8, c5, 0");
}
void MMU_InvalidITLBSingleEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c8, c5, 1");
}
void MMU_InvalidDTLB(void)
{
unsigned int r0 = 0;
__asm("mcr p15, 0, r0, c8, c6, 0");
}
void MMU_InvalidDTLBSingleEntry(unsigned int MVA)
{
__asm("mcr p15, 0, MVA, c8, c6, 1");
}
Register 9, cache lockdown register:
unsigned int MMU_ReadDCacheLockdownBase(void)
{
unsigned int r0;
__asm("mrc p15, 0, r0, c9, c0, 0");
r0 >>= 26;
return r0;
}
void MMU_WriteDCacheLockdownBase(unsigned int index)
{
index <<= 26;
__asm("mcr p15, 0, index, c9, c0, 0");
}
unsigned int MMU_ReadICacheLockdownBase(void)
{
unsigned int r0;
__asm("mrc p15, 0, r0, c9, c0, 1");
r0 >>= 26;
return r0;
}
void MMU_WriteICacheLockdownBase(unsigned int index)
{
index <<= 26;
__asm("mcr p15, 0, index, c9, c0, 1");
}
Register 13, FCSE PID register:
unsigned int MMU_ReadPID(void)
{
unsigned int pid;
__asm("mrc p15, 0, pid, c13, c0, 0");
return (pid >> 25);
}
void MMU_WritePID(unsigned int pid)
{
pid <<= 25;
__asm("mcr p15, 0, pid, c13, c0, 0");
}
设置Memory Translation Table:
void MMU_SetMTT(unsigned int vStart, unsigned int vEnd, unsigned int pStart, unsigned int attr)
{
unsigned int vaddr, paddr;
vaddr = vStart;
paddr = pStart;
while(vaddr != (vEnd + 1))
{
TTB[vaddr >> 20] = (paddr & 0xFFF00000) | attr;
vaddr += 0x100000;
paddr += 0x100000;
}
}
MMU初始化:
void MMU_Init(void)
{
MMU_DisableICache();
MMU_DisableDCache();
MMU_SetTTB();
MMU_SetDomain(0xFFFFFFFF);
MMU_InvalidAllTLB();
MMU_EnableAlignFault();
MMU_SetMTT(0x00000000, 0x001FFFFF, 0x00000000, RW_CB);
MMU_SetMTT(0x30000000, 0x33FFFFFF, 0x30000000, RW_CB);
MMU_SetMTT(0x40000000, 0x4FFFFFFF, 0x40000000, RW_NCNB);
MMU_SetMTT(0x50000000, 0x5FFFFFFF, 0x50000000, RW_NCNB);
MMU_EnableICache();
MMU_EnableDCache();
MMU_Enable();
}
在本代码中需要注意的是,如果直接使用S3C2440.s的话,在C代码中调用上述代码会导致Undefine异常。因为进入main()之前,启动代码已经将处理器模式设置为USER模式了,而在USER模式下是无法操作CP15处理器的,所以产生异常。如果要在C中正常调用上述嵌入汇编,则需要将启动代码S3C2440.s中处理器模式设置为USER模式的那段代码注释掉,直接以SVC模式运行,就能正常执行,如下:
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
; MOV SP, R0
; SUB SL, SP, #USR_Stack_Size
; Enter User Mode and set its Stack Pointer
; MSR CPSR_c, #Mode_USR
; IF :DEF:__MICROLIB
; EXPORT __initial_sp
; ELSE
; MOV SP, R0
; SUB SL, SP, #USR_Stack_Size
; ENDIF
或者不修改处理器模式,而直接将以下汇编插入到S3C2440.s中Clock设置代码的后面,一样能运行:
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0xc0000000
mcr p15, 0, r0, c1, c0, 0
史海拾趣
|
我现在的WIFE登录后,重新开机发现不能记住上次我成功登录的网络,密码也不会记,用户使用起来很麻烦。 我也看到别人的机器上能够保存,我找了一下,好象是在PUBLIC下面的NETUI里面实现的,不知道哪位仁兄做过,赐教一下 或是微软有更新过这里, ...… 查看全部问答> |
|
如题,var myTextField=document.getElementById(\"myText\"); 这个没法实现。要是能实现该如何做? 看了yudong54的回帖(http://topic.eeworld.net/u/20091116/14/1b2cc357-3aea-4329-b527-ab7828142f8f.html?26416)说要打08年的补丁和09年一月 ...… 查看全部问答> |
|
大家好. 我碰到了一个vxworks中打印机方面的问题.我的目标机是pc486, TornadoV2.02, 24针老式打印机EPSON LQ-1600K,用telnet 进行连接调试.BUILD中包含了并口组件.现在我想要让打印机打出一些测试文字,然后我写了一小段代码 ******************** ...… 查看全部问答> |
|
承接电子设计(单片机)项目 (一)、PCB LAYOUT(2层 or 4层) 老牛承接专业抄板、画板,质优价廉,可每天查看画板进度,有问题及时沟通。 可加我QQ看画过的样板,因为老牛是个人接活,所以价钱肯定比抄板公司低,希望各位同行有活之余多多照顾。 ...… 查看全部问答> |
|
最近在使用TI的stellaris的芯片,项目主要用来做系统的控制模块,M3的外设基本都用到了,后面一点点总结各个模块简单的用法,并附上之前搜集和学习的资料,方便大家学习特别适合新手的入门学习,共同进步吧,感觉自己也还属于菜鸟级的呢,同时也感 ...… 查看全部问答> |
|
STM32接光纤模块构建以太网,官方参考电路板的PHY片子DP83848CVV可以接光纤模块吗? 我用的方案是STM32F107+DP83848CVV+OCM2521,DP83848是官方的电路图使用的PHY,但是官方的电路图接的是RJ45电口,我想用DP83848CVV接光纤模块,光纤模块用的是OCM2521多模光纤,但是现在一直无法连通,光纤链路的灯都不亮。 我阅读了DP83848CVV的 ...… 查看全部问答> |




