Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d52ab16 authored by David Daney's avatar David Daney Committed by Ralf Baechle
Browse files

MIPS: OCTEON: Extend number of supported CPUs past 32



To support more than 48 CPUs, the bootinfo structure grows a new
coremask structure.  Add the definition of the structure and add it to
struct cvmx_bootinfo.  In prom_init(), copy the new coremask data into
the sysinfo structure, and use it in smp_setup().

Signed-off-by: default avatarDavid Daney <david.daney@cavium.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12319/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 58546e3b
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -637,9 +637,22 @@ void __init prom_init(void)
	sysinfo = cvmx_sysinfo_get();
	memset(sysinfo, 0, sizeof(*sysinfo));
	sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
	sysinfo->phy_mem_desc_ptr =
		cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
	sysinfo->core_mask = octeon_bootinfo->core_mask;
	sysinfo->phy_mem_desc_addr = (u64)phys_to_virt(octeon_bootinfo->phy_mem_desc_addr);

	if ((octeon_bootinfo->major_version > 1) ||
	    (octeon_bootinfo->major_version == 1 &&
	     octeon_bootinfo->minor_version >= 4))
		cvmx_coremask_copy(&sysinfo->core_mask,
				   &octeon_bootinfo->ext_core_mask);
	else
		cvmx_coremask_set64(&sysinfo->core_mask,
				    octeon_bootinfo->core_mask);

	/* Some broken u-boot pass garbage in upper bits, clear them out */
	if (!OCTEON_IS_MODEL(OCTEON_CN78XX))
		for (i = 512; i < 1024; i++)
			cvmx_coremask_clear_core(&sysinfo->core_mask, i);

	sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
	sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
	sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+3 −1
Original line number Diff line number Diff line
@@ -103,6 +103,8 @@ static void octeon_smp_setup(void)
	int cpus;
	int id;
	int core_mask = octeon_get_boot_coremask();
	struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();

#ifdef CONFIG_HOTPLUG_CPU
	unsigned int num_cores = cvmx_octeon_num_cores();
#endif
@@ -119,7 +121,7 @@ static void octeon_smp_setup(void)
	/* The present CPUs get the lowest CPU numbers. */
	cpus = 1;
	for (id = 0; id < NR_CPUS; id++) {
		if ((id != coreid) && (core_mask & (1 << id))) {
		if ((id != coreid) && cvmx_coremask_is_core_set(&sysinfo->core_mask, id)) {
			set_cpu_possible(cpus, true);
			set_cpu_present(cpus, true);
			__cpu_number_map[id] = cpus;
+13 −1
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#ifndef __CVMX_BOOTINFO_H__
#define __CVMX_BOOTINFO_H__

#include "cvmx-coremask.h"

/*
 * Current major and minor versions of the CVMX bootinfo block that is
 * passed from the bootloader to the application.  This is versioned
@@ -39,7 +41,7 @@
 * versions.
 */
#define CVMX_BOOTINFO_MAJ_VER 1
#define CVMX_BOOTINFO_MIN_VER 3
#define CVMX_BOOTINFO_MIN_VER 4

#if (CVMX_BOOTINFO_MAJ_VER == 1)
#define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20
@@ -124,6 +126,13 @@ struct cvmx_bootinfo {
	 */
	uint64_t fdt_addr;
#endif
#if (CVMX_BOOTINFO_MIN_VER >= 4)
	/*
	 * Coremask used for processors with more than 32 cores
	 * or with OCI.  This replaces core_mask.
	 */
	struct cvmx_coremask ext_core_mask;
#endif
#else				/* __BIG_ENDIAN */
	/*
	 * Little-Endian: When the CPU mode is switched to
@@ -177,6 +186,9 @@ struct cvmx_bootinfo {
#if (CVMX_BOOTINFO_MIN_VER >= 3)
	uint64_t fdt_addr;
#endif
#if (CVMX_BOOTINFO_MIN_VER >= 4)
	struct cvmx_coremask ext_core_mask;
#endif
#endif
};

+89 −0
Original line number Diff line number Diff line
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2016  Cavium Inc. (support@cavium.com).
 *
 */

/*
 * Module to support operations on bitmap of cores. Coremask can be used to
 * select a specific core, a group of cores, or all available cores, for
 * initialization and differentiation of roles within a single shared binary
 * executable image.
 *
 * The core numbers used in this file are the same value as what is found in
 * the COP0_EBASE register and the rdhwr 0 instruction.
 *
 * For the CN78XX and other multi-node environments the core numbers are not
 * contiguous.  The core numbers for the CN78XX are as follows:
 *
 * Node 0:	Cores 0 - 47
 * Node 1:	Cores 128 - 175
 * Node 2:	Cores 256 - 303
 * Node 3:	Cores 384 - 431
 *
 */

#ifndef __CVMX_COREMASK_H__
#define __CVMX_COREMASK_H__

#define CVMX_MIPS_MAX_CORES 1024
/* bits per holder */
#define CVMX_COREMASK_ELTSZ 64

/* cvmx_coremask_t's size in u64 */
#define CVMX_COREMASK_BMPSZ (CVMX_MIPS_MAX_CORES / CVMX_COREMASK_ELTSZ)


/* cvmx_coremask_t */
struct cvmx_coremask {
	u64 coremask_bitmap[CVMX_COREMASK_BMPSZ];
};

/*
 * Is ``core'' set in the coremask?
 */
static inline bool cvmx_coremask_is_core_set(const struct cvmx_coremask *pcm,
					    int core)
{
	int n, i;

	n = core % CVMX_COREMASK_ELTSZ;
	i = core / CVMX_COREMASK_ELTSZ;

	return (pcm->coremask_bitmap[i] & ((u64)1 << n)) != 0;
}

/*
 * Make a copy of a coremask
 */
static inline void cvmx_coremask_copy(struct cvmx_coremask *dest,
				      const struct cvmx_coremask *src)
{
	memcpy(dest, src, sizeof(*dest));
}

/*
 * Set the lower 64-bit of the coremask.
 */
static inline void cvmx_coremask_set64(struct cvmx_coremask *pcm,
				       uint64_t coremask_64)
{
	pcm->coremask_bitmap[0] = coremask_64;
}

/*
 * Clear ``core'' from the coremask.
 */
static inline void cvmx_coremask_clear_core(struct cvmx_coremask *pcm, int core)
{
	int n, i;

	n = core % CVMX_COREMASK_ELTSZ;
	i = core / CVMX_COREMASK_ELTSZ;
	pcm->coremask_bitmap[i] &= ~(1ull << n);
}

#endif /* __CVMX_COREMASK_H__ */
+4 −3
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@
#ifndef __CVMX_SYSINFO_H__
#define __CVMX_SYSINFO_H__

#include "cvmx-coremask.h"

#define OCTEON_SERIAL_LEN 20
/**
 * Structure describing application specific information.
@@ -50,8 +52,7 @@ struct cvmx_sysinfo {
	uint64_t system_dram_size;

	/* ptr to memory descriptor block */
	void *phy_mem_desc_ptr;

	uint64_t phy_mem_desc_addr;

	/* Application image specific variables */
	/* stack top address (virtual) */
@@ -63,7 +64,7 @@ struct cvmx_sysinfo {
	/* heap size in bytes */
	uint32_t heap_size;
	/* coremask defining cores running application */
	uint32_t core_mask;
	struct cvmx_coremask core_mask;
	/* Deprecated, use cvmx_coremask_first_core() to select init core */
	uint32_t init_core;