1 /*        $NetBSD: bootstrap.h,v 1.11 2024/06/29 08:03:28 rin Exp $   */
2 
3 /*-
4  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: src/sys/boot/common/bootstrap.h,v 1.38.6.1 2004/09/03 19:25:40 iedowse Exp $
29  */
30 
31 #ifndef _BOOTSTRAP_H_
32 #define _BOOTSTRAP_H_
33 
34 #include <sys/types.h>
35 #include <sys/queue.h>
36 
37 /*
38  * Generic device specifier; architecture-dependent
39  * versions may be larger, but should be allowed to
40  * overlap.
41  */
42 
43 struct devdesc
44 {
45     struct devsw    *d_dev;
46     int                       d_type;
47 #define DEVT_NONE   0
48 #define DEVT_DISK   1
49 #define DEVT_NET    2
50 #define   DEVT_CD             3
51 };
52 
53 typedef int         (bootblk_cmd_t)(int argc, char *argv[]);
54 int command_seterr(const char *fmt, ...) __printflike(1, 2);
55 const char *command_geterr(void);
56 
57 #define CMD_OK                0
58 #define CMD_ERROR   1
59 
60 
61 /* interp.c */
62 void      interact(void);
63 int       include(const char *filename);
64 
65 /* interp_backslash.c */
66 char      *backslash(char *str);
67 
68 /* interp_parse.c */
69 int       parse(int *argc, char ***argv, char *str);
70 
71 /* interp_forth.c */
72 void      bf_init(void);
73 int       bf_run(char *line);
74 
75 /* boot.c */
76 int       autoboot(int timeout, char *prompt);
77 void      autoboot_maybe(void);
78 int       getrootmount(char *rootdev);
79 
80 /* misc.c */
81 char      *unargv(int argc, char *argv[]);
82 #if 0
83 void      hexdump(void *region, size_t len);
84 #endif
85 size_t    strlenout(vaddr_t str);
86 char      *strdupout(vaddr_t str);
87 void      kern_bzero(vaddr_t dest, size_t len);
88 int       kern_pread(int fd, vaddr_t dest, size_t len, off_t off);
89 void      *alloc_pread(int fd, off_t off, size_t len);
90 
91 /* bcache.c */
92 int       bcache_init(u_int nblks, size_t bsize);
93 void      bcache_flush(void);
94 int       bcache_strategy(void *devdata, int unit, int rw, daddr_t blk,
95                               size_t size, char *buf, size_t *rsize);
96 
97 
98 /* strdup.c */
99 char      *strdup(const char*);
100 
101 /*
102  * Disk block cache
103  */
104 struct bcache_devdata
105 {
106     int         (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize);
107     void  *dv_devdata;
108 };
109 
110 /*
111  * Modular console support.
112  */
113 struct console
114 {
115     const char      *c_name;
116     const char      *c_desc;
117     int             c_flags;
118 #define C_PRESENTIN (1<<0)
119 #define C_PRESENTOUT          (1<<1)
120 #define C_ACTIVEIN  (1<<2)
121 #define C_ACTIVEOUT (1<<3)
122     void  (* c_probe)(struct console *cp);        /* set c_flags to match hardware */
123     int             (* c_init)(int arg);                              /* reinit XXX may need more args */
124     void  (* c_out)(int c);                       /* emit c */
125     int             (* c_in)(void);                                   /* wait for and return input */
126     int             (* c_ready)(void);                      /* return nonzer if input waiting */
127 };
128 extern struct console         *consoles[];
129 void                cons_probe(void);
130 int                 ischar(void);
131 
132 /*
133  * Plug-and-play enumerator/configurator interface.
134  */
135 struct pnphandler
136 {
137     const char      *pp_name;           /* handler/bus name */
138     void  (* pp_enumerate)(void);       /* enumerate PnP devices, add to chain */
139 };
140 
141 struct pnpident
142 {
143     char                      *id_ident;          /* ASCII identifier, actual format varies with bus/handler */
144     STAILQ_ENTRY(pnpident)    id_link;
145 };
146 
147 struct pnpinfo
148 {
149     char                      *pi_desc; /* ASCII description, optional */
150     int                                 pi_revision;        /* optional revision (or -1) if not supported */
151     char                      *pi_module;         /* module/args nominated to handle device */
152     int                                 pi_argc;  /* module arguments */
153     char                      **pi_argv;
154     struct pnphandler                   *pi_handler;        /* handler which detected this device */
155     STAILQ_HEAD(,pnpident)    pi_ident; /* list of identifiers */
156     STAILQ_ENTRY(pnpinfo)     pi_link;
157 };
158 
159 STAILQ_HEAD(pnpinfo_stql, pnpinfo);
160 
161 extern struct pnpinfo_stql pnp_devices;
162 
163 extern struct pnphandler      *pnphandlers[];               /* provided by MD code */
164 
165 void                          pnp_addident(struct pnpinfo *pi, char *ident);
166 struct pnpinfo                *pnp_allocinfo(void);
167 void                          pnp_freeinfo(struct pnpinfo *pi);
168 void                          pnp_addinfo(struct pnpinfo *pi);
169 char                          *pnp_eisaformat(u_int8_t *data);
170 
171 /*
172  *  < 0   - No ISA in system
173  * == 0   - Maybe ISA, search for read data port
174  *  > 0   - ISA in system, value is read data port address
175  */
176 extern int                              isapnp_readport;
177 
178 struct preloaded_file;
179 
180 /*
181  * Preloaded file information. Depending on type, file can contain
182  * additional units called 'modules'.
183  *
184  * At least one file (the kernel) must be loaded in order to boot.
185  * The kernel is always loaded first.
186  *
187  * String fields (m_name, m_type) should be dynamically allocated.
188  */
189 struct preloaded_file
190 {
191     char                      *f_name;  /* file name */
192     char                      *f_type;  /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */
193     char                      *f_args;  /* arguments for the file */
194     int                                 f_loader; /* index of the loader that read the file */
195     vaddr_t                             f_addr;             /* load address */
196     size_t                              f_size;             /* file size */
197     struct preloaded_file     *f_next;  /* next file */
198     u_long                      marks[MARK_MAX];/* filled by loadfile() */
199 };
200 
201 struct file_format
202 {
203     /* Load function must return EFTYPE if it can't handle the module supplied */
204     int             (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result);
205     /* Only a loader that will load a kernel (first module) should have an exec handler */
206     int             (* l_exec)(struct preloaded_file *mp);
207 };
208 
209 extern struct file_format     *file_formats[];    /* supplied by consumer */
210 extern struct preloaded_file  *preloaded_files;
211 
212 int                           mod_load(char *name, int argc, char *argv[]);
213 int                           mod_loadkld(const char *name, int argc, char *argv[]);
214 
215 struct preloaded_file *file_alloc(void);
216 struct preloaded_file *file_findfile(char *name, char *type);
217 
218 int file_loadkernel(char *filename, int argc, char *argv[]);
219 void file_discard(struct preloaded_file *fp);
220 
221 int       elf64_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result);
222 
223 /*
224  * Support for commands
225  */
226 struct bootblk_command
227 {
228     const char                *c_name;
229     const char                *c_desc;
230     bootblk_cmd_t   *c_fn;
231 };
232 
233 /* Prototypes for the command handlers within stand/common/ */
234 
235 /* command.c */
236 
237 int command_help(int argc, char *argv[]) ;
238 int command_commandlist(int argc, char *argv[]);
239 int command_show(int argc, char *argv[]);
240 int command_set(int argc, char *argv[]);
241 int command_unset(int argc, char *argv[]);
242 int command_echo(int argc, char *argv[]);
243 int command_read(int argc, char *argv[]);
244 int command_more(int argc, char *argv[]);
245 int command_lsdev(int argc, char *argv[]);
246 
247 /*        bcache.c  XXX: Fixme: Do we need the bcache ?*/
248 /* int command_bcache(int argc, char *argv[]); */
249 /*        boot.c              */
250 int command_boot(int argc, char *argv[]);
251 int command_autoboot(int argc, char *argv[]);
252 /*        fileload.c          */
253 int command_load(int argc, char *argv[]);
254 int command_unload(int argc, char *argv[]);
255 int command_lskern(int argc, char *argv[]);
256 /*        interp.c  */
257 int command_include(int argc, char *argv[]);
258 /*        ls.c                */
259 int command_ls(int argc, char *argv[]);
260 
261 #define COMMAND_SET(a, b, c, d) /* nothing */
262 
263 #define COMMON_COMMANDS                                                                   \
264           /*        common.c  */                                                \
265           { "help", "detailed help",    command_help },               \
266           { "?",              "list commands",    command_commandlist },        \
267           { "show", "show variable(s)", command_show },                         \
268           { "set", "set a variable", command_set },                             \
269           { "unset", "unset a variable", command_unset },                       \
270           { "echo", "echo arguments", command_echo },                           \
271           { "read", "read input from the terminal", command_read },   \
272           { "more", "show contents of a file", command_more },                  \
273           { "lsdev", "list all devices", command_lsdev },                       \
274                                                                                           \
275           /*        bcache.c  XXX: Fixme: Do we need the bcache ? */  \
276                                                                                           \
277 /*        { "bcachestat", "get disk block cache stats", command_bcache }, */\
278                                                                                           \
279           /*        boot.c    */                                                          \
280                                                                                           \
281           { "boot", "boot a file or loaded kernel", command_boot },   \
282           { "autoboot", "boot automatically after a delay", command_autoboot }, \
283                                                                                           \
284           /*        fileload.c          */                                                \
285                                                                                           \
286           { "load", "load a kernel", command_load },                            \
287           { "unload", "unload all modules", command_unload },                   \
288           { "lskern", "list loaded kernel", command_lskern },                   \
289                                                                                           \
290           /*        interp.c  */                                                \
291                                                                                           \
292           { "include", "read commands from a file", command_include },          \
293                                                                                           \
294           /*        ls.c      */                                                          \
295                                                                                           \
296           { "ls", "list files", command_ls }
297 
298 extern struct bootblk_command commands[];
299 
300 
301 /*
302  * The intention of the architecture switch is to provide a convenient
303  * encapsulation of the interface between the bootstrap MI and MD code.
304  * MD code may selectively populate the switch at runtime based on the
305  * actual configuration of the target system.
306  */
307 struct arch_switch
308 {
309     /* Automatically load modules as required by detected hardware */
310     int             (*arch_autoload)(void);
311     /* Locate the device for (name), return pointer to tail in (*path) */
312     int             (*arch_getdev)(void **dev, const char *name, const char **path);
313     /* Copy from local address space to module address space, similar to bcopy() */
314     ssize_t         (*arch_copyin)(const void *src, vaddr_t dest,
315                                      const size_t len);
316     /* Copy to local address space from module address space, similar to bcopy() */
317     ssize_t         (*arch_copyout)(const vaddr_t src, void *dest,
318                                         const size_t len);
319     /* Read from file to module address space, same semantics as read() */
320     ssize_t         (*arch_readin)(const int fd, vaddr_t dest,
321                                      const size_t len);
322     /* Perform ISA byte port I/O (only for systems with ISA) */
323     int             (*arch_isainb)(int port);
324     void  (*arch_isaoutb)(int port, int value);
325 };
326 extern struct arch_switch archsw;
327 
328 /* This must be provided by the MD code, but should it be in the archsw? */
329 void      delay(int delay);
330 
331 void      dev_cleanup(void);
332 
333 time_t    time(time_t *tloc);
334 
335 /* calloc.c */
336 void    *calloc(unsigned int, unsigned int);
337 
338 /* various string functions */
339 size_t    strspn(const char *s1, const char *s2);
340 size_t    strlen(const char *s);
341 char *strcpy(char * restrict dst, const char * restrict src);
342 char *strcat(char * restrict s, const char * restrict append);
343 
344 /* pager.c */
345 extern void         pager_open(void);
346 extern void         pager_close(void);
347 extern int          pager_output(const char *lines);
348 extern int          pager_file(const char *fname);
349 
350 /* environment.c */
351 #define EV_DYNAMIC  (1<<0)              /* value was dynamically allocated, free if changed/unset */
352 #define EV_VOLATILE (1<<1)              /* value is volatile, make a copy of it */
353 #define EV_NOHOOK   (1<<2)              /* don't call hook when setting */
354 
355 struct env_var;
356 typedef char        *(ev_format_t)(struct env_var *ev);
357 typedef int         (ev_sethook_t)(struct env_var *ev, int flags,
358                         const void *value);
359 typedef int         (ev_unsethook_t)(struct env_var *ev);
360 
361 struct env_var
362 {
363     char            *ev_name;
364     int                       ev_flags;
365     void            *ev_value;
366     ev_sethook_t    *ev_sethook;
367     ev_unsethook_t  *ev_unsethook;
368     struct env_var  *ev_next, *ev_prev;
369 };
370 extern struct env_var         *environ;
371 
372 extern struct env_var         *env_getenv(const char *name);
373 extern int                    env_setenv(const char *name, int flags,
374                                            const void *value, ev_sethook_t sethook,
375                                            ev_unsethook_t unsethook);
376 extern char                   *getenv(const char *name);
377 extern int                    setenv(const char *name, const char *value,
378                                      int overwrite);
379 extern int                    putenv(const char *string);
380 extern int                    unsetenv(const char *name);
381 
382 extern ev_sethook_t env_noset;                    /* refuse set operation */
383 extern ev_unsethook_t         env_nounset;                  /* refuse unset operation */
384 
385 
386 
387 /* FreeBSD wrappers */
388 
389 
390 struct dirent *readdirfd(int);               /* XXX move to stand.h */
391 
392 #define free(ptr) dealloc(ptr, 0) /* XXX UGLY HACK!!! This should work for just now though. See: libsa/alloc.c:free() */
393 
394 /* XXX Hack Hack Hack!!! Need to update stand.h with fs_ops->fo_readdir */
395 #ifdef SKIFS /* defined via stand/ia64/ski/Makefile */
396 #define FS_READDIR(f, dirptr) skifs_readdir(f, dirptr)
397 #else
398 #define FS_READDIR(f, dirptr) efifs_readdir(f, dirptr)
399 #endif
400 
401 /* gets.c XXX move to libsa/ */
402 
403 extern int          fgetstr(char *buf, int size, int fd);
404 extern void         ngets(char *, int);
405 
406 /* imports from stdlib, modified for sa */
407 
408 extern long         strtol(const char *, char **, int);
409 
410 extern long         strtol(const char *, char **, int);
411 
412 /* XXX: From <fcntl.h>. Its not very _STANDALONE friendly */
413 /* open-only flags */
414 #define   O_RDONLY  0x00000000          /* open for reading only */
415 #define   O_WRONLY  0x00000001          /* open for writing only */
416 #define   O_RDWR              0x00000002          /* open for reading and writing */
417 #define   O_ACCMODE 0x00000003          /* mask for above modes */
418 
419 #define ELF64_KERNELTYPE "elf kernel"
420 
421 #endif /* _BOOTSTRAP_H_ */
422