From patchwork Wed Jan 29 12:32:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandar Rikalo X-Patchwork-Id: 13953722 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 765F823AD; Wed, 29 Jan 2025 12:32:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738153981; cv=none; b=VqK6M+HIqzyMUv59B7e50LTiHyh02Ubz/gYa6bgPsmwZnaWycEbUqgM8ka+A8fTN9nqn1p0UA2KujKqZ9CW0XC6b4HFcyuT2eBLL3DyF0aQmYf47rHmEvH13uVkvsyimYtaxFLsvyXxioNTViuscmX0i7YbXTIWFB2r784n8Dzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738153981; c=relaxed/simple; bh=3cjx2TjxatDPLqJe/6zEWQTSw1AQs8ksSwrAIojLhxY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fSUMtZpETCMGfMPu5ifRg4mJuow3hAHD8WVB5SSPrPT7MFnJul6RWqzlddFrP8eNGOGd6ZtSy6tSYCl5jXORa/gBnvE+KStpUXgORrfVWYjJ5xDI7/2lOuQU3tJbscnUGyPuJ8fzttb3klIXRGKFSJoHHWi//9B0Mf5F8XqxY3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=W5MDXvRA; arc=none smtp.client-ip=209.85.218.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W5MDXvRA" Received: by mail-ej1-f43.google.com with SMTP id a640c23a62f3a-aa6a92f863cso1356958966b.1; Wed, 29 Jan 2025 04:32:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1738153977; x=1738758777; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Nqic8N3aCmviXH9sGcbk48Wn5BVUu3oDSMpElIGJuME=; b=W5MDXvRAr4n7IxtmTZqXPshJuWkPOC3EA0wvChJ06rGSVl8+4ET6SXv8fyyxovFCon FMY57mGp42xH2/HTv51F59feV/wiSM4w2e4car5bFTU1nSYn1I1xQsPT1xkOCKKacKxx bnOdtlkbqmvs85/lDpzdFTTch9NOqGNKoX8RqRTuKxK78MF0o2ZGu92jom6aAYCpIwUE QKd+WkO9xGawkKDdqdNcdC1AGG/0qp+RTaCHIWTO228otd7y/hA8ghFPxJNpMA2+ulWy VxVKsl6VyNiS54YGbEGqS3zop6m884gjuMyvlNzKgsiveaUVsoe1j8U59NxKQWb6wa7H oUhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738153977; x=1738758777; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Nqic8N3aCmviXH9sGcbk48Wn5BVUu3oDSMpElIGJuME=; b=eHmDUvJSLNJI5KPJleisFDD7SflLM4UkUA8Eqe1wFVlNo0bzl8qEnFi6zPqVb5WC8m FMHN+/FlcxToZWdvAb0qOxOcnjYCCmlNVX+LwxvJY33PDvUnmVloTphr1ZIVGEWydm61 iyt8CgTtBbZ1J75qZGfzv/vBAcpEBnP+nORoiGW3Z/8ocnbCt1nSv1X2vsrhOyqaSRYd HpC584uNBg3RB6G64CurY3rtVWcr6PQlyiDd5LCQh59MVIsr3sk6RgsbH/qUjQVUtac5 Rvz1Cr/ueCFMqlBM4aEnDmaPxZ62Pu7LWWIrvq5tN+CrvZwW9xGBLzFEtYKQumoa9tA6 8lXQ== X-Gm-Message-State: AOJu0YzsnFAH5GW+DSet/QpdQxFuagv60x6RoVKoRAfFbUDPyBnykf// EjYA+BhmeaehirWePLRYWAEOQmFcXxNVePIF3atTeY9ezNIw32ii6k22lDB5 X-Gm-Gg: ASbGnctxgLF6L0Oxo1jPasZUve5gqXTcolVJL+tJolgW+pDxmNgrznYaOJaznPifiWu kVDch6vJcxXGL/tfDZixiX/ILWGDxWFkC3uv8s82YYGCjrLC0q/9ruqUcXnLAaClAje6mZ8w4Ta MS11+SnsbVtXOGUz5Z+jCDvdyzew2dV6As0PtSZ9LTAvpP8GQ9+gvjgxbnzNloiSs/8VRsNpIcs ivM7n4YQaXE5TyEW6wZNw3FQmnyd+ZkCR1SYv/WXSUJFlrbz8NUx/iUv5a9YW/XexNsIUG7CIGE 2aNd1X1A08Jbn8Gs/HmQzQXr X-Google-Smtp-Source: AGHT+IFYC6HW2cW22fKXnZlUC6K8G02XvzM9QfiLtu+NzFcwfMK/TaosRDJNZar5hojZqF80RGKbBA== X-Received: by 2002:a17:907:1c27:b0:aa6:873b:ed8a with SMTP id a640c23a62f3a-ab6cfdc6719mr258649466b.47.1738153977252; Wed, 29 Jan 2025 04:32:57 -0800 (PST) Received: from localhost.localdomain ([79.175.114.8]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab69051b1ddsm733540766b.180.2025.01.29.04.32.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Jan 2025 04:32:56 -0800 (PST) From: Aleksandar Rikalo To: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Thomas Bogendoerfer , Daniel Lezcano , Thomas Gleixner , Gregory CLEMENT , Serge Semin , Jiaxun Yang , Paul Burton , Aleksandar Rikalo , Chao-ying Fu , Djordje Todorovic Subject: [PATCH v9 3/4] MIPS: CPS: Introduce struct cluster_boot_config Date: Wed, 29 Jan 2025 13:32:49 +0100 Message-Id: <20250129123250.711910-4-arikalo@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250129123250.711910-1-arikalo@gmail.com> References: <20250129123250.711910-1-arikalo@gmail.com> Precedence: bulk X-Mailing-List: linux-mips@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Paul Burton 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 Signed-off-by: Dragan Mladjenovic Signed-off-by: Aleksandar Rikalo Tested-by: Serge Semin Tested-by: Gregory CLEMENT --- 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);