S3C6410 ADS1.2 下裸奔 4----系统启动代码的改进

来源:互联网 发布:怎么自学淘宝运营 编辑:程序博客网 时间:2024/05/19 04:26

一、 initcpu.s中的代码,主要是初始化中断,调用C语言的初始化函数和设置堆栈

代码如下:


Mode_USR        EQU     0x10
Mode_FIQ        EQU     0x11
Mode_IRQ        EQU     0x12
Mode_SVC        EQU     0x13
Mode_ABT        EQU     0x17
Mode_UND        EQU     0x1B
Mode_SYS        EQU     0x1F
I_BIT           EQU     0x80  ; when I bit is set (1), IRQ is disabled
F_BIT           EQU     0x40  ; when F bit is set (1), FIQ is disabled

 

Peripheral_base  EQU    0x70000000
vic0_intenclear  EQU    0x71200014
vic1_intenclear  EQU    0x71200014
wtcon  EQU              0x7e004000


 PRESERVE8
 AREA Init, CODE, READONLY
StartUp
        b        ResetHandler
        b        .                ; HandlerUndef    (0x00000004)
        b        .                ; HandlerSWI        (0x00000008)
        b        .                ; HandlerPabort    (0x0000000C)
        b        .                ; HandlerDabort    (0x00000010)
        b        .                ; HandlerReserved    (0x00000014)
        ldr      pc,IRQHandler    ; HandlerIRQ        (0x00000018)
        b        .                ; HandlerFIQ        (0x0000001C)


IRQHandler DCD 0x50000018

ResetHandler
    mrs     r0,cpsr
    bic     r0,r0,#0x1f
    orr     r1,r0,#Mode_SYS|I_BIT | F_BIT
    msr     cpsr_cxsf,r1
    ldr     sp,=0xc002000

    mov  r0, #0
    mcr  p15, 0, r0, c7, c7, 0   ; Invalidate Entire I&D Cache

    mrc  p15, 0, r0, c1, c0, 0
    BIC  r0, r0, #1<<12
    mcr  p15, 0, r0, c1, c0, 0    ;Disable I Cache

; Peripheral Port Setup,Base Addres : 0x70000000, Size : 256 MB (0x13)
    ldr     r0, =(Peripheral_base+0x13)
    mcr     p15,0,r0,c15,c2,4

; Interrupt Disable
    ldr     r0, =vic0_intenclear
    ldr     r1, =0xFFFFFFFF;
    str     r1, [r0]

    ldr     r0, =vic0_intenclear
    ldr     r1, =0xFFFFFFFF;
    str     r1, [r0]

    ldr     r0, =wtcon      ; Disable WatchDog Timer
    ldr     r1, =0x0
    str     r1, [r0]


    IMPORT  Sys_Init
    bl      Sys_Init
    IMPORT  srom_cs0_init
    IMPORT  dram_init
    bl      srom_cs0_init
    bl      dram_init

    MSR     CPSR_c, #(Mode_SVC | I_BIT | F_BIT)  ; 0xd3
    LDR     SP, StackSvc

    MSR     CPSR_c, #(Mode_IRQ | I_BIT | F_BIT)  ; 0xd2
    LDR     SP, StackIrq

    MSR     CPSR_c, #(Mode_FIQ | I_BIT | F_BIT)  ; 0xd1
    LDR     SP, StackFiq

    MSR     CPSR_c, #(Mode_ABT | I_BIT | F_BIT)  ; 0xd7
    LDR     SP, StackAbt

    MSR     CPSR_c, #(Mode_UND | I_BIT | F_BIT)  ; 0xdb
    LDR     SP, StackUnd

    MSR     CPSR_c, #(Mode_SYS | I_BIT | F_BIT)  ; 0xdf
    LDR     SP, StackUsr   
   
    MSR     CPSR_c, #(Mode_SYS | I_BIT | F_BIT)  ; 0xd3  

    IMPORT  Main
    b       Main

 

 

USR_STACK_LEGTH     EQU         64
SVC_STACK_LEGTH     EQU         64
FIQ_STACK_LEGTH     EQU         0
IRQ_STACK_LEGTH     EQU         64
ABT_STACK_LEGTH     EQU         0
UND_STACK_LEGTH     EQU         0

StackUsr    DCD     UsrStackSpace + (USR_STACK_LEGTH - 1)* 4
StackSvc    DCD     SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq    DCD     IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq    DCD     FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt    DCD     AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd    DCD     UndtStackSpace + (UND_STACK_LEGTH - 1)* 4

  


; /* 分配堆栈空间 */
        AREA    Stacks, DATA, NOINIT, ALIGN=2
