CPU/Arm920T/cpu.c解读

 

 

#include "stdio.h"
//操作协处理器CP15的寄存器C1主要是cache控制器
//读取CP15/C1中的内容
static unsigned long read_p15_c1(void)
{
 unsigned long value;
 
 __asm__ __volatile__(
  "mrc p15,0,%0,c1,c0,0 @read control reg\n"
  :"=r"(value)
  :
  :"memory");
 
#ifdef MMU_DEBUG
 printf("p15/c1 is = %08lx\n",value);
#endif
 return value;
 
}

//把给定的值写入CP15/C1.,cache控制寄存器
static void write_p15_c1(unsigned long value)
{
#ifdef MMU_DEBUG
 printf("write %08lx to p15/c1\n",value);
#endif

 __asm__ __volatile__(
  "mcr p15,0,%0,c1,c0,0 @write it back\n"
  :
  :"r"(value)
  :"memory");
//再把刚才写得值读出来 什么意思啊??  
 read_p15_c1();
}

//就是在读写 协处理器CP15之间稍微的延迟一段时间
static void cp_delay(void)
{
 volatile int i;
 for(i=0;i<100;i++); 
}

#define C1_MMU  (1<<0) //C1的此位禁止或使能MMU/PU
#define C1_ALIGN (1<<1) //C1的此位禁止或使能地址对齐检查功能
#define C1_DC  (1<<2) //C1的此位禁止或使能数据cache
#define C1_BIG_ENDIAN (1<<7) //C1的此位控制配置系统那种内存模式
#define C1_SYS_PROT  (1<<8) //C1的此位用于系统保护
#define C1_ROM_PROT  (1<<9) //C1的此位用于ROM保护
#define C1_IC  (1<<12) //C1的此位禁止或使能指令cache
#define C1_HIGH_VECTORS (1<<13) //C1的此位控制向量表的位置
//CPU的初始化中设计到 堆栈的设置,主要还是NOR flash的设置
//由于在前文我们已经设定 AM2904是bottom boot 方式所以堆栈是从下往上增长的
//程序的起始地址就是 _armboot_start=_start
int cpu_init(void)
{
/*
由以上定义可以看出CFG_ENV_SIZE=0x20000=128KB

#define CFG_MALLOC_LEN  (CFG_ENV_SIZE + 128*1024)
可得CFG_MALLOC_LEN=CFG_ENV_SIZE + 128*1024=128KB+128KB=0x40000=256KB

 

#define CFG_GBL_DATA_SIZE  128 /* size in bytes reserved for initial data

#ifdef CONFIG_USE_IRQ
#define CONFIG_STACKSIZE_IRQ  (4*1024) // IRQ stack  4KB=0x1000
#define CONFIG_STACKSIZE_FIQ  (4*1024) // FIQ stack 4KB=0x1000
#endif

#define CONFIG_STACKSIZE  (128*1024) // regular stack  128KB=0x20000

#define PHYS_SDRAM_1   0x30000000 // SDRAM Bank #1

//配饰的nor flash为AMD_LV400
#ifdef CONFIG_AMD_LV800
#define PHYS_FLASH_SIZE  0x00100000 // 1MB
#define CFG_MAX_FLASH_SECT (19) // max number of sectors on one chip
#define CFG_ENV_ADDR  (CFG_FLASH_BASE + 0x0F0000) // addr of environment
#endif
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE  0x00080000 // 512KB
#define CFG_MAX_FLASH_SECT (11) // max number of sectors on one chip
#define CFG_ENV_ADDR  (CFG_FLASH_BASE + 0x070000) // addr of environment
#endif

cpu/arm920T/start.s中有_armboot_start的定义

.globl _armboot_start
_armboot_start:
 .word _start
//配置的nor flash为Am29LV400T 大小为0x00000-0x7FFFF=1M大小
//此程序中配置的Am29LV400T位bottomboot启动方式,而_start位于开始为止,即_armboot_start=_start=0x7FFFF
*/
#ifdef CONFIG_USE_IRQ
 IRQ_STACK_START=_armboot_start-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-4;
 FIQ_STACK_START=IRQ_STACK_START-CONFIG_STACKSIZE_IRQ;
 FREE_RAM_END=FIQ_STACK_START-CONFIG_STACKSIZE_FIQ-CONFIG_STACKSIZE;
 FREE_RAM_SIZE=FREE_RAM_END-PHYS_SDRAM_1;
else
 FREE_RAM_END=_armboot_start-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-4-CONFIG_STACKSIZE;
 FREE_RAM_SIZE=FREE_RAM_END-PHYS_SDRAM_1;
#endif
 
 return 0;
 
}

int cleanup_before_linux(void)
{
 unsigned long i;
 disable_interrupt();
 
 asm("mrc p15,0,%0,c1,c0,0":"=r"(i)); //读取C1寄存器的值放到i中
 i&=~(C1_DC|C1_IC); //禁止数据与指令cache
 asm("mcr p15,0,%0,c1,c0,0"::"r"(i)); //把I的值写入C1寄存器
 i=0;    
 asm("mcr p15,0,%0,c1,c0,0"::"r"(i)); //把C1全部清零,等待linux的初始化
 
 return (0);
}

int do_reset(cmd_tbl_t *cmdtp,int flag,int argc,char*argv[])
{
 disable_interrupts();
 reset_cpu();
 return(0);
}

//其中reset_cpu()如下
void reset_cpu (ulong ignored)
{
 volatile S3C24X0_WATCHDOG * watchdog;

#ifdef CONFIG_TRAB
 extern void disable_vfd (void);

 disable_vfd();
#endif

 watchdog = S3C24X0_GetBase_WATCHDOG();

 /* Disable watchdog */
 watchdog->WTCON = 0x0000;

 /* Initialize watchdog timer count register */
 watchdog->WTCNT = 0x0001;

 /* Enable watchdog timer; assert reset at timer timeout */
 watchdog->WTCON = 0x0021;

 while(1); /* loop forever and wait for reset to happen */

 /*NOTREACHED*/
}
//以下cache的操作函数都是依赖于对控制协处理器CP15的C1寄存器的操作
//其中两个重要的函数read_p15_c1()和write_p15_c1(ulong value)

void icache_enable(void)
{
 ulong reg;
 reg=read_p15_c1();
 cp_delay();
 write_p15_c1(reg|C1_IC);
}

void icache_disable(void)
{
 ulong reg;
 reg=read_p15_c1();
 cp_delay();
 write_p15_c1(reg&~C1_IC);
}

void icache_status(void)
{
 return(read_p15_c1()&C1_IC)!=0;
}

#ifdef USE_920T_MMU
//在includ/configs/enbedsky.h中定义#define USE_920T_MMU   1

void dcache_enable (void)
{
 ulong reg;

 reg = read_p15_c1 ();
 cp_delay ();
 write_p15_c1 (reg | C1_DC);
}

void dcache_disable (void)
{
 ulong reg;

 reg = read_p15_c1 ();
 cp_delay ();
 reg &= ~C1_DC;
 write_p15_c1 (reg);
}

int dcache_status (void)
{
 return (read_p15_c1 () & C1_DC) != 0;
}
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值