[PATCH v2] platform: generic: spacemit: add K1

Troy Mitchell troy.mitchell at linux.spacemit.com
Sun Sep 21 20:56:08 PDT 2025


Hi Xing W, Thanks for you reviewing.

> > +static void spacemit_k1_pre_init(void)
> > +{
> > +	unsigned int hartid, clusterid, cluster_enabled = 0;
> > +	unsigned int cur_hartid = current_hartid();
> > +	struct sbi_scratch *scratch;
> > +	int i;
> > +
> > +	scratch = sbi_hartid_to_scratch(cur_hartid);
> 
> s/sbi_hartid_to_scratch(cur_hartid)/sbi_scratch_thishart_ptr()/
> 
> sbi_hartid_to_scratch can not access before sbi_scratch_init.
Uh, I have double checked the sbi source code,
and I think I can call sbi_hartid_to_scratch() here.

in lib/sbi/sbi_init.c +281:
```
static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
{
	int rc;
	unsigned long *count;
	const struct sbi_platform *plat = sbi_platform_ptr(scratch);

	/* Note: This has to be first thing in coldboot init sequence */
	rc = sbi_scratch_init(scratch);
	if (rc)
		sbi_hart_hang();

  ...

  rc = sbi_platform_early_init(plat, true);
	if (rc)
		sbi_hart_hang();
  ...
}
```

and k1_pre_init() is called by k1_early_init() after
sbi_scratch_init().

If I'm missing something, please let me know.

But I have checked the API what you mentioned.
That's a right API and I'll use it in the next version.

But I really wanna know if sbi_hartid_to_scratch() can be called here.

                - Troy


> 
> Regards,
> Xiang W
> 
> > +
> > +	writel(scratch->warmboot_addr, (unsigned int *)C0_RVBADDR_LO_ADDR);
> > +	writel(scratch->warmboot_addr >> 32, (unsigned int *)C0_RVBADDR_HI_ADDR);
> > +
> > +	writel(scratch->warmboot_addr, (unsigned int *)C1_RVBADDR_LO_ADDR);
> > +	writel(scratch->warmboot_addr >> 32, (unsigned int *)C1_RVBADDR_HI_ADDR);
> > +
> > +	for (i = 0; i < platform.hart_count; i++) {
> > +		hartid = platform.hart_index2id[i];
> > +		clusterid = CPU_TO_CLUSTER(hartid);
> > +
> > +		if (!(cluster_enabled & (1 << clusterid))) {
> > +			cluster_enabled |= 1 << clusterid;
> > +			cci_enable_snoop_dvm_reqs(clusterid);
> > +		}
> > +	}
> > +}
> > +
> > +/* Start (or power-up) the given hart */
> > +static int spacemit_hart_start(unsigned int hartid, unsigned long saddr)
> > +{
> > +	spacemit_wakeup_cpu(hartid);
> > +
> > +	return 0;
> > +}
> > +
> > +/*
> > + * Stop (or power-down) the current hart from running. This call
> > + * doesn't expect to return if success.
> > + */
> > +static int spacemit_hart_stop(void)
> > +{
> > +	csr_write(CSR_STIMECMP, GENMASK_ULL(63, 0));
> > +	csr_clear(CSR_MIE, MIP_SSIP | MIP_MSIP | MIP_STIP | MIP_MTIP | MIP_SEIP | MIP_MEIP);
> > +
> > +	/* disable data preftch */
> > +	csr_clear(CSR_MSETUP, MSETUP_PFE);
> > +	asm volatile ("fence iorw, iorw");
> > +
> > +	/* flush local dcache */
> > +	csr_write(CSR_MRAOP, MRAOP_ICACHE_INVALID);
> > +	asm volatile ("fence iorw, iorw");
> > +
> > +	/* disable dcache */
> > +	csr_clear(CSR_MSETUP, MSETUP_DE);
> > +	asm volatile ("fence iorw, iorw");
> > +
> > +	/*
> > +	 * Core4-7 do not have dedicated bits in ML2SETUP;
> > +	 * instead, they reuse the same bits as core0-3.
> > +	 *
> > +	 * Therefore, use modulo with PLATFORM_MAX_CPUS_PER_CLUSTER
> > +	 * to select the proper bit.
> > +	 */
> > +	csr_clear(CSR_ML2SETUP, 1 << (current_hartid() % PLATFORM_MAX_CPUS_PER_CLUSTER));
> > +	asm volatile ("fence iorw, iorw");
> > +
> > +	spacemit_assert_cpu();
> > +
> > +	wfi();
> > +
> > +	return SBI_ENOTSUPP;
> > +}
> > +
> > +static const struct sbi_hsm_device spacemit_hsm_ops = {
> > +	.name		= "spacemit-hsm",
> > +	.hart_start	= spacemit_hart_start,
> > +	.hart_stop	= spacemit_hart_stop,
> > +};
> > +
> > +/*
> > + * Platform early initialization.
> > + */
> > +static int spacemit_k1_early_init(bool cold_boot)
> > +{
> > +	int rc;
> > +
> > +	rc = generic_early_init(cold_boot);
> > +	if (rc)
> > +		return rc;
> > +
> > +	csr_set(CSR_MSETUP, MSETUP_DE | MSETUP_IE | MSETUP_BPE |
> > +		MSETUP_PFE | MSETUP_MME | MSETUP_ECCE);
> > +
> > +	if (cold_boot)
> > +		spacemit_k1_pre_init();
> > +	else
> > +		spacemit_deassert_cpu();
> > +
> > +	return 0;
> > +}
> > +
> > +static int spacemit_k1_final_init(bool cold_boot)
> > +{
> > +	if (cold_boot)
> > +		sbi_hsm_set_device(&spacemit_hsm_ops);
> > +
> > +	return generic_final_init(cold_boot);
> > +}
> > +
> > +static bool spacemit_cold_boot_allowed(u32 hartid)
> > +{
> > +	csr_set(CSR_ML2SETUP, 1 << (hartid % PLATFORM_MAX_CPUS_PER_CLUSTER));
> > +
> > +	return !hartid;
> > +}
> > +
> > +static int spacemit_k1_platform_init(const void *fdt, int nodeoff,
> > +				     const struct fdt_match *match)
> > +{
> > +	generic_platform_ops.early_init = spacemit_k1_early_init;
> > +	generic_platform_ops.final_init = spacemit_k1_final_init;
> > +	generic_platform_ops.cold_boot_allowed = spacemit_cold_boot_allowed;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct fdt_match spacemit_k1_match[] = {
> > +	{ .compatible = "spacemit,k1" },
> > +	{ /* sentinel */ }
> > +};
> > +
> > +const struct fdt_driver spacemit_k1 = {
> > +	.match_table = spacemit_k1_match,
> > +	.init = spacemit_k1_platform_init,
> > +};
> > diff --git a/platform/generic/spacemit/objects.mk b/platform/generic/spacemit/objects.mk
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..4bf973aab1ba749b59cfdc14a572226d54c3ff15
> > --- /dev/null
> > +++ b/platform/generic/spacemit/objects.mk
> > @@ -0,0 +1,7 @@
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause
> > +#
> > +# Copyright (c) 2025 SpacemiT
> > +
> > +carray-platform_override_modules-$(CONFIG_PLATFORM_SPACEMIT_K1) += spacemit_k1
> > +platform-objs-$(CONFIG_PLATFORM_SPACEMIT_K1) += spacemit/k1.o
> > 
> > ---
> > base-commit: 153cdeea5350837c1206a2d2b6189fd0ba06d1f2
> > change-id: 20250911-smt-k1-8-cores-8985c5f40c5f
> > 
> > Best regards,
> > -- 
> > Troy Mitchell <troy.mitchell at linux.spacemit.com>
> > 
> 
> 



More information about the opensbi mailing list