nvs.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <string.h>
00023 #include <errno.h>
00024 #include <assert.h>
00025 #include <gpxe/nvs.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 int nvs_read ( struct nvs_device *nvs, unsigned int address,
00043 void *data, size_t len ) {
00044 size_t frag_len;
00045 int rc;
00046
00047
00048
00049
00050 assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
00051
00052 while ( len ) {
00053
00054
00055 frag_len = ( ( nvs->block_size -
00056 ( address & ( nvs->block_size - 1 ) ) )
00057 << nvs->word_len_log2 );
00058
00059
00060 if ( frag_len > len )
00061 frag_len = len;
00062
00063
00064 if ( ( rc = nvs->read ( nvs, address, data, frag_len ) ) != 0 )
00065 return rc;
00066
00067
00068 data += frag_len;
00069 address += ( frag_len >> nvs->word_len_log2 );
00070 len -= frag_len;
00071 }
00072
00073 return 0;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static int nvs_verify ( struct nvs_device *nvs, unsigned int address,
00086 const void *data, size_t len ) {
00087 uint8_t read_data[len];
00088 int rc;
00089
00090
00091 if ( ( rc = nvs_read ( nvs, address, read_data, len ) ) != 0 )
00092 return rc;
00093
00094
00095 if ( memcmp ( data, read_data, len ) != 0 ) {
00096 DBG ( "NVS %p verification failed at %#04x+%zd\n",
00097 nvs, address, len );
00098 return -EIO;
00099 }
00100
00101 return 0;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 int nvs_write ( struct nvs_device *nvs, unsigned int address,
00114 const void *data, size_t len ) {
00115 size_t frag_len;
00116 int rc;
00117
00118
00119
00120
00121 assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
00122
00123 while ( len ) {
00124
00125
00126 frag_len = ( ( nvs->block_size -
00127 ( address & ( nvs->block_size - 1 ) ) )
00128 << nvs->word_len_log2 );
00129
00130
00131 if ( frag_len > len )
00132 frag_len = len;
00133
00134
00135 if ( ( rc = nvs->write ( nvs, address, data, frag_len ) ) != 0)
00136 return rc;
00137
00138
00139 if ( ( rc = nvs_verify ( nvs, address, data, frag_len ) ) != 0)
00140 return rc;
00141
00142
00143 data += frag_len;
00144 address += ( frag_len >> nvs->word_len_log2 );
00145 len -= frag_len;
00146 }
00147
00148 return 0;
00149 }