1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2011 Nathan Whitehorn
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$
29 */
30
31#include <sys/types.h>
32#include <sys/sysctl.h>
33#include <string.h>
34
35#include "partedit.h"
36
37/* EFI partition size in bytes */
38#define	EFI_BOOTPART_SIZE	(200 * 1024 * 1024)
39#define	EFI_BOOTPART_PATH	"/boot/boot1.efifat"
40
41static const char *
42x86_bootmethod(void)
43{
44	static char fw[255] = "";
45	size_t len = sizeof(fw);
46	int error;
47
48	if (strlen(fw) == 0) {
49		error = sysctlbyname("machdep.bootmethod", fw, &len, NULL, -1);
50		if (error != 0)
51			return ("BIOS");
52	}
53
54	return (fw);
55}
56
57const char *
58default_scheme(void)
59{
60	if (strcmp(x86_bootmethod(), "UEFI") == 0)
61		return ("GPT");
62	else
63		return ("MBR");
64}
65
66int
67is_scheme_bootable(const char *part_type)
68{
69
70	if (strcmp(part_type, "GPT") == 0)
71		return (1);
72	if (strcmp(x86_bootmethod(), "BIOS") == 0) {
73		if (strcmp(part_type, "BSD") == 0)
74			return (1);
75		if (strcmp(part_type, "MBR") == 0)
76			return (1);
77	}
78
79	return (0);
80}
81
82int
83is_fs_bootable(const char *part_type, const char *fs)
84{
85
86	if (strcmp(fs, "freebsd-ufs") == 0)
87		return (1);
88
89	if (strcmp(fs, "freebsd-zfs") == 0 &&
90	    strcmp(part_type, "GPT") == 0 &&
91	    strcmp(x86_bootmethod(), "BIOS") == 0)
92		return (1);
93
94	return (0);
95}
96
97size_t
98bootpart_size(const char *scheme)
99{
100
101	/* No partcode except for GPT */
102	if (strcmp(scheme, "GPT") != 0)
103		return (0);
104
105	if (strcmp(x86_bootmethod(), "BIOS") == 0)
106		return (512*1024);
107	else
108		return (EFI_BOOTPART_SIZE);
109
110	return (0);
111}
112
113const char *
114bootpart_type(const char *scheme, const char **mountpoint)
115{
116
117	if (strcmp(x86_bootmethod(), "UEFI") == 0)
118		return ("efi");
119
120	return ("freebsd-boot");
121}
122
123const char *
124bootcode_path(const char *part_type)
125{
126
127	if (strcmp(x86_bootmethod(), "UEFI") == 0)
128		return (NULL);
129
130	if (strcmp(part_type, "GPT") == 0)
131		return ("/boot/pmbr");
132	if (strcmp(part_type, "MBR") == 0)
133		return ("/boot/mbr");
134	if (strcmp(part_type, "BSD") == 0)
135		return ("/boot/boot");
136
137	return (NULL);
138}
139
140const char *
141partcode_path(const char *part_type, const char *fs_type)
142{
143
144	if (strcmp(part_type, "GPT") == 0) {
145		if (strcmp(x86_bootmethod(), "UEFI") == 0)
146			return (EFI_BOOTPART_PATH);
147		else if (strcmp(fs_type, "zfs") == 0)
148			return ("/boot/gptzfsboot");
149		else
150			return ("/boot/gptboot");
151	}
152
153	/* No partcode except for GPT */
154	return (NULL);
155}
156
157