Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openhackware / src / libexec / core.c
1 /*
2  * <file.c>
3  *
4  * Open Hack'Ware BIOS executable file loader
5  * 
6  * Copyright (c) 2004-2005 Jocelyn Mayer
7  * 
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License V2
10  *   as published by the Free Software Foundation
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include "bios.h"
25 #include "exec.h"
26
27 /*****************************************************************************/
28 uint32_t file_seek (inode_t *file, uint32_t pos)
29 {
30     uint32_t blocsize, bloc, offset;
31
32     if (file == NULL)
33         return -1;
34     blocsize = part_blocsize(fs_inode_get_part(file));
35     bloc = pos / blocsize;
36     offset = pos % blocsize;
37
38     return fs_seek(file, bloc, offset);
39 }
40
41 /*****************************************************************************/
42 /* Executable file loaders */
43
44 enum {
45     FILE_TYPE_ELF = 0,
46     FILE_TYPE_XCOFF,
47     FILE_TYPE_MACHO,
48     FILE_TYPE_PEF,
49     FILE_TYPE_CHRP,
50     FILE_TYPE_PREP,
51     FILE_TYPE_FLAT,
52 };
53
54 uint32_t fs_inode_get_size (inode_t *inode);
55 unsigned int part_get_entry (part_t *part);
56 /*****************************************************************************/
57 /* Generic boot file loader */
58 int _bootfile_load (inode_t *file, void **dest, void **entry, void **end,
59                     uint32_t loffset, int type)
60 {
61     int (*do_load)(inode_t *file, void **dest, void **entry, void **end,
62                    uint32_t loffset);
63     uint32_t size;
64     int ret;
65     int i;
66
67     if (type == -1)
68         i = 0;
69     else
70         i = type;
71     for (;; i++) {
72         switch (i) {
73         case FILE_TYPE_ELF:
74             do_load = &exec_load_elf;
75             break;
76         case FILE_TYPE_XCOFF:
77             do_load = &exec_load_xcoff;
78             break;
79         case FILE_TYPE_MACHO:
80             do_load = &exec_load_macho;
81             break;
82         case FILE_TYPE_PEF:
83             do_load = &exec_load_pef;
84             break;
85         case FILE_TYPE_CHRP:
86             do_load = &exec_load_chrp;
87             break;
88         case FILE_TYPE_PREP:
89             do_load = &exec_load_prep;
90             break;
91         default:
92             if (*dest == NULL)
93                 *dest = (void *)DEFAULT_LOAD_DEST;
94             if (*entry == NULL) {
95                 if (part_get_entry(fs_inode_get_part(file)) != 0 || 1) {
96                     *entry = (char *)*dest +
97                         part_get_entry(fs_inode_get_part(file));
98                     dprintf("dest %p entry %08x => %p\n",
99                             *dest, part_get_entry(fs_inode_get_part(file)),
100                             *entry);
101                 } else {
102                     *entry = *dest + 0xC;
103                 }
104             }
105             size = fs_inode_get_size(file);
106             *end = (char *)*dest + size - loffset;
107             printf("Load raw file into memory at %p %d (%08x) %d (%08x)\n",
108                    *dest, size, size, loffset, loffset);
109             file_seek(file, loffset);
110             set_loadinfo(*dest, size);
111             if ((uint32_t)fs_read(file, *dest, size) != size) {
112                 ERROR("Error loading file...\n");
113                 ret = -1;
114             } else {
115                 ret = 0;
116             }
117             goto out;
118         }
119         DPRINTF("Check file type %d at offset %d %p\n", i, loffset, do_load);
120         ret = (*do_load)(file, dest, entry, end, loffset);
121         if (ret >= -1 || type == i) {
122             if (type == i)
123                 ret = -2;
124             break;
125         }
126     }
127  out:
128
129     return ret;
130 }
131
132 int bootfile_load (void **dest, void **entry, void **end,
133                    part_t *part, int type, const unsigned char *fname,
134                    uint32_t loffset)
135 {
136     inode_t *file;
137     int ret;
138
139     DPRINTF("Load file '%s' %p %p type: %d offset: %0x => %d %p\n",
140             fname, part, part_fs(part), type, loffset, part_blocsize(part), *dest);
141     if (fname == NULL)
142         file = fs_get_bootfile(part_fs(part));
143     else
144         file = fs_open(part_fs(part), fname);
145     if (file == NULL)
146         return -1;
147     ret = _bootfile_load(file, dest, entry, end, loffset, type);
148     fs_close(file);
149
150     return ret;
151 }