arch/riscv/kernel/cpu.c

Source file repositories/reference/linux-study-clean/arch/riscv/kernel/cpu.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/kernel/cpu.c
Extension
.c
Size
9123 bytes
Lines
382
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

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

of_property_match_string(node, "riscv,isa-extensions", "a") < 0) {
		pr_warn("CPU with hartid=%lu does not support ima", *hart);
		return -ENODEV;
	}

	return 0;

old_interface:
	if (!riscv_isa_fallback) {
		pr_warn("CPU with hartid=%lu is invalid: this kernel does not parse \"riscv,isa\"",
			*hart);
		return -ENODEV;
	}

	if (of_property_read_string(node, "riscv,isa", &isa)) {
		pr_warn("CPU with hartid=%lu has no \"riscv,isa-base\" or \"riscv,isa\" property\n",
			*hart);
		return -ENODEV;
	}

	if (IS_ENABLED(CONFIG_32BIT) && strncasecmp(isa, "rv32ima", 7)) {
		pr_warn("CPU with hartid=%lu does not support rv32ima", *hart);
		return -ENODEV;
	}

	if (IS_ENABLED(CONFIG_64BIT) && strncasecmp(isa, "rv64ima", 7)) {
		pr_warn("CPU with hartid=%lu does not support rv64ima", *hart);
		return -ENODEV;
	}

	return 0;
}

/*
 * Find hart ID of the CPU DT node under which given DT node falls.
 *
 * To achieve this, we walk up the DT tree until we find an active
 * RISC-V core (HART) node and extract the cpuid from it.
 */
int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
{
	for (; node; node = node->parent) {
		if (of_device_is_compatible(node, "riscv")) {
			*hartid = (unsigned long)of_get_cpu_hwid(node, 0);
			if (*hartid == ~0UL) {
				pr_warn("Found CPU without hart ID\n");
				return -ENODEV;
			}
			return 0;
		}
	}

	return -1;
}

unsigned long __init riscv_get_marchid(void)
{
	struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);

#if IS_ENABLED(CONFIG_RISCV_SBI)
	ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
	ci->marchid = csr_read(CSR_MARCHID);
#else
	ci->marchid = 0;
#endif
	return ci->marchid;
}

unsigned long __init riscv_get_mvendorid(void)
{
	struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);

#if IS_ENABLED(CONFIG_RISCV_SBI)
	ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
	ci->mvendorid = csr_read(CSR_MVENDORID);
#else
	ci->mvendorid = 0;
#endif
	return ci->mvendorid;
}

DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);

unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
{
	struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);

	return ci->mvendorid;

Annotation

Implementation Notes