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: David Daney <david.daney@cavium.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/12319/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
Родитель
58546e3b73
Коммит
7d52ab163c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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__ */
|
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче