Browse Source

native_sim: Update native simulator to latest and align with it

Align with the latest upstream native simulator
4c595794588f9d7f67fcf0fe05c3db02892a00f9
including:

* 4c59579 Makefile: Add option to build native part
* 910f934 Makefile: NSI_EXTRA_INCLUDES option and lots of commentary
* d9bf489 cmd line parsin: Minor header refactoring
* 02f3555 cmd line cleanup: Run as NSI_TASK instead of calling expl.
* 2c88173 Split exit call in two
* 2b989b4 CPU IF change: nsif_cpu0_cleanup() to return int
* e696228 HW scheduler: Add API to get next event time
* ae0e9e8 native irq ctrl: Miscellaneous fixes and improvements
* 3fd84cd NSI_TASK: Add compile check of valid priority
* 7e09fb8 HW events: Change internal storage

And two minor updates to the native_sim board,
to align with this updated version:
* nsif_cpu0_cleanup(void) now must return an int
* We need to explicitly tell the native simulator build we want
  the native components built

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
pull/61584/head
Alberto Escolar Piedras 2 years ago committed by Carles Cufí
parent
commit
732b03ced6
  1. 1
      boards/posix/native_sim/CMakeLists.txt
  2. 7
      boards/posix/native_sim/nsi_if.c
  3. 50
      scripts/native_simulator/Makefile
  4. 15
      scripts/native_simulator/common/other/linker_script.pre.ld
  5. 26
      scripts/native_simulator/common/src/include/nsi_cmdline_main_if.h
  6. 2
      scripts/native_simulator/common/src/include/nsi_cpu_if.h
  7. 1
      scripts/native_simulator/common/src/include/nsi_hw_scheduler.h
  8. 28
      scripts/native_simulator/common/src/include/nsi_hws_models_if.h
  9. 15
      scripts/native_simulator/common/src/include/nsi_main.h
  10. 19
      scripts/native_simulator/common/src/main.c
  11. 39
      scripts/native_simulator/common/src/nsi_hw_scheduler.c
  12. 21
      scripts/native_simulator/common/src/nsi_tasks.h
  13. 3
      scripts/native_simulator/native/src/include/nsi_cmdline.h
  14. 28
      scripts/native_simulator/native/src/irq_ctrl.c
  15. 5
      scripts/native_simulator/native/src/nsi_cmdline.c

1
boards/posix/native_sim/CMakeLists.txt

@ -40,6 +40,7 @@ set(nsi_config_content
"NSI_EXTRA_SRCS:=$<JOIN:$<TARGET_PROPERTY:native_simulator,INTERFACE_SOURCES>,\ >" "NSI_EXTRA_SRCS:=$<JOIN:$<TARGET_PROPERTY:native_simulator,INTERFACE_SOURCES>,\ >"
"NSI_LINK_OPTIONS:=$<JOIN:$<TARGET_PROPERTY:native_simulator,INTERFACE_LINK_OPTIONS>,\ >" "NSI_LINK_OPTIONS:=$<JOIN:$<TARGET_PROPERTY:native_simulator,INTERFACE_LINK_OPTIONS>,\ >"
"NSI_PATH:=${NSI_DIR}/" "NSI_PATH:=${NSI_DIR}/"
"NSI_NATIVE=1"
) )
string(REPLACE ";" "\n" nsi_config_content "${nsi_config_content}") string(REPLACE ";" "\n" nsi_config_content "${nsi_config_content}")

7
boards/posix/native_sim/nsi_if.c

@ -25,9 +25,14 @@ void nsif_cpu0_boot(void)
run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL); run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL);
} }
void nsif_cpu0_cleanup(void) int nsif_cpu0_cleanup(void)
{ {
/*
* Note posix_soc_clean_up() may not return, but in that case,
* nsif_cpu0_cleanup() will be called again
*/
posix_soc_clean_up(); posix_soc_clean_up();
return 0;
} }
void nsif_cpu0_irq_raised(void) void nsif_cpu0_irq_raised(void)

