]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/boot/common/bootstrap.h
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / sys / boot / common / bootstrap.h
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include <sys/types.h>
30 #include <sys/queue.h>
31 #include <sys/linker_set.h>
32
33 /*
34  * Generic device specifier; architecture-dependant 
35  * versions may be larger, but should be allowed to
36  * overlap.
37  */
38 struct devdesc 
39 {
40     struct devsw        *d_dev;
41     int                 d_type;
42 #define DEVT_NONE       0
43 #define DEVT_DISK       1
44 #define DEVT_NET        2
45 #define DEVT_CD         3
46 #define DEVT_ZFS        4
47     int                 d_unit;
48 };
49
50 /* Commands and return values; nonzero return sets command_errmsg != NULL */
51 typedef int     (bootblk_cmd_t)(int argc, char *argv[]);
52 extern char     *command_errmsg;        
53 extern char     command_errbuf[];       /* XXX blah, length */
54 #define CMD_OK          0
55 #define CMD_ERROR       1
56
57 /* interp.c */
58 void    interact(void);
59 int     include(const char *filename);
60
61 /* interp_backslash.c */
62 char    *backslash(char *str);
63
64 /* interp_parse.c */
65 int     parse(int *argc, char ***argv, char *str);
66
67 /* interp_forth.c */
68 void    bf_init(void);
69 int     bf_run(char *line);
70
71 /* boot.c */
72 int     autoboot(int timeout, char *prompt);
73 void    autoboot_maybe(void);
74 int     getrootmount(char *rootdev);
75
76 /* misc.c */
77 char    *unargv(int argc, char *argv[]);
78 void    hexdump(caddr_t region, size_t len);
79 size_t  strlenout(vm_offset_t str);
80 char    *strdupout(vm_offset_t str);
81 void    kern_bzero(vm_offset_t dest, size_t len);
82 int     kern_pread(int fd, vm_offset_t dest, size_t len, off_t off);
83 void    *alloc_pread(int fd, off_t off, size_t len);
84
85 /* bcache.c */
86 int     bcache_init(u_int nblks, size_t bsize);
87 void    bcache_flush(void);
88 int     bcache_strategy(void *devdata, int unit, int rw, daddr_t blk,
89                         size_t size, char *buf, size_t *rsize);
90
91 /*
92  * Disk block cache
93  */
94 struct bcache_devdata
95 {
96     int         (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize);
97     void        *dv_devdata;
98 };
99
100 /*
101  * Modular console support.
102  */
103 struct console 
104 {
105     const char  *c_name;
106     const char  *c_desc;
107     int         c_flags;
108 #define C_PRESENTIN     (1<<0)
109 #define C_PRESENTOUT    (1<<1)
110 #define C_ACTIVEIN      (1<<2)
111 #define C_ACTIVEOUT     (1<<3)
112     void        (* c_probe)(struct console *cp);        /* set c_flags to match hardware */
113     int         (* c_init)(int arg);                    /* reinit XXX may need more args */
114     void        (* c_out)(int c);                       /* emit c */
115     int         (* c_in)(void);                         /* wait for and return input */
116     int         (* c_ready)(void);                      /* return nonzer if input waiting */
117 };
118 extern struct console   *consoles[];
119 void            cons_probe(void);
120
121 /*
122  * Plug-and-play enumerator/configurator interface.
123  */
124 struct pnphandler 
125 {
126     const char  *pp_name;               /* handler/bus name */
127     void        (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */
128 };
129
130 struct pnpident
131 {
132     char                        *id_ident;      /* ASCII identifier, actual format varies with bus/handler */
133     STAILQ_ENTRY(pnpident)      id_link;
134 };
135
136 struct pnpinfo
137 {
138     char                        *pi_desc;       /* ASCII description, optional */
139     int                         pi_revision;    /* optional revision (or -1) if not supported */
140     char                        *pi_module;     /* module/args nominated to handle device */
141     int                         pi_argc;        /* module arguments */
142     char                        **pi_argv;
143     struct pnphandler           *pi_handler;    /* handler which detected this device */
144     STAILQ_HEAD(,pnpident)      pi_ident;       /* list of identifiers */
145     STAILQ_ENTRY(pnpinfo)       pi_link;
146 };
147
148 STAILQ_HEAD(pnpinfo_stql, pnpinfo);
149
150 extern struct pnpinfo_stql pnp_devices;
151
152 extern struct pnphandler        *pnphandlers[];         /* provided by MD code */
153
154 void                    pnp_addident(struct pnpinfo *pi, char *ident);
155 struct pnpinfo          *pnp_allocinfo(void);
156 void                    pnp_freeinfo(struct pnpinfo *pi);
157 void                    pnp_addinfo(struct pnpinfo *pi);
158 char                    *pnp_eisaformat(u_int8_t *data);
159
160 /*
161  *  < 0 - No ISA in system
162  * == 0 - Maybe ISA, search for read data port
163  *  > 0 - ISA in system, value is read data port address
164  */
165 extern int                      isapnp_readport;
166
167 /*
168  * Preloaded file metadata header.
169  *
170  * Metadata are allocated on our heap, and copied into kernel space
171  * before executing the kernel.
172  */
173 struct file_metadata 
174 {
175     size_t                      md_size;
176     u_int16_t                   md_type;
177     struct file_metadata        *md_next;
178     char                        md_data[1];     /* data are immediately appended */
179 };
180
181 struct preloaded_file;
182 struct mod_depend;
183
184 struct kernel_module
185 {
186     char                        *m_name;        /* module name */
187     int                         m_version;      /* module version */
188 /*    char                      *m_args;*/      /* arguments for the module */
189     struct preloaded_file       *m_fp;
190     struct kernel_module        *m_next;
191 };
192
193 /*
194  * Preloaded file information. Depending on type, file can contain
195  * additional units called 'modules'.
196  *
197  * At least one file (the kernel) must be loaded in order to boot.
198  * The kernel is always loaded first.
199  *
200  * String fields (m_name, m_type) should be dynamically allocated.
201  */
202 struct preloaded_file
203 {
204     char                        *f_name;        /* file name */
205     char                        *f_type;        /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
206     char                        *f_args;        /* arguments for the file */
207     struct file_metadata        *f_metadata;    /* metadata that will be placed in the module directory */
208     int                         f_loader;       /* index of the loader that read the file */
209     vm_offset_t                 f_addr;         /* load address */
210     size_t                      f_size;         /* file size */
211     struct kernel_module        *f_modules;     /* list of modules if any */
212     struct preloaded_file       *f_next;        /* next file */
213 };
214
215 struct file_format
216 {
217     /* Load function must return EFTYPE if it can't handle the module supplied */
218     int         (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result);
219     /* Only a loader that will load a kernel (first module) should have an exec handler */
220     int         (* l_exec)(struct preloaded_file *mp);
221 };
222
223 extern struct file_format       *file_formats[];        /* supplied by consumer */
224 extern struct preloaded_file    *preloaded_files;
225
226 int                     mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]);
227 int                     mod_loadkld(const char *name, int argc, char *argv[]);
228
229 struct preloaded_file *file_alloc(void);
230 struct preloaded_file *file_findfile(char *name, char *type);
231 struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
232 void file_discard(struct preloaded_file *fp);
233 void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
234 int  file_addmodule(struct preloaded_file *fp, char *modname, int version,
235         struct kernel_module **newmp);
236
237 /* MI module loaders */
238 #ifdef __elfN
239 /* Relocation types. */
240 #define ELF_RELOC_REL   1
241 #define ELF_RELOC_RELA  2
242
243 /* Relocation offset for some architectures */
244 extern u_int64_t __elfN(relocation_offset);
245
246 struct elf_file;
247 typedef Elf_Addr (symaddr_fn)(struct elf_file *ef, Elf_Size symidx);
248
249 int     __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result);
250 int     __elfN(obj_loadfile)(char *filename, u_int64_t dest,
251             struct preloaded_file **result);
252 int     __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr,
253             const void *reldata, int reltype, Elf_Addr relbase,
254             Elf_Addr dataaddr, void *data, size_t len);
255 #endif
256
257 /*
258  * Support for commands 
259  */
260 struct bootblk_command 
261 {
262     const char          *c_name;
263     const char          *c_desc;
264     bootblk_cmd_t       *c_fn;
265 };
266
267 #define COMMAND_SET(tag, key, desc, func)                               \
268     static bootblk_cmd_t func;                                          \
269     static struct bootblk_command _cmd_ ## tag = { key, desc, func };   \
270     DATA_SET(Xcommand_set, _cmd_ ## tag)
271
272 SET_DECLARE(Xcommand_set, struct bootblk_command);
273
274 /* 
275  * The intention of the architecture switch is to provide a convenient
276  * encapsulation of the interface between the bootstrap MI and MD code.
277  * MD code may selectively populate the switch at runtime based on the
278  * actual configuration of the target system.
279  */
280 struct arch_switch
281 {
282     /* Automatically load modules as required by detected hardware */
283     int         (*arch_autoload)(void);
284     /* Locate the device for (name), return pointer to tail in (*path) */
285     int         (*arch_getdev)(void **dev, const char *name, const char **path);
286     /* Copy from local address space to module address space, similar to bcopy() */
287     ssize_t     (*arch_copyin)(const void *src, vm_offset_t dest,
288                                const size_t len);
289     /* Copy to local address space from module address space, similar to bcopy() */
290     ssize_t     (*arch_copyout)(const vm_offset_t src, void *dest,
291                                 const size_t len);
292     /* Read from file to module address space, same semantics as read() */
293     ssize_t     (*arch_readin)(const int fd, vm_offset_t dest,
294                                const size_t len);
295     /* Perform ISA byte port I/O (only for systems with ISA) */
296     int         (*arch_isainb)(int port);
297     void        (*arch_isaoutb)(int port, int value);
298     /* Pass in initial kernel memory size */
299     void        (*arch_maphint)(vm_offset_t va, size_t len);    
300 };
301 extern struct arch_switch archsw;
302
303 /* This must be provided by the MD code, but should it be in the archsw? */
304 void    delay(int delay);
305
306 void    dev_cleanup(void);
307
308 time_t  time(time_t *tloc);