GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_driver_read.c Lines: 28 30 93.3 %
Date: 2024-03-11 05:20:25 Branches: 18 20 90.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                                                           */
18
/**                                                                       */
19
/**************************************************************************/
20
/**************************************************************************/
21
22
#define LX_SOURCE_CODE
23
24
25
/* Disable ThreadX error checking.  */
26
27
#ifndef LX_DISABLE_ERROR_CHECKING
28
#define LX_DISABLE_ERROR_CHECKING
29
#endif
30
31
32
/* Include necessary system files.  */
33
34
#include "lx_api.h"
35
36
37
/**************************************************************************/
38
/*                                                                        */
39
/*  FUNCTION                                               RELEASE        */
40
/*                                                                        */
41
/*    _lx_nor_flash_extended_cache_read                  PORTABLE C       */
42
/*                                                           6.2.1       */
43
/*  AUTHOR                                                                */
44
/*                                                                        */
45
/*    William E. Lamie, Microsoft Corporation                             */
46
/*                                                                        */
47
/*  DESCRIPTION                                                           */
48
/*                                                                        */
49
/*    This function performs a read of the NOR flash memory.              */
50
/*                                                                        */
51
/*  INPUT                                                                 */
52
/*                                                                        */
53
/*    nor_flash                             NOR flash instance            */
54
/*    flash_address                         Address of NOR flash to read  */
55
/*    destination                           Destination for the read      */
56
/*    words                                 Number of words to read       */
57
/*                                                                        */
58
/*  OUTPUT                                                                */
59
/*                                                                        */
60
/*    return status                                                       */
61
/*                                                                        */
62
/*  CALLS                                                                 */
63
/*                                                                        */
64
/*    (lx_nor_flash_driver_read)            Actual driver read            */
65
/*                                                                        */
66
/*  CALLED BY                                                             */
67
/*                                                                        */
68
/*    Application Code                                                    */
69
/*                                                                        */
70
/*  RELEASE HISTORY                                                       */
71
/*                                                                        */
72
/*    DATE              NAME                      DESCRIPTION             */
73
/*                                                                        */
74
/*  05-19-2020     William E. Lamie         Initial Version 6.0           */
75
/*  09-30-2020     William E. Lamie         Modified comment(s),          */
76
/*                                            resulting in version 6.1    */
77
/*  06-02-2021     Bhupendra Naphade        Modified comment(s),          */
78
/*                                            resulting in version 6.1.7  */
79
/*  03-08-2023     Xiuwen Cai               Modified comment(s),          */
80
/*                                            added new driver interface, */
81
/*                                            resulting in version 6.2.1 */
82
/*                                                                        */
83
/**************************************************************************/
84
361155
UINT  _lx_nor_flash_driver_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words)
85
{
86
#ifndef LX_NOR_DISABLE_EXTENDED_CACHE
87
88
UINT    status;
89
UINT    i;
90
ULONG   *cache_entry_start;
91
ULONG   *cache_entry_end;
92
ULONG   cache_offset;
93
UINT    least_used_cache_entry;
94
95
96
    /* Is the request a whole sector or a partial sector.  */
97

361155
    if ((words == 1) && (nor_flash -> lx_nor_flash_extended_cache_entries))
98
    {
99
100
        /* One word request, which implies that it is a NOR flash metadata read.  */
101
102
103
        /* Initialize the least used cache entry.  */
104
172242
        least_used_cache_entry =  0;
105
106
        do
107
        {
108
109
            /* Loop through the cache entries to see if there is a sector in cache.  */
110
515018
            for (i = 0; i < nor_flash -> lx_nor_flash_extended_cache_entries; i++)
111
            {
112
113
                /* Search through the cache to find the entry.  */
114
115
                /* Determine the cache entry addresses.  */
116
498870
                cache_entry_start =  nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_address;
117
498870
                cache_entry_end =    cache_entry_start + LX_NOR_SECTOR_SIZE;
118
119
                /* Determine if the flash address in in the cache entry.  */
120

498870
                if ((cache_entry_start) && (flash_address >= cache_entry_start) && (flash_address < cache_entry_end))
121
                {
122
123
                    /* Yes, we found the entry.  */
124
125
                    /* Increment the accessed count.  */
126
172242
                    nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_access_count++;
127
128
                    /* Calculate the offset into the cache entry.  */
129
172242
                    cache_offset =  (ULONG)(flash_address - cache_entry_start);
130
131
                    /* Copy the word from the cache.  */
132
172242
                    *destination =  *(nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_memory + cache_offset);
133
134
                    /* Increment the number of cache hits.  */
135
172242
                    nor_flash -> lx_nor_flash_extended_cache_hits++;
136
137
                    /* Return success.  */
138
172242
                    return(LX_SUCCESS);
139
                }
140
                else
141
                {
142
143
                    /* Determine if we have a new least used sector.  */
144
326628
                    if (i != least_used_cache_entry)
145
                    {
146
147
                        /* Determine if this entry has a smaller accessed count.  */
148
192865
                        if (nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_access_count <
149
192865
                            nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_access_count)
150
                        {
151
152
                            /* New least used entry.  */
153
68961
                            least_used_cache_entry =  i;
154
                        }
155
                    }
156
                }
157
            }
158
159
            /* Now read in the sector into the cache.  */
160
16148
            cache_offset =  (ULONG)(flash_address - nor_flash -> lx_nor_flash_base_address);
161
16148
            cache_offset =  cache_offset & ~((ULONG) (LX_NOR_SECTOR_SIZE-1));
162
16148
            cache_entry_start =  nor_flash -> lx_nor_flash_base_address + cache_offset;
163
164
            /* Call the actual driver read function.  */
165
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
166
            status =  (nor_flash -> lx_nor_flash_driver_read)(nor_flash, cache_entry_start,
167
                            nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_memory,
168
                            LX_NOR_SECTOR_SIZE);
169
#else
170
16148
            status =  (nor_flash -> lx_nor_flash_driver_read)(cache_entry_start,
171
                            nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_memory,
172
                            LX_NOR_SECTOR_SIZE);
173
#endif
174
175
            /* Determine if there was an error.  */
176
16148
            if (status != LX_SUCCESS)
177
            {
178
179
                /* Return the error to the caller.  */
180
                return(status);
181
            }
182
183
            /* Setup the cache entry.  */
184
16148
            nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_address =  cache_entry_start;
185
16148
            nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_access_count =    0;
186
187
            /* Increment the number of cache misses.  */
188
16148
            nor_flash -> lx_nor_flash_extended_cache_misses++;
189
190
            /* Decrement the number of cache hits, so that the increment that will happen next will be cancelled out.  */
191
16148
            nor_flash -> lx_nor_flash_extended_cache_hits--;
192
193
16148
        } while (status == LX_SUCCESS);
194
195
        /* Return success.  */
196
        return(LX_SUCCESS);
197
    }
198
    else
199
    {
200
201
        /* Call the actual driver read function.  */
202
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
203
        status =  (nor_flash -> lx_nor_flash_driver_read)(nor_flash, flash_address, destination, words);
204
#else
205
188913
        status =  (nor_flash -> lx_nor_flash_driver_read)(flash_address, destination, words);
206
#endif
207
208
        /* Return completion status.  */
209
188913
        return(status);
210
    }
211
#else
212
UINT    status;
213
214
215
    /* Call the actual driver read function.  */
216
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
217
    status =  (nor_flash -> lx_nor_flash_driver_read)(nor_flash, flash_address, destination, words);
218
#else
219
    status =  (nor_flash -> lx_nor_flash_driver_read)(flash_address, destination, words);
220
#endif
221
222
    /* Return completion status.  */
223
    return(status);
224
#endif
225
}
226
227