Print some info on exceptions.
This commit is contained in:
parent
9f1f1e80f2
commit
355b1641bd
156
serial.txt
Normal file
156
serial.txt
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01H[2J[01;01H[=3h[2J[01;01HBdsDxe: loading Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0)
|
||||||
|
BdsDxe: starting Boot0001 "UEFI QEMU DVD-ROM QM00003 " from PciRoot(0x0)/Pci(0x1,0x1)/Ata(Secondary,Master,0x0)
|
||||||
|
[2J[01;01H
|
||||||
|
|
||||||
|
This is BadAppleOS and everything is fine!
|
||||||
|
|
||||||
|
Key event: scancode=S(0x1B), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=D(0x23), down=true, repeat=false
|
||||||
|
Key event: scancode=D(0x23), down=false, repeat=false
|
||||||
|
Key event: scancode=S(0x1B), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=F(0x2B), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=F(0x2B), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=W(0x1D), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=W(0x1D), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=F(0x2B), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=F(0x2B), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=W(0x1D), down=true, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=W(0x1D), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=L(0x4B), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=true, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=P(0x4D), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=L(0x4B), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=P(0x4D), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=T(0x2C), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=T(0x2C), down=false, repeat=false
|
||||||
|
Key event: scancode=P(0x4D), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=P(0x4D), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=U(0x3C), down=true, repeat=false
|
||||||
|
Key event: scancode=U(0x3C), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=O(0x44), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=I(0x43), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=T(0x2C), down=true, repeat=false
|
||||||
|
Key event: scancode=T(0x2C), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=true, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=true, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=false, repeat=false
|
||||||
|
Key event: scancode=R(0x2D), down=false, repeat=false
|
||||||
|
Key event: scancode=E(0x24), down=false, repeat=false
|
||||||
|
Key event: scancode=G(0x34), down=true, repeat=false
|
||||||
|
Key event: scancode=N(0x31), down=true, repeat=false
|
||||||
|
Key event: scancode=K(0x42), down=false, repeat=false
|
||||||
|
Key event: scancode=J(0x3B), down=false, repeat=false
|
227
targets/_any/include/os/tools/printf_helper.hpp
Normal file
227
targets/_any/include/os/tools/printf_helper.hpp
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_OS_TOOLS_PRINTF_HELPER_HPP_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_OS_TOOLS_PRINTF_HELPER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#if !defined(BAOS_IPRINTF_FUNC_ATTRIBUTE)
|
||||||
|
#define BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace baos
|
||||||
|
{
|
||||||
|
template<typename TPrinter>
|
||||||
|
class PrintFHelper
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
TPrinter mPrinter;
|
||||||
|
public:
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
explicit PrintFHelper(TPrinter printer = {}) noexcept : mPrinter(std::move(printer)) {}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printInt(long value)
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
mPrinter.putchar('0');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
mPrinter.putchar('-');
|
||||||
|
return printInt(-value) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char digits[19]; // 9223372036854775807 has 10 digits
|
||||||
|
char* pos = &digits[0];
|
||||||
|
|
||||||
|
while (value > 0)
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>('0' + (value % 10));
|
||||||
|
value /= 10;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
for (char* chr = pos - 1; chr >= digits; --chr)
|
||||||
|
{
|
||||||
|
mPrinter.putchar(*chr);
|
||||||
|
}
|
||||||
|
return pos - digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printUInt(uint64_t value)
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
mPrinter.putchar('0');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char digits[20]; // 18,446,744,073,709,551,615 has 20 digits
|
||||||
|
char* pos = &digits[0];
|
||||||
|
|
||||||
|
while (value > 0)
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>('0' + (value % 10));
|
||||||
|
value /= 10;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
for (char* chr = pos - 1; chr >= digits; --chr)
|
||||||
|
{
|
||||||
|
mPrinter.putchar(*chr);
|
||||||
|
}
|
||||||
|
return pos - digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printHexInt(uint64_t value)
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
mPrinter.putchar('0');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char digits[16]; // FFFFFFFFFFFFFFFF has 16 digits
|
||||||
|
char* pos = &digits[0];
|
||||||
|
|
||||||
|
while (value > 0)
|
||||||
|
{
|
||||||
|
const uint64_t digit = (value % 16);
|
||||||
|
if (digit < 10)
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>('0' + digit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>('A' + digit - 10);
|
||||||
|
}
|
||||||
|
value /= 16;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
for (char* chr = pos - 1; chr >= digits; --chr)
|
||||||
|
{
|
||||||
|
mPrinter.putchar(*chr);
|
||||||
|
}
|
||||||
|
return pos - digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printPointer(void* ptr)
|
||||||
|
{
|
||||||
|
return printHexInt(reinterpret_cast<uint64_t>(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printString(const char* str)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
mPrinter.putchar(*str);
|
||||||
|
++str;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
return static_cast<int>(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int printByteSize(size_t bytes)
|
||||||
|
{
|
||||||
|
const char* suffixes[] = {
|
||||||
|
"B", "KiB", "MiB", "GiB", "TiB"
|
||||||
|
};
|
||||||
|
int suffixIdx = 0;
|
||||||
|
for (; suffixIdx < sizeof(suffixes) / sizeof(suffixes[0]); ++suffixIdx)
|
||||||
|
{
|
||||||
|
if (bytes < 1024) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes /= 1024;
|
||||||
|
}
|
||||||
|
return printUInt(bytes) + printString(suffixes[suffixIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAOS_IPRINTF_FUNC_ATTRIBUTE
|
||||||
|
int vprintf(const char* format, va_list vlist) noexcept
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
const char* pos = format;
|
||||||
|
while (*pos != '\0')
|
||||||
|
{
|
||||||
|
if (*pos == '%')
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
switch (*pos)
|
||||||
|
{
|
||||||
|
case '%':
|
||||||
|
mPrinter.putchar('%');
|
||||||
|
++result;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
// TODO: invalid format string, do something
|
||||||
|
assert(!"Invalid format string, ends with %.");
|
||||||
|
return -1;
|
||||||
|
case 'b':
|
||||||
|
result += printByteSize(va_arg(vlist, size_t));
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
const char chr = static_cast<char>(va_arg(vlist, int));
|
||||||
|
mPrinter.putchar(chr);
|
||||||
|
++result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
result += printString(va_arg(vlist, const char*));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
result += printInt(va_arg(vlist, int));
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
result += printPointer(va_arg(vlist, void*));
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
result += printHexInt(va_arg(vlist, unsigned));
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
++pos;
|
||||||
|
switch (*pos)
|
||||||
|
{
|
||||||
|
case '\0':
|
||||||
|
assert(!"Invalid format string, ends with %l.");
|
||||||
|
return -1;
|
||||||
|
case 'd':
|
||||||
|
result += printInt(va_arg(vlist, long));
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
result += printHexInt(va_arg(vlist, unsigned long));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"Invalid format string, unknown format identifier.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mPrinter.putchar(*pos);
|
||||||
|
}
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
++result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_OS_TOOLS_PRINTF_HELPER_HPP_INCLUDED)
|
@ -5,6 +5,7 @@
|
|||||||
#define BAD_APPLE_OS_STDIO_H_INCLUDED
|
#define BAD_APPLE_OS_STDIO_H_INCLUDED
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "./detail/common.h"
|
#include "./detail/common.h"
|
||||||
|
|
||||||
BA_EXTERN_C_BEGIN
|
BA_EXTERN_C_BEGIN
|
||||||
@ -13,6 +14,8 @@ int putchar(int chr) BA_CXX_NOEXCEPT;
|
|||||||
int puts(const char* str) BA_CXX_NOEXCEPT;
|
int puts(const char* str) BA_CXX_NOEXCEPT;
|
||||||
int printf(const char* format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 1, 2)));
|
int printf(const char* format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 1, 2)));
|
||||||
int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT;
|
int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||||
|
int snprintf(char* buffer, size_t bufferSize, const char* format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 3, 4)));
|
||||||
|
int vsnprintf(char* buffer, size_t bufferSize, const char* format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
BA_EXTERN_C_END
|
BA_EXTERN_C_END
|
||||||
|
|
||||||
|
@ -1,135 +1,43 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <utility>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "os/serial.hpp"
|
#include "os/serial.hpp"
|
||||||
#include "os/tty.hpp"
|
#include "os/tty.hpp"
|
||||||
|
#include "os/tools/printf_helper.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct RegularPrinter
|
||||||
|
{
|
||||||
|
void putchar(int chr) noexcept // NOLINT
|
||||||
|
{
|
||||||
|
::putchar(chr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BufferPrinter
|
||||||
|
{
|
||||||
|
char* pos = nullptr;
|
||||||
|
char* end = nullptr;
|
||||||
|
|
||||||
|
void putchar(int chr) noexcept // NOLINT
|
||||||
|
{
|
||||||
|
if (pos != end)
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>(chr);
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
int printInt(long value)
|
|
||||||
{
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
putchar('0');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (value < 0)
|
|
||||||
{
|
|
||||||
putchar('-');
|
|
||||||
return printInt(-value) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char digits[19]; // 9223372036854775807 has 10 digits
|
|
||||||
char* pos = &digits[0];
|
|
||||||
|
|
||||||
while (value > 0)
|
|
||||||
{
|
|
||||||
*pos = static_cast<char>('0' + (value % 10));
|
|
||||||
value /= 10;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
for (char* chr = pos - 1; chr >= digits; --chr)
|
|
||||||
{
|
|
||||||
putchar(*chr);
|
|
||||||
}
|
|
||||||
return pos - digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
int printUInt(uint64_t value)
|
|
||||||
{
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
putchar('0');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char digits[20]; // 18,446,744,073,709,551,615 has 20 digits
|
|
||||||
char* pos = &digits[0];
|
|
||||||
|
|
||||||
while (value > 0)
|
|
||||||
{
|
|
||||||
*pos = static_cast<char>('0' + (value % 10));
|
|
||||||
value /= 10;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
for (char* chr = pos - 1; chr >= digits; --chr)
|
|
||||||
{
|
|
||||||
putchar(*chr);
|
|
||||||
}
|
|
||||||
return pos - digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
int printHexInt(uint64_t value)
|
|
||||||
{
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
putchar('0');
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char digits[16]; // FFFFFFFFFFFFFFFF has 16 digits
|
|
||||||
char* pos = &digits[0];
|
|
||||||
|
|
||||||
while (value > 0)
|
|
||||||
{
|
|
||||||
const uint64_t digit = (value % 16);
|
|
||||||
if (digit < 10)
|
|
||||||
{
|
|
||||||
*pos = static_cast<char>('0' + digit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*pos = static_cast<char>('A' + digit - 10);
|
|
||||||
}
|
|
||||||
value /= 16;
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
for (char* chr = pos - 1; chr >= digits; --chr)
|
|
||||||
{
|
|
||||||
putchar(*chr);
|
|
||||||
}
|
|
||||||
return pos - digits;
|
|
||||||
}
|
|
||||||
|
|
||||||
int printPointer(void* ptr)
|
|
||||||
{
|
|
||||||
return printHexInt(reinterpret_cast<uint64_t>(ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
int printString(const char* str)
|
|
||||||
{
|
|
||||||
const size_t len = std::strlen(str);
|
|
||||||
|
|
||||||
for (size_t idx = 0; idx < len; ++idx)
|
|
||||||
{
|
|
||||||
putchar(str[idx]);
|
|
||||||
}
|
|
||||||
return static_cast<int>(len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int printByteSize(size_t bytes)
|
|
||||||
{
|
|
||||||
const char* suffixes[] = {
|
|
||||||
"B", "KiB", "MiB", "GiB", "TiB"
|
|
||||||
};
|
|
||||||
int suffixIdx = 0;
|
|
||||||
for (; suffixIdx < sizeof(suffixes) / sizeof(suffixes[0]); ++suffixIdx)
|
|
||||||
{
|
|
||||||
if (bytes < 1024) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
bytes /= 1024;
|
|
||||||
}
|
|
||||||
return printUInt(bytes) + printString(suffixes[suffixIdx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int putchar(int chr) noexcept
|
int putchar(int chr) noexcept
|
||||||
{
|
{
|
||||||
tty::putChar(static_cast<char>(chr));
|
tty::putChar(static_cast<char>(chr));
|
||||||
@ -167,74 +75,30 @@ int printf(const char* format, ...) noexcept
|
|||||||
|
|
||||||
int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT
|
int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT
|
||||||
{
|
{
|
||||||
int result = 0;
|
return baos::PrintFHelper<RegularPrinter>().vprintf(format, vlist);
|
||||||
const char* pos = format;
|
}
|
||||||
while (*pos != '\0')
|
|
||||||
{
|
int snprintf(char* buffer, size_t bufferSize, const char* format, ...) noexcept
|
||||||
if (*pos == '%')
|
{
|
||||||
{
|
va_list parameters;
|
||||||
++pos;
|
va_start(parameters, format);
|
||||||
switch (*pos)
|
const int result = vsnprintf(buffer, bufferSize, format, parameters);
|
||||||
{
|
va_end(parameters);
|
||||||
case '%':
|
|
||||||
putchar('%');
|
|
||||||
++result;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
// TODO: invalid format string, do something
|
|
||||||
assert(!"Invalid format string, ends with %.");
|
|
||||||
return -1;
|
|
||||||
case 'b':
|
|
||||||
result += printByteSize(va_arg(vlist, size_t));
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
const char chr = static_cast<char>(va_arg(vlist, int));
|
|
||||||
putchar(chr);
|
|
||||||
++result;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 's':
|
|
||||||
result += printString(va_arg(vlist, const char*));
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
result += printInt(va_arg(vlist, int));
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
result += printPointer(va_arg(vlist, void*));
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
result += printHexInt(va_arg(vlist, unsigned));
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
++pos;
|
|
||||||
switch (*pos)
|
|
||||||
{
|
|
||||||
case '\0':
|
|
||||||
assert(!"Invalid format string, ends with %l.");
|
|
||||||
return -1;
|
|
||||||
case 'd':
|
|
||||||
result += printInt(va_arg(vlist, long));
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
result += printHexInt(va_arg(vlist, unsigned long));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(!"Invalid format string, unknown format identifier.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
putchar(*pos);
|
|
||||||
}
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
++result;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char* buffer, size_t bufferSize, const char* format, va_list vlist) noexcept
|
||||||
|
{
|
||||||
|
BufferPrinter printer{
|
||||||
|
.pos = buffer,
|
||||||
|
.end = bufferSize > 0 ? buffer + bufferSize - 1 : buffer
|
||||||
|
};
|
||||||
|
const int length = baos::PrintFHelper(printer).vprintf(format, vlist);
|
||||||
|
if (bufferSize > 0)
|
||||||
|
{
|
||||||
|
buffer[std::min(static_cast<int>(bufferSize - 1), length)] = '\0';
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
@ -1,17 +1,49 @@
|
|||||||
|
|
||||||
|
#define BAOS_IPRINTF_FUNC_ATTRIBUTE __attribute__((no_caller_saved_registers))
|
||||||
|
#include "os/tools/printf_helper.hpp"
|
||||||
|
|
||||||
#include "os/interrupt.hpp"
|
#include "os/interrupt.hpp"
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
#include "os/serial.hpp"
|
#include "os/serial.hpp"
|
||||||
#include "os/tty.hpp"
|
|
||||||
|
|
||||||
namespace baos
|
namespace baos
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct InterruptPrinter
|
||||||
|
{
|
||||||
|
__attribute__((no_caller_saved_registers))
|
||||||
|
void putchar(char chr) noexcept // NOLINT
|
||||||
|
{
|
||||||
|
if (chr == '\n') {
|
||||||
|
writePortByte(PORT_COM1, '\r');
|
||||||
|
}
|
||||||
|
writePortByte(PORT_COM1, static_cast<std::uint8_t>(chr));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((no_caller_saved_registers, format(printf, 1, 2)))
|
||||||
|
void iprintf(const char* format, ...) noexcept
|
||||||
|
{
|
||||||
|
std::va_list parameters;
|
||||||
|
va_start(parameters, format);
|
||||||
|
PrintFHelper<InterruptPrinter>().vprintf(format, parameters);
|
||||||
|
va_end(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" [[noreturn]] void __halt();
|
extern "C" [[noreturn]] void __halt();
|
||||||
|
|
||||||
__attribute__((no_caller_saved_registers))
|
__attribute__((no_caller_saved_registers))
|
||||||
void handleException(const char* name, InterruptFrame* interruptFrame) noexcept
|
void handleException(const char* name, InterruptFrame* interruptFrame) noexcept
|
||||||
{
|
{
|
||||||
tty::write(name);
|
iprintf("Exception occurred: %s\n", name);
|
||||||
serialWriteString(PORT_COM1, name);
|
iprintf("IP: 0x%lX\n", interruptFrame->ip);
|
||||||
|
iprintf("CS: 0x%lX\n", interruptFrame->cs);
|
||||||
|
iprintf("FLAGS: 0x%lX\n", interruptFrame->flags);
|
||||||
|
iprintf("SP: 0x%lX\n", interruptFrame->sp);
|
||||||
|
iprintf("SS: 0x%lX\n", interruptFrame->ss);
|
||||||
__halt();
|
__halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +240,10 @@ void kernel_main()
|
|||||||
event.down ? "true" : "false",
|
event.down ? "true" : "false",
|
||||||
event.repeat ? "true" : "false"
|
event.repeat ? "true" : "false"
|
||||||
);
|
);
|
||||||
|
if (event.down && event.scancode == ps2::Scancode::ESCAPE)
|
||||||
|
{
|
||||||
|
int x = 1 / 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user