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_A2_VERSION = 0x01010002,
27 } enum_rom_version_t;
28 
29 #ifdef __SLA_FWK__
30 /***** Includes *****/
31 #include <stdio.h>
32 #include <stdint.h>
33 
34 extern unsigned int _start_SWAP;
35 extern unsigned int _SLA_Size_SWAP;
36 
37 typedef enum {
38     MagicH = 0x48495357,
39     MagicL = 0x45444744,
40 } enum_magic_t;
41 
42 typedef struct {
43     enum_magic_t MagicHigh; //> SLA Header magic
44     enum_magic_t MagicLow; //> SLA Header magic
45 } magic_t;
46 
47 typedef struct {
48     magic_t Magic;
49     enum_rom_version_t RomVersion; //> ROM version
50     unsigned int LoadAddr; //> Relocation address.
51     unsigned int SLA_CodeSize; //> SLA code size in bytes
52     unsigned int *JumpAddr; //> Rom code will jump at this address
53     unsigned int ArgSize; //> Size of the Argument
54     unsigned int AppVersionNumber; //> Version of this application
55 } flash_app_header_t;
56 
57 __attribute__((section(".sb_sla_header"))) __attribute__((__used__))
58 const flash_app_header_t sb_header = {
59     .Magic =
60         {
61             .MagicHigh = SWAP(MagicH),
62             .MagicLow  = SWAP(MagicL),
63         },
64 #if defined(MAX32520_A2)
65     .RomVersion = SWAP(ROM_A2_VERSION),
66 #else
67     .RomVersion = SWAP(ROM_A1_VERSION),
68 #endif
69     .LoadAddr         = SWAP(0x1000C000),
70     .SLA_CodeSize     = (unsigned int)&_SLA_Size_SWAP, // Trick to get constant defined at link time
71     .JumpAddr         = &_start_SWAP,
72     .ArgSize          = 0,
73     .AppVersionNumber = SWAP(0x01000000), // 0xAABBCCCC for version AA.BB.CCCC
74 };
75 
76 //__attribute__ ((section(".sb_sla_trailer"))) __attribute__ ((__used__))
77 //const unsigned int dummy_signature=0xCAFEFADE;
78 
79 #endif //__SLA_FWK__
80 
81 #ifdef __SCPA_FWK__
82 /** Global declarations */
83 
84 #include <string.h>
85 
86 typedef enum {
87     MagicH = 0xDEADBEEF,
88     MagicL = 0xCAFEFADE,
89 } enum_magic_t;
90 
91 typedef struct {
92     enum_magic_t MagicHigh; //> SLA Header magic
93     enum_magic_t MagicLow; //> SLA Header magic
94 } magic_t;
95 
96 typedef int (*__scpa_write_t)(unsigned int dest, unsigned int length, unsigned char *p_src);
97 typedef int (*__scpa_erase_t)(unsigned int dest, unsigned int length);
98 
99 /** Generic Plugin Operations */
100 typedef struct {
101     __scpa_write_t write; //> Write to memory
102     __scpa_write_t compare; //> Compare memory data
103     __scpa_erase_t erase; //> Erase memory
104 } scpa_ops_t;
105 
106 typedef struct {
107     magic_t Magic;
108     enum_rom_version_t RomVersion; //> ROM version
109     unsigned int mem_base_addr; //> Base address of memory targetted by applet
110     unsigned int mem_size; //> Size of this memory
111     scpa_ops_t ops; //> Operations of the SCP Applet
112 } scpa_header_t;
113 
114 int start_scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src);
115 int start_scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src);
116 int start_scpa_erase(unsigned int dest, unsigned int length);
117 
118 int __attribute__((weak)) scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src);
119 int __attribute__((weak))
120 scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src);
121 int __attribute__((weak)) scpa_erase(unsigned int dest, unsigned int length);
122 
123 extern unsigned int __bss_start__;
124 extern unsigned int __bss_end__;
125 extern unsigned int __bss_magic__;
126 
127 #ifndef SCPA_MEM_BASE_ADDR
128 #define SCPA_MEM_BASE_ADDR 0xC0000000
129 #warning 'SCPA_MEM_BASE_ADDR not defined using default value 0xC0000000'
130 #endif
131 
132 #ifndef SCPA_MEM_SIZE
133 #define SCPA_MEM_SIZE 1024
134 #warning 'SCPA_MEM_SIZE not defined using default value 1024'
135 #endif
136 
137 unsigned int __attribute__((section(".scpa_init"))) Magic_bss = 0xABADCAFE;
138 
139 __attribute__((section(".scpa_header"))) __attribute__((__used__))
140 const scpa_header_t scpa_header = {
141     .Magic =
142         {
143             .MagicHigh = MagicH,
144             .MagicLow  = MagicL,
145         },
146 #ifdef MAX32520_A1
147     .RomVersion = SWAP(ROM_A1_VERSION),
148 #elif defined(MAX32520_A2)
149     .RomVersion = SWAP(ROM_A2_VERSION),
150 #else
151 #error "Please Select a chip ROM revision"
152 #endif
153     .mem_base_addr = SCPA_MEM_BASE_ADDR,
154     .mem_size      = SCPA_MEM_SIZE,
155     .ops =
156         {
157             .write   = (__scpa_write_t)start_scpa_write,
158             .compare = (__scpa_write_t)start_scpa_compare,
159             .erase   = (__scpa_erase_t)start_scpa_erase,
160         },
161 };
162 
163 int __attribute__((section(".scpa_ops")))
start_scpa_write(unsigned int dest,unsigned int length,unsigned char * p_src)164 start_scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src)
165 {
166     volatile unsigned int bss_size =
167         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
168     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
169     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
170 
171     // Automatic Code for bss init
172     if (*p_magic == 0xABADCAFE) {
173         memset((void *)p_bss, 0x00, bss_size);
174         *p_magic = 0x0;
175     }
176     return scpa_write(dest, length, p_src);
177 }
178 
179 int __attribute__((section(".scpa_ops")))
start_scpa_compare(unsigned int dest,unsigned int length,unsigned char * p_src)180 start_scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src)
181 {
182     volatile unsigned int bss_size =
183         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
184     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
185     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
186 
187     // Automatic Code for bss init
188     if (*p_magic == 0xABADCAFE) {
189         memset((void *)p_bss, 0x00, bss_size);
190         *p_magic = 0x0;
191     }
192     return scpa_compare(dest, length, p_src);
193 }
194 
start_scpa_erase(unsigned int dest,unsigned int length)195 int __attribute__((section(".scpa_ops"))) start_scpa_erase(unsigned int dest, unsigned int length)
196 {
197     volatile unsigned int bss_size =
198         (volatile unsigned int)&__bss_end__ - (volatile unsigned int)&__bss_start__;
199     volatile unsigned char *p_bss = (volatile unsigned char *)&__bss_start__;
200     volatile unsigned int *p_magic = (volatile unsigned int *)&__bss_magic__;
201 
202     // Automatic Code for bss init
203     if ((*p_magic == 0xABADCAFE)) {
204         memset((void *)p_bss, 0x00, bss_size);
205         *p_magic = 0x0;
206     }
207     return scpa_erase(dest, length);
208 }
209 
210 int __attribute__((section(".scpa_ops")))
scpa_write(unsigned int dest,unsigned int length,unsigned char * p_src)211 scpa_write(unsigned int dest, unsigned int length, unsigned char *p_src)
212 {
213     (void)dest;
214     (void)length;
215     (void)p_src;
216     return 0;
217 }
218 
219 int __attribute__((section(".scpa_ops")))
scpa_compare(unsigned int dest,unsigned int length,unsigned char * p_src)220 scpa_compare(unsigned int dest, unsigned int length, unsigned char *p_src)
221 {
222     (void)dest;
223     (void)length;
224     (void)p_src;
225     return 0;
226 }
227 
scpa_erase(unsigned int dest,unsigned int length)228 int __attribute__((section(".scpa_ops"))) scpa_erase(unsigned int dest, unsigned int length)
229 {
230     (void)dest;
231     (void)length;
232     return 0;
233 }
234 
Reset_Handler(void)235 void Reset_Handler(void) {}
236 
237 #endif //__SCPA_FWK__
238