设为首页 加入收藏

TOP

ARM64启动汇编和内存初始化(中) --- (二)(二)
2023-07-23 13:31:20 】 浏览:201
Tags:ARM64 ---
.unreq tcr SYM_FUNC_END(__cpu_setup)

2.5.1 设置EL0和EL1异常等级可以访问浮点运算单元

2.5.2 调试监控系统寄存器

2.5.3 设置PSTATE寄存器的调试掩码域

??宏enable_dbg定义在/arch/arm64/include/asm/assembler.h中

	.macro	enable_dbg
	msr	daifclr, #8
	.endm

2.5.4 内存属性值赋值给mair(x17)

armv8内存可分为device memory和normal memory,它们又可以具有不同的属性,如:

  • device memory可配置不同的nGnRnE属性,以确定其访问内存时的行为;
  • normal memory可以有不同的cache策略,如cache写回、cache写通或者non cache等。寄存器MAIR_EL1用于设置内存属性表,它按八位一组分成了八组属性,其定义如下图:

??宏MAIR_EL1_SET定义在arch/arm64/mm/proc.S文件中,

/*
 * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
 * changed during __cpu_setup to Normal Tagged if the system supports MTE.
 */
#define MAIR_EL1_SET							\
	(MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |	\
	 MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRE, MT_DEVICE_nGnRE) |	\
	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_NC, MT_NORMAL_NC) |		\
	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL) |			\
	 MAIR_ATTRIDX(MAIR_ATTR_NORMAL, MT_NORMAL_TAGGED))

2.5.5 管理页表映射的值赋值给tcr --- Translation Control Register寄存器(x16)

2.5.6 MTE

??MTE 是ARM新架构(ARM V8.5 引入)的一个特性,它通过给分配的内存打标记(tag),追踪最常见的非法内存操作。如果密钥的值和锁的值一样,表示访问成功,否则会报告一个错误。ARM MTE简介

2.5.7 清除触发此CPU上错误的TCR位

??宏tcr_clear_errata_bits定义在/arch/arm64/include/asm/assembler.h中

/*
 * tcr_clear_errata_bits - Clear TCR bits that trigger an errata on this CPU.
 */
	.macro	tcr_clear_errata_bits, tcr, tmp1, tmp2
#ifdef CONFIG_FUJITSU_ERRATUM_010001
	mrs	\tmp1, midr_el1

	mov_q	\tmp2, MIDR_FUJITSU_ERRATUM_010001_MASK
	and	\tmp1, \tmp1, \tmp2
	mov_q	\tmp2, MIDR_FUJITSU_ERRATUM_010001
	cmp	\tmp1, \tmp2
	b.ne	10f

	mov_q	\tmp2, TCR_CLEAR_FUJITSU_ERRATUM_010001
	bic	\tcr, \tcr, \tmp2
10:
#endif /* CONFIG_FUJITSU_ERRATUM_010001 */
	.endm

2.5.8 设置TTBR0_EL1寻址的内存区域的大小为2^(64-T0SZ)字节。

2.5.9 设置TCR_EL1中的IPS位为ID_AA64MMFR0_EL1.PARange支持的最高值

??ID_AA64MMFR0_EL1 - Memory model feature register 0

/*
 * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
 * ID_AA64MMFR0_EL1.PARange value
 *
 *	tcr:		register with the TCR_ELx value to be updated
 *	pos:		IPS or PS bitfield position
 *	tmp{0,1}:	temporary registers
 */
	.macro	tcr_compute_pa_size, tcr, pos, tmp0, tmp1  //pos =32
	mrs	\tmp0, ID_AA64MMFR0_EL1
	// Narrow PARange to fit the PS field in TCR_ELx
        //UBFX Xd, Xn, #lsb, #width 
        //ubfx指令是无符号位域提取指令:UBFX指令的意思是从Wn寄存器的第lsb位开始,提取width位到Wd寄存器,剩余高位用0填充。
	ubfx	\tmp0, \tmp0, #ID_AA64MMFR0_PARANGE_SHIFT, #3        //ID_AA64MMFR0_PARANGE_SHIFT = 0
	mov	\tmp1, #ID_AA64MMFR0_PARANGE_MAX                     //根据配置可能是48/52
	cmp	\tmp0, \tmp1
        //CSEL  Xd, Xn, Xm, cond  :条件选择,返回第一个或第二个输入
	csel	\tmp0, \tmp1, \tmp0, hi                 //hi:无符号数大于
	bfi	\tcr, \tmp0, \pos, #3
	.endm

2.5.10 用硬件实现更新访问脏页面的标记位

??ARMV8.1支持的硬件特性。如果支持了这个硬件特性,访问一个物理页面时,硬件会自动设置PTE的AF域,否则需要软件(缺页中断)方式来模拟。

2.5.11 系统控制寄存器(SCTLR)域值

??并未设置SCTLR在,只是作为一个参数,传给下一个函数。

2.6 C运行时环境初始化(__primary_switch )

??_primary_switch主要用于设置c运行时环境,如使能MMU,设置异常向量表,栈,BSS段等,最后跳转到C语言函数start_kernel 。该函数具体实现如下,我们暂且跳过与主流程关联较小的kaslr和内核重定向相关代码。

SYM_FUNC_START_LOCAL(__primary_switch)          // __primary_switch在恒等映射段中(物理地址==虚拟地址)
#ifdef CONFIG_RANDOMIZE_BASE                    // ---(2.6.1)
	mov	x19, x0				// preserve new SCTLR_EL1 value
	mrs	x20, sctlr_el1			// preserve old SCTLR_EL1 value
#endif

	adrp	x1, init_pg_dir                 // kernel image的映射使用的页表起始地址【重点关注,下面TTBR1会用这个值】
	bl	__enable_mmu                    // ---(2.6.
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇STM32F7xx外设驱动6-adc(寄存器) 下一篇FreeRtos于嵌入式环境的应用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目