UsrStackSpace      SPACE   USR_STACK_LEGTH * 4  ;用户(系统)模式堆栈空间
SvcStackSpace      SPACE   SVC_STACK_LEGTH * 4  ;管理模式堆栈空间
IrqStackSpace      SPACE   IRQ_STACK_LEGTH * 4  ;中断模式堆栈空间
FiqStackSpace      SPACE   FIQ_STACK_LEGTH * 4  ;快速中断模式堆栈空间
AbtStackSpace      SPACE   ABT_STACK_LEGTH * 4  ;中止义模式堆栈空间
UndtStackSpace     SPACE   UND_STACK_LEGTH * 4  ;未定义模式堆栈

    END

 

二、系统时钟、存储器的初始化

#include "..\inc\config.h"

volatile PSYSCON_REGS GpSysRegs;

void Sys_Init(void)
{  
    int i;
    GpSysRegs = (volatile PSYSCON_REGS)SYSCON_REGS_BASE_ADDR;
    GpSysRegs->OTHERS |= 0x40;
    for (i = 0; i < 10; i++);
    GpSysRegs->OTHERS |= 0x80;
    while( ( (GpSysRegs->OTHERS) & 0xF00) != 0xF00);
   
    GpSysRegs->CLK_SRC   &= ~(0x07); // select FIN out,Disable PLL clk out
    GpSysRegs->CLK_DIV0  &= 0xFFFF0000;
    GpSysRegs->CLK_DIV0  |=  ((PCLK_DIV<<12)+(HCLKX2_DIV<<9)+(HCLK_DIV<<8)+(MPLL_DIV<<4)+(APLL_DIV<<0));
   
    GpSysRegs->APLL_LOCK = 0x4B1;
    GpSysRegs->MPLL_LOCK = 0x4B1;
    GpSysRegs->EPLL_LOCK = 0xE13;
   
    GpSysRegs->APLL_CON  = ((1L<<31)+(APLL_MDIV<<16)+(APLL_PDIV<<8)+(APLL_SDIV));
    GpSysRegs->MPLL_CON  = ((1L<<31)+(MPLL_MDIV<<16)+(MPLL_PDIV<<8)+(MPLL_SDIV));
    GpSysRegs->EPLL_CON0 = ((1L<<31)+(EPLL_MDIV<<16)+(EPLL_PDIV<<8)+(EPLL_SDIV));
    GpSysRegs->EPLL_CON1 = EPLL_KDIV;
   
    GpSysRegs->CLK_SRC   |= (0x07);
   
   
    GpSysRegs->MEM_SYS_CFG |= 0x1000;
    GpSysRegs->MEM_SYS_CFG &= ~0xbf;
   
   
}


//片选0(norflash)参数定义
#define cn_cs0_pmc      0
#define cn_cs0_tacp     0//2
#define cn_cs0_tcah     0//2
#define cn_cs0_tcoh     0//2
#define cn_cs0_tacc     15
#define cn_cs0_tcos     0//3
#define cn_cs0_tcas     0//2

#define cn_cs0_bwth     1
#define cn_cs0_wait     0
#define cn_cs0_ublb     0

//mobile dram 参数定义
#define cn_DDR_REF      7800   // 7800ns
#define cn_DDR_RAS      45     // min. 45ns
#define cn_DDR_RC       68     // min. 67.5ns
#define cn_DDR_RCD      23     // min. 22.5ns
#define cn_DDR_RFC      80     // min. 80ns
#define cn_DDR_RP       23     // min. 22.5ns
#define cn_DDR_RRD      15     // min. 15ns
#define cn_DDR_WR       15     // min. 15ns
#define cn_DDR_XSR      120    // min 120ns
#define cn_AP_bit       0
#define cn_Row_bit      2      // 13bit
#define cn_Col_bit      2      // 10bit

#define cn_ALLEN        0
#define cn_StopEN       1      // Mem Clock is dynamically stopped

#define cn_DIS_AutoPD   0
#define cn_EN_AutoPD    1

static  volatile struct dram_reg *const pg_dram_reg = (void*)0x7E001000;
static  volatile struct srom_reg *const pg_srom_reg = (void*)0x70000000;

void srom_cs0_init(void)
{
    uint32 temp;
    temp = pg_srom_reg->SROM_BW;
    temp &= 0xfffffff0;
    temp |= (cn_cs0_bwth<<0)+(cn_cs0_wait<<2)+(cn_cs0_ublb<<3);
    pg_srom_reg->SROM_BW = temp;
    pg_srom_reg->SROM_BC0 = (cn_cs0_tcas<<28) + (cn_cs0_tcos<<24)
                            +(cn_cs0_tacc<<16) + (cn_cs0_tcoh<<12)
                            +(cn_cs0_tcah<<8) + (cn_cs0_tacp<<4)
                            +(cn_cs0_pmc<<0);
  
}

