RISCV——内核及汇编

RISCV------内核及汇编

小狼@http://blog.csdn.net/xiaolangyangyang


1、寄存器组(ABI)

2、异常及中断

XV6 trap(二)RISCV中断异常处理/定时器中断

  • mie:中断开关
  • mip:中断状态
  • mstatus.mie:全局中断开关

RISCV异常及中断向量有两种方式:一是全部异常及中断使用同一个入口,二是使用向量表,D1s芯片使用的是第一种方式,全部异常及中断使用同一入口,再通过scause判断是异常还是中断,以及异常或中断编号,如下图所示:

3、特权模式

RISC-V特权模式与寄存器

4、启动代码分析

复制代码
/* linker.ld */
/* 起始地址是0x27000 */

SECTIONS
{
	/*
        * 设置benos的加载入口地址为0x27000
        *
        * 这里"."表示location counter,当前位置
        */
	. = 0x27000,

	/*
        * 这里是第一个段text.boot,起始地址就是0x27000
	* 这个段存放了benos的第一条指令
        */
	_text_boot = .;
	.text.boot : { *(.text.boot) }
	_etext_boot = .;

	/*
        * text代码段
        */
	. = ALIGN(8);
	_text = .;
	_stext = .;
	.text :
       {
               *(.text)
       }
	. = ALIGN(8);
	_etext = .;

	/*
        * 只读数据段
        */
	_rodata = .;
	.rodata : { *(.rodata) }
	_erodata = .;

	/*
        * 数据段
        */
	_data = .;
	.data : { *(.data) }
	_edata = .;

	/*
        * bss段
        *
        * ALIGN(8)表示8个字节对齐
        * bss_begin的起始地址以8字节对齐
        */
	. = ALIGN(0x8);
	_bss = .;
	.bss : { *(.bss*) } 
	_ebss = .;
}

/* boot.S */
/* 启动代码,需要设置SP指针 */

.section ".text.boot"

.globl _start
_start:
	/* 关闭中断 */
	csrw sie, zero

	call __init_uart
	call print_asm

	/* 设置栈, 栈的大小为4KB */
	la sp, stacks_start
	li t0, 4096
	add sp, sp, t0

	/* 跳转到C语言 */
	tail kernel_main

print_asm:
        /*此时SP栈空间还没分配,把返回地址ra保存到临时寄存器中*/
	mv s1, ra

	la a0, boot_string
	call put_string_uart

	/*恢复返回地址ra*/
	mv ra, s1
	ret

.section .data
.align  12
.global stacks_start
stacks_start:
	.skip 4096

.section  .rodata
.align 3
.globl boot_string
boot_string:
       .string "\r\nBooting at asm\r\n"

/* entry.S */
/* 主要定义了异常及中断入口 */

#include "asm/asm-offsets.h"
#include "asm/csr.h"

.macro kernel_entry
	addi sp, sp, -(PT_SIZE)

	sd x1,  PT_RA(sp)
	sd x3,  PT_GP(sp)
	sd x5,  PT_T0(sp)
	sd x6,  PT_T1(sp)
	sd x7,  PT_T2(sp)
	sd x8,  PT_S0(sp)
	sd x9,  PT_S1(sp)
	sd x10, PT_A0(sp)
	sd x11, PT_A1(sp)
	sd x12, PT_A2(sp)
	sd x13, PT_A3(sp)
	sd x14, PT_A4(sp)
	sd x15, PT_A5(sp)
	sd x16, PT_A6(sp)
	sd x17, PT_A7(sp)
	sd x18, PT_S2(sp)
	sd x19, PT_S3(sp)
	sd x20, PT_S4(sp)
	sd x21, PT_S5(sp)
	sd x22, PT_S6(sp)
	sd x23, PT_S7(sp)
	sd x24, PT_S8(sp)
	sd x25, PT_S9(sp)
	sd x26, PT_S10(sp)
	sd x27, PT_S11(sp)
	sd x28, PT_T3(sp)
	sd x29, PT_T4(sp)
	sd x30, PT_T5(sp)
	sd x31, PT_T6(sp)

	csrr s1, sstatus
	sd s1, PT_SSTATUS(sp)

	/*保存sepc*/
	csrr s2, sepc
	sd s2, PT_SEPC(sp)
	
	/*保存sbadaddr*/
	csrr s3, sbadaddr
	sd s3, PT_SBADADDR(sp)

	/*保存scause*/
	csrr s4, scause
	sd s4, PT_SCAUSE(sp)

	/*保存ssratch*/
	csrr s5, sscratch
	sd s5, PT_TP(sp)

	/*保存SP*/
	addi s0, sp, PT_SIZE 
	sd s0, PT_SP(sp)
