1/* $NetBSD: bootstrap.h,v 1.10 2017/12/10 02:32: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-dependent 39 * versions may be larger, but should be allowed to 40 * overlap. 41 */ 42 43struct 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 53typedef int (bootblk_cmd_t)(int argc, char *argv[]); 54int command_seterr(const char *fmt, ...) __printflike(1, 2); 55const char *command_geterr(void); 56 57#define CMD_OK 0 58#define CMD_ERROR 1 59 60 61/* interp.c */ 62void interact(void); 63int include(const char *filename); 64 65/* interp_backslash.c */ 66char *backslash(char *str); 67 68/* interp_parse.c */ 69int parse(int *argc, char ***argv, char *str); 70 71/* interp_forth.c */ 72void bf_init(void); 73int bf_run(char *line); 74 75/* boot.c */ 76int autoboot(int timeout, char *prompt); 77void autoboot_maybe(void); 78int getrootmount(char *rootdev); 79 80/* misc.c */ 81char *unargv(int argc, char *argv[]); 82#if 0 83void hexdump(void *region, size_t len); 84#endif 85size_t strlenout(vaddr_t str); 86char *strdupout(vaddr_t str); 87void kern_bzero(vaddr_t dest, size_t len); 88int kern_pread(int fd, vaddr_t dest, size_t len, off_t off); 89void *alloc_pread(int fd, off_t off, size_t len); 90 91/* bcache.c */ 92int bcache_init(u_int nblks, size_t bsize); 93void bcache_flush(void); 94int 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 */ 99char *strdup(const char*); 100 101/* 102 * Disk block cache 103 */ 104struct 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 */ 113struct 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}; 128extern struct console *consoles[]; 129void cons_probe(void); 130int ischar(void); 131 132/* 133 * Plug-and-play enumerator/configurator interface. 134 */ 135struct pnphandler 136{ 137 const char *pp_name; /* handler/bus name */ 138 void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */ 139}; 140 141struct pnpident 142{ 143 char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 144 STAILQ_ENTRY(pnpident) id_link; 145}; 146 147struct 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 159STAILQ_HEAD(pnpinfo_stql, pnpinfo); 160 161extern struct pnpinfo_stql pnp_devices; 162 163extern struct pnphandler *pnphandlers[]; /* provided by MD code */ 164 165void pnp_addident(struct pnpinfo *pi, char *ident); 166struct pnpinfo *pnp_allocinfo(void); 167void pnp_freeinfo(struct pnpinfo *pi); 168void pnp_addinfo(struct pnpinfo *pi); 169char *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 */ 176extern int isapnp_readport; 177 178struct 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 */ 189struct 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 201struct 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 209extern struct file_format *file_formats[]; /* supplied by consumer */ 210extern struct preloaded_file *preloaded_files; 211 212int mod_load(char *name, int argc, char *argv[]); 213int mod_loadkld(const char *name, int argc, char *argv[]); 214 215struct preloaded_file *file_alloc(void); 216struct preloaded_file *file_findfile(char *name, char *type); 217 218int file_loadkernel(char *filename, int argc, char *argv[]); 219void file_discard(struct preloaded_file *fp); 220 221int elf64_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result); 222 223/* 224 * Support for commands 225 */ 226struct 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 237int command_help(int argc, char *argv[]) ; 238int command_commandlist(int argc, char *argv[]); 239int command_show(int argc, char *argv[]); 240int command_set(int argc, char *argv[]); 241int command_unset(int argc, char *argv[]); 242int command_echo(int argc, char *argv[]); 243int command_read(int argc, char *argv[]); 244int command_more(int argc, char *argv[]); 245int 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 */ 250int command_boot(int argc, char *argv[]); 251int command_autoboot(int argc, char *argv[]); 252/* fileload.c */ 253int command_load(int argc, char *argv[]); 254int command_unload(int argc, char *argv[]); 255int command_lskern(int argc, char *argv[]); 256/* interp.c */ 257int command_include(int argc, char *argv[]); 258/* ls.c */ 259int 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 298extern 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 */ 307struct 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}; 326extern struct arch_switch archsw; 327 328/* This must be provided by the MD code, but should it be in the archsw? */ 329void delay(int delay); 330 331void dev_cleanup(void); 332 333time_t time(time_t *tloc); 334 335/* calloc.c */ 336void *calloc(unsigned int, unsigned int); 337 338/* various string functions */ 339size_t strspn(const char *s1, const char *s2); 340size_t strlen(const char *s); 341char *strcpy(char * restrict dst, const char * restrict src); 342char *strcat(char * restrict s, const char * restrict append); 343 344/* pager.c */ 345extern void pager_open(void); 346extern void pager_close(void); 347extern int pager_output(const char *lines); 348extern 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 355struct env_var; 356typedef char *(ev_format_t)(struct env_var *ev); 357typedef int (ev_sethook_t)(struct env_var *ev, int flags, 358 const void *value); 359typedef int (ev_unsethook_t)(struct env_var *ev); 360 361struct 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}; 370extern struct env_var *environ; 371 372extern struct env_var *env_getenv(const char *name); 373extern int env_setenv(const char *name, int flags, 374 const void *value, ev_sethook_t sethook, 375 ev_unsethook_t unsethook); 376extern char *getenv(const char *name); 377extern int setenv(const char *name, const char *value, 378 int overwrite); 379extern int putenv(const char *string); 380extern int unsetenv(const char *name); 381 382extern ev_sethook_t env_noset; /* refuse set operation */ 383extern ev_unsethook_t env_nounset; /* refuse unset operation */ 384 385 386 387/* FreeBSD wrappers */ 388 389 390struct 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 403extern int fgetstr(char *buf, int size, int fd); 404extern void ngets(char *, int); 405 406/* imports from stdlib, modified for sa */ 407 408extern long strtol(const char *, char **, int); 409extern char *optarg; /* getopt(3) external variables */ 410extern int optind, opterr, optopt, optreset; 411extern int getopt(int, char * const [], const char *); 412 413extern long strtol(const char *, char **, int); 414 415/* XXX: From <fcntl.h>. Its not very _STANDALONE friendly */ 416/* open-only flags */ 417#define O_RDONLY 0x00000000 /* open for reading only */ 418#define O_WRONLY 0x00000001 /* open for writing only */ 419#define O_RDWR 0x00000002 /* open for reading and writing */ 420#define O_ACCMODE 0x00000003 /* mask for above modes */ 421 422#define ELF64_KERNELTYPE "elf kernel" 423 424#endif /* _BOOTSTRAP_H_ */ 425