mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-25 06:37:35 -04:00
[sw/lib] add SMP HAL
This commit is contained in:
parent
c13a0f5909
commit
e3cc802d7d
4 changed files with 152 additions and 1 deletions
|
@ -80,6 +80,7 @@ The NEORV32 HAL consists of the following files.
|
||||||
| `neorv32_rte.c` | `neorv32_rte.h` | <<_neorv32_runtime_environment>>
|
| `neorv32_rte.c` | `neorv32_rte.h` | <<_neorv32_runtime_environment>>
|
||||||
| `neorv32_sdi.c` | `neorv32_sdi.h` | <<_serial_data_interface_controller_sdi>> HAL
|
| `neorv32_sdi.c` | `neorv32_sdi.h` | <<_serial_data_interface_controller_sdi>> HAL
|
||||||
| `neorv32_slink.c` | `neorv32_slink.h` | <<_stream_link_interface_slink>> HAL
|
| `neorv32_slink.c` | `neorv32_slink.h` | <<_stream_link_interface_slink>> HAL
|
||||||
|
| `neorv32_smp.c` | `neorv32_smp.h` | HAL for the SMP <<_dual_core_configuration>>
|
||||||
| `neorv32_spi.c` | `neorv32_spi.h` | <<_serial_peripheral_interface_controller_spi>> HAL
|
| `neorv32_spi.c` | `neorv32_spi.h` | <<_serial_peripheral_interface_controller_spi>> HAL
|
||||||
| `neorv32_sysinfo.c` | `neorv32_sysinfo.h` | <<_system_configuration_information_memory_sysinfo>> HAL
|
| `neorv32_sysinfo.c` | `neorv32_sysinfo.h` | <<_system_configuration_information_memory_sysinfo>> HAL
|
||||||
| `neorv32_trng.c` | `neorv32_trng.h` | <<_true_random_number_generator_trng>> HAL
|
| `neorv32_trng.c` | `neorv32_trng.h` | <<_true_random_number_generator_trng>> HAL
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// ================================================================================ //
|
// ================================================================================ //
|
||||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||||
// Copyright (c) NEORV32 contributors. //
|
// Copyright (c) NEORV32 contributors. //
|
||||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||||
// SPDX-License-Identifier: BSD-3-Clause //
|
// SPDX-License-Identifier: BSD-3-Clause //
|
||||||
// ================================================================================ //
|
// ================================================================================ //
|
||||||
|
@ -262,6 +262,7 @@ typedef union {
|
||||||
|
|
||||||
// NEORV32 runtime environment
|
// NEORV32 runtime environment
|
||||||
#include "neorv32_rte.h"
|
#include "neorv32_rte.h"
|
||||||
|
#include "neorv32_smp.h"
|
||||||
|
|
||||||
// IO/peripheral devices
|
// IO/peripheral devices
|
||||||
#include "neorv32_cfs.h"
|
#include "neorv32_cfs.h"
|
||||||
|
|
79
sw/lib/include/neorv32_smp.h
Normal file
79
sw/lib/include/neorv32_smp.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// ================================================================================ //
|
||||||
|
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||||
|
// Copyright (c) NEORV32 contributors. //
|
||||||
|
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||||
|
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause //
|
||||||
|
// ================================================================================ //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file neorv32_smp.h
|
||||||
|
* @brief SMP HW driver header file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef neorv32_smp_h
|
||||||
|
#define neorv32_smp_h
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* @name Prototypes
|
||||||
|
**************************************************************************/
|
||||||
|
/**@{*/
|
||||||
|
int neorv32_smp_launch(int hart_id, void (*entry_point)(void), uint8_t* stack_memory, size_t stack_size_bytes);
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* Get data from core via ICC link.
|
||||||
|
* Check link status before #neorv32_smp_icc_avail().
|
||||||
|
*
|
||||||
|
* @param[in] hart_sel Source core.
|
||||||
|
* @return Data word (32-bit) received from selected core.
|
||||||
|
**************************************************************************/
|
||||||
|
inline uint32_t __attribute__ ((always_inline)) neorv32_smp_icc_get(int hart_sel) {
|
||||||
|
|
||||||
|
neorv32_cpu_csr_write(CSR_MXICCSR0, (uint32_t)hart_sel);
|
||||||
|
return neorv32_cpu_csr_read(CSR_MXICCRXD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* Send data to core via ICC link.
|
||||||
|
* Check link status before #neorv32_smp_icc_free().
|
||||||
|
*
|
||||||
|
* @param[in] hart_sel Destination core.
|
||||||
|
* @param[in] data Data word (32-bit) to be send to selected core.
|
||||||
|
**************************************************************************/
|
||||||
|
inline void __attribute__ ((always_inline)) neorv32_smp_icc_put(int hart_sel, uint32_t data) {
|
||||||
|
|
||||||
|
neorv32_cpu_csr_write(CSR_MXICCSR0, (uint32_t)hart_sel);
|
||||||
|
neorv32_cpu_csr_write(CSR_MXICCTXD, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* Check if ICC link data is available.
|
||||||
|
*
|
||||||
|
* @param[in] hart_sel Source core.
|
||||||
|
* @return 0 = no data available, nonzero = data available.
|
||||||
|
**************************************************************************/
|
||||||
|
inline int __attribute__ ((always_inline)) neorv32_smp_icc_avail(int hart_sel) {
|
||||||
|
|
||||||
|
neorv32_cpu_csr_write(CSR_MXICCSR0, (uint32_t)hart_sel);
|
||||||
|
return neorv32_cpu_csr_read(CSR_MXICCSR0) & (1 << CSR_MXICCSR_RX_AVAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* Check if free space in ICC link.
|
||||||
|
*
|
||||||
|
* @param[in] hart_sel Destination core.
|
||||||
|
* @return 0 = no free space available, nonzero = free space available.
|
||||||
|
**************************************************************************/
|
||||||
|
inline int __attribute__ ((always_inline)) neorv32_smp_icc_free(int hart_sel) {
|
||||||
|
|
||||||
|
neorv32_cpu_csr_write(CSR_MXICCSR0, (uint32_t)hart_sel);
|
||||||
|
return neorv32_cpu_csr_read(CSR_MXICCSR0) & (1 << CSR_MXICCSR_TX_FREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // neorv32_smp_h
|
70
sw/lib/source/neorv32_smp.c
Normal file
70
sw/lib/source/neorv32_smp.c
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// ================================================================================ //
|
||||||
|
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||||
|
// Copyright (c) NEORV32 contributors. //
|
||||||
|
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||||
|
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause //
|
||||||
|
// ================================================================================ //
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file neorv32_smp.c
|
||||||
|
* @brief SMP HW driver source file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <neorv32.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************//**
|
||||||
|
* Configure and start SMP core.
|
||||||
|
*
|
||||||
|
* @warning This function can be executed on core 0 only.
|
||||||
|
*
|
||||||
|
* @param[in] hart_id Hart/core select.
|
||||||
|
* @param[in] entry_point Core's main function (must be of type "void entry_point(void)").
|
||||||
|
* @param[in] stack_memory Pointer to beginning of core's stack memory array. Should be at least 512 bytes.
|
||||||
|
* @param[in] stack_size_bytes Core's stack size in bytes.
|
||||||
|
* @return 0 if launching succeeded. -1 if invalid hart ID or CLINT not available. -2 if core is not responding.
|
||||||
|
**************************************************************************/
|
||||||
|
int neorv32_smp_launch(int hart_id, void (*entry_point)(void), uint8_t* stack_memory, size_t stack_size_bytes) {
|
||||||
|
|
||||||
|
const uint32_t signature = 0xffab4321u;
|
||||||
|
int num_cores = (int)NEORV32_SYSINFO->MISC[SYSINFO_MISC_HART];
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
if ((neorv32_cpu_csr_read(CSR_MHARTID) != 0) || // this can be executed on core 0 only
|
||||||
|
(hart_id == 0) || // we cannot launch core 0
|
||||||
|
(hart_id > (num_cores-1)) || // selected core not available
|
||||||
|
(neorv32_clint_available() == 0)) { // we need the CLINT
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// drain input queue from selected core
|
||||||
|
while (neorv32_smp_icc_avail(hart_id)) {
|
||||||
|
neorv32_smp_icc_get(hart_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// align end of stack to 16-bytes according to the RISC-V ABI (#1021)
|
||||||
|
uint32_t stack_top = ((uint32_t)stack_memory + (uint32_t)(stack_size_bytes-1)) & 0xfffffff0u;
|
||||||
|
|
||||||
|
// send launch configuration
|
||||||
|
neorv32_smp_icc_put(hart_id, signature); // signature
|
||||||
|
neorv32_smp_icc_put(hart_id, stack_top); // top of core's stack
|
||||||
|
neorv32_smp_icc_put(hart_id, (uint32_t)entry_point); // entry point
|
||||||
|
|
||||||
|
// start core by triggering its software interrupt
|
||||||
|
neorv32_clint_msi_set(hart_id);
|
||||||
|
|
||||||
|
// wait for start acknowledge
|
||||||
|
int cnt = 0;
|
||||||
|
while (1) {
|
||||||
|
if (neorv32_smp_icc_avail(hart_id)) {
|
||||||
|
if (neorv32_smp_icc_get(hart_id) == signature) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cnt > 10000) {
|
||||||
|
return -2; // timeout; core did not respond
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue