1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Texas Instruments K3 Mailbox Driver 4 * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ 5 */ 6 7 #include <io.h> 8 #include <kernel/delay.h> 9 #include <mm/core_memprot.h> 10 #include <mm/core_mmu.h> 11 #include <platform_config.h> 12 #include <stddef.h> 13 #include <stdint.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include "ti_sci_protocol.h" 18 #include "ti_sci_transport.h" 19 20 static vaddr_t mailbox_tx_base; 21 static vaddr_t mailbox_rx_base; 22 static vaddr_t mailbox_tx_sram_va; 23 static vaddr_t mailbox_rx_sram_va; 24 25 static TEE_Result ti_mailbox_poll_rx_status(void) 26 { 27 uint32_t num_messages_pending = 0U; 28 vaddr_t mailbox_status_addr = mailbox_rx_base + TI_MAILBOX_MSG_STATUS; 29 30 if (IO_READ32_POLL_TIMEOUT(mailbox_status_addr, num_messages_pending, 31 num_messages_pending != 0, 10, 1000)) { 32 EMSG("Mailbox RX status polling timed out"); 33 return TEE_ERROR_TIMEOUT; 34 } 35 36 return TEE_SUCCESS; 37 } 38 39 TEE_Result ti_sci_transport_send(const struct ti_sci_msg *msg) 40 { 41 uint32_t num_bytes = 0; 42 paddr_t phys_addr = 0; 43 44 if (!msg) 45 return TEE_ERROR_BAD_PARAMETERS; 46 47 num_bytes = msg->len; 48 if (num_bytes > TI_SCI_MAX_MESSAGE_SIZE) { 49 EMSG("Message size exceeds maximum allowed size"); 50 return TEE_ERROR_BAD_STATE; 51 } 52 53 if (io_read32(mailbox_tx_base + TI_MAILBOX_FIFO_STATUS) != 0U) { 54 EMSG("Mailbox TX FIFO is full"); 55 return TEE_ERROR_BUSY; 56 } 57 58 memmove((void *)mailbox_tx_sram_va, msg->buf, num_bytes); 59 phys_addr = virt_to_phys((void *)mailbox_tx_sram_va); 60 io_write32(mailbox_tx_base + TI_MAILBOX_MSG, (uint32_t)phys_addr); 61 62 return TEE_SUCCESS; 63 } 64 65 TEE_Result ti_sci_transport_recv(struct ti_sci_msg *msg) 66 { 67 uint32_t num_bytes = 0; 68 uint64_t recv_pa = 0; 69 vaddr_t recv_offset = 0; 70 vaddr_t recv_va = 0; 71 TEE_Result ret = TEE_SUCCESS; 72 73 if (!msg) 74 return TEE_ERROR_BAD_PARAMETERS; 75 76 num_bytes = msg->len; 77 if (num_bytes > TI_SCI_MAX_MESSAGE_SIZE) { 78 EMSG("Message size exceeds maximum allowed size\n"); 79 return TEE_ERROR_BAD_STATE; 80 } 81 82 ret = ti_mailbox_poll_rx_status(); 83 if (ret != TEE_SUCCESS) { 84 EMSG("Mailbox RX status polling failed"); 85 return ret; 86 } 87 88 recv_pa = io_read32(mailbox_rx_base + TI_MAILBOX_MSG); 89 if (recv_pa < MAILBOX_RX_START_REGION) { 90 EMSG("Message not received invalid address\n"); 91 return TEE_ERROR_BAD_FORMAT; 92 } 93 94 recv_offset = (vaddr_t)(recv_pa - MAILBOX_RX_START_REGION); 95 recv_va = (vaddr_t)(mailbox_rx_sram_va + recv_offset); 96 memmove(msg->buf, (uint8_t *)recv_va, num_bytes); 97 return TEE_SUCCESS; 98 } 99 100 TEE_Result ti_sci_transport_init(void) 101 { 102 mailbox_rx_base = core_mmu_get_va(TI_MAILBOX_RX_BASE, 103 MEM_AREA_IO_SEC, 104 TI_MAILBOX_DEFAULT_SIZE); 105 if (!mailbox_rx_base) 106 return TEE_ERROR_OUT_OF_MEMORY; 107 108 mailbox_tx_base = core_mmu_get_va(TI_MAILBOX_TX_BASE, 109 MEM_AREA_IO_SEC, 110 TI_MAILBOX_DEFAULT_SIZE); 111 if (!mailbox_tx_base) 112 return TEE_ERROR_OUT_OF_MEMORY; 113 114 mailbox_tx_sram_va = core_mmu_get_va(MAILBOX_TX_START_REGION, 115 MEM_AREA_IO_SEC, 116 TI_MAILBOX_DEFAULT_SIZE); 117 if (!mailbox_tx_sram_va) 118 return TEE_ERROR_OUT_OF_MEMORY; 119 120 mailbox_rx_sram_va = core_mmu_get_va(MAILBOX_RX_START_REGION, 121 MEM_AREA_IO_SEC, 122 TI_MAILBOX_DEFAULT_SIZE); 123 if (!mailbox_rx_sram_va) 124 return TEE_ERROR_OUT_OF_MEMORY; 125 126 return TEE_SUCCESS; 127 } 128