1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Description: 8 * Framework API for the architecture layer. 9 */ 10 #include <internal/fwk_module.h> 11 12 #include <fwk_arch.h> 13 #include <fwk_assert.h> 14 15 #include <arch_helpers.h> 16 17 #if FWK_HAS_INCLUDE(<fmw_arch.h>) 18 # include <fmw_arch.h> 19 #endif 20 21 #include <internal/fwk_core.h> 22 23 #include <fwk_io.h> 24 #include <fwk_log.h> 25 #include <fwk_module.h> 26 #include <fwk_module_idx.h> 27 #include <fwk_status.h> 28 29 #include <string.h> 30 31 extern int fwk_interrupt_init(const struct fwk_arch_interrupt_driver *driver); 32 fwk_arch_interrupt_init(int (* interrupt_init_handler)(const struct fwk_arch_interrupt_driver ** driver))33static int fwk_arch_interrupt_init(int (*interrupt_init_handler)( 34 const struct fwk_arch_interrupt_driver **driver)) 35 { 36 /* Initialize interrupt management */ 37 int status; 38 const struct fwk_arch_interrupt_driver *driver; 39 40 /* 41 * Retrieve a pointer to the interrupt management driver from the 42 * architecture layer. 43 */ 44 status = interrupt_init_handler(&driver); 45 if (status != FWK_SUCCESS) { 46 return FWK_E_PANIC; 47 } 48 49 /* Initialize the interrupt management component */ 50 status = fwk_interrupt_init(driver); 51 if (status != FWK_SUCCESS) { 52 return FWK_E_PANIC; 53 } 54 55 return FWK_SUCCESS; 56 } 57 fwk_arch_init(const struct fwk_arch_init_driver * driver)58int fwk_arch_init(const struct fwk_arch_init_driver *driver) 59 { 60 int status; 61 62 if (driver == NULL) { 63 return FWK_E_PARAM; 64 } 65 66 if (driver->interrupt == NULL) { 67 return FWK_E_PARAM; 68 } 69 70 fwk_module_init(); 71 72 status = fwk_io_init(); 73 if (!fwk_expect(status == FWK_SUCCESS)) { 74 return FWK_E_PANIC; 75 } 76 77 status = fwk_log_init(); 78 if (!fwk_expect(status == FWK_SUCCESS)) { 79 return FWK_E_PANIC; 80 } 81 82 /* Initialize interrupt management */ 83 status = fwk_arch_interrupt_init(driver->interrupt); 84 if (!fwk_expect(status == FWK_SUCCESS)) { 85 return FWK_E_PANIC; 86 } 87 88 status = fwk_module_start(); 89 if (!fwk_expect(status == FWK_SUCCESS)) { 90 return FWK_E_PANIC; 91 } 92 93 /* 94 * In case firmware running under other OS context, finish processing of 95 * any raised events/interrupts and return. Else continue to process events 96 * in a forever loop. 97 */ 98 #if defined(BUILD_HAS_SUB_SYSTEM_MODE) 99 fwk_process_event_queue(); 100 fwk_log_flush(); 101 #else 102 __fwk_run_main_loop(); 103 #endif 104 105 return FWK_SUCCESS; 106 } 107 fwk_arch_deinit(void)108int fwk_arch_deinit(void) 109 { 110 int status; 111 112 status = fwk_module_stop(); 113 if (!fwk_expect(status == FWK_SUCCESS)) { 114 return FWK_E_PANIC; 115 } 116 117 return FWK_SUCCESS; 118 } 119 fwk_arch_suspend(void)120void fwk_arch_suspend(void) 121 { 122 /* On some arm plaforms, wfe is supported architecturally, however 123 * implementation is erroneous. In such platforms FMW_DISABLE_ARCH_SUSPEND 124 * needs to be defined 125 */ 126 #if !defined(FMW_DISABLE_ARCH_SUSPEND) 127 arch_suspend(); 128 #endif 129 } 130