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