Skip to content

Commit

Permalink
[hal] WIP: Integrate picolibc and UART HAL testing
Browse files Browse the repository at this point in the history
  • Loading branch information
viv-eth committed Dec 23, 2024
1 parent 0489216 commit 48617f4
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 22 deletions.
64 changes: 64 additions & 0 deletions cmake/picolibc.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2024 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Viviane Potocnik <[email protected]>

include(ExternalProject)

message(STATUS "[CHIMERA-SDK] Setting up picolibc for target ${TARGET}")

foreach(var CROSS_C_COMPILER CROSS_C_COMPILER_ARGS CROSS_AR CROSS_STRIP CROSS_CPU CROSS_CPU_FAMILY CROSS_ENDIAN CROSS_SYSTEM CROSS_C_ARGS CROSS_C_LINK_ARGS)
if(NOT DEFINED ${var})
message(FATAL_ERROR "[CHIMERA-SDK] Variable ${var} is not set. It must be defined before including picolibc.cmake.")
endif()
endforeach()

# Prepare Meson arrays
function(prepare_meson_array output_var input_string)
string(REPLACE " " ";" temp_list "${input_string}")
set(formatted_list "")
foreach(item IN LISTS temp_list)
list(APPEND formatted_list "'${item}'")
endforeach()
string(JOIN ", " result ${formatted_list})
set(${output_var} "${result}" PARENT_SCOPE)
endfunction()

prepare_meson_array(CROSS_C_COMPILER_ARGS_LIST "${CROSS_C_COMPILER_ARGS}")
prepare_meson_array(CROSS_C_ARGS_LIST "${CROSS_C_ARGS}")
prepare_meson_array(CROSS_C_LINK_ARGS_LIST "${CROSS_C_LINK_ARGS}")

set(PICOLIBC_SRC_DIR ${CMAKE_BINARY_DIR}/picolibc-src)
set(PICOLIBC_BUILD_DIR ${CMAKE_BINARY_DIR}/picolibc-build-${TARGET})
set(PICOLIBC_INSTALL_DIR ${CMAKE_BINARY_DIR}/picolibc-install-${TARGET})
set(PICOLIBC_CROSS_FILE ${CMAKE_BINARY_DIR}/picolibc-cross-file-${TARGET}.txt)


# Generate the Meson cross-file
configure_file(${CMAKE_CURRENT_LIST_DIR}/../scripts/picolibc-cross-file.txt.in ${PICOLIBC_CROSS_FILE} @ONLY)

message(STATUS "[CHIMERA-SDK] Saving cross compilation file to ${PICOLIBC_CROSS_FILE}")
# Add picolibc as an external project
ExternalProject_Add(
picolibc-${TARGET}
GIT_REPOSITORY https://github.com/picolibc/picolibc.git
GIT_TAG main
SOURCE_DIR ${PICOLIBC_SRC_DIR}
BINARY_DIR ${PICOLIBC_BUILD_DIR}
INSTALL_DIR ${PICOLIBC_INSTALL_DIR}
CONFIGURE_COMMAND meson setup ${PICOLIBC_BUILD_DIR} ${PICOLIBC_SRC_DIR} --cross-file ${PICOLIBC_CROSS_FILE} --prefix ${PICOLIBC_INSTALL_DIR} --default-library=static
BUILD_COMMAND ninja -C ${PICOLIBC_BUILD_DIR}
INSTALL_COMMAND ninja -C ${PICOLIBC_BUILD_DIR} install
)

set(PICOLIBC_INSTALL_DIR ${PICOLIBC_INSTALL_DIR} PARENT_SCOPE)
set(PICOLIBC_TARGET picolibc-${TARGET} PARENT_SCOPE)

add_library(picolibc STATIC IMPORTED GLOBAL)

set_target_properties(picolibc PROPERTIES
IMPORTED_LOCATION "${PICOLIBC_INSTALL_DIR}/lib/libc.a"
)

