1235154Savg/*-
2235154Savg * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>
3235154Savg * All rights reserved.
4235154Savg *
5235154Savg * Redistribution and use in source and binary forms are freely
6235154Savg * permitted provided that the above copyright notice and this
7235154Savg * paragraph and the following disclaimer are duplicated in all
8235154Savg * such forms.
9235154Savg *
10235154Savg * This software is provided "AS IS" and without any express or
11235154Savg * implied warranties, including, without limitation, the implied
12235154Savg * warranties of merchantability and fitness for a particular
13235154Savg * purpose.
14235154Savg *
15235154Savg * $FreeBSD: stable/11/stand/i386/common/bootargs.h 344399 2019-02-20 23:55:35Z kevans $
16235154Savg */
17235154Savg
18235154Savg#ifndef _BOOT_I386_ARGS_H_
19235154Savg#define	_BOOT_I386_ARGS_H_
20235154Savg
21344399Skevans#define	KARGS_FLAGS_CD		0x0001	/* .bootdev is a bios CD dev */
22344399Skevans#define	KARGS_FLAGS_PXE		0x0002	/* .pxeinfo is valid */
23344399Skevans#define	KARGS_FLAGS_ZFS		0x0004	/* .zfspool is valid, EXTARG is zfs_boot_args */
24344399Skevans#define	KARGS_FLAGS_EXTARG	0x0008	/* variably sized extended argument */
25344399Skevans#define	KARGS_FLAGS_GELI	0x0010	/* EXTARG is geli_boot_args */
26235154Savg
27235154Savg#define	BOOTARGS_SIZE	24	/* sizeof(struct bootargs) */
28235154Savg#define	BA_BOOTFLAGS	8	/* offsetof(struct bootargs, bootflags) */
29235154Savg#define	BA_BOOTINFO	20	/* offsetof(struct bootargs, bootinfo) */
30235154Savg#define	BI_SIZE		48	/* offsetof(struct bootinfo, bi_size) */
31235154Savg
32235154Savg/*
33235154Savg * We reserve some space above BTX allocated stack for the arguments
34235154Savg * and certain data that could hang off them.  Currently only struct bootinfo
35235154Savg * is supported in that category.  The bootinfo is placed at the top
36235154Savg * of the arguments area and the actual arguments are placed at ARGOFF offset
37235154Savg * from the top and grow towards the top.  Hopefully we have enough space
38235154Savg * for bootinfo and the arguments to not run into each other.
39235154Savg * Arguments area below ARGOFF is reserved for future use.
40235154Savg */
41235154Savg#define	ARGSPACE	0x1000	/* total size of the BTX args area */
42235154Savg#define	ARGOFF		0x800	/* actual args offset within the args area */
43235154Savg#define	ARGADJ		(ARGSPACE - ARGOFF)
44235154Savg
45235154Savg#ifndef __ASSEMBLER__
46235154Savg
47344399Skevans/*
48344399Skevans * This struct describes the contents of the stack on entry to btxldr.S.  This
49344399Skevans * is the data that follows the return address, so it begins at 4(%esp).  On
50344399Skevans * the sending side, this data is passed as individual args to __exec().  On the
51344399Skevans * receiving side, code in btxldr.S copies the data from the entry stack to a
52344399Skevans * known fixed location in the new address space.  Then, btxcsu.S sets the
53344399Skevans * global variable __args to point to that known fixed location before calling
54344399Skevans * main(), which casts __args to a struct bootargs pointer to access the data.
55344399Skevans * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra
56344399Skevans * args data is copied along with the other bootargs from the entry stack to the
57344399Skevans * fixed location in the new address space.
58344399Skevans *
59344399Skevans * The bootinfo field is actually a pointer to a bootinfo struct that has been
60344399Skevans * converted to uint32_t using VTOP().  On the receiving side it must be
61344399Skevans * converted back to a pointer using PTOV().  Code in btxldr.S is aware of this
62344399Skevans * field and if it's non-NULL it copies the data it points to into another known
63344399Skevans * fixed location, and adjusts the bootinfo field to point to that new location.
64344399Skevans */
65235154Savgstruct bootargs
66235154Savg{
67235154Savg	uint32_t			howto;
68235154Savg	uint32_t			bootdev;
69235154Savg	uint32_t			bootflags;
70235154Savg	union {
71235154Savg		struct {
72235154Savg			uint32_t	pxeinfo;
73235154Savg			uint32_t	reserved;
74235154Savg		};
75235154Savg		uint64_t		zfspool;
76235154Savg	};
77235154Savg	uint32_t			bootinfo;
78235154Savg
79235154Savg	/*
80235154Savg	 * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields
81235154Savg	 * are followed by a uint32_t field that specifies a size of the
82235154Savg	 * extended arguments (including the size field).
83235154Savg	 */
84235154Savg};
85235154Savg
86329099Skevans#ifdef LOADER_GELI_SUPPORT
87329099Skevans#include <crypto/intake.h>
88344399Skevans#include "geliboot.h"
89329099Skevans#endif
90329099Skevans
91344399Skevans/*
92344399Skevans * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader)
93344399Skevans * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader).
94344399Skevans */
95344399Skevansstruct geli_boot_data
96296963Sallanjude{
97329099Skevans    union {
98329099Skevans        char            gelipw[256];
99329099Skevans        struct {
100329099Skevans            char                notapw;	/*
101329099Skevans					 * single null byte to stop keybuf
102329099Skevans					 * being interpreted as a password
103329099Skevans					 */
104329099Skevans            uint32_t            keybuf_sentinel;
105329099Skevans#ifdef LOADER_GELI_SUPPORT
106329099Skevans            struct keybuf       *keybuf;
107329099Skevans#else
108329099Skevans            void                *keybuf;
109329099Skevans#endif
110329099Skevans        };
111329099Skevans    };
112296963Sallanjude};
113296963Sallanjude
114344399Skevans#ifdef LOADER_GELI_SUPPORT
115344399Skevans
116344399Skevansstatic inline void
117344399Skevansexport_geli_boot_data(struct geli_boot_data *gbdata)
118344399Skevans{
119344399Skevans
120344399Skevans	gbdata->notapw = '\0';
121344399Skevans	gbdata->keybuf_sentinel = KEYBUF_SENTINEL;
122344399Skevans	gbdata->keybuf = malloc(sizeof(struct keybuf) +
123344399Skevans	    (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
124344399Skevans	geli_export_key_buffer(gbdata->keybuf);
125344399Skevans}
126344399Skevans
127344399Skevansstatic inline void
128344399Skevansimport_geli_boot_data(struct geli_boot_data *gbdata)
129344399Skevans{
130344399Skevans
131344399Skevans	if (gbdata->gelipw[0] != '\0') {
132344399Skevans	    setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1);
133344399Skevans	    explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw));
134344399Skevans	} else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) {
135344399Skevans	    geli_import_key_buffer(gbdata->keybuf);
136344399Skevans	}
137344399Skevans}
138344399Skevans#endif /* LOADER_GELI_SUPPORT */
139344399Skevans
140344399Skevansstruct geli_boot_args
141344399Skevans{
142344399Skevans	uint32_t		size;
143344399Skevans	struct geli_boot_data	gelidata;
144344399Skevans};
145344399Skevans
146344399Skevansstruct zfs_boot_args
147344399Skevans{
148344399Skevans	uint32_t		size;
149344399Skevans	uint32_t		reserved;
150344399Skevans	uint64_t		pool;
151344399Skevans	uint64_t		root;
152344399Skevans	uint64_t		primary_pool;
153344399Skevans	uint64_t		primary_vdev;
154344399Skevans	struct geli_boot_data	gelidata;
155344399Skevans};
156344399Skevans
157235154Savg#endif /*__ASSEMBLER__*/
158235154Savg
159235154Savg#endif	/* !_BOOT_I386_ARGS_H_ */
160