-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
subsys: sdfw services: add device information service. #19278
subsys: sdfw services: add device information service. #19278
Conversation
CI InformationTo view the history of this post, clich the 'edited' button above Inputs:Sources:sdk-nrf: PR head: 5f25abc9c0584ead37b7f90d470ddc050f2c3003 more detailssdk-nrf:
Github labels
List of changed files detected by CI (13)
Outputs:ToolchainVersion: b77d8c1312 Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped;
|
You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds. Note: This comment is automatically posted by the Documentation Publish GitHub Action. |
a232655
to
277a4a5
Compare
{ | ||
int err = -1; /* initialize with negative value for error */ | ||
|
||
if ((NULL != uuid_words) && (uuid_words_count >= UUID_BYTES_LENGTH)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there some reason for having the bigger than or equal >=
instead of equals ==
?` I'd assume UUID is always fixed in length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the read buffer and its size are provided by the user, it is okay to provide bigger than necessary buffer. In any case, the API will ALWAYS copy only 16 bytes to the output since, as you mentioned, the UUID has a fixed size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess uuid_words_count
could also be omitted from the API then, since the length is known and fixed? Maybe it would be better to define a struct with a fixed length array member? For example:
struct ssf_device_info_uuid {
uint8_t value[UUID_BYTES_LENGTH];
};
int ssf_device_info_get_uuid(struct ssf_device_info_uuid *uuid);
Or if you agree with my suggestion below (#19278 (comment)) of combining all the device info reads into one request, you could make a single struct for this, for example
struct ssf_device_info {
uint8_t uuid[16];
uint32_t type;
uint8_t testimprint[32];
uint32_t partno;
uint32_t hwrevision;
uint32_t productionrevision;
};
int ssf_device_info_get(struct ssf_device_info *info);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done, I've reworked the generated files and the service API.
now the device info handler on the secure side returns all the OICR register content at once in the device_info structure, the device_info.h header offers an API that assumes the uuid_buffer size to be 16 bytes.
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
cba6b88
to
b2f5472
Compare
struct read_resp uuid_read_response = read_response.resp_msg_read_resp_m; | ||
|
||
if (read_response.resp_msg_choice == resp_msg_read_resp_m_c) { | ||
if (entity_UUID_c == uuid_read_response.read_resp_target.entity_choice) { | ||
ret = read_response.resp_msg_read_resp_m.read_resp_status | ||
.stat_choice; | ||
if (stat_SUCCESS_c != ret) { | ||
ssf_client_decode_done(rsp_pkt); | ||
return ret; | ||
} | ||
} else { | ||
/* the received response message is not a read UUID response */ | ||
ssf_client_decode_done(rsp_pkt); | ||
return stat_INTERNAL_ERROR_c; | ||
} | ||
|
||
} else { | ||
/* the received response message is not a read response */ | ||
ssf_client_decode_done(rsp_pkt); | ||
return stat_INTERNAL_ERROR_c; | ||
} | ||
|
||
size_t uuid_words_len = uuid_read_response.read_resp_data_uint_count; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare variables at top of functions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
0c03ce0
to
fc6e850
Compare
{ | ||
int err = -1; /* initialize with negative value for error */ | ||
|
||
if ((NULL != uuid_words) && (uuid_words_count >= UUID_BYTES_LENGTH)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess uuid_words_count
could also be omitted from the API then, since the length is known and fixed? Maybe it would be better to define a struct with a fixed length array member? For example:
struct ssf_device_info_uuid {
uint8_t value[UUID_BYTES_LENGTH];
};
int ssf_device_info_get_uuid(struct ssf_device_info_uuid *uuid);
Or if you agree with my suggestion below (#19278 (comment)) of combining all the device info reads into one request, you could make a single struct for this, for example
struct ssf_device_info {
uint8_t uuid[16];
uint32_t type;
uint8_t testimprint[32];
uint32_t partno;
uint32_t hwrevision;
uint32_t productionrevision;
};
int ssf_device_info_get(struct ssf_device_info *info);
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
; Device Info service response to read data. | ||
read_resp = ( | ||
1, | ||
target: entity, | ||
status: stat, | ||
data: [1*8 uint] ; table of at least 1 int - at most 8 int | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned above, I think it would be preferable if each of the returned data types had a well defined type in this schema. Currently the length of the responses is not enforced by the protocol, and the lengths are not actually defined anywhere except for in a macro internal to device_info_service.c
.
Unless there is a good reason to read/write the individual parts of the data you could consider combining them in a single request - that might help keep the client code size low as well as reduce the IPC overhead if you need to request multiple of these in a row. I think that would be pretty reasonable since the full data would be 64 bytes total. For example:
device_info = [
uuid: bstr .size 16,
type: uint,
testimprint: bstr .size 32,
partno: uint,
hwrevision: uint,
productionrevision: uint,
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for suggesting this !
it required some dipper changes to the handler / service files but it is now done.
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
fc6e850
to
c966f97
Compare
ff27f4f
to
a0bd0b8
Compare
735715c
to
4e38232
Compare
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
subsys/sdfw_services/services/device_info/device_info_service.c
Outdated
Show resolved
Hide resolved
4e38232
to
0af7815
Compare
6a00573
to
809e4a6
Compare
Ref: NRFX-6558 Signed-off-by: Aymen LAOUINI <[email protected]>
809e4a6
to
5f25abc
Compare
.read_resp_data | ||
.device_info_productionrevision; | ||
|
||
memcpy((uint8_t *)(device_info_data->device_info_testimprint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why we need to cast to u8 pointers as the C standard function API has them as void pointers?
Memcpy function call returns void pointer, so the return value could be explicitly casted to void to show the intent of programmer.
https://en.cppreference.com/w/c/string/byte/memcpy
But nevertheless this code probably works as is. Might be something that static code analysis would nag about.
Enable reading device information (UUID for instance) as a service requested by a client and executed by the secure domain.