add_dependencies(picolibc picolibc-${TARGET})
40 changes: 37 additions & 3 deletions drivers/uart_opentitan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ set(OPENTITAN_SPARSE_PATTERNS
"sw/device/lib/base/math_builtins.c"
"sw/device/lib/base/memory.c"
"sw/device/lib/base/memory.h"
"sw/device/lib/base/mmio.c"
"sw/device/lib/base/mmio.h"
"sw/device/lib/base/multibits.c"
"sw/device/lib/base/multibits.h"
"sw/device/lib/base/internal/status.h"
"sw/device/lib/base/internal/absl_status.h"
"sw/device/lib/dif/dif_base.c"
"sw/device/lib/dif/dif_base.h"
"sw/device/lib/dif/dif_uart.c"
"sw/device/lib/dif/dif_uart.h"
"sw/device/lib/dif/autogen/dif_uart_autogen.c"
"sw/device/lib/dif/autogen/dif_uart_autogen.h"
)

# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -55,13 +67,35 @@ add_custom_command(
COMMENT "Generating ${UART_REGS_H} with COMMAND ${Python3_EXECUTABLE} ${REGTOOL_PY} ${UART_HJSON} -D > ${UART_REGS_H}"
)

message(STATUS "[REMOVE ME] COMMAND: ${Python3_EXECUTABLE} ${REGTOOL_PY} ${UART_HJSON} -D > ${UART_REGS_H}")

# Generate the uart_regs.h header using the OT regtool
add_custom_target(
generate_uart_regs
ALL
DEPENDS "${UART_REGS_H}"
)

add_dependencies(generate_uart_regs opentitan_interface_${OPENTITAN_COMMIT_HASH})
add_dependencies(generate_uart_regs opentitan_interface_${OPENTITAN_COMMIT_HASH})

# ------------------------------------------------------------------------------
# Add the UART driver library
# ------------------------------------------------------------------------------
add_library(uart_lib STATIC)

file(GLOB_RECURSE UART_SOURCES
"${OPENTITAN_SW_DIR}/device/lib/base/*.c"
"${OPENTITAN_SW_DIR}/device/lib/dif/*.c"
)

target_sources(
uart_lib
PRIVATE
${UART_SOURCES}
${UART_REGS_H}
)

target_include_directories(
uart_lib
PUBLIC
${OPENTITAN_DIR}
${OPENTITAN_SW_DIR}/device/lib/dif/autogen
)
6 changes: 6 additions & 0 deletions hal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ target_include_directories(hal_host
PUBLIC
"inc/"
)

target_link_libraries(hal_host
PUBLIC
uart_lib
picolibc
)
39 changes: 20 additions & 19 deletions hal/inc/device_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,32 @@

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>

/**
* \addtogroup device
* @{
*/

/**
* @brief Device structure.
*
*/
typedef struct chi_device {
/**
* @brief Device API.
*/
struct chi_device_api *api; // function pointers
/**
* @brief Device address.
*/
uint32_t *device_addr;
/**
* @brief Device configuration.
*/
void *cfg;
} chi_device_t;

/**
* @brief Callback function for asynchronous device operations.
*
Expand Down Expand Up @@ -59,23 +79,4 @@ typedef struct chi_device_api {
chi_device_callback cb);
} chi_device_api_t;

/**
* @brief Device structure.
*
*/
typedef struct chi_device {
/**
* @brief Device API.
*/
struct chi_device_api *api; // function pointers
/**
* @brief Device address.
*/
uint32_t *device_addr;
/**
* @brief Device configuration.
*/
void *cfg;
} chi_device_t;

/** @} */
67 changes: 67 additions & 0 deletions hal/inc/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2024 ETH Zurich and University of Bologna.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Viviane Potcnik <[email protected]>

#ifndef UART_H
#define UART_H

#include <stdint.h>
#include "device_api.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "uart_regs.h"
#include <stddef.h>
#include <stdlib.h>

// Parity options
#define UART_PARITY_NONE 0
#define UART_PARITY_EVEN 1
#define UART_PARITY_ODD 2

// Default UART configurations (can be overridden via compiler defines)
#ifndef UART_DEFAULT_BAUD_RATE
#define UART_DEFAULT_BAUD_RATE 115200
#endif

#ifndef UART_DEFAULT_DATA_BITS
#define UART_DEFAULT_DATA_BITS 8
#endif

#ifndef UART_DEFAULT_PARITY
#define UART_DEFAULT_PARITY UART_PARITY_NONE
#endif

#ifndef UART_DEFAULT_STOP_BITS
#define UART_DEFAULT_STOP_BITS 1
#endif

