Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ARM Neoverse N1 platform #381

Merged
merged 11 commits into from
Jun 5, 2023
48 changes: 44 additions & 4 deletions src/docs/sphinx/ARM.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@
ARM Overview
##############

This implementation of the ARM port of Variorum supports the Arm Juno r2 SoC.
Variorum supports two flavors of ARM architectures: - Arm Juno r2 SoC - Ampere
Neoverse N1

The Arm Juno r2 platform is a big.LITTLE cluster with Cortex-A72 (big) and
Cortex-A53 (LITTLE) clusters (also called processors), respectively. It also has
an Arm Mali GP-GPU. We have tested the ARM functionality of Variorum on Linaro
supported Linux.

The Ampere Neoverse N1 platform is an 80-core single-processor platform with two
Nvidia Ampere GPUs.

**************
Requirements
**************
Expand All @@ -23,6 +28,17 @@ Monitoring (hwmon) subsystem for access to the telemetry and control interfaces
on the tested ARM platform. The standardized data interfaces provided by the
hwmon framework enable a generic ARM implementation of Variorum.

**********************
Model Identification
**********************

Variorum use the `MIDR_EL1` (Main ID) register which provides the identification
information of the ARM processor to initialize the low-level interfaces on the
target architecture. Specifically, Variorum uses bits `[15:4]` of `MIDR_E1` to
get the primary part number. For Neoverse N1 the primary part number is `0xD0C`
whereas for Arm Juno r2 big.LITTLE SoC the primary part numbers are `0xD08`
(Cortex-A72) and `0xD03` (Cortex-A53).

************************************************
Monitoring and Control Through Sysfs Interface
************************************************
Expand Down Expand Up @@ -65,17 +81,28 @@ Interface (SCPI).

Instantaneous temperatures are reported in degree Celsius.

On the Neoverse N1 system, the following thermal sensors are provided:

- Ethernet connector temperature: ``/sys/class/hwmon/hwmon0/temp1_input``
- SoC temperature: ``/sys/class/hwmon/hwmon1/temp1_input``

Clocks telemetry
================

Clocks are collected by the sysfs interface using the GetClockValue command in
SCPI. A separate ``policy*/`` subdirectory is provided for the big and LITTLE
cluster.
SCPI on both of the supported ARM platforms. On the Arm Juno r2 platform, a
separate ``policy*/`` subdirectory is provided for the big and LITTLE clusters.

- big clocks: ``/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq``
- LITTLE clocks:
``/sys/devices/system/cpu/cpufreq/policy1/scaling_cur_freq``

On the Neoverse N1 platform, a separate ``policy*/`` subdirectory is provided
for each core in the SoC.

- Core clocks:
``/sys/devices/system/cpu/cpufreq/policy[0-79]/scaling_cur_freq``

Frequencies are reported by the sysfs interface in KHz. Variorum reports the
clocks in MHz to keep it consistent with the clocks reported for other supported
architectures.
Expand All @@ -84,12 +111,19 @@ Frequency control
=================

The sysfs interface uses the SetClockValue SCPI command to set processor
frequency for the following user-facing interfaces:
frequency for the following user-facing interfaces on the supported platforms:

Arm Juno r2:

- big clocks: ``/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed``
- LITTLE clocks:
``/sys/devices/system/cpu/cpufreq/policy1/scaling_setspeed``

Neoverse N1:

- core clocks:
``/sys/devices/system/cpu/cpufreq/policy[0-79]/scaling_setspeed``

New frequency is specified in KHz to these interfaces. Variorum takes the new
frequency as input in MHz and performs this conversion internally.

Expand All @@ -105,6 +139,12 @@ applied when the governor in ``policy*/scaling_governor`` is set to `userspace`.

