Compare commits

..

No commits in common. "fb458e6fd4d1c8c52ab82aa1a17242b0a4298966" and "e642f3900f33cb0b96486a83e656f1876f770ef6" have entirely different histories.

19 changed files with 171 additions and 245 deletions

View File

@ -16,3 +16,28 @@ add_subdirectory(zion)
add_subdirectory(lib)
add_subdirectory(yunq)
add_subdirectory(sys)
# Use machine q35 to access PCI devices.
set(QEMU_CMD qemu-system-x86_64 -machine q35 -d guest_errors -m 1G -serial stdio -hda disk.img)
add_custom_command(
OUTPUT disk.img
COMMAND sudo sh ../scripts/build_image.sh disk.img
DEPENDS zion yellowstone denali victoriafalls
USES_TERMINAL
)
add_custom_target(qemu
COMMAND ${QEMU_CMD}
DEPENDS disk.img
USES_TERMINAL)
add_custom_target(qemu-dbg
COMMAND ${QEMU_CMD} -S -s
DEPENDS disk.img
USES_TERMINAL)
add_custom_target(qemu-int
COMMAND ${QEMU_CMD} -d int
DEPENDS disk.img
USES_TERMINAL)

View File

@ -9,47 +9,24 @@ namespace glcr {
template <typename T>
class Array {
public:
// Constructors.
Array() : data_(nullptr), size_(0) {}
Array(const Array&) = delete;
Array& operator=(const Array&) = delete;
Array(Array&&);
Array& operator=(Array&&);
explicit Array(uint64_t size) : data_(new T[size]), size_(size) {}
Array(const ArrayView<T>& view);
~Array() {
if (data_) {
delete[] data_;
Array(const ArrayView<T> view) : Array(view.size()) {
for (uint64_t i = 0; i < size_; i++) {
data_[i] = view[i];
}
}
// Accessors.
T& operator[](uint64_t index) { return data_[index]; }
const T& operator[](uint64_t index) const { return data_[index]; }
Array(const Array&) = delete;
T* RawPtr() { return data_; }
const T* RawPtr() const { return data_; }
uint64_t size() const { return size_; }
bool empty() const { return size_ == 0; }
private:
T* data_;
uint64_t size_;
};
template <typename T>
Array<T>::Array(Array&& other) : data_(other.data_), size_(other.size_) {
Array(Array&& other) : data_(other.data_), size_(other.size_) {
other.data_ = nullptr;
other.size_ = 0;
}
template <typename T>
Array<T>& Array<T>::operator=(Array&& other) {
Array& operator=(Array&& other) {
if (data_) {
delete[] data_;
}
@ -60,11 +37,23 @@ Array<T>& Array<T>::operator=(Array&& other) {
return *this;
}
template <typename T>
Array<T>::Array(const ArrayView<T>& view) : Array(view.size()) {
for (uint64_t i = 0; i < size_; i++) {
data_[i] = view[i];
~Array() {
if (data_) {
delete[] data_;
}
}
T* RawPtr() { return data_; }
const T* RawPtr() const { return data_; }
uint64_t size() const { return size_; }
T& operator[](uint64_t index) { return data_[index]; }
const T& operator[](uint64_t index) const { return data_[index]; }
private:
T* data_;
uint64_t size_;
};
} // namespace glcr

View File

@ -8,21 +8,16 @@ template <typename T>
class ArrayView {
public:
ArrayView() : data_(nullptr), size_(0) {}
ArrayView(const ArrayView&) = default;
ArrayView(ArrayView&&) = default;
ArrayView(T* data, uint64_t size) : data_(data), size_(size) {}
// Accessors.
T& operator[](uint64_t index) { return data_[index]; }
const T& operator[](uint64_t index) const { return data_[index]; }
T* RawPtr() { return data_; }
const T* RawPtr() const { return data_; }
uint64_t size() const { return size_; }
bool empty() const { return size_; }
T& operator[](uint64_t index) { return data_[index]; }
const T& operator[](uint64_t index) const { return data_[index]; }
private:
T* data_;

View File

@ -12,23 +12,56 @@ class LinkedList {
LinkedList() {}
LinkedList(const LinkedList&) = delete;
LinkedList(LinkedList&&) = delete;
// Accessors.
bool empty() const { return size_ == 0; }
uint64_t size() const { return size_; }
void PushFront(const T& item) {
ListItem* new_item = new ListItem{
.item = item,
.next = front_,
};
front_ = new_item;
size_++;
}
void PushFront(T&& item) {
ListItem* new_item = new ListItem{
.item = glcr::Move(item),
.next = front_,
};
front_ = new_item;
size_++;
}
void PushBack(const T& item) {
ListItem* new_item = new ListItem{
.item = item,
.next = nullptr,
};
PushBackInternal(new_item);
}
void PushBack(T&& item) {
ListItem* new_item = new ListItem{
.item = glcr::Move(item),
.next = nullptr,
};
PushBackInternal(new_item);
}
T PopFront() {
size_--;
ListItem* old_front = front_;
front_ = front_->next;
T ret = glcr::Move(old_front->item);
delete old_front;
return ret;
}
T& PeekFront() { return front_->item; }
const T& PeekFront() const { return front_->item; }
T PopFront();
void PushFront(const T& item);
void PushFront(T&& item);
void PushBack(const T& item);
void PushBack(T&& item);
struct ListItem {
T item;
ListItem* next;
@ -74,53 +107,4 @@ class LinkedList {
}
};
template <typename T>
void LinkedList<T>::PushFront(const T& item) {
ListItem* new_item = new ListItem{
.item = item,
.next = front_,
};
front_ = new_item;
size_++;
}
template <typename T>
void LinkedList<T>::PushFront(T&& item) {
ListItem* new_item = new ListItem{
.item = glcr::Move(item),
.next = front_,
};
front_ = new_item;
size_++;
}
template <typename T>
void LinkedList<T>::PushBack(const T& item) {
ListItem* new_item = new ListItem{
.item = item,
.next = nullptr,
};
PushBackInternal(new_item);
}
template <typename T>
void LinkedList<T>::PushBack(T&& item) {
ListItem* new_item = new ListItem{
.item = glcr::Move(item),
.next = nullptr,
};
PushBackInternal(new_item);
}
template <typename T>
T LinkedList<T>::PopFront() {
size_--;
ListItem* old_front = front_;
front_ = front_->next;
T ret = Move(old_front->item);
delete old_front;
return Move(ret);
}
} // namespace glcr

View File

@ -8,61 +8,16 @@ namespace glcr {
template <typename T>
class Vector {
public:
// Constructors.
Vector() : data_(nullptr), size_(0), capacity_(0) {}
Vector(const Vector&) = delete;
Vector& operator=(const Vector&) = delete;
Vector(Vector&& other);
Vector& operator=(Vector&& other);
~Vector() {
if (data_) {
delete[] data_;
}
}
// Accessors.
T& operator[](uint64_t index) { return data_[index]; }
const T& operator[](uint64_t index) const { return data_[index]; }
T& at(uint64_t index) { return data_[index]; }
const T& at(uint64_t index) const { return data_[index]; }
uint64_t size() const { return size_; }
bool empty() const { return size_ == 0; }
uint64_t capacity() const { return capacity_; }
const T* RawPtr() const { return data_; }
// Setters.
// FIXME: Handle downsizing.
void Resize(uint64_t capacity);
void PushBack(const T& item);
void PushBack(T&& item);
template <typename... Args>
void EmplaceBack(Args&&... args);
private:
T* data_;
uint64_t size_;
uint64_t capacity_;
void Expand();
}; // namespace glcr
template <typename T>
Vector<T>::Vector(Vector&& other)
Vector(Vector&& other)
: data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
other.data_ = nullptr;
other.size_ = 0;
other.capacity_ = 0;
}
template <typename T>
Vector<T>& Vector<T>::operator=(Vector&& other) {
Vector& operator=(Vector&& other) {
if (data_) {
delete[] data_;
}
@ -78,6 +33,40 @@ Vector<T>& Vector<T>::operator=(Vector&& other) {
return *this;
}
~Vector() {
if (data_) {
delete[] data_;
}
}
// FIXME: Handle downsizing.
void Resize(uint64_t capacity);
// Setters.
void PushBack(const T& item);
void PushBack(T&& item);
template <typename... Args>
void EmplaceBack(Args... args);
// Accessors.
T& operator[](uint64_t index);
const T& operator[](uint64_t index) const;
T& at(uint64_t index);
const T& at(uint64_t index) const;
uint64_t size() const { return size_; }
uint64_t capacity() const { return capacity_; }
const T* RawPtr() const { return data_; }
private:
T* data_;
uint64_t size_;
uint64_t capacity_;
void Expand();
};
template <typename T>
void Vector<T>::Resize(uint64_t capacity) {
T* new_data = new T[capacity];
@ -111,7 +100,7 @@ void Vector<T>::PushBack(T&& item) {
template <typename T>
template <typename... Args>
void Vector<T>::EmplaceBack(Args&&... args) {
void Vector<T>::EmplaceBack(Args... args) {
if (size_ >= capacity_) {
Expand();
}
@ -119,6 +108,26 @@ void Vector<T>::EmplaceBack(Args&&... args) {
data_[size_++] = T(args...);
}
template <typename T>
T& Vector<T>::operator[](uint64_t index) {
return data_[index];
}
template <typename T>
const T& Vector<T>::operator[](uint64_t index) const {
return data_[index];
}
template <typename T>
T& Vector<T>::at(uint64_t index) {
return data_[index];
}
template <typename T>
const T& Vector<T>::at(uint64_t index) const {
return data_[index];
}
template <typename T>
void Vector<T>::Expand() {
uint64_t new_capacity = capacity_ == 0 ? 1 : capacity_ * 2;

View File

@ -44,7 +44,7 @@ z_err_t ParseInitPort(uint64_t init_port_cap) {
case Z_BOOT_FRAMEBUFFER_INFO_VMMO:
gBootFramebufferVmmoCap = init_cap;
default:
dbgln("Unexpected init type {x}, continuing.", init_sig);
dbgln("Unexpected init type {}, continuing.", init_sig);
}
}

View File

@ -1,24 +0,0 @@
#! /bin/bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo $DIR
BUILD_DIR="${DIR}/../builddbg"
pushd $BUILD_DIR
ninja
ninja install
sudo sh ${DIR}/build_image.sh disk.img
# Use machine q35 to access PCI devices.
qemu-system-x86_64 -machine q35 -d guest_errors -m 1G -serial stdio -hda disk.img
popd
# Extra options to add to this script in the future.
# Debug opts: -S -s
# Interrupt opts: -d int

View File

@ -143,6 +143,7 @@ void AhciDriver::InterruptLoop() {
for (uint64_t i = 0; i < 32; i++) {
if (devices_[i] != nullptr && devices_[i]->IsInit() &&
(ahci_hba_->interrupt_status & (1 << i))) {
dbgln("Interrupt for {}", i);
devices_[i]->HandleIrq();
ahci_hba_->interrupt_status &= ~(1 << i);
}

View File

@ -1,5 +1,4 @@
add_executable(teton
framebuffer/framebuffer.cpp
teton.cpp
)

View File

@ -1,15 +0,0 @@
#include "framebuffer/framebuffer.h"
#include <mammoth/memory_region.h>
Framebuffer::Framebuffer(const FramebufferInfo& info) : fb_info_(info) {
uint64_t buff_size_bytes = fb_info_.height() * fb_info_.pitch();
MappedMemoryRegion region = MappedMemoryRegion::DirectPhysical(
fb_info_.address_phys(), buff_size_bytes);
fb_ = reinterpret_cast<uint32_t*>(region.vaddr());
}
void Framebuffer::DrawPixel(uint32_t row, uint32_t col, uint32_t pixel) {
// Div by 4 because pitch is in bytes and fb_ is a 32bit array.
fb_[(row * fb_info_.pitch() / 4) + col] = pixel;
}

View File

@ -1,16 +0,0 @@
#pragma once
#include <yellowstone/yellowstone.yunq.h>
class Framebuffer {
public:
Framebuffer(const FramebufferInfo& info);
void DrawPixel(uint32_t row, uint32_t col, uint32_t pixel);
private:
// FIXME: Implement Yunq copy or move so we
// don't have to store a reference here.
const FramebufferInfo& fb_info_;
uint32_t* fb_;
};

View File

@ -1,30 +1,11 @@
#include <mammoth/debug.h>
#include <mammoth/init.h>
#include <yellowstone/yellowstone.yunq.client.h>
#include "framebuffer/framebuffer.h"
uint64_t main(uint64_t init_port) {
ParseInitPort(init_port);
dbgln("Teton Starting");
// 1. Set up framebuffer.
YellowstoneClient client(gInitEndpointCap);
FramebufferInfo framebuffer;
RET_ERR(client.GetFramebufferInfo({}, framebuffer));
dbgln("FB addr {x}, bpp {}, width {} , height {}, pitch {}",
framebuffer.address_phys(), framebuffer.bpp(), framebuffer.width(),
framebuffer.height(), framebuffer.pitch());
Framebuffer fbuf(framebuffer);
for (uint64_t r = 0; r < 20; r++) {
for (uint64_t c = 0; c < 20; c++) {
fbuf.DrawPixel(r, c, 0x0000FF00);
}
}
// 2. Parse a font file.

View File

@ -7,8 +7,6 @@
#include <zcall.h>
#include <zglobal.h>
#define GPT_DEBUG 0
const uint64_t kSectorSize = 512;
const uint64_t kGptPartitionSignature = 0x54524150'20494645;
@ -81,26 +79,23 @@ glcr::ErrorCode GptReader::ParsePartitionTables() {
dbgln("Incorrect OS type: {x}", first_partition->os_type);
return glcr::FAILED_PRECONDITION;
}
#if GPT_DEBUG
dbgln("LBAs: ({x}, {x})", first_partition->starting_lba,
first_partition->ending_lba);
#endif
// FIXME: Don't hardcode sector size.
ParititionHeader* header =
reinterpret_cast<ParititionHeader*>(lba_1_and_2.vaddr() + 512);
dbgln("signature {}", header->signature);
uint64_t num_partitions = header->num_partitions;
uint64_t entry_size = header->parition_entry_size;
uint64_t num_blocks = (num_partitions * entry_size) / 512;
#if GPT_DEBUG
dbgln("signature {}", header->signature);
dbgln("lba_partition_entries {x}", header->lba_partition_entries);
dbgln("num_partitions: {x}", num_partitions);
dbgln("partition_entry_size: {x}", entry_size);
dbgln("Num blocks: {x}", num_blocks);
#endif
req.set_device_id(0);
req.set_lba(header->lba_partition_entries);
@ -108,17 +103,16 @@ glcr::ErrorCode GptReader::ParsePartitionTables() {
RET_ERR(denali_->Read(req, resp));
MappedMemoryRegion part_table =
MappedMemoryRegion::FromCapability(resp.memory());
dbgln("Entries");
for (uint64_t i = 0; i < num_partitions; i++) {
PartitionEntry* entry = reinterpret_cast<PartitionEntry*>(
part_table.vaddr() + (i * entry_size));
if (entry->type_guid_low != 0 || entry->type_guid_high != 0) {
#if GPT_DEBUG
dbgln("Entry {}", i);
dbgln("T Guid: {x}-{x}", entry->type_guid_high, entry->type_guid_low);
dbgln("P Guid: {x}-{x}", entry->part_guid_high, entry->part_guid_low);
dbgln("LBA: {x}, {x}", entry->lba_start, entry->lba_end);
dbgln("Attrs: {x}", entry->attributes);
#endif
// For now we hardcode these values to the type that is
// created in our setup script.
// FIXME: Set up our own root partition type guid at some

View File

@ -4,8 +4,6 @@
#include <mammoth/init.h>
#include <zcall.h>
#define PCI_DEBUG 0
namespace {
PciDeviceHeader* PciHeader(uint64_t base, uint64_t bus, uint64_t dev,
@ -17,10 +15,14 @@ PciDeviceHeader* PciHeader(uint64_t base, uint64_t bus, uint64_t dev,
} // namespace
PciReader::PciReader() {
dbgln("Creating addr space");
uint64_t vaddr;
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootPciVmmoCap, &vaddr));
dbgln("Addr {x}", vaddr);
dbgln("Dumping PCI");
PciDump(vaddr);
dbgln("Done");
header_ = PciHeader(vaddr, 0, 0, 0);
}
@ -38,21 +40,17 @@ void PciReader::FunctionDump(uint64_t base, uint64_t bus, uint64_t dev,
if (hdr->vendor_id == 0xFFFF) {
return;
}
#if PCI_DEBUG
dbgln(
"[{}.{}.{}] (Vendor, Device): ({x}, {x}), (Type, Class, Sub, PIF): ({}, "
"{x}, {x}, {x})",
bus, dev, fun, hdr->vendor_id, hdr->device_id, hdr->header_type,
hdr->class_code, hdr->subclass, hdr->prog_interface);
#endif
if ((hdr->class_code == 0x6) && (hdr->subclass == 0x4)) {
dbgln("FIXME: Handle PCI to PCI bridge.");
}
if (hdr->class_code == 0x1) {
#if PCI_DEBUG
dbgln("SATA Device at: {x}", reinterpret_cast<uint64_t>(hdr) - base);
#endif
achi_device_offset_ = reinterpret_cast<uint64_t>(hdr) - base;
}
}

View File

@ -54,6 +54,7 @@ glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&,
AhciInfo& info) {
info.set_ahci_region(pci_reader_.GetAhciVmmo());
info.set_region_length(kPcieConfigurationSize);
dbgln("Resp ahci");
return glcr::OK;
}
@ -87,12 +88,13 @@ glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&,
info.set_denali_endpoint(new_denali);
info.set_device_id(device_id_);
info.set_lba_offset(lba_offset_);
dbgln("Resp denali");
return glcr::OK;
}
glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint(
const RegisterEndpointRequest& req, Empty&) {
dbgln("Registering {}.", req.endpoint_name());
dbgln("Registering.");
if (req.endpoint_name() == "denali") {
// FIXME: Rather than blocking and calling the denali service
// immediately we should signal the main thread that it can continue init.

View File

@ -154,6 +154,7 @@ extern "C" void interrupt_apic_timer(InterruptFrame*) {
glcr::RefPtr<Port> pci1_port;
extern "C" void isr_pci1();
extern "C" void interrupt_pci1(InterruptFrame*) {
dbgln("Interrupt PCI line 1");
pci1_port->Send({});
gApic->SignalEOI();
}

View File

@ -114,8 +114,9 @@ class PhysicalMemoryManager {
uint64_t AvailablePages() {
uint64_t available = 0;
for (const auto& mem_block : memory_blocks) {
available += mem_block.num_pages;
for (auto iter = memory_blocks.begin(); iter != memory_blocks.end();
iter = iter.next()) {
available += iter->num_pages;
}
return available;
}

View File

@ -83,6 +83,7 @@ void Scheduler::Yield() {
} else {
if (runnable_threads_.size() == 0) {
current_thread_ = sleep_thread_;
dbgln("Sleeping");
} else {
current_thread_ = runnable_threads_.PopFront();
}

View File

@ -58,6 +58,7 @@ extern "C" void zion() {
gScheduler->Enable();
gScheduler->Yield();
dbgln("Sleeping!");
while (1)
;
}