1 /* 2 * Common Hardware Reference Platform NVRAM helper functions. 3 * 4 * The CHRP NVRAM layout is used by OpenBIOS and SLOF. See CHRP 5 * specification, chapter 8, or the LoPAPR specification for details 6 * about the NVRAM layout. 7 * 8 * This code is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published 10 * by the Free Software Foundation; either version 2 of the License, 11 * or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "qemu/cutils.h" 24 #include "qemu/error-report.h" 25 #include "hw/nvram/chrp_nvram.h" 26 #include "sysemu/sysemu.h" 27 28 static int chrp_nvram_set_var(uint8_t *nvram, int addr, const char *str, 29 int max_len) 30 { 31 int len; 32 33 len = strlen(str) + 1; 34 35 if (max_len < len) { 36 return -1; 37 } 38 39 memcpy(&nvram[addr], str, len); 40 41 return addr + len; 42 } 43 44 /** 45 * Create a "system partition", used for the Open Firmware 46 * environment variables. 47 */ 48 int chrp_nvram_create_system_partition(uint8_t *data, int min_len, int max_len) 49 { 50 ChrpNvramPartHdr *part_header; 51 unsigned int i; 52 int end; 53 54 if (max_len < sizeof(*part_header)) { 55 goto fail; 56 } 57 58 part_header = (ChrpNvramPartHdr *)data; 59 part_header->signature = CHRP_NVPART_SYSTEM; 60 pstrcpy(part_header->name, sizeof(part_header->name), "system"); 61 62 end = sizeof(ChrpNvramPartHdr); 63 for (i = 0; i < nb_prom_envs; i++) { 64 end = chrp_nvram_set_var(data, end, prom_envs[i], max_len - end); 65 if (end == -1) { 66 goto fail; 67 } 68 } 69 70 /* End marker */ 71 data[end++] = '\0'; 72 73 end = (end + 15) & ~15; 74 /* XXX: OpenBIOS is not able to grow up a partition. Leave some space for 75 new variables. */ 76 if (end < min_len) { 77 end = min_len; 78 } 79 chrp_nvram_finish_partition(part_header, end); 80 81 return end; 82 83 fail: 84 error_report("NVRAM is too small. Try to pass less data to -prom-env"); 85 exit(EXIT_FAILURE); 86 } 87 88 /** 89 * Create a "free space" partition 90 */ 91 int chrp_nvram_create_free_partition(uint8_t *data, int len) 92 { 93 ChrpNvramPartHdr *part_header; 94 95 part_header = (ChrpNvramPartHdr *)data; 96 part_header->signature = CHRP_NVPART_FREE; 97 pstrcpy(part_header->name, sizeof(part_header->name), "free"); 98 99 chrp_nvram_finish_partition(part_header, len); 100 101 return len; 102 } 103