Compare commits

...

3 Commits

11 changed files with 159 additions and 162 deletions

View File

@ -59,10 +59,16 @@ void StrFormatInternal(StringBuilder& builder, StringView format, T value,
}
template <typename... Args>
StringBuilder StrFormat(StringView format, Args... args) {
StringBuilder builder;
String StrFormat(StringView format, Args... args) {
VariableStringBuilder builder;
StrFormatInternal(builder, format, args...);
return builder.ToString();
}
template <typename... Args>
void StrFormatIntoBuffer(StringBuilder& builder, StringView format,
Args... args) {
StrFormatInternal(builder, format, args...);
return glcr::Move(builder);
}
} // namespace glcr

View File

@ -2,23 +2,52 @@
namespace glcr {
void StringBuilder::PushBack(const StringView& str) {
if (capacity() < size() + str.size()) {
uint64_t new_capacity = capacity() == 0 ? 1 : capacity() * 2;
uint64_t VariableStringBuilder::size() const { return data_.size(); }
void VariableStringBuilder::PushBack(const StringView& str) {
if (data_.capacity() < size() + str.size()) {
uint64_t new_capacity = data_.capacity() == 0 ? 1 : data_.capacity() * 2;
while (new_capacity < size() + str.size()) {
new_capacity *= 2;
}
Resize(new_capacity);
data_.Resize(new_capacity);
}
for (uint64_t i = 0; i < str.size(); i++) {
Vector<char>::PushBack(str[i]);
data_.PushBack(str[i]);
}
}
String StringBuilder::ToString() const { return String(RawPtr(), size()); }
void VariableStringBuilder::PushBack(const char str) { data_.PushBack(str); }
StringBuilder::operator StringView() const {
return StringView(RawPtr(), size());
String VariableStringBuilder::ToString() const {
return String(data_.RawPtr(), size());
}
VariableStringBuilder::operator StringView() const {
return StringView(data_.RawPtr(), size());
}
void FixedStringBuilder::PushBack(const StringView& str) {
for (uint64_t i = 0; i < str.size(); i++) {
PushBack(str[i]);
}
}
void FixedStringBuilder::PushBack(const char str) {
if (size_ >= capacity_) {
// Somewhat random sequence of characters to show that we've overrun the
// buffer.
buffer_[capacity_ - 1] = '>';
buffer_[capacity_ - 2] = '!';
} else {
buffer_[size_++] = str;
}
}
String FixedStringBuilder::ToString() const { return String(buffer_, size_); }
FixedStringBuilder::operator StringView() const {
return StringView(buffer_, size_);
}
} // namespace glcr

View File

@ -6,21 +6,64 @@
namespace glcr {
class StringBuilder : public Vector<char> {
class StringBuilder {
public:
StringBuilder() : Vector<char>() {}
StringBuilder(const StringBuilder&) = delete;
StringBuilder(StringBuilder&& str) : Vector<char>(Move(str)) {}
virtual uint64_t size() const = 0;
virtual void PushBack(const StringView& str) = 0;
virtual void PushBack(const char str) = 0;
void PushBack(const StringView& str);
using Vector<char>::PushBack;
virtual String ToString() const = 0;
String ToString() const;
virtual operator StringView() const = 0;
};
class VariableStringBuilder : public StringBuilder {
public:
VariableStringBuilder() = default;
VariableStringBuilder(const VariableStringBuilder&) = delete;
VariableStringBuilder(VariableStringBuilder&&) = default;
~VariableStringBuilder() = default;
virtual uint64_t size() const override;
virtual void PushBack(const StringView& str) override;
virtual void PushBack(const char str) override;
virtual String ToString() const override;
// Note that this could become invalidated
// at any time if more characters are pushed
// onto the builder.
operator StringView() const;
virtual operator StringView() const override;
private:
Vector<char> data_;
};
class FixedStringBuilder : public StringBuilder {
public:
FixedStringBuilder() = delete;
FixedStringBuilder(const FixedStringBuilder&) = delete;
FixedStringBuilder(FixedStringBuilder&&) = delete;
~FixedStringBuilder() = default;
FixedStringBuilder(char* buffer, uint64_t size)
: buffer_(buffer), capacity_(size), size_(0) {}
virtual uint64_t size() const override { return size_; }
virtual void PushBack(const StringView& str) override;
virtual void PushBack(const char str) override;
virtual String ToString() const override;
virtual operator StringView() const override;
private:
char* buffer_;
uint64_t capacity_;
uint64_t size_;
};
} // namespace glcr

View File

@ -6,7 +6,7 @@
#include <ztypes.h>
// TODO: Take StringView here instead.
void dbgln(const glcr::StringBuilder& builder);
void dbgln(const glcr::String& string);
template <typename... Args>
void dbgln(const glcr::StringView& fmt, Args... args) {

View File

@ -3,10 +3,7 @@
#include <glacier/status/error.h>
#include <zcall.h>
void dbgln(const glcr::StringBuilder& builder) {
glcr::String str = builder.ToString();
(void)ZDebug(str.cstr());
}
void dbgln(const glcr::String& string) { (void)ZDebug(string.cstr()); }
void check(uint64_t code) {
switch (code) {

View File

@ -27,59 +27,6 @@ void dbg(const glcr::StringView& str) {
}
}
void U64ToStr(uint64_t u, char* str) {
uint64_t len = 0;
uint64_t u2 = u;
while (u2 != 0) {
len++;
u2 /= 10;
}
if (len == 0) {
len = 1;
}
str[len] = '\0';
for (int64_t i = len - 1; i >= 0; i--) {
str[i] = (u % 10) + '0';
u /= 10;
}
}
void HexToStr(uint64_t u, char* str) {
uint64_t len = 0;
uint64_t u2 = u;
while (u2 != 0) {
len++;
u2 /= 16;
}
if (len == 0) {
len = 1;
}
len += 2;
str[0] = '0';
str[1] = 'x';
str[len] = '\0';
const char* hex = "0123456789ABCDEF";
for (uint64_t i = len - 1; i > 1; i--) {
str[i] = hex[u & 0xF];
u >>= 4;
}
}
void MemToStr(uint64_t u, char* str) {
str[0] = '0';
str[1] = 'x';
const char* hex = "0123456789ABCDEF";
for (uint64_t i = 0; i < 16; i++) {
str[17 - i] = hex[(u >> (i * 4)) & 0xF];
}
str[18] = '\0';
}
void AddProcPrefix() {
if (gScheduler != nullptr) {
auto t = gScheduler->CurrentThread();
@ -87,90 +34,15 @@ void AddProcPrefix() {
}
}
void dbg_internal(const char* fmt, va_list args) {
for (; *fmt != '\0'; fmt++) {
if (*fmt != '%') {
dbgputchar(*fmt);
continue;
}
fmt++;
switch (*fmt) {
case '%':
dbgputchar('%');
break;
case 's': {
char* str = va_arg(args, char*);
dbgcstr(str);
break;
}
case 'c': {
char c = va_arg(args, int);
dbgputchar(c);
break;
}
case 'u': {
uint64_t u = va_arg(args, uint64_t);
char str[21];
U64ToStr(u, str);
dbgcstr(str);
break;
}
case 'x': {
uint64_t u = va_arg(args, uint64_t);
char str[19];
HexToStr(u, str);
dbgcstr(str);
break;
}
case 'm': {
uint64_t u = va_arg(args, uint64_t);
char str[19];
MemToStr(u, str);
dbgcstr(str);
break;
}
default: {
panic("Bad format char: %c", *fmt);
}
}
}
}
} // namespace
void early_dbgln(const char* str) { dbgcstr(str); }
void early_dbgln(const char* str) {
dbgcstr(str);
dbgcstr("\n");
}
void dbgln(const glcr::StringView& str) {
AddProcPrefix();
dbg(str);
dbg("\n");
}
void dbg(const char* fmt, ...) {
va_list arg;
va_start(arg, fmt);
dbg_internal(fmt, arg);
va_end(arg);
}
void dbgln(const char* fmt, ...) {
AddProcPrefix();
va_list arg;
va_start(arg, fmt);
dbg_internal(fmt, arg);
va_end(arg);
dbgputchar('\n');
}
void panic(const char* fmt, ...) {
asm volatile("cli");
AddProcPrefix();
va_list arg;
va_start(arg, fmt);
dbg_internal(fmt, arg);
va_end(arg);
dbgputchar('\n');
dbgln("PANIC");
while (1)
;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <glacier/string/str_format.h>
#include <glacier/string/string_builder.h>
#include <stdarg.h>
#include "include/ztypes.h"
@ -11,15 +12,32 @@ void early_dbgln(const char* str);
void dbgln(const glcr::StringView& str);
// TODO: Write a version of StrFormat that
// accepts a fix-sized buffer for output
// to use in the kernel. That way we make
// dbgln and panic calls without allocation.
// Optionally, add a dbgln_unbounded method for
// things like the Debug syscall where the formatted
// string may be fairly large.
template <typename... Args>
void dbgln(const char* str, Args... args) {
char buffer[256];
glcr::FixedStringBuilder builder(buffer, 256);
glcr::StrFormatIntoBuffer(builder, str, args...);
dbgln(builder);
}
template <typename... Args>
void dbgln_large(const char* str, Args... args) {
dbgln(glcr::StrFormat(str, args...));
}
template <typename... Args>
void panic(const char* str, Args... args) {
dbgln(glcr::StrFormat(str, args...));
dbgln(str, args...);
dbgln("PANIC");
asm volatile("hlt;");
}
#define UNREACHABLE \

View File

@ -36,9 +36,6 @@ class PhysicalMemoryManager {
const limine_memmap_response& memmap = boot::GetMemoryMap();
for (uint64_t i = 0; i < memmap.entry_count; i++) {
const limine_memmap_entry& entry = *memmap.entries[i];
#if K_PHYS_DEBUG
dbgln("Region({}) at {x}:{x}", entry.type, entry.base, entry.length);
#endif
if (entry.type == 0) {
uint64_t base = entry.base;
uint64_t size = entry.length;
@ -155,6 +152,38 @@ void InitBootstrapPageAllocation() {
void InitPhysicalMemoryManager() { gPmm = new PhysicalMemoryManager(); }
glcr::StringView MemoryRegionStr(uint64_t type) {
switch (type) {
case LIMINE_MEMMAP_USABLE:
return "USABLE";
case LIMINE_MEMMAP_RESERVED:
return "RESRVD";
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
return "ACPIREC";
case LIMINE_MEMMAP_ACPI_NVS:
return "ACPINVS";
case LIMINE_MEMMAP_BAD_MEMORY:
return "BADMEM";
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
return "LIMINE";
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
return "KERNEL";
case LIMINE_MEMMAP_FRAMEBUFFER:
return "FRMBFR";
default:
return "UNKNWN";
}
}
void DumpRegions() {
const limine_memmap_response& memmap = boot::GetMemoryMap();
for (uint64_t i = 0; i < memmap.entry_count; i++) {
const limine_memmap_entry& entry = *memmap.entries[i];
dbgln("Region({}) at {x}:{x} ({x})", MemoryRegionStr(entry.type),
entry.base, entry.base + entry.length, entry.length);
}
}
uint64_t AllocatePage() {
if (gPmm != nullptr) {
return gPmm->AllocatePage();
@ -164,7 +193,7 @@ uint64_t AllocatePage() {
}
#if K_PHYS_DEBUG
dbgln("[PMM] Boostrap Alloc!");
early_dbgln("[PMM] Boostrap Alloc!");
#endif
uint64_t page = gBootstrap.next_page;

View File

@ -13,6 +13,8 @@ void InitBootstrapPageAllocation();
// Initializes the main physical memory manager.
void InitPhysicalMemoryManager();
void DumpRegions();
uint64_t AllocatePage();
uint64_t AllocateAndZeroPage();

View File

@ -5,6 +5,6 @@
#include "debug/debug.h"
z_err_t Debug(ZDebugReq* req) {
dbgln("[Debug] {}", req->message);
dbgln_large("[Debug] {}", req->message);
return glcr::OK;
}

View File

@ -26,6 +26,7 @@ extern "C" void zion() {
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
phys_mem::InitPhysicalMemoryManager();
heap.InitializeSlabAllocators();
phys_mem::DumpRegions();
dbgln("[boot] Memory allocations available now.");