Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[metal] Add a uprintf() routine, for non-emergency boot logging #905

Merged
merged 4 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,13 @@ include third_party/puff/puff.mk # │
include libc/elf/elf.mk #
include ape/ape.mk #
include libc/fmt/fmt.mk #
include libc/vga/vga.mk #─┘
include libc/vga/vga.mk #
include libc/irq/irq.mk #─┘
include libc/calls/calls.mk #─┐
include third_party/nsync/nsync.mk #
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
include third_party/double-conversion/dc.mk # │ You can issue system calls
include libc/irq/irq.mk # ├──SYSTEMS RUNTIME
include third_party/nsync/nsync.mk # │ You can issue system calls
include libc/runtime/runtime.mk #
include third_party/double-conversion/dc.mk #
include libc/crt/crt.mk #
include third_party/dlmalloc/dlmalloc.mk #─┘
include libc/mem/mem.mk #─┐
Expand Down Expand Up @@ -340,6 +342,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_RUNTIME \
THIRD_PARTY_NSYNC \
LIBC_ELF \
LIBC_IRQ \
LIBC_CALLS \
LIBC_SYSV_CALLS \
LIBC_VGA \
Expand Down
1 change: 1 addition & 0 deletions examples/examples.mk
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ EXAMPLES_DIRECTDEPS = \
LIBC_DNS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_IRQ \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
Expand Down
2 changes: 2 additions & 0 deletions examples/vga2.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

__static_yoink("vga_console");
__static_yoink("_idt");
__static_yoink("_AcpiMadtFlags");
__static_yoink("_AcpiBootFlags");
__static_yoink("EfiMain");

int main(int argc, char *argv[]) {
Expand Down
2 changes: 2 additions & 0 deletions libc/calls/metalfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "libc/calls/internal.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/intrin/directmap.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
Expand Down Expand Up @@ -74,6 +75,7 @@ textstartup void InitializeMetalFile(void) {
memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size);
__ape_com_base = copied_base;
__ape_com_size = size;
KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size);
}
}

Expand Down
4 changes: 2 additions & 2 deletions libc/calls/metalfile_init.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
#include "libc/macros.internal.h"
#include "libc/calls/metalfile.internal.h"

.init.start 101,_init_metalfile
.init.start 102,_init_metalfile
push %rdi
push %rsi
call InitializeMetalFile
pop %rsi
pop %rdi
.init.end 101,_init_metalfile
.init.end 102,_init_metalfile
APE_COM_NAME:
.endobj APE_COM_NAME,globl,hidden
2 changes: 2 additions & 0 deletions libc/integral/c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,8 @@ void abort(void) wontreturn;
#endif

