1 /*
2  *  SPDX-License-Identifier: BSD-3-Clause
3  *  SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4  *
5  */
6 
7 #include "tfm_hal_mailbox.h"
8 #include "tfm_multi_core.h"
9 #include "tfm_hal_interrupt.h"
10 #include "tfm_peripherals_def.h"
11 #include "hardware/irq.h"
12 #include "interrupt.h"
13 
14 #include "platform_multicore.h"
15 
16 #include "pico/multicore.h"
17 
18 static struct irq_t mbox_irq_info = {0};
19 
tfm_mailbox_hal_init(struct secure_mailbox_queue_t * s_queue)20 int32_t tfm_mailbox_hal_init(struct secure_mailbox_queue_t *s_queue)
21 {
22     struct mailbox_init_t *ns_init = NULL;
23 
24     multicore_ns_fifo_push_blocking_inline(NS_MAILBOX_INIT);
25 
26     ns_init = (struct mailbox_init_t *) multicore_ns_fifo_pop_blocking_inline();
27 
28     /*
29      * FIXME
30      * Necessary sanity check of the address of NPSE mailbox queue should
31      * be implemented there.
32      */
33     if (ns_init->slot_count > NUM_MAILBOX_QUEUE_SLOT) {
34         return MAILBOX_INIT_ERROR;
35     }
36 
37     s_queue->ns_status = ns_init->status;
38     s_queue->ns_slot_count = ns_init->slot_count;
39     s_queue->ns_slots = ns_init->slots;
40 
41     multicore_ns_fifo_push_blocking_inline(S_MAILBOX_READY);
42 
43     return MAILBOX_SUCCESS;
44 }
45 
tfm_mailbox_hal_notify_peer(void)46 int32_t tfm_mailbox_hal_notify_peer(void)
47 {
48     multicore_ns_fifo_push_blocking_inline(NOTIFY_FROM_CORE0);
49     return MAILBOX_SUCCESS;
50 }
51 
tfm_mailbox_hal_enter_critical(void)52 void tfm_mailbox_hal_enter_critical(void)
53 {
54     /* Reading a spinlock register attempts to claim it, returning nonzero
55      * if the claim was successful and 0 if unsuccessful */
56     while(!*MAILBOX_SPINLOCK);
57     return;
58 }
59 
tfm_mailbox_hal_exit_critical(void)60 void tfm_mailbox_hal_exit_critical(void)
61 {
62     /* Writing to a spinlock register releases it */
63     *MAILBOX_SPINLOCK = 0x1u;
64     return;
65 }
66 
67 /* Platform specific inter-processor communication interrupt handler. */
SIO_IRQ_FIFO_NS_IRQHandler(void)68 void SIO_IRQ_FIFO_NS_IRQHandler(void)
69 {
70     /*
71      * SPM will send a MAILBOX_SIGNAL to the corresponding partition
72      * indicating that a message has arrived and can be processed.
73      */
74     uint32_t msg;
75     if (multicore_ns_fifo_rvalid())
76     {
77         msg = multicore_ns_fifo_pop_blocking_inline();
78         if (msg == NOTIFY_FROM_CORE1) {
79             spm_handle_interrupt(mbox_irq_info.p_pt, mbox_irq_info.p_ildi);
80         }
81     }
82 }
83 
mailbox_irq_init(void * p_pt,const struct irq_load_info_t * p_ildi)84 enum tfm_hal_status_t mailbox_irq_init(void *p_pt,
85                                        const struct irq_load_info_t *p_ildi)
86 {
87     mbox_irq_info.p_pt = p_pt;
88     mbox_irq_info.p_ildi = p_ildi;
89 
90 
91     NVIC_SetPriority(SIO_IRQ_FIFO_NS_IRQn, DEFAULT_IRQ_PRIORITY-1);
92     irq_set_exclusive_handler(SIO_IRQ_FIFO_NS, SIO_IRQ_FIFO_NS_IRQHandler);
93 
94     if (tfm_multi_core_register_client_id_range(CLIENT_ID_OWNER_MAGIC,
95                                                 p_ildi->client_id_base,
96                                                 p_ildi->client_id_limit) != 0) {
97         return TFM_HAL_ERROR_INVALID_INPUT;
98     }
99 
100     return TFM_HAL_SUCCESS;
101 }