mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
Move to RAII-style status_line objects for console status
This commit is contained in:
@@ -22,7 +22,19 @@ static constexpr int level_ok = 0;
|
|||||||
static constexpr int level_warn = 1;
|
static constexpr int level_warn = 1;
|
||||||
static constexpr int level_fail = 2;
|
static constexpr int level_fail = 2;
|
||||||
|
|
||||||
|
static const wchar_t *level_tags[] = {
|
||||||
|
L" ok ",
|
||||||
|
L" warn ",
|
||||||
|
L"failed"
|
||||||
|
};
|
||||||
|
static const uefi::attribute level_colors[] = {
|
||||||
|
uefi::attribute::green,
|
||||||
|
uefi::attribute::brown,
|
||||||
|
uefi::attribute::light_red
|
||||||
|
};
|
||||||
|
|
||||||
console *console::s_console = nullptr;
|
console *console::s_console = nullptr;
|
||||||
|
status_line *status_line::s_current = nullptr;
|
||||||
|
|
||||||
static const wchar_t digits[] = {u'0', u'1', u'2', u'3', u'4', u'5',
|
static const wchar_t digits[] = {u'0', u'1', u'2', u'3', u'4', u'5',
|
||||||
u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'};
|
u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'};
|
||||||
@@ -30,8 +42,6 @@ static const wchar_t digits[] = {u'0', u'1', u'2', u'3', u'4', u'5',
|
|||||||
console::console(uefi::boot_services *bs, uefi::protos::simple_text_output *out) :
|
console::console(uefi::boot_services *bs, uefi::protos::simple_text_output *out) :
|
||||||
m_rows(0),
|
m_rows(0),
|
||||||
m_cols(0),
|
m_cols(0),
|
||||||
m_status_level(0),
|
|
||||||
m_status_line(0),
|
|
||||||
m_out(out)
|
m_out(out)
|
||||||
{
|
{
|
||||||
pick_mode(bs);
|
pick_mode(bs);
|
||||||
@@ -253,98 +263,113 @@ console::print(const wchar_t *fmt, ...)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
status_line::status_line(const wchar_t *message) :
|
||||||
console::status_begin(const wchar_t *message)
|
m_level(level_ok)
|
||||||
{
|
{
|
||||||
m_status_line = m_out->mode->cursor_row;
|
auto out = console::get().m_out;
|
||||||
m_status_level = level_ok;
|
m_line = out->mode->cursor_row;
|
||||||
|
m_depth = (s_current ? 1 + s_current->m_depth : 0);
|
||||||
|
|
||||||
m_out->set_cursor_position(0, m_status_line);
|
int indent = 2 * m_depth;
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
out->set_cursor_position(indent, m_line);
|
||||||
m_out->output_string(message);
|
out->set_attribute(uefi::attribute::light_gray);
|
||||||
m_out->output_string(L"\r\n");
|
out->output_string(message);
|
||||||
|
out->output_string(L"\r\n");
|
||||||
|
|
||||||
|
m_next = s_current;
|
||||||
|
s_current = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_line::~status_line()
|
||||||
|
{
|
||||||
|
if (s_current != this)
|
||||||
|
error::raise(uefi::status::unsupported, L"Destroying non-current status_line");
|
||||||
|
|
||||||
|
finish();
|
||||||
|
if (m_next && m_level > m_next->m_level) {
|
||||||
|
m_next->m_level = m_level;
|
||||||
|
m_next->print_status_tag();
|
||||||
|
}
|
||||||
|
s_current = m_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console::status_end()
|
status_line::print_status_tag()
|
||||||
{
|
{
|
||||||
if (m_status_level > level_ok)
|
auto out = console::get().m_out;
|
||||||
return;
|
int row = out->mode->cursor_row;
|
||||||
|
int col = out->mode->cursor_column;
|
||||||
|
|
||||||
int row = m_out->mode->cursor_row;
|
uefi::attribute color = level_colors[m_level];
|
||||||
int col = m_out->mode->cursor_column;
|
const wchar_t *tag = level_tags[m_level];
|
||||||
|
|
||||||
m_out->set_cursor_position(50, m_status_line);
|
out->set_cursor_position(50, m_line);
|
||||||
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
out->set_attribute(uefi::attribute::light_gray);
|
||||||
m_out->output_string(L"[");
|
out->output_string(L"[");
|
||||||
m_out->set_attribute(uefi::attribute::green);
|
out->set_attribute(color);
|
||||||
m_out->output_string(L" ok ");
|
out->output_string(tag);
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
out->set_attribute(uefi::attribute::light_gray);
|
||||||
m_out->output_string(L"]\r\n");
|
out->output_string(L"]\r\n");
|
||||||
|
|
||||||
m_out->set_cursor_position(col, row);
|
out->set_cursor_position(col, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console::status_warn(const wchar_t *message, const wchar_t *error)
|
status_line::do_warn(const wchar_t *message, const wchar_t *error)
|
||||||
{
|
{
|
||||||
int row = m_out->mode->cursor_row;
|
auto out = console::get().m_out;
|
||||||
|
int row = out->mode->cursor_row;
|
||||||
|
|
||||||
if (m_status_level <= level_warn) {
|
if (m_level < level_warn) {
|
||||||
m_status_level = level_warn;
|
m_level = level_warn;
|
||||||
|
print_status_tag();
|
||||||
m_out->set_cursor_position(50, m_status_line);
|
|
||||||
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
|
||||||
m_out->output_string(L"[");
|
|
||||||
m_out->set_attribute(uefi::attribute::brown);
|
|
||||||
m_out->output_string(L" warn ");
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
|
||||||
m_out->output_string(L"]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->set_cursor_position(4, row);
|
int indent = 2 + 2 * m_depth;
|
||||||
|
out->set_cursor_position(indent, row);
|
||||||
m_out->set_attribute(uefi::attribute::yellow);
|
out->set_attribute(uefi::attribute::yellow);
|
||||||
m_out->output_string(message);
|
out->output_string(message);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
m_out->output_string(L": ");
|
out->output_string(L": ");
|
||||||
m_out->output_string(error);
|
out->output_string(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
out->set_attribute(uefi::attribute::light_gray);
|
||||||
m_out->output_string(L"\r\n");
|
out->output_string(L"\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
console::status_fail(const wchar_t *message, const wchar_t *error)
|
status_line::do_fail(const wchar_t *message, const wchar_t *error)
|
||||||
{
|
{
|
||||||
m_status_level = level_fail;
|
auto out = console::get().m_out;
|
||||||
|
int row = out->mode->cursor_row;
|
||||||
|
|
||||||
int row = m_out->mode->cursor_row;
|
if (s_current->m_level < level_fail) {
|
||||||
m_out->set_cursor_position(50, m_status_line);
|
m_level = level_fail;
|
||||||
|
print_status_tag();
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
|
||||||
m_out->output_string(L"[");
|
|
||||||
m_out->set_attribute(uefi::attribute::light_red);
|
|
||||||
m_out->output_string(L"failed");
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
|
||||||
m_out->output_string(L"]");
|
|
||||||
|
|
||||||
m_out->set_cursor_position(4, row);
|
|
||||||
|
|
||||||
m_out->set_attribute(uefi::attribute::red);
|
|
||||||
m_out->output_string(message);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
m_out->output_string(L": ");
|
|
||||||
m_out->output_string(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_out->set_attribute(uefi::attribute::light_gray);
|
int indent = 2 + 2 * m_depth;
|
||||||
m_out->output_string(L"\r\n");
|
out->set_cursor_position(indent, row);
|
||||||
|
out->set_attribute(uefi::attribute::red);
|
||||||
|
out->output_string(message);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
out->output_string(L": ");
|
||||||
|
out->output_string(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
out->set_attribute(uefi::attribute::light_gray);
|
||||||
|
out->output_string(L"\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
status_line::finish()
|
||||||
|
{
|
||||||
|
if (m_level <= level_ok)
|
||||||
|
print_status_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -11,11 +11,6 @@ class console
|
|||||||
public:
|
public:
|
||||||
console(uefi::boot_services *bs, uefi::protos::simple_text_output *out);
|
console(uefi::boot_services *bs, uefi::protos::simple_text_output *out);
|
||||||
|
|
||||||
void status_begin(const wchar_t *message);
|
|
||||||
void status_warn(const wchar_t *message, const wchar_t *error=nullptr);
|
|
||||||
void status_fail(const wchar_t *message, const wchar_t *error=nullptr);
|
|
||||||
void status_end();
|
|
||||||
|
|
||||||
size_t print_hex(uint32_t n) const;
|
size_t print_hex(uint32_t n) const;
|
||||||
size_t print_dec(uint32_t n) const;
|
size_t print_dec(uint32_t n) const;
|
||||||
size_t print_long_hex(uint64_t n) const;
|
size_t print_long_hex(uint64_t n) const;
|
||||||
@@ -26,19 +21,45 @@ public:
|
|||||||
static size_t print(const wchar_t *fmt, ...);
|
static size_t print(const wchar_t *fmt, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class status_line;
|
||||||
|
|
||||||
void pick_mode(uefi::boot_services *bs);
|
void pick_mode(uefi::boot_services *bs);
|
||||||
size_t vprintf(const wchar_t *fmt, va_list args) const;
|
size_t vprintf(const wchar_t *fmt, va_list args) const;
|
||||||
|
|
||||||
size_t m_rows, m_cols;
|
size_t m_rows, m_cols;
|
||||||
|
|
||||||
int m_status_level;
|
|
||||||
int m_status_line;
|
|
||||||
|
|
||||||
uefi::protos::simple_text_output *m_out;
|
uefi::protos::simple_text_output *m_out;
|
||||||
|
|
||||||
static console *s_console;
|
static console *s_console;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class status_line
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
status_line(const wchar_t *message);
|
||||||
|
~status_line();
|
||||||
|
|
||||||
|
inline static void warn(const wchar_t *message, const wchar_t *error=nullptr) {
|
||||||
|
if (s_current) s_current->do_warn(message, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void fail(const wchar_t *message, const wchar_t *error=nullptr) {
|
||||||
|
if (s_current) s_current->do_fail(message, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void print_status_tag();
|
||||||
|
void do_warn(const wchar_t *message, const wchar_t *error);
|
||||||
|
void do_fail(const wchar_t *message, const wchar_t *error);
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
size_t m_line;
|
||||||
|
int m_level;
|
||||||
|
int m_depth;
|
||||||
|
|
||||||
|
status_line *m_next;
|
||||||
|
static status_line *s_current;
|
||||||
|
};
|
||||||
|
|
||||||
uefi::status
|
uefi::status
|
||||||
con_get_framebuffer(
|
con_get_framebuffer(
|
||||||
uefi::boot_services *bs,
|
uefi::boot_services *bs,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ uefi_handler::uefi_handler(console &con) :
|
|||||||
[[ noreturn ]] void
|
[[ noreturn ]] void
|
||||||
uefi_handler::handle(uefi::status s, const wchar_t *message)
|
uefi_handler::handle(uefi::status s, const wchar_t *message)
|
||||||
{
|
{
|
||||||
m_con.status_fail(message, error_message(s));
|
status_line::fail(message, error_message(s));
|
||||||
while (1) asm("hlt");
|
while (1) asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,9 +83,11 @@ detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uintptr_t
|
void *
|
||||||
find_acpi_table(uefi::system_table *st)
|
find_acpi_table(uefi::system_table *st)
|
||||||
{
|
{
|
||||||
|
status_line status(L"Searching for ACPI table");
|
||||||
|
|
||||||
// Find ACPI tables. Ignore ACPI 1.0 if a 2.0 table is found.
|
// Find ACPI tables. Ignore ACPI 1.0 if a 2.0 table is found.
|
||||||
uintptr_t acpi1_table = 0;
|
uintptr_t acpi1_table = 0;
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ find_acpi_table(uefi::system_table *st)
|
|||||||
|
|
||||||
// If we find an ACPI 2.0 table, return it immediately
|
// If we find an ACPI 2.0 table, return it immediately
|
||||||
if (table->vendor_guid == uefi::vendor_guids::acpi2)
|
if (table->vendor_guid == uefi::vendor_guids::acpi2)
|
||||||
return reinterpret_cast<uintptr_t>(table->vendor_table);
|
return table->vendor_table;
|
||||||
|
|
||||||
if (table->vendor_guid == uefi::vendor_guids::acpi1) {
|
if (table->vendor_guid == uefi::vendor_guids::acpi1) {
|
||||||
// Mark a v1 table with the LSB high
|
// Mark a v1 table with the LSB high
|
||||||
@@ -103,7 +105,13 @@ find_acpi_table(uefi::system_table *st)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return acpi1_table;
|
if (!acpi1_table) {
|
||||||
|
error::raise(uefi::status::not_found, L"Could not find ACPI table");
|
||||||
|
} else if (acpi1_table & 1) {
|
||||||
|
status_line::warn(L"Only found ACPI 1.0 table");
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<void*>(acpi1_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
uefi::status
|
uefi::status
|
||||||
@@ -114,53 +122,51 @@ bootloader_main_uefi(uefi::system_table *st, console &con)
|
|||||||
uefi::boot_services *bs = st->boot_services;
|
uefi::boot_services *bs = st->boot_services;
|
||||||
uefi::runtime_services *rs = st->runtime_services;
|
uefi::runtime_services *rs = st->runtime_services;
|
||||||
|
|
||||||
con.status_begin(L"Initializing pointer fixup for virtualization");
|
|
||||||
memory::init_pointer_fixup(bs, rs);
|
memory::init_pointer_fixup(bs, rs);
|
||||||
con.status_end();
|
|
||||||
|
|
||||||
con.status_begin(L"Searching for ACPI table");
|
void *acpi_table = find_acpi_table(st);
|
||||||
uintptr_t acpi_table = find_acpi_table(st);
|
|
||||||
if (!acpi_table) {
|
|
||||||
error::raise(uefi::status::not_found, L"Could not find ACPI table");
|
|
||||||
} else if (acpi_table & 1) {
|
|
||||||
con.status_warn(L"Only found ACPI 1.0 table");
|
|
||||||
}
|
|
||||||
con.status_end();
|
|
||||||
|
|
||||||
con.status_begin(L"Setting up kernel args memory");
|
|
||||||
kernel::args::header *args = nullptr;
|
kernel::args::header *args = nullptr;
|
||||||
|
kernel::args::module *modules = nullptr;
|
||||||
|
|
||||||
size_t args_size =
|
{
|
||||||
sizeof(kernel::args::header) + // The header itself
|
status_line status(L"Setting up kernel args memory");
|
||||||
max_modules * sizeof(kernel::args::module); // The module structures
|
|
||||||
|
|
||||||
try_or_raise(
|
size_t args_size =
|
||||||
bs->allocate_pool(
|
sizeof(kernel::args::header) + // The header itself
|
||||||
uefi::memory_type::loader_data,
|
max_modules * sizeof(kernel::args::module); // The module structures
|
||||||
args_size,
|
|
||||||
reinterpret_cast<void**>(&args)),
|
|
||||||
L"Could not allocate argument memory");
|
|
||||||
|
|
||||||
kernel::args::module *modules =
|
try_or_raise(
|
||||||
reinterpret_cast<kernel::args::module*>(args + 1);
|
bs->allocate_pool(
|
||||||
|
uefi::memory_type::loader_data,
|
||||||
|
args_size,
|
||||||
|
reinterpret_cast<void**>(&args)),
|
||||||
|
L"Could not allocate argument memory");
|
||||||
|
|
||||||
args->magic = kernel::args::magic;
|
modules = reinterpret_cast<kernel::args::module*>(args + 1);
|
||||||
args->version = kernel::args::version;
|
|
||||||
args->runtime_services = rs;
|
|
||||||
args->acpi_table = reinterpret_cast<void*>(acpi_table);
|
|
||||||
args->modules = modules;
|
|
||||||
args->num_modules = 0;
|
|
||||||
|
|
||||||
con.status_end();
|
args->magic = kernel::args::magic;
|
||||||
|
args->version = kernel::args::version;
|
||||||
|
args->runtime_services = rs;
|
||||||
|
args->acpi_table = reinterpret_cast<void*>(acpi_table);
|
||||||
|
args->modules = modules;
|
||||||
|
args->num_modules = 0;
|
||||||
|
}
|
||||||
|
|
||||||
con.status_begin(L"Loading initrd into memory");
|
{
|
||||||
kernel::args::module &initrd = modules[args->num_modules++];
|
status_line status(L"Loading modules");
|
||||||
initrd.type = kernel::args::type::initrd;
|
{
|
||||||
con.status_end();
|
status_line status(L"Finding boot device");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
status_line status(L"Loading initrd into memory");
|
||||||
|
status_line::warn(L"I can't even");
|
||||||
|
|
||||||
|
kernel::args::module &initrd = modules[args->num_modules++];
|
||||||
|
initrd.type = kernel::args::type::initrd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
while(1);
|
|
||||||
return uefi::status::success;
|
return uefi::status::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +296,9 @@ efi_main(uefi::handle image_handle, uefi::system_table *st)
|
|||||||
error::cpu_assert_handler handler;
|
error::cpu_assert_handler handler;
|
||||||
console con(st->boot_services, st->con_out);
|
console con(st->boot_services, st->con_out);
|
||||||
|
|
||||||
return bootloader_main_uefi(st, con);
|
/*return*/ bootloader_main_uefi(st, con);
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
return uefi::status::success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <uefi/types.h>
|
#include <uefi/types.h>
|
||||||
|
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "console.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
|
||||||
@@ -71,6 +72,8 @@ update_marked_addresses(uefi::event, void *context)
|
|||||||
void
|
void
|
||||||
init_pointer_fixup(uefi::boot_services *bs, uefi::runtime_services *rs)
|
init_pointer_fixup(uefi::boot_services *bs, uefi::runtime_services *rs)
|
||||||
{
|
{
|
||||||
|
status_line status(L"Initializing pointer virtualization event");
|
||||||
|
|
||||||
uefi::event event;
|
uefi::event event;
|
||||||
|
|
||||||
try_or_raise(
|
try_or_raise(
|
||||||
|
|||||||
Reference in New Issue
Block a user