The Pedigree Project 0.1
BootstrapInfo.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/BootstrapInfo.h"
21#include "pedigree/kernel/compiler.h"
22#include "pedigree/kernel/processor/types.h"
23
24static_assert(sizeof(BootstrapStruct_t::MemoryMapEntry) == 32,
25 "bootstrap memory-map entries must match the UEFI wire format");
26static_assert(sizeof(BootstrapStruct_t) == 108, "bootstrap wire layout must match the UEFI loader");
27
28BootstrapStruct_t::BootstrapStruct_t() {
29 flags = 0;
30 reserved = 0;
31}
32
33void BootstrapStruct_t::setMemoryMap(const MemoryMapEntry* entries, size_t count) {
34 mmap_addr = reinterpret_cast<uintptr_t>(entries);
35 mmap_entry_size = sizeof(MemoryMapEntry);
36 mmap_length = count * mmap_entry_size;
37 flags |= BOOTSTRAP_FLAG_MEMORY_MAP;
38}
39
40void BootstrapStruct_t::setModules(const Module* modules, size_t count) {
41 mods_addr = reinterpret_cast<uintptr_t>(modules);
42 mods_count = count;
43 flags |= BOOTSTRAP_FLAG_MODULES;
44}
45
46void BootstrapStruct_t::setCommandLine(const char* text) {
47 cmdline = reinterpret_cast<uintptr_t>(text);
48 flags |= BOOTSTRAP_FLAG_CMDLINE;
49}
50
51void BootstrapStruct_t::setUefi() {
52 flags |= BOOTSTRAP_FLAG_UEFI;
53}
54
55void BootstrapStruct_t::setAcpiRsdp(uintptr_t address) {
56 acpi_rsdp = address;
57 flags |= BOOTSTRAP_FLAG_ACPI;
58}
59
60bool BootstrapStruct_t::isInitrdLoaded() const {
61 if (flags & BOOTSTRAP_FLAG_MODULES)
62 return (mods_count != 0) && mods_addr;
63 else
64 return false;
65}
66
67uint8_t* BootstrapStruct_t::getInitrdAddress() const {
68 const Module* modules = getModuleArray();
69 if (isInitrdLoaded() && modules)
70 return reinterpret_cast<uint8_t*>(modules[0].base);
71 else
72 return 0;
73}
74
75size_t BootstrapStruct_t::getInitrdSize() const {
76 const Module* modules = getModuleArray();
77 if (isInitrdLoaded() && modules)
78 return modules[0].end - modules[0].base;
79 else
80 return 0;
81}
82
83char* BootstrapStruct_t::getCommandLine() const {
84 if (flags & BOOTSTRAP_FLAG_CMDLINE)
85 return reinterpret_cast<char*>(cmdline);
86 else
87 return 0;
88}
89
90size_t BootstrapStruct_t::getSectionHeaderCount() const {
91 if (flags & BOOTSTRAP_FLAG_ELF)
92 return num;
93 else
94 return 0;
95}
96
97size_t BootstrapStruct_t::getSectionHeaderEntrySize() const {
98 if (flags & BOOTSTRAP_FLAG_ELF)
99 return size;
100 else
101 return 0;
102}
103
104size_t BootstrapStruct_t::getSectionHeaderStringTableIndex() const {
105 if (flags & BOOTSTRAP_FLAG_ELF)
106 return shndx;
107 else
108 return 0;
109}
110
111uintptr_t BootstrapStruct_t::getSectionHeaders() const {
112 if (flags & BOOTSTRAP_FLAG_ELF)
113 return addr;
114 else
115 return 0;
116}
117
118void* BootstrapStruct_t::getMemoryMap() const {
119 if (flags & BOOTSTRAP_FLAG_MEMORY_MAP)
120 return reinterpret_cast<void*>(mmap_addr);
121 else
122 return 0;
123}
124
125uint64_t BootstrapStruct_t::getMemoryMapEntryAddress(void* opaque) const {
126 if (!opaque)
127 return 0;
128
129 MemoryMapEntry* entry = reinterpret_cast<MemoryMapEntry*>(opaque);
130 return entry->address;
131}
132
133uint64_t BootstrapStruct_t::getMemoryMapEntryLength(void* opaque) const {
134 if (!opaque)
135 return 0;
136
137 MemoryMapEntry* entry = reinterpret_cast<MemoryMapEntry*>(opaque);
138 return entry->length;
139}
140
141uint32_t BootstrapStruct_t::getMemoryMapEntryType(void* opaque) const {
142 if (!opaque)
143 return 0;
144
145 MemoryMapEntry* entry = reinterpret_cast<MemoryMapEntry*>(opaque);
146 return entry->type;
147}
148
149void* BootstrapStruct_t::nextMemoryMapEntry(void* opaque) const {
150 if (!opaque)
151 return 0;
152
153 MemoryMapEntry* entry = reinterpret_cast<MemoryMapEntry*>(opaque);
154 uintptr_t entry_addr = reinterpret_cast<uintptr_t>(opaque);
155 const uintptr_t entry_size = mmap_entry_size ? mmap_entry_size : sizeof(MemoryMapEntry);
156 void* new_opaque = reinterpret_cast<void*>(entry_addr + entry_size);
157
158 if (reinterpret_cast<uintptr_t>(new_opaque) >= (mmap_addr + mmap_length))
159 return 0;
160 else
161 return new_opaque;
162}
163
164size_t BootstrapStruct_t::getModuleCount() const {
165 if (flags & BOOTSTRAP_FLAG_MODULES)
166 return mods_count;
167 else
168 return 0;
169}
170
171void* BootstrapStruct_t::getModuleBase() const {
172 if (flags & BOOTSTRAP_FLAG_MODULES)
173 return reinterpret_cast<void*>(mods_addr);
174 else
175 return 0;
176}
177
178uintptr_t BootstrapStruct_t::getAcpiRsdp() const {
179 return (flags & BOOTSTRAP_FLAG_ACPI) ? acpi_rsdp : 0;
180}
181
182uintptr_t BootstrapStruct_t::getSmbios() const {
183 return (flags & BOOTSTRAP_FLAG_SMBIOS) ? smbios : 0;
184}
185
186bool BootstrapStruct_t::isUefi() const {
187 return (flags & BOOTSTRAP_FLAG_UEFI) != 0;
188}
189
190bool BootstrapStruct_t::getFramebuffer(FramebufferInfo& info) const {
191 if (!(flags & BOOTSTRAP_FLAG_FRAMEBUFFER) || !framebuffer || !framebuffer_width ||
192 !framebuffer_height || framebuffer_bpp != 32 || framebuffer_format > 1 ||
193 framebuffer_width > ~uint32_t(0) / 4 || framebuffer_pitch < framebuffer_width * 4 ||
194 (framebuffer_pitch & 3) ||
195 static_cast<uint64_t>(framebuffer_pitch) * framebuffer_height > ~uint64_t(0) - framebuffer)
196 return false;
197 info = {framebuffer, framebuffer_width, framebuffer_height,
198 framebuffer_pitch, framebuffer_bpp, framebuffer_format};
199 return true;
200}