storage.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #include "storage.h" 4 5 #include <assert.h> 6 #include <stdio.h> 7 8 #include "commonlib/bsd/compiler.h" 9 #include "fmap.h" 10 11 #include "fv.h" 12 #include "utils.h" 13 14 bool storage_open(const char store_file[], struct storage_t *storage, bool rw) 15 { 16 storage->rw = rw; 17 18 storage->file = map_file(store_file, rw); 19 if (storage->file.start == NULL) { 20 fprintf(stderr, "Failed to load smm-store-file \"%s\"\n", 21 store_file); 22 return false; 23 } 24 25 /* If we won't find FMAP with SMMSTORE, use the whole file, but fail if 26 * FMAP is there without SMMSTORE. */ 27 storage->region = storage->file; 28 29 long fmap_offset = fmap_find(storage->file.start, storage->file.length); 30 if (fmap_offset >= 0) { 31 struct fmap *fmap = (void *)(storage->file.start + fmap_offset); 32 const struct fmap_area *area = fmap_find_area(fmap, "SMMSTORE"); 33 if (area == NULL) { 34 fprintf(stderr, 35 "Found FMAP without SMMSTORE in \"%s\"\n", 36 store_file); 37 return false; 38 } 39 40 storage->region.start += area->offset; 41 storage->region.length = area->size; 42 } 43 44 bool auth_vars; 45 if (!fv_parse(storage->region, &storage->store_area, &auth_vars)) { 46 if (!rw) { 47 fprintf(stderr, 48 "Failed to find variable store in \"%s\"\n", 49 store_file); 50 goto error; 51 } 52 53 fprintf(stderr, 54 "\nThe variable store has not been found in the ROM image\n" 55 "and is about to be initialized. This situation is normal\n" 56 "for a release image, as the variable store is usually\n" 57 "initialized on the first boot of the platform.\n\n"); 58 59 if (!fv_init(storage->region)) { 60 fprintf(stderr, 61 "Failed to create variable store in \"%s\"\n", 62 store_file); 63 goto error; 64 } 65 66 if (!fv_parse(storage->region, &storage->store_area, &auth_vars)) { 67 fprintf(stderr, 68 "Failed to parse newly formatted store in \"%s\"\n", 69 store_file); 70 goto error; 71 } 72 73 fprintf(stderr, 74 "Successfully created variable store in \"%s\"\n", 75 store_file); 76 } 77 78 storage->vs = vs_load(storage->store_area, auth_vars); 79 return true; 80 81 error: 82 unmap_file(storage->file); 83 return false; 84 } 85 86 bool storage_write_back(struct storage_t *storage) 87 { 88 assert(storage->rw && "Only RW storage can be updated."); 89 90 bool success = vs_store(&storage->vs, storage->store_area); 91 if (!success) 92 fprintf(stderr, "Failed to update variable store\n"); 93 storage_drop(storage); 94 return success; 95 } 96 97 void storage_drop(struct storage_t *storage) 98 { 99 unmap_file(storage->file); 100 vs_free(&storage->vs); 101 }