GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_simulator.c Lines: 37 39 94.9 %
Date: 2024-03-11 05:20:25 Branches: 12 12 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** LevelX Component                                                      */
16
/**                                                                       */
17
/**   NOR Flash Simulator                                                 */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
23
/* Include necessary files.  */
24
25
#include "lx_api.h"
26
27
/* Define constants for the NOR flash simulation. */
28
29
/* This configuration is for one physical sector of overhead.  */
30
31
32
#define TOTAL_BLOCKS                        8
33
#define PHYSICAL_SECTORS_PER_BLOCK          16          /* Min value of 2, max value of 120 for 1 sector of overhead.  */
34
#define WORDS_PER_PHYSICAL_SECTOR           128
35
#define FREE_BIT_MAP_WORDS                  ((PHYSICAL_SECTORS_PER_BLOCK-1)/32)+1
36
#define USABLE_SECTORS_PER_BLOCK            (PHYSICAL_SECTORS_PER_BLOCK-1)
37
#define UNUSED_METADATA_WORDS_PER_BLOCK     (WORDS_PER_PHYSICAL_SECTOR-(3+FREE_BIT_MAP_WORDS+USABLE_SECTORS_PER_BLOCK))
38
39
40
typedef struct PHYSICAL_SECTOR_STRUCT
41
{
42
    unsigned long memory[WORDS_PER_PHYSICAL_SECTOR];
43
} PHYSICAL_SECTOR;
44
45
46
typedef struct FLASH_BLOCK_STRUCT
47
{
48
    unsigned long       erase_count;
49
    unsigned long       min_log_sector;
50
    unsigned long       max_log_sector;
51
    unsigned long       free_bit_map[FREE_BIT_MAP_WORDS];
52
    unsigned long       sector_metadata[USABLE_SECTORS_PER_BLOCK];
53
    unsigned long       unused_words[UNUSED_METADATA_WORDS_PER_BLOCK];
54
    PHYSICAL_SECTOR     physical_sectors[USABLE_SECTORS_PER_BLOCK];
55
} FLASH_BLOCK;
56
57
FLASH_BLOCK   nor_memory_area[TOTAL_BLOCKS];
58
59
ULONG         nor_sector_memory[WORDS_PER_PHYSICAL_SECTOR];
60
61
UINT  _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash);
62
UINT  _lx_nor_flash_simulator_erase_all(VOID);
63
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
64
UINT  _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words);
65
UINT  _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words);
66
UINT  _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count);
67
UINT  _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block);
68
UINT  _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector);
69
#else
70
UINT  _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words);
71
UINT  _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words);
72
UINT  _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count);
73
UINT  _lx_nor_flash_simulator_block_erased_verify(ULONG block);
74
UINT  _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector);
75
#endif
76
77
78
19
UINT  _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash)
79
{
80
81
    /* Setup the base address of the flash memory.  */
82
19
    nor_flash -> lx_nor_flash_base_address =                (ULONG *) &nor_memory_area[0];
83
84
    /* Setup geometry of the flash.  */
85
19
    nor_flash -> lx_nor_flash_total_blocks =                TOTAL_BLOCKS;
86
19
    nor_flash -> lx_nor_flash_words_per_block =             sizeof(FLASH_BLOCK)/sizeof(ULONG);
87
88
    /* Setup function pointers for the NOR flash services.  */
89
19
    nor_flash -> lx_nor_flash_driver_read =                 _lx_nor_flash_simulator_read;
90
19
    nor_flash -> lx_nor_flash_driver_write =                _lx_nor_flash_simulator_write;
91
19
    nor_flash -> lx_nor_flash_driver_block_erase =          _lx_nor_flash_simulator_block_erase;
92
19
    nor_flash -> lx_nor_flash_driver_block_erased_verify =  _lx_nor_flash_simulator_block_erased_verify;
93
94
    /* Setup local buffer for NOR flash operation. This buffer must be the sector size of the NOR flash memory.  */
95
19
    nor_flash -> lx_nor_flash_sector_buffer =  &nor_sector_memory[0];
96
97
    /* Return success.  */
98
19
    return(LX_SUCCESS);
99
}
100
101
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
102
UINT  _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words)
103
#else
104
205061
UINT  _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words)
105
#endif
106
{
107
108
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
109
    LX_PARAMETER_NOT_USED(nor_flash);
110
#endif
111
112
    /* Loop to read flash.  */
113
4738028
    while (words--)
114
    {
115
        /* Copy word.  */
116
4532967
        *destination++ =  *flash_address++;
117
    }
118
119
205061
    return(LX_SUCCESS);
120
}
121
122
123
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
124
UINT  _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words)
125
#else
126
113454
UINT  _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words)
127
#endif
128
{
129
130
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
131
    LX_PARAMETER_NOT_USED(nor_flash);
132
#endif
133
134
    /* Loop to write flash.  */
135
2496906
    while (words--)
136
    {
137
138
        /* Copy word.  */
139
2383452
        *flash_address++ =  *source++;
140
    }
141
142
113454
    return(LX_SUCCESS);
143
}
144
145
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
146
UINT  _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count)
147
#else
148
1162
UINT  _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count)
149
#endif
150
{
151
152
ULONG   *pointer;
153
ULONG   words;
154
155
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
156
    LX_PARAMETER_NOT_USED(nor_flash);
157
#endif
158
    LX_PARAMETER_NOT_USED(erase_count);
159
160
    /* Setup pointer.  */
161
1162
    pointer =  (ULONG *) &nor_memory_area[block];
162
163
    /* Loop to erase block.  */
164
1162
    words =  sizeof(FLASH_BLOCK)/sizeof(ULONG);
165
2380938
    while (words--)
166
    {
167
168
        /* Erase word of block.  */
169
2379776
        *pointer++ =  (ULONG) 0xFFFFFFFF;
170
    }
171
172
1162
    return(LX_SUCCESS);
173
}
174
175
176
7
UINT  _lx_nor_flash_simulator_erase_all(VOID)
177
{
178
179
ULONG   *pointer;
180
ULONG   words;
181
182
183
    /* Setup pointer.  */
184
7
    pointer =  (ULONG *) &nor_memory_area[0];
185
186
    /* Loop to erase block.  */
187
7
    words =  sizeof(nor_memory_area)/(sizeof(ULONG));
188
114695
    while (words--)
189
    {
190
191
        /* Erase word of block.  */
192
114688
        *pointer++ =  (ULONG) 0xFFFFFFFF;
193
    }
194
195
7
    return(LX_SUCCESS);
196
}
197
198
199
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
200
UINT  _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block)
201
#else
202
4
UINT  _lx_nor_flash_simulator_block_erased_verify(ULONG block)
203
#endif
204
{
205
206
ULONG   *word_ptr;
207
ULONG   words;
208
209
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
210
    LX_PARAMETER_NOT_USED(nor_flash);
211
#endif
212
213
    /* Determine if the block is completely erased.  */
214
215
    /* Pickup the pointer to the first word of the block.  */
216
4
    word_ptr =  (ULONG *) &nor_memory_area[block].erase_count;
217
218
    /* Calculate the number of words in a block.  */
219
4
    words =  sizeof(FLASH_BLOCK)/sizeof(ULONG);
220
221
    /* Loop to check if the block is erased.  */
222
4106
    while (words--)
223
    {
224
225
        /* Is this word erased?  */
226
4104
        if (*word_ptr++ != 0xFFFFFFFF)
227
2
            return(LX_ERROR);
228
    }
229
230
    /* Return success.  */
231
2
    return(LX_SUCCESS);
232
}
233
234
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
235
UINT  _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector)
236
#else
237
UINT  _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector)
238
#endif
239
{
240
241
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
242
    LX_PARAMETER_NOT_USED(nor_flash);
243
#endif
244
    LX_PARAMETER_NOT_USED(error_code);
245
    LX_PARAMETER_NOT_USED(block);
246
    LX_PARAMETER_NOT_USED(sector);
247
248
    /* Custom processing goes here...  all errors are fatal.  */
249
    return(LX_ERROR);
250
}
251