sparc v8架构的异常处理
sparc v8架构的异常处理
- 1.前言
- 2.异常简介
- 3.异常的使用场合
- 4.sparc v8异常处理流程
- 5.总结
1.前言
对于研究芯片处理器架构,是件非常有意思的事情。刚开始的接触时候也是一头雾水,不知所云,看着厚厚的架构手册,不知道从哪里下手。比如《ARMv8-A Architecture reference manual》一共是6666页纯英文文档,如果没真正看过,估计一上来就开始打退堂鼓了。后面接触的芯片的体系架构多了,自然也明白很多东西其实是有一些共性的,虽然架构不同,但是指令集、流水线以及系统运行的模式也能猜测7到8分准确。本文主要介绍一下sparc v8体系架构下的异常处理,同时简单的对比一下armv8体系架构的异常。
2.异常简介
Exception,中文翻译一般是异常,龙芯的手册上翻译为例外。就是系统在运行的过程中发生了异常事件,比如除0溢出、数组越界、文件找不到等。这种错误一般都是可以预测到的,所以芯片设计的时候,也会预留一些陷阱,当在特定的情况下,进入这个陷阱,说明发生了特定的事情。当然在语言处理层面,也会引入异常的这个概念,也就是比如java中,遇到异常可以throw抛弃也能够catch捕获异常。对于芯片架构来说,这种处理过程更加有意思。
在armv8中,会指定一个异常向量表,将这个异常向量表的首地址交给一个寄存器,当异常发生的时候,则会跳转到相应偏移的处理程序中。
system_vectors:
.align 11
.set VBAR, system_vectors
.org VBAR
// Exception from CurrentEL (EL1) with SP_EL0 (SPSEL=1)
.org (VBAR + 0x00 + 0)
B vector_error // Synchronous
.org (VBAR + 0x80 + 0)
B vector_irq // IRQ/vIRQ
.org (VBAR + 0x100 + 0)
B vector_fiq // FIQ/vFIQ
.org (VBAR + 0x180 + 0)
B vector_error // Error/vError
// Exception from CurrentEL (EL1) with SP_ELn
.org (VBAR + 0x200 + 0)
B vector_error // Synchronous
.org (VBAR + 0x280 + 0)
B vector_irq // IRQ/vIRQ
.org (VBAR + 0x300 + 0)
B vector_fiq // FIQ/vFIQ
.org (VBAR + 0x380 + 0)
B vector_error
// Exception from lower EL, aarch64
.org (VBAR + 0x400 + 0)
B vector_error
.org (VBAR + 0x480 + 0)
B vector_error
.org (VBAR + 0x500 + 0)
B vector_error
.org (VBAR + 0x580 + 0)
B vector_error
// Exception from lower EL, aarch32
.org (VBAR + 0x600 + 0)
B vector_error
.org (VBAR + 0x680 + 0)
B vector_error
.org (VBAR + 0x700 + 0)
B vector_error
.org (VBAR + 0x780 + 0)
B vector_error
.org (VBAR + 0x800 + 0)
B vector_error
在armv8架构中,处理器所处的模式一共有四种,EL0EL1EL2EL3。同一时刻只能处于一种ELx,所以在每个EL层级,异常的处理都会有Synchronous、IRQ、FIQ、Error四种。这也是armv8的特殊之处。
而对于sparc v8架构而言,处理器的模式只有两种,supervisor 和 user mode。只需要设置寄存器即可。相比较而言sparc v8的异常更好理解。就是系统在user模式下权限比较低,可以做不破坏系统状态的事情,比如不能改变系统运行状态,不能修改寄存器值,不能修改PC指针等等。但是在supervisor下就能够做这些事情。
所以这时候问题就来了,两种模式如何切换,这时就需要借助Exception。一般来说,sparc v8的启动入口就是异常向量的入口,所以第一次进来的就是reset异常。当系统处于异常处理程序的时候,这时候的模式为supervisor,可以做很多事情,比如修改pc指针,修改处理器模式等等。最后退出异常处理,进入用户模式进行处理。
在sparc中,预留了一些可以配置的软件中断,使用ta n
来触发系统进入特定的陷阱,其中n表示软件中断标号,这些都是设计者为芯片使用者留下的工具。
3.异常的使用场合
说起异常,很多人都觉得这是一个致命的错误,所以避而远之。其实不然,异常使用得当,将会大大提高系统的运行效率。比如在rtos porting的过程中,我们常常需要改变处理器的运行状态,或者利用异常进入到特定的处理函数中,例如system call等等。
异常也提供了安全机制,比如在芯片使用上,我们往往不会赋予我们的执行程序在芯片的最高权限下去使用这个芯片。比如armv8,我们不会去el3上运行一个系统,这样一不小心就会出现不可逆转的错误。一般的rtos或者linux都会选择el1作为系统运行的层级。需要在el3上做的事情比较少,这时候就可以通过异常转换层级,达到我们的目的。在sparc v8上也是这样,一般程序运行在user mode,只有需要的时候,才会切换到supervisor mode。
另外就是系统进入中断的时候,本质上来说,中断其实就是异常的一种,因为异常分为同步和异步,其中异步异常就是中断。在中断里做的事情一般都是比较紧急的事情。
当系统进入trap的时候,就是出现了同步异常的时候,这时候需要告知使用者,当前出现了除零错误地址访问异常等等。这些都是trap必须设置的,如果芯片没有这些保护机制,任程序继续执行下去,那将会造成不可预知的后果。
4.sparc v8异常处理流程
在sparc异常的处理中,默认情况下会在程序执行的入口处设定异常向量表。然后首先通过一个reset的异常进入第一行启动代码。系统运行起来后,会初始化状态寄存器,初始化C语言执行需要的环境,比如清除bss段、设置sp栈指针等等。
然后程序进入C语言执行,其中汇编语言中的ret1会主动将pc值填充,然后跳转。系统运行时,若遇到中断需要处理,则进入中断处理程序。如果系统在user mode下运行,需要修改pc值,那么只能通过trap指令进行,其中sparc v8的ta指令就是进入同步异常,然后去处理supervisor模式才能做的事情。
对于一个rtos来说,线程压栈的时候,会把当前的pc、和一些状态寄存器、通用寄存器的值读出来,保存在当前的线程栈中,也就是一块内存中,接着会将另外的一个线程栈的内容从内存中取出来,然后设置pc值、状态寄存器值、以及通用寄存器值等等,这时在sparc v8上就需要执行ta 3
指令了,其中ta n
中的n是自己设定的,需要自己实现相关的处理函数,这里只是预留了一个陷阱,至于陷阱怎么处理,那是需要自己来设定的。
5.总结
本文主要介绍了一下异常这部分的处理逻辑,只有在研究芯片体系架构的时候,才会需要非常深刻的了解这一块。使用好异常,将会让程序设计变得更加的合理,也能够非常清晰的了解操作系统的底层运行逻辑。
- ODL应用开发之MD-SAL中级教程
- Sql参数是一个list的最佳实践
- MyBatis 配置输出日志,不输出SQL问题解决
- lombok让你提高代码整洁度的神器附教程及原理分析
- mvn编译的时候一个破错误,google只有3个结果maven : Failed to install metadata project Could not parse metadata maven-
- 读书|《Mastering Machine Learning with Python in Six Steps》
- 几种简单的文本数据预处理方法
- Fiddler中显示IP方法
- readlink: command not found 解决方案
- Java 并发编程系列: CountDownLatch (上厕所的案例)
- 详解ANGULAR2组件中的变化检测机制(对比ANGULAR1的脏检测)
- 如何快速查看github代码库中第一次commit的记录
- 更换包管理工具npm为yarn
- 【精选】使用Cryptory分析影响加密货币价格的因素(区块链系列3)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MySQL学习笔记【基础篇】
- 设计模式~缺省适配模式
- 设计模式~合成模式
- mknod | Linux 后门系列
- Nmap NSE 库分析 >>> base64
- 视频远程通话会议EasyRTC通过SSH部署,关闭SSH后进程停止运行如何解决?
- MapReduce之ReduceJoin案例
- ios SDK如何配置
- CopyOnWriteArrayList源码阅读笔记
- python 连接数据库MYSQL
- 知识卡片 CNN 卷积神经网络
- 计算机基础知识总结与操作系统 PDF 下载
- 【动手学深度学习】笔记一
- 【Python】使用Pygame做一个Flappy bird小游戏(一)
- 从0到1,实现你的第一个多层神经网络