1 /* $NetBSD: bootstrap.h,v 1.5 2007/03/04 06:00:03 christos 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-dependant 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 /* Commands and return values; nonzero return sets command_errmsg != NULL */ 54 typedef int (bootblk_cmd_t)(int argc, char *argv[]); 55 extern char *command_errmsg; 56 extern char command_errbuf[]; /* XXX blah, length */ 57 #define CMD_OK 0 58 #define CMD_ERROR 1 59 60 /* interp.c */ 61 void interact(void); 62 int include(const char *filename); 63 64 /* interp_backslash.c */ 65 char *backslash(char *str); 66 67 /* interp_parse.c */ 68 int parse(int *argc, char ***argv, char *str); 69 70 /* interp_forth.c */ 71 void bf_init(void); 72 int bf_run(char *line); 73 74 /* boot.c */ 75 int autoboot(int timeout, char *prompt); 76 void autoboot_maybe(void); 77 int getrootmount(char *rootdev); 78 79 /* misc.c */ 80 char *unargv(int argc, char *argv[]); 81 void hexdump(void *region, size_t len); 82 size_t strlenout(vaddr_t str); 83 char *strdupout(vaddr_t str); 84 void kern_bzero(vaddr_t dest, size_t len); 85 int kern_pread(int fd, vaddr_t dest, size_t len, off_t off); 86 void *alloc_pread(int fd, off_t off, size_t len); 87 88 /* bcache.c */ 89 int bcache_init(u_int nblks, size_t bsize); 90 void bcache_flush(void); 91 int bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, 92 size_t size, char *buf, size_t *rsize); 93 94 95 /* strdup.c */ 96 char *strdup(const char*); 97 98 /* 99 * Disk block cache 100 */ 101 struct bcache_devdata 102 { 103 int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); 104 void *dv_devdata; 105 }; 106 107 /* 108 * Modular console support. 109 */ 110 struct console 111 { 112 const char *c_name; 113 const char *c_desc; 114 int c_flags; 115 #define C_PRESENTIN (1<<0) 116 #define C_PRESENTOUT (1<<1) 117 #define C_ACTIVEIN (1<<2) 118 #define C_ACTIVEOUT (1<<3) 119 void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 120 int (* c_init)(int arg); /* reinit XXX may need more args */ 121 void (* c_out)(int c); /* emit c */ 122 int (* c_in)(void); /* wait for and return input */ 123 int (* c_ready)(void); /* return nonzer if input waiting */ 124 }; 125 extern struct console *consoles[]; 126 void cons_probe(void); 127 128 /* 129 * Plug-and-play enumerator/configurator interface. 130 */ 131 struct pnphandler 132 { 133 const char *pp_name; /* handler/bus name */ 134 void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */ 135 }; 136 137 struct pnpident 138 { 139 char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 140 STAILQ_ENTRY(pnpident) id_link; 141 }; 142 143 struct pnpinfo 144 { 145 char *pi_desc; /* ASCII description, optional */ 146 int pi_revision; /* optional revision (or -1) if not supported */ 147 char *pi_module; /* module/args nominated to handle device */ 148 int pi_argc; /* module arguments */ 149 char **pi_argv; 150 struct pnphandler *pi_handler; /* handler which detected this device */ 151 STAILQ_HEAD(,pnpident) pi_ident; /* list of identifiers */ 152 STAILQ_ENTRY(pnpinfo) pi_link; 153 }; 154 155 STAILQ_HEAD(pnpinfo_stql, pnpinfo); 156 157 extern struct pnpinfo_stql pnp_devices; 158 159 extern struct pnphandler *pnphandlers[]; /* provided by MD code */ 160 161 void pnp_addident(struct pnpinfo *pi, char *ident); 162 struct pnpinfo *pnp_allocinfo(void); 163 void pnp_freeinfo(struct pnpinfo *pi); 164 void pnp_addinfo(struct pnpinfo *pi); 165 char *pnp_eisaformat(u_int8_t *data); 166 167 /* 168 * < 0 - No ISA in system 169 * == 0 - Maybe ISA, search for read data port 170 * > 0 - ISA in system, value is read data port address 171 */ 172 extern int isapnp_readport; 173 174 struct preloaded_file; 175 176 /* 177 * Preloaded file information. Depending on type, file can contain 178 * additional units called 'modules'. 179 * 180 * At least one file (the kernel) must be loaded in order to boot. 181 * The kernel is always loaded first. 182 * 183 * String fields (m_name, m_type) should be dynamically allocated. 184 */ 185 struct preloaded_file 186 { 187 char *f_name; /* file name */ 188 char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ 189 char *f_args; /* arguments for the file */ 190 int f_loader; /* index of the loader that read the file */ 191 vaddr_t f_addr; /* load address */ 192 size_t f_size; /* file size */ 193 struct preloaded_file *f_next; /* next file */ 194 u_long *marks; /* filled by loadfile() */ 195 }; 196 197 struct file_format 198 { 199 /* Load function must return EFTYPE if it can't handle the module supplied */ 200 int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); 201 /* Only a loader that will load a kernel (first module) should have an exec handler */ 202 int (* l_exec)(struct preloaded_file *mp); 203 }; 204 205 extern struct file_format *file_formats[]; /* supplied by consumer */ 206 extern struct preloaded_file *preloaded_files; 207 208 int mod_load(char *name, int argc, char *argv[]); 209 int mod_loadkld(const char *name, int argc, char *argv[]); 210 211 struct preloaded_file *file_alloc(void); 212 struct preloaded_file *file_findfile(char *name, char *type); 213 214 void file_discard(struct preloaded_file *fp); 215 216 int elf64_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result); 217 218 /* 219 * Support for commands 220 */ 221 struct bootblk_command 222 { 223 const char *c_name; 224 const char *c_desc; 225 bootblk_cmd_t *c_fn; 226 }; 227 228 /* Prototypes for the command handlers within stand/common/ */ 229 230 /* command.c */ 231 232 int command_help(int argc, char *argv[]) ; 233 int command_commandlist(int argc, char *argv[]); 234 int command_show(int argc, char *argv[]); 235 int command_set(int argc, char *argv[]); 236 int command_unset(int argc, char *argv[]); 237 int command_echo(int argc, char *argv[]); 238 int command_read(int argc, char *argv[]); 239 int command_more(int argc, char *argv[]); 240 int command_lsdev(int argc, char *argv[]); 241 242 /* bcache.c XXX: Fixme: Do we need the bcache ?*/ 243 /* int command_bcache(int argc, char *argv[]); */ 244 /* boot.c */ 245 int command_boot(int argc, char *argv[]); 246 int command_autoboot(int argc, char *argv[]); 247 /* fileload.c */ 248 int command_load(int argc, char *argv[]); 249 int command_unload(int argc, char *argv[]); 250 int command_lskern(int argc, char *argv[]); 251 /* interp.c */ 252 int command_include(int argc, char *argv[]); 253 /* ls.c */ 254 int command_ls(int argc, char *argv[]); 255 256 #define COMMAND_SET(a, b, c, d) /* nothing */ 257 258 #define COMMON_COMMANDS \ 259 /* common.c */ \ 260 { "help", "detailed help", command_help }, \ 261 { "?", "list commands", command_commandlist }, \ 262 { "show", "show variable(s)", command_show }, \ 263 { "set", "set a variable", command_set }, \ 264 { "unset", "unset a variable", command_unset }, \ 265 { "echo", "echo arguments", command_echo }, \ 266 { "read", "read input from the terminal", command_read }, \ 267 { "more", "show contents of a file", command_more }, \ 268 { "lsdev", "list all devices", command_lsdev }, \ 269 \ 270 /* bcache.c XXX: Fixme: Do we need the bcache ? */ \ 271 \ 272 /* { "bcachestat", "get disk block cache stats", command_bcache }, */\ 273 \ 274 /* boot.c */ \ 275 \ 276 { "boot", "boot a file or loaded kernel", command_boot }, \ 277 { "autoboot", "boot automatically after a delay", command_autoboot }, \ 278 \ 279 /* fileload.c */ \ 280 \ 281 { "load", "load a kernel", command_load }, \ 282 { "unload", "unload all modules", command_unload }, \ 283 { "lskern", "list loaded kernel", command_lskern }, \ 284 \ 285 /* interp.c */ \ 286 \ 287 { "include", "read commands from a file", command_include }, \ 288 \ 289 /* ls.c */ \ 290 \ 291 { "ls", "list files", command_ls } 292 293 extern struct bootblk_command commands[]; 294 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 */ 302 struct 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, vaddr_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 vaddr_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, vaddr_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 }; 321 extern struct arch_switch archsw; 322 323 /* This must be provided by the MD code, but should it be in the archsw? */ 324 void delay(int delay); 325 326 void dev_cleanup(void); 327 328 time_t time(time_t *tloc); 329 330 /* calloc.c */ 331 void *calloc(unsigned int, unsigned int); 332 333 /* pager.c */ 334 extern void pager_open(void); 335 extern void pager_close(void); 336 extern int pager_output(const char *lines); 337 extern int pager_file(const char *fname); 338 339 /* environment.c */ 340 #define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */ 341 #define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */ 342 #define EV_NOHOOK (1<<2) /* don't call hook when setting */ 343 344 struct env_var; 345 typedef char *(ev_format_t)(struct env_var *ev); 346 typedef int (ev_sethook_t)(struct env_var *ev, int flags, 347 const void *value); 348 typedef int (ev_unsethook_t)(struct env_var *ev); 349 350 struct env_var 351 { 352 char *ev_name; 353 int ev_flags; 354 void *ev_value; 355 ev_sethook_t *ev_sethook; 356 ev_unsethook_t *ev_unsethook; 357 struct env_var *ev_next, *ev_prev; 358 }; 359 extern struct env_var *environ; 360 361 extern struct env_var *env_getenv(const char *name); 362 extern int env_setenv(const char *name, int flags, 363 const void *value, ev_sethook_t sethook, 364 ev_unsethook_t unsethook); 365 extern char *getenv(const char *name); 366 extern int setenv(const char *name, const char *value, 367 int overwrite); 368 extern int putenv(const char *string); 369 extern int unsetenv(const char *name); 370 371 extern ev_sethook_t env_noset; /* refuse set operation */ 372 extern ev_unsethook_t env_nounset; /* refuse unset operation */ 373 374 375 376 /* FreeBSD wrappers */ 377 378 379 struct dirent *readdirfd(int); /* XXX move to stand.h */ 380 381 #define free(ptr) dealloc(ptr, 0) /* XXX UGLY HACK!!! This should work for just now though. See: libsa/alloc.c:free() */ 382 383 /* XXX Hack Hack Hack!!! Need to update stand.h with fs_ops->fo_readdir */ 384 #ifdef SKIFS /* defined via stand/ia64/ski/Makefile */ 385 #define FS_READDIR(f, dirptr) skifs_readdir(f, dirptr) 386 #else 387 #define FS_READDIR(f, dirptr) efifs_readdir(f, dirptr) 388 #endif 389 390 /* gets.c XXX move to libsa/ */ 391 392 extern int fgetstr(char *buf, int size, int fd); 393 extern void ngets(char *, int); 394 395 /* imports from stdlib, modified for sa */ 396 397 extern long strtol(const char *, char **, int); 398 extern char *optarg; /* getopt(3) external variables */ 399 extern int optind, opterr, optopt, optreset; 400 extern int getopt(int, char * const [], const char *); 401 402 extern long strtol(const char *, char **, int); 403 404 /* XXX: From <fcntl.h>. Its not very _STANDALONE friendly */ 405 /* open-only flags */ 406 #define O_RDONLY 0x00000000 /* open for reading only */ 407 #define O_WRONLY 0x00000001 /* open for writing only */ 408 #define O_RDWR 0x00000002 /* open for reading and writing */ 409 #define O_ACCMODE 0x00000003 /* mask for above modes */ 410 411 #define ELF64_KERNELTYPE "elf kernel" 412 413 #endif /* _BOOTSTRAP_H_ */ 414