Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / seabios / src / romfile.c
1 // Access to pseudo "file" interface for configuration information.
2 //
3 // Copyright (C) 2012  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6
7 #include "config.h" // CONFIG_*
8 #include "malloc.h" // free
9 #include "output.h" // dprintf
10 #include "romfile.h" // struct romfile_s
11 #include "string.h" // memcmp
12
13 static struct romfile_s *RomfileRoot VARVERIFY32INIT;
14
15 void
16 romfile_add(struct romfile_s *file)
17 {
18     dprintf(3, "Add romfile: %s (size=%d)\n", file->name, file->size);
19     file->next = RomfileRoot;
20     RomfileRoot = file;
21 }
22
23 // Search for the specified file.
24 static struct romfile_s *
25 __romfile_findprefix(const char *prefix, int prefixlen, struct romfile_s *prev)
26 {
27     struct romfile_s *cur = RomfileRoot;
28     if (prev)
29         cur = prev->next;
30     while (cur) {
31         if (memcmp(prefix, cur->name, prefixlen) == 0)
32             return cur;
33         cur = cur->next;
34     }
35     return NULL;
36 }
37
38 struct romfile_s *
39 romfile_findprefix(const char *prefix, struct romfile_s *prev)
40 {
41     return __romfile_findprefix(prefix, strlen(prefix), prev);
42 }
43
44 struct romfile_s *
45 romfile_find(const char *name)
46 {
47     return __romfile_findprefix(name, strlen(name) + 1, NULL);
48 }
49
50 // Helper function to find, malloc_tmphigh, and copy a romfile.  This
51 // function adds a trailing zero to the malloc'd copy.
52 void *
53 romfile_loadfile(const char *name, int *psize)
54 {
55     struct romfile_s *file = romfile_find(name);
56     if (!file)
57         return NULL;
58
59     int filesize = file->size;
60     if (!filesize)
61         return NULL;
62
63     char *data = malloc_tmphigh(filesize+1);
64     if (!data) {
65         warn_noalloc();
66         return NULL;
67     }
68
69     dprintf(5, "Copying romfile '%s' (len %d)\n", name, filesize);
70     int ret = file->copy(file, data, filesize);
71     if (ret < 0) {
72         free(data);
73         return NULL;
74     }
75     if (psize)
76         *psize = filesize;
77     data[filesize] = '\0';
78     return data;
79 }
80
81 // Attempt to load an integer from the given file - return 'defval'
82 // if unsuccessful.
83 u64
84 romfile_loadint(const char *name, u64 defval)
85 {
86     struct romfile_s *file = romfile_find(name);
87     if (!file)
88         return defval;
89
90     int filesize = file->size;
91     if (!filesize || filesize > sizeof(u64) || (filesize & (filesize-1)))
92         // Doesn't look like a valid integer.
93         return defval;
94
95     u64 val = 0;
96     int ret = file->copy(file, &val, sizeof(val));
97     if (ret < 0)
98         return defval;
99     return val;
100 }