Compare commits

...

2 Commits

Author SHA1 Message Date
Drew Galbraith 30bb10207e Add the Denali disk driver.
Begin enumerating information from the PCI structure and HBA AHCI
structures.

Currently the PCI structure address is hardcoded but it should be
passed via a capability from the init process in the future.
2023-06-08 02:36:59 -07:00
Drew Galbraith 47e3d11060 Add a syscall for creating a physical memory VMO 2023-06-08 02:36:47 -07:00
16 changed files with 298 additions and 47 deletions

View File

@ -22,7 +22,7 @@ set(QEMU_CMD qemu-system-x86_64 -machine q35 -d guest_errors -m 1G -serial stdio
add_custom_command(
OUTPUT disk.img
COMMAND sudo sh ../scripts/build_image.sh disk.img
DEPENDS zion yellowstone test2
DEPENDS zion yellowstone denali
USES_TERMINAL
)

View File

@ -10,3 +10,11 @@ void dbgln(const char* fmt, ...);
void check(uint64_t);
void crash(const char*, z_err_t);
#define RET_ERR(expr) \
{ \
z_err_t _tmp_err = expr; \
if (_tmp_err != Z_OK) { \
return _tmp_err; \
} \
}

View File

@ -38,6 +38,6 @@ cp ../zion/boot/limine.cfg efi/
cp zion/zion efi/
mkdir -p efi/sys
cp sys/yellowstone/yellowstone efi/sys/yellowstone
cp sys/test2 efi/sys/test2
cp sys/denali/denali efi/sys/denali
chown drew:drew $1

View File

@ -1,16 +1,5 @@
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
add_subdirectory(yellowstone)
add_subdirectory(denali)
add_executable(test2
test2.cpp)
target_link_libraries(test2
cxx
mammoth_lib)
set_target_properties(test2
PROPERTIES
COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}"
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}"
)

View File

@ -3,3 +3,4 @@
Current Processes;
- **yellowstone**: System Initialization
- **denali**: SATA ACHI Disk Driver

17
sys/denali/CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
add_executable(denali
ahci/ahci_driver.cpp
denali.cpp)
target_include_directories(denali
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(denali
cxx
mammoth_lib
)
set_target_properties(denali PROPERTIES
COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}"
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}"
)

View File

