ARM-1176 S3C6410 lowlevel_init过程注释

来源:互联网 发布:uptodate软件价格 编辑:程序博客网 时间:2024/05/22 17:19
花了三个晚上弄清楚整个流程之后,累翻了。我想,写完这份注释以后,大概我再也不想看到这块的启动分析了。今天到此为止,明天开始做最后一个mem_ctrl_init的解析。两天内结束。/* * 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 "smdk6410_val.h"_TEXT_BASE:    .word    TEXT_BASE    .globl lowlevel_initlowlevel_init:    mov    r12, lr;保存当前链接寄存器地址,等跳转回start.s时继续执行使用    ldr    r0, =ELFIN_GPIO_BASE ;定基地址 0x7f008000    ldr     r1, =0x55555555        str     r1, [r0, #GPKCON0_OFFSET]; 0x7f008000 + 0x800;设置引脚GPIO-K[0-7]管脚为cfdata 模式    ldr     r1, =0x55555555    str     r1, [r0, #GPKCON1_OFFSET];0x7f008000 + 0x804;设置引脚GPIO-K[8-14]管脚为cfdata 模式    ldr     r1, =0x22222666 ;0010 0010 0010 0010 0010 0110 0110 0110    str     r1, [r0, #GPLCON0_OFFSET];0x7f008000 + 0x810;设置引脚GPIO-L;打开CF卡串口通信的0-2号三根地址线,其余不变,保持默认值    ldr     r1, =0x04000000 ;01 00 00 00 00 00 00 00 00 00 00 00 00 00    str     r1, [r0, #GPFCON_OFFSET];0x7f008000 + 0xA0;设置引脚GPIO-F14为输出;GPIO-F14连接CLKOUT输出    ldr     r1, =0x2000;    10000000000000    str     r1, [r0, #GPFDAT_OFFSET];0x7f008000 + 0xA4;通过向GPIO锁存器写1,维持一个高电平信号。        /* LED on only #8 */    ldr    r0, =ELFIN_GPIO_BASE ;0x7f008000    ldr    r1, =0x00111111 ;0001 0001 0001 0001 0001 0001    str    r1, [r0, #GPMCON_OFFSET] ;0x7f008000 + 0x820;GPIO0-5引脚使能为输出    ldr    r1, =0x00000555 ;010101010101    str    r1, [r0, #GPMPUD_OFFSET];由于刚启动上电信号不稳定,GPIO0-5引脚下拉电阻保证信号毛刺消除?为何要接下拉,下拉一般是输入时用啊    ldr    r1, =0x002a;  101010    str    r1, [r0, #GPMDAT_OFFSET] ;0x7f008000 + 0x824;点亮第二个LED和第4个LED    ldr    r1, =0  /*0x55555555 phantom*/ ;1010101010101010101010101010101    str    r1, [r0, #MEM1DRVCON_OFFSET]    ;0x7f008000 + 0x1D4;内存驱动控制设置为默认值    /* Disable Watchdog */    ldr    r0, =0x7e000000        @0x7e004000    orr    r0, r0, #0x4000    mov    r1, #0    str    r1, [r0];关看门狗    @ External interrupt pending clear    ldr    r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)    /*EINTPEND*/;0x7f008000 + 0x924    ldr    r1, [r0]    str    r1, [r0];外部中断挂起    ldr    r0, =ELFIN_VIC0_BASE_ADDR     @0x71200000    ldr    r1, =ELFIN_VIC1_BASE_ADDR     @0x71300000;中断向量表0和中断向量表1地址    @ Disable all interrupts (VIC0 and VIC1)    mvn    r3, #0x0;反转为1    str    r3, [r0, #oINTMSK];中断向量表0的中断使能清0    str    r3, [r1, #oINTMSK];中断向量表1的中断是能清0;    @ Set all interrupts as IRQ    mov    r3, #0x0    str    r3, [r0, #oINTMOD];0x7120000c    str    r3, [r1, #oINTMOD];0x7130000c;中断选择寄存器,设置为0,选择IRQ中断模式    @ Pending Interrupt Clear    mov    r3, #0x0    str    r3, [r0, #oVECTADDR]    str    r3, [r1, #oVECTADDR];中断地址寄存器挂起清零。注意,手册上写,这里无论设置任何值都将挂起中断。;务必在中断服务程序执行完毕之后进行清零;否则将会导致不可预知的异常;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;运行至此处,做完了下面几件事情;1,gpio使能并设置为CF卡功能模式;2,led灯点亮;3,关闭看门狗;4,关闭外部中断并挂起;5,关闭中断并挂起;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    /* init system clock */    bl system_clock_init;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;运行至此处,做完了下面几件事情; 运行至此处,时钟分频全部完成,设置为同步模式;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    /* for UART */    bl uart_asm_init    @至此,uart串口使能完毕。    ldr    r0, =ELFIN_UART_BASE    ldr    r1, =0x4b4b4b4b    str    r1, [r0, #UTXH_OFFSET]#if defined(CONFIG_NAND)    /* simple init for NAND */    bl nand_asm_init#endif    bl    mem_ctrl_asm_init    @跳到cpu_init.s文件中执行。执行完毕,跳转回此处,再跳转回kernel流程#if 1        ldr     r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)        ldr     r1, [r0]        bic     r1, r1, #0xfffffff7        cmp     r1, #0x8        beq     wakeup_reset#endif1:    ldr    r0, =ELFIN_UART_BASE    ldr    r1, =0x4b4b4b4b    str    r1, [r0, #UTXH_OFFSET]    mov    lr, r12    mov    pc, lr#if 1wakeup_reset:    /*Clear wakeup status register*/    ldr    r0, =(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)    ldr    r1, [r0]    str    r1, [r0]        /*LED test*/        ldr     r0, =ELFIN_GPIO_BASE        ldr     r1, =0x3000        str     r1, [r0, #GPNDAT_OFFSET]    /*Load return address and jump to kernel*/    ldr    r0, =(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)    ldr    r1, [r0]    /* r1 = physical address of s3c6400_cpu_resume function*/    mov    pc, r1        /*Jump to kernel (sleep-s3c6400.S)*/    nop    nop#endif/* * system_clock_init: Initialize core clock and bus clock. * void system_clock_init(void) */system_clock_init:    ldr    r0, =ELFIN_CLOCK_POWER_BASE  @0x7e00f000;APLL时钟地址#ifdef    CONFIG_SYNC_MODE    ldr    r1, [r0, #OTHERS_OFFSET]    ;0x7e00f000 + 0x900    mov    r2, #0x40                   ;100 0000    orr    r1, r1, r2                  ;设置为异步模式,不修改其他设置    str    r1, [r0, #OTHERS_OFFSET];开始浮空,等待指令生效    nop    nop    nop    nop    nop    ldr    r2, =0x80      ; 1000 0000;不理解此句,第八位开始是只读选项    orr    r1, r1, r2    str    r1, [r0, #OTHERS_OFFSET] ;0x7e00f000 + 0x900地址里的内容check_syncack:    ldr    r1, [r0, #OTHERS_OFFSET]    ldr    r2, =0xf00                  ;1111 0000 0000    and    r1, r1, r2    cmp    r1, #0xf00    bne    check_syncack; bne 非零则跳转#else    /* ASYNC Mode */#endif    mov    r1, #0xff00    orr    r1, r1, #0xff    str    r1, [r0, #APLL_LOCK_OFFSET]    str    r1, [r0, #MPLL_LOCK_OFFSET]    str    r1, [r0, #EPLL_LOCK_OFFSET];使A,M,E三个时钟使能/* CLKUART(=66.5Mhz) = CLKUART_input(532/2=266Mhz) / (UART_RATIO(3)+1) *//* CLKUART(=50Mhz) = CLKUART_input(400/2=200Mhz) / (UART_RATIO(3)+1) *//* Now, When you use UART CLK SRC by EXT_UCLK1, We support 532MHz & 400MHz value */#if defined(CONFIG_CLKSRC_CLKUART)    ldr       r1, [r0, #CLK_DIV2_OFFSET]              ;0x28    ;取时钟分频地址    bic    r1, r1, #0x70000                            ;0111 0000 0000 0000 0000    orr    r1, r1, #0x30000                            ;0011 0000 0000 0000 0000    str    r1, [r0, #CLK_DIV2_OFFSET]#endif    ldr       r1, [r0, #CLK_DIV0_OFFSET]    /*Set Clock Divider*/    bic    r1, r1, #0x30000    bic    r1, r1, #0xff00    bic    r1, r1, #0xff    ldr    r2, =CLK_DIV_VAL;时钟频率设置,;#if defined(CONFIG_CLK_800_133_66);#define Startup_APLLdiv        0;#define Startup_HCLKx2div    2;#elif defined(CONFIG_CLK_400_133_66);#define Startup_APLLdiv        1;#define Startup_HCLKx2div    2;#else;#define Startup_APLLdiv        0;#define Startup_HCLKx2div    1;#endif        ;#define    Startup_PCLKdiv        3    ;#define Startup_HCLKdiv        1    ;#define Startup_MPLLdiv        1    ;#define CLK_DIV_VAL    ((Startup_PCLKdiv<<12)|(Startup_HCLKx2div<<9)|(Startup_HCLKdiv<<8)|(Startup_MPLLdiv<<4 startup_aplldiv="" orr="" r1="" r1="" r2="" str="" r1="" r0="" clk_div0_offset="" ldr="" r1="" apll_val="" str="" r1="" r0="" apll_con_offset="" ldr="" r1="" mpll_val="" str="" r1="" r0="" mpll_con_offset="" ldr="" r1="" 0x80200203="" fout="" of="" epll="" is="" 96mhz="" str="" r1="" r0="" epll_con0_offset="" ldr="" r1="" 0x0="" str="" r1="" r0="" epll_con1_offset="" ldr="" r1="" r0="" clk_src_offset="" apll="" mpll="" epll="" select="" to="" fout="" if="" defined="" config_clksrc_clkuart="" ldr="" r2="" 0x2007="" else="" ldr="" r2="" 0x7="" endif="" orr="" r1="" r1="" r2="" str="" r1="" r0="" clk_src_offset="" wait="" at="" least="" 200us="" to="" stablize="" all="" clock="" mov="" r1="" 0x10000="" 1:="" subs="" r1="" r1="" 1="" bne="" 1b="" 2000="" ifdef="" config_sync_mode="" synchronization="" for="" vic="" port="" ldr="" r1="" r0="" others_offset="" orr="" r1="" r1="" 0x20="" str="" r1="" r0="" others_offset="" else="" ldr="" r1="" r0="" others_offset="" bic="" r1="" r1="" 0x20="" str="" r1="" r0="" others_offset="" endif="" mov="" pc="" lr="" bl="" uart_asm_init="" uart_asm_init:="" initialize="" uart="" in="" asm="" mode="" 115200bps="" fixed="" void="" uart_asm_init="" void="" uart_asm_init:="" set="" gpio="" to="" enable="" uart="" gpio="" setting="" for="" uart="" ldr="" r0="" elfin_gpio_base="" 0x7f008000="" ldr="" r1="" 0x220022="" 0000="" 0000="" 0010="" 0010="" 0000="" 0000="" 0010="" 0010="" str="" r1="" r0="" gpacon_offset="" 0x00="" uart1="" gpio-a2="" gpio-a3="" uart2="" gpio-a6="" gpio-a7="" ldr="" r1="" 0x2222="" 0000="" 0000="" 0000="" 0000="" 0010="" 0010="" 0010="" 0010="" str="" r1="" r0="" gpbcon_offset="" 0x7f008000="" 0x20="" uart2="" uart3="" gpio-b3="" gpio-b7="" ok="" 4="" 32="" ldr="" r0="" elfin_uart_console_base="" 0x7f005000="" mov="" r1="" 0x0="" str="" r1="" r0="" ufcon_offset="" define="" ufcon_offset="" 0x08="" str="" r1="" r0="" umcon_offset="" define="" umcon_offset="" 0x0c="" mov="" r1="" 0x3="" was="" 0="" str="" r1="" r0="" ulcon_offset="" 8bit="" 1="" if="" defined="" config_clksrc_clkuart="" ldr="" r1="" 0xe45="" uartclk="" src="11"> EXT_UCLK1*/#else    ldr    r1, =0x245            /* UARTCLK SRC = x0 => PCLK */#endif    str    r1, [r0, #UCON_OFFSET]               ;0x04 ,按照硬件手册配时钟频率#if defined(CONFIG_UART_50)    ldr    r1, =0x1A#elif defined(CONFIG_UART_66)    ldr    r1, =0x22#else    ldr    r1, =0x1A#endif    str    r1, [r0, #UBRDIV_OFFSET]             ;0x28 设置串口波特率#if defined(CONFIG_UART_50)    ldr    r1, =0x3#elif defined(CONFIG_UART_66)    ldr    r1, =0x1FFF#else    ldr    r1, =0x3#endif    str    r1, [r0, #UDIVSLOT_OFFSET]           ;波特率    ldr    r1, =0x4f4f4f4f    str    r1, [r0, #UTXH_OFFSET]        @'O'           ;0x20    @设置串口缓冲寄存器    mov    pc, lr    @跳转回主干继续往下走/* * Nand Interface Init for SMDK6400 */nand_asm_init:    ldr    r0, =ELFIN_NAND_BASE             ;nand flash 基址#define ELFIN_NAND_BASE0x70200000    ldr    r1, [r0, #NFCONF_OFFSET]         ;#define NFCONF_OFFSET           0x00;    orr    r1, r1, #0x70                    ; 0 0000 0 00 000000000 111 0 111 0 111 0000    orr    r1, r1, #0x7700    str     r1, [r0, #NFCONF_OFFSET];nandflash控制寄存器配置完成    ldr    r1, [r0, #NFCONT_OFFSET]    orr    r1, r1, #0x03                     ;0 0000 0 00 000000000 111 0 111 0 111 0000 AND 11    str     r1, [r0, #NFCONT_OFFSET]        ;0 0000 0 00 000000000 111 0 111 0 111 0011    mov    pc, lr    @至此,nandflash简单的配置了一下,其实我觉得这里可以不用配置,在mm control过程中配置也是可以的。    从链接寄存器取出当前PC指针,跳回主干流程,执行mem_ctrl_asm_init过程。当前ARM芯片工作模式为SVC模式,现在还没回到启动代码kernel中。

原创粉丝点击