1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * alternative runtime patching
4  * inspired by the ARM64 and x86 version
5  *
6  * Copyright (C) 2021 Sifive.
7  */
8 
9 #include <linux/init.h>
10 #include <linux/cpu.h>
11 #include <linux/uaccess.h>
12 #include <asm/alternative.h>
13 #include <asm/sections.h>
14 #include <asm/vendorid_list.h>
15 #include <asm/sbi.h>
16 #include <asm/csr.h>
17 
18 static struct cpu_manufacturer_info_t {
19 	unsigned long vendor_id;
20 	unsigned long arch_id;
21 	unsigned long imp_id;
22 } cpu_mfr_info;
23 
24 static void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end,
25 				 unsigned long archid, unsigned long impid);
26 
riscv_fill_cpu_mfr_info(void)27 static inline void __init riscv_fill_cpu_mfr_info(void)
28 {
29 #ifdef CONFIG_RISCV_M_MODE
30 	cpu_mfr_info.vendor_id = csr_read(CSR_MVENDORID);
31 	cpu_mfr_info.arch_id = csr_read(CSR_MARCHID);
32 	cpu_mfr_info.imp_id = csr_read(CSR_MIMPID);
33 #else
34 	cpu_mfr_info.vendor_id = sbi_get_mvendorid();
35 	cpu_mfr_info.arch_id = sbi_get_marchid();
36 	cpu_mfr_info.imp_id = sbi_get_mimpid();
37 #endif
38 }
39 
init_alternative(void)40 static void __init init_alternative(void)
41 {
42 	riscv_fill_cpu_mfr_info();
43 
44 	switch (cpu_mfr_info.vendor_id) {
45 #ifdef CONFIG_ERRATA_SIFIVE
46 	case SIFIVE_VENDOR_ID:
47 		vendor_patch_func = sifive_errata_patch_func;
48 		break;
49 #endif
50 	default:
51 		vendor_patch_func = NULL;
52 	}
53 }
54 
55 /*
56  * This is called very early in the boot process (directly after we run
57  * a feature detect on the boot CPU). No need to worry about other CPUs
58  * here.
59  */
apply_boot_alternatives(void)60 void __init apply_boot_alternatives(void)
61 {
62 	/* If called on non-boot cpu things could go wrong */
63 	WARN_ON(smp_processor_id() != 0);
64 
65 	init_alternative();
66 
67 	if (!vendor_patch_func)
68 		return;
69 
70 	vendor_patch_func((struct alt_entry *)__alt_start,
71 			  (struct alt_entry *)__alt_end,
72 			  cpu_mfr_info.arch_id, cpu_mfr_info.imp_id);
73 }
74 
75