void dram_init(void)
{
    uint32  Para_RCD, Scheduled_Para,uPara_RFC, uPara_RP,uPara_XSR;

    pg_dram_reg->MEMCCMD = 0x4<<0;
    pg_dram_reg->REFRESH = (((HCLK /1000 *cn_DDR_REF) -1)/1000000 + 1);

    pg_dram_reg->CASLAT = 0x3<<1;
    pg_dram_reg->T_DQSS = 0x1;
    pg_dram_reg->T_MRD = 0x2;

    pg_dram_reg->T_RAS = ((HCLK /1000 *cn_DDR_RAS) -1)/1000000 + 1;
    pg_dram_reg->T_RC = ((HCLK /1000 *cn_DDR_RC) -1)/1000000 + 1;
    Para_RCD = (((HCLK /1000 *cn_DDR_RCD) -1)/1000000 + 1);
    if (Para_RCD <4) {
        Scheduled_Para = 3;
    } else {
        Scheduled_Para = Para_RCD;
    }
    Para_RCD = ((Scheduled_Para-3)<<3) | (Para_RCD);
    pg_dram_reg->T_RCD = Para_RCD;
    uPara_RFC = (((HCLK /1000 *cn_DDR_RFC) -1)/1000000 + 1);
    if (uPara_RFC <4) {
         Scheduled_Para = 3;
    } else {
        Scheduled_Para = uPara_RFC;
    }
    uPara_RFC = ((Scheduled_Para-3)<<3) | (uPara_RFC);
    pg_dram_reg->T_RFC = uPara_RFC;
    uPara_RP = (((HCLK /1000 *cn_DDR_RP) -1)/1000000 + 1);
    if (uPara_RP <4) {
         Scheduled_Para = 3;
    } else {
        Scheduled_Para = uPara_RP;
    }
    uPara_RP = ((Scheduled_Para-3)<<3) | (uPara_RP);
    pg_dram_reg->T_RP = uPara_RP;
    pg_dram_reg->T_RRD = ((HCLK /1000 *cn_DDR_RRD) -1)/1000000 + 1;

    pg_dram_reg->T_WR = ((HCLK /1000 *cn_DDR_WR) -1)/1000000 + 1;
    pg_dram_reg->T_WTR = 2;
    pg_dram_reg->T_XP = 2;
    uPara_XSR= (((HCLK /1000 *cn_DDR_XSR) -1)/1000000 + 1) ;
    pg_dram_reg->T_XSR = uPara_XSR;
    pg_dram_reg->T_ESR = uPara_XSR;

    pg_dram_reg->MEMCFG =
        (0<<31)         |       // Disable Individul CKE Control
        (0<<21)         |       // 1chip
        (0<<18)         |       // Qos master selection by ARID[3:0]
        (2<<15)         |       // Burst 4
        (0<<14)         |       // Disable Stop Mem Clock ( 0)
        (0<<13)         |       // Disable Auto Power Down (0)
        (0<<7)          |       // Auto Power Down Period
        (cn_AP_bit<<6)    |       // Auto Precharge bit in bit 10
        (cn_Row_bit<<3)   |       // 13bit Row bits
        (cn_Col_bit<<0);          // 10bit Column bits


    pg_dram_reg->MEMCFG2 =
        (1<<11)     |      // Read delay 1 cycle from the Pad I/F ( 0x1 => mDDR)
        (3<<8)      |      // Memory Type (mDDR)
        (1<<6)      |      // Width ( 32bit)
        (0<<4)      |      // Bank bits = 2bit
        (0<<2)      |      // DQM state
        (1<<0);            // Sync. clock scheme


    pg_dram_reg->CHIP_0_CFG = 0x150f8; // Bank-Row-Column, 0x5000_0000 ~ 0x57ff_ffff ( 128MB)

    // NOP
    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (3<<18);        // Command - NOP

    // Precharge All
    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (0<<18) ;      // Command - PALL

    // AutoRefresh 2 times
    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (1<<18);      // Command - Autorefresh

    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (1<<18);      // Command - Autorefresh

    // MRS
    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (2<<18) |       // Command - MRS/EMRS
        (0<<16) |       // [17:16] - MRS ( 0 )
        (0x32<<0);     //  [6:4]- CAS Latency - 3,
                        // [3] - Burst Type (Sequential), [2:0] - Burst Length(4) -> 8

    // EMRS
    pg_dram_reg->DIRECTCMD =
        (0<<20) |       // Chip Address  - Chip 0
        (2<<18) |       // Command - MRS/EMRS
        (2<<16) |       // [17:16] - EMRS (2)
        (0x0<<0);      // [6:5]- Full Strength,
                        // [2:0] - PASR - Full Array


    //'GO'  Mode
    pg_dram_reg->MEMCCMD = (0x0<<0);    // Go Command

    // Check Controller State
    while((pg_dram_reg->MEMSTAT&0x3) != 1  );
}

 

 

原创粉丝点击