bcm283x: Unite mailbox implementations Signed-off-by: Lukas Graber <lukas.graber@hensoldt-cyber.de>
diff --git a/libplatsupport/CMakeLists.txt b/libplatsupport/CMakeLists.txt index c4d83fd..0316c13 100644 --- a/libplatsupport/CMakeLists.txt +++ b/libplatsupport/CMakeLists.txt
@@ -34,21 +34,27 @@ "ega;LibPlatSupportX86ConsoleDeviceEGA;LIB_PLAT_SUPPORT_SERIAL_TEXT_EGA;KernelPlatPC99" ) -if(NOT ${KernelArmMach} STREQUAL "") +set(LibPlatSupportMach "") +if(KernelPlatformRpi3 OR KernelPlatformRpi4) + set(LibPlatSupportMach "bcm283x") +elseif(NOT ${KernelArmMach} STREQUAL "") + # falling back to kernel settings is done to keep legacy compatibility set(LibPlatSupportMach "${KernelArmMach}") -else() - set(LibPlatSupportMach "") endif() file( GLOB deps - src/mach/${LibPlatSupportMach}/*.c src/plat/${KernelPlatform}/*.c src/*.c src/plat/${KernelPlatform}/acpi/*.c ) +if(NOT ${LibPlatSupportMach} STREQUAL "") + file(GLOB lib_deps "src/mach/${LibPlatSupportMach}/*.c") + list(APPEND deps ${lib_deps}) +endif() + if(${KernelArch} STREQUAL "arm") list(APPEND deps src/arch/arm/clock.c) list(APPEND deps src/arch/arm/delay.c)
diff --git a/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h new file mode 100644 index 0000000..0f18899 --- /dev/null +++ b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h
@@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021, HENSOLDT Cyber GmbH + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <stdint.h> +#include <utils/util.h> +#include <platsupport/io.h> + +// Mailbox status codes +enum { + MAILBOX_OK = 0, + MAILBOX_ERR_INTERNAL = -1, + MAILBOX_ERR_INVALID = -2, + MAILBOX_ERR_BUSY = -3, + MAILBOX_ERR_DMA = -4, + MAILBOX_ERR_READ = -5, + MAILBOX_ERR_WRITE = -6, + MAILBOX_ERR_BUFFER = -7, + MAILBOX_ERR_TAG = -8 +}; + +typedef struct mailbox { + /** + * Mailbox request/response message. + * @param mbox Initialized mailbox driver instance. + * @param tag_id Tag ID encoding a mailbox command. + * @param request_tag Pointer to request tag struct object. + * @param request_tag_size Size of request tag struct object. + * @param response_tag Pointer to response tag struct object. + * @param response_tag_size Size of response tag struct object. + * @return 0 on success. Non-zero on error. + */ + int (*message)(struct mailbox *mbox, + uint32_t tag_id, + void *request_tag, + uint32_t request_tag_size, + void *response_tag, + uint32_t response_tag_size); + /* Device data */ + void *priv; + /* DMA allocator */ + ps_dma_man_t *dma_man; + /* Buffer for mailbox requests/responses */ + void *buffer; + /* Physical Address of the DMA region */ + uintptr_t phys_addr; +} mailbox_t; + +// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +#define CODE_BUFFER_REQUEST_PROCESS 0x00000000 +#define CODE_BUFFER_RESPONSE_SUCCESS 0x80000000 +#define CODE_BUFFER_RESPONSE_FAILURE 0x80000001 +typedef struct MailboxInterface_PropertyBuffer { + uint32_t buffer_size; + uint32_t code; + uint8_t tags[0]; +} +MailboxInterface_PropertyBuffer_t; + +// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +// bit 0-30: value length in bytes +// bit 31: request (clear) / response (set) +#define VALUE_LENGTH_RESPONSE (1u << 31) +typedef struct MailboxInterface_PropertyTag { + uint32_t tag_id; + uint32_t value_buffer_size; + uint32_t value_length; +} +MailboxInterface_PropertyTag_t; + +/** + * Initialise the mailbox subsystem and provide a handle for access + * @param[in] io_ops io operations for device initialisation + * @param[out] mailbox A mailbox handle structure to initialise + * @return 0 on success, errno value otherwise + */ +int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox); + +/** + * Destroy the mailbox by freeing the allocated DMA region. + * @param[in] mailbox A mailbox handle structure to destroy + * @return 0 on success, errno value otherwise + */ +int mailbox_destroy(mailbox_t *mailbox);
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox_util.h b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h similarity index 94% rename from libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox_util.h rename to libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h index c75fd0e..aaf107a 100644 --- a/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox_util.h +++ b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h
@@ -108,10 +108,10 @@ //-----------------------------Mailbox Functions------------------------------// //////////////////////////////////////////////////////////////////////////////// -bool bcm2837_set_power_state_on(mailbox_t *mbox, uint32_t device_id); +bool mailbox_set_power_state_on(mailbox_t *mbox, uint32_t device_id); -int bcm2837_get_clock_rate(mailbox_t *mbox, uint32_t clock_id); +int mailbox_get_clock_rate(mailbox_t *mbox, uint32_t clock_id); -bool bcm2837_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]); +bool mailbox_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]); // TODO: Add more mailbox functions if needed
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h index 0f18899..555fb7d 100644 --- a/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h +++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h
@@ -6,83 +6,9 @@ #pragma once -#include <stdint.h> -#include <utils/util.h> -#include <platsupport/io.h> +#include <platsupport/mach/mailbox.h> -// Mailbox status codes -enum { - MAILBOX_OK = 0, - MAILBOX_ERR_INTERNAL = -1, - MAILBOX_ERR_INVALID = -2, - MAILBOX_ERR_BUSY = -3, - MAILBOX_ERR_DMA = -4, - MAILBOX_ERR_READ = -5, - MAILBOX_ERR_WRITE = -6, - MAILBOX_ERR_BUFFER = -7, - MAILBOX_ERR_TAG = -8 -}; - -typedef struct mailbox { - /** - * Mailbox request/response message. - * @param mbox Initialized mailbox driver instance. - * @param tag_id Tag ID encoding a mailbox command. - * @param request_tag Pointer to request tag struct object. - * @param request_tag_size Size of request tag struct object. - * @param response_tag Pointer to response tag struct object. - * @param response_tag_size Size of response tag struct object. - * @return 0 on success. Non-zero on error. - */ - int (*message)(struct mailbox *mbox, - uint32_t tag_id, - void *request_tag, - uint32_t request_tag_size, - void *response_tag, - uint32_t response_tag_size); - /* Device data */ - void *priv; - /* DMA allocator */ - ps_dma_man_t *dma_man; - /* Buffer for mailbox requests/responses */ - void *buffer; - /* Physical Address of the DMA region */ - uintptr_t phys_addr; -} mailbox_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -#define CODE_BUFFER_REQUEST_PROCESS 0x00000000 -#define CODE_BUFFER_RESPONSE_SUCCESS 0x80000000 -#define CODE_BUFFER_RESPONSE_FAILURE 0x80000001 -typedef struct MailboxInterface_PropertyBuffer { - uint32_t buffer_size; - uint32_t code; - uint8_t tags[0]; -} -MailboxInterface_PropertyBuffer_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -// bit 0-30: value length in bytes -// bit 31: request (clear) / response (set) -#define VALUE_LENGTH_RESPONSE (1u << 31) -typedef struct MailboxInterface_PropertyTag { - uint32_t tag_id; - uint32_t value_buffer_size; - uint32_t value_length; -} -MailboxInterface_PropertyTag_t; - -/** - * Initialise the mailbox subsystem and provide a handle for access - * @param[in] io_ops io operations for device initialisation - * @param[out] mailbox A mailbox handle structure to initialise - * @return 0 on success, errno value otherwise - */ -int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox); - -/** - * Destroy the mailbox by freeing the allocated DMA region. - * @param[in] mailbox A mailbox handle structure to destroy - * @return 0 on success, errno value otherwise - */ -int mailbox_destroy(mailbox_t *mailbox); +// The actual mailbox base address is 0xFE00B880 but mappings have to be page +// aligned (actually DMA_PAGE_SIZE aligned). +#define MAILBOX_PADDR 0xfe00b000 +#define MAILBOX_SIZE 0x1000
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox_util.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox_util.h deleted file mode 100644 index 5746662..0000000 --- a/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox_util.h +++ /dev/null
@@ -1,117 +0,0 @@ -/* - * Copyright (C) 2021, HENSOLDT Cyber GmbH - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <stdint.h> -#include <stdbool.h> -#include <platsupport/plat/mailbox.h> - -// Clock IDs: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#clocks -enum { - CLOCK_ID_EMMC = 1, - CLOCK_ID_UART, - CLOCK_ID_ARM, - CLOCK_ID_CORE, - CLOCK_ID_V3D, - CLOCK_ID_H264, - CLOCK_ID_ISP, - CLOCK_ID_SDRAM, - CLOCK_ID_PIXEL, - CLOCK_ID_PWM, - CLOCK_ID_HEVC, - CLOCK_ID_EMMC2, - CLOCK_ID_M2MC, - CLOCK_ID_PIXEL_BVB -}; - -// Device IDs: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#power -enum { - DEVICE_ID_SD_CARD = 0, - DEVICE_ID_UART0, - DEVICE_ID_UART1, - DEVICE_ID_USB_HCD, - DEVICE_ID_I2C0, - DEVICE_ID_I2C1, - DEVICE_ID_I2C2, - DEVICE_ID_SPI, - DEVICE_ID_CCP2TX -}; - -//////////////////////////////////////////////////////////////////////////////// -//--------------------------------Property Tags-------------------------------// -//////////////////////////////////////////////////////////////////////////////// - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -#define TAG_SET_POWER_STATE 0x00028001 -#define TAG_GET_CLOCK_RATE 0x00030002 -#define TAG_GET_MAC_ADDRESS 0x00010003 - -// TODO: Add more property tags if needed - -//////////////////////////////////////////////////////////////////////////////// -//-----------------------------Request/Reponse Tags---------------------------// -//////////////////////////////////////////////////////////////////////////////// - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#set-power-state -#define SET_POWER_STATE_OFF (0u << 0) -#define SET_POWER_STATE_ON (1u << 0) -#define SET_POWER_STATE_WAIT (1u << 1) -typedef struct { - MailboxInterface_PropertyTag_t tag; - uint32_t device_id; - uint32_t state; -} -PropertyTag_SetPowerState_Request_t; - -#define SET_POWER_STATE_NO_DEVICE (1u << 1) -typedef struct { - MailboxInterface_PropertyTag_t tag; - uint32_t device_id; - uint32_t state; -} -PropertyTag_SetPowerState_Response_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-clock-rate -typedef struct { - MailboxInterface_PropertyTag_t tag; - uint32_t clock_id; -} -PropertyTag_GetClockRate_Request_t; - -typedef struct { - MailboxInterface_PropertyTag_t tag; - uint32_t clock_id; - uint32_t rate; -} -PropertyTag_GetClockRate_Response_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-board-mac-address -#define MAC_ADDRESS_SIZE 6 -typedef struct { - MailboxInterface_PropertyTag_t tag; -} -PropertyTag_GetMACAddress_Request_t; - -typedef struct { - MailboxInterface_PropertyTag_t tag; - uint8_t mac_address[MAC_ADDRESS_SIZE]; -} -PropertyTag_GetMACAddress_Response_t; - -// TODO: Add more request/reponse tags if needed - -//////////////////////////////////////////////////////////////////////////////// -//-----------------------------Mailbox Functions------------------------------// -//////////////////////////////////////////////////////////////////////////////// - -bool bcm2711_set_power_state_on(mailbox_t *mbox, uint32_t device_id); - -int bcm2711_get_clock_rate(mailbox_t *mbox, uint32_t clock_id); - -bool bcm2711_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]); - -// TODO: Add more mailbox functions if needed
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h index 0f18899..89ae38e 100644 --- a/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h +++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h
@@ -6,83 +6,9 @@ #pragma once -#include <stdint.h> -#include <utils/util.h> -#include <platsupport/io.h> +#include <platsupport/mach/mailbox.h> -// Mailbox status codes -enum { - MAILBOX_OK = 0, - MAILBOX_ERR_INTERNAL = -1, - MAILBOX_ERR_INVALID = -2, - MAILBOX_ERR_BUSY = -3, - MAILBOX_ERR_DMA = -4, - MAILBOX_ERR_READ = -5, - MAILBOX_ERR_WRITE = -6, - MAILBOX_ERR_BUFFER = -7, - MAILBOX_ERR_TAG = -8 -}; - -typedef struct mailbox { - /** - * Mailbox request/response message. - * @param mbox Initialized mailbox driver instance. - * @param tag_id Tag ID encoding a mailbox command. - * @param request_tag Pointer to request tag struct object. - * @param request_tag_size Size of request tag struct object. - * @param response_tag Pointer to response tag struct object. - * @param response_tag_size Size of response tag struct object. - * @return 0 on success. Non-zero on error. - */ - int (*message)(struct mailbox *mbox, - uint32_t tag_id, - void *request_tag, - uint32_t request_tag_size, - void *response_tag, - uint32_t response_tag_size); - /* Device data */ - void *priv; - /* DMA allocator */ - ps_dma_man_t *dma_man; - /* Buffer for mailbox requests/responses */ - void *buffer; - /* Physical Address of the DMA region */ - uintptr_t phys_addr; -} mailbox_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -#define CODE_BUFFER_REQUEST_PROCESS 0x00000000 -#define CODE_BUFFER_RESPONSE_SUCCESS 0x80000000 -#define CODE_BUFFER_RESPONSE_FAILURE 0x80000001 -typedef struct MailboxInterface_PropertyBuffer { - uint32_t buffer_size; - uint32_t code; - uint8_t tags[0]; -} -MailboxInterface_PropertyBuffer_t; - -// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface -// bit 0-30: value length in bytes -// bit 31: request (clear) / response (set) -#define VALUE_LENGTH_RESPONSE (1u << 31) -typedef struct MailboxInterface_PropertyTag { - uint32_t tag_id; - uint32_t value_buffer_size; - uint32_t value_length; -} -MailboxInterface_PropertyTag_t; - -/** - * Initialise the mailbox subsystem and provide a handle for access - * @param[in] io_ops io operations for device initialisation - * @param[out] mailbox A mailbox handle structure to initialise - * @return 0 on success, errno value otherwise - */ -int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox); - -/** - * Destroy the mailbox by freeing the allocated DMA region. - * @param[in] mailbox A mailbox handle structure to destroy - * @return 0 on success, errno value otherwise - */ -int mailbox_destroy(mailbox_t *mailbox); +// The actual mailbox base address is 0x3F00B880 but mappings have to be page +// aligned (actually DMA_PAGE_SIZE aligned). +#define MAILBOX_PADDR 0x3f00b000 +#define MAILBOX_SIZE 0x1000
diff --git a/libplatsupport/src/plat/bcm2711/mailbox.c b/libplatsupport/src/mach/bcm283x/mailbox.c similarity index 96% rename from libplatsupport/src/plat/bcm2711/mailbox.c rename to libplatsupport/src/mach/bcm283x/mailbox.c index 92fe5b7..b519e9e 100644 --- a/libplatsupport/src/plat/bcm2711/mailbox.c +++ b/libplatsupport/src/mach/bcm283x/mailbox.c
@@ -21,11 +21,6 @@ #define DMA_PAGE_SIZE 4096 #define DMA_ALIGNEMENT 4096 -// The actual mailbox base address is 0x3F00B880 but mappings have to be page -// aligned (actually DMA_PAGE_SIZE aligned). -#define MAILBOX_PADDR 0xfe00b000 -#define MAILBOX_SIZE 0x1000 - // See: https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes#addresses-as-data #define VC_BASE_CACHED 0x40000000 #define VC_BASE_UNCACHED 0xC0000000 @@ -166,7 +161,7 @@ return 0; } -static int bcm2711_mailbox_message( +static int mailbox_message( mailbox_t *mbox, uint32_t tag_id, void *request_tag, @@ -249,7 +244,7 @@ MAP_IF_NULL(io_ops, MAILBOX, reg); mailbox->priv = reg; mailbox->dma_man = &io_ops->dma_manager; - mailbox->message = &bcm2711_mailbox_message; + mailbox->message = &mailbox_message; mailbox->buffer = mailbox->dma_man->dma_alloc_fn( mailbox->dma_man->cookie, DMA_PAGE_SIZE,
diff --git a/libplatsupport/src/plat/bcm2711/mailbox_util.c b/libplatsupport/src/mach/bcm283x/mailbox_util.c similarity index 94% rename from libplatsupport/src/plat/bcm2711/mailbox_util.c rename to libplatsupport/src/mach/bcm283x/mailbox_util.c index 4037317..dcf0cd5 100644 --- a/libplatsupport/src/plat/bcm2711/mailbox_util.c +++ b/libplatsupport/src/mach/bcm283x/mailbox_util.c
@@ -11,7 +11,7 @@ * - https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md */ -#include <platsupport/plat/mailbox_util.h> +#include <platsupport/mach/mailbox_util.h> #include <string.h> static int mbox_req_resp(mailbox_t *mbox, @@ -43,7 +43,7 @@ * @param device_id Device ID of device that should be activated. * @return true on success, false on failure */ -bool bcm2711_set_power_state_on(mailbox_t *mbox, uint32_t device_id) +bool mailbox_set_power_state_on(mailbox_t *mbox, uint32_t device_id) { PropertyTag_SetPowerState_Request_t TagRequest = { .device_id = device_id, @@ -77,7 +77,7 @@ * @return requested clock rate on success, 0 on failure (e.g. clock id * is not valid -> clock does not exist) */ -int bcm2711_get_clock_rate(mailbox_t *mbox, uint32_t clock_id) +int mailbox_get_clock_rate(mailbox_t *mbox, uint32_t clock_id) { PropertyTag_GetClockRate_Request_t TagRequest = { .clock_id = clock_id @@ -108,7 +108,7 @@ * be copied to. * @return true on success, false on failure */ -bool bcm2711_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]) +bool mailbox_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]) { PropertyTag_GetMACAddress_Request_t TagRequest; PropertyTag_GetMACAddress_Response_t TagResponse;
diff --git a/libplatsupport/src/plat/bcm2837/mailbox.c b/libplatsupport/src/plat/bcm2837/mailbox.c deleted file mode 100644 index 58b65c3..0000000 --- a/libplatsupport/src/plat/bcm2837/mailbox.c +++ /dev/null
@@ -1,273 +0,0 @@ -/* - * 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 <stdint.h> -#include <string.h> - -#include <utils/util.h> -#include <platsupport/plat/mailbox.h> -#include "../../services.h" - -#define DMA_PAGE_SIZE 4096 -#define DMA_ALIGNEMENT 4096 - -// The actual mailbox base address is 0x3F00B880 but mappings have to be page -// aligned (actually DMA_PAGE_SIZE aligned). -#define MAILBOX_PADDR 0x3f00b000 -#define MAILBOX_SIZE 0x1000 - -// See: https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes#addresses-as-data -#define VC_BASE_CACHED 0x40000000 -#define VC_BASE_UNCACHED 0xC0000000 -#define VC_BASE VC_BASE_UNCACHED - -// See: https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes#sample-code -#define MAILBOX_EMPTY 0x40000000 -#define MAILBOX_FULL 0x80000000 - -// See: https://github.com/raspberrypi/firmware/wiki/Mailboxes#channels -#define MAILBOX_CHANNEL 8 - -typedef volatile struct { - uint32_t read; // 0x00 - uint32_t reg_04; // 0x04 - uint32_t reg_08; // 0x08 - uint32_t reg_0c; // 0x0c - uint32_t reg_10; // 0x10 - uint32_t reg_14; // 0x14 - uint32_t status0; // 0x18 - uint32_t reg_1c; // 0x1c - uint32_t write; // 0x20 - uint32_t reg_24; // 0x24 - uint32_t reg_28; // 0x28 - uint32_t reg_2c; // 0x2c - uint32_t reg_30; // 0x30 - uint32_t reg_34; // 0x34 - uint32_t status1; // 0x38 -} mailbox_regs_t; - -static inline mailbox_regs_t *get_mailbox_regs(mailbox_t *mbox) -{ - return (mbox != NULL && mbox->priv != NULL) ? (mailbox_regs_t *)((uintptr_t)mbox->priv + 0x880) - : NULL; -} - -static inline uint32_t get_bus_address(uint32_t addr) -{ - return (((addr) & ~VC_BASE) | VC_BASE); -} - -/* - * Mailbox read operation - * - * 1. Read the status register until the empty flag is not set - * 2. Read data from the read register - * 3. If the lower four bits do not match the channel number desired then repeat - * from 1 - * 4. The upper 28 bits are the returned data - * - * See: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/accessing.md#general-procedure - */ -static int mailbox_read( - mailbox_regs_t *mailbox, - uint32_t channel, - uint32_t *rsp -) -{ - uint32_t value; - do { - while (mailbox->status0 & MAILBOX_EMPTY) { - // busy loop - } - value = mailbox->read; - } while ((value & 0xF) != channel); - - *rsp = value & ~0xF; - - return 0; -} - -/* - * Mailbox write operation - * - * 1. Read the status register until the full flag is not set - * 2. Write the data (shifted into the upper 28 bits) combined with the channel - * (in the lower four bits) to the write register - * - * See: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/accessing.md#general-procedure - */ -static int mailbox_write( - mailbox_regs_t *mailbox, - uint32_t channel, - uint32_t data -) -{ - while (mailbox->status1 & MAILBOX_FULL) { - // busy loop - } - mailbox->write = (data & ~0xF) | (channel & 0xF); - - return 0; -} - -/* - * Mailbox Command - * - * A command should only be issued in case the mailbox is empty. If the mailbox - * is not empty, it is said to be busy. In this case, it is the reponsibility of - * the caller to handle this situation. - * - * Every mailbox command consists of a request and a response. For this purpose - * PropertyTags must be created and configured for request. Afterwards, the - * mailbox interface is notified that there is a message waiting in the buffer. - * This signalling is done with the mailbox_write operation, that writes the - * buffer_address and the channel number into the write register. The - * mailbox_read operation makes sure that the response waiting in the mailbox - * interface belongs to the issued request by checking the current - * buffer_address and channel number in the read register. - */ -static int mailbox_command( - mailbox_t *mbox, - uint32_t channel, - uint32_t data, - uint32_t *rsp -) -{ - mailbox_regs_t *mailbox = get_mailbox_regs(mbox); - if (mailbox == NULL) { - ZF_LOGE("Mailbox is invalid!"); - return MAILBOX_ERR_INVALID; - } - - // mailbox command should start operation with an empty mailbox - if (!(mailbox->status0 & MAILBOX_EMPTY)) { - ZF_LOGE("Mailbox is busy!"); - return MAILBOX_ERR_BUSY; - } - - if (mailbox_write(mailbox, channel, data) != 0) { - ZF_LOGE("Error when writing to mailbox!"); - return MAILBOX_ERR_WRITE; - } - if (mailbox_read(mailbox, channel, rsp) != 0) { - ZF_LOGE("Error when reading from mailbox!"); - return MAILBOX_ERR_READ; - } - return 0; -} - -static int bcm2837_mailbox_message( - mailbox_t *mbox, - uint32_t tag_id, - void *request_tag, - uint32_t request_tag_size, - void *response_tag, - uint32_t response_tag_size -) -{ - // ToDo: Implement the mailbox interface to handle multiple concatenated - // tags per message. Currently, we assume only one tag per message. - // See: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#message-content - - // Prepare Mailbox - uint32_t tag_size = MAX(request_tag_size, response_tag_size); - MailboxInterface_PropertyBuffer_t *buffer = (MailboxInterface_PropertyBuffer_t *)mbox->buffer; - buffer->buffer_size = sizeof(MailboxInterface_PropertyBuffer_t) - + tag_size - + sizeof(uint32_t); - buffer->code = CODE_BUFFER_REQUEST_PROCESS; - - MailboxInterface_PropertyTag_t *tags = (MailboxInterface_PropertyTag_t *)buffer->tags; - memcpy(tags, request_tag, request_tag_size); - tags->tag_id = tag_id; - tags->value_buffer_size = tag_size - sizeof(MailboxInterface_PropertyTag_t); - tags->value_length = tags->value_buffer_size & ~VALUE_LENGTH_RESPONSE; - - uint32_t *end_tag = (uint32_t *)(tags + tag_size); - *end_tag = 0; - assert((uintptr_t)(const void *)end_tag % 4 == 0); - - // Mailbox command - uint32_t rsp = 0; - uint32_t buffer_address = get_bus_address((uint32_t) mbox->phys_addr); - int status = mailbox_command(mbox, - MAILBOX_CHANNEL, - buffer_address, - &rsp); - - // Response Evaluation - // Buffer format: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#buffer-contents - // Tag format: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#tag-format - if (status != 0) { - ZF_LOGE("Mailbox command error - code: %d!", status); - return status; - } else if (rsp != buffer_address) { - ZF_LOGE("Mailbox response should be buffer address!"); - return MAILBOX_ERR_INTERNAL; - } else if (buffer->buffer_size != sizeof(MailboxInterface_PropertyBuffer_t) - + tag_size - + sizeof(uint32_t)) { - ZF_LOGE("Wrong buffer size returned!"); - return MAILBOX_ERR_BUFFER; - } else if (buffer->code != CODE_BUFFER_RESPONSE_SUCCESS) { - ZF_LOGE("Mailbox response is not successful!"); - return MAILBOX_ERR_BUFFER; - } else if (tags->tag_id != tag_id) { - ZF_LOGE("Wrong tag id returned!"); - return MAILBOX_ERR_TAG; - } else if (!(tags->value_length & VALUE_LENGTH_RESPONSE)) { - ZF_LOGE("Received tag is not a response!"); - return MAILBOX_ERR_TAG; - } else if ((tags->value_length &= ~VALUE_LENGTH_RESPONSE) == 0) { - ZF_LOGE("Value buffer has length 0 bytes!"); - return MAILBOX_ERR_TAG; - } - - memcpy(response_tag, tags, response_tag_size); - - return MAILBOX_OK; -} - -int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox) -{ - void *reg = NULL; - MAP_IF_NULL(io_ops, MAILBOX, reg); - mailbox->priv = reg; - mailbox->dma_man = &io_ops->dma_manager; - mailbox->message = &bcm2837_mailbox_message; - mailbox->buffer = mailbox->dma_man->dma_alloc_fn( - mailbox->dma_man->cookie, - DMA_PAGE_SIZE, - DMA_ALIGNEMENT, - 0, - PS_MEM_NORMAL); - if (mailbox->buffer == NULL) { - ZF_LOGE("DMA allocation failed."); - return MAILBOX_ERR_DMA; - } - mailbox->phys_addr = mailbox->dma_man->dma_pin_fn(mailbox->dma_man->cookie, - mailbox->buffer, - DMA_PAGE_SIZE); - return 0; -} - -int mailbox_destroy(mailbox_t *mailbox) -{ - mailbox->dma_man->dma_free_fn(mailbox->dma_man->cookie, - mailbox->buffer, - DMA_PAGE_SIZE); - mailbox->dma_man->dma_unpin_fn(mailbox->dma_man->cookie, - mailbox->buffer, - DMA_PAGE_SIZE); - return 0; -}
diff --git a/libplatsupport/src/plat/bcm2837/mailbox_util.c b/libplatsupport/src/plat/bcm2837/mailbox_util.c deleted file mode 100644 index 6473f41..0000000 --- a/libplatsupport/src/plat/bcm2837/mailbox_util.c +++ /dev/null
@@ -1,132 +0,0 @@ -/* - * 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/plat/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 bcm2837_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 bcm2837_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 bcm2837_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; -}