chrp_nvram.c (2764B)
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 28static 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 */ 48int 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 83fail: 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 */ 91int 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}