TQ210 —— s5pv210 lowlevel_init.S分析(uboot第一阶段)

发布者:Radiant777最新更新时间:2020-12-16 来源: eefocus关键字:TQ210  s5pv210  S分析  uboot 手机看文章 扫描二维码
随时随地手机看文章

/*

 * Memory Setup stuff - taken from blob memsetup.S

 *

 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and

 *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)

 *

 * 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

 

#include

#include "tq210_val.h"

 

@ 讲start.S的时候已经说过这个TEXT_BASE了

_TEXT_BASE:

.word TEXT_BASE

 

.globl 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]

 

/* 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

ldr r2, =0x444444

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, =0xff000fff

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 PMIC chip */

#ifdef CONFIG_TQ210_IIC_PM_CHIP

bl PMIC_InitIp

#endif

 

/* init system clock */

@ 时钟初始化 PLL初始化,要想看懂此汇编,请查看datsheet中,clk control章节

bl system_clock_init

 

/* Memory initialize */

@ 内存初始化

bl mem_ctrl_asm_init

1:

/* for UART */

@ 串口初始化,要看懂此汇编, 请查看datsheet中, 请查看串口章节

bl uart_asm_init

 

bl tzpc_init

 

@ 这段不执行

#if defined(CONFIG_ONENAND)

bl onenandcon_init

#endif

 

    @ nand初始化

#if defined(CONFIG_NAND)

/* simple init for NAND */

bl nand_asm_init

#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

/* L2 cache enable at sleep.S of kernel

* bl enable_l2cache 

*/

#ifdef CONFIG_TQ210

bl enable_l2cache

#endif

 

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:

   /* 这一段的作用是将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 r0, =ELFIN_CLOCK_POWER_BASE @0xe0100000

 

/* Set Mux to FIN */

ldr r1, =0x0

str r1, [r0, #CLK_SRC0_OFFSET]

 

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 */

#if defined(CONFIG_CHECK_MPLL_LOCK)

retryloop:

#endif

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]   @ 重复配置MPLL,确保MPLL配置成功

 

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<    *   |(3<    *#define APLL_RATIO         0

    *#define A2M_RATIO          4

    *#define HCLK_MSYS_RATIO    8

    *#define PCLK_MSYS_RATIO    12

    *#define HCLK_DSYS_RATIO    16

    *#define PCLK_DSYS_RATIO    20

    *#define HCLK_PSYS_RATIO    24

    *#define PCLK_PSYS_RATIO    28

    */

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])

[1] [2] [3]
关键字:TQ210  s5pv210  S分析  uboot 引用地址:TQ210 —— s5pv210 lowlevel_init.S分析(uboot第一阶段)

上一篇:TQ210 —— s5pv210 board.c分析(uboot第二阶段)
下一篇:TQ210 —— s5pv210 start.S分析

推荐阅读最新更新时间:2024-11-17 03:55

