Compare commits
16 Commits
21b73b5b92
...
685070d65e
Author | SHA1 | Date |
---|---|---|
|
685070d65e | |
|
7bd6aa42b0 | |
|
5e99dbf7d1 | |
|
7dcbbd671e | |
|
6e86ce67f0 | |
|
424b032146 | |
|
bbc31a0d2b | |
|
857b7fae03 | |
|
cc191cd6bb | |
|
378ced6b6c | |
|
09ac87e6f5 | |
|
2ea1f90690 | |
|
0a909eae0e | |
|
528723e490 | |
|
4c936623b5 | |
|
35f24e7c77 |
|
@ -1,4 +1,5 @@
|
|||
#include <zcall.h>
|
||||
#include <zglobal.h>
|
||||
|
||||
#include "stdlib.h"
|
||||
|
||||
|
@ -14,7 +15,7 @@ class NaiveAllocator {
|
|||
if (err != 0) {
|
||||
ZProcessExit(err);
|
||||
}
|
||||
err = ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &next_addr_);
|
||||
err = ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &next_addr_);
|
||||
max_addr_ = next_addr_ + kSize;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
add_library(mammoth_lib STATIC
|
||||
src/channel.cpp
|
||||
src/debug.cpp
|
||||
src/init.cpp
|
||||
src/memory_region.cpp
|
||||
src/process.cpp
|
||||
src/port.cpp
|
||||
src/thread.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zerrors.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
class Channel {
|
||||
public:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zerrors.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
void dbgln(const char* fmt, ...);
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zglobal.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
z_err_t ParseInitPort(uint64_t init_port_cap);
|
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zcall.h>
|
||||
|
||||
class Port {
|
||||
public:
|
||||
Port(uint64_t port_cap);
|
||||
|
||||
z_err_t PollForIntCap(uint64_t* msg, uint64_t* cap);
|
||||
|
||||
template <typename T>
|
||||
z_err_t WriteMessage(const T& obj, uint64_t cap);
|
||||
|
||||
private:
|
||||
uint64_t port_cap_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
z_err_t Port::WriteMessage(const T& obj, uint64_t cap) {
|
||||
return ZPortSend(port_cap_, sizeof(obj),
|
||||
reinterpret_cast<const uint8_t*>(&obj), 1, &cap);
|
||||
}
|
|
@ -35,8 +35,7 @@ z_err_t Channel::WriteStr(const char* msg) {
|
|||
if (!chan_cap_) {
|
||||
return Z_ERR_NULL;
|
||||
}
|
||||
uint64_t type = 0;
|
||||
return ZChannelSend(chan_cap_, type, strlen(msg),
|
||||
return ZChannelSend(chan_cap_, strlen(msg),
|
||||
reinterpret_cast<const uint8_t*>(msg), 0, 0);
|
||||
}
|
||||
|
||||
|
@ -44,10 +43,9 @@ z_err_t Channel::ReadStr(char* buffer, uint64_t* size) {
|
|||
if (!chan_cap_) {
|
||||
return Z_ERR_NULL;
|
||||
}
|
||||
uint64_t type;
|
||||
uint64_t num_caps;
|
||||
return ZChannelRecv(chan_cap_, *size, reinterpret_cast<uint8_t*>(buffer), 0,
|
||||
0, &type, size, &num_caps);
|
||||
0, size, &num_caps);
|
||||
}
|
||||
|
||||
z_err_t CreateChannels(Channel& c1, Channel& c2) {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <zcall.h>
|
||||
#include <zerrors.h>
|
||||
|
||||
void dbgln_internal(const char* str) { // Safe to ignore the result since right
|
||||
// now this doesn't throw.
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include "mammoth/init.h"
|
||||
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "mammoth/debug.h"
|
||||
#include "mammoth/port.h"
|
||||
|
||||
uint64_t gSelfProcCap = 0;
|
||||
uint64_t gSelfVmasCap = 0;
|
||||
|
||||
uint64_t gInitChannelCap = 0;
|
||||
|
||||
uint64_t gBootDenaliVmmoCap = 0;
|
||||
|
||||
z_err_t ParseInitPort(uint64_t init_port_cap) {
|
||||
Port port(init_port_cap);
|
||||
z_err_t ret;
|
||||
uint64_t init_sig, init_cap;
|
||||
while ((ret = port.PollForIntCap(&init_sig, &init_cap)) != Z_ERR_EMPTY) {
|
||||
RET_ERR(ret);
|
||||
switch (init_sig) {
|
||||
case Z_INIT_SELF_PROC:
|
||||
dbgln("received proc");
|
||||
gSelfProcCap = init_cap;
|
||||
break;
|
||||
case Z_INIT_SELF_VMAS:
|
||||
dbgln("received vmas");
|
||||
gSelfVmasCap = init_cap;
|
||||
break;
|
||||
case Z_INIT_CHANNEL:
|
||||
gInitChannelCap = init_cap;
|
||||
break;
|
||||
case Z_BOOT_DENALI_VMMO:
|
||||
dbgln("received denali");
|
||||
gBootDenaliVmmoCap = init_cap;
|
||||
break;
|
||||
default:
|
||||
dbgln("Unexpected init type %x, continuing.", init_sig);
|
||||
}
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#include <zcall.h>
|
||||
|
||||
#include "mammoth/debug.h"
|
||||
#include "mammoth/init.h"
|
||||
|
||||
MappedMemoryRegion MappedMemoryRegion::DirectPhysical(uint64_t paddr,
|
||||
uint64_t size) {
|
||||
|
@ -10,7 +11,7 @@ MappedMemoryRegion MappedMemoryRegion::DirectPhysical(uint64_t paddr,
|
|||
check(ZMemoryObjectCreatePhysical(paddr, size, &vmmo_cap));
|
||||
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr));
|
||||
|
||||
return MappedMemoryRegion(vmmo_cap, paddr, vaddr, size);
|
||||
}
|
||||
|
@ -20,7 +21,7 @@ MappedMemoryRegion MappedMemoryRegion::ContiguousPhysical(uint64_t size) {
|
|||
check(ZMemoryObjectCreateContiguous(size, &vmmo_cap, &paddr));
|
||||
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr));
|
||||
|
||||
return MappedMemoryRegion(vmmo_cap, paddr, vaddr, size);
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ MappedMemoryRegion MappedMemoryRegion::Default(uint64_t size) {
|
|||
check(ZMemoryObjectCreate(size, &vmmo_cap));
|
||||
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr));
|
||||
|
||||
return MappedMemoryRegion(vmmo_cap, 0, vaddr, size);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include "mammoth/port.h"
|
||||
|
||||
#include <zcall.h>
|
||||
|
||||
#include "mammoth/debug.h"
|
||||
|
||||
Port::Port(uint64_t port_cap) : port_cap_(port_cap) {}
|
||||
|
||||
z_err_t Port::PollForIntCap(uint64_t *msg, uint64_t *cap) {
|
||||
uint64_t bytes, caps;
|
||||
RET_ERR(ZPortPoll(port_cap_, sizeof(uint64_t),
|
||||
reinterpret_cast<uint8_t *>(msg), /* num_caps= */ 1, cap,
|
||||
&bytes, &caps));
|
||||
|
||||
if (bytes != sizeof(uint64_t)) {
|
||||
return Z_ERR_INVALID;
|
||||
}
|
||||
if (caps != 1) {
|
||||
return Z_ERR_INVALID;
|
||||
}
|
||||
return Z_OK;
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
#include "mammoth/process.h"
|
||||
|
||||
#include <zcall.h>
|
||||
#include <zerrors.h>
|
||||
|
||||
#include "mammoth/channel.h"
|
||||
#include "mammoth/debug.h"
|
||||
#include "mammoth/init.h"
|
||||
#include "mammoth/port.h"
|
||||
|
||||
#define MAM_PROC_DEBUG 0
|
||||
|
||||
|
@ -76,7 +77,7 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) {
|
|||
dbgln("Map Local");
|
||||
#endif
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, mem_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr));
|
||||
|
||||
#if MAM_PROC_DEBUG
|
||||
dbgln("Copy");
|
||||
|
@ -97,26 +98,40 @@ uint64_t SpawnProcessFromElfRegion(uint64_t program, Channel& local) {
|
|||
Channel foreign;
|
||||
check(CreateChannels(local, foreign));
|
||||
|
||||
uint64_t proc_cap;
|
||||
uint64_t as_cap;
|
||||
uint64_t foreign_port_id;
|
||||
uint64_t port_cap;
|
||||
#if MAM_PROC_DEBUG
|
||||
dbgln("Port Create");
|
||||
#endif
|
||||
check(ZPortCreate(&port_cap));
|
||||
uint64_t port_cap_donate;
|
||||
check(ZCapDuplicate(port_cap, &port_cap_donate));
|
||||
|
||||
#if MAM_PROC_DEBUG
|
||||
dbgln("Spawn");
|
||||
#endif
|
||||
uint64_t proc_cap;
|
||||
uint64_t as_cap;
|
||||
uint64_t foreign_chan_id;
|
||||
check(ZProcessSpawn(Z_INIT_PROC_SELF, foreign.release_cap(), &proc_cap,
|
||||
&as_cap, &foreign_chan_id));
|
||||
check(ZProcessSpawn(gSelfProcCap, port_cap_donate, &proc_cap, &as_cap,
|
||||
&foreign_port_id));
|
||||
|
||||
uint64_t entry_point = LoadElfProgram(program, as_cap);
|
||||
|
||||
#if MAM_PROC_DEBUG
|
||||
dbgln("Thread Create");
|
||||
#endif
|
||||
uint64_t thread_cap;
|
||||
check(ZThreadCreate(proc_cap, &thread_cap));
|
||||
|
||||
Port p(port_cap);
|
||||
check(p.WriteMessage<uint64_t>(Z_INIT_SELF_PROC, proc_cap));
|
||||
check(p.WriteMessage<uint64_t>(Z_INIT_SELF_VMAS, as_cap));
|
||||
check(p.WriteMessage<uint64_t>(Z_INIT_CHANNEL, foreign.release_cap()));
|
||||
|
||||
#if MAM_PROC_DEBUG
|
||||
dbgln("Thread start");
|
||||
#endif
|
||||
check(ZThreadStart(thread_cap, entry_point, foreign_chan_id, 0));
|
||||
check(ZThreadStart(thread_cap, entry_point, foreign_port_id, 0));
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <zcall.h>
|
||||
|
||||
#include "mammoth/debug.h"
|
||||
#include "mammoth/init.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -15,7 +16,7 @@ extern "C" void thread_entry(Thread::Entry entry, void* arg1) {
|
|||
} // namespace
|
||||
|
||||
Thread::Thread(Entry e, const void* arg1) {
|
||||
check(ZThreadCreate(Z_INIT_PROC_SELF, &thread_cap_));
|
||||
check(ZThreadCreate(gSelfProcCap, &thread_cap_));
|
||||
check(ZThreadStart(thread_cap_, reinterpret_cast<uint64_t>(thread_entry),
|
||||
reinterpret_cast<uint64_t>(e),
|
||||
reinterpret_cast<uint64_t>(arg1)));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <mammoth/memory_region.h>
|
||||
#include <zerrors.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "ahci/ahci.h"
|
||||
#include "ahci/command.h"
|
||||
|
|
|
@ -140,8 +140,8 @@ void AhciDriver::DumpPorts() {
|
|||
void AhciDriver::InterruptLoop() {
|
||||
dbgln("Starting interrupt loop");
|
||||
while (true) {
|
||||
uint64_t type, bytes, caps;
|
||||
check(ZPortRecv(irq_port_cap_, 0, 0, 0, 0, &type, &bytes, &caps));
|
||||
uint64_t bytes, caps;
|
||||
check(ZPortRecv(irq_port_cap_, 0, 0, 0, 0, &bytes, &caps));
|
||||
for (uint64_t i = 0; i < 32; i++) {
|
||||
if (devices_[i] != nullptr && devices_[i]->IsInit() &&
|
||||
(ahci_hba_->interrupt_status & (1 << i))) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <mammoth/thread.h>
|
||||
#include <zerrors.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "ahci/ahci.h"
|
||||
#include "ahci/ahci_device.h"
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include <mammoth/channel.h>
|
||||
#include <mammoth/debug.h>
|
||||
#include <mammoth/init.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ahci/ahci_driver.h"
|
||||
#include "denali_server.h"
|
||||
|
||||
int main(uint64_t bootstrap_cap) {
|
||||
uint64_t main(uint64_t init_port_cap) {
|
||||
check(ParseInitPort(init_port_cap));
|
||||
AhciDriver driver;
|
||||
RET_ERR(driver.Init());
|
||||
|
||||
DenaliServer server(bootstrap_cap, driver);
|
||||
DenaliServer server(gInitChannelCap, driver);
|
||||
RET_ERR(server.RunServer());
|
||||
// FIXME: Add thread join.
|
||||
return 0;
|
||||
|
|
|
@ -19,9 +19,13 @@ z_err_t DenaliServer::RunServer() {
|
|||
while (true) {
|
||||
uint64_t buff_size = kBuffSize;
|
||||
uint64_t cap_size = 0;
|
||||
uint64_t type = DENALI_INVALID;
|
||||
RET_ERR(ZChannelRecv(channel_cap_, buff_size, read_buffer_, 0, nullptr,
|
||||
&type, &buff_size, &cap_size));
|
||||
&buff_size, &cap_size));
|
||||
if (buff_size < sizeof(uint64_t)) {
|
||||
dbgln("Skipping invalid message");
|
||||
continue;
|
||||
}
|
||||
uint64_t type = *reinterpret_cast<uint64_t*>(read_buffer_);
|
||||
switch (type) {
|
||||
case Z_INVALID:
|
||||
dbgln(reinterpret_cast<char*>(read_buffer_));
|
||||
|
@ -55,6 +59,6 @@ void DenaliServer::HandleResponse(uint64_t lba, uint64_t size, uint64_t cap) {
|
|||
.lba = lba,
|
||||
.size = size,
|
||||
};
|
||||
check(ZChannelSend(channel_cap_, DENALI_READ, sizeof(resp),
|
||||
check(ZChannelSend(channel_cap_, sizeof(resp),
|
||||
reinterpret_cast<uint8_t*>(&resp), 1, &cap));
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define DENALI_READ 100
|
||||
|
||||
struct DenaliRead {
|
||||
uint64_t request_type = DENALI_READ;
|
||||
uint64_t device_id;
|
||||
|
||||
uint64_t lba;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "hw/pcie.h"
|
||||
|
||||
#include <mammoth/debug.h>
|
||||
#include <mammoth/init.h>
|
||||
#include <zcall.h>
|
||||
|
||||
namespace {
|
||||
|
@ -91,7 +92,7 @@ void DumpPciEDevices() {
|
|||
|
||||
dbgln("Creating addr space");
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr));
|
||||
dbgln("Addr %lx", vaddr);
|
||||
|
||||
dbgln("Dumping PCI");
|
||||
|
|
|
@ -1,27 +1,18 @@
|
|||
#include <denali/denali.h>
|
||||
#include <mammoth/channel.h>
|
||||
#include <mammoth/debug.h>
|
||||
#include <mammoth/init.h>
|
||||
#include <mammoth/process.h>
|
||||
#include <zcall.h>
|
||||
|
||||
#include "hw/pcie.h"
|
||||
|
||||
int main(uint64_t port_cap) {
|
||||
uint64_t main(uint64_t port_cap) {
|
||||
dbgln("Yellowstone Initializing.");
|
||||
uint64_t msg_type, type, cap, bytes, caps;
|
||||
check(ZPortRecv(port_cap, 8, reinterpret_cast<uint8_t*>(&msg_type), 1, &cap,
|
||||
&type, &bytes, &caps));
|
||||
uint64_t vmmo_cap = 0;
|
||||
if (bytes != 8 || caps != 1) {
|
||||
crash("Invalid boot msg", Z_ERR_INVALID);
|
||||
}
|
||||
if (msg_type == Z_INIT_BOOT_VMMO) {
|
||||
vmmo_cap = cap;
|
||||
} else {
|
||||
crash("Missing vmmo cap", Z_ERR_UNIMPLEMENTED);
|
||||
}
|
||||
check(ParseInitPort(port_cap));
|
||||
|
||||
uint64_t vaddr;
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, vmmo_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr));
|
||||
|
||||
Channel local;
|
||||
check(SpawnProcessFromElfRegion(vaddr, local));
|
||||
|
@ -31,19 +22,17 @@ int main(uint64_t port_cap) {
|
|||
.lba = 0,
|
||||
.size = 1,
|
||||
};
|
||||
check(ZChannelSend(local.cap(), DENALI_READ, sizeof(DenaliRead),
|
||||
check(ZChannelSend(local.cap(), sizeof(DenaliRead),
|
||||
reinterpret_cast<uint8_t*>(&read), 0, nullptr));
|
||||
|
||||
DenaliReadResponse resp;
|
||||
uint64_t mem_cap;
|
||||
uint64_t mem_cap, bytes, caps;
|
||||
|
||||
check(ZChannelRecv(local.cap(), sizeof(resp),
|
||||
reinterpret_cast<uint8_t*>(&resp), 1, &mem_cap, &type,
|
||||
&bytes, &caps));
|
||||
reinterpret_cast<uint8_t*>(&resp), 1, &mem_cap, &bytes,
|
||||
&caps));
|
||||
|
||||
dbgln("Resp: %u", type);
|
||||
|
||||
check(ZAddressSpaceMap(Z_INIT_VMAS_SELF, 0, mem_cap, &vaddr));
|
||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr));
|
||||
uint32_t* mbr = reinterpret_cast<uint32_t*>(vaddr + 0x1FE);
|
||||
dbgln("MBR: %x", *mbr);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "include/zerrors.h"
|
||||
#include "include/ztypes.h"
|
||||
|
||||
void ProbeRsdp();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "include/zerrors.h"
|
||||
#include "include/ztypes.h"
|
||||
|
||||
void dbg(const char* fmt, ...);
|
||||
void dbgln(const char* str, ...);
|
||||
|
|
|
@ -2,103 +2,62 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "zerrors.h"
|
||||
|
||||
#define Z_INVALID 0x0
|
||||
|
||||
#define ZC_WRITE 0x01
|
||||
#define ZC_READ 0x02
|
||||
|
||||
// Process Calls.
|
||||
#define Z_PROCESS_EXIT 0x01
|
||||
#define Z_PROCESS_SPAWN 0x02
|
||||
#define Z_PROCESS_START 0x03
|
||||
|
||||
#define ZC_PROC_SPAWN_PROC 0x100
|
||||
#define ZC_PROC_SPAWN_THREAD 0x101
|
||||
|
||||
#define Z_INIT_PROC_SELF 0x1
|
||||
|
||||
// Thread Calls.
|
||||
#define Z_THREAD_CREATE 0x10
|
||||
#define Z_THREAD_START 0x11
|
||||
#define Z_THREAD_EXIT 0x12
|
||||
|
||||
// Memory Calls
|
||||
#define Z_ADDRESS_SPACE_MAP 0x21
|
||||
#define Z_ADDRESS_SPACE_UNMAP 0x22
|
||||
|
||||
#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
|
||||
|
||||
#define Z_INIT_BOOT_VMMO 0x31
|
||||
|
||||
// IPC Calls
|
||||
#define Z_CHANNEL_CREATE 0x40
|
||||
#define Z_CHANNEL_SEND 0x41
|
||||
#define Z_CHANNEL_RECV 0x42
|
||||
#define Z_CHANNEL_SENDRECV 0x43
|
||||
|
||||
#define Z_PORT_CREATE 0x50
|
||||
#define Z_PORT_SEND 0x51
|
||||
#define Z_PORT_RECV 0x52
|
||||
|
||||
#define Z_IRQ_REGISTER 0x58
|
||||
|
||||
#define Z_IRQ_PCI_BASE 0x30
|
||||
|
||||
// Debugging Calls.
|
||||
#define Z_DEBUG_PRINT 0x10000000
|
||||
#include "ztypes.h"
|
||||
|
||||
void ZProcessExit(uint64_t code);
|
||||
|
||||
[[nodiscard]] z_err_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
|
||||
uint64_t* new_proc_cap,
|
||||
uint64_t* new_vmas_cap,
|
||||
uint64_t* new_bootstrap_cap);
|
||||
[[nodiscard]] z_err_t ZProcessSpawn(z_cap_t proc_cap, z_cap_t bootstrap_cap,
|
||||
z_cap_t* new_proc_cap,
|
||||
z_cap_t* new_vmas_cap,
|
||||
z_cap_t* new_bootstrap_cap);
|
||||
|
||||
// UNUSED for now, I think we can get away with just starting a thread.
|
||||
[[nodiscard]] z_err_t ZProcessStart(uint64_t proc_cap, uint64_t thread_cap,
|
||||
[[nodiscard]] z_err_t ZProcessStart(z_cap_t proc_cap, z_cap_t thread_cap,
|
||||
uint64_t entry, uint64_t arg1,
|
||||
uint64_t arg2);
|
||||
|
||||
[[nodiscard]] z_err_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap);
|
||||
[[nodiscard]] z_err_t ZThreadCreate(z_cap_t proc_cap, z_cap_t* thread_cap);
|
||||
|
||||
[[nodiscard]] z_err_t ZThreadStart(uint64_t thread_cap, uint64_t entry,
|
||||
[[nodiscard]] z_err_t ZThreadStart(z_cap_t thread_cap, uint64_t entry,
|
||||
uint64_t arg1, uint64_t arg2);
|
||||
|
||||
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 ZAddressSpaceMap(z_cap_t vmas_cap, uint64_t vmas_offset,
|
||||
z_cap_t vmmo_cap, uint64_t* vaddr);
|
||||
[[nodiscard]] z_err_t ZMemoryObjectCreate(uint64_t size, z_cap_t* vmmo_cap);
|
||||
[[nodiscard]] z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
|
||||
uint64_t* vmmo_cap);
|
||||
z_cap_t* vmmo_cap);
|
||||
[[nodiscard]] z_err_t ZMemoryObjectCreateContiguous(uint64_t size,
|
||||
uint64_t* vmmo_cap,
|
||||
z_cap_t* vmmo_cap,
|
||||
uint64_t* paddr);
|
||||
|
||||
[[nodiscard]] z_err_t ZTempPcieConfigObjectCreate(uint64_t* vmmo_cap,
|
||||
[[nodiscard]] z_err_t ZTempPcieConfigObjectCreate(z_cap_t* vmmo_cap,
|
||||
uint64_t* vmmo_size);
|
||||
|
||||
[[nodiscard]] z_err_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2);
|
||||
[[nodiscard]] z_err_t ZChannelSend(uint64_t chan_cap, uint64_t type,
|
||||
uint64_t num_bytes, const uint8_t* bytes,
|
||||
uint64_t num_caps, const uint64_t* caps);
|
||||
[[nodiscard]] z_err_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes,
|
||||
[[nodiscard]] z_err_t ZChannelCreate(z_cap_t* channel1, z_cap_t* channel2);
|
||||
[[nodiscard]] z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes,
|
||||
const uint8_t* bytes, uint64_t num_caps,
|
||||
const z_cap_t* caps);
|
||||
[[nodiscard]] z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes,
|
||||
uint8_t* bytes, uint64_t num_caps,
|
||||
uint64_t* caps, uint64_t* type,
|
||||
uint64_t* actual_bytes,
|
||||
z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps);
|
||||
|
||||
[[nodiscard]] z_err_t ZPortRecv(uint64_t port_cap, uint64_t num_bytes,
|
||||
[[nodiscard]] z_err_t ZPortCreate(z_cap_t* port_cap);
|
||||
[[nodiscard]] z_err_t ZPortSend(z_cap_t port_cap, uint64_t num_bytes,
|
||||
const uint8_t* bytes, uint64_t num_caps,
|
||||
z_cap_t* caps);
|
||||
[[nodiscard]] z_err_t ZPortRecv(z_cap_t port_cap, uint64_t num_bytes,
|
||||
uint8_t* bytes, uint64_t num_caps,
|
||||
uint64_t* caps, uint64_t* type,
|
||||
uint64_t* actual_bytes, uint64_t* actual_caps);
|
||||
[[nodiscard]] z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap);
|
||||
z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps);
|
||||
[[nodiscard]] z_err_t ZPortPoll(z_cap_t port_cap, uint64_t num_bytes,
|
||||
uint8_t* bytes, uint64_t num_caps,
|
||||
z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps);
|
||||
[[nodiscard]] z_err_t ZIrqRegister(uint64_t irq_num, z_cap_t* port_cap);
|
||||
|
||||
[[nodiscard]] z_err_t ZCapDuplicate(z_cap_t cap_in, z_cap_t* cap_out);
|
||||
|
||||
[[nodiscard]] z_err_t ZDebug(const char* message);
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define Z_OK 0x0
|
||||
#define Z_ERR_NOT_FOUND 0x1
|
||||
#define Z_ERR_INVALID 0x2
|
||||
#define Z_ERR_DENIED 0x3
|
||||
#define Z_ERR_UNIMPLEMENTED 0x4
|
||||
#define Z_ERR_BUFF_SIZE 005
|
||||
#define Z_ERR_NULL 0x6
|
||||
#define Z_ERR_EXISTS 0x7
|
||||
|
||||
#define Z_ERR_CAP_NOT_FOUND 0x100
|
||||
#define Z_ERR_CAP_TYPE 0x101
|
||||
#define Z_ERR_CAP_DENIED 0x102
|
||||
|
||||
typedef uint64_t z_err_t;
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern uint64_t gSelfProcCap;
|
||||
extern uint64_t gSelfVmasCap;
|
||||
|
||||
extern uint64_t gInitChannelCap;
|
||||
|
||||
extern uint64_t gBootDenaliVmmoCap;
|
|
@ -0,0 +1 @@
|
|||
#pragma once
|
|
@ -0,0 +1,103 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ------------------------------
|
||||
* Error Types
|
||||
*
|
||||
* Bit 31 always set to 1 to
|
||||
* distinguish from user-space errors.
|
||||
* ------------------------------*/
|
||||
#define Z_OK 0x0
|
||||
|
||||
#define Z_ERR_NOT_FOUND 0x1000'0001
|
||||
#define Z_ERR_INVALID 0x1000'0002
|
||||
#define Z_ERR_DENIED 0x1000'0003
|
||||
#define Z_ERR_UNIMPLEMENTED 0x1000'0004
|
||||
#define Z_ERR_BUFF_SIZE 001000'0005
|
||||
#define Z_ERR_NULL 0x1000'0006
|
||||
#define Z_ERR_EXISTS 0x1000'0007
|
||||
#define Z_ERR_EMPTY 0x1000'0008
|
||||
|
||||
#define Z_ERR_CAP_NOT_FOUND 0x1001'0000
|
||||
#define Z_ERR_CAP_TYPE 0x1001'0001
|
||||
#define Z_ERR_CAP_DENIED 0x1001'0002
|
||||
|
||||
typedef uint64_t z_err_t;
|
||||
|
||||
/* ------------------------------
|
||||
* Syscall Types
|
||||
* ------------------------------*/
|
||||
|
||||
// Process Calls.
|
||||
#define Z_PROCESS_EXIT 0x01
|
||||
#define Z_PROCESS_SPAWN 0x02
|
||||
#define Z_PROCESS_START 0x03
|
||||
|
||||
// Thread Calls.
|
||||
#define Z_THREAD_CREATE 0x10
|
||||
#define Z_THREAD_START 0x11
|
||||
#define Z_THREAD_EXIT 0x12
|
||||
|
||||
// Memory Calls
|
||||
#define Z_ADDRESS_SPACE_MAP 0x21
|
||||
#define Z_ADDRESS_SPACE_UNMAP 0x22
|
||||
|
||||
#define Z_MEMORY_OBJECT_CREATE 0x30
|
||||
#define Z_MEMORY_OBJECT_CREATE_PHYSICAL 0x31
|
||||
|
||||
#define Z_TEMP_PCIE_CONFIG_OBJECT_CREATE 0x3F
|
||||
|
||||
// IPC Calls
|
||||
#define Z_CHANNEL_CREATE 0x40
|
||||
#define Z_CHANNEL_SEND 0x41
|
||||
#define Z_CHANNEL_RECV 0x42
|
||||
#define Z_CHANNEL_SENDRECV 0x43
|
||||
|
||||
#define Z_PORT_CREATE 0x50
|
||||
#define Z_PORT_SEND 0x51
|
||||
#define Z_PORT_RECV 0x52
|
||||
#define Z_PORT_POLL 0x53
|
||||
|
||||
#define Z_IRQ_REGISTER 0x58
|
||||
|
||||
#define Z_IRQ_PCI_BASE 0x30
|
||||
|
||||
// Capability Calls
|
||||
#define Z_CAP_DUPLICATE 0x60
|
||||
|
||||
// Debugging Calls.
|
||||
#define Z_DEBUG_PRINT 0x10000000
|
||||
|
||||
/* ------------------------------
|
||||
* Capability Types
|
||||
* ------------------------------*/
|
||||
|
||||
typedef uint64_t z_cap_t;
|
||||
|
||||
#define Z_INVALID 0x0
|
||||
|
||||
// General Capability Permissions
|
||||
#define ZC_WRITE 0x01
|
||||
#define ZC_READ 0x02
|
||||
|
||||
// Capability Specific Permissions
|
||||
#define ZC_PROC_SPAWN_PROC 0x100
|
||||
#define ZC_PROC_SPAWN_THREAD 0x200
|
||||
|
||||
/* ------------------------------
|
||||
* Process Init Types
|
||||
*
|
||||
* Used to pull capabilites off
|
||||
* the initialization port.
|
||||
*
|
||||
* Start at a high number only to
|
||||
* make them distinctive as a raw
|
||||
* value.
|
||||
* ------------------------------*/
|
||||
#define Z_INIT_SELF_PROC 0x4000'0000
|
||||
#define Z_INIT_SELF_VMAS 0x4000'0001
|
||||
|
||||
#define Z_INIT_CHANNEL 0x4100'0000
|
||||
|
||||
#define Z_BOOT_DENALI_VMMO 0x4200'0000
|
|
@ -70,7 +70,6 @@ class SharedPtr {
|
|||
return;
|
||||
}
|
||||
if (--(*ref_cnt_) == 0) {
|
||||
dbgln("Deleting shared ptr: %m", ptr_);
|
||||
delete ptr_;
|
||||
delete ref_cnt_;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ uint64_t LoadElfProgram(Process& dest_proc, uint64_t base, uint64_t offset) {
|
|||
program.type, program.flags, program.offset, program.vaddr,
|
||||
program.paddr, program.filesz, program.memsz, program.align);
|
||||
#endif
|
||||
auto mem_obj = MakeRefCounted<MemoryObject>(program.filesz);
|
||||
auto mem_obj = MakeRefCounted<MemoryObject>(program.memsz);
|
||||
mem_obj->CopyBytesToObject(base + program.offset, program.filesz);
|
||||
dest_proc.vmas()->MapInMemoryObject(program.vaddr, mem_obj);
|
||||
}
|
||||
|
@ -129,25 +129,16 @@ void LoadInitProgram() {
|
|||
prog2_vmmo->CopyBytesToObject(reinterpret_cast<uint64_t>(prog2.address),
|
||||
prog2.size);
|
||||
|
||||
// TODO: Probably add a way for the kernel to write caps directly rather than
|
||||
// by installing them first.
|
||||
uint64_t vmmo_cap =
|
||||
gScheduler->CurrentProcess().AddNewCapability(prog2_vmmo, ZC_WRITE);
|
||||
|
||||
auto port = MakeRefCounted<Port>();
|
||||
uint64_t port_cap = proc->AddNewCapability(port, ZC_READ | ZC_WRITE);
|
||||
|
||||
uint64_t vmmo_id = Z_INIT_BOOT_VMMO;
|
||||
ZMessage vmmo_msg{
|
||||
.type = 0,
|
||||
.num_bytes = 8,
|
||||
.bytes = reinterpret_cast<uint8_t*>(&vmmo_id),
|
||||
.num_caps = 1,
|
||||
.caps = &vmmo_cap,
|
||||
};
|
||||
if (port->Write(vmmo_msg) != Z_OK) {
|
||||
panic("Failed to write cap");
|
||||
}
|
||||
port->WriteKernel(Z_INIT_SELF_PROC,
|
||||
MakeRefCounted<Capability>(
|
||||
proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD));
|
||||
port->WriteKernel(Z_INIT_SELF_VMAS,
|
||||
MakeRefCounted<Capability>(proc->vmas(), ZC_WRITE));
|
||||
port->WriteKernel(Z_BOOT_DENALI_VMMO,
|
||||
MakeRefCounted<Capability>(prog2_vmmo, ZC_READ | ZC_WRITE));
|
||||
|
||||
proc->CreateThread()->Start(entry, port_cap, 0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "object/channel.h"
|
||||
|
||||
#include "include/zerrors.h"
|
||||
#include "include/ztypes.h"
|
||||
#include "scheduler/scheduler.h"
|
||||
|
||||
Pair<RefPtr<Channel>, RefPtr<Channel>> Channel::CreateChannelPair() {
|
||||
|
@ -34,7 +34,6 @@ z_err_t Channel::Read(ZMessage& msg) {
|
|||
return Z_ERR_BUFF_SIZE;
|
||||
}
|
||||
|
||||
msg.type = next_msg->type;
|
||||
msg.num_bytes = next_msg->num_bytes;
|
||||
|
||||
for (uint64_t i = 0; i < msg.num_bytes; i++) {
|
||||
|
@ -59,7 +58,6 @@ z_err_t Channel::EnqueueMessage(const ZMessage& msg) {
|
|||
}
|
||||
|
||||
auto message = MakeShared<Message>();
|
||||
message->type = msg.type;
|
||||
|
||||
// Copy Message body.
|
||||
message->num_bytes = msg.num_bytes;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "capability/capability.h"
|
||||
#include "include/zerrors.h"
|
||||
#include "include/ztypes.h"
|
||||
#include "lib/linked_list.h"
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/pair.h"
|
||||
|
@ -35,8 +35,6 @@ class Channel : public KernelObject {
|
|||
Mutex mutex_{"channel"};
|
||||
|
||||
struct Message {
|
||||
uint64_t type;
|
||||
|
||||
uint64_t num_bytes;
|
||||
uint8_t* bytes;
|
||||
|
||||
|
|
|
@ -9,10 +9,9 @@ z_err_t Port::Write(const ZMessage& msg) {
|
|||
dbgln("Large message size unimplemented: %x", msg.num_bytes);
|
||||
return Z_ERR_INVALID;
|
||||
}
|
||||
dbgln("port write");
|
||||
|
||||
auto message = MakeShared<Message>();
|
||||
message->type = msg.type, message->num_bytes = msg.num_bytes;
|
||||
message->num_bytes = msg.num_bytes;
|
||||
message->bytes = new uint8_t[msg.num_bytes];
|
||||
for (uint64_t i = 0; i < msg.num_bytes; i++) {
|
||||
message->bytes[i] = msg.bytes[i];
|
||||
|
@ -37,7 +36,6 @@ z_err_t Port::Write(const ZMessage& msg) {
|
|||
}
|
||||
|
||||
z_err_t Port::Read(ZMessage& msg) {
|
||||
dbgln("port read");
|
||||
mutex_.Lock();
|
||||
while (pending_messages_.size() < 1) {
|
||||
blocked_threads_.PushBack(gScheduler->CurrentThread());
|
||||
|
@ -56,7 +54,6 @@ z_err_t Port::Read(ZMessage& msg) {
|
|||
return Z_ERR_BUFF_SIZE;
|
||||
}
|
||||
|
||||
msg.type = next_msg->type;
|
||||
msg.num_bytes = next_msg->num_bytes;
|
||||
|
||||
for (uint64_t i = 0; i < msg.num_bytes; i++) {
|
||||
|
@ -73,3 +70,24 @@ z_err_t Port::Read(ZMessage& msg) {
|
|||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
void Port::WriteKernel(uint64_t init, RefPtr<Capability> cap) {
|
||||
MutexHolder h(mutex_);
|
||||
|
||||
auto msg = MakeShared<Message>();
|
||||
msg->bytes = new uint8_t[8];
|
||||
msg->num_bytes = sizeof(init);
|
||||
|
||||
uint8_t* data = reinterpret_cast<uint8_t*>(&init);
|
||||
for (uint8_t i = 0; i < sizeof(init); i++) {
|
||||
msg->bytes[i] = data[i];
|
||||
}
|
||||
msg->caps.PushBack(cap);
|
||||
|
||||
pending_messages_.PushBack(msg);
|
||||
}
|
||||
|
||||
bool Port::HasMessages() {
|
||||
MutexHolder h(mutex_);
|
||||
return pending_messages_.size() != 0;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,12 @@ class Port : public KernelObject {
|
|||
z_err_t Write(const ZMessage& msg);
|
||||
z_err_t Read(ZMessage& msg);
|
||||
|
||||
void WriteKernel(uint64_t init, RefPtr<Capability> cap);
|
||||
|
||||
bool HasMessages();
|
||||
|
||||
private:
|
||||
struct Message {
|
||||
uint64_t type;
|
||||
uint64_t num_bytes;
|
||||
uint8_t* bytes;
|
||||
|
||||
|
|
|
@ -20,13 +20,7 @@ RefPtr<Process> Process::RootProcess() {
|
|||
|
||||
return proc;
|
||||
}
|
||||
RefPtr<Process> Process::Create() {
|
||||
auto proc = MakeRefCounted<Process>();
|
||||
proc->AddNewCapabilityWithId(Z_INIT_PROC_SELF, proc,
|
||||
ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD);
|
||||
proc->AddNewCapabilityWithId(Z_INIT_VMAS_SELF, proc->vmas(), ZC_WRITE);
|
||||
return proc;
|
||||
}
|
||||
RefPtr<Process> Process::Create() { return MakeRefCounted<Process>(); }
|
||||
|
||||
Process::Process()
|
||||
: id_(gNextId++), vmas_(MakeRefCounted<AddressSpace>()), state_(RUNNING) {}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "common/msr.h"
|
||||
#include "debug/debug.h"
|
||||
#include "include/zcall.h"
|
||||
#include "include/zerrors.h"
|
||||
#include "interrupt/interrupt.h"
|
||||
#include "memory/physical_memory.h"
|
||||
#include "object/channel.h"
|
||||
|
@ -57,7 +56,10 @@ z_err_t ValidateCap(const RefPtr<Capability>& cap, uint64_t permissions) {
|
|||
if (!cap) {
|
||||
return Z_ERR_CAP_NOT_FOUND;
|
||||
}
|
||||
// FIXME: Check capability type before permissions, otherwise you can
|
||||
// get a confusing error.
|
||||
if (!cap->HasPermissions(permissions)) {
|
||||
dbgln("PERM, has %x needs %x", cap->permissions(), permissions);
|
||||
return Z_ERR_CAP_DENIED;
|
||||
}
|
||||
return Z_OK;
|
||||
|
@ -72,7 +74,7 @@ z_err_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
|
|||
gProcMan->InsertProcess(proc);
|
||||
|
||||
resp->proc_cap = curr_proc.AddNewCapability(
|
||||
proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_PROC | ZC_WRITE);
|
||||
proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD | ZC_WRITE);
|
||||
resp->vmas_cap = curr_proc.AddNewCapability(proc->vmas(), ZC_WRITE);
|
||||
|
||||
if (req->bootstrap_cap != 0) {
|
||||
|
@ -123,7 +125,7 @@ z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
|
|||
auto vmmo = vmmo_cap->obj<MemoryObject>();
|
||||
RET_IF_NULL(vmas);
|
||||
RET_IF_NULL(vmmo);
|
||||
dbgln("Ptr %x, %x", vmas.get(), vmmo.get());
|
||||
|
||||
// FIXME: Validation necessary.
|
||||
if (req->vmas_offset != 0) {
|
||||
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
|
||||
|
@ -198,6 +200,23 @@ z_err_t ChannelRecv(ZChannelRecvReq* req) {
|
|||
return chan->Read(req->message);
|
||||
}
|
||||
|
||||
z_err_t PortCreate(ZPortCreateResp* resp) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
auto port = MakeRefCounted<Port>();
|
||||
resp->port_cap = proc.AddNewCapability(port, ZC_WRITE | ZC_READ);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
z_err_t PortSend(ZPortSendReq* req) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
auto port_cap = proc.GetCapability(req->port_cap);
|
||||
RET_ERR(ValidateCap(port_cap, ZC_WRITE));
|
||||
|
||||
auto port = port_cap->obj<Port>();
|
||||
RET_IF_NULL(port);
|
||||
return port->Write(req->message);
|
||||
}
|
||||
|
||||
z_err_t PortRecv(ZPortRecvReq* req) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
auto port_cap = proc.GetCapability(req->port_cap);
|
||||
|
@ -208,6 +227,19 @@ z_err_t PortRecv(ZPortRecvReq* req) {
|
|||
return port->Read(req->message);
|
||||
}
|
||||
|
||||
z_err_t PortPoll(ZPortRecvReq* req) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
auto port_cap = proc.GetCapability(req->port_cap);
|
||||
RET_ERR(ValidateCap(port_cap, ZC_READ));
|
||||
|
||||
auto port = port_cap->obj<Port>();
|
||||
RET_IF_NULL(port);
|
||||
if (!port->HasMessages()) {
|
||||
return Z_ERR_EMPTY;
|
||||
}
|
||||
return port->Read(req->message);
|
||||
}
|
||||
|
||||
z_err_t IrqRegister(ZIrqRegisterReq* req, ZIrqRegisterResp* resp) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
if (req->irq_num != Z_IRQ_PCI_BASE) {
|
||||
|
@ -220,12 +252,22 @@ z_err_t IrqRegister(ZIrqRegisterReq* req, ZIrqRegisterResp* resp) {
|
|||
return Z_OK;
|
||||
}
|
||||
|
||||
z_err_t CapDuplicate(ZCapDuplicateReq* req, ZCapDuplicateResp* resp) {
|
||||
auto& proc = gScheduler->CurrentProcess();
|
||||
auto cap = proc.GetCapability(req->cap);
|
||||
if (!cap) {
|
||||
return Z_ERR_CAP_NOT_FOUND;
|
||||
}
|
||||
resp->cap = proc.AddExistingCapability(cap);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
||||
RefPtr<Thread> thread = gScheduler->CurrentThread();
|
||||
switch (call_id) {
|
||||
case Z_PROCESS_EXIT:
|
||||
// FIXME: kill process here.
|
||||
dbgln("Exit code: %u", req);
|
||||
dbgln("Exit code: %x", req);
|
||||
thread->Exit();
|
||||
panic("Returned from thread exit");
|
||||
break;
|
||||
|
@ -262,11 +304,20 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
|||
return ChannelSend(reinterpret_cast<ZChannelSendReq*>(req));
|
||||
case Z_CHANNEL_RECV:
|
||||
return ChannelRecv(reinterpret_cast<ZChannelRecvReq*>(req));
|
||||
case Z_PORT_CREATE:
|
||||
return PortCreate(reinterpret_cast<ZPortCreateResp*>(resp));
|
||||
case Z_PORT_SEND:
|
||||
return PortSend(reinterpret_cast<ZPortSendReq*>(req));
|
||||
case Z_PORT_RECV:
|
||||
return PortRecv(reinterpret_cast<ZPortRecvReq*>(req));
|
||||
case Z_PORT_POLL:
|
||||
return PortPoll(reinterpret_cast<ZPortRecvReq*>(req));
|
||||
case Z_IRQ_REGISTER:
|
||||
return IrqRegister(reinterpret_cast<ZIrqRegisterReq*>(req),
|
||||
reinterpret_cast<ZIrqRegisterResp*>(resp));
|
||||
case Z_CAP_DUPLICATE:
|
||||
return CapDuplicate(reinterpret_cast<ZCapDuplicateReq*>(req),
|
||||
reinterpret_cast<ZCapDuplicateResp*>(resp));
|
||||
case Z_DEBUG_PRINT:
|
||||
dbgln("[Debug] %s", req);
|
||||
return Z_OK;
|
||||
|
|
|
@ -23,9 +23,9 @@ void ZProcessExit(uint64_t code) {
|
|||
SysCall1(Z_PROCESS_EXIT, reinterpret_cast<void*>(code));
|
||||
}
|
||||
|
||||
z_err_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
|
||||
uint64_t* new_proc_cap, uint64_t* new_vmas_cap,
|
||||
uint64_t* new_bootstrap_cap) {
|
||||
z_err_t ZProcessSpawn(z_cap_t proc_cap, z_cap_t bootstrap_cap,
|
||||
z_cap_t* new_proc_cap, z_cap_t* new_vmas_cap,
|
||||
z_cap_t* new_bootstrap_cap) {
|
||||
ZProcessSpawnReq req{
|
||||
.proc_cap = proc_cap,
|
||||
.bootstrap_cap = bootstrap_cap,
|
||||
|
@ -38,7 +38,7 @@ z_err_t ZProcessSpawn(uint64_t proc_cap, uint64_t bootstrap_cap,
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap) {
|
||||
z_err_t ZThreadCreate(z_cap_t proc_cap, z_cap_t* thread_cap) {
|
||||
ZThreadCreateReq req{
|
||||
.proc_cap = proc_cap,
|
||||
};
|
||||
|
@ -48,7 +48,7 @@ z_err_t ZThreadCreate(uint64_t proc_cap, uint64_t* thread_cap) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1,
|
||||
z_err_t ZThreadStart(z_cap_t thread_cap, uint64_t entry, uint64_t arg1,
|
||||
uint64_t arg2) {
|
||||
ZThreadStartReq req{
|
||||
.thread_cap = thread_cap,
|
||||
|
@ -61,8 +61,8 @@ z_err_t ZThreadStart(uint64_t thread_cap, uint64_t entry, uint64_t arg1,
|
|||
|
||||
void ZThreadExit() { SysCall0(Z_THREAD_EXIT); }
|
||||
|
||||
z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
|
||||
uint64_t vmmo_cap, uint64_t* vaddr) {
|
||||
z_err_t ZAddressSpaceMap(z_cap_t vmas_cap, uint64_t vmas_offset,
|
||||
z_cap_t vmmo_cap, uint64_t* vaddr) {
|
||||
ZAddressSpaceMapReq req{
|
||||
.vmas_cap = vmas_cap,
|
||||
.vmas_offset = vmas_offset,
|
||||
|
@ -74,7 +74,7 @@ z_err_t ZAddressSpaceMap(uint64_t vmas_cap, uint64_t vmas_offset,
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) {
|
||||
z_err_t ZMemoryObjectCreate(uint64_t size, z_cap_t* vmmo_cap) {
|
||||
ZMemoryObjectCreateReq req{
|
||||
.size = size,
|
||||
};
|
||||
|
@ -85,7 +85,7 @@ z_err_t ZMemoryObjectCreate(uint64_t size, uint64_t* vmmo_cap) {
|
|||
}
|
||||
|
||||
z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
|
||||
uint64_t* vmmo_cap) {
|
||||
z_cap_t* vmmo_cap) {
|
||||
ZMemoryObjectCreatePhysicalReq req{
|
||||
.paddr = paddr,
|
||||
.size = size,
|
||||
|
@ -96,7 +96,7 @@ z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZMemoryObjectCreateContiguous(uint64_t size, uint64_t* vmmo_cap,
|
||||
z_err_t ZMemoryObjectCreateContiguous(uint64_t size, z_cap_t* vmmo_cap,
|
||||
uint64_t* paddr) {
|
||||
ZMemoryObjectCreatePhysicalReq req{
|
||||
.paddr = 0,
|
||||
|
@ -109,7 +109,7 @@ z_err_t ZMemoryObjectCreateContiguous(uint64_t size, uint64_t* vmmo_cap,
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZTempPcieConfigObjectCreate(uint64_t* vmmo_cap, uint64_t* vmmo_size) {
|
||||
z_err_t ZTempPcieConfigObjectCreate(z_cap_t* vmmo_cap, uint64_t* vmmo_size) {
|
||||
ZTempPcieConfigObjectCreateResp resp;
|
||||
z_err_t ret = SysCall2(Z_TEMP_PCIE_CONFIG_OBJECT_CREATE, 0, &resp);
|
||||
*vmmo_cap = resp.vmmo_cap;
|
||||
|
@ -117,7 +117,7 @@ z_err_t ZTempPcieConfigObjectCreate(uint64_t* vmmo_cap, uint64_t* vmmo_size) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2) {
|
||||
z_err_t ZChannelCreate(z_cap_t* channel1, z_cap_t* channel2) {
|
||||
ZChannelCreateResp resp;
|
||||
z_err_t ret = SysCall2(Z_CHANNEL_CREATE, 0, &resp);
|
||||
*channel1 = resp.chan_cap1;
|
||||
|
@ -125,31 +125,28 @@ z_err_t ZChannelCreate(uint64_t* channel1, uint64_t* channel2) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZChannelSend(uint64_t chan_cap, uint64_t type, uint64_t num_bytes,
|
||||
const uint8_t* bytes, uint64_t num_caps,
|
||||
const uint64_t* caps) {
|
||||
z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes, const uint8_t* bytes,
|
||||
uint64_t num_caps, const z_cap_t* caps) {
|
||||
ZChannelSendReq req{
|
||||
.chan_cap = chan_cap,
|
||||
.message =
|
||||
{
|
||||
.type = type,
|
||||
.num_bytes = num_bytes,
|
||||
.bytes = const_cast<uint8_t*>(bytes),
|
||||
.num_caps = num_caps,
|
||||
.caps = const_cast<uint64_t*>(caps),
|
||||
.caps = const_cast<z_cap_t*>(caps),
|
||||
},
|
||||
};
|
||||
return SysCall1(Z_CHANNEL_SEND, &req);
|
||||
}
|
||||
|
||||
z_err_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||
uint64_t num_caps, uint64_t* caps, uint64_t* type,
|
||||
uint64_t* actual_bytes, uint64_t* actual_caps) {
|
||||
z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||
uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps) {
|
||||
ZChannelRecvReq req{
|
||||
.chan_cap = chan_cap,
|
||||
.message =
|
||||
{
|
||||
.type = 0,
|
||||
.num_bytes = num_bytes,
|
||||
.bytes = bytes,
|
||||
.num_caps = num_caps,
|
||||
|
@ -157,20 +154,37 @@ z_err_t ZChannelRecv(uint64_t chan_cap, uint64_t num_bytes, uint8_t* bytes,
|
|||
},
|
||||
};
|
||||
z_err_t ret = SysCall1(Z_CHANNEL_RECV, &req);
|
||||
*type = req.message.type;
|
||||
*actual_bytes = req.message.num_bytes;
|
||||
*actual_caps = req.message.num_caps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZPortRecv(uint64_t port_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||
uint64_t num_caps, uint64_t* caps, uint64_t* type,
|
||||
uint64_t* actual_bytes, uint64_t* actual_caps) {
|
||||
z_err_t ZPortCreate(z_cap_t* port_cap) {
|
||||
ZPortCreateResp resp;
|
||||
z_err_t ret = SysCall2(Z_PORT_CREATE, 0, &resp);
|
||||
*port_cap = resp.port_cap;
|
||||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZPortSend(z_cap_t port_cap, uint64_t num_bytes, const uint8_t* bytes,
|
||||
uint64_t num_caps, z_cap_t* caps) {
|
||||
ZPortSendReq req{.port_cap = port_cap,
|
||||
.message = {
|
||||
.num_bytes = num_bytes,
|
||||
.bytes = const_cast<uint8_t*>(bytes),
|
||||
.num_caps = num_caps,
|
||||
.caps = caps,
|
||||
}};
|
||||
return SysCall1(Z_PORT_SEND, &req);
|
||||
}
|
||||
|
||||
z_err_t ZPortRecv(z_cap_t port_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||
uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps) {
|
||||
ZPortRecvReq req{
|
||||
.port_cap = port_cap,
|
||||
.message =
|
||||
{
|
||||
.type = 0,
|
||||
.num_bytes = num_bytes,
|
||||
.bytes = bytes,
|
||||
.num_caps = num_caps,
|
||||
|
@ -178,13 +192,31 @@ z_err_t ZPortRecv(uint64_t port_cap, uint64_t num_bytes, uint8_t* bytes,
|
|||
},
|
||||
};
|
||||
z_err_t ret = SysCall1(Z_PORT_RECV, &req);
|
||||
*type = req.message.type;
|
||||
*actual_bytes = req.message.num_bytes;
|
||||
*actual_caps = req.message.num_caps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap) {
|
||||
z_err_t ZPortPoll(z_cap_t port_cap, uint64_t num_bytes, uint8_t* bytes,
|
||||
uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes,
|
||||
uint64_t* actual_caps) {
|
||||
ZPortRecvReq req{
|
||||
.port_cap = port_cap,
|
||||
.message =
|
||||
{
|
||||
.num_bytes = num_bytes,
|
||||
.bytes = bytes,
|
||||
.num_caps = num_caps,
|
||||
.caps = caps,
|
||||
},
|
||||
};
|
||||
z_err_t ret = SysCall1(Z_PORT_POLL, &req);
|
||||
*actual_bytes = req.message.num_bytes;
|
||||
*actual_caps = req.message.num_caps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZIrqRegister(uint64_t irq_num, z_cap_t* port_cap) {
|
||||
ZIrqRegisterReq req{
|
||||
.irq_num = irq_num,
|
||||
};
|
||||
|
@ -194,4 +226,14 @@ z_err_t ZIrqRegister(uint64_t irq_num, uint64_t* port_cap) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZCapDuplicate(z_cap_t cap_in, z_cap_t* cap_out) {
|
||||
ZCapDuplicateReq req{
|
||||
.cap = cap_in,
|
||||
};
|
||||
ZCapDuplicateResp resp;
|
||||
z_err_t ret = SysCall2(Z_CAP_DUPLICATE, &req, &resp);
|
||||
*cap_out = resp.cap;
|
||||
return ret;
|
||||
}
|
||||
|
||||
z_err_t ZDebug(const char* message) { return SysCall1(Z_DEBUG_PRINT, message); }
|
||||
|
|
|
@ -2,36 +2,38 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "include/ztypes.h"
|
||||
|
||||
struct ZProcessSpawnReq {
|
||||
uint64_t proc_cap;
|
||||
uint64_t bootstrap_cap;
|
||||
z_cap_t proc_cap;
|
||||
z_cap_t bootstrap_cap;
|
||||
};
|
||||
|
||||
struct ZProcessSpawnResp {
|
||||
uint64_t proc_cap;
|
||||
uint64_t vmas_cap;
|
||||
uint64_t bootstrap_cap;
|
||||
z_cap_t proc_cap;
|
||||
z_cap_t vmas_cap;
|
||||
z_cap_t bootstrap_cap;
|
||||
};
|
||||
|
||||
struct ZThreadCreateReq {
|
||||
uint64_t proc_cap;
|
||||
z_cap_t proc_cap;
|
||||
};
|
||||
|
||||
struct ZThreadCreateResp {
|
||||
uint64_t thread_cap;
|
||||
z_cap_t thread_cap;
|
||||
};
|
||||
|
||||
struct ZThreadStartReq {
|
||||
uint64_t thread_cap;
|
||||
z_cap_t thread_cap;
|
||||
uint64_t entry;
|
||||
uint64_t arg1;
|
||||
uint64_t arg2;
|
||||
};
|
||||
|
||||
struct ZAddressSpaceMapReq {
|
||||
uint64_t vmas_cap;
|
||||
uint64_t vmas_offset;
|
||||
uint64_t vmmo_cap;
|
||||
z_cap_t vmas_cap;
|
||||
z_cap_t vmas_offset;
|
||||
z_cap_t vmmo_cap;
|
||||
};
|
||||
|
||||
struct ZAddressSpaceMapResp {
|
||||
|
@ -43,7 +45,7 @@ struct ZMemoryObjectCreateReq {
|
|||
};
|
||||
|
||||
struct ZMemoryObjectCreateResp {
|
||||
uint64_t vmmo_cap;
|
||||
z_cap_t vmmo_cap;
|
||||
};
|
||||
|
||||
struct ZMemoryObjectCreatePhysicalReq {
|
||||
|
@ -52,42 +54,49 @@ struct ZMemoryObjectCreatePhysicalReq {
|
|||
};
|
||||
|
||||
struct ZMemoryObjectCreatePhysicalResp {
|
||||
uint64_t vmmo_cap;
|
||||
z_cap_t vmmo_cap;
|
||||
uint64_t paddr;
|
||||
};
|
||||
|
||||
struct ZTempPcieConfigObjectCreateResp {
|
||||
uint64_t vmmo_cap;
|
||||
z_cap_t vmmo_cap;
|
||||
uint64_t vmmo_size;
|
||||
};
|
||||
|
||||
struct ZChannelCreateResp {
|
||||
uint64_t chan_cap1;
|
||||
uint64_t chan_cap2;
|
||||
z_cap_t chan_cap1;
|
||||
z_cap_t chan_cap2;
|
||||
};
|
||||
|
||||
struct ZMessage {
|
||||
uint64_t type;
|
||||
|
||||
uint64_t num_bytes;
|
||||
uint8_t* bytes;
|
||||
|
||||
uint64_t num_caps;
|
||||
uint64_t* caps;
|
||||
z_cap_t* caps;
|
||||
};
|
||||
|
||||
struct ZChannelSendReq {
|
||||
uint64_t chan_cap;
|
||||
z_cap_t chan_cap;
|
||||
ZMessage message;
|
||||
};
|
||||
|
||||
struct ZChannelRecvReq {
|
||||
uint64_t chan_cap;
|
||||
z_cap_t chan_cap;
|
||||
ZMessage message;
|
||||
};
|
||||
|
||||
struct ZPortCreateResp {
|
||||
z_cap_t port_cap;
|
||||
};
|
||||
|
||||
struct ZPortSendReq {
|
||||
z_cap_t port_cap;
|
||||
ZMessage message;
|
||||
};
|
||||
|
||||
struct ZPortRecvReq {
|
||||
uint64_t port_cap;
|
||||
z_cap_t port_cap;
|
||||
ZMessage message;
|
||||
};
|
||||
|
||||
|
@ -96,5 +105,13 @@ struct ZIrqRegisterReq {
|
|||
};
|
||||
|
||||
struct ZIrqRegisterResp {
|
||||
uint64_t port_cap;
|
||||
z_cap_t port_cap;
|
||||
};
|
||||
|
||||
struct ZCapDuplicateReq {
|
||||
z_cap_t cap;
|
||||
};
|
||||
|
||||
struct ZCapDuplicateResp {
|
||||
z_cap_t cap;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue