Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
02f8c038
Unverified
Commit
02f8c038
authored
Mar 29, 2018
by
Dimitris Papastamos
Committed by
GitHub
Mar 29, 2018
Browse files
Merge pull request #1327 from npoushin/npoushin/sgi575
ARM platforms: Add support for SGI575
parents
6ab136c2
b44cfc6d
Changes
15
Hide whitespace changes
Inline
Side-by-side
plat/arm/board/sgi575/platform.mk
0 → 100644
View file @
02f8c038
#
# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
include
plat/arm/css/sgi/sgi-common.mk
plat/arm/css/sgi/aarch64/sgi_helper.S
0 → 100644
View file @
02f8c038
/*
*
Copyright
(
c
)
2018
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
.
globl
plat_is_my_cpu_primary
.
globl
plat_arm_calc_core_pos
/
*
-----------------------------------------------------
*
unsigned
int
plat_is_my_cpu_primary
(
void
)
;
*
*
Find
out
whether
the
current
cpu
is
the
primary
*
cpu
(
applicable
only
after
a
cold
boot
)
*
-----------------------------------------------------
*/
func
plat_is_my_cpu_primary
mov
x9
,
x30
bl
plat_my_core_pos
ldr
x1
,
=
SGI_BOOT_CFG_ADDR
ldr
x1
,
[
x1
]
ubfx
x1
,
x1
,
#
PLAT_CSS_PRIMARY_CPU_SHIFT
,
\
#
PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
cmp
x0
,
x1
cset
w0
,
eq
ret
x9
endfunc
plat_is_my_cpu_primary
/
*
-----------------------------------------------------
*
unsigned
int
plat_arm_calc_core_pos
(
uint64_t
mpidr
)
*
Helper
function
to
calculate
the
core
position
.
*
-----------------------------------------------------
*/
func
plat_arm_calc_core_pos
mrs
x2
,
mpidr_el1
ands
x2
,
x2
,
#
MPIDR_MT_MASK
beq
1
f
lsr
x0
,
x0
,
#
MPIDR_AFF1_SHIFT
1
:
and
x1
,
x0
,
#
MPIDR_CPU_MASK
and
x0
,
x0
,
#
MPIDR_CLUSTER_MASK
add
x0
,
x1
,
x0
,
LSR
#
6
and
x0
,
x0
,
#
MPIDR_AFFLVL_MASK
ret
endfunc
plat_arm_calc_core_pos
plat/arm/css/sgi/include/plat_macros.S
0 → 100644
View file @
02f8c038
/*
*
Copyright
(
c
)
2018
,
ARM
Limited
and
Contributors
.
All
rights
reserved
.
*
*
SPDX
-
License
-
Identifier
:
BSD
-
3
-
Clause
*/
#ifndef __PLAT_MACROS_S__
#define __PLAT_MACROS_S__
#include <css_macros.S>
/*
---------------------------------------------
*
The
below
required
platform
porting
macro
*
prints
out
relevant
platform
registers
*
whenever
an
unhandled
exception
is
taken
in
*
BL31
.
*
*
There
are
currently
no
platform
specific
regs
*
to
print
.
*
---------------------------------------------
*/
.
macro
plat_crash_print_regs
.
endm
#endif /* __PLAT_MACROS_S__ */
plat/arm/css/sgi/include/platform_def.h
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __PLATFORM_DEF_H__
#define __PLATFORM_DEF_H__
#include <arm_def.h>
#include <board_arm_def.h>
#include <board_css_def.h>
#include <common_def.h>
#include <css_def.h>
#include <soc_css_def.h>
#define CSS_SGI_MAX_CORES_PER_CLUSTER 4
/* CPU topology */
#define PLAT_ARM_CLUSTER_COUNT 2
#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \
CSS_SGI_MAX_CORES_PER_CLUSTER)
#if ARM_BOARD_OPTIMISE_MEM
#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 6
# define MAX_XLAT_TABLES 4
#else
# define PLAT_ARM_MMAP_ENTRIES 10
# define MAX_XLAT_TABLES 5
#endif
#if TRUSTED_BOARD_BOOT
# define PLAT_ARM_MAX_BL1_RW_SIZE 0xA000
#else
# define PLAT_ARM_MAX_BL1_RW_SIZE 0x6000
#endif
#if TRUSTED_BOARD_BOOT
# define PLAT_ARM_MAX_BL2_SIZE 0x1D000
#else
# define PLAT_ARM_MAX_BL2_SIZE 0xC000
#endif
#endif
/* ARM_BOARD_OPTIMISE_MEM */
#define PLAT_ARM_NSTIMER_FRAME_ID 0
#define PLAT_CSS_MHU_BASE 0x45000000
#define PLAT_ARM_TRUSTED_ROM_BASE 0x0
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
/* 512KB */
#define PLAT_MAX_PWR_LVL 1
#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
CSS_IRQ_MHU
#define PLAT_ARM_G0_IRQS ARM_G0_IRQS
#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp)
#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
#define CSS_SGI_DEVICE_BASE (0x20000000)
#define CSS_SGI_DEVICE_SIZE (0x20000000)
#define CSS_SGI_MAP_DEVICE MAP_REGION_FLAT( \
CSS_SGI_DEVICE_BASE, \
CSS_SGI_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000
#define SGI_BOOT_CFG_ADDR 0x45410000
#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 6
/* GIC related constants */
#define PLAT_ARM_GICD_BASE 0x30000000
#define PLAT_ARM_GICC_BASE 0x2C000000
#define PLAT_ARM_GICR_BASE 0x300C0000
/* Platform ID address */
#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
#ifndef __ASSEMBLY__
/* SSC_VERSION related accessors */
/* Returns the part number of the platform */
#define GET_SGI_PART_NUM \
GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
/* Returns the configuration number of the platform */
#define GET_SGI_CONFIG_NUM \
GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
#endif
/* __ASSEMBLY__ */
#endif
/* __PLATFORM_DEF_H__ */
plat/arm/css/sgi/include/sgi_plat_config.h
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SGI_PLAT_CONFIG_H__
#define __SGI_PLAT_CONFIG_H__
#include <arm_gic.h>
#include <ccn.h>
#include <gicv3.h>
/* The type of interconnect */
typedef
enum
{
ARM_CCI
=
0
,
ARM_CCN
,
ARM_CMN
}
css_inteconn_type_t
;
typedef
ccn_desc_t
inteconn_desc_t
;
/* Interconnect configurations */
typedef
struct
css_inteconn_config
{
css_inteconn_type_t
ip_type
;
const
inteconn_desc_t
*
plat_inteconn_desc
;
}
css_inteconn_config_t
;
/* Topology configurations */
typedef
struct
css_topology
{
const
unsigned
char
*
power_tree
;
unsigned
int
plat_cluster_core_count
;
}
css_topology_t
;
typedef
struct
css_plat_config
{
const
gicv3_driver_data_t
*
gic_data
;
const
css_inteconn_config_t
*
inteconn
;
const
css_topology_t
*
topology
;
}
css_plat_config_t
;
void
plat_config_init
(
void
);
css_plat_config_t
*
get_plat_config
(
void
);
#endif
/* __SGI_PLAT_CONFIG_H__ */
plat/arm/css/sgi/include/sgi_variant.h
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SGI_VARIANT_H__
#define __SGI_VARIANT_H__
/* SSC_VERSION values for SGI575 */
#define SGI575_SSC_VER_PART_NUM 0x0783
#endif
/* __SGI_VARIANT_H__ */
plat/arm/css/sgi/sgi-common.mk
0 → 100644
View file @
02f8c038
#
# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ENABLE_PLAT_COMPAT
:=
0
CSS_ENT_BASE
:=
plat/arm/css/sgi
INTERCONNECT_SOURCES
:=
${CSS_ENT_BASE}
/sgi_interconnect.c
PLAT_INCLUDES
+=
-I
${CSS_ENT_BASE}
/include
ENT_CPU_SOURCES
:=
lib/cpus/aarch64/cortex_a75.S
ENT_GIC_SOURCES
:=
drivers/arm/gic/common/gic_common.c
\
drivers/arm/gic/v3/gicv3_main.c
\
drivers/arm/gic/v3/gicv3_helpers.c
\
plat/common/plat_gicv3.c
\
plat/arm/common/arm_gicv3.c
\
${CSS_ENT_BASE}
/sgi_gic_config.c
\
drivers/arm/gic/v3/gic600.c
PLAT_BL_COMMON_SOURCES
+=
${CSS_ENT_BASE}
/sgi_plat.c
\
${CSS_ENT_BASE}
/aarch64/sgi_helper.S
BL1_SOURCES
+=
${INTERCONNECT_SOURCES}
\
${ENT_CPU_SOURCES}
\
${CSS_ENT_BASE}
/sgi_bl1_setup.c
\
${CSS_ENT_BASE}
/sgi_plat_config.c
BL2_SOURCES
+=
${CSS_ENT_BASE}
/sgi_security.c
BL31_SOURCES
+=
${ENT_CPU_SOURCES}
\
${INTERCONNECT_SOURCES}
\
${ENT_GIC_SOURCES}
\
${CSS_ENT_BASE}
/sgi_bl31_setup.c
\
${CSS_ENT_BASE}
/sgi_topology.c
\
${CSS_ENT_BASE}
/sgi_plat_config.c
$(eval
$(call
add_define,SGI_PLAT))
override CSS_LOAD_SCP_IMAGES
:
= 0
override NEED_BL2U
:
= no
override ARM_BL31_IN_DRAM
:
= 1
# System coherency is managed in hardware
HW_ASSISTED_COHERENCY
:=
1
# When building for systems with hardware-assisted coherency, there's no need to
# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
USE_COHERENT_MEM
:=
0
include
plat/arm/common/arm_common.mk
include
plat/arm/css/common/css_common.mk
include
plat/arm/soc/common/soc_css.mk
include
plat/arm/board/common/board_common.mk
plat/arm/css/sgi/sgi_bl1_setup.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <debug.h>
#include <plat_arm.h>
#include <sgi_plat_config.h>
#include <soc_css.h>
void
bl1_early_platform_setup
(
void
)
{
/* Initialize the platform configuration structure */
plat_config_init
();
arm_bl1_early_platform_setup
();
}
plat/arm/css/sgi/sgi_bl31_setup.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <debug.h>
#include <plat_arm.h>
#include <sgi_plat_config.h>
void
bl31_early_platform_setup2
(
u_register_t
arg0
,
u_register_t
arg1
,
u_register_t
arg2
,
u_register_t
arg3
)
{
uint32_t
plat_version
;
bl_params_node_t
*
bl_params
;
bl_params
=
((
bl_params_t
*
)
arg0
)
->
head
;
/* Initialize the platform configuration structure */
plat_config_init
();
while
(
bl_params
)
{
if
(
bl_params
->
image_id
==
BL33_IMAGE_ID
)
{
plat_version
=
mmio_read_32
(
SSC_VERSION
);
bl_params
->
ep_info
->
args
.
arg2
=
plat_version
;
break
;
}
bl_params
=
bl_params
->
next_params_info
;
}
arm_bl31_early_platform_setup
((
void
*
)
arg0
,
arg1
,
arg2
,
(
void
*
)
arg3
);
}
plat/arm/css/sgi/sgi_gic_config.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <sgi_plat_config.h>
void
plat_arm_gic_driver_init
(
void
)
{
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in S-EL1. This is because the S-EL1
* can use GIC system registers to manage interrupts and does
* not need GIC interface base addresses to be configured.
*/
gicv3_driver_init
(
get_plat_config
()
->
gic_data
);
}
plat/arm/css/sgi/sgi_interconnect.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <debug.h>
#include <sgi_plat_config.h>
/*
* For SGI575 which support FCM (with automatic interconnect enter/exit),
* we should not do anything in these interface functions.
* They are used to override the weak functions in cci drivers.
*/
/******************************************************************************
* Helper function to initialize ARM interconnect driver.
*****************************************************************************/
void
plat_arm_interconnect_init
(
void
)
{
}
/******************************************************************************
* Helper function to place current master into coherency
*****************************************************************************/
void
plat_arm_interconnect_enter_coherency
(
void
)
{
}
/******************************************************************************
* Helper function to remove current master from coherency
*****************************************************************************/
void
plat_arm_interconnect_exit_coherency
(
void
)
{
}
plat/arm/css/sgi/sgi_plat.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_def.h>
#include <bl_common.h>
#include <ccn.h>
#include <debug.h>
#include <plat_arm.h>
#include <platform.h>
#include "../../../../bl1/bl1_private.h"
#if USE_COHERENT_MEM
/*
* The next 2 constants identify the extents of the coherent memory region.
* These addresses are used by the MMU setup code and therefore they must be
* page-aligned. It is the responsibility of the linker script to ensure that
* __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols
* refer to page-aligned addresses.
*/
#define BL1_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL1_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
#define BL31_COHERENT_RAM_BASE (uintptr_t)(&__COHERENT_RAM_START__)
#define BL31_COHERENT_RAM_LIMIT (uintptr_t)(&__COHERENT_RAM_END__)
#endif
#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
V2M_FLASH0_SIZE, \
MT_DEVICE | MT_RO | MT_SECURE)
/*
* Table of regions for different BL stages to map using the MMU.
* This doesn't include Trusted RAM as the 'mem_layout' argument passed to
* arm_configure_mmu_elx() will give the available subset of that.
*
* Replace or extend the below regions as required
*/
#if IMAGE_BL1
const
mmap_region_t
plat_arm_mmap
[]
=
{
ARM_MAP_SHARED_RAM
,
SGI_MAP_FLASH0_RO
,
CSS_SGI_MAP_DEVICE
,
SOC_CSS_MAP_DEVICE
,
{
0
}
};
#endif
#if IMAGE_BL2
const
mmap_region_t
plat_arm_mmap
[]
=
{
ARM_MAP_SHARED_RAM
,
SGI_MAP_FLASH0_RO
,
CSS_SGI_MAP_DEVICE
,
SOC_CSS_MAP_DEVICE
,
ARM_MAP_NS_DRAM1
,
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM
,
#endif
{
0
}
};
#endif
#if IMAGE_BL31
const
mmap_region_t
plat_arm_mmap
[]
=
{
ARM_MAP_SHARED_RAM
,
V2M_MAP_IOFPGA
,
CSS_SGI_MAP_DEVICE
,
SOC_CSS_MAP_DEVICE
,
{
0
}
};
#endif
ARM_CASSERT_MMAP
/*
* Set up the page tables for the generic and platform-specific memory regions.
* The extents of the generic memory regions are specified by the function
* arguments and consist of:
* - Trusted SRAM seen by the BL image;
* - Code section;
* - Read-only data section;
* - Coherent memory region, if applicable.
*/
#if IMAGE_BL1
void
bl1_plat_arch_setup
(
void
)
{
arm_setup_page_tables
(
ARM_BL_RAM_BASE
,
ARM_BL_RAM_SIZE
,
BL_CODE_BASE
,
BL1_CODE_END
,
BL1_RO_DATA_BASE
,
BL1_RO_DATA_END
#if USE_COHERENT_MEM
,
BL1_COHERENT_RAM_BASE
,
BL1_COHERENT_RAM_LIMIT
#endif
/* USE_COHERENT_MEM */
);
enable_mmu_el3
(
0
);
}
#endif
/* IMAGE_BL1 */
#if IMAGE_BL2
void
bl2_plat_arch_setup
(
void
)
{
arm_setup_page_tables
(
BL2_BASE
,
BL2_LIMIT
-
BL2_BASE
,
BL_CODE_BASE
,
BL_CODE_END
,
BL_RO_DATA_BASE
,
BL_RO_DATA_END
#if USE_COHERENT_MEM
,
BL2_COHERENT_RAM_BASE
,
BL2_COHERENT_RAM_LIMIT
#endif
/* USE_COHERENT_MEM */
);
enable_mmu_el1
(
0
);
}
#endif
/* IMAGE_BL2 */
plat/arm/css/sgi/sgi_plat_config.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <debug.h>
#include <plat_arm.h>
#include <platform_def.h>
#include <sgi_variant.h>
#include <sgi_plat_config.h>
#include <string.h>
static
css_plat_config_t
*
css_plat_info
;
/* GIC */
/* The GICv3 driver only needs to be initialized in EL3 */
uintptr_t
rdistif_base_addrs
[
PLATFORM_CORE_COUNT
];
const
interrupt_prop_t
sgi575_interrupt_props
[]
=
{
CSS_G1S_IRQ_PROPS
(
INTR_GROUP1S
),
ARM_G0_IRQ_PROPS
(
INTR_GROUP0
),
};
/* Special definition for SGI575 */
/* GIC configuration for SGI575 */
const
gicv3_driver_data_t
sgi575_gic_data
=
{
.
gicd_base
=
PLAT_ARM_GICD_BASE
,
.
gicr_base
=
PLAT_ARM_GICR_BASE
,
.
interrupt_props
=
sgi575_interrupt_props
,
.
interrupt_props_num
=
ARRAY_SIZE
(
sgi575_interrupt_props
),
.
rdistif_num
=
PLATFORM_CORE_COUNT
,
.
rdistif_base_addrs
=
rdistif_base_addrs
,
.
mpidr_to_core_pos
=
plat_arm_calc_core_pos
};
/* Interconnect configuration for SGI575 */
const
css_inteconn_config_t
sgi575_inteconn
=
{
.
ip_type
=
ARM_CMN
,
.
plat_inteconn_desc
=
NULL
};
/* Configuration structure for SGI575 */
css_plat_config_t
sgi575_config
=
{
.
gic_data
=
&
sgi575_gic_data
,
.
inteconn
=
&
sgi575_inteconn
,
};
/*******************************************************************************
* This function initializes the platform sturcture.
******************************************************************************/
void
plat_config_init
(
void
)
{
/* Get the platform configurations */
switch
(
GET_SGI_PART_NUM
)
{
case
SGI575_SSC_VER_PART_NUM
:
css_plat_info
=
&
sgi575_config
;
break
;
default:
ERROR
(
"Not a valid sgi variant!
\n
"
);
panic
();
}
}
/*******************************************************************************
* This function returns the platform structure pointer.
******************************************************************************/
css_plat_config_t
*
get_plat_config
(
void
)
{
assert
(
css_plat_info
!=
NULL
);
return
css_plat_info
;
}
plat/arm/css/sgi/sgi_security.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arm_config.h>
#include <plat_arm.h>
/*
* We assume that all security programming is done by the primary core.
*/
void
plat_arm_security_setup
(
void
)
{
}
plat/arm/css/sgi/sgi_topology.c
0 → 100644
View file @
02f8c038
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <plat_arm.h>
#include <sgi_plat_config.h>
/* Topology */
/*
* The power domain tree descriptor. The cluster power domains are
* arranged so that when the PSCI generic code creates the power domain tree,
* the indices of the CPU power domain nodes it allocates match the linear
* indices returned by plat_core_pos_by_mpidr().
*/
const
unsigned
char
sgi_pd_tree_desc
[]
=
{
PLAT_ARM_CLUSTER_COUNT
,
CSS_SGI_MAX_CORES_PER_CLUSTER
,
CSS_SGI_MAX_CORES_PER_CLUSTER
};
/* Topology configuration for sgi platform */
const
css_topology_t
sgi_topology
=
{
.
power_tree
=
sgi_pd_tree_desc
,
.
plat_cluster_core_count
=
CSS_SGI_MAX_CORES_PER_CLUSTER
};
/*******************************************************************************
* This function returns the topology tree information.
******************************************************************************/
const
unsigned
char
*
plat_get_power_domain_tree_desc
(
void
)
{
return
sgi_topology
.
power_tree
;
}
/*******************************************************************************
* This function returns the core count within the cluster corresponding to
* `mpidr`.
******************************************************************************/
unsigned
int
plat_arm_get_cluster_core_count
(
u_register_t
mpidr
)
{
return
sgi_topology
.
plat_cluster_core_count
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment