Profiles and CMake build process

Overview

AMC uses CMake for its build procedure, automating each stage of the compilation processes.

AMC source code has been designed to be agnostic from target platform (hardware) and operating system. The CMake build process allows target platform and target OS to be configured at compilation.

Build

See the AMC source ReadMe for full description of AMC build procedure.

The build procedure can be broken into two key stages depending on the target OS and platform specified:

  • Generation of BSP (Board support package)

  • Source code compilation

The following diagram outlines the build stage called by build.sh, depending on the parameters specified by the user.

image1

Full FreeRTOS build

To build AMC for FreeRTOS, targeting AMD Alveo™ vXX profiles (e.g. v80), the appropriate board support package (BSP) is required. The `scripts/build.sh` script will auto-generate the appropriate BSP with the AMD Vitis™, when an appropriate xsa file is specified.

Partial FreeRTOS build

When the `-amc` flag is used, the `scripts/build.sh` will not re-generate the BSP, instead, it will simply call cmake to compile the source, where it is expected the BSP has been previously generated. Useful for rebuilding an AMC-only change.

Linux

To build AMC for Linux, no BSP files are required, and the `scripts/build.sh` script will simply use cmake to compile the source for Linux OS using the appropriate Linux source files.

Profiles

The profiles layer holds all profile-specific (board-specific) includes and definitions, allowing AMC to be ported to different target platform (hardware) without requiring code changes in the AMC or its layers.

The profile directories currently supported on AMC can be seen the src/profiles/.


Cmake will include the appropriate set of header files, depending on the profile specified by the user (Linux, v80, etc.). This allows platform (hardware) specific data to be changed and AMC source code to remain the same.

Porting AMC to new platforms in the future should only require additional profile directories to be created, with no source code changes required. See the following code snippet for detail.

CMakeLists.txt

#set custom profile with -DPROFILE flag (v80, Linux, etc), Defaults to v80 if not specified
if(NOT PROFILE)
    include_directories(src/profiles/v80)
    set(PROFILE "v80")
    set(PROFILE_FAL_PATH "src/profiles/v80/profile_fal.c")
    set(PROFILE_DEBUG_MENU_PATH "src/profiles/v80/profile_debug_menu.c")
    add_definitions(-DOOB_ENABLED)
else()
    if(PROFILE MATCHES "^(v80*)$")
        include_directories(src/profiles/v80)
        set(PROFILE "v80")
        set(PROFILE_FAL_PATH "src/profiles/v80/profile_fal.c")
        set(PROFILE_DEBUG_MENU_PATH "src/profiles/v80/profile_debug_menu.c")
        add_definitions(-DOOB_ENABLED)
    elseif(PROFILE MATCHES "^(Linux)$")
        include_directories(src/profiles/Linux)
        set(PROFILE "Linux")
        set(PROFILE_FAL_PATH "src/profiles/Linux/profile_fal.c")
        set(PROFILE_DEBUG_MENU_PATH "src/profiles/Linux/profile_debug_menu.c")
    else()
        include_directories(src/profiles/v80)
        set(PROFILE "v80")
        set(PROFILE_FAL_PATH "src/profiles/v80/profile_fal.c")
        set(PROFILE_DEBUG_MENU_PATH "src/profiles/v80/profile_debug_menu.c")
        add_definitions(-DOOB_ENABLED)
    endif()
endif()

Each profile directory includes the following header files.

profiles/
├── Linux
│   ├── profile_bim.h
│   ├── profile_fal.c
│   ├── profile_fal.h
│   ├── profile_hal_memory_base.c
│   ├── profile_hal.h
│   ├── profile_muxed_device.h
│   ├── profile_pdr.h
│   ├── profile_print.h
│   └── profile_sensors.h
└── v80
    ├── profile_bim.h
    ├── profile_fal.c
    ├── profile_fal.h
    ├── profile_hal.h
    ├── profile_muxed_device.h
    ├── profile_pdr.h
    ├── profile_print.h
    └── profile_sensors.h
└── etc...

BIM Profile

The profile_bim.h header file provides event tables for the Built in Monitoring (BIM) Application.

Firmware Interface Abstraction Layer (FAL) Profile

The profile_fal.c file provides specific initialization for the FAL.

The profile_fal.h header file provides profile (hardware) specific definitions for the FAL.

Header Abstraction Layer (HAL) Profile

The profile_hal.h header file provides all other profile (hardware) specific definitions.

Printing Profile

The profile_print.h header file provides profile (hardware) specific definitions for printing.

Muxed Device Profile

The profile_muxed_device.h header file provides profile (hardware) specific definitions for QSFP and DIMM devices.

PDR Profile

The profile_pdr.h header file provides profile (hardware) specific definitions for Out Of Band PDR and sensor reporting.

Sensors Profile

The profile_sensors.h header file provides profile (hardware) specific definitions for all sensors.