TQ210_裸机编程(二)——按键控制LED灯
首先我们可以在开发板配套材料中找到按键的电路图,E:TQ210_CD开发板配套电路图Bottompdf格式TQ210_BOARD_V4_20121023。 可以看到按键key1~key6对应的地址线为XEINT0~XEINT5,我们暂时就只用前面几个按键。 然后我们再找地址线在板子中相应的引脚号。 可以看到 按键地址线XEINT0~XEINT5对应的管脚号为GPH0_1~GPH0_5。 现在在S5PV210_UM_REV1.1文档中就能找到GPH0的控制寄存器,对应的控制6个按键。 将按键控制寄存器都设置为外部中断处理。然后去设定外部中断的处理相应参数。 外部中断要设置2个中断寄存器,EXT_INT_CON,E
[单片机]
TQ210_裸机编程(二)——按键控制LED灯
TQ210 —— 点亮LED
1、S5PV210 GPIO硬件简介 1.1、GPIO 【S5PV210有237个多功能IO口,通过设置寄存器确定某个引脚用于输入输出或者其他特殊功能】 GPIO的英文全称为General-PurposeIO ports,也就是通用IO接口。在嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对这些设备/电路,有的需要CPU为之提供控制手段,有的则需要被CPU用做输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了。比如,控制某个LED灯亮与灭,或者通过获取某个引脚的电平属性来达到判断外围设备的状态。对这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制器芯片上一般都
[单片机]
<font color='red'>TQ210</font> —— 点亮LED
ARM S3C2440中断分析
1.什么是中断 所谓中断,是指CPU在正常运行程序时,由于内部/外部事件或由程序预先安排的事件,引起CPU中断正在运行的程序,而转到为内部/外部事件或为预先安排的事件服务的中断程序中去,服务完毕,再返回去执行刚才被中断的程序。 2.什么是中断优先级 中断优先级是指,中断源被响应和处理的优先等级。设置优先级的目的是为了在有多个中断源同时发出中断请求时,CPU能够按照预定的顺序(如:按事件的轻重缓急处理)进行响应并处理。 3.什么是中断嵌套 中断嵌套是指当CPU正在处理某个中断源即正在执行中断服务程序时,会出现优先级更高的中断源申请中断,为了使更急的中断源及时得到服务,需要暂时中断(挂起)当前正在执行的级别较低的中断服务程序,去处理更
[单片机]
基于S5PV210的智能家居系统设计
提出了一种基于S5PV210芯片的智能家居系统的设计方法。在基于S5PV210处理器和linux2.6.30内核的嵌入式系统平台上使用QT开发了软件系统和人机交互界面,控制各种传感器采集信息以及TC35i等模块,并配置实现了Boa服务器;利用CGI实现了客户端浏览器和嵌入式Web服务器之间的交互;设计了基于STC89C52的门禁系统。 智能家居(Smart Home)是融合了计算机、通信、控制技术于一体的现代智慧家居解决方案,目前,国内外各种类型的智能家居产品越来越多。但一部分采用低性能的CPU作为主控芯片,无法在智能家居系统中集成更复杂的任务。还有一部分在控制系统上没有开发出更友好的人机界面(GUI),使用户无法完成便捷的操作。
[单片机]
基于<font color='red'>S5PV210</font>的智能家居系统设计
S3C2440之ADC分析
一、硬件原理分析 我们从结构图和数据手册可以知道,该ADC模块总共有8个通道可以进行模拟信号的输入,分别是AIN0、AIN1、AIN2、AIN3、YM、YP、XM、XP。那么ADC是怎么实现模拟信号到数字信号的转换呢?首先模拟信号从任一通道输入,然后设定寄存器中预分频器的值来确定AD转换器频率,最后ADC将模拟信号转换为数字信号保存到ADC数据寄存器0中(ADCDAT0),然后ADCDAT0中的数据可以通过中断或查询的方式来访问。对于ADC的各寄存器的操作和注意事项请参阅数据手册。 开发板通过一个10K的电位器(可变电阻)来产生电压模拟信号,然后通过第一个通道(即:AIN0)将模拟信号输入ADC。左图中的Aref表示AD的参
[单片机]
S5PV210的Uart应用
准备分析 S5PV210的NandFlash应用(一)出现很多bug,所以要先把Uart搞出来了。Uart一般是和clock相关联的,但是IROM中的代码已经提升了PCLK到66.5MHZ,这里就不进行CLOCK的设置了。 资源工具 同《 S5PV210的LED应用(一)》 着手写程序 为实现代码最简化,只是在LED程序的基础上进行添加,其它硬件如NandFlash,重定向等等都不涉及。函数设计如下: (1) void uart_init (void) ,初始化Uart (2) char getc (void),接收一个字符 (3) void putc (char c) ,发送一个字符 (4) puthex(
[单片机]
<font color='red'>S5PV210</font>的Uart应用
吹田电气推出S系列高精度功率分析
产品广泛应用于新能源汽车、工业控制、人工智能及消费电子领域的系统级测试 2018年7月26日日本大阪府吹田市讯,日本吹田电气株式会社今日宣布推出S系列功率分析仪,该产品可用于精确测量电压、电流、功率、谐波、电机转速、扭矩等各项参数。仪器具备多通道输入、高速采样、所有通道谐波同时测量等功能,实时数值显示、波形显示、趋势图、棒图、矢量图、X-Y等多种显示,谐波分析、电机评估、电压波动及闪变测量和FFT(快速傅里叶变换)等高级分析功能,可对各种应用系统进行高效测量和分析。 吹田电气日本本社社长饭田守宏表示:“吹田电气S系列功率分析仪,作为测试测量领域的生力军,将为客户带来更准确的测试测量效果,更好的应用操作体验,更优质更人性化的
[测试测量]
吹田电气推出<font color='red'>S</font>系列高精度功率<font color='red'>分析</font>仪
S5PV210进行LED流水灯实验总结(基于九鼎科技开发板)
/* * 文件:LED.s * 作者:周金宝 * 描述:实现开发板上4颗LED的流水灯效果 */ #define GPD0CON 0xE02000A0 //这里要注意,芯片手册上为了美观,地址是0xE020_00A0 中间加了个“-”,复制粘帖的时候要去掉,要不然会报错 #define GPD0DAT 0xE02000A4 #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start //把_start的链接属性改为外部,消除警告 _start: ldr r0, =0X11111111 //将GPJ0所有引脚定义为output模式 ldr r1,
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved