接上文,继续学习TC277的启动过程。分析启动函数

有关用的寄存器说明,参考文章

TC27x寄存器学习

目录

TC27x寄存器学习

start函数分析

isync汇编指令(同步指令)

dsync汇编指令(同步数据),

1清除endinit

2设置中断堆栈

3启用对系统全局寄存器的写访问

4初始化SDA基指针

5关闭对系统全局寄存器的写访问

6关闭看门狗,恢复Endinit位

7初始化CSA

8初始化ram,拷贝rom数据到ram

9跳转主函数


start函数分析

__asm ("_START: movh.a %a10,hi:0xD000F000");
__asm ("  lea  %a10,[%a10]lo:0xD000F000");
__asm ("  movh.a %a15,hi:_start");
__asm ("  lea  %a15,[%a15]lo:_start");
__asm ("  ji %a15");

movh.a是(Move High to Address),将0xD000F000的高16bit写入address resgster A[10]地址寄存器中

A[10]是堆栈指针寄存器(SP)

lea指令(Load Effective Address)将0xD000F000的低16bit 写入address resgster A[10]的低16bit

0xD000F000应该表示SP地址值

A[15]是隐式地址寄存器, movh.a %a15,hi:_start 将 _start函数的地址高16位写入A[15]

ji指令(Jump Indirect)将A[15]的地址写入PC指针,并跳转到相应地址,即跳转到_start函数中执行

这个汇编的跳转没太懂,为什么要这么写?

void _start(void)

{

unsigned int coreID = _mfcr(CPU_CORE_ID) & IFX_CPU_CORE_ID_CORE_ID_MSK;

const CoreInit_t *core; /* the core initialisation structure */

core = &CPUInit[coreID];//初始化core0

cstart(core);//启动core0

}

_mfcr是汇编语言中的获取寄存器中的值

MTCR是写操作_mtcr(regaddr, val) 对寄存器写值

CPU_CORE_ID是Core Identification Register CSFR_Base + FE1CH

头文件中定义为 #define CPU_CORE_ID (0xFE1C)

CPU必须使用MTCR和MFCR指令访问自己的CSFR寄存器。其他CPU的CSFR寄存器可以通过XBAR_SRI使用加载和存储指令进行访问。任何CPU的SFR寄存器只能通过XBAR_SRI使用加载和存储指令进行访问。目前,CPUx的覆盖控制和访问保护寄存器映射到CPUx SFR地址范围。

CSFR-Core Special Function Registers.

void cstart(constCoreInit_t *)__attribute__ ((interrupt,noinline)); 声明为非内联函数。

interrupt此属性指示编译器以适合用作异常处理程序的方式生成函数

isync汇编指令(同步指令)

,强制完成之前的所有指令,然后刷新CPU管道,并在继续执行下一条指令之前使任何缓存的管道状态无效。ISYNC指令应该跟在MTCR指令之后。

dsync汇编指令(同步数据),

强制所有数据访问在与指令关联的任何数据访问之前完成,为确保内存一致性,必须在访问活动CSA内存位置之前执行DSYNC指令。

/*

* the initial startup routine 初始化启动程序

* - initialise the global RAM 初始化全局ram

* - start the other CPUs 启动其他CPU

* - disable/enable System Watchdog 关闭/开启 系统开门狗

* - call the main function 调用主函数

*/

void cstart(const CoreInit_t *core)

