1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 #define SWAP(x) \
22     (((x) >> 24) | (((x)&0x00FF0000) >> 8) | (((x)&0x0000FF00) << 8) | (((x)&0x000000FF) << 24))
23 
24 typedef enum {
25     ROM_A1_VERSION = 0x01000000,
26     ROM_A4_VERSION = 0x01030003,
27 } enum_rom_version_t;
28 
29 #ifdef __SLA_FWK__
30 #include <stdio.h>
31 #include <stdint.h>
32 
33 extern unsigned int _start_SWAP;
34 extern unsigned int _SLA_Size_SWAP;
35 
36 typedef enum {
37     MagicH = 0x46495357,
38     /* NOTE: The 0xF nibble means something called stack_method=1.
39  * If set to 0xF, the ROM fetches SP and PC immediately after the header at offset 0x20.
40  * If set to 0x4, the ROM uses the PC in the header at offset 0x14.
41  */
42     /*  MagicH = 0xF6495357,*/
43     MagicL = 0x45444744,
44 } enum_magic_t;
45 
46 typedef struct {
47     enum_magic_t MagicHigh; //> SLA Header magic
48     enum_magic_t MagicLow; //> SLA Header magic
49 } magic_t;
50 
51 typedef struct {
52     magic_t Magic;
53     enum_rom_version_t RomVersion; //> ROM version
54     unsigned int LoadAddr; //> Relocation address.
55     unsigned int SLA_CodeSize; //> SLA code size in bytes
56     unsigned int *JumpAddr; //> Rom code will jump at this address
57     unsigned int ArgSize; //> Size of the Argument
58     unsigned int AppVersionNumber; //> Version of this application
59 } flash_app_header_t;
60 
61 __attribute__((section(".sb_sla_header"))) __attribute__((__used__))
62 const flash_app_header_t sb_header = {
63     .Magic =
64         {
65             .MagicHigh = SWAP(MagicH),
66             .MagicLow  = SWAP(MagicL),
67         },
68 
69 #if defined(MAX32651_A4)
70     .RomVersion = SWAP(ROM_A4_VERSION),
71 #else
72     .RomVersion = SWAP(ROM_A1_VERSION),
73 #endif
74     .LoadAddr         = SWAP(0x10000000),
75     .SLA_CodeSize     = (unsigned int)&_SLA_Size_SWAP, // Trick to get constant defined at link time
76     .JumpAddr         = &_start_SWAP,
77     .ArgSize          = 0,
78     .AppVersionNumber = SWAP(0x01000000), // 0xAABBCCCC for version AA.BB.CCCC
79 };
80 
81 #endif //__SLA_FWK__
82 
83 #ifdef __SCPA_FWK__
84 /** Global declarations */
85 
86 #include <string.h>
87 
88 typedef enum {
89     MagicH = 0xDEADBEEF,
90     MagicL = 0xCAFEFADE,
91 } enum_magic_t;
92 
93 typedef struct {
94     enum_magic_t MagicHigh; //> SLA Header magic
95     enum_magic_t MagicLow; //> SLA Header magic
96 } magic_t;
97 
98 typedef int (*__scpa_write_t)(unsigned int dest, unsigned int length, unsigned char *p_src);
99 typedef int (*__scpa_erase_t)(unsigned int dest, unsigned int length);
100 
101 /** Generic Plugin Operations */
102 typedef struct {
103     __scpa_write_t write; //> Write to memory
104     __scpa_write_t compare; //> Compare memory data
105     __scpa_erase_t erase; //> Erase memory
106 } scpa_ops_t;
107 
108 typedef struct {
109     magic_t Magic;
110     enum_rom_version_t RomVersion; //> ROM version
111     unsigned int mem_base_addr; //> Base address of memory targetted by applet
112     unsigned int mem_size; //> Size of this memory
113     scpa_ops_t ops; //> Operations of the SCP Applet
114 } scpa_header_t;
115 
116 int start_scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src);
117 int start_scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src);
118 int start_scpa_erase(unsigned int dest, unsigned int length);
119 
120 int __attribute__((weak)) scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src);
121 int __attribute__((weak))
122 scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src);
123 int __attribute__((weak)) scpa_erase(unsigned int dest, unsigned int length);
124 
125 extern unsigned int __bss_start__;
126 extern unsigned int __bss_end__;
127 extern unsigned int __bss_magic__;
128 
129 #ifndef SCPA_MEM_BASE_ADDR
130 #define SCPA_MEM_BASE_ADDR 0xC0000000
131 #warning 'SCPA_MEM_BASE_ADDR not defined using default value 0xC0000000'
132 #endif
133 
134 #ifndef SCPA_MEM_SIZE
135 #define SCPA_MEM_SIZE 1024
136 #warning 'SCPA_MEM_SIZE not defined using default value 1024'
137 #endif
138 
139 unsigned int __attribute__((section(".scpa_init"))) Magic_bss = 0xABADCAFE;
140 
141 __attribute__((section(".scpa_header"))) __attribute__((__used__))
142 const scpa_header_t scpa_header = {
143     .Magic =
144         {
145             .MagicHigh = MagicH,
146             .MagicLow  = MagicL,
147         },
148 #ifdef MAX32651_A1
149     .RomVersion = SWAP(ROM_A1_VERSION),
150 #elif defined(MAX32651_A4)
151     .RomVersion = SWAP(ROM_A4_VERSION),
152 #else
153 #error "Please Select a chip ROM revision"
154 #endif
155     .mem_base_addr = SCPA_MEM_BASE_ADDR,
156     .mem_size      = SCPA_MEM_SIZE,
157     .ops =
158         {
159             .write   = (__scpa_write_t)start_scpa_write,
160             .compare = (__scpa_write_t)start_scpa_compare,
161             .erase   = (__scpa_erase_t)start_scpa_erase,
162         },
163 };
164 
165 int __attribute__((section(".scpa_ops")))
start_scpa_write(unsigned int dest,unsigned int length,unsigned char * p_src)166 start_scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src)
167 {
168     volatile unsigned int bss_size =
169         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
170     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
171     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
172 
173     // Automatic Code for bss init
174     if (*p_magic == 0xABADCAFE) {
175         memset((void *)p_bss, 0x00, bss_size);
176         *p_magic = 0x0;
177     }
178     return scpa_write(dest, length, p_src);
179 }
180 
181 int __attribute__((section(".scpa_ops")))
start_scpa_compare(unsigned int dest,unsigned int length,unsigned char * p_src)182 start_scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src)
183 {
184     volatile unsigned int bss_size =
185         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
186     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
187     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
188 
189     // Automatic Code for bss init
190     if (*p_magic == 0xABADCAFE) {
191         memset((void *)p_bss, 0x00, bss_size);
192         *p_magic = 0x0;
193     }
194     return scpa_compare(dest, length, p_src);
195 }
196 
start_scpa_erase(unsigned int dest,unsigned int length)197 int __attribute__((section(".scpa_ops"))) start_scpa_erase(unsigned int dest, unsigned int length)
198 {
199     volatile unsigned int bss_size =
200         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
201     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
202     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
203 
204     // Automatic Code for bss init
205     if ((*p_magic == 0xABADCAFE)) {
206         memset((void *)p_bss, 0x00, bss_size);
207         *p_magic = 0x0;
208     }
209     return scpa_erase(dest, length);
210 }
211 
212 int __attribute__((section(".scpa_ops")))
scpa_write(unsigned int dest,unsigned int length,unsigned char * p_src)213 scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src)
214 {
215     (void)dest;
216     (void)length;
217     (void)p_src;
218     return 0;
219 }
220 
221 int __attribute__((section(".scpa_ops")))
scpa_compare(unsigned int dest,unsigned int length,unsigned char * p_src)222 scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src)
223 {
224     (void)dest;
225     (void)length;
226     (void)p_src;
227     return 0;
228 }
229 
scpa_erase(unsigned int dest,unsigned int length)230 int __attribute__((section(".scpa_ops"))) scpa_erase(unsigned int dest, unsigned int length)
231 {
232     (void)dest;
233     (void)length;
234     return 0;
235 }
236 
Reset_Handler(void)237 void Reset_Handler(void) {}
238 
239 #endif //__SCPA_FWK__
240