#define __weak_reference(sym, alias) \
__weak_reference_impl(sym, alias)
#define __weak_reference_impl(sym, alias) \
__asm__(".weak\t" #alias "\n\t" \
".equ\t" #alias ", " #sym "\n\t" \
".type\t" #alias ",@notype")
Expand Down
2 changes: 2 additions & 0 deletions libc/intrin/interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
│ OTHER DEALINGS IN THE SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/pc.internal.h"

// Code and data structures for bare metal interrupt handling.
Expand Down
37 changes: 22 additions & 15 deletions libc/intrin/kprintf.greg.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,14 +385,29 @@ privileged long kloghandle(void) {
return __klog_handle;
}

privileged void _klog_serial(const char *b, size_t n) {
size_t i;
uint16_t dx;
unsigned char al;
for (i = 0; i < n; ++i) {
for (;;) {
dx = 0x3F8 + UART_LSR;
asm("inb\t%1,%0" : "=a"(al) : "dN"(dx));
if (al & UART_TTYTXR) break;
asm("pause");
}
dx = 0x3F8;
asm volatile("outb\t%0,%1"
: /* no inputs */
: "a"(b[i]), "dN"(dx));
}
}

privileged void klog(const char *b, size_t n) {
#ifdef __x86_64__
int e;
long h;
size_t i;
uint16_t dx;
uint32_t wrote;
unsigned char al;
long rax, rdi, rsi, rdx;
if ((h = kloghandle()) == -1) {
return;
Expand All @@ -407,18 +422,7 @@ privileged void klog(const char *b, size_t n) {
if (_weaken(_klog_vga)) {
_weaken(_klog_vga)(b, n);
}
for (i = 0; i < n; ++i) {
for (;;) {
dx = 0x3F8 + UART_LSR;
asm("inb\t%1,%0" : "=a"(al) : "dN"(dx));
if (al & UART_TTYTXR) break;
asm("pause");
}
dx = 0x3F8;
asm volatile("outb\t%0,%1"
: /* no inputs */
: "a"(b[i]), "dN"(dx));
}
_klog_serial(b, n);
} else {
asm volatile("syscall"
: "=a"(rax), "=D"(rdi), "=S"(rsi), "=d"(rdx)
Expand Down Expand Up @@ -1152,3 +1156,6 @@ privileged void kprintf(const char *fmt, ...) {
kvprintf(fmt, v);
va_end(v);
}

__weak_reference(kprintf, uprintf);
__weak_reference(kvprintf, uvprintf);
36 changes: 30 additions & 6 deletions libc/intrin/kprintf.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,49 @@
#define kvsnprintf __kvsnprintf
#define kloghandle __kloghandle
#define kisdangerous __kisdangerous
#define uprintf __uprintf
#define uvprintf __uvprintf

#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_

void kprintf(const char *, ...);
size_t ksnprintf(char *, size_t, const char *, ...);
void kvprintf(const char *, va_list);
size_t kvsnprintf(char *, size_t, const char *, va_list);
bool kisdangerous(const void *);
COSMOPOLITAN_C_START_

void kprintf(const char *, ...);
size_t ksnprintf(char *, size_t, const char *, ...);
void kvprintf(const char *, va_list);
size_t kvsnprintf(char *, size_t, const char *, va_list);

bool kisdangerous(const void *);

void klog(const char *, size_t);
void _klog_serial(const char *, size_t);
long kloghandle(void);

void uprintf(const char *, ...);
void uvprintf(const char *, va_list);

#ifndef TINY
#define KINFOF(FMT, ...) \
tkchia marked this conversation as resolved.
Show resolved Hide resolved
do { \
uprintf("\r\e[35m%s:%d: " FMT "\e[0m\n", \
__FILE__, __LINE__, ## __VA_ARGS__); \
} while (0)
#define KWARNF(FMT, ...) \
do { \
uprintf("\r\e[94;49mwarn: %s:%d: " FMT "\e[0m\n", \
__FILE__, __LINE__, ## __VA_ARGS__); \
} while (0)
#else
#define KINFOF(FMT, ...) ((void)0)
#define KWARNF(FMT, ...) ((void)0)
#endif
#define KDIEF(FMT, ...) \
do { \
kprintf("\r\e[30;101mfatal: %s:%d: " FMT "\e[0m\n", \
__FILE__, __LINE__, ## __VA_ARGS__); \
for (;;) asm volatile("cli\n\thlt"); \
} while (0)

COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* _COSMO_SOURCE */
Expand Down
43 changes: 43 additions & 0 deletions libc/irq/acpi-fadt-init.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ This is free and unencumbered software released into the public domain. │
│ │
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
│ distribute this software, either in source code form or as a compiled │
│ binary, for any purpose, commercial or non-commercial, and by any │
│ means. │
│ │
│ In jurisdictions that recognize copyright laws, the author or authors │
│ of this software dedicate any and all copyright interest in the │
│ software to the public domain. We make this dedication for the benefit │
│ of the public at large and to the detriment of our heirs and │
│ successors. We intend this dedication to be an overt act of │
│ relinquishment in perpetuity of all present and future rights to this │
│ software under copyright law. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
│ OTHER DEALINGS IN THE SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/irq/acpi.internal.h"
#include "libc/macros.internal.h"
#include "libc/runtime/pc.internal.h"

.init.start 312,_init_acpi_fadt
push %rdi
push %rsi
call _AcpiFadtInit
pop %rsi
pop %rdi
.init.end 312,_init_acpi_fadt
.data
_AcpiBootFlags:
.short kAcpiFadtLegacyDevices | kAcpiFadt8042
.endobj _AcpiBootFlags,globl
.previous
80 changes: 80 additions & 0 deletions libc/irq/acpi-fadt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ This is free and unencumbered software released into the public domain. │
│ │
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
│ distribute this software, either in source code form or as a compiled │
│ binary, for any purpose, commercial or non-commercial, and by any │
│ means. │
│ │
│ In jurisdictions that recognize copyright laws, the author or authors │
│ of this software dedicate any and all copyright interest in the │
│ software to the public domain. We make this dedication for the benefit │
│ of the public at large and to the detriment of our heirs and │
│ successors. We intend this dedication to be an overt act of │
│ relinquishment in perpetuity of all present and future rights to this │
│ software under copyright law. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
│ OTHER DEALINGS IN THE SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/irq/acpi.internal.h"

#ifdef __x86_64__

textstartup static void _AcpiDsdtInit(uintptr_t dsdt_phy) {
const AcpiTableDsdt *dsdt;
size_t length;
if (!dsdt_phy) {
KWARNF("FADT: no DSDT");
return;
}
dsdt = _AcpiMapTable(dsdt_phy);
KINFOF("FADT: DSDT @ %p", dsdt);
length = dsdt->Header.Length;
if (length <= offsetof(AcpiTableDsdt, Aml)) {
KWARNF("DSDT: no AML?");
return;
}
/* TODO: parse AML to discover hardware configuration */
}

textstartup void _AcpiFadtInit(void) {
if (IsMetal()) {
const AcpiTableFadt *fadt;
size_t length;
uint16_t flags;
uintptr_t dsdt_phy = 0;
if (!_AcpiSuccess(_AcpiGetTable("FACP", 0, (void **)&fadt))) {
KINFOF("no FADT found");
return;
}
length = fadt->Header.Length;
KINFOF("FADT @ %p,+%#zx", fadt, length);
_Static_assert(offsetof(AcpiTableFadt, Dsdt) == 40);
_Static_assert(offsetof(AcpiTableFadt, BootFlags) == 109);
_Static_assert(offsetof(AcpiTableFadt, XDsdt) == 140);
if (length >= offsetof(AcpiTableFadt, BootFlags) + sizeof(fadt->BootFlags))
{
_AcpiBootFlags = flags = fadt->BootFlags;
KINFOF("FADT: boot flags %#x", (unsigned)flags);
}
if (length >= offsetof(AcpiTableFadt, XDsdt) + sizeof(fadt->XDsdt) &&
fadt->XDsdt) {
dsdt_phy = fadt->XDsdt;
} else if (length >= offsetof(AcpiTableFadt, Dsdt) + sizeof(fadt->Dsdt)) {
dsdt_phy = fadt->Dsdt;
}
_AcpiDsdtInit(dsdt_phy);
}
}

#endif /* __x86_64__ */
51 changes: 51 additions & 0 deletions libc/irq/acpi-madt-init.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ This is free and unencumbered software released into the public domain. │
│ │
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
│ distribute this software, either in source code form or as a compiled │
│ binary, for any purpose, commercial or non-commercial, and by any │
│ means. │
│ │
│ In jurisdictions that recognize copyright laws, the author or authors │
│ of this software dedicate any and all copyright interest in the │
│ software to the public domain. We make this dedication for the benefit │
│ of the public at large and to the detriment of our heirs and │
│ successors. We intend this dedication to be an overt act of │
│ relinquishment in perpetuity of all present and future rights to this │
│ software under copyright law. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
│ OTHER DEALINGS IN THE SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/irq/acpi.internal.h"
#include "libc/macros.internal.h"
#include "libc/runtime/pc.internal.h"

.init.start 311,_init_acpi_madt
push %rdi
push %rsi
call _AcpiMadtInit
pop %rsi
pop %rdi
.init.end 311,_init_acpi_madt
.data
_AcpiMadtFlags:
.long kAcpiMadtPcAtCompat
.endobj _AcpiMadtFlags,globl
.previous
.bss
_AcpiNumIoApics:
.skip 8
.endobj _AcpiNumIoApics,globl
_AcpiIoApics:
.skip 8
.endobj _AcpiIoApics,globl
.previous
Loading