{

1清除endinit

/* reset endinit and disable watchdog */复位endinit 关闭看门狗

/* clear endinit bit in CPU0 WDT */

/* clear endinit bit in safety WDT */

WDT_ClearEndinit(volatileunsignedint *wdtbase)

{

unsigned int passwd;

passwd = *wdtbase;//读取寄存器中的值,获取原始密码

passwd &= 0xffffff00;//低8位清0

*wdtbase = passwd | 0xf1;//lck位置0,endinit位置1 应该是Password Access过程,[7:2]置111100

*wdtbase = passwd | 0xf2;//【2】lck位置1,endinit位置0,获取访问许可,应该是Modify Access过程

/* read back new value ==> synchronise LFI */

(void)*wdtbase;//读取更新返回值

}

2设置中断堆栈

/* setup interrupt stack */

_mtcr(CPU_ISP, (unsigned int)core->istack);//_mtcr(regaddr, val) 对寄存器写值

//加载中断向量指针寄存器

/* install trap handlers */

//加载陷阱向量表指针寄存器

_mtcr(CPU_PCON0, (unsigned int)0);//操作PMI0,程序允许缓存

_isync();//同步指令

/* initialise call depth counter */

psw = _mfcr(CPU_PSW);//读寄存器值

psw |= IFX_CPU_PSW_CDC_MSK;//禁用call depth counter

//关闭call depth counter,其实上面设置就够了

_mtcr(CPU_PSW, psw);//写入PSW

_isync();//同步指令

3启用对系统全局寄存器的写访问

/* enable write access to system global registers */

psw = _mfcr(CPU_PSW);//读寄存器值

//启用A[0], A[1], A[8], A[9] 写入权限

_mtcr(CPU_PSW, psw);//写入PSW

_isync();

4初始化SDA基指针

/* initialise SDA base pointers */

目的是啥?

5关闭对系统全局寄存器的写访问

/* disable write access to system global registers */

psw = _mfcr(CPU_PSW);

//关闭A[0], A[1], A[8], A[9] 写入权限

_mtcr(CPU_PSW, psw);

_isync();

6关闭看门狗,恢复Endinit位

/* disable Watchdogs */

if (core == &CPUInit[0])

{

/* safety WDT handled by CPU0 */

SCU_WDTSCON1.B.DR = 1;

WDT_SetEndinit(&SCU_WDTSCON0.U);

}

core->wdtCon1->B.DR = 1;

WDT_SetEndinit(&core->wdtCon0->U);

7初始化CSA

init_csa(core->csaBase, core->csaSize);

8初始化ram,拷贝rom数据到ram

/* handle global clear and copy tables */

if (core == &CPUInit[0])

{

clear_table_func(&__clear_table);

copy_table_func(&__copy_table);

}

/* handle core specific clear and copy tables */

clear_table_func(core->cleartable);

copy_table_func(core->copytable);

....

9跳转主函数

(*core->main)(1, (char **)&core->ustack[0]);//调用core0的main函数

}

WDTCPU0定义的联合

/** \brief CPU WDT Control Register 0 */

typedef union

{

unsigned int U; /**< \brief Unsigned access */

signed int I; /**< \brief Signed access */

Ifx_SCU_WDTCPU_CON0_Bits B; /**< \brief Bitfield access */

} Ifx_SCU_WDTCPU_CON0;

/** \brief CPU WDT Control Register 0 */

typedef struct _Ifx_SCU_WDTCPU_CON0_Bits

{

Ifx_Strict_32Bit ENDINIT:1; /**< \brief [0:0] End-of-Initialization Control Bit (rwh) */

Ifx_Strict_32Bit LCK:1; /**< \brief [1:1] Lock Bit to Control Access to WDTxCON0 (rwh) */

Ifx_Strict_32Bit PW:14; /**< \brief [15:2] User-Definable Password Field for Access to WDTxCON0 (rwh) */

Ifx_Strict_32Bit REL:16; /**< \brief [31:16] Reload Value for the WDT (also Time Check Value) (rw) */

} Ifx_SCU_WDTCPU_CON0_Bits;

该main函数在Bswinit.c中

int main(void)

{

BswInit_PreInitPowerOn();

BswInit_InitializeOne();

BswInit_InitializeTwo();

EcuM_Init(); /* never returns */

return 0;

}

BswInit_PreInitPowerOn在BswInit_callout_Stubs.c中

可用于ASR模块未涵盖的任何与硬件相关的初始化

以上还没看到其他CPU启动的过程。需要继续分析后面的代码

