天天看點

armv8 架構arm64 lookup_processor_type分析

檔案位置:"arch/arm64/kernel/head.S"

kernel版本:4.0.0

ENTRY(lookup_processor_type)
	adr	x1, __lookup_processor_type_data    // x1 =pa(__lookup_processor_type_data),adr擷取到的是__lookup_processor_type_data的實體位址
	ldp	x2, x3, [x1]        // x2 = .   x3 = cpu_table va,即x2為__lookup_processor_type_data處的虛拟位址
                            // 由于 pa = va - PAGE_OFFFSET + PHYS_OFFSET    
                            // 是以 va - pa = PHYS_OFFSET - PAGE_OFFSET
	sub	x1, x1, x2			// get offset between VA and PA     x1 = va - pa
                                                  // PHYS_OFFSET-PAGE_OFFSET
	add	x3, x3, x1			// convert VA to PA // x3 = pa(cpu_tale) 轉換cpu_table處的虛拟位址為實體位址
1:
	ldp	w5, w6, [x3]			// load cpu_id_val and cpu_id_mask  	w5 =cpu_id_val = 0x000f0000 , w6 = cpu_id_mask = 0x000f0000
	cbz	w5, 2f				// end of list? cpu_table 以全0結構體結尾
	and	w6, w6, w0          // w0(參看下面解釋)為processor ID,與上掩碼, 根據kernel啟動log,發現讀出來的processor id 為 0x411fd070 , 或者 0x412fc09a 
							// 發現 processor_id & 0x000f0000 = 0x000f0000,即16~19位為全1,是以隻要讀出來的值,此4位為1,則驗證ok
	cmp	w5, w6				// 比較 w6 和 0x000f0000 是否相等
	b.eq	3f				// 相等則退出,跳到3f處
	add	x3, x3, #CPU_INFO_SZ	// 如果不相等,則 将 cpu_info跳到下一個結構體中
	b	1b						//然後繼續和processor id 對比
2:
	mov	x3, #0				// unknown processor	如果都不相等,則将 最後一個cpu_info結構體設定為0
3:
	mov	x0, x3				// 将結果傳回給 x0 ,此處傳回的是 cpu_info結構體的位址
	ret
ENDPROC(lookup_processor_type)
           

調用lookup_processor_type之前,執行了

        mrs x22, midr_el1           // x22=cpuid 

        mov x0, x22                   // 将cpuid放在 x0中

由《ARM Architecture Reference Manual ARMv8》文檔可知:

The letter W denotes a general-purpose register holding a 32-bit word, and X denotes a general-purpose register holding a 64-bit doubleword.

是以 x0 是64位的寄存器,而w0是x0的低32位,32的寄存器

因為 x0 = cpuid,是以w0 也是cpuid

ENTRY(stext)
	mov	x21, x0				// x21=FDT
	bl	el2_setup			// Drop to EL1, w20=cpu_boot_mode
	bl	__calc_phys_offset		// x24=PHYS_OFFSET, x28=PHYS_OFFSET-PAGE_OFFSET
	bl	set_cpu_boot_mode_flag
	mrs	x22, midr_el1			// x22=cpuid
	mov	x0, x22
	bl	lookup_processor_type
	mov	x23, x0				// x23=current cpu_table
	/*
	 * __error_p may end up out of range for cbz if text areas are
	 * aligned up to section sizes.
	 */
	cbnz	x23, 1f				// invalid processor (x23=0)?
	b	__error_p
           

midr_el1寄存器描述: 

mrs    x22, midr_el1            // x22=cpuid

可以看到此寄存器的 bits[19:16] 為Architecture相關,為全1,圖檔來源于:《ARM Architecture Reference Manual ARMv8》

armv8 架構arm64 lookup_processor_type分析
armv8 架構arm64 lookup_processor_type分析

繼續閱讀