Use an output iterator for the lucore stdout sink
This commit is contained in:
parent
58ee03c249
commit
6ebebae770
|
@ -1,3 +1,6 @@
|
|||
#include <bits/iterator_concepts.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <lucore/Logger.hpp>
|
||||
|
||||
|
@ -35,11 +38,31 @@ namespace lucore {
|
|||
}
|
||||
|
||||
void StdoutSink::OutputMessage(const Logger::MessageData& data) {
|
||||
// This is very nasty, but required until more standard libraries support the C++23 <print>
|
||||
// This is kinda iffy, but required until more standard libraries support the C++23 <print>
|
||||
// header.
|
||||
std::puts(std::format("[Lucore/{}] [{}] {}", Logger::SeverityToString(data.severity),
|
||||
data.time, std::vformat(data.format, data.args))
|
||||
.c_str());
|
||||
struct FileOutIterator {
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using value_type = void;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
using reference = void;
|
||||
|
||||
FileOutIterator(std::FILE* file) : file(file) {}
|
||||
FileOutIterator& operator*() { return *this; }
|
||||
FileOutIterator& operator++() { return *this; }
|
||||
FileOutIterator& operator++(int) { return *this; }
|
||||
|
||||
FileOutIterator& operator=(const char& val) {
|
||||
fputc(val, file);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::FILE* file;
|
||||
};
|
||||
std::format_to(FileOutIterator(data.severity < Logger::MessageSeverity::Error ? stdout : stderr), "[Lucore/{}] [{}] {}\n",
|
||||
Logger::SeverityToString(data.severity), data.time,
|
||||
std::vformat(data.format, data.args));
|
||||
}
|
||||
|
||||
void LoggerAttachStdout() {
|
||||
|
|
|
@ -29,12 +29,8 @@ namespace riscv {
|
|||
/// the ability to... well, clock!
|
||||
virtual void Clock() {}
|
||||
|
||||
// TODO(feat): Need to implement ability to generate interrupts
|
||||
// from devices. This needs to be implemented to facilitate the
|
||||
// implementation of the timer device as an actual Device implmentation
|
||||
// instead of poorly hard-coding it into the CPU core logic.
|
||||
//
|
||||
// Also, default implementations of Peek* and Poke* should trap.
|
||||
// TODO(feat): default implementations of Peek* and Poke* should exist
|
||||
// and trap the CPU (similarly to what happens if a unmapped bus read occurs).
|
||||
|
||||
|
||||
// Peek() -> reads a value from this device.
|
||||
|
@ -49,6 +45,7 @@ namespace riscv {
|
|||
|
||||
};
|
||||
|
||||
Bus(CPU* cpu);
|
||||
~Bus();
|
||||
|
||||
/// Attach a device to the bus.
|
||||
|
@ -66,7 +63,6 @@ namespace riscv {
|
|||
/// Clock all clocked devices.
|
||||
void Clock();
|
||||
|
||||
//
|
||||
u8 PeekByte(AddressT address);
|
||||
u16 PeekShort(AddressT address);
|
||||
u32 PeekWord(AddressT address);
|
||||
|
|
|
@ -1,11 +1,43 @@
|
|||
|
||||
#include <riscv/Bus.hpp>
|
||||
#include <riscv/Types.hpp>
|
||||
|
||||
namespace riscv {
|
||||
|
||||
/** The CPU core. There will be one of these in a [System]. */
|
||||
/** The CPU core. */
|
||||
struct CPU {
|
||||
struct State {
|
||||
u32 gpr[32];
|
||||
u32 pc;
|
||||
u32 mstatus;
|
||||
u32 cyclel;
|
||||
u32 cycleh;
|
||||
|
||||
u32 timerl;
|
||||
u32 timerh;
|
||||
u32 timermatchl;
|
||||
u32 timermatchh;
|
||||
|
||||
u32 mscratch;
|
||||
u32 mtvec;
|
||||
u32 mie;
|
||||
u32 mip;
|
||||
|
||||
u32 mepc;
|
||||
u32 mtval;
|
||||
u32 mcause;
|
||||
|
||||
// Note: only a few bits are used. (Machine = 3, User = 0)
|
||||
// Bits 0..1 = privilege.
|
||||
// Bit 2 = WFI (Wait for interrupt)
|
||||
// Bit 3+ = Load/Store reservation LSBs.
|
||||
u32 extraflags;
|
||||
};
|
||||
|
||||
State& GetState() { return state; }
|
||||
|
||||
private:
|
||||
State state;
|
||||
Bus bus;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace riscv
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
|
||||
namespace riscv {
|
||||
|
||||
Bus::Bus(CPU* cpu)
|
||||
: attachedCpu(cpu) {
|
||||
|
||||
}
|
||||
|
||||
Bus::~Bus() {
|
||||
// Free all devices
|
||||
for(auto& pair : mapped_devices)
|
||||
|
|
Loading…
Reference in New Issue