-
Notifications
You must be signed in to change notification settings - Fork 734
[nrf fromtree] soc: nordic: ironside: Add counter service #3545
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
Open
SebastianBoe
wants to merge
2
commits into
nrfconnect:main
Choose a base branch
from
SebastianBoe:counter_serice_ncs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+231
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * Copyright (c) 2025 Nordic Semiconductor ASA | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #include <stddef.h> | ||
| #include <nrf_ironside/counter.h> | ||
| #include <nrf_ironside/call.h> | ||
|
|
||
| int ironside_counter_set(enum ironside_counter counter_id, uint32_t value) | ||
| { | ||
| int err; | ||
| struct ironside_call_buf *const buf = ironside_call_alloc(); | ||
|
|
||
| buf->id = IRONSIDE_CALL_ID_COUNTER_SET_V1; | ||
| buf->args[IRONSIDE_COUNTER_SET_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; | ||
| buf->args[IRONSIDE_COUNTER_SET_SERVICE_VALUE_IDX] = value; | ||
|
|
||
| ironside_call_dispatch(buf); | ||
|
|
||
| if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { | ||
| err = buf->args[IRONSIDE_COUNTER_SET_SERVICE_RETCODE_IDX]; | ||
| } else { | ||
| err = buf->status; | ||
| } | ||
|
|
||
| ironside_call_release(buf); | ||
|
|
||
| return err; | ||
| } | ||
|
|
||
| int ironside_counter_get(enum ironside_counter counter_id, uint32_t *value) | ||
| { | ||
| int err; | ||
| struct ironside_call_buf *buf; | ||
|
|
||
| if (value == NULL) { | ||
| return -IRONSIDE_COUNTER_ERROR_INVALID_PARAM; | ||
| } | ||
|
|
||
| buf = ironside_call_alloc(); | ||
|
|
||
| buf->id = IRONSIDE_CALL_ID_COUNTER_GET_V1; | ||
| buf->args[IRONSIDE_COUNTER_GET_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; | ||
|
|
||
| ironside_call_dispatch(buf); | ||
|
|
||
| if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { | ||
| err = buf->args[IRONSIDE_COUNTER_GET_SERVICE_RETCODE_IDX]; | ||
| if (err == 0) { | ||
| *value = buf->args[IRONSIDE_COUNTER_GET_SERVICE_VALUE_IDX]; | ||
| } | ||
| } else { | ||
| err = buf->status; | ||
| } | ||
|
|
||
| ironside_call_release(buf); | ||
|
|
||
| return err; | ||
| } | ||
|
|
||
| int ironside_counter_lock(enum ironside_counter counter_id) | ||
| { | ||
| int err; | ||
| struct ironside_call_buf *const buf = ironside_call_alloc(); | ||
|
|
||
| buf->id = IRONSIDE_CALL_ID_COUNTER_LOCK_V1; | ||
| buf->args[IRONSIDE_COUNTER_LOCK_SERVICE_COUNTER_ID_IDX] = (uint32_t)counter_id; | ||
|
|
||
| ironside_call_dispatch(buf); | ||
|
|
||
| if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { | ||
| err = buf->args[IRONSIDE_COUNTER_LOCK_SERVICE_RETCODE_IDX]; | ||
| } else { | ||
| err = buf->status; | ||
| } | ||
|
|
||
| ironside_call_release(buf); | ||
|
|
||
| return err; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| /* | ||
| * Copyright (c) 2025 Nordic Semiconductor ASA | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
|
|
||
| #ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ | ||
| #define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ | ||
|
|
||
| #include <stdint.h> | ||
| #include <zephyr/toolchain.h> | ||
| #include <nrf_ironside/call.h> | ||
|
|
||
| /** | ||
| * @name Counter service error codes. | ||
| * @{ | ||
| */ | ||
|
|
||
| /** Counter value is lower than current value (monotonic violation). */ | ||
| #define IRONSIDE_COUNTER_ERROR_TOO_LOW (1) | ||
| /** Invalid counter ID. */ | ||
| #define IRONSIDE_COUNTER_ERROR_INVALID_ID (2) | ||
| /** Counter is locked and cannot be modified. */ | ||
| #define IRONSIDE_COUNTER_ERROR_LOCKED (3) | ||
| /** Invalid parameter. */ | ||
| #define IRONSIDE_COUNTER_ERROR_INVALID_PARAM (4) | ||
| /** Storage operation failed. */ | ||
| #define IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE (5) | ||
|
|
||
| /** | ||
| * @} | ||
| */ | ||
|
|
||
| /** Maximum value for a counter */ | ||
| #define IRONSIDE_COUNTER_MAX_VALUE UINT32_MAX | ||
|
|
||
| /** Number of counters */ | ||
| #define IRONSIDE_COUNTER_NUM 4 | ||
|
|
||
| /** | ||
| * @brief Counter identifiers. | ||
| */ | ||
| enum ironside_counter { | ||
| IRONSIDE_COUNTER_0 = 0, | ||
| IRONSIDE_COUNTER_1, | ||
| IRONSIDE_COUNTER_2, | ||
| IRONSIDE_COUNTER_3 | ||
| }; | ||
|
|
||
| /* IronSide call identifiers with implicit versions. */ | ||
| #define IRONSIDE_CALL_ID_COUNTER_SET_V1 6 | ||
| #define IRONSIDE_CALL_ID_COUNTER_GET_V1 7 | ||
| #define IRONSIDE_CALL_ID_COUNTER_LOCK_V1 8 | ||
|
|
||
| enum { | ||
| IRONSIDE_COUNTER_SET_SERVICE_COUNTER_ID_IDX, | ||
| IRONSIDE_COUNTER_SET_SERVICE_VALUE_IDX, | ||
| /* The last enum value is reserved for the number of arguments */ | ||
| IRONSIDE_COUNTER_SET_NUM_ARGS | ||
| }; | ||
|
|
||
| enum { | ||
| IRONSIDE_COUNTER_GET_SERVICE_COUNTER_ID_IDX, | ||
| /* The last enum value is reserved for the number of arguments */ | ||
| IRONSIDE_COUNTER_GET_NUM_ARGS | ||
| }; | ||
|
|
||
| enum { | ||
| IRONSIDE_COUNTER_LOCK_SERVICE_COUNTER_ID_IDX, | ||
| /* The last enum value is reserved for the number of arguments */ | ||
| IRONSIDE_COUNTER_LOCK_NUM_ARGS | ||
| }; | ||
|
|
||
| /* Index of the return code within the service buffer. */ | ||
| #define IRONSIDE_COUNTER_SET_SERVICE_RETCODE_IDX (0) | ||
| #define IRONSIDE_COUNTER_GET_SERVICE_RETCODE_IDX (0) | ||
| #define IRONSIDE_COUNTER_LOCK_SERVICE_RETCODE_IDX (0) | ||
|
|
||
| /* Index of the value within the GET response buffer. */ | ||
| #define IRONSIDE_COUNTER_GET_SERVICE_VALUE_IDX (1) | ||
|
|
||
| BUILD_ASSERT(IRONSIDE_COUNTER_SET_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); | ||
| BUILD_ASSERT(IRONSIDE_COUNTER_GET_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); | ||
| BUILD_ASSERT(IRONSIDE_COUNTER_LOCK_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); | ||
|
|
||
| /** | ||
| * @brief Set a counter value. | ||
| * | ||
| * This sets the specified counter to the given value. The counter is monotonic, | ||
| * so the new value must be greater than or equal to the current value. | ||
| * If the counter is locked, the operation will fail. | ||
| * | ||
| * @note Counters are automatically initialized to 0 during the first boot in LCS ROT. | ||
| * The monotonic constraint applies to all subsequent writes. | ||
| * | ||
| * @param counter_id Counter identifier. | ||
| * @param value New counter value. | ||
| * | ||
| * @retval 0 on success. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_TOO_LOW if value is lower than current value. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_LOCKED if counter is locked. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE if storage operation failed. | ||
| * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). | ||
| */ | ||
| int ironside_counter_set(enum ironside_counter counter_id, uint32_t value); | ||
|
|
||
| /** | ||
| * @brief Get a counter value. | ||
| * | ||
| * This retrieves the current value of the specified counter. | ||
| * | ||
| * @note Counters are automatically initialized to 0 during the first boot in LCS ROT, | ||
| * so this function will always succeed for valid counter IDs. | ||
| * | ||
| * @param counter_id Counter identifier. | ||
| * @param value Pointer to store the counter value. | ||
| * | ||
| * @retval 0 on success. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_INVALID_PARAM if value is NULL. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_STORAGE_FAILURE if storage operation failed. | ||
| * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). | ||
| */ | ||
| int ironside_counter_get(enum ironside_counter counter_id, uint32_t *value); | ||
|
|
||
| /** | ||
| * @brief Lock a counter for the current boot. | ||
| * | ||
| * This locks the specified counter, preventing any further modifications until the next reboot. | ||
| * The lock state is not persistent and will be cleared on reboot. | ||
| * | ||
| * @note The intended use case is for a bootloader to lock a counter before transferring control | ||
| * to the next boot stage, preventing that image from modifying the counter value. | ||
| * | ||
| * @param counter_id Counter identifier. | ||
| * | ||
| * @retval 0 on success. | ||
| * @retval -IRONSIDE_COUNTER_ERROR_INVALID_ID if counter_id is invalid. | ||
| * @retval Positive error status if reported by IronSide call (see error codes in @ref call.h). | ||
| */ | ||
| int ironside_counter_lock(enum ironside_counter counter_id); | ||
|
|
||
| #endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_COUNTER_H_ */ |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.