#ifndef UART_CLK_FREQ_HZ
#define UART_CLK_FREQ_HZ 100000000
#endif

#ifndef UART_BASE_ADDR
#define UART_BASE_ADDR 0x40000000
#endif

// UART configuration structure
typedef struct {
uint32_t baud_rate;
uint32_t clk_freq_hz;
uint8_t data_bits;
uint8_t parity;
uint8_t stop_bits;
} uart_config_t;

// Function declarations
int uart_open(struct chi_device *device);
int uart_close(struct chi_device *device);
ssize_t uart_read_async(struct chi_device *device, void *buffer, uint32_t size, chi_device_callback cb);
ssize_t uart_write_async(struct chi_device *device, const void *buffer, uint32_t size, chi_device_callback cb);

// Extern the UART API structure
extern struct chi_device_api uart_api;
extern uart_config_t default_cfg;

#endif // UART_H
91 changes: 91 additions & 0 deletions hal/src/uart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright 2024 ETH Zurich and University of Bologna.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Viviane Potcnik <[email protected]>

#include "uart.h"

// Define the UART API structure
struct chi_device_api uart_api = {
.open = uart_open,
.close = uart_close,
.read_async = uart_read_async,
.write_async = uart_write_async
};

// UART context structure
typedef struct uart_context {
dif_uart_t uart; // UART DIF handle
// Asynchronous read state
uint8_t *rx_buffer;
uint32_t rx_size;
uint32_t rx_pos;
chi_device_callback rx_callback;
// Asynchronous write state
const uint8_t *tx_buffer;
uint32_t tx_size;
uint32_t tx_pos;
chi_device_callback tx_callback;
} uart_context_t;

// Default UART configuration
uart_config_t default_cfg = {
.baud_rate = UART_DEFAULT_BAUD_RATE,
.clk_freq_hz = UART_CLK_FREQ_HZ,
.data_bits = UART_DEFAULT_DATA_BITS,
.parity = UART_DEFAULT_PARITY,
.stop_bits = UART_DEFAULT_STOP_BITS
};

int uart_open(struct chi_device *device) {

// Check if the device and device address are valid
if (device == NULL || device->device_addr == NULL) {
return -1; // Invalid argument
}

// Initialize the UART context
uart_context_t *ctx = malloc(sizeof(uart_context_t));
if (ctx == NULL) {
return -2; // Out of memory error
}
memset(ctx, 0, sizeof(uart_context_t));

// // If no cfg is provided, use the default configuration
// uart_config_t *cfg = device->cfg;
// if (cfg == NULL) {
// cfg = &default_cfg;
// }

// free(ctx); // Free the UART context

return 0; // Success
}

int uart_close(struct chi_device *device) {

if (device == NULL || device->cfg == NULL) {
return -1; // Invalid argument
}

return 0; // Success
}

ssize_t uart_read_async(struct chi_device *device, void *buffer, uint32_t size, chi_device_callback cb) {

if (device == NULL || device->cfg == NULL || buffer == NULL || size == 0) {
return -1; // Invalid argument
}

return size; // Return the number of bytes to be read
}

ssize_t uart_write_async(struct chi_device *device, const void *buffer, uint32_t size, chi_device_callback cb) {

if (device == NULL || device->cfg == NULL || buffer == NULL || size == 0) {
return -1; // Invalid argument
}

return size; // Return the number of bytes to be written
}
19 changes: 19 additions & 0 deletions scripts/picolibc-cross-file.txt.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2024 ETH Zurich and University of Bologna.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

[binaries]
c = [ '@CROSS_C_COMPILER@', @CROSS_C_COMPILER_ARGS_LIST@ ]
ar = '@CROSS_AR@'
strip = '@CROSS_STRIP@'

[host_machine]
system = '@CROSS_SYSTEM@'
cpu_family = '@CROSS_CPU_FAMILY@'
cpu = '@CROSS_CPU@'
endian = '@CROSS_ENDIAN@'

[properties]
c_args = [ @CROSS_C_ARGS_LIST@ ]
c_link_args = [ @CROSS_C_LINK_ARGS_LIST@ ]
skip_sanity_check = @CROSS_SKIP_SANITY_CHECK@
Loading

0 comments on commit 48617f4

Please sign in to comment.