blob: dcf0cd59b4a64cffff898bc016ca653acd941838 [file] [log] [blame]
/*
* Copyright (C) 2021, HENSOLDT Cyber GmbH
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/*
* More information about the mailboxes:
* - https://github.com/raspberrypi/firmware/wiki/Mailboxes
* - https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
* - https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md
*/
#include <platsupport/mach/mailbox_util.h>
#include <string.h>
static int mbox_req_resp(mailbox_t *mbox,
uint32_t tag_id,
void *req,
uint32_t req_size,
void *resp,
uint32_t resp_size)
{
// ToDo: could add a max loop counter to timeout here to exit the polling
// loop if there is no reponse
for (;;) {
int status = mbox->message(mbox,
tag_id,
req,
req_size,
resp,
resp_size);
if (MAILBOX_ERR_BUSY != status) {
return status;
}
}
}
/**
* Set power state on of device.
*
* @param mbox Initialized mailbox driver instance
* @param device_id Device ID of device that should be activated.
* @return true on success, false on failure
*/
bool mailbox_set_power_state_on(mailbox_t *mbox, uint32_t device_id)
{
PropertyTag_SetPowerState_Request_t TagRequest = {
.device_id = device_id,
.state = SET_POWER_STATE_ON | SET_POWER_STATE_WAIT
};
PropertyTag_SetPowerState_Response_t TagResponse;
int status = mbox_req_resp(mbox,
TAG_SET_POWER_STATE,
&TagRequest,
sizeof(TagRequest),
&TagResponse,
sizeof(TagResponse));
if (MAILBOX_OK != status
|| (TagResponse.state & SET_POWER_STATE_NO_DEVICE)
|| !(TagResponse.state & SET_POWER_STATE_ON)) {
ZF_LOGE("Failed to set power state on - error code: %d!", status);
return false;
}
return true;
}
/**
* Get clock rate of certain device clock.
*
* @param mbox Initialized mailbox driver instance
* @param clock_id ID of clock
* @return requested clock rate on success, 0 on failure (e.g. clock id
* is not valid -> clock does not exist)
*/
int mailbox_get_clock_rate(mailbox_t *mbox, uint32_t clock_id)
{
PropertyTag_GetClockRate_Request_t TagRequest = {
.clock_id = clock_id
};
PropertyTag_GetClockRate_Response_t TagResponse;
int status = mbox_req_resp(mbox,
TAG_GET_CLOCK_RATE,
&TagRequest,
sizeof(TagRequest),
&TagResponse,
sizeof(TagResponse));
if (MAILBOX_OK != status) {
ZF_LOGE("Failed to get clock rate of clock %d - error code: %d!", clock_id, status);
TagResponse.rate = 0;
}
return TagResponse.rate;
}
/**
* Get board MAC address.
*
* @param mbox Initialized mailbox driver instance
* @param buffer Buffer address to which each digit of the MAC address should
* be copied to.
* @return true on success, false on failure
*/
bool mailbox_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE])
{
PropertyTag_GetMACAddress_Request_t TagRequest;
PropertyTag_GetMACAddress_Response_t TagResponse;
int status = mbox_req_resp(mbox,
TAG_GET_MAC_ADDRESS,
&TagRequest,
sizeof(TagRequest),
&TagResponse,
sizeof(TagResponse));
if (MAILBOX_OK != status) {
ZF_LOGE("Failed to get mac address of board - error code: %d!", status);
memset(buffer, 0, MAC_ADDRESS_SIZE);
return false;
}
memcpy(buffer, TagResponse.mac_address, MAC_ADDRESS_SIZE);
return true;
}