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