Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Rework Arm (32bit and 64bit) AP startup so that cpu...
details: https://anonhg.NetBSD.org/src/rev/40920aaad5c4
branches: trunk
changeset: 990626:40920aaad5c4
user: skrll <skrll%NetBSD.org@localhost>
date: Sun Oct 31 16:23:47 2021 +0000
description:
Rework Arm (32bit and 64bit) AP startup so that cpu_hatch doesn't sleep.
The AP initialisation code in cpu_init_secondary_processor will read and
initialise the required system registers and state for the BP to attach
and report.
Rework the interrupt handler code for this new sequence. Thankfully,
this removes a bunch of code for bcm2836mp.
The VFP detection handler on <= armv7 relies on the global undefined
handler being in place until the BP attaches vfp. That is, after the
APs have been spun up.
gicv3_its.c has a serialisation issue which is protected against in
the gicv3_its_cpu_init, which is called from cpu_hatch, with a spin
lock. The serialisation issue needs addressing more completely.
Tested on RPI3, Apple M1, QEMU, and lx2k
Fixes PR port-arm/56264:
diagnostic assertion "l->l_stat == LSONPROC" failed on RPI3
diffstat:
sys/arch/aarch64/aarch64/aarch64_machdep.c | 6 +-
sys/arch/aarch64/aarch64/cpu.c | 103 ++++++++++-------
sys/arch/aarch64/aarch64/cpufunc.c | 93 +++++++---------
sys/arch/aarch64/aarch64/db_machdep.c | 23 +++-
sys/arch/aarch64/aarch64/locore.S | 60 +++-------
sys/arch/aarch64/include/cpu.h | 32 +++++-
sys/arch/aarch64/include/cpufunc.h | 33 +----
sys/arch/aarch64/include/db_machdep.h | 5 +-
sys/arch/arm/apple/apple_intc.c | 91 +++++++--------
sys/arch/arm/arm/cpu_subr.c | 11 +-
sys/arch/arm/arm/undefined.c | 40 ++++++-
sys/arch/arm/arm32/arm32_boot.c | 27 +---
sys/arch/arm/arm32/arm32_machdep.c | 16 ++-
sys/arch/arm/arm32/cpu.c | 56 +++++----
sys/arch/arm/broadcom/bcm2835_intr.c | 118 +++----------------
sys/arch/arm/cortex/gicv3_its.c | 20 ++-
sys/arch/arm/cortex/gicv3_its.h | 5 +-
sys/arch/arm/cortex/gtmr.c | 5 +-
sys/arch/arm/include/cpu.h | 16 +-
sys/arch/arm/include/locore.h | 3 +-
sys/arch/arm/include/undefined.h | 7 +-
sys/arch/arm/pic/pic.c | 6 +-
sys/arch/arm/vfp/vfp_init.c | 164 ++++++++++++----------------
23 files changed, 452 insertions(+), 488 deletions(-)
diffs (truncated from 1996 to 300 lines):
diff -r 5eb5ac1dea5c -r 40920aaad5c4 sys/arch/aarch64/aarch64/aarch64_machdep.c
--- a/sys/arch/aarch64/aarch64/aarch64_machdep.c Sun Oct 31 15:32:14 2021 +0000
+++ b/sys/arch/aarch64/aarch64/aarch64_machdep.c Sun Oct 31 16:23:47 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.62 2021/10/08 21:41:29 ryo Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.63 2021/10/31 16:23:47 skrll Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.62 2021/10/08 21:41:29 ryo Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.63 2021/10/31 16:23:47 skrll Exp $");
#include "opt_arm_debug.h"
#include "opt_cpuoptions.h"
@@ -359,7 +359,7 @@
VM_MAX_KERNEL_ADDRESS);
#ifdef DDB
- db_machdep_init();
+ db_machdep_cpu_init();
#endif
uvm_md_init();
diff -r 5eb5ac1dea5c -r 40920aaad5c4 sys/arch/aarch64/aarch64/cpu.c
--- a/sys/arch/aarch64/aarch64/cpu.c Sun Oct 31 15:32:14 2021 +0000
+++ b/sys/arch/aarch64/aarch64/cpu.c Sun Oct 31 16:23:47 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.66 2021/10/30 10:47:03 skrll Exp $ */
+/* $NetBSD: cpu.c,v 1.67 2021/10/31 16:23:47 skrll Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.66 2021/10/30 10:47:03 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.67 2021/10/31 16:23:47 skrll Exp $");
#include "locators.h"
#include "opt_arm_debug.h"
@@ -72,12 +72,13 @@
#endif
void cpu_attach(device_t, cpuid_t);
+void cpu_setup_id(struct cpu_info *);
+
static void identify_aarch64_model(uint32_t, char *, size_t);
static void cpu_identify(device_t self, struct cpu_info *);
static void cpu_identify1(device_t self, struct cpu_info *);
static void cpu_identify2(device_t self, struct cpu_info *);
static void cpu_init_counter(struct cpu_info *);
-static void cpu_setup_id(struct cpu_info *);
static void cpu_setup_sysctl(device_t, struct cpu_info *);
static void cpu_setup_rng(device_t, struct cpu_info *);
static void cpu_setup_aes(device_t, struct cpu_info *);
@@ -109,7 +110,6 @@
if (unit == 0) {
ci = curcpu();
ci->ci_cpuid = id;
- cpu_setup_id(ci);
} else {
#ifdef MULTIPROCESSOR
if ((boothowto & RB_MD1) != 0) {
@@ -150,26 +150,31 @@
arm_cpu_do_topology(ci);
cpu_identify(dv, ci);
+ cpu_setup_sysctl(dv, ci);
+
#ifdef MULTIPROCESSOR
if (unit != 0) {
mi_cpu_attach(ci);
pmap_tlb_info_attach(&pmap_tlb0_info, ci);
- return;
+ aarch64_parsecacheinfo(ci);
}
#endif /* MULTIPROCESSOR */
- set_cpufuncs();
fpu_attach(ci);
cpu_identify1(dv, ci);
+ aarch64_printcacheinfo(dv, ci);
+ cpu_identify2(dv, ci);
- /* aarch64_getcacheinfo(0) was called by locore.S */
- aarch64_printcacheinfo(dv);
- cpu_identify2(dv, ci);
+ if (unit != 0) {
+ return;
+ }
+
+ db_machdep_init(ci);
cpu_init_counter(ci);
- cpu_setup_sysctl(dv, ci);
+ /* These currently only check the BP. */
cpu_setup_rng(dv, ci);
cpu_setup_aes(dv, ci);
cpu_setup_chacha(dv, ci);
@@ -251,10 +256,9 @@
static void
cpu_identify1(device_t self, struct cpu_info *ci)
{
- uint64_t ctr, clidr, sctlr; /* for cache */
+ struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
+ uint64_t sctlr = ci->ci_sctlr_el1;
- /* SCTLR - System Control Register */
- sctlr = reg_sctlr_el1_read();
if (sctlr & SCTLR_I)
aprint_verbose_dev(self, "IC enabled");
else
@@ -288,8 +292,8 @@
/*
* CTR - Cache Type Register
*/
- ctr = reg_ctr_el0_read();
- clidr = reg_clidr_el1_read();
+ const uint64_t ctr = id->ac_ctr;
+ const uint64_t clidr = id->ac_clidr;
aprint_verbose_dev(self, "Cache Writeback Granule %" PRIu64 "B,"
" Exclusives Reservation Granule %" PRIu64 "B\n",
__SHIFTOUT(ctr, CTR_EL0_CWG_LINE) * 4,
@@ -313,22 +317,14 @@
static void
cpu_identify2(device_t self, struct cpu_info *ci)
{
- struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
- uint64_t dfr0;
-
- if (!CPU_IS_PRIMARY(ci)) {
- cpu_setup_id(ci);
- cpu_setup_sysctl(self, ci);
- }
-
- dfr0 = reg_id_aa64dfr0_el1_read();
+ struct aarch64_sysctl_cpu_id * const id = &ci->ci_id;
aprint_debug_dev(self, "midr=0x%" PRIx32 " mpidr=0x%" PRIx32 "\n",
- (uint32_t)ci->ci_id.ac_midr, (uint32_t)ci->ci_id.ac_mpidr);
+ (uint32_t)id->ac_midr, (uint32_t)id->ac_mpidr);
aprint_verbose_dev(self, "revID=0x%" PRIx64, id->ac_revidr);
/* ID_AA64DFR0_EL1 */
- switch (__SHIFTOUT(dfr0, ID_AA64DFR0_EL1_PMUVER)) {
+ switch (__SHIFTOUT(id->ac_aa64dfr0, ID_AA64DFR0_EL1_PMUVER)) {
case ID_AA64DFR0_EL1_PMUVER_V3:
aprint_verbose(", PMCv3");
break;
@@ -501,13 +497,16 @@
}
/*
- * Fill in this CPUs id data. Must be called from hatched cpus.
+ * Fill in this CPUs id data. Must be called on all cpus.
*/
-static void
+void __noasan
cpu_setup_id(struct cpu_info *ci)
{
struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
+ /* SCTLR - System Control Register */
+ ci->ci_sctlr_el1 = reg_sctlr_el1_read();
+
memset(id, 0, sizeof *id);
id->ac_midr = reg_midr_el1_read();
@@ -611,10 +610,6 @@
{
struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
- /* Probably shared between cores. */
- if (!CPU_IS_PRIMARY(ci))
- return;
-
/* Verify that it is supported. */
switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_RNDR)) {
case ID_AA64ISAR0_EL1_RNDR_RNDRRS:
@@ -676,25 +671,47 @@
}
#ifdef MULTIPROCESSOR
+/*
+ * Initialise a secondary processor.
+ *
+ * printf isn't available as kmutex(9) relies on curcpu which isn't setup yet.
+ *
+ */
+void __noasan
+cpu_init_secondary_processor(int cpuindex)
+{
+ struct cpu_info * ci = &cpu_info_store[cpuindex];
+ struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
+
+ aarch64_setcpufuncs(ci);
+
+ /* Sets ci->ci_{sctlr,midr,mpidr}, etc */
+ cpu_setup_id(ci);
+
+ arm_cpu_topology_set(ci, id->ac_mpidr);
+ aarch64_getcacheinfo(ci);
+
+ cpu_set_hatched(cpuindex);
+
+ /*
+ * return to assembly to wait for cpu_boot_secondary_processors
+ */
+}
+
+
+/*
+ * When we are called, the MMU and caches are on and we are running on the stack
+ * of the idlelwp for this cpu.
+ */
void
cpu_hatch(struct cpu_info *ci)
{
KASSERT(curcpu() == ci);
KASSERT((reg_tcr_el1_read() & TCR_EPD0) != 0);
- mutex_enter(&cpu_hatch_lock);
-
- set_cpufuncs();
- fpu_attach(ci);
-
- cpu_identify1(ci->ci_dev, ci);
- aarch64_getcacheinfo(device_unit(ci->ci_dev));
- aarch64_printcacheinfo(ci->ci_dev);
- cpu_identify2(ci->ci_dev, ci);
#ifdef DDB
- db_machdep_init();
+ db_machdep_cpu_init();
#endif
- mutex_exit(&cpu_hatch_lock);
cpu_init_counter(ci);
diff -r 5eb5ac1dea5c -r 40920aaad5c4 sys/arch/aarch64/aarch64/cpufunc.c
--- a/sys/arch/aarch64/aarch64/cpufunc.c Sun Oct 31 15:32:14 2021 +0000
+++ b/sys/arch/aarch64/aarch64/cpufunc.c Sun Oct 31 16:23:47 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.c,v 1.31 2021/10/31 07:56:55 skrll Exp $ */
+/* $NetBSD: cpufunc.c,v 1.32 2021/10/31 16:23:47 skrll Exp $ */
/*
* Copyright (c) 2017 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -30,7 +30,7 @@
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.31 2021/10/31 07:56:55 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.32 2021/10/31 16:23:47 skrll Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -53,13 +53,7 @@
int aarch64_pan_enabled __read_mostly;
int aarch64_pac_enabled __read_mostly;
-/* cache info per cluster. the same cluster has the same cache configuration? */
-#define MAXCPUPACKAGES MAXCPUS /* maximum of ci->ci_package_id */
-static struct aarch64_cache_info *aarch64_cacheinfo[MAXCPUPACKAGES];
-static struct aarch64_cache_info aarch64_cacheinfo0[MAX_CACHE_LEVEL];
-
-
-static void
+static void __noasan
extract_cacheunit(int level, bool insn, int cachetype,
struct aarch64_cache_info *cacheinfo)
{
@@ -101,35 +95,14 @@
cunit->cache_size = cunit->cache_way_size * cunit->cache_ways;
}
-void
-aarch64_getcacheinfo(int unit)
+
+/* Must be called on each processor */
+void __noasan
+aarch64_getcacheinfo(struct cpu_info *ci)
{
- struct cpu_info * const ci = curcpu();
+ struct aarch64_cache_info * const cinfo = ci->ci_cacheinfo;
uint32_t clidr, ctr;
- u_int vindexsize;
int level, cachetype;
- struct aarch64_cache_info *cinfo = NULL;
-
- if (cputype == 0)
- cputype = aarch64_cpuid();
-
- /* already extract about this cluster? */
Home |
Main Index |
Thread Index |
Old Index