From: Aleksandar Rikalo <arikalo@gmail.com>
To: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
Daniel Lezcano <daniel.lezcano@linaro.org>,
Thomas Gleixner <tglx@linutronix.de>,
Gregory CLEMENT <gregory.clement@bootlin.com>,
Serge Semin <fancer.lancer@gmail.com>,
Jiaxun Yang <jiaxun.yang@flygoat.com>,
Paul Burton <paulburton@kernel.org>,
Aleksandar Rikalo <arikalo@gmail.com>,
Chao-ying Fu <cfu@mips.com>,
Djordje Todorovic <djordje.todorovic@htecgroup.com>
Subject: [PATCH v9 3/4] MIPS: CPS: Introduce struct cluster_boot_config
Date: Wed, 29 Jan 2025 13:32:49 +0100 [thread overview]
Message-ID: <20250129123250.711910-4-arikalo@gmail.com> (raw)
In-Reply-To: <20250129123250.711910-1-arikalo@gmail.com>
From: Paul Burton <paulburton@kernel.org>
In preparation for supporting multi-cluster systems, introduce a struct
cluster_boot_config as an extra layer in the boot configuration
maintained by the MIPS Coherent Processing System (CPS) SMP
implementation. For now only one struct cluster_boot_config will be
allocated & we'll simply defererence its core_config field to find the
struct core_boot_config array which can be used to boot as usual.
Signed-off-by: Paul Burton <paulburton@kernel.org>
Signed-off-by: Dragan Mladjenovic <dragan.mladjenovic@syrmia.com>
Signed-off-by: Aleksandar Rikalo <arikalo@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/mips/include/asm/smp-cps.h | 6 ++-
arch/mips/kernel/asm-offsets.c | 3 ++
arch/mips/kernel/cps-vec.S | 19 ++++++--
arch/mips/kernel/pm-cps.c | 5 +-
arch/mips/kernel/smp-cps.c | 82 +++++++++++++++++++++------------
5 files changed, 81 insertions(+), 34 deletions(-)
diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h
index ab94e50f62b8..a629e948a6fd 100644
--- a/arch/mips/include/asm/smp-cps.h
+++ b/arch/mips/include/asm/smp-cps.h
@@ -22,7 +22,11 @@ struct core_boot_config {
struct vpe_boot_config *vpe_config;
};
-extern struct core_boot_config *mips_cps_core_bootcfg;
+struct cluster_boot_config {
+ struct core_boot_config *core_config;
+};
+
+extern struct cluster_boot_config *mips_cps_cluster_bootcfg;
extern void mips_cps_core_boot(int cca, void __iomem *gcr_base);
extern void mips_cps_core_init(void);
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index cb1045ebab06..b29944160b28 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -404,6 +404,9 @@ void output_cps_defines(void)
{
COMMENT(" MIPS CPS offsets. ");
+ OFFSET(CLUSTERBOOTCFG_CORECONFIG, cluster_boot_config, core_config);
+ DEFINE(CLUSTERBOOTCFG_SIZE, sizeof(struct cluster_boot_config));
+
OFFSET(COREBOOTCFG_VPEMASK, core_boot_config, vpe_mask);
OFFSET(COREBOOTCFG_VPECONFIG, core_boot_config, vpe_config);
DEFINE(COREBOOTCFG_SIZE, sizeof(struct core_boot_config));
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index f876309130ad..2ae7034a3d5c 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -19,6 +19,10 @@
#define GCR_CPC_BASE_OFS 0x0088
#define GCR_CL_COHERENCE_OFS 0x2008
#define GCR_CL_ID_OFS 0x2028
+#define CM3_GCR_Cx_ID_CLUSTER_SHF 8
+#define CM3_GCR_Cx_ID_CLUSTER_MSK (0xff << 8)
+#define CM3_GCR_Cx_ID_CORENUM_SHF 0
+#define CM3_GCR_Cx_ID_CORENUM_MSK (0xff << 0)
#define CPC_CL_VC_STOP_OFS 0x2020
#define CPC_CL_VC_RUN_OFS 0x2028
@@ -271,12 +275,21 @@ LEAF(mips_cps_core_init)
*/
LEAF(mips_cps_get_bootcfg)
/* Calculate a pointer to this cores struct core_boot_config */
+ PTR_LA v0, mips_cps_cluster_bootcfg
+ PTR_L v0, 0(v0)
lw t0, GCR_CL_ID_OFS(s1)
+#ifdef CONFIG_CPU_MIPSR6
+ ext t1, t0, CM3_GCR_Cx_ID_CLUSTER_SHF, 8
+ li t2, CLUSTERBOOTCFG_SIZE
+ mul t1, t1, t2
+ PTR_ADDU \
+ v0, v0, t1
+#endif
+ PTR_L v0, CLUSTERBOOTCFG_CORECONFIG(v0)
+ andi t0, t0, CM3_GCR_Cx_ID_CORENUM_MSK
li t1, COREBOOTCFG_SIZE
mul t0, t0, t1
- PTR_LA t1, mips_cps_core_bootcfg
- PTR_L t1, 0(t1)
- PTR_ADDU v0, t0, t1
+ PTR_ADDU v0, v0, t0
/* Calculate this VPEs ID. If the core doesn't support MT use 0 */
li t9, 0
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
index 9369a8dc385e..3de0e05e0511 100644
--- a/arch/mips/kernel/pm-cps.c
+++ b/arch/mips/kernel/pm-cps.c
@@ -101,12 +101,14 @@ static void coupled_barrier(atomic_t *a, unsigned online)
int cps_pm_enter_state(enum cps_pm_state state)
{
unsigned cpu = smp_processor_id();
+ unsigned int cluster = cpu_cluster(¤t_cpu_data);
unsigned core = cpu_core(¤t_cpu_data);
unsigned online, left;
cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled);
u32 *core_ready_count, *nc_core_ready_count;
void *nc_addr;
cps_nc_entry_fn entry;
+ struct cluster_boot_config *cluster_cfg;
struct core_boot_config *core_cfg;
struct vpe_boot_config *vpe_cfg;
atomic_t *barrier;
@@ -136,7 +138,8 @@ int cps_pm_enter_state(enum cps_pm_state state)
if (!mips_cps_smp_in_use())
return -EINVAL;
- core_cfg = &mips_cps_core_bootcfg[core];
+ cluster_cfg = &mips_cps_cluster_bootcfg[cluster];
+ core_cfg = &cluster_cfg->core_config[core];
vpe_cfg = &core_cfg->vpe_config[cpu_vpe_id(¤t_cpu_data)];
vpe_cfg->pc = (unsigned long)mips_cps_pm_restore;
vpe_cfg->gp = (unsigned long)current_thread_info();
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index 82c8f9b9573c..3d8cf3098656 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -40,7 +40,7 @@ static DECLARE_BITMAP(core_power, NR_CPUS);
static u64 core_entry_reg;
static phys_addr_t cps_vec_pa;
-struct core_boot_config *mips_cps_core_bootcfg;
+struct cluster_boot_config *mips_cps_cluster_bootcfg;
static unsigned __init core_vpe_count(unsigned int cluster, unsigned core)
{
@@ -238,8 +238,10 @@ static void __init cps_smp_setup(void)
static void __init cps_prepare_cpus(unsigned int max_cpus)
{
- unsigned ncores, core_vpes, c, cca;
+ unsigned int nclusters, ncores, core_vpes, c, cl, cca;
bool cca_unsuitable, cores_limited;
+ struct cluster_boot_config *cluster_bootcfg;
+ struct core_boot_config *core_bootcfg;
mips_mt_set_cpuoptions();
@@ -281,40 +283,54 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
setup_cps_vecs();
- /* Allocate core boot configuration structs */
- ncores = mips_cps_numcores(0);
- mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg),
- GFP_KERNEL);
- if (!mips_cps_core_bootcfg) {
- pr_err("Failed to allocate boot config for %u cores\n", ncores);
- goto err_out;
- }
+ /* Allocate cluster boot configuration structs */
+ nclusters = mips_cps_numclusters();
+ mips_cps_cluster_bootcfg = kcalloc(nclusters,
+ sizeof(*mips_cps_cluster_bootcfg),
+ GFP_KERNEL);
- /* Allocate VPE boot configuration structs */
- for (c = 0; c < ncores; c++) {
- core_vpes = core_vpe_count(0, c);
- mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes,
- sizeof(*mips_cps_core_bootcfg[c].vpe_config),
- GFP_KERNEL);
- if (!mips_cps_core_bootcfg[c].vpe_config) {
- pr_err("Failed to allocate %u VPE boot configs\n",
- core_vpes);
+ for (cl = 0; cl < nclusters; cl++) {
+ /* Allocate core boot configuration structs */
+ ncores = mips_cps_numcores(cl);
+ core_bootcfg = kcalloc(ncores, sizeof(*core_bootcfg),
+ GFP_KERNEL);
+ if (!core_bootcfg)
goto err_out;
+ mips_cps_cluster_bootcfg[cl].core_config = core_bootcfg;
+
+ /* Allocate VPE boot configuration structs */
+ for (c = 0; c < ncores; c++) {
+ core_vpes = core_vpe_count(cl, c);
+ core_bootcfg[c].vpe_config = kcalloc(core_vpes,
+ sizeof(*core_bootcfg[c].vpe_config),
+ GFP_KERNEL);
+ if (!core_bootcfg[c].vpe_config)
+ goto err_out;
}
}
/* Mark this CPU as booted */
- atomic_set(&mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)].vpe_mask,
- 1 << cpu_vpe_id(¤t_cpu_data));
+ cl = cpu_cluster(¤t_cpu_data);
+ c = cpu_core(¤t_cpu_data);
+ cluster_bootcfg = &mips_cps_cluster_bootcfg[cl];
+ core_bootcfg = &cluster_bootcfg->core_config[c];
+ atomic_set(&core_bootcfg->vpe_mask, 1 << cpu_vpe_id(¤t_cpu_data));
return;
err_out:
/* Clean up allocations */
- if (mips_cps_core_bootcfg) {
- for (c = 0; c < ncores; c++)
- kfree(mips_cps_core_bootcfg[c].vpe_config);
- kfree(mips_cps_core_bootcfg);
- mips_cps_core_bootcfg = NULL;
+ if (mips_cps_cluster_bootcfg) {
+ for (cl = 0; cl < nclusters; cl++) {
+ cluster_bootcfg = &mips_cps_cluster_bootcfg[cl];
+ ncores = mips_cps_numcores(cl);
+ for (c = 0; c < ncores; c++) {
+ core_bootcfg = &cluster_bootcfg->core_config[c];
+ kfree(core_bootcfg->vpe_config);
+ }
+ kfree(mips_cps_cluster_bootcfg[c].core_config);
+ }
+ kfree(mips_cps_cluster_bootcfg);
+ mips_cps_cluster_bootcfg = NULL;
}
/* Effectively disable SMP by declaring CPUs not present */
@@ -405,17 +421,23 @@ static void boot_core(unsigned int core, unsigned int vpe_id)
static void remote_vpe_boot(void *dummy)
{
+ unsigned int cluster = cpu_cluster(¤t_cpu_data);
unsigned core = cpu_core(¤t_cpu_data);
- struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
+ struct cluster_boot_config *cluster_cfg =
+ &mips_cps_cluster_bootcfg[cluster];
+ struct core_boot_config *core_cfg = &cluster_cfg->core_config[core];
mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data));
}
static int cps_boot_secondary(int cpu, struct task_struct *idle)
{
+ unsigned int cluster = cpu_cluster(&cpu_data[cpu]);
unsigned core = cpu_core(&cpu_data[cpu]);
unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]);
- struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core];
+ struct cluster_boot_config *cluster_cfg =
+ &mips_cps_cluster_bootcfg[cluster];
+ struct core_boot_config *core_cfg = &cluster_cfg->core_config[core];
struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id];
unsigned int remote;
int err;
@@ -576,12 +598,14 @@ static void cps_kexec_nonboot_cpu(void)
static int cps_cpu_disable(void)
{
unsigned cpu = smp_processor_id();
+ struct cluster_boot_config *cluster_cfg;
struct core_boot_config *core_cfg;
if (!cps_pm_support_state(CPS_PM_POWER_GATED))
return -EINVAL;
- core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)];
+ cluster_cfg = &mips_cps_cluster_bootcfg[cpu_cluster(¤t_cpu_data)];
+ core_cfg = &cluster_cfg->core_config[cpu_core(¤t_cpu_data)];
atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask);
smp_mb__after_atomic();
set_cpu_online(cpu, false);
--
2.25.1
next prev parent reply other threads:[~2025-01-29 12:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-29 12:32 [PATCH v9 0/4] MIPS: Support I6500 multi-cluster configuration Aleksandar Rikalo
2025-01-29 12:32 ` [PATCH v9 1/4] clocksource: mips-gic-timer: Enable counter when CPUs start Aleksandar Rikalo
2025-02-19 11:50 ` Thomas Bogendoerfer
2025-02-19 12:38 ` Daniel Lezcano
2025-01-29 12:32 ` [PATCH v9 2/4] MIPS: pm-cps: Use per-CPU variables as per-CPU, not per-core Aleksandar Rikalo
2025-01-29 12:32 ` Aleksandar Rikalo [this message]
2025-01-29 12:32 ` [PATCH v9 4/4] MIPS: CPS: Boot CPUs in secondary clusters Aleksandar Rikalo
2025-02-21 9:31 ` [PATCH v9 0/4] MIPS: Support I6500 multi-cluster configuration Thomas Bogendoerfer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250129123250.711910-4-arikalo@gmail.com \
--to=arikalo@gmail.com \
--cc=cfu@mips.com \
--cc=daniel.lezcano@linaro.org \
--cc=djordje.todorovic@htecgroup.com \
--cc=fancer.lancer@gmail.com \
--cc=gregory.clement@bootlin.com \
--cc=jiaxun.yang@flygoat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=paulburton@kernel.org \
--cc=tglx@linutronix.de \
--cc=tsbogend@alpha.franken.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.