關於lowlevel_init函數的理解
我迷迷糊學看了lowlevel_init.S中的代碼之後,有一個感覺就是,要想讀懂其中的代碼首先得看一下你所用的芯片手冊,因爲裏面有比較詳細的存儲器控制(MemoryController)描述。我用的是s3c2440手冊裏寫得十分清楚,總共有8個塊(Banks)(Bank0~Bank7),每個塊對應着不同的控制與地址線,其實這些Bank很大一部分是對應着的控制寄存器的地址,這個要看實際的芯片與板子,看了下面的理解估計會有個大概。
第二,就是要清楚你的板子上對的存儲地址的分配,一般板子手冊上都會有的。我的開發板是友善之臂的mini2440(不是很富裕只能買一些平民板子),在它的手冊裏寫有SDRAM存儲系統與FLASH系統的介紹包括芯片型號,存儲大小,這些都是後面移植要注意,畢竟U-boot的移植就是對硬件支持的修改。mini2440的SDRAM使用兩片32M bytes總共64M bytes型號爲HY57V561620FTP芯片,地址空間爲0x30000000~0x34000000
進入正題:
/*
* 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
*/
#include
#include
/* some parameters for the board */
/*
*
* Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
*
* Copyright (C) 2002 Samsung Electronics SW.LEE
*
*/
#define BWSCON 0x48000000 /*總線寬度&等待控制寄存器的宏定義(由s3c2440芯片手冊5.4可知BW
SCON的地址正好爲0x48000000可R/W復位值爲0*/
/* BWSCON */
#define DW8 (0x0)
#define DW16 (0x1)
#define DW32 (0x2) /*上面三個宏是數據總線寬度,分別是8位、16位、32位在s3c2440芯片手
冊5.4中可以看到一個對BWSCON中每一位的詳解其中DWn就是對每一個Bank
要使用的數寬度進行定義*/
#define WAIT (0x1<<2) /*位WSn的宏定義,具體的作用在手冊中有說明*/
#define UBLB (0x1<<3) /*位STn的宏定義*/
#define B1_BWSCON (DW32)
#define B2_BWSCON (DW16)
#define B3_BWSCON (DW16 + WAIT + UBLB)
#define B4_BWSCON (DW16)
#define B5_BWSCON (DW16)
#define B6_BWSCON (DW32)
#define B7_BWSCON (DW32) /*以上是對BANKn的數據總線寬度與功能的宏定義,對於BANK3因爲要接
網卡,網卡有wait信號與沒有wait信號兩種,所以這裏有些特別*/
//以下是對每一個Bank的BANKCON進行配置,這裏要根據SRAM手冊來配置來對應的值,否則不能正常進行使用,在0~5中大多是對一些時序與Page模式的配置,只對應SRAM的要求就可以了*/
/* BANK0CON */
#define B0_Tacs 0x0 /* 0clk */
#define B0_Tcos 0x0 /* 0clk */
#define B0_Tacc 0x7 /* 14clk */
#define B0_Tcoh 0x0 /* 0clk */
#define B0_Tah 0x0 /* 0clk */
#define B0_Tacp 0x0
#define B0_PMC 0x0 /* normal */
/* BANK1CON */
#define B1_Tacs 0x0 /* 0clk */
#define B1_Tcos 0x0 /* 0clk */
#define B1_Tacc 0x7 /* 14clk */
#define B1_Tcoh 0x0 /* 0clk */
#define B1_Tah 0x0 /* 0clk */
#define B1_Tacp 0x0
#define B1_PMC 0x0
#define B2_Tacs 0x0
#define B2_Tcos 0x0
#define B2_Tacc 0x7
#define B2_Tcoh 0x0
#define B2_Tah 0x0
#define B2_Tacp 0x0
#define B2_PMC 0x0
#define B3_Tacs 0x0 /* 0clk */
#define B3_Tcos 0x3 /* 4clk */
#define B3_Tacc 0x7 /* 14clk */
#define B3_Tcoh 0x1 /* 1clk */
#define B3_Tah 0x0 /* 0clk */
#define B3_Tacp 0x3 /* 6clk */
#define B3_PMC 0x0 /* normal */
#define B4_Tacs 0x0 /* 0clk */
#define B4_Tcos 0x0 /* 0clk */
#define B4_Tacc 0x7 /* 14clk */
#define B4_Tcoh 0x0 /* 0clk */
#define B4_Tah 0x0 /* 0clk */
#define B4_Tacp 0x0
#define B4_PMC 0x0 /* normal */
#define B5_Tacs 0x0 /* 0clk */
#define B5_Tcos 0x0 /* 0clk */
#define B5_Tacc 0x7 /* 14clk */
#define B5_Tcoh 0x0 /* 0clk */
#define B5_Tah 0x0 /* 0clk */
#define B5_Tacp 0x0
#define B5_PMC 0x0 /* normal */
//在B6之後是SDBAM的配置,根據Datasheet裏說的後兩個Bank是可以作爲ROM、SRAM、SDRAM等儲存器
//因爲這裏配置爲SDRAM所以其他只對於ROM、SRAM有效的位就不用配置了,其實這些位和上面的Bank是
//一樣的。
//Bank的所就相應的選擇配置位了MT
#define B6_MT 0x3 /* SDRAM */
#define B6_Trcd 0x1 //RAStoCAS的延時時鐘週期
#define B6_SCAN 0x1 /* 9bit */ //列地址位數的宏定義,列掃描數,在SDRAM手冊上定有
#define B7_MT 0x3 /* SDRAM */
#define B7_Trcd 0x1 /* 3clk */
#define B7_SCAN 0x1 /* 9bit */
//以下爲刷新控制寄存器的配置,得根據SDRAM的具體參數來配置,移植時要特別的注意
/* REFRESH parameter */
#define REFEN 0x1 /* Refresh enable */ //使能刷新
#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */ //刷新模式在此爲自刷新
#define Trp 0x0 /* 2clk */ //RAS預充電時間
#define Trc 0x3 /* 7clk */ //SDRAM半行週期時間,行週期Trc=Tsrc+Trp
#define Tchr 0x2 /* 3clk */ //本人在s3c2440的Datasheet中沒有找到這個位
#define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
//SDRAM刷新計數值,即刷新頻率
//以下是重點了,也即是重要的lowlevel_init函數了
/**************************************/
_TEXT_BASE:
.word TEXT_BASE //這裏是獲得代碼段的起始地址,我的是0x33F80000(在board/xxx/config.mk中
//可到找到“TEXT_BASE=0x33F80000”
.globl lowlevel_init //這裏相當於定義一個全局的lowlevel_init以方便調用
lowlevel_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA //SMDATA表示這13個寄存器的值存放的開始地址,值爲0x33F8xxxx,處於內
//存中,這一句的作用是把其值加載到r0中
ldr r1, _TEXT_BASE //把代碼的起始地址(0x33F80000)加載到r1中
sub r0, r0, r1 //r0減去r1其結果存入r0,也即SMDATA中的起始地址0x33F8xxxx減去
//0x33F80000,其結果就是13個寄存器的值在NOR Flash存放的開始地址
ldr r1, =BWSCON /* Bus Width Status Controller */ //存儲控制器的基地址
add r2, r0, #13*4 //在計算出來的存放地址加上#13*4,然後其結果保存在r2中
//13個寄存器,每個寄存器佔4個字節
0:
ldr r3, [r0], #4 //內存中r0的值加載到r3中,然後r0加4,即下一個寄存器的
str r3, [r1], #4 //讀出寄存器的值保存到r1中,然後r1也偏移4
cmp r2, r0 //比較r0與r2的值,如果不等繼續返回0:執行,也即13個寄存器的值
//是否讀完
bne 0b
/* everything is fine now */
mov pc, lr //程序跳轉,返回到cpu_init_crit中
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
//設置每個BWCSCON,BANK0由硬件連線定
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
//以上是對BANKCON0~BANKCON5的設置
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) //對BANKCON6、BANKCON7的設置
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32 //BANKSIZE寄存器的設置
.word 0x30 //對MRSRB6設置
.word 0x30 //對MRSRB7設置
通過以上對代碼的分析可以知道,這裏主要是對儲存寄存器的設置,特別是SMRDATA後面的。這裏代碼的作用是爲加載Bootloader的第二階段代碼準備RAM空間。所謂準備,即是初始化內存芯片,使其可用。這個函數被cpu/xxx/start.S調用。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/iamwenyifuxing/archive/2010/05/12/5581999.aspx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.