arch/riscv/kernel/entry.S

Source file repositories/reference/linux-study-clean/arch/riscv/kernel/entry.S

File Facts

System
Linux kernel
Corpus path
arch/riscv/kernel/entry.S
Extension
.S
Size
13654 bytes
Lines
515
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: arch/riscv
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/init.h>
#include <linux/linkage.h>

#include <asm/alternative-macros.h>
#include <asm/asm.h>
#include <asm/csr.h>
#include <asm/scs.h>
#include <asm/unistd.h>
#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
#include <asm/errata_list.h>
#include <linux/sizes.h>

	.section .irqentry.text, "ax"

.macro new_valid_map_cpus_check
	REG_S 	a0, TASK_TI_A0(tp)
	csrr 	a0, CSR_CAUSE
	/* Exclude IRQs */
	blt  	a0, zero, .Lnew_valid_map_cpus_restore_context_a0

	REG_S 	a1, TASK_TI_A1(tp)
	/* Only check new_valid_map_cpus if we are in page/protection fault */
	li   	a1, EXC_LOAD_PAGE_FAULT
	beq  	a0, a1, .Lnew_valid_map_cpus_kernel_address
	li   	a1, EXC_STORE_PAGE_FAULT
	beq  	a0, a1, .Lnew_valid_map_cpus_kernel_address
	li   	a1, EXC_INST_PAGE_FAULT
	bne  	a0, a1, .Lnew_valid_map_cpus_restore_context_a1

.Lnew_valid_map_cpus_kernel_address:
	/* Is it a kernel address? */
	csrr 	a0, CSR_TVAL
	bge 	a0, zero, .Lnew_valid_map_cpus_restore_context_a1

	/* Check if a new vmalloc mapping appeared that could explain the trap */
	REG_S	a2, TASK_TI_A2(tp)
	/*
	 * Computes:
	 * a0 = &new_valid_map_cpus[BIT_WORD(cpu)]
	 * a1 = BIT_MASK(cpu)
	 */
	lw	a2, TASK_TI_CPU(tp)
	/*
	 * Compute the new_valid_map_cpus element position:
	 * (cpu / 64) * 8 = (cpu >> 6) << 3
	 */
	srli	a1, a2, 6
	slli	a1, a1, 3
	la	a0, new_valid_map_cpus
	add	a0, a0, a1
	/*
	 * Compute the bit position in the new_valid_map_cpus element:
	 * bit_pos = cpu % 64 = cpu - (cpu / 64) * 64 = cpu - (cpu >> 6) << 6
	 * 	   = cpu - ((cpu >> 6) << 3) << 3
	 */
	slli	a1, a1, 3
	sub	a1, a2, a1
	/* Compute the "get mask": 1 << bit_pos */
	li	a2, 1
	sll	a1, a2, a1

	/* Check the value of new_valid_map_cpus for this cpu */
	REG_L	a2, 0(a0)
	and	a2, a2, a1
	beq	a2, zero, .Lnew_valid_map_cpus_restore_context

	/* Atomically reset the current cpu bit in new_valid_map_cpus */
	amoxor.d	a0, a1, (a0)

Annotation

Implementation Notes