bootstrap.h revision 65614
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: head/sys/boot/common/bootstrap.h 65614 2000-09-08 16:51:29Z dcs $
27 */
28
29#include <sys/types.h>
30#include <sys/queue.h>
31
32/*
33 * Generic device specifier; architecture-dependant
34 * versions may be larger, but should be allowed to
35 * overlap.
36 */
37struct devdesc
38{
39    struct devsw	*d_dev;
40    int			d_type;
41#define DEVT_NONE	0
42#define DEVT_DISK	1
43#define DEVT_NET	2
44};
45
46/* Commands and return values; nonzero return sets command_errmsg != NULL */
47typedef int	(bootblk_cmd_t)(int argc, char *argv[]);
48extern char	*command_errmsg;
49extern char	command_errbuf[];	/* XXX blah, length */
50#define CMD_OK		0
51#define CMD_ERROR	1
52
53/* interp.c */
54void	interact(void);
55int	include(const char *filename);
56
57/* interp_backslash.c */
58char	*backslash(char *str);
59
60/* interp_parse.c */
61int	parse(int *argc, char ***argv, char *str);
62
63/* interp_forth.c */
64void	bf_init(void);
65int	bf_run(char *line);
66
67/* boot.c */
68int	autoboot(int timeout, char *prompt);
69void	autoboot_maybe(void);
70int	getrootmount(char *rootdev);
71
72/* misc.c */
73char	*unargv(int argc, char *argv[]);
74void	hexdump(caddr_t region, size_t len);
75size_t	strlenout(vm_offset_t str);
76char	*strdupout(vm_offset_t str);
77
78/* bcache.c */
79int	bcache_init(u_int nblks, size_t bsize);
80void	bcache_flush(void);
81int	bcache_strategy(void *devdata, int unit, int rw, daddr_t blk,
82			size_t size, char *buf, size_t *rsize);
83
84/*
85 * Disk block cache
86 */
87struct bcache_devdata
88{
89    int         (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize);
90    void	*dv_devdata;
91};
92
93/*
94 * Modular console support.
95 */
96struct console
97{
98    const char	*c_name;
99    const char	*c_desc;
100    int		c_flags;
101#define C_PRESENTIN	(1<<0)
102#define C_PRESENTOUT	(1<<1)
103#define C_ACTIVEIN	(1<<2)
104#define C_ACTIVEOUT	(1<<3)
105    void	(* c_probe)(struct console *cp);	/* set c_flags to match hardware */
106    int		(* c_init)(int arg);			/* reinit XXX may need more args */
107    void	(* c_out)(int c);			/* emit c */
108    int		(* c_in)(void);				/* wait for and return input */
109    int		(* c_ready)(void);			/* return nonzer if input waiting */
110};
111extern struct console	*consoles[];
112void		cons_probe(void);
113
114/*
115 * Plug-and-play enumerator/configurator interface.
116 */
117struct pnphandler
118{
119    const char	*pp_name;		/* handler/bus name */
120    void	(* pp_enumerate)(void);	/* enumerate PnP devices, add to chain */
121};
122
123struct pnpident
124{
125    char			*id_ident;	/* ASCII identifier, actual format varies with bus/handler */
126    STAILQ_ENTRY(pnpident)	id_link;
127};
128
129struct pnpinfo
130{
131    char			*pi_desc;	/* ASCII description, optional */
132    int				pi_revision;	/* optional revision (or -1) if not supported */
133    char			*pi_module;	/* module/args nominated to handle device */
134    int				pi_argc;	/* module arguments */
135    char			**pi_argv;
136    struct pnphandler		*pi_handler;	/* handler which detected this device */
137    STAILQ_HEAD(,pnpident)	pi_ident;	/* list of identifiers */
138    STAILQ_ENTRY(pnpinfo)	pi_link;
139};
140
141STAILQ_HEAD(pnpinfo_stql, pnpinfo);
142
143extern struct pnpinfo_stql pnp_devices;
144
145extern struct pnphandler	*pnphandlers[];		/* provided by MD code */
146
147void			pnp_addident(struct pnpinfo *pi, char *ident);
148struct pnpinfo		*pnp_allocinfo(void);
149void			pnp_freeinfo(struct pnpinfo *pi);
150void			pnp_addinfo(struct pnpinfo *pi);
151char			*pnp_eisaformat(u_int8_t *data);
152
153/*
154 *  < 0	- No ISA in system
155 * == 0	- Maybe ISA, search for read data port
156 *  > 0	- ISA in system, value is read data port address
157 */
158extern int			isapnp_readport;
159
160/*
161 * Preloaded file metadata header.
162 *
163 * Metadata are allocated on our heap, and copied into kernel space
164 * before executing the kernel.
165 */
166struct file_metadata
167{
168    size_t			md_size;
169    u_int16_t			md_type;
170    struct file_metadata	*md_next;
171    char			md_data[1];	/* data are immediately appended */
172};
173
174struct preloaded_file;
175
176struct kernel_module
177{
178    char			*m_name;	/* module name */
179/*    char			*m_args;*/	/* arguments for the module */
180    struct preloaded_file	*m_fp;
181    struct kernel_module	*m_next;
182};
183
184/*
185 * Preloaded file information. Depending on type, file can contain
186 * additional units called 'modules'.
187 *
188 * At least one file (the kernel) must be loaded in order to boot.
189 * The kernel is always loaded first.
190 *
191 * String fields (m_name, m_type) should be dynamically allocated.
192 */
193struct preloaded_file
194{
195    char			*f_name;	/* file name */
196    char			*f_type;	/* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
197    char			*f_args;	/* arguments for the file */
198    struct file_metadata	*f_metadata;	/* metadata that will be placed in the module directory */
199    int				f_loader;	/* index of the loader that read the file */
200    vm_offset_t			f_addr;		/* load address */
201    size_t			f_size;		/* file size */
202    struct kernel_module	*f_modules;	/* list of modules if any */
203    struct preloaded_file	*f_next;	/* next file */
204};
205
206struct file_format
207{
208    /* Load function must return EFTYPE if it can't handle the module supplied */
209    int		(* l_load)(char *filename, vm_offset_t dest, struct preloaded_file **result);
210    /* Only a loader that will load a kernel (first module) should have an exec handler */
211    int		(* l_exec)(struct preloaded_file *mp);
212};
213
214extern struct file_format	*file_formats[];	/* supplied by consumer */
215extern struct preloaded_file	*preloaded_files;
216
217int			mod_load(char *name, int argc, char *argv[]);
218int			mod_loadobj(char *type, char *name);
219
220struct preloaded_file *file_alloc(void);
221struct preloaded_file *file_findfile(char *name, char *type);
222struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
223void file_discard(struct preloaded_file *fp);
224void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
225int  file_addmodule(struct preloaded_file *fp, char *modname,
226	struct kernel_module **newmp);
227
228
229/* MI module loaders */
230int		aout_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
231vm_offset_t	aout_findsym(char *name, struct preloaded_file *fp);
232
233int	elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
234
235#ifndef NEW_LINKER_SET
236#include <sys/linker_set.h>
237
238/* XXX just for conversion's sake, until we move to the new linker set code */
239
240#define SET_FOREACH(pvar, set)				\
241	    for ((char*) pvar = set.ls_items;			\
242		 (char*) pvar < (char*) &set.ls_items[set.ls_length];	\
243		 pvar++)
244
245#else /* NEW_LINKER_SET */
246
247/*
248 * Private macros, not to be used outside this header file.
249 */
250#define __MAKE_SET(set, sym)						\
251	static void *__CONCAT(__setentry,__LINE__)			\
252	__attribute__((__section__("set_" #set),__unused__)) = &sym
253#define __SET_BEGIN(set)						\
254	({ extern void *__CONCAT(__start_set_,set);			\
255	    &__CONCAT(__start_set_,set); })
256#define __SET_END(set)							\
257	({ extern void *__CONCAT(__stop_set_,set);			\
258	    &__CONCAT(__stop_set_,set); })
259
260/*
261 * Public macros.
262 */
263
264/* Add an entry to a set. */
265#define DATA_SET(set, sym) __MAKE_SET(set, sym)
266
267/*
268 * Iterate over all the elements of a set.
269 *
270 * Sets always contain addresses of things, and "pvar" points to words
271 * containing those addresses.  Thus is must be declared as "type **pvar",
272 * and the address of each set item is obtained inside the loop by "*pvar".
273 */
274#define SET_FOREACH(pvar, set)						\
275	for (pvar = (__typeof__(pvar))__SET_BEGIN(set);			\
276	    pvar < (__typeof__(pvar))__SET_END(set); pvar++)
277#endif
278
279/*
280 * Support for commands
281 */
282struct bootblk_command
283{
284    const char		*c_name;
285    const char		*c_desc;
286    bootblk_cmd_t	*c_fn;
287};
288
289#define COMMAND_SET(tag, key, desc, func)				\
290    static bootblk_cmd_t func;						\
291    static struct bootblk_command _cmd_ ## tag = { key, desc, func };	\
292    DATA_SET(Xcommand_set, _cmd_ ## tag)
293
294extern struct linker_set Xcommand_set;
295
296/*
297 * The intention of the architecture switch is to provide a convenient
298 * encapsulation of the interface between the bootstrap MI and MD code.
299 * MD code may selectively populate the switch at runtime based on the
300 * actual configuration of the target system.
301 */
302struct arch_switch
303{
304    /* Automatically load modules as required by detected hardware */
305    int		(*arch_autoload)(void);
306    /* Locate the device for (name), return pointer to tail in (*path) */
307    int		(*arch_getdev)(void **dev, const char *name, const char **path);
308    /* Copy from local address space to module address space, similar to bcopy() */
309    ssize_t	(*arch_copyin)(const void *src, vm_offset_t dest,
310			       const size_t len);
311    /* Copy to local address space from module address space, similar to bcopy() */
312    ssize_t	(*arch_copyout)(const vm_offset_t src, void *dest,
313				const size_t len);
314    /* Read from file to module address space, same semantics as read() */
315    ssize_t	(*arch_readin)(const int fd, vm_offset_t dest,
316			       const size_t len);
317    /* Perform ISA byte port I/O (only for systems with ISA) */
318    int		(*arch_isainb)(int port);
319    void	(*arch_isaoutb)(int port, int value);
320};
321extern struct arch_switch archsw;
322
323/* This must be provided by the MD code, but should it be in the archsw? */
324void	delay(int delay);
325
326void	dev_cleanup(void);
327