.endm

.macro kernel_exit
	ld a0, PT_SSTATUS(sp)
	csrw sstatus, a0

	ld a2, PT_SEPC(sp)
	csrw sepc, a2

	ld x1,  PT_RA(sp)
	ld x3,  PT_GP(sp)
	ld x4,  PT_TP(sp)
	ld x5,  PT_T0(sp)
	ld x6,  PT_T1(sp)
	ld x7,  PT_T2(sp)
	ld x8,  PT_S0(sp)
	ld x9,  PT_S1(sp)
	ld x10, PT_A0(sp)
	ld x11, PT_A1(sp)
	ld x12, PT_A2(sp)
	ld x13, PT_A3(sp)
	ld x14, PT_A4(sp)
	ld x15, PT_A5(sp)
	ld x16, PT_A6(sp)
	ld x17, PT_A7(sp)
	ld x18, PT_S2(sp)
	ld x19, PT_S3(sp)
	ld x20, PT_S4(sp)
	ld x21, PT_S5(sp)
	ld x22, PT_S6(sp)
	ld x23, PT_S7(sp)
	ld x24, PT_S8(sp)
	ld x25, PT_S9(sp)
	ld x26, PT_S10(sp)
	ld x27, PT_S11(sp)
	ld x28, PT_T3(sp)
	ld x29, PT_T4(sp)
	ld x30, PT_T5(sp)
	ld x31, PT_T6(sp)

	ld x2,  PT_SP(sp)
.endm

/*
   do_exception_vector必须4字节对齐
   否则写入stvec寄存器会不成功
 */
.align 2
.global do_exception_vector
do_exception_vector:
	kernel_entry

	csrw sscratch, x0

	la ra, ret_from_exception

	mv a0, sp /* pt_regs */
	mv a1, s4
	tail do_exception

ret_from_exception:

restore_all:
	kernel_exit
	sret

.global trigger_load_access_fault
trigger_load_access_fault:
	li a0, 0x100001
	ld a0, (a0)
	ret

5、调试

体验第一个程序

平头哥IP核C906的JTAG调试器DIY教程(一)

平头哥IP核C906的JTAG调试器DIY教程(二)

《T-HEAD+CPU调试技巧.pdf》

6、各特权态的指令

  • 各个特权级都拥有的指令:

ECALL:U态陷入S态,S态陷入M态

EBREAK:产生断点异常

FENCE.I:产生一个内存读写屏障

SRET/URET:M太返回S态,S态返回U态

  • S态引入的指令:

SFENCE.VMA:主要用于刷新页表

  • M态引入的指令:

WFI:让当前处理器核心进入睡眠状态

7、各特权态的CSR

  • CSR寄存器有自己的一套独立的地址空间,访问CSR需要使用专用的指令
  • 每一个处理器核心都有自己一套独立的4K CSR,这4K CSR分别对应到4个特权态(U\S\V\M),对于每个特权态,最多有1024个CSR可使用
  • 访问没有权限的CSR会Trap,访问不存在的CSR会Trap,写只读CSR会Trap,对于可选寄存器的操作会被忽略

【百问网DongshanPI-D1S开发板体验】2环境搭建
全志D1s开发板裸机开发之坏境搭建
DongshanPi-D1s快速上手 | 开发环境搭建
韦东山D1S板子------xfel工具无法烧写bin文件到spi norFlash问题解决
RISC-V 架构 - 精讲

相关推荐
我在人间贩卖青春4 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春4 天前
汇编之伪操作
汇编·伪操作
济6175 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka5 天前
汇编TEST指令
汇编
我在人间贩卖青春5 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春5 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka5 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子5 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka6 天前
指令格式举例
汇编·笔记·计算机组成原理
我在人间贩卖青春6 天前
汇编之分支跳转指令
汇编·arm·分支跳转