最近一直在学习研究u-boot,这是我对s5pv210的u-boot的一些学习的一些列的文章中的一部分。这是我的注释代码,希望能帮到正在学习的你们。
/*
* Memory Setup stuff - taken from blob memsetup.S
*
* Copyright (C) 1999 2000 2001 Erik Mouw ([email protected]) and
* Jan-Derk Bakker ([email protected])
*
* Modified for the Samsung SMDK2410 by
* (C) Copyright 2002
* David Mueller, ELSOFT AG,
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*参考引用
http:@www.cnblogs.com/Efronc/archive/2012/02/29/2373668.html u-boot_smdkv210 分析三:启动代码lowlevel.s分析
*/
#include
#include
#include
#include "smart210_val.h"
_TEXT_BASE: @定义一个标签,后面将会用到,用于判断代码是否在外部RAM中运行,以此来判断是否初始化外部RAM
.word CONFIG_SYS_TEXT_BASE @这句话的意思是就是在当前位置放一个word型的值,这个值就是CONFIG_SYS_TEXT_BASE 可以这样理解,_TEXT_BASE是一个地址,这个地址中的内容是CONFIG_SYS_TEXT_BASE
@配合后面的 ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */ 就是将以_TEXT_BASE为地址的变量的值即CONFIG_SYS_TEXT_BASE赋给r2
.globl lowlevel_init @指示告诉汇编器,lowlevel_init这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号
lowlevel_init:
push {lr} @将上一个函数的返回地址压到栈中
/* check reset status */
@读取复位标志,如果是睡眠唤醒,跳过接下来的初始化
ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)@将跳转目的地址Reset Control Register的地址传送给r0 Address = 0xE010_A000 =0xE010_0000+0xA000
ldr r1, [r0] @将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1。
bic r1, r1, #0xfff6ffff @将r1与0xfff6ffff的反码按位进行与运算(既和0xfff6ffff进行与非运算),并写入r1;结合上一步,可知,这一步的作用是16和19bit置一,其他位清零
cmp r1, #0x10000 @判断16bit是不是等于1
beq wakeup_reset_pre @如果是从睡眠状态唤醒,就跳转到wakeup_reset_pre,既跳过接下来的初始化
cmp r1, #0x80000 @判断是不是从深度空闲(Deep-IDLE)状态唤醒
beq wakeup_reset_from_didle @如果是,就跳转到wakeup_reset_from_didle
/* IO Retention release */
ldr r0, =(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET) @将跳转目的地址MISC Register的地址传送给r0 Address = 0xE010_E000 =0xE010_0000+0xE000
ldr r1, [r0] @将存储器地址为 R0(内存储的值) 的字数据读入寄存器 R1
ldr r2, =IO_RET_REL @将IO_RET_REL( ((1 << 31) | (1 << 29) | (1 << 28)) )存入r2
orr r1, r1, r2 @将r1和r2的值进行或运算,结果存入r1
str r1, [r0] @将r1的值写入以r0内的值为地址的内存空间
/* Disable Watchdog 关闭看门狗*/
ldr r0, =ELFIN_WATCHDOG_BASE /* 0xE2700000 */
mov r1, #0
str r1, [r0] @清空以r0内的值为地址的内存空间
/* SRAM(2MB) init for SMDKC110 */
/* GPJ1 SROM_ADDR_16to21 */
/*配置sram引脚,16位数据宽度,22位地址宽度*/
ldr r0, =ELFIN_GPIO_BASE
ldr r1, [r0, #GPJ1CON_OFFSET]
bic r1, r1, #0xFFFFFF @清除r1内的低24位值
ldr r2, =0x444444 @引脚设置为addr功能
orr r1, r1, r2
str r1, [r0, #GPJ1CON_OFFSET]
ldr r1, [r0, #GPJ1PUD_OFFSET]
ldr r2, =0x3ff
bic r1, r1, r2
str r1, [r0, #GPJ1PUD_OFFSET]
/* GPJ4 SROM_ADDR_16to21 */
ldr r1, [r0, #GPJ4CON_OFFSET]
bic r1, r1, #(0xf<<16)
ldr r2, =(0x4<<16)
orr r1, r1, r2
str r1, [r0, #GPJ4CON_OFFSET]
ldr r1, [r0, #GPJ4PUD_OFFSET]
ldr r2, =(0x3<<8)
bic r1, r1, r2
str r1, [r0, #GPJ4PUD_OFFSET]
/* CS0 - 16bit sram, enable nBE, Byte base address */
ldr r0, =ELFIN_SROM_BASE /* 0xE8000000 */
mov r1, #0x1
str r1, [r0]
/* PS_HOLD pin(GPH0_0) set to high */
/*设置PMIC(Power Management IC)控制引脚,既电源管理ic引脚(基于I2C)*/
ldr r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET)
ldr r1, [r0]
orr r1, r1, #0x300
orr r1, r1, #0x1
str r1, [r0]
/* when we already run in ram, we don't need to relocate U-Boot.
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
/*下面的代码事实上只是判断pc和_TEXT_BASE(0X23e00000)的最高两位是否相同*/
/*根据s5pv210的数据手册可知,首先,系统会运行固化在irom的BL0,紧接着会从外部nand
*或sdcard等设备读取前16K的BL1代码到IRAM中的0xD0020000处。然后从0xD0020010处运行(因为前16byte是校验和的值)
*BL1的作用是初始化DRAM,拷贝BL2到DRAM中_TEXT_BASE(0X23e00000)处,然后跳到DRAM中运行
×因此可以通过最高两位来判断代码是在哪里运行
×同时可知,当代码已经就在DRAM中运行时,就必须跳过DRAM的初始化
*/
ldr r0, =0x00ffffff
bic r1, pc, r0 /* r0 <- current base addr of code */
ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */
bic r2, r2, r0 /* r0 <- current base addr of code */
cmp r1, r2 /* compare r0, r1 */
beq 1f /* r0 == r1 then skip sdram init */
/* init system clock */
bl system_clock_init
/* Memory initialize */
bl mem_ctrl_asm_init
1:
/* for UART */
bl uart_asm_init @调用Uart初始化
bl tzpc_init
#if defined(CONFIG_ONENAND)
bl onenandcon_init
#endif
#if defined(CONFIG_NAND)
/* simple init for NAND */
bl nand_asm_init @nand初始化
#endif
/* check reset status */
ldr r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
ldr r1, [r0]
bic r1, r1, #0xfffeffff
cmp r1, #0x10000
beq wakeup_reset_pre
/* ABB disable */
ldr r0, =0xE010C300
orr r1, r1, #(0x1<<23)
str r1, [r0]
/* Print 'K' */
ldr r0, =ELFIN_UART_CONSOLE_BASE
ldr r1, =0x4b4b4b4b
str r1, [r0, #UTXH_OFFSET]
pop {pc} @返回到start.s
wakeup_reset_from_didle: @从深度睡眠中唤醒
/* Wait when APLL is locked */
ldr r0, =ELFIN_CLOCK_POWER_BASE
lockloop:
ldr r1, [r0, #APLL_CON0_OFFSET]
and r1, r1, #(1<<29)
cmp r1, #(1<<29)
bne lockloop
beq exit_wakeup
wakeup_reset_pre:
mrc p15, 0, r1, c1, c0, 1 @Read CP15 Auxiliary control register
and r1, r1, #0x80000000 @Check L2RD is disable or not
cmp r1, #0x80000000
bne wakeup_reset @if L2RD is not disable jump to wakeup_reset
bl disable_l2cache
bl v7_flush_dcache_all
bl enable_l2cache
wakeup_reset:
/* init system clock */
bl system_clock_init
bl mem_ctrl_asm_init
bl tzpc_init
#if defined(CONFIG_ONENAND)
bl onenandcon_init
#endif
#if defined(CONFIG_NAND)
bl nand_asm_init
#endif
exit_wakeup:
/*Load return address and jump to kernel*/
ldr r0, =(INF_REG_BASE+INF_REG0_OFFSET)
ldr r1, [r0] /* r1 = physical address of s5pc110_cpu_resume function*/
mov pc, r1 /*Jump to kernel */
nop
nop
/*
* system_clock_init: Initialize core clock and bus clock.
* void system_clock_init(void)
*/
system_clock_init:
ldr r0, =ELFIN_CLOCK_POWER_BASE @0xe0100000 将时钟的基地址装载如r0
/* Set Mux to FIN */
ldr r1, =0x0 @将0x00000000装入r1
str r1, [r0, #CLK_SRC0_OFFSET] @将r1内的值装入地址为(r0内的值+CLK_SRC0_OFFSET = 0xe0100200)的内存(即Clock Source Control Registers)
/*上面一段的作用是将Clock Source Control Registers值清空
*具体的作用是将VPLL_SEL、EPLL_SEL、MPLL_SEL和APLL_SEL的时钟源设置为FINVPLL,将MUX_MSYS_SEL、MUX_DSYS_SEL和MUX_PSYS_SEL时钟源设置为SCLKMPLL
*将ONENAND_SEL时钟源设置为HCLK_PSYS
*为什么这样设置,因为未设置 PLL 和各种分频系数之前,我们不能使用 PLL,为了保险起见,暂时直接使用频率较低
*的外接的 24MHz 晶振,待设置好 PLL 和分频系数后再重新设置各种时钟开关
*/
ldr r1, =APLL_LOCKTIME_VAL @将APLL_LOCKTIME_VAL(0x2cf)装入r1
str r1, [r0, #APLL_LOCK_OFFSET] @将r1内的值装入地址为(r0内的值+CLK_SRC0_OFFSET = 0xe0100000)的内存,即设置APLL的锁定周期
/*
*下面是原文对这个步骤的解释,本人不才,不能很好的翻译过来,只能照抄誊录,希望高手空闲的时候能帮忙翻译一下
*A PLL requires locking period when input frequency is changed or frequency division (multiplication) values are
*changed.PLL_LOCK register specifies this locking period, which is based on PLL’s source clock. During this
*period, output will be low state
*/
/* Disable PLL */
ldr r1, =0x0
str r1, [r0, #APLL_CON0_OFFSET] @将APLL控制寄存器的值清空,这个寄存器的第31位置零关闭APLL 25-16bit配置MDIV的分频
/*
*13-8bit配置PDIV的分频 2-0bit配置SDIV的分频
*/
ldr r1, =0x0
str r1, [r0, #MPLL_CON_OFFSET] @配置MPLL
ldr r1, =0x0
str r1, [r0, #MPLL_CON_OFFSET] @?为什么再次配置,查看数据手册没有提到需要配置两次
ldr r1, [r0, #CLK_DIV0_OFFSET] @Clock Divider Control Register(0xe0100300)
ldr r2, =CLK_DIV0_MASK @CLK_DIV0_MASK(0x7fffffff)
bic r1, r1, r2 @首先清零
ldr r2, =CLK_DIV0_VAL @CLK_DIV0_VAL
orr r1, r1, r2
str r1, [r0, #CLK_DIV0_OFFSET]
/*
*CLK_DIV0_VAL = ((0<
ldr r1, =APLL_VAL
str r1, [r0, #APLL_CON0_OFFSET]
ldr r1, =MPLL_VAL
str r1, [r0, #MPLL_CON_OFFSET]
ldr r1, =VPLL_VAL
str r1, [r0, #VPLL_CON_OFFSET]
#if defined(CONFIG_EVT1)
ldr r1, =AFC_ON
str r1, [r0, #APLL_CON1_OFFSET]
#endif
mov r1, #0x10000
1: subs r1, r1, #1 @延时 将r1-1的值存入r1
bne 1b @如果运算结果不等零(即CPSR寄存器标志位Z不等于一),退回到前面标签“1”处执行 当 CPSR 寄存器中的 Z
@条件码置位时(即前面的计算结果为零),则顺序执行(即运行接下来的:ldr r1, [r0, #CLK_SRC0_OFFSET])
@当计算结果为零时,Z为1
ldr r1, [r0, #CLK_SRC0_OFFSET] @Clock Source Control Registers(0xe0100200)
ldr r2, =0x10001111 @
orr r1, r1, r2 @ONENAND时钟源为HCLK_DSYS MUX_PSYS_SEL时钟源为SCLKMPLL MUX_DSYS_SEL时钟源为SCLKMPLL MUX_MSYS_SEL时钟源为SCLKAPLL
@VPLL_SEL时钟源为FOUTVPLL EPLL_SEL时钟源为FOUTEPLL MPLL_SEL时钟源为FOUTMPLL APLL_SEL时钟源为FOUTAPLL
str r1, [r0, #CLK_SRC0_OFFSET] @装载
#if defined(CONFIG_MCP_AC) @210没有定义,暂时不分析
/* CLK_SRC6[25:24] -> OneDRAM clock sel = MPLL */
ldr r1, [r0, #CLK_SRC6_OFFSET]
bic r1, r1, #(0x3<<24)
orr r1, r1, #0x01000000
str r1, [r0, #CLK_SRC6_OFFSET]
/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */
ldr r1, [r0, #CLK_DIV6_OFFSET]
bic r1, r1, #(0xF<<28)
bic r1, r1, #(0x7<<12) @; ONENAND_RATIO: 0
orr r1, r1, #0x30000000
str r1, [r0, #CLK_DIV6_OFFSET]
#elif defined (CONFIG_MCP_H)
/* CLK_SRC6[25:24] -> OneDRAM clock sel = 00:SCLKA2M, 01:SCLKMPLL */
ldr r1, [r0, #CLK_SRC6_OFFSET]
bic r1, r1, #(0x3<<24)
orr r1, r1, #0x00000000
str r1, [r0, #CLK_SRC6_OFFSET]
/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */
ldr r1, [r0, #CLK_DIV6_OFFSET]
bic r1, r1, #(0xF<<28)
bic r1, r1, #(0x7<<12) @; ONENAND_RATIO: 0
orr r1, r1, #0x00000000
str r1, [r0, #CLK_DIV6_OFFSET]
#elif defined (CONFIG_MCP_B) || defined (CONFIG_MCP_D)
/* CLK_SRC6[25:24] -> OneDRAM clock sel = 00:SCLKA2M, 01:SCLKMPLL */
ldr r1, [r0, #CLK_SRC6_OFFSET]
bic r1, r1, #(0x3<<24)
orr r1, r1, #0x01000000
str r1, [r0, #CLK_SRC6_OFFSET]
/* CLK_DIV6[31:28] -> 4=1/5, 3=1/4(166MHZ@667MHz), 2=1/3 */
ldr r1, [r0, #CLK_DIV6_OFFSET]
bic r1, r1, #(0xF<<28)
bic r1, r1, #(0x7<<12) @; ONENAND_RATIO: 0
orr r1, r1, #0x30000000
str r1, [r0, #CLK_DIV6_OFFSET]
#elif defined (CONFIG_MCP_SINGLE) @定义了这个,我们进行分析
/* CLK_DIV6 */
ldr r1, [r0, #CLK_DIV6_OFFSET] @设置分频 Clock Divider Control Register(0xe0100318)
bic r1, r1, #(0x7<<12) @; ONENAND_RATIO:
@0DIVFLASH clock divider ratio,计算公式:SCLK_ONENAND = MOUTFLASH / (ONENAND_RATIO + 1)
str r1, [r0, #CLK_DIV6_OFFSET]
#endif
mov pc, lr @打完收功!
/*
* uart_asm_init: Initialize UART in asm mode, 115200bps fixed.
* void uart_asm_init(void)
*/
uart_asm_init:
/* set GPIO(GPA) to enable UART 没什么可说的,串口引脚复用设置*/
@ GPIO setting for UART
ldr r0, =ELFIN_GPIO_BASE
ldr r1, =0x22222222
str r1, [r0, #GPA0CON_OFFSET]
ldr r1, =0x2222
str r1, [r0, #GPA1CON_OFFSET]
@ HP V210 use. SMDK not use.
#if defined(CONFIG_VOGUES)
ldr r1, =0x100
str r1, [r0, #GPC0CON_OFFSET]
ldr r1, =0x4
str r1, [r0, #GPC0DAT_OFFSET]
#endif
ldr r0, =ELFIN_UART_CONSOLE_BASE @0xE2900000
mov r1, #0x0
str r1, [r0, #UFCON_OFFSET] @0xE2900008 UART FIFO Control Register 在这里关闭了FIFO功能
str r1, [r0, #UMCON_OFFSET] @0xE290000c UART Modem Control Register 在这里关闭了AFL(Auto Flow Control硬件流控制)和中断
mov r1, #0x3
str r1, [r0, #ULCON_OFFSET] @0xE2900000 UART Line Control Register 在这里采用8bit 1个停止位 无奇偶校验
ldr r1, =0x3c5
str r1, [r0, #UCON_OFFSET] @0xE2900000 UART Control Register
ldr r1, =UART_UBRDIV_VAL @波特率设置
str r1, [r0, #UBRDIV_OFFSET] @0xE2900028
ldr r1, =UART_UDIVSLOT_VAL @较细一些分频,用于补偿
str r1, [r0, #UDIVSLOT_OFFSET]
ldr r1, =0x4f4f4f4f
str r1, [r0, #UTXH_OFFSET] @'O' @打印“O”
mov pc, lr
/*
* Nand Interface Init for SMDKC110
*/
nand_asm_init:
/* Setting GPIO for NAND */
/* This setting is NAND initialze code at booting time in iROM. */
@设置IO BASE
ldr r1, [r0, #MP01CON_OFFSET]
bic r1, r1, #(0xf<<8)
orr r1, r1, #(0x3<<8)
str r1, [r0, #MP01CON_OFFSET]
ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<4)
str r1, [r0, #MP01PUD_OFFSET]
ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET]
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
ldr r0, =ELFIN_NAND_BASE @0xB0E00000
ldr r1, [r0, #NFCONF_OFFSET] @Nand Flash Configuration Register 0xB0E00000
ldr r2, =0x1412 @smart210对应的NANDFlash是每页是2K 从nand的数据手册可知,需要4个周期所以bit2设置为1 同样bit2选择page大小为2K
/*可知nand类型是SLC,bit3设置为0(PS:事实上,原版的不是这样的,选择的是MLC,我这里为了适应我的板子,改为SLC,各位看官可以根据具体
*情况自我修改)bit[7-4]TWRPH1 设置nand的延时,公式为:Duration = HCLK x ( TWRPH1 + 1 ) 这里设置为b0001
*bit[11-8]TWRPH0 设置nand的延时,公式为:Duration = HCLK x ( TWRPH0 + 1 ) 这里设置为b0100
*[15:12] CLE and ALE duration 公式:Duration = HCLK x TACLS 设置为b0001
*/
bic r1, r1, r2
ldr r2, =0x1412@原来是0x7772 ldr r2, =NFCONF_VAL 我对应我的板子做了修改
orr r1, r1, r2
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL @NFCONT_VAL (0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x3<<1)|(1<<0)
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
/*??蔿?誶???蝦????NFCONF_OFFSET]
orr r1, r1, #0x70
orr r1, r1, #0x7700
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
orr r1, r1, #0x03
str r1, [r0, #NFCONT_OFFSET]
*/
mov pc, lr
/*
* Setting TZPC[TrustZone Protection Controller]
*/
tzpc_init:
ldr r0, =ELFIN_TZPC0_BASE
mov r1, #0x0
str r1, [r0]
mov r1, #0xff
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
ldr r0, =ELFIN_TZPC1_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
ldr r0, =ELFIN_TZPC2_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
ldr r0, =ELFIN_TZPC3_BASE
str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
mov pc, lr
/*
* OneNAND Interface Init
*/
onenandcon_ 癷譶胕觮OneNAND ?肎覲?蝧etting for OneNAND
ldr r0, =ELFIN_GPIO_BASE @0xE0200000
ldr r1, [r0, #MP01CON_OFFSET]
orr r1, r1, #0x00550000
str r1, [r0, #MP01CON_OFFSET]
ldr r1, [r0, #MP03CON_OFFSET]
orr r1, r1, #0x0550
orr r1, r1, #0x00550000
str r1, [r0, #MP03CON_OFFSET]
ldr r1, =0xFFFF
str r1, [r0, #MP01DRV_SR_OFFSET]
str r1, [r0, #MP03DRV_SR_OFFSET]
str r1, [r0, #MP06DRV_SR_OFFSET]
str r1, [r0, #MP07DRV_SR_OFFSET]
wait_orwb:
@; Read ONENAND_IF_STATUS
ldr r0, =ELFIN_ONENANDCON_BASE @; 0xB0600000
ldr r1, [r0, #ONENAND_IF_STATUS_OFFSET]
bic r1, r1, #0xFFFFFFFE
cmp r1, #0x0
@; ORWB != 0x0
bne wait_orwb
@; write new configuration to onenand system configuration1 register
ldr r1, =0xF006 @; Sync.
ldr r2, =(ELFIN_ONENAND_BASE+0x1E442) @; 0x1E442(REG_SYS_CONF1)
strh r1, [r2]
@; read one dummy halfword
ldrh r1, [r2]
ldrh r1, [r2]
@; write new configuration to ONENAND_IF_CTRL
ldr r0, =ELFIN_ONENANDCON_BASE @; 0xB0600000
@;ldr r1, =0x2F006 @; ONENAND_IF_CTRL_REG_VAL (GCE off)
ldr r1, =0x402F006 @; ONENAND_IF_CTRL_REG_VAL (GCE on)
str r1, [r0, #ONENAND_IF_CTRL_OFFSET]
mov pc, lr
#ifdef CONFIG_ENABLE_MMU @uboot没有开启mmu
#ifdef CONFIG_MCP_SINGLE
/*
* MMU Table for SMDKC110
* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed
* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF
* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF
* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed
* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF
*/
/* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
.word (\base << 20) | (\ap << 10) | \
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
.align 14
@ the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0
@ Access for iRAM
.rept 0x100
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
@ Not Allowed
.rept 0x200 - 0x100
.word 0x00000000
.endr
.set __base,0x200
@ should be accessed
.rept 0x600 - 0x200
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
.rept 0x800 - 0x600
.word 0x00000000
.endr
.set __base,0x800
@ should be accessed
.rept 0xb00 - 0x800
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
/* .rept 0xc00 - 0xb00
.word 0x00000000
.endr */
.set __base,0xB00
.rept 0xc00 - 0xb00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
.set __base,0x200
@ 256MB for SDRAM with cacheable
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
@ access is not allowed.
@.rept 0xD00 - 0xC80
@.word 0x00000000
@.endr
.set __base,0xD00
@ 1:1 mapping for debugging with non-cacheable
.rept 0x1000 - 0xD00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
#else @ CONFIG_MCP_AC, CONFIG_MCP_H, CONFIG_MCP_B
/*
* MMU Table for SMDKC110
* 0x0000_0000 -- 0xBFFF_FFFF => Not Allowed
* 0xB000_0000 -- 0xB7FF_FFFF => A:0xB000_0000 -- 0xB7FF_FFFF
* 0xC000_0000 -- 0xC7FF_FFFF => A:0x3000_0000 -- 0x37FF_FFFF
* 0xC800_0000 -- 0xDFFF_FFFF => Not Allowed
* 0xE000_0000 -- 0xFFFF_FFFF => A:0xE000_0000 -- 0XFFFF_FFFF
*/
/* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
.word (\base << 20) | (\ap << 10) | \
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
.align 14
@ the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0
@ Access for iRAM
.rept 0x100
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
@ Not Allowed
.rept 0x300 - 0x100
.word 0x00000000
.endr
.set __base,0x300
@ should be accessed
.rept 0x350 - 0x300
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
@ Not Allowed
.rept 0x400 - 0x350
.word 0x00000000
.endr
.set __base,0x400
@ should be accessed
.rept 0x500 - 0x400
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
.rept 0x800 - 0x500
.word 0x00000000
.endr
.set __base,0x800
@ should be accessed
.rept 0xb00 - 0x800
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
.set __base,0xB00
.rept 0xc00 - 0xb00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
.set __base,0x300
@ 80MB for SDRAM with cacheable
.rept 0xC50 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
@ Not Allowed
.rept 0xD00 - 0xC50
.word 0x00000000
.endr
.set __base,0xD00
@ 1:1 mapping for debugging with non-cacheable
.rept 0x1000 - 0xD00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
#endif
#endif
如果你觉得写得还行,转载时请保留作者信息。作者:捷宇 邮箱:[email protected]