Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: firmware/lib/vboot_nvstorage.c

Issue 6532040: Add NV storage API to vboot reference (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/vboot_reference.git@master
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « firmware/include/vboot_nvstorage.h ('k') | tests/Makefile » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 /* Non-volatile storage routines.
7 */
8
9 #include "utility.h"
10 #include "vboot_common.h"
11 #include "vboot_nvstorage.h"
12
13 /* Constants for NV storage. We use this rather than structs and
14 * bitfields so the data format is consistent across platforms and
15 * compilers. */
16 #define HEADER_OFFSET 0
17 #define HEADER_MASK 0xC0
18 #define HEADER_SIGNATURE 0x40
19 #define HEADER_FIRMWARE_SETTINGS_RESET 0x20
20 #define HEADER_KERNEL_SETTINGS_RESET 0x10
21
22 #define BOOT_OFFSET 1
23 #define BOOT_DEBUG_RESET_MODE 0x80
24 #define BOOT_TRY_B_COUNT 0x0F
25
26 #define RECOVERY_OFFSET 2
27 #define LOCALIZATION_OFFSET 3
28 #define KERNEL_FIELD_OFFSET 11
29 #define CRC_OFFSET 15
30
31
32 /* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. A
33 * table-based algorithm would be faster, but for only 15 bytes isn't
34 * worth the code size. */
35 static uint8_t Crc8(const uint8_t* data, int len) {
36 unsigned crc = 0;
37 int i, j;
38
39 for (j = len; j; j--, data++) {
40 crc ^= (*data << 8);
41 for(i = 8; i; i--) {
42 if (crc & 0x8000)
43 crc ^= (0x1070 << 3);
44 crc <<= 1;
45 }
46 }
47
48 return (uint8_t)(crc >> 8);
49 }
50
51
52 int VbNvOpen(VbNvContext* context) {
53 uint8_t* raw = context->raw;
54
55 /* TODO: implement locking when called from OS */
56
57 /* Nothing has changed yet. */
58 context->raw_changed = 0;
59 context->regenerate_crc = 0;
60
61 /* Check data for consistency */
62 if ((HEADER_SIGNATURE != (raw[HEADER_OFFSET] & HEADER_MASK))
63 || (Crc8(raw, CRC_OFFSET) != raw[CRC_OFFSET])) {
64
65 /* Data is inconsistent (bad CRC or header), so reset defaults */
66 Memset(raw, 0, NV_BLOCK_SIZE);
67 raw[HEADER_OFFSET] = (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
68 HEADER_KERNEL_SETTINGS_RESET);
69
70 /* Regenerate CRC on exit */
71 context->regenerate_crc = 1;
72 }
73
74 return 0;
75 }
76
77
78 int VbNvClose(VbNvContext* context) {
79
80 if (context->regenerate_crc) {
81 context->raw[CRC_OFFSET] = Crc8(context->raw, CRC_OFFSET);
82 context->regenerate_crc = 0;
83 context->raw_changed = 1;
84 }
85
86 /* TODO: implement locking when called from OS */
87 return 0;
88 }
89
90
91 int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest) {
92 const uint8_t* raw = context->raw;
93
94 switch (param) {
95 case VBNV_FIRMWARE_SETTINGS_RESET:
96 *dest = (raw[HEADER_OFFSET] & HEADER_FIRMWARE_SETTINGS_RESET ? 1 : 0);
97 return 0;
98
99 case VBNV_KERNEL_SETTINGS_RESET:
100 *dest = (raw[HEADER_OFFSET] & HEADER_KERNEL_SETTINGS_RESET ? 1 : 0);
101 return 0;
102
103 case VBNV_DEBUG_RESET_MODE:
104 *dest = (raw[BOOT_OFFSET] & BOOT_DEBUG_RESET_MODE ? 1 : 0);
105 return 0;
106
107 case VBNV_TRY_B_COUNT:
108 *dest = raw[BOOT_OFFSET] & BOOT_TRY_B_COUNT;
109 return 0;
110
111 case VBNV_RECOVERY_REQUEST:
112 *dest = raw[RECOVERY_OFFSET];
113 return 0;
114
115 case VBNV_LOCALIZATION_INDEX:
116 *dest = raw[LOCALIZATION_OFFSET];
117 return 0;
118
119 case VBNV_KERNEL_FIELD:
120 *dest = (raw[KERNEL_FIELD_OFFSET]
121 | (raw[KERNEL_FIELD_OFFSET + 1] << 8)
122 | (raw[KERNEL_FIELD_OFFSET + 2] << 16)
123 | (raw[KERNEL_FIELD_OFFSET + 3] << 24));
124 return 0;
125
126 default:
127 return 1;
128 }
129 }
130
131
132 int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value) {
133 uint8_t* raw = context->raw;
134 uint32_t current;
135
136 /* If we're not changing the value, we don't need to regenerate the CRC. */
137 if (0 == VbNvGet(context, param, &current) && current == value)
138 return 0;
139
140 switch (param) {
141 case VBNV_FIRMWARE_SETTINGS_RESET:
142 if (value)
143 raw[HEADER_OFFSET] |= HEADER_FIRMWARE_SETTINGS_RESET;
144 else
145 raw[HEADER_OFFSET] &= ~HEADER_FIRMWARE_SETTINGS_RESET;
146 break;
147
148 case VBNV_KERNEL_SETTINGS_RESET:
149 if (value)
150 raw[HEADER_OFFSET] |= HEADER_KERNEL_SETTINGS_RESET;
151 else
152 raw[HEADER_OFFSET] &= ~HEADER_KERNEL_SETTINGS_RESET;
153 break;
154
155 case VBNV_DEBUG_RESET_MODE:
156 if (value)
157 raw[BOOT_OFFSET] |= BOOT_DEBUG_RESET_MODE;
158 else
159 raw[BOOT_OFFSET] &= BOOT_DEBUG_RESET_MODE;
160 break;
161
162 case VBNV_TRY_B_COUNT:
163 raw[BOOT_OFFSET] &= ~BOOT_TRY_B_COUNT;
164 raw[BOOT_OFFSET] |= (uint8_t)(value & BOOT_TRY_B_COUNT);
165 break;
166
167 case VBNV_RECOVERY_REQUEST:
168 raw[RECOVERY_OFFSET] = (uint8_t)value;
169 break;
170
171 case VBNV_LOCALIZATION_INDEX:
172 raw[LOCALIZATION_OFFSET] = (uint8_t)value;
173 break;
174
175 case VBNV_KERNEL_FIELD:
176 raw[KERNEL_FIELD_OFFSET] = (uint8_t)(value);
177 raw[KERNEL_FIELD_OFFSET + 1] = (uint8_t)(value >> 8);
178 raw[KERNEL_FIELD_OFFSET + 2] = (uint8_t)(value >> 16);
179 raw[KERNEL_FIELD_OFFSET + 3] = (uint8_t)(value >> 24);
180 break;
181
182 default:
183 return 1;
184 }
185
186 /* Need to regenerate CRC, since the value changed. */
187 context->regenerate_crc = 1;
188 return 0;
189 }
OLDNEW
« no previous file with comments | « firmware/include/vboot_nvstorage.h ('k') | tests/Makefile » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698