aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2020-07-01 16:57:57 +0000
committerAndrew Turner <andrew@FreeBSD.org>2020-07-01 16:57:57 +0000
commite4fc3b653aceb1254d61efe674fbbe1bd4088085 (patch)
treeb5426cd96071bf5e3a99220d7af3355db699681e /sys/arm64
parent5dbd4b8e96521244525a0fee29694719c873bd75 (diff)
downloadsrc-e4fc3b653aceb1254d61efe674fbbe1bd4088085.tar.gz
src-e4fc3b653aceb1254d61efe674fbbe1bd4088085.zip
Read the CPU 0 arm64 ID registers early in initarm
We also update the kernel view early in the boot. This will allow the use of the common kernel view in ifunc resolvers. Sponsored by: Innovate UK
Notes
Notes: svn path=/head/; revision=362845
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/arm64/identcpu.c15
-rw-r--r--sys/arm64/arm64/machdep.c5
-rw-r--r--sys/arm64/arm64/mp_machdep.c4
-rw-r--r--sys/arm64/include/cpu.h3
4 files changed, 13 insertions, 14 deletions
diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index 6220e7f365ae..356e434bd677 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -992,7 +992,7 @@ update_lower_register(uint64_t val, uint64_t new_val, u_int shift,
return (val);
}
-static void
+void
update_special_regs(u_int cpu)
{
struct mrs_field *fields;
@@ -1072,7 +1072,8 @@ identify_cpu_sysinit(void *dummy __unused)
elf_hwcap = hwcap;
else
elf_hwcap &= hwcap;
- update_special_regs(cpu);
+ if (cpu != 0)
+ update_special_regs(cpu);
if (CTR_DIC_VAL(cpu_desc[cpu].ctr) == 0)
dic = false;
@@ -1457,24 +1458,16 @@ identify_cache(uint64_t ctr)
}
void
-identify_cpu(void)
+identify_cpu(u_int cpu)
{
u_int midr;
u_int impl_id;
u_int part_id;
- u_int cpu;
size_t i;
const struct cpu_parts *cpu_partsp = NULL;
- cpu = PCPU_GET(cpuid);
midr = get_midr();
- /*
- * Store midr to pcpu to allow fast reading
- * from EL0, EL1 and assembly code.
- */
- PCPU_SET(midr, midr);
-
impl_id = CPU_IMPL(midr);
for (i = 0; i < nitems(cpu_implementers); i++) {
if (impl_id == cpu_implementers[i].impl_id ||
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index fa698c7dbdaa..9c6788eece8e 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -172,7 +172,6 @@ cpu_startup(void *dummy)
{
undef_init();
- identify_cpu();
install_cpu_errata();
vm_ksubmap_init(&kmi);
@@ -1138,6 +1137,9 @@ initarm(struct arm64_bootparams *abp)
if (kmdp == NULL)
kmdp = preload_search_by_type("elf64 kernel");
+ identify_cpu(0);
+ update_special_regs(0);
+
link_elf_ireloc(kmdp);
try_load_dtb(kmdp);
@@ -1181,6 +1183,7 @@ initarm(struct arm64_bootparams *abp)
"msr tpidr_el1, %0" :: "r"(pcpup));
PCPU_SET(curthread, &thread0);
+ PCPU_SET(midr, get_midr());
/* Do basic tuning, hz etc */
init_param1();
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index b90873c65054..d3dea3597106 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -220,7 +220,7 @@ init_secondary(uint64_t cpu)
* We need this before signalling the CPU is ready to
* let the boot CPU use the results.
*/
- identify_cpu();
+ identify_cpu(cpu);
/* Ensure the stores in identify_cpu have completed */
atomic_thread_fence_acq_rel();
@@ -230,6 +230,8 @@ init_secondary(uint64_t cpu)
while (!atomic_load_int(&aps_ready))
__asm __volatile("wfe");
+ pcpup->pc_midr = get_midr();
+
/* Initialize curthread */
KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
pcpup->pc_curthread = pcpup->pc_idlethread;
diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h
index 7cd7461e528c..fcc97149fb8c 100644
--- a/sys/arm64/include/cpu.h
+++ b/sys/arm64/include/cpu.h
@@ -167,11 +167,12 @@ void cpu_halt(void) __dead2;
void cpu_reset(void) __dead2;
void fork_trampoline(void);
void identify_cache(uint64_t);
-void identify_cpu(void);
+void identify_cpu(u_int);
void install_cpu_errata(void);
void swi_vm(void *v);
/* Functions to read the sanitised view of the special registers */
+void update_special_regs(u_int);
bool extract_user_id_field(u_int, u_int, uint8_t *);
bool get_kernel_reg(u_int, uint64_t *);