bootstrap.h revision 60938
1104476Ssam/*-
2139825Simp * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3104476Ssam * All rights reserved.
4104476Ssam *
5104476Ssam * Redistribution and use in source and binary forms, with or without
6104476Ssam * modification, are permitted provided that the following conditions
7104476Ssam * are met:
8104476Ssam * 1. Redistributions of source code must retain the above copyright
9104476Ssam *    notice, this list of conditions and the following disclaimer.
10104476Ssam * 2. Redistributions in binary form must reproduce the above copyright
11104476Ssam *    notice, this list of conditions and the following disclaimer in the
12104476Ssam *    documentation and/or other materials provided with the distribution.
13104476Ssam *
14104476Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15104476Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16104476Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17104476Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18104476Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19104476Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20104476Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21104476Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22104476Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23104476Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24104476Ssam * SUCH DAMAGE.
25104476Ssam *
26104476Ssam * $FreeBSD: head/sys/boot/common/bootstrap.h 60938 2000-05-26 02:09:24Z jake $
27104476Ssam */
28104476Ssam
29104476Ssam#include <sys/types.h>
30104476Ssam#include <sys/queue.h>
31104476Ssam
32104476Ssam/* XXX debugging */
33104476Ssamextern struct console vidconsole;
34104476Ssam#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();}
35104476Ssam
36104476Ssam/*
37104476Ssam * Generic device specifier; architecture-dependant
38104476Ssam * versions may be larger, but should be allowed to
39116191Sobrien * overlap.
40116191Sobrien */
41116191Sobrienstruct devdesc
42104476Ssam{
43104476Ssam    struct devsw	*d_dev;
44104476Ssam    int			d_type;
45104476Ssam#define DEVT_NONE	0
46104476Ssam#define DEVT_DISK	1
47104476Ssam#define DEVT_NET	2
48104476Ssam};
49104476Ssam
50104476Ssam/* Commands and return values; nonzero return sets command_errmsg != NULL */
51104476Ssamtypedef int	(bootblk_cmd_t)(int argc, char *argv[]);
52104476Ssamextern char	*command_errmsg;
53104476Ssamextern char	command_errbuf[];	/* XXX blah, length */
54104476Ssam#define CMD_OK		0
55104476Ssam#define CMD_ERROR	1
56104476Ssam
57104476Ssam/* interp.c */
58104476Ssamextern void	interact(void);
59104476Ssamextern int	include(char *filename);
60104476Ssam
61104476Ssam/* interp_parse.c */
62104476Ssamextern int	parse(int *argc, char ***argv, char *str);
63104476Ssam
64104476Ssam/* interp_forth.c */
65104476Ssamextern void	bf_init(void);
66104476Ssamextern int	bf_run(char *line);
67104476Ssam
68104476Ssam/* boot.c */
69104476Ssamextern int	autoboot(int delay, char *prompt);
70104476Ssamextern void	autoboot_maybe(void);
71104476Ssamextern int	getrootmount(char *rootdev);
72104476Ssam
73104476Ssam/* misc.c */
74104476Ssamextern char	*unargv(int argc, char *argv[]);
75104476Ssamextern void	hexdump(caddr_t region, size_t len);
76104476Ssamextern size_t	strlenout(vm_offset_t str);
77104476Ssamextern char	*strdupout(vm_offset_t str);
78104476Ssam
79104476Ssam/* bcache.c */
80104476Ssamextern int	bcache_init(int nblks, size_t bsize);
81104476Ssamextern void	bcache_flush();
82104476Ssam
83104476Ssam/*
84104476Ssam * Disk block cache
85104476Ssam */
86104476Ssamstruct bcache_devdata
87104476Ssam{
88104476Ssam    int         (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, void *buf, size_t *rsize);
89104476Ssam    void	*dv_devdata;
90104476Ssam};
91104476Ssam
92104476Ssam/*
93104476Ssam * Modular console support.
94104476Ssam */
95104476Ssamstruct console
96104476Ssam{
97104476Ssam    char	*c_name;
98104476Ssam    char	*c_desc;
99104476Ssam    int		c_flags;
100104476Ssam#define C_PRESENTIN	(1<<0)
101104476Ssam#define C_PRESENTOUT	(1<<1)
102104476Ssam#define C_ACTIVEIN	(1<<2)
103104476Ssam#define C_ACTIVEOUT	(1<<3)
104104476Ssam    void	(* c_probe)(struct console *cp);	/* set c_flags to match hardware */
105104476Ssam    int		(* c_init)(int arg);			/* reinit XXX may need more args */
106104476Ssam    void	(* c_out)(int c);			/* emit c */
107104476Ssam    int		(* c_in)(void);				/* wait for and return input */
108104476Ssam    int		(* c_ready)(void);			/* return nonzer if input waiting */
109104476Ssam};
110104476Ssamextern struct console	*consoles[];
111104476Ssamextern void		cons_probe(void);
112104476Ssam
113104476Ssam/*
114104476Ssam * Plug-and-play enumerator/configurator interface.
115104476Ssam */
116104476Ssamstruct pnphandler
117104476Ssam{
118104476Ssam    char	*pp_name;		/* handler/bus name */
119104476Ssam    void	(* pp_enumerate)(void);	/* enumerate PnP devices, add to chain */
120104476Ssam};
121104476Ssam
122104476Ssamstruct pnpident
123104476Ssam{
124104476Ssam    char			*id_ident;	/* ASCII identifier, actual format varies with bus/handler */
125104476Ssam    STAILQ_ENTRY(pnpident)	id_link;
126104476Ssam};
127104476Ssam
128104476Ssamstruct pnpinfo
129104476Ssam{
130104476Ssam    char			*pi_desc;	/* ASCII description, optional */
131104476Ssam    int				pi_revision;	/* optional revision (or -1) if not supported */
132104476Ssam    char			*pi_module;	/* module/args nominated to handle device */
133104476Ssam    int				pi_argc;	/* module arguments */
134104476Ssam    char			**pi_argv;
135104476Ssam    struct pnphandler		*pi_handler;	/* handler which detected this device */
136104476Ssam    STAILQ_HEAD(,pnpident)	pi_ident;	/* list of identifiers */
137104476Ssam    STAILQ_ENTRY(pnpinfo)	pi_link;
138104476Ssam};
139104476Ssam
140104476Ssamextern struct pnphandler	*pnphandlers[];		/* provided by MD code */
141104476Ssam
142104476Ssamextern void			pnp_addident(struct pnpinfo *pi, char *ident);
143104476Ssamextern struct pnpinfo		*pnp_allocinfo(void);
144104476Ssamextern void			pnp_freeinfo(struct pnpinfo *pi);
145104476Ssamextern void			pnp_addinfo(struct pnpinfo *pi);
146104476Ssamextern char			*pnp_eisaformat(u_int8_t *data);
147104476Ssam
148104476Ssam/*
149104476Ssam *  < 0	- No ISA in system
150104476Ssam * == 0	- Maybe ISA, search for read data port
151104476Ssam *  > 0	- ISA in system, value is read data port address
152104476Ssam */
153104476Ssamextern int			isapnp_readport;
154104476Ssam
155104476Ssam/*
156104476Ssam * Preloaded file metadata header.
157104476Ssam *
158104476Ssam * Metadata are allocated on our heap, and copied into kernel space
159104476Ssam * before executing the kernel.
160104476Ssam */
161104476Ssamstruct file_metadata
162104476Ssam{
163104476Ssam    size_t			md_size;
164104476Ssam    u_int16_t			md_type;
165104476Ssam    struct file_metadata	*md_next;
166104476Ssam    char			md_data[0];	/* data are immediately appended */
167104476Ssam};
168104476Ssam
169104476Ssamstruct preloaded_file;
170104476Ssam
171104476Ssamstruct kernel_module
172104476Ssam{
173104476Ssam    char			*m_name;	/* module name */
174104476Ssam/*    char			*m_args;*/	/* arguments for the module */
175104476Ssam    struct preloaded_file	*m_fp;
176104476Ssam    struct kernel_module	*m_next;
177104476Ssam};
178104476Ssam
179104476Ssam/*
180104476Ssam * Preloaded file information. Depending on type, file can contain
181104476Ssam * additional units called 'modules'.
182104476Ssam *
183104476Ssam * At least one file (the kernel) must be loaded in order to boot.
184104476Ssam * The kernel is always loaded first.
185104476Ssam *
186104476Ssam * String fields (m_name, m_type) should be dynamically allocated.
187104476Ssam */
188104476Ssamstruct preloaded_file
189104476Ssam{
190104476Ssam    char			*f_name;	/* file name */
191104476Ssam    char			*f_type;	/* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
192104476Ssam    char			*f_args;	/* arguments for the file */
193104476Ssam    struct file_metadata	*f_metadata;	/* metadata that will be placed in the module directory */
194104476Ssam    int				f_loader;	/* index of the loader that read the file */
195104476Ssam    vm_offset_t			f_addr;		/* load address */
196104476Ssam    size_t			f_size;		/* file size */
197104476Ssam    struct kernel_module	*f_modules;	/* list of modules if any */
198104476Ssam    struct preloaded_file	*f_next;	/* next file */
199104476Ssam};
200104476Ssam
201104476Ssamstruct file_format
202104476Ssam{
203104476Ssam    /* Load function must return EFTYPE if it can't handle the module supplied */
204104476Ssam    int		(* l_load)(char *filename, vm_offset_t dest, struct preloaded_file **result);
205104476Ssam    /* Only a loader that will load a kernel (first module) should have an exec handler */
206104476Ssam    int		(* l_exec)(struct preloaded_file *mp);
207104476Ssam};
208104476Ssam
209104476Ssamextern struct file_format	*file_formats[];	/* supplied by consumer */
210104476Ssamextern struct preloaded_file	*preloaded_files;
211104476Ssam
212104476Ssamextern int			mod_load(char *name, int argc, char *argv[]);
213104476Ssamextern int			mod_loadobj(char *type, char *name);
214104476Ssam
215104476Ssamstruct preloaded_file *file_alloc(void);
216104476Ssamstruct preloaded_file *file_findfile(char *name, char *type);
217104476Ssamstruct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
218104476Ssamvoid file_discard(struct preloaded_file *fp);
219104476Ssamvoid file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
220104476Ssamint  file_addmodule(struct preloaded_file *fp, char *modname,
221104476Ssam	struct kernel_module **newmp);
222104476Ssam
223104476Ssam
224104476Ssam/* MI module loaders */
225104476Ssamextern int		aout_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
226104476Ssamextern vm_offset_t	aout_findsym(char *name, struct preloaded_file *fp);
227104476Ssam
228104476Ssamextern int	elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result);
229104476Ssam
230104476Ssam#ifndef NEW_LINKER_SET
231104476Ssam#include <sys/linker_set.h>
232104476Ssam
233104476Ssam/* XXX just for conversion's sake, until we move to the new linker set code */
234104476Ssam
235104476Ssam#define SET_FOREACH(pvar, set)				\
236104476Ssam	    for ((char*) pvar = set.ls_items;			\
237104476Ssam		 (char*) pvar < (char*) &set.ls_items[set.ls_length];	\
238104476Ssam		 pvar++)
239104476Ssam
240104476Ssam#else /* NEW_LINKER_SET */
241104476Ssam
242104476Ssam/*
243104476Ssam * Private macros, not to be used outside this header file.
244104476Ssam */
245104476Ssam#define __MAKE_SET(set, sym)						\
246104476Ssam	static void *__CONCAT(__setentry,__LINE__)			\
247104476Ssam	__attribute__((__section__("set_" #set),__unused__)) = &sym
248104476Ssam#define __SET_BEGIN(set)						\
249104476Ssam	({ extern void *__CONCAT(__start_set_,set);			\
250104476Ssam	    &__CONCAT(__start_set_,set); })
251104476Ssam#define __SET_END(set)							\
252104476Ssam	({ extern void *__CONCAT(__stop_set_,set);			\
253104476Ssam	    &__CONCAT(__stop_set_,set); })
254104476Ssam
255104476Ssam/*
256104476Ssam * Public macros.
257104476Ssam */
258104476Ssam
259104476Ssam/* Add an entry to a set. */
260104476Ssam#define DATA_SET(set, sym) __MAKE_SET(set, sym)
261104476Ssam
262104476Ssam/*
263104476Ssam * Iterate over all the elements of a set.
264104476Ssam *
265104476Ssam * Sets always contain addresses of things, and "pvar" points to words
266104476Ssam * containing those addresses.  Thus is must be declared as "type **pvar",
267104476Ssam * and the address of each set item is obtained inside the loop by "*pvar".
268104476Ssam */
269104476Ssam#define SET_FOREACH(pvar, set)						\
270104476Ssam	for (pvar = (__typeof__(pvar))__SET_BEGIN(set);			\
271104476Ssam	    pvar < (__typeof__(pvar))__SET_END(set); pvar++)
272104476Ssam#endif
273104476Ssam
274104476Ssam/*
275104476Ssam * Support for commands
276104476Ssam */
277104476Ssamstruct bootblk_command
278104476Ssam{
279104476Ssam    const char		*c_name;
280104476Ssam    const char		*c_desc;
281104476Ssam    bootblk_cmd_t	*c_fn;
282104476Ssam};
283104476Ssam
284104476Ssam#define COMMAND_SET(tag, key, desc, func)				\
285104476Ssam    static bootblk_cmd_t func;						\
286104476Ssam    static struct bootblk_command _cmd_ ## tag = { key, desc, func };	\
287104476Ssam    DATA_SET(Xcommand_set, _cmd_ ## tag);
288104476Ssam
289104476Ssamextern struct linker_set Xcommand_set;
290104476Ssam
291104476Ssam/*
292104476Ssam * The intention of the architecture switch is to provide a convenient
293104476Ssam * encapsulation of the interface between the bootstrap MI and MD code.
294104476Ssam * MD code may selectively populate the switch at runtime based on the
295104476Ssam * actual configuration of the target system.
296104476Ssam */
297104476Ssamstruct arch_switch
298104476Ssam{
299104476Ssam    /* Automatically load modules as required by detected hardware */
300104476Ssam    int			(* arch_autoload)();
301104476Ssam    /* Locate the device for (name), return pointer to tail in (*path) */
302104476Ssam    int			(*arch_getdev)(void **dev, const char *name, const char **path);
303104476Ssam    /* Copy from local address space to module address space, similar to bcopy() */
304104476Ssam    int			(*arch_copyin)(void *src, vm_offset_t dest, size_t len);
305104476Ssam    /* Copy to local address space from module address space, similar to bcopy() */
306104476Ssam    int			(*arch_copyout)(vm_offset_t src, void *dest, size_t len);
307104476Ssam    /* Read from file to module address space, same semantics as read() */
308104476Ssam    int			(*arch_readin)(int fd, vm_offset_t dest, size_t len);
309104476Ssam    /* Perform ISA byte port I/O (only for systems with ISA) */
310104476Ssam    int			(*arch_isainb)(int port);
311104476Ssam    void		(*arch_isaoutb)(int port, int value);
312104476Ssam};
313104476Ssamextern struct arch_switch archsw;
314104476Ssam
315104476Ssam/* This must be provided by the MD code, but should it be in the archsw? */
316104476Ssamextern void		delay(int delay);
317104476Ssam