bootstrap.h revision 40140
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 * $Id: bootstrap.h,v 1.12 1998/10/09 07:09:22 msmith Exp $ 27 */ 28 29#include <sys/types.h> 30 31/* XXX debugging */ 32extern struct console vidconsole; 33#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();} 34 35/* 36 * Generic device specifier; architecture-dependant 37 * versions may be larger, but should be allowed to 38 * overlap. 39 */ 40struct devdesc 41{ 42 struct devsw *d_dev; 43 int d_type; 44#define DEVT_NONE 0 45#define DEVT_DISK 1 46#define DEVT_NET 2 47}; 48 49/* Commands and return values; nonzero return sets command_errmsg != NULL */ 50typedef int (bootblk_cmd_t)(int argc, char *argv[]); 51extern char *command_errmsg; 52extern char command_errbuf[]; /* XXX blah, length */ 53#define CMD_OK 0 54#define CMD_ERROR 1 55 56/* interp.c */ 57extern void interact(void); 58extern void source(char *filename); 59 60/* interp_parse.c */ 61extern int parse(int *argc, char ***argv, char *str); 62 63/* boot.c */ 64extern int autoboot(int delay, char *prompt); 65extern void autoboot_maybe(void); 66 67/* misc.c */ 68extern char *unargv(int argc, char *argv[]); 69extern void hexdump(caddr_t region, size_t len); 70extern size_t strlenout(vm_offset_t str); 71extern char *strdupout(vm_offset_t str); 72 73/* 74 * Modular console support. 75 */ 76struct console 77{ 78 char *c_name; 79 char *c_desc; 80 int c_flags; 81#define C_PRESENTIN (1<<0) 82#define C_PRESENTOUT (1<<1) 83#define C_ACTIVEIN (1<<2) 84#define C_ACTIVEOUT (1<<3) 85 void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 86 int (* c_init)(int arg); /* reinit XXX may need more args */ 87 void (* c_out)(int c); /* emit c */ 88 int (* c_in)(void); /* wait for and return input */ 89 int (* c_ready)(void); /* return nonzer if input waiting */ 90}; 91extern struct console *consoles[]; 92extern void cons_probe(void); 93 94/* 95 * Plug-and-play enumerator/configurator interface. 96 */ 97struct pnpident 98{ 99 char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 100 struct pnpident *id_next; /* the next identifier */ 101}; 102 103struct pnphandler; 104struct pnpinfo 105{ 106 struct pnpident *pi_ident; /* list of identifiers */ 107 int pi_revision; /* optional revision (or -1) if not supported */ 108 char *pi_module; /* module/args nominated to handle device */ 109 int pi_argc; /* module arguments */ 110 char **pi_argv; 111 struct pnphandler *pi_handler; /* handler which detected this device */ 112 struct pnpinfo *pi_next; 113}; 114 115struct pnphandler 116{ 117 char *pp_name; /* handler/bus name */ 118 void (* pp_enumerate)(struct pnpinfo **); /* add detected devices to chain */ 119}; 120 121extern struct pnphandler *pnphandlers[]; /* provided by MD code */ 122 123extern void pnp_addident(struct pnpinfo *pi, char *ident); 124 125/* 126 * Module metadata header. 127 * 128 * Metadata are allocated on our heap, and copied into kernel space 129 * before executing the kernel. 130 */ 131struct module_metadata 132{ 133 size_t md_size; 134 u_int16_t md_type; 135 struct module_metadata *md_next; 136 char md_data[0]; /* data are immediately appended */ 137}; 138 139/* 140 * Loaded module information. 141 * 142 * At least one module (the kernel) must be loaded in order to boot. 143 * The kernel is always loaded first. 144 * 145 * String fields (m_name, m_type) should be dynamically allocated. 146 */ 147struct loaded_module 148{ 149 char *m_name; /* module name */ 150 char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */ 151 char *m_args; /* arguments for the module */ 152 struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */ 153 int m_loader; /* index of the loader that read the file */ 154 vm_offset_t m_addr; /* load address */ 155 size_t m_size; /* module size */ 156 struct loaded_module *m_next; /* next module */ 157}; 158 159struct module_format 160{ 161 /* Load function must return EFTYPE if it can't handle the module supplied */ 162 int (* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result); 163 /* Only a loader that will load a kernel (first module) should have an exec handler */ 164 int (* l_exec)(struct loaded_module *mp); 165}; 166extern struct module_format *module_formats[]; /* supplied by consumer */ 167extern struct loaded_module *loaded_modules; 168extern int mod_load(char *name, int argc, char *argv[]); 169extern int mod_loadobj(char *type, char *name); 170extern struct loaded_module *mod_findmodule(char *name, char *type); 171extern void mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p); 172extern struct module_metadata *mod_findmetadata(struct loaded_module *mp, int type); 173extern void mod_discard(struct loaded_module *mp); 174extern struct loaded_module *mod_allocmodule(void); 175 176 177/* MI module loaders */ 178extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); 179extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp); 180 181extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); 182 183#if defined(__ELF__) 184 185/* 186 * Alpha GAS needs an align before the section change. It seems to assume 187 * that after the .previous, it is aligned, so the following .align 3 is 188 * ignored. Since the previous instructions often contain strings, this is 189 * a problem. 190 */ 191 192#ifdef __alpha__ 193#define MAKE_SET(set, sym) \ 194 static void const * const __set_##set##_sym_##sym = &sym; \ 195 __asm(".align 3"); \ 196 __asm(".section .set." #set ",\"aw\""); \ 197 __asm(".quad " #sym); \ 198 __asm(".previous") 199#else 200#define MAKE_SET(set, sym) \ 201 static void const * const __set_##set##_sym_##sym = &sym; \ 202 __asm(".section .set." #set ",\"aw\""); \ 203 __asm(".long " #sym); \ 204 __asm(".previous") 205#endif 206#define TEXT_SET(set, sym) MAKE_SET(set, sym) 207#define DATA_SET(set, sym) MAKE_SET(set, sym) 208#define BSS_SET(set, sym) MAKE_SET(set, sym) 209#define ABS_SET(set, sym) MAKE_SET(set, sym) 210 211#else 212 213/* 214 * Linker set support, directly from <sys/kernel.h> 215 * 216 * NB: the constants defined below must match those defined in 217 * ld/ld.h. Since their calculation requires arithmetic, we 218 * can't name them symbolically (e.g., 23 is N_SETT | N_EXT). 219 */ 220#define MAKE_SET(set, sym, type) \ 221 static void const * const __set_##set##_sym_##sym = &sym; \ 222 __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym) 223#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23) 224#define DATA_SET(set, sym) MAKE_SET(set, sym, 25) 225#define BSS_SET(set, sym) MAKE_SET(set, sym, 27) 226#define ABS_SET(set, sym) MAKE_SET(set, sym, 21) 227 228#endif 229 230struct linker_set { 231 int ls_length; 232 const void *ls_items[1]; /* really ls_length of them, trailing NULL */ 233}; 234 235/* 236 * Support for commands 237 */ 238struct bootblk_command 239{ 240 const char *c_name; 241 const char *c_desc; 242 bootblk_cmd_t *c_fn; 243}; 244 245#define COMMAND_SET(tag, key, desc, func) \ 246 static bootblk_cmd_t func; \ 247 static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ 248 DATA_SET(Xcommand_set, _cmd_ ## tag); 249 250extern struct linker_set Xcommand_set; 251 252/* 253 * The intention of the architecture switch is to provide a convenient 254 * encapsulation of the interface between the bootstrap MI and MD code. 255 * MD code may selectively populate the switch at runtime based on the 256 * actual configuration of the target system. 257 */ 258struct arch_switch 259{ 260 /* Automatically load modules as required by detected hardware */ 261 int (* arch_autoload)(); 262 /* Locate the device for (name), return pointer to tail in (*path) */ 263 int (*arch_getdev)(void **dev, const char *name, const char **path); 264 /* Copy from local address space to module address space, similar to bcopy() */ 265 int (*arch_copyin)(void *src, vm_offset_t dest, size_t len); 266 /* Copy to local address space from module address space, similar to bcopy() */ 267 int (*arch_copyout)(vm_offset_t src, void *dest, size_t len); 268 /* Read from file to module address space, same semantics as read() */ 269 int (*arch_readin)(int fd, vm_offset_t dest, size_t len); 270 /* Perform ISA byte port I/O (only for systems with ISA) */ 271 int (*arch_isainb)(int port); 272 void (*arch_isaoutb)(int port, int value); 273}; 274extern struct arch_switch archsw; 275 276/* This must be provided by the MD code, but should it be in the archsw? */ 277extern void delay(int delay); 278