1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** ThreadX Component                                                     */
16 /**                                                                       */
17 /**   Module Manager                                                      */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #ifdef FX_FILEX_PRESENT
23 
24 #define TX_SOURCE_CODE
25 
26 #include "tx_api.h"
27 #include "tx_initialize.h"
28 #include "tx_mutex.h"
29 #include "tx_thread.h"
30 #include "tx_byte_pool.h"
31 #include "fx_api.h"
32 #include "txm_module.h"
33 #include "txm_module_manager_util.h"
34 
35 
36 /**************************************************************************/
37 /*                                                                        */
38 /*  FUNCTION                                               RELEASE        */
39 /*                                                                        */
40 /*    _txm_module_manager_file_load                       PORTABLE C      */
41 /*                                                           6.1          */
42 /*  AUTHOR                                                                */
43 /*                                                                        */
44 /*    Scott Larson, Microsoft Corporation                                 */
45 /*                                                                        */
46 /*  DESCRIPTION                                                           */
47 /*                                                                        */
48 /*    This function reads the module preamble, allocates memory for       */
49 /*    module code, loads the module code from the file, and calls         */
50 /*    _txm_module_manager_internal_load to load the data and prepare the  */
51 /*    module for execution.                                               */
52 /*                                                                        */
53 /*  INPUT                                                                 */
54 /*                                                                        */
55 /*    module_instance                   Module instance pointer           */
56 /*    module_name                       Name of module                    */
57 /*    media_ptr                         FileX media pointer               */
58 /*    file_name                         Name of module binary file        */
59 /*                                                                        */
60 /*  OUTPUT                                                                */
61 /*                                                                        */
62 /*    status                            Completion status                 */
63 /*                                                                        */
64 /*  CALLS                                                                 */
65 /*                                                                        */
66 /*    fx_file_close                     Close file                        */
67 /*    fx_file_open                      Open file                         */
68 /*    fx_file_read                      File read                         */
69 /*    fx_file_seek                      File seek                         */
70 /*    _tx_byte_allocate                 Allocate data area                */
71 /*    _txm_module_manager_internal_load Load data and prepare module for  */
72 /*                                        execution                       */
73 /*                                                                        */
74 /*  CALLED BY                                                             */
75 /*                                                                        */
76 /*    Application code                                                    */
77 /*                                                                        */
78 /*  RELEASE HISTORY                                                       */
79 /*                                                                        */
80 /*    DATE              NAME                      DESCRIPTION             */
81 /*                                                                        */
82 /*  09-30-2020      Scott Larson            Initial Version 6.1           */
83 /*                                                                        */
84 /**************************************************************************/
_txm_module_manager_file_load(TXM_MODULE_INSTANCE * module_instance,CHAR * module_name,FX_MEDIA * media_ptr,CHAR * file_name)85 UINT  _txm_module_manager_file_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, FX_MEDIA *media_ptr, CHAR *file_name)
86 {
87 
88 
89 TXM_MODULE_PREAMBLE     *module_preamble;
90 FX_FILE                 module_file;
91 TXM_MODULE_PREAMBLE     preamble;
92 ULONG                   code_start;
93 ULONG                   code_size;
94 ULONG                   code_alignment;
95 ULONG                   code_allocation_size;
96 CHAR                    *code_memory_ptr;
97 UCHAR                   *destination_ptr;
98 ULONG                   actual_size;
99 UINT                    status;
100 
101 
102     /* Attempt to open the file.  */
103     status =  fx_file_open(media_ptr, &module_file, file_name, FX_OPEN_FOR_READ);
104 
105     /* Check the file open status.  */
106     if (status == FX_SUCCESS)
107     {
108 
109         /* Read the preamble of the module.  */
110         status =  fx_file_read(&module_file, (VOID *) &preamble, sizeof(TXM_MODULE_PREAMBLE), &actual_size);
111 
112         /* Check the file read status.  */
113         if (status == FX_SUCCESS)
114         {
115 
116             /* Check the number of bytes read.  */
117             if (actual_size == sizeof(TXM_MODULE_PREAMBLE))
118             {
119 
120                 /* Pickup the module's information.  */
121                 module_preamble =  (TXM_MODULE_PREAMBLE *) &preamble;
122 
123                 /* Pickup the module code size.  */
124                 code_size =  module_preamble -> txm_module_preamble_code_size;
125 
126                 /* Check for valid sizes.  */
127                 if (code_size != 0)
128                 {
129 
130                     /* Initialize module control block to all zeros.  */
131                     TX_MEMSET(module_instance, 0, sizeof(TXM_MODULE_INSTANCE));
132 
133                     /* Get the amount of the bytes we need to allocate for the module's code as well as the required alignment.  */
134                     status =  _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size);
135                     if (status == TX_SUCCESS)
136                     {
137 
138                         /* Allocate code memory for the module.  */
139                         status =  _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &code_memory_ptr, code_allocation_size, TX_NO_WAIT);
140 
141                         /* Determine if the module's code memory allocation was successful.  */
142                         if (status == TX_SUCCESS)
143                         {
144 
145                             /* Prepare to read the module code into memory.  */
146                             code_start =       (ULONG) code_memory_ptr;
147                             code_start =       (code_start + (code_alignment - 1)) & ~(code_alignment - 1);
148                             destination_ptr =  (UCHAR *)  code_start;
149 
150                             /* Seek back to the beginning of the file.  */
151                             status =  fx_file_seek(&module_file, 0);
152                             if (status == FX_SUCCESS)
153                             {
154 
155                                 /* Read the module into memory.  */
156                                 status =  fx_file_read(&module_file, (VOID *) destination_ptr, code_size, &actual_size);
157                                 if (status == FX_SUCCESS)
158                                 {
159 
160                                     /* Check the actual size read.  */
161                                     if (actual_size == code_size)
162                                     {
163 
164                                         /* At this point, the module's instruction area is now in the RAM code area.  */
165 
166                                         /* Now load it in-place.  */
167                                         status =  _txm_module_manager_internal_load(module_instance, module_name, (VOID *) code_start,
168                                                                                     code_size, code_memory_ptr, code_allocation_size);
169                                         if (status == TX_SUCCESS)
170                                         {
171 
172                                             /* Close the file.  */
173                                             fx_file_close(&module_file);
174 
175                                             /* Return success.  */
176                                             return(TX_SUCCESS);
177                                         }
178                                     }
179                                     else
180                                     {
181 
182                                         /* Invalid number of bytes read.  */
183                                         status =  TXM_MODULE_FILEX_INVALID_BYTES_READ;
184                                     }
185                                 }
186                             }
187 
188                             /* Release the memory.  */
189                             _tx_byte_release(code_memory_ptr);
190                         }
191                     }
192                 }
193                 else
194                 {
195 
196                     /* Invalid module preamble.  */
197                     status =  TXM_MODULE_INVALID;
198                 }
199             }
200             else
201             {
202 
203                 /* Invalid number of bytes read.  */
204                 status =  TXM_MODULE_FILEX_INVALID_BYTES_READ;
205             }
206         }
207 
208         /* Close the file.  */
209         fx_file_close(&module_file);
210     }
211 
212     /* Return success.  */
213     return(status);
214 }
215 
216 #endif
217