BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
box_init.c
00001 /* 00002 * Copyright (c) 2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #include "uvisor-lib/uvisor-lib.h" 00018 #include "api/inc/pool_queue_exports.h" 00019 #include "api/inc/rpc_exports.h" 00020 #include "api/inc/uvisor_semaphore.h" 00021 #include "api/inc/box_config.h" 00022 #include "mbed_interface.h" 00023 #include "cmsis_os2.h" 00024 #include <stdint.h> 00025 #include <stdlib.h> 00026 #include <string.h> 00027 00028 /* Register the OS with uVisor */ 00029 extern void SVC_Handler(void); 00030 extern void PendSV_Handler(void); 00031 extern void SysTick_Handler(void); 00032 extern int32_t svcRtxKernelLock(void); 00033 00034 UVISOR_SET_PRIV_SYS_HOOKS(SVC_Handler, PendSV_Handler, SysTick_Handler, svcRtxKernelLock, __uvisor_semaphore_post); 00035 00036 extern RtxBoxIndex * const __uvisor_ps; 00037 00038 void __uvisor_initialize_rpc_queues(void) 00039 { 00040 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) 00041 // TODO Initialize RPC queues on ARMv8-M (via uvisor_start). 00042 return; 00043 #endif 00044 00045 UvisorBoxIndex * const index = &__uvisor_ps->index; 00046 00047 uvisor_pool_slot_t i; 00048 00049 uvisor_rpc_outgoing_message_queue_t * rpc_outgoing_msg_queue = &(uvisor_rpc(index)->outgoing_message_queue); 00050 uvisor_rpc_incoming_message_queue_t * rpc_incoming_msg_queue = &(uvisor_rpc(index)->incoming_message_queue); 00051 uvisor_rpc_fn_group_queue_t * rpc_fn_group_queue = &(uvisor_rpc(index)->fn_group_queue); 00052 00053 /* Initialize the outgoing RPC message queue. */ 00054 if (uvisor_pool_queue_init(&rpc_outgoing_msg_queue->queue, 00055 &rpc_outgoing_msg_queue->pool, 00056 rpc_outgoing_msg_queue->messages, 00057 sizeof(*rpc_outgoing_msg_queue->messages), 00058 UVISOR_RPC_OUTGOING_MESSAGE_SLOTS)) { 00059 uvisor_error(USER_NOT_ALLOWED); 00060 } 00061 00062 /* Initialize all the result semaphores. */ 00063 for (i = 0; i < UVISOR_RPC_OUTGOING_MESSAGE_SLOTS; i++) { 00064 UvisorSemaphore * semaphore = &rpc_outgoing_msg_queue->messages[i].semaphore; 00065 if (__uvisor_semaphore_init(semaphore, 1, 0)) { 00066 uvisor_error(USER_NOT_ALLOWED); 00067 } 00068 } 00069 00070 /* Initialize the incoming RPC message queues. */ 00071 if (uvisor_pool_queue_init(&rpc_incoming_msg_queue->todo_queue, 00072 &rpc_incoming_msg_queue->pool, 00073 rpc_incoming_msg_queue->messages, 00074 sizeof(*rpc_incoming_msg_queue->messages), 00075 UVISOR_RPC_INCOMING_MESSAGE_SLOTS)) { 00076 uvisor_error(USER_NOT_ALLOWED); 00077 } 00078 /* This is a double init of the pool. We need a function that just inits 00079 * the queue, not the pool, and init everybody separately. */ 00080 if (uvisor_pool_queue_init(&rpc_incoming_msg_queue->done_queue, 00081 &rpc_incoming_msg_queue->pool, 00082 rpc_incoming_msg_queue->messages, 00083 sizeof(*rpc_incoming_msg_queue->messages), 00084 UVISOR_RPC_INCOMING_MESSAGE_SLOTS)) { 00085 uvisor_error(USER_NOT_ALLOWED); 00086 } 00087 00088 /* Initialize the function group pool. */ 00089 if (uvisor_pool_queue_init(&rpc_fn_group_queue->queue, 00090 &rpc_fn_group_queue->pool, 00091 rpc_fn_group_queue->fn_groups, 00092 sizeof(*rpc_fn_group_queue->fn_groups), 00093 UVISOR_RPC_FN_GROUP_SLOTS)) { 00094 uvisor_error(USER_NOT_ALLOWED); 00095 } 00096 00097 /* Initialize all the function group semaphores. */ 00098 for (i = 0; i < UVISOR_RPC_FN_GROUP_SLOTS; i++) { 00099 UvisorSemaphore * semaphore = &rpc_fn_group_queue->fn_groups[i].semaphore; 00100 if (__uvisor_semaphore_init(semaphore, 1, 0)) { 00101 uvisor_error(USER_NOT_ALLOWED); 00102 } 00103 } 00104 } 00105 00106 /* This function is called by uVisor in unprivileged mode. On this OS, we 00107 * create box main threads for the box. */ 00108 void __uvisor_lib_box_init(void * lib_config) 00109 { 00110 osThreadId_t thread_id; 00111 uvisor_box_main_t * box_main = lib_config; 00112 osThreadAttr_t thread_attr = { 0 }; 00113 00114 __uvisor_initialize_rpc_queues(); 00115 00116 thread_attr.name = "uvisor_box_main_thread"; 00117 thread_attr.priority = box_main->priority; 00118 thread_attr.stack_size = box_main->stack_size; 00119 00120 /* Note that the box main thread stack is separate from the box stack. This 00121 * is because the thread must be created to use a different stack than the 00122 * stack osCreateThread() is called from, as context information is saved 00123 * to the thread stack by the call to osCreateThread(). */ 00124 /* Allocate memory for the main thread from the box heap. This memory is 00125 * never freed, even if the box's main thread exits. */ 00126 thread_attr.stack_mem = malloc(thread_attr.stack_size); 00127 if (thread_attr.stack_mem == NULL) { 00128 /* No process heap memory available for thread stack */ 00129 uvisor_error(USER_NOT_ALLOWED); 00130 } 00131 00132 /* Allocate memory for the main thread control block from the box heap. 00133 * This memory is never freed, even if the box's main thread exits. */ 00134 thread_attr.cb_size = sizeof(osRtxThread_t); 00135 thread_attr.cb_mem = malloc(thread_attr.cb_size); 00136 if (thread_attr.cb_mem == NULL) { 00137 /* No process heap memory available for thread control block. */ 00138 uvisor_error(USER_NOT_ALLOWED); 00139 } 00140 00141 thread_id = osThreadNew((osThreadFunc_t) box_main->function, NULL, &thread_attr); 00142 00143 if (thread_id == NULL) { 00144 /* Failed to create thread */ 00145 uvisor_error(USER_NOT_ALLOWED); 00146 } 00147 }
Generated on Tue Jul 12 2022 12:21:44 by
