This repository was archived by the owner on Jun 5, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 223
Expand file tree
/
Copy pathConfigurationManager.cpp
More file actions
289 lines (228 loc) · 8.47 KB
/
ConfigurationManager.cpp
File metadata and controls
289 lines (228 loc) · 8.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft Corporation. All rights reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <Tinyhal.h>
#include "configurationManager.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// The ConfiguraionSectorManager is only used for the Booter section, as it doesn't get the g_ConfigurationSector, no Configuraitonsector is defined for it.
void ConfigurationSectorManager::LocateConfigurationSector( UINT32 BlockUsage )
{
BlockStorageStream stream;
m_booterAddressOffset = 0xFFFFFFFF;
if(stream.Initialize( BlockUsage ))
{
const BlockDeviceInfo *DeviceInfo;
UINT32 rangeIndex, regionIndex;
m_device = stream.Device;
m_cfgPhysicalAddress = stream.BaseAddress;
DeviceInfo = m_device->GetDeviceInfo();
if(DeviceInfo->FindRegionFromAddress( m_cfgPhysicalAddress, regionIndex, rangeIndex ))
{
m_region = &DeviceInfo->Regions[ regionIndex ];
}
else
{
ASSERT(FALSE);
}
if (DeviceInfo->Attribute.SupportsXIP)
{
m_fSupportsXIP = TRUE;
m_fUsingRAM = FALSE;
// Get the real address
m_configurationSector = (ConfigurationSector *)CPU_GetUncachableAddress( m_cfgPhysicalAddress );
}
else
{
m_fSupportsXIP = FALSE;
m_configurationSector = &m_localCfg;
if (m_configurationSector !=NULL)
{
m_device->Read( m_cfgPhysicalAddress, c_ConfigurationSectorSize, (BYTE *)m_configurationSector );
}
else
{
ASSERT(0);
}
}
}
else
{
m_device = NULL;
m_region = NULL;
m_fSupportsXIP = TRUE; // will use RAM
m_fUsingRAM = TRUE;
}
}
void ConfigurationSectorManager::LoadConfiguration()
{
if (m_device ==NULL)
return;
if (m_fSupportsXIP)
{
// Get the real address
m_configurationSector = (ConfigurationSector *)CPU_GetUncachableAddress( m_cfgPhysicalAddress );
return ;
}
else
{
m_configurationSector = &m_localCfg;
m_device->Read( m_cfgPhysicalAddress, c_ConfigurationSectorSize, (BYTE *)m_configurationSector );
return ;
}
}
void ConfigurationSectorManager::WriteConfiguration( UINT32 writeOffset, BYTE *data, UINT32 size, BOOL checkWrite )
{
BOOL eraseWrite = FALSE;
UINT32 writeLengthInBytes ;
if (m_device ==NULL)
return ;
LoadConfiguration();
// Get the real address
BYTE* configurationInBytes = (BYTE*)m_configurationSector;
if (!m_fSupportsXIP)
{
writeLengthInBytes = c_ConfigurationSectorSize;
}
else
{
writeLengthInBytes = size;
}
// Validity write
if (checkWrite)
{
for (UINT32 i = 0; i<size; i++)
{
if ((~configurationInBytes[ i + writeOffset ]) & data[ i ])
{
eraseWrite = TRUE;
writeLengthInBytes = m_region->BytesPerBlock;
break;
}
}
//else XIP device directly write.
}
// Copy the whole block to a buffer, for NonXIP or need to erase block
if ((eraseWrite) || (!m_fSupportsXIP))
{
configurationInBytes =(BYTE*)malloc(writeLengthInBytes);
// load data to the local buffer.
if (configurationInBytes)
{
m_device->Read( m_cfgPhysicalAddress, writeLengthInBytes, configurationInBytes );
// copy the new data to the configdata.
for (UINT32 i = 0; i<size; i++)
{
configurationInBytes[ i + writeOffset ] = data[ i ];
}
}
else
ASSERT(0); // must have enough ram space for it.
if(eraseWrite)
{
m_device->EraseBlock( m_cfgPhysicalAddress );
}
// rewrite from the start of block
m_device->Write( m_cfgPhysicalAddress, writeLengthInBytes, configurationInBytes, FALSE );
free(configurationInBytes);
}
else // no need to erase and XIP device
{
UINT32 physicalAddr = (UINT32)m_configurationSector + writeOffset;
m_device->Write( physicalAddr, writeLengthInBytes, data, FALSE );
}
// No need to reload as the if XIP-, the pCFg is pointing to the righ address,it will updated when it read ad hoc..
// for the non-XIP, the m_configurationSector points to the LocalConfiguration, which has the newly write data.
//LoadConfiguration();
}
// Caller provide the new data and replace with the new data
void ConfigurationSectorManager::EraseWriteConfigBlock( BYTE * data, UINT32 sizeInBytes )
{
m_device->EraseBlock( m_cfgPhysicalAddress );
m_device->Write( m_cfgPhysicalAddress, sizeInBytes, data, FALSE );
// reload configuratoin
LoadConfiguration();
}
BOOL ConfigurationSectorManager::IsBootLoaderRequired( INT32 &bootModeTimeout )
{
const UINT32 c_Empty = 0xFFFFFFFF;
if(m_device == NULL)
return FALSE;
volatile UINT32* data = (volatile UINT32*)&m_configurationSector->BooterFlagArray[ 0 ];
for(int i=0; i<ConfigurationSector::c_MaxBootEntryFlags; i++ )
{
switch(data[ i ])
{
case ConfigurationSector::c_BootEntryKey:
bootModeTimeout = 20000; // 20 seconds wait time
m_booterAddressOffset = (UINT32)&data[ i ]- (UINT32)m_configurationSector;
return TRUE;
case c_Empty: // anything else means we do not enter boot loader
return FALSE;
}
}
return FALSE;
}
void ConfigurationSectorManager::CleanBootLoaderFlag()
{
const UINT32 eraseKey = 0;
// as going to write zeros, no need to validate the writeable or not.
if (m_booterAddressOffset != 0xFFFFFFFF)
{
WriteConfiguration( m_booterAddressOffset,(BYTE*)&eraseKey, sizeof(UINT32), FALSE );
}
}
BOOL ConfigurationSectorManager::CheckSignatureKeyEmpty( UINT32 Index )
{
BYTE *data = &m_configurationSector->DeploymentKeys[ Index ].SectorKey[ 0 ] ;
for(int i=0; i<sizeof(TINYBOOTER_KEY_CONFIG); i++)
{
if( data[ i ] !=0xFF)
{
return FALSE;
}
}
return TRUE;
}
void ConfigurationSectorManager::UpdateSignatureKey( UINT32 Index, BYTE* data )
{
UINT32 Offset = (UINT32)&m_configurationSector->DeploymentKeys[ Index ].SectorKey[ 0 ] - (UINT32)m_configurationSector;
WriteConfiguration( Offset, data, sizeof(TINYBOOTER_KEY_CONFIG), TRUE );
}
BOOL ConfigurationSectorManager::VerifiySignatureKey( UINT32 Index, BYTE*data )
{
// reload the configuration, make sure it is right;
LoadConfiguration();
for(int i=0; i<sizeof(TINYBOOTER_KEY_CONFIG); i++)
{
if( data[ i ] !=m_configurationSector->DeploymentKeys[ Index ].SectorKey[ i ])
{
return FALSE;
}
}
return TRUE;
}
UINT8* ConfigurationSectorManager::GetDeploymentKeys( UINT32 Index )
{
if (m_device == NULL) return 0;
LoadConfiguration();
return &(m_configurationSector->DeploymentKeys[ Index ].SectorKey[ 0 ]);
}
UINT8 ConfigurationSectorManager::GetTinyBooterVersion()
{
if (m_device == NULL) return 0;
return m_configurationSector->Version.TinyBooter;
}
UINT16 ConfigurationSectorManager::GetVersion()
{
if (m_device == NULL) return 0;
return m_configurationSector->Version.Major <<8 | m_configurationSector->Version.Minor ;
}
//--//
#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section zidata = "g_PrimaryConfigManager"
#endif
ConfigurationSectorManager g_PrimaryConfigManager;
#if defined(ADS_LINKER_BUG__NOT_ALL_UNUSED_VARIABLES_ARE_REMOVED)
#pragma arm section zidata
#endif
//--//