1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved. 2 // 3 // SPDX-License-Identifier: BSD-3-Clause 4 5 #include <assert.h> 6 #include <hyptypes.h> 7 #include <string.h> 8 9 #include <bootmem.h> 10 #include <idle.h> 11 #include <object.h> 12 #include <panic.h> 13 #include <refcount.h> 14 #include <thread.h> 15 #include <thread_init.h> 16 17 #include "event_handlers.h" 18 #include "thread_arch.h" 19 20 extern void 21 thread_switch_boot_thread(thread_t *new_thread); 22 23 // Thread size is the size of the whole thread TLS area to be allocated, 24 // which is larger than 'struct thread' 25 extern const size_t thread_size; 26 extern const size_t thread_align; 27 28 void thread_standard_handle_boot_runtime_first_init(void)29thread_standard_handle_boot_runtime_first_init(void) 30 { 31 void_ptr_result_t ret; 32 thread_t *idle_thread; 33 34 // Allocate boot CPU idle thread and TLS out of bootmem. 35 ret = bootmem_allocate(thread_size, thread_align); 36 if (ret.e != OK) { 37 panic("unable to allocate boot idle thread"); 38 } 39 40 // For now, we just zero-initialise the thread and TLS data and init the 41 // reference count. The real setup will be done in the idle module after 42 // partitions and allocators are working. 43 idle_thread = (thread_t *)ret.r; 44 45 assert(thread_size >= sizeof(*idle_thread)); 46 errno_t err_mem = memset_s(idle_thread, thread_size, 0, thread_size); 47 if (err_mem != 0) { 48 panic("Error in memset_s operation!"); 49 } 50 refcount_init(&idle_thread->header.refcount); 51 52 // This must be the last operation in boot_runtime_first_init. 53 thread_switch_boot_thread(idle_thread); 54 } 55 56 void thread_standard_handle_boot_runtime_warm_init(thread_t * idle_thread)57thread_standard_handle_boot_runtime_warm_init(thread_t *idle_thread) 58 { 59 // This must be the last operation in boot_runtime_warm_init. 60 thread_switch_boot_thread(idle_thread); 61 } 62 63 noreturn void thread_boot_set_idle(void)64thread_boot_set_idle(void) 65 { 66 thread_t *thread = thread_get_self(); 67 assert(thread == idle_thread()); 68 69 thread_arch_set_thread(thread); 70 } 71