acpi: Add IORT helper functions
[coreboot2.git] / util / cbfstool / common.c
blob7154bc9d54254d641fee4de2902ddcb629780cb7
1 /* common utility functions for cbfstool */
2 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <strings.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <libgen.h>
12 #include "common.h"
13 #include "cbfs.h"
15 /* Utilities */
16 int verbose = 0;
18 static off_t get_file_size(FILE *f)
20 off_t fsize;
21 fseek(f, 0, SEEK_END);
22 fsize = ftell(f);
23 fseek(f, 0, SEEK_SET);
24 return fsize;
27 /* Buffer and file I/O */
28 int buffer_create(struct buffer *buffer, size_t size, const char *name)
30 buffer->name = strdup(name);
31 buffer->offset = 0;
32 buffer->size = size;
33 buffer->data = (char *)malloc(buffer->size);
34 if (!buffer->data) {
35 fprintf(stderr, "buffer_create: Insufficient memory (0x%zx).\n",
36 size);
37 if (buffer->name) {
38 free(buffer->name);
39 buffer->name = NULL;
41 return -1;
43 return 0;
46 int buffer_from_file_aligned_size(struct buffer *buffer, const char *filename,
47 size_t size_granularity)
49 FILE *fp = fopen(filename, "rb");
50 if (!fp) {
51 perror(filename);
52 return -1;
54 off_t file_size = get_file_size(fp);
55 if (file_size < 0) {
56 fprintf(stderr, "could not determine size of %s\n", filename);
57 fclose(fp);
58 return -1;
60 if (buffer_create(buffer, ALIGN_UP(file_size, size_granularity), filename)) {
61 fprintf(stderr, "could not allocate buffer\n");
62 fclose(fp);
63 return -1;
65 if (fread(buffer->data, 1, file_size, fp) != (size_t)file_size) {
66 fprintf(stderr, "incomplete read: %s\n", filename);
67 fclose(fp);
68 buffer_delete(buffer);
69 return -1;
71 fclose(fp);
73 if (buffer->size > (size_t)file_size)
74 memset(buffer->data + file_size, 0xff, buffer->size - file_size);
76 return 0;
79 int buffer_from_file(struct buffer *buffer, const char *filename)
81 return buffer_from_file_aligned_size(buffer, filename, 1);
84 int buffer_write_file(struct buffer *buffer, const char *filename)
86 FILE *fp = fopen(filename, "wb");
87 if (!fp) {
88 perror(filename);
89 return -1;
91 assert(buffer && buffer->data);
92 if (fwrite(buffer->data, 1, buffer->size, fp) != buffer->size) {
93 fprintf(stderr, "incomplete write: %s\n", filename);
94 fclose(fp);
95 return -1;
97 fclose(fp);
98 return 0;
101 void buffer_delete(struct buffer *buffer)
103 assert(buffer);
104 if (buffer->name) {
105 free(buffer->name);
106 buffer->name = NULL;
108 if (buffer->data) {
109 free(buffer_get_original_backing(buffer));
110 buffer->data = NULL;
112 buffer->offset = 0;
113 buffer->size = 0;
116 static struct {
117 uint32_t arch;
118 const char *name;
119 } arch_names[] = {
120 { CBFS_ARCHITECTURE_AARCH64, "arm64" },
121 { CBFS_ARCHITECTURE_ARM, "arm" },
122 { CBFS_ARCHITECTURE_MIPS, "mips" },
123 { CBFS_ARCHITECTURE_PPC64, "ppc64" },
124 /* power8 is a reasonable alias */
125 { CBFS_ARCHITECTURE_PPC64, "power8" },
126 { CBFS_ARCHITECTURE_RISCV, "riscv" },
127 { CBFS_ARCHITECTURE_X86, "x86" },
128 { CBFS_ARCHITECTURE_UNKNOWN, "unknown" }
131 uint32_t string_to_arch(const char *arch_string)
133 size_t i;
134 uint32_t ret = CBFS_ARCHITECTURE_UNKNOWN;
136 for (i = 0; i < ARRAY_SIZE(arch_names); i++) {
137 if (!strcasecmp(arch_string, arch_names[i].name)) {
138 ret = arch_names[i].arch;
139 break;
143 return ret;
146 const char *arch_to_string(uint32_t a)
148 size_t i;
149 const char *ret = NULL;
151 for (i = 0; i < ARRAY_SIZE(arch_names); i++) {
152 if (a == arch_names[i].arch) {
153 ret = arch_names[i].name;
154 break;
158 return ret;
161 void print_supported_architectures(void)
163 size_t i;
165 for (i = 0; i < ARRAY_SIZE(arch_names); i++) {
166 printf(i == 0? " ":", ");
167 printf("%s", arch_names[i].name);
170 printf("\n");
173 void print_supported_filetypes(void)
175 int i;
177 for (i=0; filetypes[i].name; i++) {
178 printf(" %s%c", filetypes[i].name, filetypes[i + 1].name ? ',' : '\n');
179 if ((i%8) == 7)
180 printf("\n");
184 uint64_t intfiletype(const char *name)
186 size_t i;
187 for (i = 0; filetypes[i].name; i++)
188 if (strcmp(filetypes[i].name, name) == 0)
189 return filetypes[i].type;
190 return -1;
193 char *bintohex(uint8_t *data, size_t len)
195 static const char translate[16] = "0123456789abcdef";
197 char *result = malloc(len * 2 + 1);
198 if (result == NULL)
199 return NULL;
201 result[len*2] = '\0';
202 unsigned int i;
203 for (i = 0; i < len; i++) {
204 result[i*2] = translate[(data[i] >> 4) & 0xf];
205 result[i*2+1] = translate[data[i] & 0xf];
207 return result;