138465Smsmith/*- 238465Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 338465Smsmith * All rights reserved. 438465Smsmith * 538465Smsmith * Redistribution and use in source and binary forms, with or without 638465Smsmith * modification, are permitted provided that the following conditions 738465Smsmith * are met: 838465Smsmith * 1. Redistributions of source code must retain the above copyright 938465Smsmith * notice, this list of conditions and the following disclaimer. 1038465Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1138465Smsmith * notice, this list of conditions and the following disclaimer in the 1238465Smsmith * documentation and/or other materials provided with the distribution. 1338465Smsmith * 1438465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1538465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1638465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1738465Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1838465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1938465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2038465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2138465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2238465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2338465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2438465Smsmith * SUCH DAMAGE. 2538465Smsmith * 2650477Speter * $FreeBSD$ 2738465Smsmith */ 2838465Smsmith 29234789Smarius#ifndef _BOOTSTRAP_H_ 30234789Smarius#define _BOOTSTRAP_H_ 31234789Smarius 3238465Smsmith#include <sys/types.h> 3340553Smsmith#include <sys/queue.h> 3478195Speter#include <sys/linker_set.h> 3538465Smsmith 3638465Smsmith/* 3738465Smsmith * Generic device specifier; architecture-dependant 3838465Smsmith * versions may be larger, but should be allowed to 3938465Smsmith * overlap. 4038465Smsmith */ 4138465Smsmithstruct devdesc 4238465Smsmith{ 4338465Smsmith struct devsw *d_dev; 4438465Smsmith int d_type; 4538465Smsmith#define DEVT_NONE 0 4638465Smsmith#define DEVT_DISK 1 4738465Smsmith#define DEVT_NET 2 4886090Sjhb#define DEVT_CD 3 49185029Spjd#define DEVT_ZFS 4 50163897Smarcel int d_unit; 51201941Smarcel void *d_opendata; 5238465Smsmith}; 5338465Smsmith 5438465Smsmith/* Commands and return values; nonzero return sets command_errmsg != NULL */ 5538465Smsmithtypedef int (bootblk_cmd_t)(int argc, char *argv[]); 5638465Smsmithextern char *command_errmsg; 5738465Smsmithextern char command_errbuf[]; /* XXX blah, length */ 5838465Smsmith#define CMD_OK 0 5938465Smsmith#define CMD_ERROR 1 6038465Smsmith 6138465Smsmith/* interp.c */ 6264187Sjhbvoid interact(void); 6364187Sjhbint include(const char *filename); 6438465Smsmith 6564187Sjhb/* interp_backslash.c */ 6664187Sjhbchar *backslash(char *str); 6764187Sjhb 6839178Smsmith/* interp_parse.c */ 6964187Sjhbint parse(int *argc, char ***argv, char *str); 7039178Smsmith 7143614Sdcs/* interp_forth.c */ 7264187Sjhbvoid bf_init(void); 7364187Sjhbint bf_run(char *line); 7443614Sdcs 7538465Smsmith/* boot.c */ 7664187Sjhbint autoboot(int timeout, char *prompt); 7764187Sjhbvoid autoboot_maybe(void); 7864187Sjhbint getrootmount(char *rootdev); 7938465Smsmith 8038465Smsmith/* misc.c */ 8164187Sjhbchar *unargv(int argc, char *argv[]); 8264187Sjhbvoid hexdump(caddr_t region, size_t len); 8364187Sjhbsize_t strlenout(vm_offset_t str); 8464187Sjhbchar *strdupout(vm_offset_t str); 85134441Siedowsevoid kern_bzero(vm_offset_t dest, size_t len); 86134441Siedowseint kern_pread(int fd, vm_offset_t dest, size_t len, off_t off); 87134441Siedowsevoid *alloc_pread(int fd, off_t off, size_t len); 8838465Smsmith 8943614Sdcs/* bcache.c */ 9064187Sjhbint bcache_init(u_int nblks, size_t bsize); 9164187Sjhbvoid bcache_flush(void); 9264187Sjhbint bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, 9364187Sjhb size_t size, char *buf, size_t *rsize); 9443614Sdcs 9538465Smsmith/* 9640834Smsmith * Disk block cache 9740834Smsmith */ 9840834Smsmithstruct bcache_devdata 9940834Smsmith{ 10064187Sjhb int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); 10140834Smsmith void *dv_devdata; 10240834Smsmith}; 10340834Smsmith 10440834Smsmith/* 10538465Smsmith * Modular console support. 10638465Smsmith */ 10738465Smsmithstruct console 10838465Smsmith{ 10964187Sjhb const char *c_name; 11064187Sjhb const char *c_desc; 11138465Smsmith int c_flags; 112241299Savg#define C_PRESENTIN (1<<0) /* console can provide input */ 113241299Savg#define C_PRESENTOUT (1<<1) /* console can provide output */ 114241299Savg#define C_ACTIVEIN (1<<2) /* user wants input from console */ 115241299Savg#define C_ACTIVEOUT (1<<3) /* user wants output to console */ 11638465Smsmith void (* c_probe)(struct console *cp); /* set c_flags to match hardware */ 11738465Smsmith int (* c_init)(int arg); /* reinit XXX may need more args */ 11838465Smsmith void (* c_out)(int c); /* emit c */ 11938465Smsmith int (* c_in)(void); /* wait for and return input */ 12038465Smsmith int (* c_ready)(void); /* return nonzer if input waiting */ 12138465Smsmith}; 12238465Smsmithextern struct console *consoles[]; 12364187Sjhbvoid cons_probe(void); 12438465Smsmith 12538465Smsmith/* 12638789Smsmith * Plug-and-play enumerator/configurator interface. 12738789Smsmith */ 12840553Smsmithstruct pnphandler 12939178Smsmith{ 13064187Sjhb const char *pp_name; /* handler/bus name */ 13140553Smsmith void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */ 13239178Smsmith}; 13339178Smsmith 13440553Smsmithstruct pnpident 13538789Smsmith{ 13640553Smsmith char *id_ident; /* ASCII identifier, actual format varies with bus/handler */ 13760938Sjake STAILQ_ENTRY(pnpident) id_link; 13839178Smsmith}; 13938789Smsmith 14040553Smsmithstruct pnpinfo 14138789Smsmith{ 14240553Smsmith char *pi_desc; /* ASCII description, optional */ 14340553Smsmith int pi_revision; /* optional revision (or -1) if not supported */ 14440553Smsmith char *pi_module; /* module/args nominated to handle device */ 14540553Smsmith int pi_argc; /* module arguments */ 14640553Smsmith char **pi_argv; 14740553Smsmith struct pnphandler *pi_handler; /* handler which detected this device */ 14860938Sjake STAILQ_HEAD(,pnpident) pi_ident; /* list of identifiers */ 14960938Sjake STAILQ_ENTRY(pnpinfo) pi_link; 15038789Smsmith}; 15138789Smsmith 15265614SdcsSTAILQ_HEAD(pnpinfo_stql, pnpinfo); 15365614Sdcs 15465614Sdcsextern struct pnpinfo_stql pnp_devices; 15565614Sdcs 15639178Smsmithextern struct pnphandler *pnphandlers[]; /* provided by MD code */ 15738789Smsmith 15864187Sjhbvoid pnp_addident(struct pnpinfo *pi, char *ident); 15964187Sjhbstruct pnpinfo *pnp_allocinfo(void); 16064187Sjhbvoid pnp_freeinfo(struct pnpinfo *pi); 16164187Sjhbvoid pnp_addinfo(struct pnpinfo *pi); 16264187Sjhbchar *pnp_eisaformat(u_int8_t *data); 16339178Smsmith 16438789Smsmith/* 16540597Smsmith * < 0 - No ISA in system 16640597Smsmith * == 0 - Maybe ISA, search for read data port 16740597Smsmith * > 0 - ISA in system, value is read data port address 16840597Smsmith */ 16940597Smsmithextern int isapnp_readport; 17040597Smsmith 17140597Smsmith/* 17259854Sbp * Preloaded file metadata header. 17338465Smsmith * 17438465Smsmith * Metadata are allocated on our heap, and copied into kernel space 17538465Smsmith * before executing the kernel. 17638465Smsmith */ 17759854Sbpstruct file_metadata 17838465Smsmith{ 17938465Smsmith size_t md_size; 18038465Smsmith u_int16_t md_type; 18159854Sbp struct file_metadata *md_next; 18264187Sjhb char md_data[1]; /* data are immediately appended */ 18338465Smsmith}; 18438465Smsmith 18559854Sbpstruct preloaded_file; 18683321Speterstruct mod_depend; 18759854Sbp 18859854Sbpstruct kernel_module 18959854Sbp{ 19059854Sbp char *m_name; /* module name */ 19183321Speter int m_version; /* module version */ 19259854Sbp/* char *m_args;*/ /* arguments for the module */ 19359854Sbp struct preloaded_file *m_fp; 19459854Sbp struct kernel_module *m_next; 19559854Sbp}; 19659854Sbp 19738465Smsmith/* 19859854Sbp * Preloaded file information. Depending on type, file can contain 19959854Sbp * additional units called 'modules'. 20038465Smsmith * 20159854Sbp * At least one file (the kernel) must be loaded in order to boot. 20238465Smsmith * The kernel is always loaded first. 20338712Smsmith * 20438712Smsmith * String fields (m_name, m_type) should be dynamically allocated. 20538465Smsmith */ 20659854Sbpstruct preloaded_file 20738465Smsmith{ 20859854Sbp char *f_name; /* file name */ 20959854Sbp char *f_type; /* verbose file type, eg 'ELF kernel', 'pnptable', etc. */ 21059854Sbp char *f_args; /* arguments for the file */ 21159854Sbp struct file_metadata *f_metadata; /* metadata that will be placed in the module directory */ 21259854Sbp int f_loader; /* index of the loader that read the file */ 21359854Sbp vm_offset_t f_addr; /* load address */ 21459854Sbp size_t f_size; /* file size */ 21559854Sbp struct kernel_module *f_modules; /* list of modules if any */ 21659854Sbp struct preloaded_file *f_next; /* next file */ 21738465Smsmith}; 21838465Smsmith 21959854Sbpstruct file_format 22038465Smsmith{ 22138465Smsmith /* Load function must return EFTYPE if it can't handle the module supplied */ 222114379Speter int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); 22338712Smsmith /* Only a loader that will load a kernel (first module) should have an exec handler */ 22459854Sbp int (* l_exec)(struct preloaded_file *mp); 22538465Smsmith}; 22659854Sbp 22759854Sbpextern struct file_format *file_formats[]; /* supplied by consumer */ 22859854Sbpextern struct preloaded_file *preloaded_files; 22959854Sbp 23083321Speterint mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]); 23183321Speterint mod_loadkld(const char *name, int argc, char *argv[]); 23238465Smsmith 23359854Sbpstruct preloaded_file *file_alloc(void); 23459854Sbpstruct preloaded_file *file_findfile(char *name, char *type); 23559854Sbpstruct file_metadata *file_findmetadata(struct preloaded_file *fp, int type); 23659854Sbpvoid file_discard(struct preloaded_file *fp); 23759854Sbpvoid file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p); 23883321Speterint file_addmodule(struct preloaded_file *fp, char *modname, int version, 23959854Sbp struct kernel_module **newmp); 24039178Smsmith 24139178Smsmith/* MI module loaders */ 242114379Speter#ifdef __elfN 243134458Siedowse/* Relocation types. */ 244134458Siedowse#define ELF_RELOC_REL 1 245134458Siedowse#define ELF_RELOC_RELA 2 246134458Siedowse 247176484Smarcel/* Relocation offset for some architectures */ 248176484Smarcelextern u_int64_t __elfN(relocation_offset); 249176484Smarcel 250134458Siedowsestruct elf_file; 251153504Smarceltypedef Elf_Addr (symaddr_fn)(struct elf_file *ef, Elf_Size symidx); 252134458Siedowse 253114379Speterint __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result); 254134459Siedowseint __elfN(obj_loadfile)(char *filename, u_int64_t dest, 255134459Siedowse struct preloaded_file **result); 256134458Siedowseint __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr, 257134458Siedowse const void *reldata, int reltype, Elf_Addr relbase, 258134458Siedowse Elf_Addr dataaddr, void *data, size_t len); 259114379Speter#endif 26039178Smsmith 26138465Smsmith/* 26238465Smsmith * Support for commands 26338465Smsmith */ 26438465Smsmithstruct bootblk_command 26538465Smsmith{ 26638465Smsmith const char *c_name; 26738465Smsmith const char *c_desc; 26838465Smsmith bootblk_cmd_t *c_fn; 26938465Smsmith}; 27038465Smsmith 27138465Smsmith#define COMMAND_SET(tag, key, desc, func) \ 27238465Smsmith static bootblk_cmd_t func; \ 27338465Smsmith static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \ 27464187Sjhb DATA_SET(Xcommand_set, _cmd_ ## tag) 27538465Smsmith 27678195SpeterSET_DECLARE(Xcommand_set, struct bootblk_command); 27738465Smsmith 27838465Smsmith/* 27938712Smsmith * The intention of the architecture switch is to provide a convenient 28038712Smsmith * encapsulation of the interface between the bootstrap MI and MD code. 28138712Smsmith * MD code may selectively populate the switch at runtime based on the 28238712Smsmith * actual configuration of the target system. 28338465Smsmith */ 28438465Smsmithstruct arch_switch 28538465Smsmith{ 28638465Smsmith /* Automatically load modules as required by detected hardware */ 28764187Sjhb int (*arch_autoload)(void); 28838465Smsmith /* Locate the device for (name), return pointer to tail in (*path) */ 28964187Sjhb int (*arch_getdev)(void **dev, const char *name, const char **path); 29038712Smsmith /* Copy from local address space to module address space, similar to bcopy() */ 29164187Sjhb ssize_t (*arch_copyin)(const void *src, vm_offset_t dest, 29264187Sjhb const size_t len); 29338764Smsmith /* Copy to local address space from module address space, similar to bcopy() */ 29464187Sjhb ssize_t (*arch_copyout)(const vm_offset_t src, void *dest, 29564187Sjhb const size_t len); 29638712Smsmith /* Read from file to module address space, same semantics as read() */ 29764187Sjhb ssize_t (*arch_readin)(const int fd, vm_offset_t dest, 29864187Sjhb const size_t len); 29939178Smsmith /* Perform ISA byte port I/O (only for systems with ISA) */ 30064187Sjhb int (*arch_isainb)(int port); 30164187Sjhb void (*arch_isaoutb)(int port, int value); 302220311Smarcel 303220311Smarcel /* 304220311Smarcel * Interface to adjust the load address according to the "object" 305220311Smarcel * being loaded. 306220311Smarcel */ 307220311Smarcel uint64_t (*arch_loadaddr)(u_int type, void *data, uint64_t addr); 308220311Smarcel#define LOAD_ELF 1 /* data points to the ELF header. */ 309220311Smarcel#define LOAD_RAW 2 /* data points to the file name. */ 310220311Smarcel 311220311Smarcel /* 312220311Smarcel * Interface to inform MD code about a loaded (ELF) segment. This 313220311Smarcel * can be used to flush caches and/or set up translations. 314220311Smarcel */ 315220311Smarcel#ifdef __elfN 316220311Smarcel void (*arch_loadseg)(Elf_Ehdr *eh, Elf_Phdr *ph, uint64_t delta); 317220311Smarcel#else 318220311Smarcel void (*arch_loadseg)(void *eh, void *ph, uint64_t delta); 319220311Smarcel#endif 320235329Savg 321235329Savg /* Probe ZFS pool(s), if needed. */ 322235329Savg void (*arch_zfs_probe)(void); 32338465Smsmith}; 32438465Smsmithextern struct arch_switch archsw; 32538465Smsmith 32639178Smsmith/* This must be provided by the MD code, but should it be in the archsw? */ 32764187Sjhbvoid delay(int delay); 32861659Sps 32964187Sjhbvoid dev_cleanup(void); 33091219Sbde 33191219Sbdetime_t time(time_t *tloc); 332234789Smarius 333235153Savg#ifndef CTASSERT /* Allow lint to override */ 334235153Savg#define CTASSERT(x) _CTASSERT(x, __LINE__) 335235153Savg#define _CTASSERT(x, y) __CTASSERT(x, y) 336235153Savg#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1] 337235153Savg#endif 338235153Savg 339234789Smarius#endif /* !_BOOTSTRAP_H_ */ 340