@ -0,0 +1,149 @@
#include "ahci/ahci_driver.h"
#include <mammoth/debug.h>
#include <stdint.h>
#include <zcall.h>
namespace {
const uint64_t kSataPciPhys = 0xB00FA000;
const uint64_t kPciSize = 0x1000;
} // namespace
z_err_t AhciDriver::Init() {
RET_ERR(LoadPciDeviceHeader());
dbgln("ABAR: %x", pci_device_header_->abar);
RET_ERR(LoadHbaRegisters());
dbgln("Version: %x", ahci_hba_->version);
DumpCapabilities();
DumpPorts();
return Z_OK;
}
void AhciDriver::DumpCapabilities() {
dbgln("AHCI Capabilities:");
uint32_t caps = ahci_hba_->capabilities;
dbgln("Num Ports: %u", (caps & 0x1F) + 1);
dbgln("Num Command Slots: %u", (caps & 0x1F00) >> 8);
if (caps & 0x20) {
dbgln("External SATA");
}
if (caps & 0x40) {
dbgln("Enclosure Management");
}
if (caps & 0x80) {
dbgln("Command Completion Coalescing");
}
if (caps & 0x2000) {
dbgln("Partial State Capable");
}
if (caps & 0x4000) {
dbgln("Slumber state capable");
}
if (caps & 0x8000) {
dbgln("PIO Multiple DRQ Block");
}
if (caps & 0x1'0000) {
dbgln("FIS-Based Switching");
}
if (caps & 0x2'0000) {
dbgln("Port Multiplier");
}
if (caps & 0x4'0000) {
dbgln("AHCI mode only");
}
dbgln("Speed support: %u", (caps & 0xF0'0000) >> 20);
if (caps & 0x100'0000) {
dbgln("Command list override");
}
if (caps & 0x200'0000) {
dbgln("Activity LED");
}
if (caps & 0x400'0000) {
dbgln("Aggresive link power management");
}
if (caps & 0x800'0000) {
dbgln("Staggered spin up");
}
if (caps & 0x1000'0000) {
dbgln("Mechanical Switch Presence");
}
if (caps & 0x2000'0000) {
dbgln("SNotification Register");
}
if (caps & 0x4000'0000) {
dbgln("Native Command Queueing");
}
if (caps & 0x8000'0000) {
dbgln("64bit Addressing");
}
// Secondary.
caps = ahci_hba_->capabilities_ext;
if (caps & 0x1) {
dbgln("BIOS/OS handoff");
}
if (caps & 0x2) {
dbgln("NVMHCI Present");
}
if (caps & 0x4) {
dbgln("Auto partial to slumber tranisitions");
}
if (caps & 0x8) {
dbgln("Device sleep");
}
if (caps & 0x10) {
dbgln("Aggressive device sleep management");
}
}
void AhciDriver::DumpPorts() {
dbgln("Ports implemented %x", ahci_hba_->port_implemented);
uint64_t port_index = 0;
uint32_t ports_implemented = ahci_hba_->port_implemented;
while (ports_implemented) {
if (!(ports_implemented & 0x1)) {
ports_implemented >>= 1;
port_index++;
continue;
}
uint64_t port_addr =
reinterpret_cast<uint64_t>(ahci_hba_) + 0x100 + (0x80 * port_index);
AhciPort* port = reinterpret_cast<AhciPort*>(port_addr);
dbgln("");
dbgln("Port %u:", port_index);
dbgln("Comlist: %lx", port->command_list_base);
dbgln("FIS: %lx", port->fis_base);
dbgln("Command: %x", port->command);
dbgln("Signature: %x", port->signature);
dbgln("SATA status: %x", port->sata_status);
ports_implemented >>= 1;
port_index++;
}
}
z_err_t AhciDriver::LoadPciDeviceHeader() {
uint64_t vmmo_cap;
RET_ERR(ZMemoryObjectCreatePhysical(kSataPciPhys, kPciSize, &vmmo_cap));
uint64_t vaddr;
RET_ERR(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
pci_device_header_ = reinterpret_cast<PciDeviceHeader*>(vaddr);
return Z_OK;
}
z_err_t AhciDriver::LoadHbaRegisters() {
uint64_t vmmo_cap;
RET_ERR(
ZMemoryObjectCreatePhysical(pci_device_header_->abar, 0x1100, &vmmo_cap));
uint64_t vaddr;
RET_ERR(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
ahci_hba_ = reinterpret_cast<AhciHba*>(vaddr);
return Z_OK;
}

View File

@ -0,0 +1,76 @@
#pragma once
#include <zerrors.h>
struct PciDeviceHeader {
uint16_t vendor_id;
uint16_t device_id;
uint16_t command_reg;
uint16_t status_reg;
uint8_t revision;
uint8_t prog_interface;
uint8_t subclass;
uint8_t class_code;
uint8_t cache_line_size;
uint8_t latency_timer;
uint8_t header_type;
uint8_t bist;
uint32_t bars[5];
uint32_t abar;
uint32_t subsystem_id;
uint32_t expansion_rom;
uint8_t cap_ptr;
uint8_t reserved[7];
uint8_t interrupt_line;
uint8_t interrupt_pin;
uint8_t min_grant;
uint8_t max_latency;
} __attribute__((packed));
struct AhciHba {
uint32_t capabilities;
uint32_t global_host_control;
uint32_t interrupt_status;
uint32_t port_implemented;
uint32_t version;
uint32_t ccc_ctl; // 0x14, Command completion coalescing control
uint32_t ccc_pts; // 0x18, Command completion coalescing ports
uint32_t em_loc; // 0x1C, Enclosure management location
uint32_t em_ctl; // 0x20, Enclosure management control
uint32_t capabilities_ext;
uint32_t bohc; // 0x28, BIOS/OS handoff control and status
};
struct AhciPort {
uint64_t command_list_base;
uint64_t fis_base;
uint32_t interrupt_status;
uint32_t interrupt_enable;
uint32_t command;
uint32_t reserved;
uint32_t task_file_data;
uint32_t signature;
uint32_t sata_status;
uint32_t sata_control;
uint32_t sata_error;
uint32_t sata_active;
uint32_t command_issue;
uint32_t sata_notification;
uint32_t fis_based_switching_ctl;
uint32_t device_sleep;
};
class AhciDriver {
public:
z_err_t Init();
void DumpCapabilities();
void DumpPorts();
private:
PciDeviceHeader* pci_device_header_ = nullptr;
AhciHba* ahci_hba_ = nullptr;
z_err_t LoadPciDeviceHeader();
z_err_t LoadHbaRegisters();
};

8
sys/denali/denali.cpp Normal file
View File

@ -0,0 +1,8 @@
#include <stdint.h>
#include "ahci/ahci_driver.h"
int main(uint64_t bootstrap_cap) {
AhciDriver driver;
return driver.Init();
}

View File

@ -1,28 +0,0 @@
#include <mammoth/channel.h>
#include <mammoth/debug.h>
#include <mammoth/thread.h>
#include <stdlib.h>
void thread_entry(void* a) {
dbgln("In thread");
dbgln(static_cast<const char*>(a));
}
int main(uint64_t bootstrap_cap) {
dbgln("Main thread");
const char* a = "a";
const char* b = "bee";
const char* c = "cee";
const char* d = "dee";
Thread t1(thread_entry, a);
Thread t2(thread_entry, b);
uint64_t size = 10;
char* buff = new char[size];
Channel c1;
c1.adopt_cap(bootstrap_cap);
check(c1.ReadStr(buff, &size));
dbgln(buff);
return 0;
}

View File

@ -7,4 +7,4 @@ TIMEOUT=0
KERNEL_PATH=boot:///zion
MODULE_PATH=boot:///sys/yellowstone
MODULE_PATH=boot:///sys/test2
MODULE_PATH=boot:///sys/denali

View File

@ -31,6 +31,7 @@
#define Z_INIT_VMAS_SELF 0x20
#define Z_MEMORY_OBJECT_CREATE 0x30
#define Z_MEMORY_OBJECT_CREATE_PHYSICAL 0x31
#define Z_TEMP_PCIE_CONFIG_OBJECT_CREATE 0x3F
@ -67,6 +68,8 @@ void ZThreadExit();
[[nodiscard]] z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
uint64_t vmmo_cap, uint64_t* vaddr);
[[nodiscard]] z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap);
[[nodiscard]] z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
uint64_t* vmmo_cap);
[[nodiscard]] z_err_t ZTempPcieConfigObjectCreate(uint64_t* vmmo_cap,
uint64_t* vmmo_size);

View File

@ -123,7 +123,7 @@ void LoadInitProgram() {
uint64_t entry = LoadElfProgram(
*proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size);
const limine_file& prog2 = GetInitProgram("/sys/test2");
const limine_file& prog2 = GetInitProgram("/sys/denali");
RefPtr<MemoryObject> prog2_vmmo = MakeRefCounted<MemoryObject>(prog2.size);
prog2_vmmo->CopyBytesToObject(reinterpret_cast<uint64_t>(prog2.address),
prog2.size);

View File

@ -130,14 +130,20 @@ z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
return Z_OK;
}
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req,
ZMemoryObjectCreateResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess();
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(req->paddr, req->size);
resp->vmmo_cap =
curr_proc.AddCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
return Z_OK;
}
z_err_t TempPcieConfigObjectCreate(ZTempPcieConfigObjectCreateResp* resp) {
auto& curr_proc = gScheduler->CurrentProcess();
uint64_t pci_base, pci_size;
dbgln("Getting config");
RET_ERR(GetPciExtendedConfiguration(&pci_base, &pci_size));
dbgln("Making obj");
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(pci_base, pci_size);
dbgln("Adding cap");
resp->vmmo_cap =
curr_proc.AddCapability(StaticCastRefPtr<MemoryObject>(vmmo_ref));
resp->vmmo_size = pci_size;
@ -201,6 +207,10 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
return MemoryObjectCreate(
reinterpret_cast<ZMemoryObjectCreateReq*>(req),
reinterpret_cast<ZMemoryObjectCreateResp*>(resp));
case Z_MEMORY_OBJECT_CREATE_PHYSICAL:
return MemoryObjectCreatePhysical(
reinterpret_cast<ZMemoryObjectCreatePhysicalReq*>(req),
reinterpret_cast<ZMemoryObjectCreateResp*>(resp));
case Z_TEMP_PCIE_CONFIG_OBJECT_CREATE:
return TempPcieConfigObjectCreate(
reinterpret_cast<ZTempPcieConfigObjectCreateResp*>(resp));

View File

@ -73,6 +73,7 @@ z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
*vaddr = resp.vaddr;
return ret;
}
z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) {
ZMemoryObjectCreateReq req{
.size = size,
@ -83,6 +84,18 @@ z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) {
return ret;
}
z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
uint64_t* vmmo_cap) {
ZMemoryObjectCreatePhysicalReq req{
.paddr = paddr,
.size = size,
};
ZMemoryObjectCreateResp resp;
z_err_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE_PHYSICAL, &req, &resp);
*vmmo_cap = resp.vmmo_cap;
return ret;
}
z_err_t ZTempPcieConfigObjectCreate(uint64_t* vmmo_cap, uint64_t* vmmo_size) {
ZTempPcieConfigObjectCreateResp resp;
z_err_t ret = SysCall2(Z_TEMP_PCIE_CONFIG_OBJECT_CREATE, 0, &resp);

View File

@ -46,6 +46,11 @@ struct ZMemoryObjectCreateResp {
uint64_t vmmo_cap;
};
struct ZMemoryObjectCreatePhysicalReq {
uint64_t paddr;
uint64_t size;
};
struct ZTempPcieConfigObjectCreateResp {
uint64_t vmmo_cap;
uint64_t vmmo_size;