Xyris  0.5
Handoff.cpp
Go to the documentation of this file.
1 /**
2  * @file Handoff.cpp
3  * @author Keeton Feavel ([email protected])
4  * @brief Bootloader information parsing and kernel handoff container
5  * @version 0.1
6  * @date 2021-06-02
7  *
8  * @copyright Copyright the Xyris Contributors (c) 2021
9  *
10  */
11 #include <Arch/Arch.hpp>
12 #include <Bootloader/Arguments.hpp>
13 #include <Bootloader/Handoff.hpp>
14 // System library functions
15 #include <Library/stdio.hpp>
16 #include <Library/string.hpp>
17 #include <Memory/paging.hpp>
18 #include <Logger.hpp>
19 #include <Panic.hpp>
20 // Generic devices
22 #include <Devices/Serial/rs232.hpp>
23 // Bootloaders
24 #include <stivale/stivale2.h>
25 
26 #define STIVALE2_MAGIC 0x73747632
27 
28 namespace Boot {
29 
30 /*
31  * _ _ _ __ __
32  * | || |__ _ _ _ __| |___ / _|/ _|
33  * | __ / _` | ' \/ _` / _ \ _| _|
34  * |_||_\__,_|_||_\__,_\___/_| |_|
35  *
36  */
37 
39  : m_handle(NULL)
40  , m_magic(0)
41 {
42  // Initialize nothing.
43 }
44 
45 Handoff::Handoff(void* handoff, uint32_t magic)
46  : m_handle(handoff)
47  , m_magic(magic)
48 {
49  // Parse the handle based on the magic
50  Logger::Info(__func__, "Bootloader info at 0x%p", handoff);
51  if (magic == STIVALE2_MAGIC) {
53  parseStivale2(this, handoff);
54  } else {
55  panic("Invalid bootloader magic!");
56  }
57 }
58 
59 /*
60  * ___ _ _ _ ___
61  * / __| |_(_)_ ____ _| |___|_ )
62  * \__ \ _| \ V / _` | / -_)/ /
63  * |___/\__|_|\_/\__,_|_\___/___|
64  */
65 
66 void Handoff::parseStivale2(Handoff* that, void* handoff)
67 {
68  Logger::Info(__func__, "Booted via Stivale2");
69  // Walk the list of tags in the header
70  struct stivale2_struct* fixed = (struct stivale2_struct*)handoff;
71  struct stivale2_tag* tag = (struct stivale2_tag*)(fixed->tags);
72  while (tag) {
73  switch (tag->identifier) {
74  case STIVALE2_STRUCT_TAG_MEMMAP_ID: {
75  auto memmap = (struct stivale2_struct_tag_memmap*)tag;
76  Logger::Debug(__func__, "Found %Lu Stivale2 memmap entries.", memmap->entries);
77  if (memmap->entries > that->m_memoryMap.Count()) {
78  panic("Not enough space to add all memory map entries!");
79  }
80  // Follows the tag list order in stivale2.h
81  for (size_t i = 0; i < memmap->entries; i++) {
82  auto entry = memmap->memmap[i];
83  uint64_t end = entry.base + entry.length - 1;
84  that->m_memoryMap[i] = Memory::Section(entry.base, end);
85  Logger::Debug(__func__, "[%zu] 0x%08LX-0x%08LX 0x%08LX", i, entry.base, end, entry.length);
86  // TODO: Make this a map that can be indexed
87  switch (entry.type) {
88  case STIVALE2_MMAP_USABLE:
89  that->m_memoryMap[i].setType(Memory::Available);
90  break;
91 
92  case STIVALE2_MMAP_RESERVED:
93  that->m_memoryMap[i].setType(Memory::Reserved);
94  break;
95 
96  case STIVALE2_MMAP_ACPI_RECLAIMABLE:
97  that->m_memoryMap[i].setType(Memory::ACPI);
98  break;
99 
100  case STIVALE2_MMAP_ACPI_NVS:
101  that->m_memoryMap[i].setType(Memory::NVS);
102  break;
103 
104  case STIVALE2_MMAP_BAD_MEMORY:
105  that->m_memoryMap[i].setType(Memory::Bad);
106  break;
107 
108  case STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE:
109  that->m_memoryMap[i].setType(Memory::Bootloader);
110  break;
111 
112  case STIVALE2_MMAP_KERNEL_AND_MODULES:
113  that->m_memoryMap[i].setType(Memory::Kernel);
114  break;
115 
116  default:
117  that->m_memoryMap[i].setType(Memory::Unknown);
118  break;
119  }
120  }
121  break;
122  }
123  case STIVALE2_STRUCT_TAG_CMDLINE_ID: {
124  auto cmdline = (struct stivale2_struct_tag_cmdline*)tag;
125  that->m_cmdline = (char*)(cmdline->cmdline);
126  Logger::Debug(__func__, "Stivale2 cmdline: '%s'", that->m_cmdline);
128  break;
129  }
130  case STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID: {
131  auto framebuffer = (struct stivale2_struct_tag_framebuffer*)tag;
133  __func__,
134  "Stivale2 framebuffer:\n"
135  "\tAddress: 0x%08LX\n"
136  "\tResolution: %ux%ux%u\n"
137  "\tPixel format:\n"
138  "\t\tRed size: %u\n"
139  "\t\tRed shift: %u\n"
140  "\t\tGreen size: %u\n"
141  "\t\tGreen shift: %u\n"
142  "\t\tBlue size: %u\n"
143  "\t\tBlue shift: %u",
144  framebuffer->framebuffer_addr,
145  framebuffer->framebuffer_width,
146  framebuffer->framebuffer_height,
147  framebuffer->framebuffer_bpp,
148  framebuffer->red_mask_size,
149  framebuffer->red_mask_shift,
150  framebuffer->green_mask_size,
151  framebuffer->green_mask_shift,
152  framebuffer->blue_mask_size,
153  framebuffer->blue_mask_shift);
154  // Initialize the framebuffer information
156  framebuffer->framebuffer_width,
157  framebuffer->framebuffer_height,
158  framebuffer->framebuffer_bpp,
159  framebuffer->framebuffer_pitch,
160  reinterpret_cast<void*>(framebuffer->framebuffer_addr),
161  static_cast<Graphics::FramebufferMemoryModel>(framebuffer->memory_model),
162  framebuffer->red_mask_size,
163  framebuffer->red_mask_shift,
164  framebuffer->green_mask_size,
165  framebuffer->green_mask_shift,
166  framebuffer->blue_mask_size,
167  framebuffer->blue_mask_shift);
168  break;
169  }
170  default: {
171  Logger::Debug(__func__, "Unknown Stivale2 tag: 0x%016LX", tag->identifier);
172  break;
173  }
174  }
175 
176  tag = (struct stivale2_tag*)tag->next;
177  }
178 
179  Logger::Debug(__func__, "Done parsing Stivale2 tags");
180 }
181 
182 } // !namespace Handoff
Boot::Handoff
Definition: Handoff.hpp:88
stdio.hpp
Boot::Handoff::parseStivale2
static void parseStivale2(Handoff *that, void *handoff)
Definition: Handoff.cpp:66
Graphics::FramebufferMemoryModel
FramebufferMemoryModel
Definition: framebuffer.hpp:16
Memory::ACPI
@ ACPI
Definition: MemorySection.hpp:21
console.hpp
Framebuffer console.
Boot::Handoff::Handoff
Handoff()
Definition: Handoff.cpp:38
Memory::MemoryMap::Count
size_t Count()
Returns the max number of memory sections allowed in a MemoryMap.
Definition: MemoryMap.hpp:25
Arguments.hpp
Kernel command argument parsing.
string.hpp
Standard string and memory utility library.
STIVALE2_MAGIC
#define STIVALE2_MAGIC
Definition: Handoff.cpp:26
Memory::NVS
@ NVS
Definition: MemorySection.hpp:22
Memory::Bad
@ Bad
Definition: MemorySection.hpp:23
rs232.hpp
A simple, write-only driver for the RS232 serial device standard. Code mostly ported from Panix-Archi...
Arch.hpp
Architecture control and initialization.
Logger::Info
static void Info(const char *tag, const char *fmt,...)
Definition: Logger.cpp:81
Panic.hpp
Kernel panic management.
Boot::Handoff::m_bootType
HandoffBootloaderType m_bootType
Definition: Handoff.hpp:107
Memory::Reserved
@ Reserved
Definition: MemorySection.hpp:20
Memory::Section
Definition: MemorySection.hpp:29
Graphics::Framebuffer
Definition: framebuffer.hpp:21
Handoff.hpp
paging.hpp
Logger::Debug
static void Debug(const char *tag, const char *fmt,...)
Definition: Logger.cpp:71
Boot::Handoff::m_framebuffer
Graphics::Framebuffer m_framebuffer
Definition: Handoff.hpp:106
panic
void panic(const char *msg)
Halt the system and print the provided message on the panic screen.
Definition: Panic.cpp:82
Boot::Handoff::m_memoryMap
Memory::MemoryMap m_memoryMap
Definition: Handoff.hpp:108
Memory::Kernel
@ Kernel
Definition: MemorySection.hpp:25
Memory::Available
@ Available
Definition: MemorySection.hpp:19
Boot
Definition: Arguments.cpp:15
Memory::Unknown
@ Unknown
Definition: MemorySection.hpp:26
Boot::Handoff::m_cmdline
char * m_cmdline
Definition: Handoff.hpp:104
Boot::parseCommandLine
void parseCommandLine(char *cmdline)
Parse a command line for registered arguments.
Definition: Arguments.cpp:17
Memory::Bootloader
@ Bootloader
Definition: MemorySection.hpp:24
Logger.hpp
Boot::Stivale2
@ Stivale2
Definition: Handoff.hpp:19