TC27x启动过程(2)-TC277相关推荐

  1. TC27x启动过程(3)-TC277

    接上文,继续分析TC277多核启动过程 目录 main函数分析 Os_InitMemory->Step1 Os_Init->Os_Api_Init:执行step2 BswInit_Init ...

  2. Android系统的启动过程

    Android系统的启动过程可以简单地总结为以下几个流程: 加载BootLoader -> 初始化内核 -> 启动init进程 -> init进程fork出Zygote(孵化器)进程 ...

  3. Android系统默认Home应用程序(Launcher)的启动过程源代码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  4. Linux0.11内核引导启动过程概述

    Linux0.11仅支持x86架构.它的内核引导启动程序在文件夹boot内,共有三个汇编代码文件.按照启动流程依次是: (1)bootsect.s.boot是启动引导的意思,sect即sector,是 ...

  5. linux启动sql server数据库,SQL Server数据库启动过程详解及启动不起来的问题分析及解决方法...

    第五步.启动系统数据库model model系统数据库同样也是SQL Server启动过程中用到的一个非常关键的数据库,如果这个库损坏,SQL Server启动也会失败,关于model数据不能启动的原 ...

  6. Linux必知必会的目录与启动过程

    第1章 /etc/目录 1.1 /etc/sysconfig/network-scripts/ifcfg-eth0 linux第一块网卡的配置文件 [root@znix ~]# cat /etc/sy ...

  7. Spring Boot启动过程(二)

    书接上篇 该说refreshContext(context)了,首先是判断context是否是AbstractApplicationContext派生类的实例,之后调用了强转为AbstractAppl ...

  8. Linux X Window System运行原理和启动过程

    本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System. 一) 基本运行原理 X Window System采用C/S结构,但和我们常见 ...

  9. Spring 容器的启动过程

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 本文来源:http://r6f.cn/b47K 一. 前言 ...

  10. golang源码分析-启动过程概述

    golang源码分析-启动过程概述 golang语言作为根据CSP模型实现的一种强类型的语言,本文主要就是通过简单的实例来分析一下golang语言的启动流程,为深入了解与学习做铺垫. golang代码 ...

最新文章

  1. java11 是长期支持_这里有你不得不了解的Java 11版本特性说明
  2. 清华Thinker团队提出AI计算芯片存储优化新方法 | ISCA 2018中国唯一一作论文
  3. 虚拟化基础架构Windows 2008篇之8-添加启动映像
  4. 批处理文件中判断是否64位系统
  5. java.lang包含_原因:java.lang.IllegalArgumentException:包含(1)...
  6. 39道高级java面试题及答案(最新)
  7. java jax-rs_在Java EE 7和WildFly中使用Bean验证来验证JAX-RS资源数据
  8. 动态css语言less,less让css具有动态语言的特性
  9. HTML5 classList使用
  10. 网红手工耿造了辆电动汽车 罗永浩点赞 网友喊话雷军投资
  11. Redis 6.0 源码阅读笔记(10) -- 主从复制 Master 节点流程分析
  12. Php真太阳时计算公式,第七章:如何计算真太阳时?
  13. FastStone Capture注册破解码
  14. The Elements of Style 4ed ---英文写作指南(一)
  15. Axure RP 8--模板的使用
  16. linux把m4s格式转换mp4,批量将哔哩哔哩缓存M4S格式视频改成MP4格式
  17. MIT开创减少双量子比特门误差的新方法,提高鲁棒性迈向纠错量子计算机
  18. 怎么实现在FireFox IE Opera Safari 都可以正常播放WMV和MOV的网页播放器代码
  19. oracle对成绩开根号运算,Oracle SQL 之 数学计算-开方根(咋个办呢 zgbn)
  20. iphone与android共享位置,苹果手机,相互始终共享位置了以后,查看不了对方的位置...

热门文章

  1. 信息系统项目管理师——范围管理论文
  2. ai人工智能让女神_人工智能可能只会让你兴奋不已
  3. 微信表情包的制作以及50*50像素图片太模糊的处理方法
  4. html5dragw3c,HTML5拖拽功能drag
  5. VBA批量编辑word图片尺寸
  6. 谷歌浏览器截取整个网页为图片(无需插件)
  7. 如何在Microsoft Word里面插入图片作为背景/封面?
  8. 未受信任的企业级开发者怎么设置
  9. Excel中不复制隐藏行
  10. 手机号中间四位变成****