50
scripts/native_simulator/Makefile

@ -7,52 +7,84 @@
# By default all the build output is placed under the _build folder, but the user can override it # By default all the build output is placed under the _build folder, but the user can override it
# setting the NSI_BUILD_PATH # setting the NSI_BUILD_PATH
#
# The caller can provide an optional configuration file and point to it with NSI_CONFIG_FILE
# See "Configurable/user overridible variables" below.
#
# By default only the core of the runner will be built, but the caller can set NSI_NATIVE
# to also build the components in native/src/
NSI_CONFIG_FILE?=nsi_config NSI_CONFIG_FILE?=nsi_config
-include ${NSI_CONFIG_FILE} -include ${NSI_CONFIG_FILE}
#If the file does not exist, we don't use it as a build dependency #If the file does not exist, we don't use it as a build dependency
NSI_CONFIG_FILE:=$(wildcard ${NSI_CONFIG_FILE}) NSI_CONFIG_FILE:=$(wildcard ${NSI_CONFIG_FILE})
# Configurable/user overridible variables:
# Path to the native_simulator (this folder):
NSI_PATH?=./ NSI_PATH?=./
# Folder where the build output will be placed
NSI_BUILD_PATH?=$(abspath _build/) NSI_BUILD_PATH?=$(abspath _build/)
EXE_NAME?=native_simulator.exe EXE_NAME?=native_simulator.exe
# Final executable path/file_name which will be produced
NSI_EXE?=${NSI_BUILD_PATH}/${EXE_NAME} NSI_EXE?=${NSI_BUILD_PATH}/${EXE_NAME}
# Path to the embedded SW which will be linked with the final executable
NSI_EMBEDDED_CPU_SW?= NSI_EMBEDDED_CPU_SW?=
# Host architecture configuration switch
NSI_ARCH?=-m32 NSI_ARCH?=-m32
# Coverage switch (GCOV coverage is enabled by default)
NSI_COVERAGE?=--coverage NSI_COVERAGE?=--coverage
NSI_BUILD_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE} NSI_BUILD_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE}
NSI_LINK_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE} NSI_LINK_OPTIONS?=${NSI_ARCH} ${NSI_COVERAGE}
# Extra source files to be built in the runner context
NSI_EXTRA_SRCS?= NSI_EXTRA_SRCS?=
# Extra include directories to be used while building in the runner context
NSI_EXTRA_INCLUDES?=
# Extra libraries to be linked to the final executable
NSI_EXTRA_LIBS?= NSI_EXTRA_LIBS?=
SHELL?=bash SHELL?=bash
# Compiler
NSI_CC?=gcc NSI_CC?=gcc
# Archive program (it is unlikely you'll need to change this)
NSI_AR?=ar NSI_AR?=ar
# Objcopy program (it is unlikely you'll need to change this)
NSI_OBJCOPY?=objcopy NSI_OBJCOPY?=objcopy
no_default: # Build debug switch (by default enabled)
@echo "There is no default rule, please specify what you want to build,\
or run make help for more info"
NSI_DEBUG?=-g NSI_DEBUG?=-g
# Build optimization level (by default disabled to ease debugging)
NSI_OPT?=-O0 NSI_OPT?=-O0
# Warnings swtiches (for the runner itself)
NSI_WARNINGS?=-Wall -Wpedantic NSI_WARNINGS?=-Wall -Wpedantic
# Preprocessor flags
NSI_CPPFLAGS?=-D_POSIX_C_SOURCE=200809 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED NSI_CPPFLAGS?=-D_POSIX_C_SOURCE=200809 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED
NO_PIE_CO:=-fno-pie -fno-pic NO_PIE_CO:=-fno-pie -fno-pic
DEPENDFLAGS:=-MMD -MP DEPENDFLAGS:=-MMD -MP
CFLAGS:=${NSI_DEBUG} ${NSI_WARNINGS} ${NSI_OPT} ${NO_PIE_CO} \ CFLAGS:=${NSI_DEBUG} ${NSI_WARNINGS} ${NSI_OPT} ${NO_PIE_CO} \
-ffunction-sections -fdata-sections ${DEPENDFLAGS} -std=c11 ${NSI_BUILD_OPTIONS} -ffunction-sections -fdata-sections ${DEPENDFLAGS} -std=c11 ${NSI_BUILD_OPTIONS}
FINALLINK_FLAGS:=${NO_PIE_CO} -no-pie ${NSI_WARNINGS} \ FINALLINK_FLAGS:=${NO_PIE_CO} -no-pie ${NSI_WARNINGS} \
-Wl,--gc-sections -lm -ldl -pthread \ -Wl,--gc-sections -ldl -pthread \
${NSI_LINK_OPTIONS} ${NSI_LINK_OPTIONS} -lm
no_default:
@echo "There is no default rule, please specify what you want to build,\
or run make help for more info"
RUNNER_LIB:=runner.a RUNNER_LIB:=runner.a
SRCS:=$(shell ls ${NSI_PATH}common/src/*.c ${NSI_PATH}native/src/*.c ) SRCS:=$(shell ls ${NSI_PATH}common/src/*.c)
ifdef NSI_NATIVE
SRCS+=$(shell ls ${NSI_PATH}native/src/*.c)
endif
INCLUDES:=-I${NSI_PATH}common/src/include/ \ INCLUDES:=-I${NSI_PATH}common/src/include/ \
-I${NSI_PATH}native/src/include/ \ -I${NSI_PATH}common/src \
-I${NSI_PATH}common/src ${NSI_EXTRA_INCLUDES}
ifdef NSI_NATIVE
INCLUDES+=-I${NSI_PATH}native/src/include/
endif
EXTRA_OBJS:=$(abspath $(addprefix $(NSI_BUILD_PATH)/,$(sort ${NSI_EXTRA_SRCS:%.c=%.o}))) EXTRA_OBJS:=$(abspath $(addprefix $(NSI_BUILD_PATH)/,$(sort ${NSI_EXTRA_SRCS:%.c=%.o})))
OBJS:=$(abspath $(addprefix $(NSI_BUILD_PATH)/,${SRCS:${NSI_PATH}%.c=%.o})) ${EXTRA_OBJS} OBJS:=$(abspath $(addprefix $(NSI_BUILD_PATH)/,${SRCS:${NSI_PATH}%.c=%.o})) ${EXTRA_OBJS}

15
scripts/native_simulator/common/other/linker_script.pre.ld

@ -32,16 +32,11 @@ SECTIONS
nsi_hw_events : nsi_hw_events :
{ {
__nsi_hw_events_callbacks_start = .; __nsi_hw_events_start = .;
KEEP(*(SORT(.nsi_hw_event[0-9]_callback))); \ KEEP(*(SORT(.nsi_hw_event_[0-9]))); \
KEEP(*(SORT(.nsi_hw_event[1-9][0-9]_callback))); \ KEEP(*(SORT(.nsi_hw_event_[1-9][0-9]))); \
KEEP(*(SORT(.nsi_hw_event[1-9][0-9][0-9]_callback))); KEEP(*(SORT(.nsi_hw_event_[1-9][0-9][0-9])));
__nsi_hw_events_callbacks_end = .; __nsi_hw_events_end = .;
__nsi_hw_events_timers_start = .;
KEEP(*(SORT(.nsi_hw_event[0-9]_timer))); \
KEEP(*(SORT(.nsi_hw_event[1-9][0-9]_timer))); \
KEEP(*(SORT(.nsi_hw_event[1-9][0-9][0-9]_timer)));
__nsi_hw_events_timers_end = .;
} }
} INSERT AFTER .data; } INSERT AFTER .data;

26
scripts/native_simulator/common/src/include/nsi_cmdline_main_if.h

@ -0,0 +1,26 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief API to the native simulator expects any integrating program has for handling
* command line argument parsing
*/
#ifndef NATIVE_SIMULATOR_COMMON_SRC_NSI_CMDLINE_MAIN_IF_H
#define NATIVE_SIMULATOR_COMMON_SRC_NSI_CMDLINE_MAIN_IF_H
#ifdef __cplusplus
extern "C" {
#endif
void nsi_handle_cmd_line(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif /* NATIVE_SIMULATOR_COMMON_SRC_NSI_CMDLINE_MAIN_IF_H */

2
scripts/native_simulator/common/src/include/nsi_cpu_if.h

@ -74,7 +74,7 @@ NATIVE_SIMULATOR_IF void nsif_cpu0_boot(void);
* The embedded SW library may provide this function. * The embedded SW library may provide this function.
* to do any cleanup it needs. * to do any cleanup it needs.
*/ */
NATIVE_SIMULATOR_IF void nsif_cpu0_cleanup(void); NATIVE_SIMULATOR_IF int nsif_cpu0_cleanup(void);
/* /*
* Called by the runner each time an interrupt is raised by the HW * Called by the runner each time an interrupt is raised by the HW

1
scripts/native_simulator/common/src/include/nsi_hw_scheduler.h

@ -24,6 +24,7 @@ void nsi_hws_cleanup(void);
void nsi_hws_one_event(void); void nsi_hws_one_event(void);
void nsi_hws_set_end_of_time(uint64_t new_end_of_time); void nsi_hws_set_end_of_time(uint64_t new_end_of_time);
void nsi_hws_find_next_event(void); void nsi_hws_find_next_event(void);
uint64_t nsi_hws_get_next_event_time(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

28
scripts/native_simulator/common/src/include/nsi_hws_models_if.h

@ -15,26 +15,32 @@
extern "C" { extern "C" {
#endif #endif
/* Internal structure used to link HW events */
struct nsi_hw_event_st {
void (*const callback)(void);
uint64_t *timer;
};
/** /**
* Register an event timer and event callback * Register an event timer and event callback
* *
* The HW scheduler will keep track of this event, and call its callback whenever its * The HW scheduler will keep track of this event, and call its callback whenever its
* timer is reached. * timer is reached.
* The ordering of events in the same microsecond is given by prio (lowest first), * The ordering of events in the same microsecond is given by prio (lowest first).
* and if also in the same priority by alphabetical order of the callback.
* (Normally HW models will not care about the event ordering, and will simply set a prio like 100) * (Normally HW models will not care about the event ordering, and will simply set a prio like 100)
* *
* Only very particular models will need to execute before or after others. * Only very particular models will need to execute before or after others.
*
* Priority can be a number between 0 and 999.
*/ */
#define NSI_HW_EVENT(timer, fn, prio) \ #define NSI_HW_EVENT(t, fn, prio) \
static void (* const NSI_CONCAT(__nsi_hw_event_cb_, fn))(void) \ static const struct nsi_hw_event_st NSI_CONCAT(NSI_CONCAT(__nsi_hw_event_, fn), t) \
__attribute__((__used__)) \ __attribute__((__used__)) \
__attribute__((__section__(".nsi_hw_event" NSI_STRINGIFY(prio) "_callback")))\ __attribute__((__section__(".nsi_hw_event_" NSI_STRINGIFY(prio)))) \
= fn; \ = { \
static uint64_t * const NSI_CONCAT(__nsi_hw_event_ti_, fn) \ .callback = fn, \
__attribute__((__used__)) \ .timer = &t, \
__attribute__((__section__(".nsi_hw_event" NSI_STRINGIFY(prio) "_timer")))\ }
= &timer
#ifdef __cplusplus #ifdef __cplusplus
} }

15
scripts/native_simulator/common/src/include/nsi_main.h

@ -11,10 +11,23 @@
extern "C" { extern "C" {
#endif #endif
/**
* @brief Like nsi_exit(), do all cleanup required to terminate the
* execution of the native_simulator, but instead of exiting,
* return to the caller what would have been passed to exit()
*
* @param[in] exit_code: Requested exit code to the shell
* Note that other components may have requested a different
* exit code which may have precedence if it was !=0
*
* @returns Code which would have been passed to exit()
*/
int nsi_exit_inner(int exit_code);
/** /**
* @brief Terminate the execution of the native simulator * @brief Terminate the execution of the native simulator
* *
* exit_code: Requested exit code to the shell * @param[in] exit_code: Requested exit code to the shell
* Note that other components may have requested a different * Note that other components may have requested a different
* exit code which may have precedence if it was !=0 * exit code which may have precedence if it was !=0
*/ */

19
scripts/native_simulator/common/src/main.c

@ -13,14 +13,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include "nsi_cpu_if.h" #include "nsi_cpu_if.h"
#include "nsi_tasks.h" #include "nsi_tasks.h"
#include "nsi_cmdline.h" #include "nsi_cmdline_main_if.h"
#include "nsi_utils.h" #include "nsi_utils.h"
#include "nsi_hw_scheduler.h" #include "nsi_hw_scheduler.h"
void nsi_exit(int exit_code) int nsi_exit_inner(int exit_code)
{ {
static int max_exit_code; static int max_exit_code;
@ -30,12 +30,19 @@ void nsi_exit(int exit_code)
* but instead it would get nsi_exit() recalled again * but instead it would get nsi_exit() recalled again
* ASAP from the HW thread * ASAP from the HW thread
*/ */
nsif_cpu0_cleanup(); int cpu_0_ret = nsif_cpu0_cleanup();
max_exit_code = NSI_MAX(cpu_0_ret, max_exit_code);
nsi_run_tasks(NSITASK_ON_EXIT_PRE_LEVEL); nsi_run_tasks(NSITASK_ON_EXIT_PRE_LEVEL);
nsi_hws_cleanup(); nsi_hws_cleanup();
nsi_cleanup_cmd_line();
nsi_run_tasks(NSITASK_ON_EXIT_POST_LEVEL); nsi_run_tasks(NSITASK_ON_EXIT_POST_LEVEL);
exit(max_exit_code); return max_exit_code;
}
void nsi_exit(int exit_code)
{
exit(nsi_exit_inner(exit_code));
} }
/** /**

39
scripts/native_simulator/common/src/nsi_hw_scheduler.c

@ -19,18 +19,15 @@
#include "nsi_main.h" #include "nsi_main.h"
#include "nsi_safe_call.h" #include "nsi_safe_call.h"
#include "nsi_hw_scheduler.h" #include "nsi_hw_scheduler.h"
#include "nsi_hws_models_if.h"
static uint64_t simu_time; /* The actual time as known by the HW models */ static uint64_t simu_time; /* The actual time as known by the HW models */
static uint64_t end_of_time = NSI_NEVER; /* When will this device stop */ static uint64_t end_of_time = NSI_NEVER; /* When will this device stop */
extern uint64_t *__nsi_hw_events_timers_start[]; extern struct nsi_hw_event_st __nsi_hw_events_start[];
extern uint64_t *__nsi_hw_events_timers_end[]; extern struct nsi_hw_event_st __nsi_hw_events_end[];
extern void (*__nsi_hw_events_callbacks_start[])(void); static unsigned int number_of_events;
extern void (*__nsi_hw_events_callbacks_end[])(void);
static unsigned int number_of_timers;
static unsigned int number_of_callbacks;
static unsigned int next_timer_index; static unsigned int next_timer_index;
static uint64_t next_timer_time; static uint64_t next_timer_time;
@ -104,16 +101,21 @@ static void nsi_hws_sleep_until_next_event(void)
void nsi_hws_find_next_event(void) void nsi_hws_find_next_event(void)
{ {
next_timer_index = 0; next_timer_index = 0;
next_timer_time = *__nsi_hw_events_timers_start[0]; next_timer_time = *__nsi_hw_events_start[0].timer;
for (unsigned int i = 1; i < number_of_timers ; i++) { for (unsigned int i = 1; i < number_of_events ; i++) {
if (next_timer_time > *__nsi_hw_events_timers_start[i]) { if (next_timer_time > *__nsi_hw_events_start[i].timer) {
next_timer_index = i; next_timer_index = i;
next_timer_time = *__nsi_hw_events_timers_start[i]; next_timer_time = *__nsi_hw_events_start[i].timer;
} }
} }
} }
uint64_t nsi_hws_get_next_event_time(void)
{
return next_timer_time;
}
/** /**
* Execute the next scheduled HW event * Execute the next scheduled HW event
* (advancing time until that event would trigger) * (advancing time until that event would trigger)
@ -122,8 +124,8 @@ void nsi_hws_one_event(void)
{ {
nsi_hws_sleep_until_next_event(); nsi_hws_sleep_until_next_event();
if (next_timer_index < number_of_timers) { /* LCOV_EXCL_BR_LINE */ if (next_timer_index < number_of_events) { /* LCOV_EXCL_BR_LINE */
__nsi_hw_events_callbacks_start[next_timer_index](); __nsi_hw_events_start[next_timer_index].callback();
} else { } else {
nsi_print_error_and_exit("next_timer_index corrupted\n"); /* LCOV_EXCL_LINE */ nsi_print_error_and_exit("next_timer_index corrupted\n"); /* LCOV_EXCL_LINE */
} }
@ -155,16 +157,7 @@ uint64_t nsi_hws_get_time(void)
*/ */
void nsi_hws_init(void) void nsi_hws_init(void)
{ {
number_of_timers = number_of_events = __nsi_hw_events_end - __nsi_hw_events_start;
(__nsi_hw_events_timers_end - __nsi_hw_events_timers_start);
number_of_callbacks =
(__nsi_hw_events_callbacks_end - __nsi_hw_events_callbacks_start);
/* LCOV_EXCL_START */
if (number_of_timers != number_of_callbacks || number_of_timers == 0) {
nsi_print_error_and_exit("number_of_timers corrupted\n");
}
/* LCOV_EXCL_STOP */
nsi_hws_set_sig_handler(); nsi_hws_set_sig_handler();
nsi_hws_find_next_event(); nsi_hws_find_next_event();

21
scripts/native_simulator/common/src/nsi_tasks.h

@ -13,6 +13,14 @@
extern "C" { extern "C" {
#endif #endif
#define NSITASK_PRE_BOOT_1_LEVEL 0
#define NSITASK_PRE_BOOT_2_LEVEL 1
#define NSITASK_HW_INIT_LEVEL 2
#define NSITASK_PRE_BOOT_3_LEVEL 3
#define NSITASK_FIRST_SLEEP_LEVEL 4
#define NSITASK_ON_EXIT_PRE_LEVEL 5
#define NSITASK_ON_EXIT_POST_LEVEL 6
/** /**
* NSI_TASK * NSI_TASK
* *
@ -45,15 +53,10 @@ extern "C" {
static void (* const NSI_CONCAT(__nsi_task_, fn))(void) \ static void (* const NSI_CONCAT(__nsi_task_, fn))(void) \
__attribute__((__used__)) \ __attribute__((__used__)) \
__attribute__((__section__(".nsi_" #level NSI_STRINGIFY(prio) "_task")))\ __attribute__((__section__(".nsi_" #level NSI_STRINGIFY(prio) "_task")))\
= fn = fn; \
/* Let's cross-check the macro level is a valid one, so we don't silently drop it */ \
#define NSITASK_PRE_BOOT_1_LEVEL 0 _Static_assert(NSITASK_##level##_LEVEL >= 0, \
#define NSITASK_PRE_BOOT_2_LEVEL 1 "Using a non pre-defined level, it will be dropped")
#define NSITASK_HW_INIT_LEVEL 2
#define NSITASK_PRE_BOOT_3_LEVEL 3
#define NSITASK_FIRST_SLEEP_LEVEL 4
#define NSITASK_ON_EXIT_PRE_LEVEL 5
#define NSITASK_ON_EXIT_POST_LEVEL 6
/** /**
* @brief Run the set of special native tasks corresponding to the given level * @brief Run the set of special native tasks corresponding to the given level

3
scripts/native_simulator/native/src/include/nsi_cmdline.h

@ -19,6 +19,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include "nsi_cmdline_main_if.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -68,11 +69,9 @@ struct args_struct_t {
#define ARG_TABLE_ENDMARKER \ #define ARG_TABLE_ENDMARKER \
{false, false, false, NULL, NULL, 0, NULL, NULL, NULL} {false, false, false, NULL, NULL, 0, NULL, NULL, NULL}
void nsi_handle_cmd_line(int argc, char *argv[]);
void nsi_get_cmd_line_args(int *argc, char ***argv); void nsi_get_cmd_line_args(int *argc, char ***argv);
void nsi_get_test_cmd_line_args(int *argc, char ***argv); void nsi_get_test_cmd_line_args(int *argc, char ***argv);
void nsi_add_command_line_opts(struct args_struct_t *args); void nsi_add_command_line_opts(struct args_struct_t *args);
void nsi_cleanup_cmd_line(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

28
scripts/native_simulator/native/src/irq_ctrl.c

@ -113,6 +113,11 @@ uint32_t hw_irq_ctrl_get_current_lock(void)
return irqs_locked; return irqs_locked;
} }
/*
* Change the overall interrupt controller "interrupt lock"
* The interrupt lock is a flag that provisionally disables all interrupts
* without affecting their status or their ability to be pended in the meanwhile
*/
uint32_t hw_irq_ctrl_change_lock(uint32_t new_lock) uint32_t hw_irq_ctrl_change_lock(uint32_t new_lock)
{ {
uint32_t previous_lock = irqs_locked; uint32_t previous_lock = irqs_locked;
@ -154,11 +159,20 @@ int hw_irq_ctrl_is_irq_enabled(unsigned int irq)
return (irq_mask & ((uint64_t)1 << irq))?1:0; return (irq_mask & ((uint64_t)1 << irq))?1:0;
} }
/**
* Get the current interrupt enable mask
*/
uint64_t hw_irq_ctrl_get_irq_mask(void) uint64_t hw_irq_ctrl_get_irq_mask(void)
{ {
return irq_mask; return irq_mask;
} }
/*
* Un-pend an interrupt from the interrupt controller.
*
* This is an API between the MCU model/IRQ handling side and the IRQ controller
* model
*/
void hw_irq_ctrl_clear_irq(unsigned int irq) void hw_irq_ctrl_clear_irq(unsigned int irq)
{ {
irq_status &= ~((uint64_t)1<<irq); irq_status &= ~((uint64_t)1<<irq);
@ -177,18 +191,17 @@ void hw_irq_ctrl_clear_irq(unsigned int irq)
void hw_irq_ctrl_enable_irq(unsigned int irq) void hw_irq_ctrl_enable_irq(unsigned int irq)
{ {
irq_mask |= ((uint64_t)1<<irq); irq_mask |= ((uint64_t)1<<irq);
if (irq_premask & ((uint64_t)1<<irq)) { /* if IRQ is pending */ if (irq_premask & ((uint64_t)1<<irq)) { /* if the interrupt is pending */
hw_irq_ctrl_raise_im_from_sw(irq); hw_irq_ctrl_raise_im_from_sw(irq);
} }
} }
static inline void hw_irq_ctrl_irq_raise_prefix(unsigned int irq) static inline void hw_irq_ctrl_irq_raise_prefix(unsigned int irq)
{ {
if (irq < N_IRQS) { if (irq < N_IRQS) {
irq_premask |= ((uint64_t)1<<irq); irq_premask |= ((uint64_t)1<<irq);
if (irq_mask & (1 << irq)) { if (irq_mask & ((uint64_t)1 << irq)) {
irq_status |= ((uint64_t)1<<irq); irq_status |= ((uint64_t)1<<irq);
} }
} else if (irq == PHONY_HARD_IRQ) { } else if (irq == PHONY_HARD_IRQ) {
@ -197,7 +210,7 @@ static inline void hw_irq_ctrl_irq_raise_prefix(unsigned int irq)
} }
/** /**
* Set/Raise an interrupt * Set/Raise/Pend an interrupt
* *
* This function is meant to be used by either the SW manual IRQ raising * This function is meant to be used by either the SW manual IRQ raising
* or by HW which wants the IRQ to be raised in one delta cycle from now * or by HW which wants the IRQ to be raised in one delta cycle from now
@ -233,11 +246,11 @@ static void irq_raising_from_hw_now(void)
} }
/** /**
* Set/Raise an interrupt immediately. * Set/Raise/Pend an interrupt immediately.
* Like hw_irq_ctrl_set_irq() but awake immediately the CPU instead of in * Like hw_irq_ctrl_set_irq() but awake immediately the CPU instead of in
* 1 delta cycle * 1 delta cycle
* *
* Call only from HW threads * Call only from HW threads; Should be used with care
*/ */
void hw_irq_ctrl_raise_im(unsigned int irq) void hw_irq_ctrl_raise_im(unsigned int irq)
{ {
@ -248,7 +261,7 @@ void hw_irq_ctrl_raise_im(unsigned int irq)
/** /**
* Like hw_irq_ctrl_raise_im() but for SW threads * Like hw_irq_ctrl_raise_im() but for SW threads
* *
* Call only from SW threads * Call only from SW threads; Should be used with care
*/ */
void hw_irq_ctrl_raise_im_from_sw(unsigned int irq) void hw_irq_ctrl_raise_im_from_sw(unsigned int irq)
{ {
@ -263,6 +276,7 @@ static void hw_irq_ctrl_timer_triggered(void)
{ {
irq_ctrl_timer = NSI_NEVER; irq_ctrl_timer = NSI_NEVER;
irq_raising_from_hw_now(); irq_raising_from_hw_now();
nsi_hws_find_next_event();
} }
NSI_HW_EVENT(irq_ctrl_timer, hw_irq_ctrl_timer_triggered, 900); NSI_HW_EVENT(irq_ctrl_timer, hw_irq_ctrl_timer_triggered, 900);

5
scripts/native_simulator/native/src/nsi_cmdline.c

@ -13,6 +13,7 @@
#include "nsi_tracing.h" #include "nsi_tracing.h"
#include "nsi_timer_model.h" #include "nsi_timer_model.h"
#include "nsi_hw_scheduler.h" #include "nsi_hw_scheduler.h"
#include "nsi_tasks.h"
static int s_argc, test_argc; static int s_argc, test_argc;
static char **s_argv, **test_argv; static char **s_argv, **test_argv;
@ -22,7 +23,7 @@ static int used_args;
static int args_aval; static int args_aval;
#define ARGS_ALLOC_CHUNK_SIZE 20 #define ARGS_ALLOC_CHUNK_SIZE 20
void nsi_cleanup_cmd_line(void) static void nsi_cleanup_cmd_line(void)
{ {
if (args_struct != NULL) { /* LCOV_EXCL_BR_LINE */ if (args_struct != NULL) { /* LCOV_EXCL_BR_LINE */
free(args_struct); free(args_struct);
@ -30,6 +31,8 @@ void nsi_cleanup_cmd_line(void)
} }
} }
NSI_TASK(nsi_cleanup_cmd_line, ON_EXIT_POST, 0);
/** /**
* Add a set of command line options to the program. * Add a set of command line options to the program.
* *

Loading…
Cancel
Save