This profile is where sensor thresholds and limits are set - if a sensor value exceeds the “critical” value, the AMI (on the host interface) will kill any host processes that are using the in-band interface (see Sensors and Hardware Monitoring). To add/change thresholds, simply change the value in the relevant sensor_profile. To disable a threshold, set it to ASC_SENSOR_INVALID_VAL (-1).

Device Drivers

The device drivers layer of AMC has similarly been designed to be abstracted from the target platform. Each device driver has been written with a common header file but separate source files for AVED and Linux, providing a common API over the BSP-provided drivers and utilities.

Cmake will include the appropriate source code paths, depending on the profile specified by the user (Linux, v80, etc.), for each of the device drivers. This allows AMC to be easily compiled for Linux or FreeRTOS OS.

See the following example of I2c and OSPI device drivers. The common header outlines the API used throughout AMC. OS specific source implementations prevent any further code changes throughout AMC when porting to a new OS/Platform.

All future device drivers added to AMC should follow this design pattern.

i2c
│   ├── aved
│   │   └── i2c.c
│   └── linux
│   │   └── i2c.c
│   ├── i2c.h
├── ospi
│   ├── aved
│   │   └── ospi.c
│   ├── linux
│   │   └── ospi.c
│   └── ospi.h

FAL (Firmware Abstraction Layer)

Similarly, the Firmware abstraction layer of AMC has been designed to be abstracted from the target platform. Each FAL implementation has been written with a common header file, providing a common API over the abstracted firmware, but with separate source files for Linux (stub) and AMC (AVED).

Just as with the device drivers, cmake will include the appropriate source code paths, depending on the profile specified by the user (Linux, v80, etc.).

See the following example of gcq, ospi and qsfp FALs. All future FAL implementations added to AMC should follow this design pattern.

├── gcq
│ ├── fw_if_gcq_amc.c
│ ├── fw_if_gcq.h
│ ├── fw_if_gcq_linux.c
│ └── fw_if_gcq_stub.c
├── ospi
│ ├── fw_if_ospi_amc.c
│ ├── fw_if_ospi.h
│ └── fw_if_ospi_stub.c
├── qsfp
│ ├── fw_if_qsfp_amc.c
│ ├── fw_if_qsfp.h
│ └── fw_if_qsfp_stub.c

See the following example code snippet for details.

Note: cmake can specify paths for appropriate device driver, and FAL (firmware abstraction layer) implementations depending on the OS specified.

CMakeLists.txt

if(OS MATCHES "^(Linux)$")
    set(CMAKE_C_COMPILER gcc)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
    set(CMAKE_BUILD_TYPE Debug)
    set(THREADS_PREFER_PTHREAD_FLAG ON)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -Wno-missing-braces")

    find_package(Threads REQUIRED)
    set(OSAL_PATH "src/osal/osal_Linux.c")
    set(FW_IF_PATH "src/fal/gcq/fw_if_gcq_linux.c")
    set(FW_I2C_PATH "src/device_drivers/i2c/linux/i2c.c")
    set(FW_SYS_MON_PATH "src/device_drivers/sensors/sys_mon/linux/sys_mon.c")
    set(FW_OSPI_PATH "src/device_drivers/ospi/linux/ospi.c")
    set(FW_IF_OSPI_PATH "src/fal/ospi/fw_if_ospi_stub.c")
    set(FW_IF_QSFP_PATH "src/fal/qsfp/fw_if_qsfp_stub.c")
    set(LINUX_HAL_MEM_BASE "src/profiles/Linux/profile_hal_memory_base.c")
    set(NAME "amc")
endif()

if(OS MATCHES "^(FreeRTOS)$")
    set(CMAKE_C_COMPILER armr5-none-eabi-gcc)
    set(CMAKE_SYSTEM_NAME Generic)
    set(CMAKE_SYSTEM_PROCESSOR arm)
    set(CMAKE_CROSSCOMPILING 1)
    set(CMAKE_C_COMPILER_WORKS TRUE)
    set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-r5 -mfloat-abi=hard -mfpu=vfpv3-d16 -Werror -Wall")
    set(OSAL_PATH "src/osal/osal_FreeRTOS.c")
    set(FW_IF_PATH "src/fal/gcq/fw_if_gcq_amc.c")
    set(FW_I2C_PATH "src/device_drivers/i2c/aved/i2c.c")
    set(FW_SYS_MON_PATH "src/device_drivers/sensors/sys_mon/aved/sys_mon.c")
    set(FW_OSPI_PATH "src/device_drivers/ospi/aved/ospi.c")
    set(FW_IF_OSPI_PATH "src/fal/ospi/fw_if_ospi_amc.c")
    set(FW_IF_QSFP_PATH "src/fal/qsfp/fw_if_qsfp_amc.c")
    set(NAME "amc.elf")

    if( FREERTOS_DEBUG )
        add_definitions(-DFREERTOS_DEBUG)
    endif()

endif()

Page Revision: v. 29