- `Arm Juno r2 technical reference
<https://developer.arm.com/documentation/100114/0200/>`_
- `Neoverse N1 technical reference
<https://developer.arm.com/documentation/100616/latest>`_
- `Cortex-A53 technical reference
<https://developer.arm.com/documentation/ddi0500/latest>`_
- `Cortex-A72 technical reference
<https://developer.arm.com/documentation/100095/latest>`_
- `hwmon sysfs interface
<https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface>`_
- `hwmon documentation
Expand Down
25 changes: 0 additions & 25 deletions src/variorum/ARM/ARM.h

This file was deleted.

32 changes: 16 additions & 16 deletions src/variorum/ARM/ARM.c → src/variorum/ARM/ARM_Juno_r2.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
#include <sys/types.h>
#include <sys/stat.h>

#include <ARM.h>
#include <ARM_Juno_r2.h>
#include <config_architecture.h>
#include <variorum_error.h>
#include <power_features.h>
#include <power_features_Juno_r2.h>

int arm_get_power(int long_ver)
int arm_juno_r2_get_power(int long_ver)
{
int ret = 0;

Expand All @@ -25,12 +25,12 @@ int arm_get_power(int long_ver)
printf("Running %s\n", __FUNCTION__);
}

ret = get_power_data(long_ver, stdout);
ret = arm_cpu_juno_r2_get_power_data(long_ver, stdout);

return ret;
}

int arm_get_thermals(int long_ver)
int arm_juno_r2_get_thermals(int long_ver)
{
int ret = 0;

Expand All @@ -40,12 +40,12 @@ int arm_get_thermals(int long_ver)
printf("Running %s\n", __FUNCTION__);
}

ret = get_thermal_data(long_ver, stdout);
ret = arm_cpu_juno_r2_get_thermal_data(long_ver, stdout);

return ret;
}

int arm_get_clocks(int long_ver)
int arm_juno_r2_get_clocks(int long_ver)
{
int ret = 0;
unsigned iter = 0;
Expand All @@ -60,13 +60,13 @@ int arm_get_clocks(int long_ver)
variorum_get_topology(&nsockets, NULL, NULL, P_ARM_CPU_IDX);
for (iter = 0; iter < nsockets; iter++)
{
ret = get_clocks_data(iter, long_ver, stdout);
ret = arm_cpu_juno_r2_get_clocks_data(iter, long_ver, stdout);
}

return ret;
}

int arm_get_frequencies(void)
int arm_juno_r2_get_frequencies(void)
{
int ret = 0;
unsigned iter = 0;
Expand All @@ -81,13 +81,13 @@ int arm_get_frequencies(void)
variorum_get_topology(&nsockets, NULL, NULL, P_ARM_CPU_IDX);
for (iter = 0; iter < nsockets; iter++)
{
ret = get_frequencies(iter, stdout);
ret = arm_cpu_juno_r2_get_frequencies(iter, stdout);
}

return ret;
}

int arm_cap_socket_frequency(int cpuid, int freq)
int arm_juno_r2_cap_socket_frequency(int cpuid, int freq)
{
int ret = 0;
unsigned nsockets;
Expand All @@ -104,12 +104,12 @@ int arm_cap_socket_frequency(int cpuid, int freq)
fprintf(stdout, "The specified CPU ID does not exist\n");
return -1;
}
ret = cap_socket_frequency(cpuid, freq);
ret = arm_cpu_juno_r2_cap_socket_frequency(cpuid, freq);

return ret;
}

int arm_get_power_json(char **get_power_obj_str)
int arm_juno_r2_get_power_json(char **get_power_obj_str)
{
int ret = 0;

Expand All @@ -121,15 +121,15 @@ int arm_get_power_json(char **get_power_obj_str)

json_t *get_power_obj = json_object();

ret = json_get_power_data(get_power_obj);
ret = arm_cpu_juno_r2_json_get_power_data(get_power_obj);

*get_power_obj_str = json_dumps(get_power_obj, 0);
json_decref(get_power_obj);

return ret;
}

int arm_get_power_domain_info_json(char **get_domain_obj_str)
int arm_juno_r2_get_power_domain_info_json(char **get_domain_obj_str)
{
int ret = 0;

Expand All @@ -141,7 +141,7 @@ int arm_get_power_domain_info_json(char **get_domain_obj_str)

json_t *get_domain_obj = json_object();

ret = json_get_power_domain_info(get_domain_obj);
ret = arm_cpu_juno_r2_json_get_power_domain_info(get_domain_obj);

*get_domain_obj_str = json_dumps(get_domain_obj, 0);
json_decref(get_domain_obj);
Expand Down
25 changes: 25 additions & 0 deletions src/variorum/ARM/ARM_Juno_r2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2019-2022 Lawrence Livermore National Security, LLC and other
// Variorum Project Developers. See the top-level LICENSE file for details.
//
// SPDX-License-Identifier: MIT

#ifndef ARM_JUNO_R2_H_INCLUDE
#define ARM_JUNO_R2_H_INCLUDE

#include <jansson.h>

int arm_juno_r2_get_power(int long_ver);

int arm_juno_r2_get_thermals(int long_ver);

int arm_juno_r2_get_clocks(int long_ver);

int arm_juno_r2_get_frequencies(void);

int arm_juno_r2_cap_socket_frequency(int cpuid, int freq);

int arm_juno_r2_get_power_json(char **get_power_obj_str);

int arm_juno_r2_get_power_domain_info_json(char **get_domain_obj_str);

#endif
Loading