Compare commits
8 Commits
4fef54084f
...
1edd5023ce
Author | SHA1 | Date |
---|---|---|
|
1edd5023ce | |
|
bd431b94ce | |
|
77bb3acfb4 | |
|
1a70ce4855 | |
|
f755cd38fe | |
|
c6dd0bbb0f | |
|
76107b7db7 | |
|
5fc7296b20 |
|
@ -7,8 +7,8 @@ class Channel {
|
||||||
public:
|
public:
|
||||||
Channel() {}
|
Channel() {}
|
||||||
void adopt_cap(uint64_t id);
|
void adopt_cap(uint64_t id);
|
||||||
uint64_t release_cap();
|
z_cap_t release_cap();
|
||||||
uint64_t cap();
|
z_cap_t cap();
|
||||||
|
|
||||||
z_err_t WriteStr(const char* msg);
|
z_err_t WriteStr(const char* msg);
|
||||||
z_err_t ReadStr(char* buffer, uint64_t* size);
|
z_err_t ReadStr(char* buffer, uint64_t* size);
|
||||||
|
@ -23,7 +23,7 @@ class Channel {
|
||||||
~Channel() {}
|
~Channel() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t chan_cap_ = 0;
|
z_cap_t chan_cap_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t CreateChannels(Channel& c1, Channel& c2);
|
uint64_t CreateChannels(Channel& c1, Channel& c2);
|
||||||
|
@ -35,9 +35,10 @@ z_err_t Channel::WriteStruct(T* obj) {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
z_err_t Channel::ReadStructAndCap(T* obj, uint64_t* cap) {
|
z_err_t Channel::ReadStructAndCap(T* obj, uint64_t* cap) {
|
||||||
uint64_t num_bytes, num_caps;
|
uint64_t num_bytes = sizeof(T);
|
||||||
uint64_t ret = ZChannelRecv(chan_cap_, sizeof(T), obj, /* num_caps= */ 1, cap,
|
uint64_t num_caps = 1;
|
||||||
&num_bytes, &num_caps);
|
uint64_t ret = ZChannelRecv(chan_cap_, &num_bytes, obj, &num_caps, cap);
|
||||||
|
|
||||||
if (ret != Z_OK) {
|
if (ret != Z_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,5 @@ class Port {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
z_err_t Port::WriteMessage(const T& obj, uint64_t cap) {
|
z_err_t Port::WriteMessage(const T& obj, uint64_t cap) {
|
||||||
return ZPortSend(port_cap_, sizeof(obj),
|
return ZPortSend(port_cap_, sizeof(obj), &obj, 1, &cap);
|
||||||
reinterpret_cast<const uint8_t*>(&obj), 1, &cap);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,33 +23,32 @@ void Channel::adopt_cap(uint64_t id) {
|
||||||
}
|
}
|
||||||
chan_cap_ = id;
|
chan_cap_ = id;
|
||||||
}
|
}
|
||||||
uint64_t Channel::release_cap() {
|
z_cap_t Channel::release_cap() {
|
||||||
uint64_t cap = chan_cap_;
|
z_cap_t cap = chan_cap_;
|
||||||
chan_cap_ = 0;
|
chan_cap_ = 0;
|
||||||
return cap;
|
return cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Channel::cap() { return chan_cap_; }
|
z_cap_t Channel::cap() { return chan_cap_; }
|
||||||
|
|
||||||
z_err_t Channel::WriteStr(const char* msg) {
|
z_err_t Channel::WriteStr(const char* msg) {
|
||||||
if (!chan_cap_) {
|
if (!chan_cap_) {
|
||||||
return Z_ERR_NULL;
|
return Z_ERR_NULL;
|
||||||
}
|
}
|
||||||
return ZChannelSend(chan_cap_, strlen(msg),
|
return ZChannelSend(chan_cap_, strlen(msg), msg, 0, nullptr);
|
||||||
reinterpret_cast<const uint8_t*>(msg), 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
z_err_t Channel::ReadStr(char* buffer, uint64_t* size) {
|
z_err_t Channel::ReadStr(char* buffer, uint64_t* size) {
|
||||||
if (!chan_cap_) {
|
if (!chan_cap_) {
|
||||||
return Z_ERR_NULL;
|
return Z_ERR_NULL;
|
||||||
}
|
}
|
||||||
uint64_t num_caps;
|
uint64_t num_caps = 0;
|
||||||
return ZChannelRecv(chan_cap_, *size, reinterpret_cast<uint8_t*>(buffer), 0,
|
return ZChannelRecv(chan_cap_, size, reinterpret_cast<uint8_t*>(buffer),
|
||||||
0, size, &num_caps);
|
&num_caps, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
z_err_t CreateChannels(Channel& c1, Channel& c2) {
|
z_err_t CreateChannels(Channel& c1, Channel& c2) {
|
||||||
uint64_t chan1, chan2;
|
z_cap_t chan1, chan2;
|
||||||
z_err_t err = ZChannelCreate(&chan1, &chan2);
|
z_err_t err = ZChannelCreate(&chan1, &chan2);
|
||||||
if (err != Z_OK) {
|
if (err != Z_OK) {
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
Port::Port(uint64_t port_cap) : port_cap_(port_cap) {}
|
Port::Port(uint64_t port_cap) : port_cap_(port_cap) {}
|
||||||
|
|
||||||
z_err_t Port::PollForIntCap(uint64_t *msg, uint64_t *cap) {
|
z_err_t Port::PollForIntCap(uint64_t *msg, uint64_t *cap) {
|
||||||
uint64_t bytes, caps;
|
uint64_t bytes = sizeof(uint64_t);
|
||||||
RET_ERR(ZPortPoll(port_cap_, sizeof(uint64_t),
|
uint64_t caps = 1;
|
||||||
reinterpret_cast<uint8_t *>(msg), /* num_caps= */ 1, cap,
|
RET_ERR(ZPortPoll(port_cap_, &bytes, reinterpret_cast<uint8_t *>(msg), &caps,
|
||||||
&bytes, &caps));
|
cap));
|
||||||
|
|
||||||
if (bytes != sizeof(uint64_t)) {
|
if (bytes != sizeof(uint64_t)) {
|
||||||
return Z_ERR_INVALID;
|
return Z_ERR_INVALID;
|
||||||
|
|
|
@ -141,7 +141,7 @@ void AhciDriver::InterruptLoop() {
|
||||||
dbgln("Starting interrupt loop");
|
dbgln("Starting interrupt loop");
|
||||||
while (true) {
|
while (true) {
|
||||||
uint64_t bytes, caps;
|
uint64_t bytes, caps;
|
||||||
check(ZPortRecv(irq_port_cap_, 0, 0, 0, 0, &bytes, &caps));
|
check(ZPortRecv(irq_port_cap_, &bytes, nullptr, &caps, nullptr));
|
||||||
for (uint64_t i = 0; i < 32; i++) {
|
for (uint64_t i = 0; i < 32; i++) {
|
||||||
if (devices_[i] != nullptr && devices_[i]->IsInit() &&
|
if (devices_[i] != nullptr && devices_[i]->IsInit() &&
|
||||||
(ahci_hba_->interrupt_status & (1 << i))) {
|
(ahci_hba_->interrupt_status & (1 << i))) {
|
||||||
|
|
|
@ -19,8 +19,8 @@ z_err_t DenaliServer::RunServer() {
|
||||||
while (true) {
|
while (true) {
|
||||||
uint64_t buff_size = kBuffSize;
|
uint64_t buff_size = kBuffSize;
|
||||||
uint64_t cap_size = 0;
|
uint64_t cap_size = 0;
|
||||||
RET_ERR(ZChannelRecv(channel_cap_, buff_size, read_buffer_, 0, nullptr,
|
RET_ERR(ZChannelRecv(channel_cap_, &buff_size, read_buffer_, &cap_size,
|
||||||
&buff_size, &cap_size));
|
nullptr));
|
||||||
if (buff_size < sizeof(uint64_t)) {
|
if (buff_size < sizeof(uint64_t)) {
|
||||||
dbgln("Skipping invalid message");
|
dbgln("Skipping invalid message");
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -27,8 +27,16 @@ add_executable(zion
|
||||||
scheduler/jump_user_space.s
|
scheduler/jump_user_space.s
|
||||||
scheduler/process_manager.cpp
|
scheduler/process_manager.cpp
|
||||||
scheduler/scheduler.cpp
|
scheduler/scheduler.cpp
|
||||||
|
syscall/address_space.cpp
|
||||||
|
syscall/capability.cpp
|
||||||
|
syscall/channel.cpp
|
||||||
|
syscall/debug.cpp
|
||||||
|
syscall/memory_object.cpp
|
||||||
|
syscall/port.cpp
|
||||||
|
syscall/process.cpp
|
||||||
syscall/syscall.cpp
|
syscall/syscall.cpp
|
||||||
syscall/syscall_enter.s
|
syscall/syscall_enter.s
|
||||||
|
syscall/thread.cpp
|
||||||
zion.cpp)
|
zion.cpp)
|
||||||
|
|
||||||
target_include_directories(zion
|
target_include_directories(zion
|
||||||
|
|
|
@ -4,58 +4,125 @@
|
||||||
|
|
||||||
#include "ztypes.h"
|
#include "ztypes.h"
|
||||||
|
|
||||||
void ZProcessExit(uint64_t code);
|
#define SYS0(name) \
|
||||||
|
struct Z##name##Req {}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name() { \
|
||||||
|
Z##name##Req req{}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZProcessSpawn(z_cap_t proc_cap, z_cap_t bootstrap_cap,
|
#define SYS1(name, t1, a1) \
|
||||||
z_cap_t* new_proc_cap,
|
struct Z##name##Req { \
|
||||||
z_cap_t* new_vmas_cap,
|
t1 a1; \
|
||||||
z_cap_t* new_bootstrap_cap);
|
}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name(t1 a1) { \
|
||||||
|
Z##name##Req req{ \
|
||||||
|
.a1 = a1, \
|
||||||
|
}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
// UNUSED for now, I think we can get away with just starting a thread.
|
#define SYS2(name, t1, a1, t2, a2) \
|
||||||
[[nodiscard]] z_err_t ZProcessStart(z_cap_t proc_cap, z_cap_t thread_cap,
|
struct Z##name##Req { \
|
||||||
uint64_t entry, uint64_t arg1,
|
t1 a1; \
|
||||||
uint64_t arg2);
|
t2 a2; \
|
||||||
|
}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name(t1 a1, t2 a2) { \
|
||||||
|
Z##name##Req req{ \
|
||||||
|
.a1 = a1, \
|
||||||
|
.a2 = a2, \
|
||||||
|
}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZThreadCreate(z_cap_t proc_cap, z_cap_t* thread_cap);
|
#define SYS3(name, t1, a1, t2, a2, t3, a3) \
|
||||||
|
struct Z##name##Req { \
|
||||||
|
t1 a1; \
|
||||||
|
t2 a2; \
|
||||||
|
t3 a3; \
|
||||||
|
}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name(t1 a1, t2 a2, t3 a3) { \
|
||||||
|
Z##name##Req req{ \
|
||||||
|
.a1 = a1, \
|
||||||
|
.a2 = a2, \
|
||||||
|
.a3 = a3, \
|
||||||
|
}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZThreadStart(z_cap_t thread_cap, uint64_t entry,
|
#define SYS4(name, t1, a1, t2, a2, t3, a3, t4, a4) \
|
||||||
uint64_t arg1, uint64_t arg2);
|
struct Z##name##Req { \
|
||||||
|
t1 a1; \
|
||||||
|
t2 a2; \
|
||||||
|
t3 a3; \
|
||||||
|
t4 a4; \
|
||||||
|
}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name(t1 a1, t2 a2, t3 a3, t4 a4) { \
|
||||||
|
Z##name##Req req{ \
|
||||||
|
.a1 = a1, \
|
||||||
|
.a2 = a2, \
|
||||||
|
.a3 = a3, \
|
||||||
|
.a4 = a4, \
|
||||||
|
}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
void ZThreadExit();
|
#define SYS5(name, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
|
||||||
|
struct Z##name##Req { \
|
||||||
|
t1 a1; \
|
||||||
|
t2 a2; \
|
||||||
|
t3 a3; \
|
||||||
|
t4 a4; \
|
||||||
|
t5 a5; \
|
||||||
|
}; \
|
||||||
|
[[nodiscard]] inline z_err_t Z##name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) { \
|
||||||
|
Z##name##Req req{ \
|
||||||
|
.a1 = a1, \
|
||||||
|
.a2 = a2, \
|
||||||
|
.a3 = a3, \
|
||||||
|
.a4 = a4, \
|
||||||
|
.a5 = a5, \
|
||||||
|
}; \
|
||||||
|
return SysCall1(kZion##name, &req); \
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZAddressSpaceMap(z_cap_t vmas_cap, uint64_t vmas_offset,
|
z_err_t SysCall1(uint64_t code, const void* req);
|
||||||
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,
|
|
||||||
z_cap_t* vmmo_cap);
|
|
||||||
[[nodiscard]] z_err_t ZMemoryObjectCreateContiguous(uint64_t size,
|
|
||||||
z_cap_t* vmmo_cap,
|
|
||||||
uint64_t* paddr);
|
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZTempPcieConfigObjectCreate(z_cap_t* vmmo_cap,
|
SYS1(ProcessExit, uint64_t, code);
|
||||||
uint64_t* vmmo_size);
|
SYS5(ProcessSpawn, 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);
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZChannelCreate(z_cap_t* channel1, z_cap_t* channel2);
|
SYS2(ThreadCreate, z_cap_t, proc_cap, z_cap_t*, thread_cap);
|
||||||
[[nodiscard]] z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes,
|
SYS4(ThreadStart, z_cap_t, thread_cap, uint64_t, entry, uint64_t, arg1,
|
||||||
const void* data, uint64_t num_caps,
|
uint64_t, arg2);
|
||||||
const z_cap_t* caps);
|
SYS0(ThreadExit);
|
||||||
[[nodiscard]] z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes,
|
|
||||||
void* data, uint64_t num_caps, z_cap_t* caps,
|
|
||||||
uint64_t* actual_bytes,
|
|
||||||
uint64_t* actual_caps);
|
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZPortCreate(z_cap_t* port_cap);
|
SYS4(AddressSpaceMap, z_cap_t, vmas_cap, uint64_t, vmas_offset, z_cap_t,
|
||||||
[[nodiscard]] z_err_t ZPortSend(z_cap_t port_cap, uint64_t num_bytes,
|
vmmo_cap, uint64_t*, vaddr);
|
||||||
const void* data, uint64_t num_caps,
|
|
||||||
z_cap_t* caps);
|
|
||||||
[[nodiscard]] z_err_t ZPortRecv(z_cap_t port_cap, uint64_t num_bytes,
|
|
||||||
void* data, uint64_t num_caps, 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,
|
|
||||||
void* data, 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);
|
SYS2(MemoryObjectCreate, uint64_t, size, z_cap_t*, vmmo_cap);
|
||||||
|
SYS3(MemoryObjectCreatePhysical, uint64_t, paddr, uint64_t, size, z_cap_t*,
|
||||||
|
vmmo_cap);
|
||||||
|
SYS3(MemoryObjectCreateContiguous, uint64_t, size, z_cap_t*, vmmo_cap,
|
||||||
|
uint64_t*, paddr);
|
||||||
|
SYS2(TempPcieConfigObjectCreate, z_cap_t*, vmmo_cap, uint64_t*, vmmo_size);
|
||||||
|
|
||||||
[[nodiscard]] z_err_t ZDebug(const char* message);
|
SYS2(ChannelCreate, z_cap_t*, channel1, z_cap_t*, channel2);
|
||||||
|
SYS5(ChannelSend, z_cap_t, chan_cap, uint64_t, num_bytes, const void*, data,
|
||||||
|
uint64_t, num_caps, z_cap_t*, caps);
|
||||||
|
SYS5(ChannelRecv, z_cap_t, chan_cap, uint64_t*, num_bytes, void*, data,
|
||||||
|
uint64_t*, num_caps, z_cap_t*, caps);
|
||||||
|
|
||||||
|
SYS1(PortCreate, z_cap_t*, port_cap);
|
||||||
|
SYS5(PortSend, z_cap_t, port_cap, uint64_t, num_bytes, const void*, data,
|
||||||
|
uint64_t, num_caps, z_cap_t*, caps);
|
||||||
|
SYS5(PortRecv, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*,
|
||||||
|
num_caps, z_cap_t*, caps);
|
||||||
|
SYS5(PortPoll, z_cap_t, port_cap, uint64_t*, num_bytes, void*, data, uint64_t*,
|
||||||
|
num_caps, z_cap_t*, caps);
|
||||||
|
|
||||||
|
SYS2(IrqRegister, uint64_t, irq_num, z_cap_t*, port_cap);
|
||||||
|
|
||||||
|
SYS2(CapDuplicate, z_cap_t, cap_in, z_cap_t*, cap_out);
|
||||||
|
|
||||||
|
SYS1(Debug, const char*, message);
|
||||||
|
|
|
@ -30,44 +30,44 @@ typedef uint64_t z_err_t;
|
||||||
* ------------------------------*/
|
* ------------------------------*/
|
||||||
|
|
||||||
// Process Calls.
|
// Process Calls.
|
||||||
#define Z_PROCESS_EXIT 0x01
|
const uint64_t kZionProcessExit = 0x1;
|
||||||
#define Z_PROCESS_SPAWN 0x02
|
const uint64_t kZionProcessSpawn = 0x2;
|
||||||
#define Z_PROCESS_START 0x03
|
|
||||||
|
|
||||||
// Thread Calls.
|
// Thread Calls.
|
||||||
#define Z_THREAD_CREATE 0x10
|
const uint64_t kZionThreadCreate = 0x10;
|
||||||
#define Z_THREAD_START 0x11
|
const uint64_t kZionThreadStart = 0x11;
|
||||||
#define Z_THREAD_EXIT 0x12
|
const uint64_t kZionThreadExit = 0x12;
|
||||||
|
|
||||||
// Memory Calls
|
// Memory Calls
|
||||||
#define Z_ADDRESS_SPACE_MAP 0x21
|
const uint64_t kZionAddressSpaceMap = 0x21;
|
||||||
#define Z_ADDRESS_SPACE_UNMAP 0x22
|
const uint64_t kZionAddressSpaceUnMap = 0x21;
|
||||||
|
|
||||||
#define Z_MEMORY_OBJECT_CREATE 0x30
|
const uint64_t kZionMemoryObjectCreate = 0x30;
|
||||||
#define Z_MEMORY_OBJECT_CREATE_PHYSICAL 0x31
|
const uint64_t kZionMemoryObjectCreatePhysical = 0x31;
|
||||||
|
const uint64_t kZionMemoryObjectCreateContiguous = 0x32;
|
||||||
|
|
||||||
#define Z_TEMP_PCIE_CONFIG_OBJECT_CREATE 0x3F
|
const uint64_t kZionTempPcieConfigObjectCreate = 0x3F;
|
||||||
|
|
||||||
// IPC Calls
|
// IPC Calls
|
||||||
#define Z_CHANNEL_CREATE 0x40
|
const uint64_t kZionChannelCreate = 0x40;
|
||||||
#define Z_CHANNEL_SEND 0x41
|
const uint64_t kZionChannelSend = 0x41;
|
||||||
#define Z_CHANNEL_RECV 0x42
|
const uint64_t kZionChannelRecv = 0x42;
|
||||||
#define Z_CHANNEL_SENDRECV 0x43
|
const uint64_t kZionChannelSendRecv = 0x43;
|
||||||
|
|
||||||
#define Z_PORT_CREATE 0x50
|
const uint64_t kZionPortCreate = 0x50;
|
||||||
#define Z_PORT_SEND 0x51
|
const uint64_t kZionPortSend = 0x51;
|
||||||
#define Z_PORT_RECV 0x52
|
const uint64_t kZionPortRecv = 0x52;
|
||||||
#define Z_PORT_POLL 0x53
|
const uint64_t kZionPortPoll = 0x53;
|
||||||
|
|
||||||
#define Z_IRQ_REGISTER 0x58
|
const uint64_t kZionIrqRegister = 0x58;
|
||||||
|
|
||||||
#define Z_IRQ_PCI_BASE 0x30
|
#define Z_IRQ_PCI_BASE 0x30
|
||||||
|
|
||||||
// Capability Calls
|
// Capability Calls
|
||||||
#define Z_CAP_DUPLICATE 0x60
|
const uint64_t kZionCapDuplicate = 0x70;
|
||||||
|
|
||||||
// Debugging Calls.
|
// Debugging Calls.
|
||||||
#define Z_DEBUG_PRINT 0x10000000
|
const uint64_t kZionDebug = 0x1'0000;
|
||||||
|
|
||||||
/* ------------------------------
|
/* ------------------------------
|
||||||
* Capability Types
|
* Capability Types
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "syscall/address_space.h"
|
||||||
|
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
|
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap);
|
||||||
|
auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap);
|
||||||
|
RET_ERR(ValidateCap(vmas_cap, ZC_WRITE));
|
||||||
|
RET_ERR(ValidateCap(vmmo_cap, ZC_WRITE));
|
||||||
|
|
||||||
|
auto vmas = vmas_cap->obj<AddressSpace>();
|
||||||
|
auto vmmo = vmmo_cap->obj<MemoryObject>();
|
||||||
|
RET_IF_NULL(vmas);
|
||||||
|
RET_IF_NULL(vmmo);
|
||||||
|
|
||||||
|
// FIXME: Validation necessary.
|
||||||
|
if (req->vmas_offset != 0) {
|
||||||
|
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
|
||||||
|
*req->vaddr = req->vmas_offset;
|
||||||
|
} else {
|
||||||
|
*req->vaddr = vmas->MapInMemoryObject(vmmo);
|
||||||
|
}
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req);
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "syscall/capability.h"
|
||||||
|
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
|
z_err_t CapDuplicate(ZCapDuplicateReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
auto cap = proc.GetCapability(req->cap_in);
|
||||||
|
if (!cap) {
|
||||||
|
return Z_ERR_CAP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
*req->cap_out = proc.AddExistingCapability(cap);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t CapDuplicate(ZCapDuplicateReq* req);
|
|
@ -0,0 +1,52 @@
|
||||||
|
#include "syscall/channel.h"
|
||||||
|
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
|
z_err_t ChannelCreate(ZChannelCreateReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
auto chan_pair = Channel::CreateChannelPair();
|
||||||
|
*req->channel1 = proc.AddNewCapability(chan_pair.first(), ZC_WRITE | ZC_READ);
|
||||||
|
*req->channel2 =
|
||||||
|
proc.AddNewCapability(chan_pair.second(), ZC_WRITE | ZC_READ);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t ChannelSend(ZChannelSendReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
auto chan_cap = proc.GetCapability(req->chan_cap);
|
||||||
|
RET_ERR(ValidateCap(chan_cap, ZC_WRITE));
|
||||||
|
|
||||||
|
auto chan = chan_cap->obj<Channel>();
|
||||||
|
RET_IF_NULL(chan);
|
||||||
|
// FIXME: Get rid of this hack.
|
||||||
|
ZMessage message{
|
||||||
|
.num_bytes = req->num_bytes,
|
||||||
|
.data = const_cast<void*>(req->data),
|
||||||
|
.num_caps = req->num_caps,
|
||||||
|
.caps = req->caps,
|
||||||
|
|
||||||
|
};
|
||||||
|
return chan->Write(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t ChannelRecv(ZChannelRecvReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
auto chan_cap = proc.GetCapability(req->chan_cap);
|
||||||
|
RET_ERR(ValidateCap(chan_cap, ZC_READ));
|
||||||
|
|
||||||
|
auto chan = chan_cap->obj<Channel>();
|
||||||
|
RET_IF_NULL(chan);
|
||||||
|
// FIXME: Get rid of this hack.
|
||||||
|
ZMessage message{
|
||||||
|
.num_bytes = *req->num_bytes,
|
||||||
|
.data = const_cast<void*>(req->data),
|
||||||
|
.num_caps = *req->num_caps,
|
||||||
|
.caps = req->caps,
|
||||||
|
|
||||||
|
};
|
||||||
|
RET_ERR(chan->Read(message));
|
||||||
|
*req->num_bytes = message.num_bytes;
|
||||||
|
*req->num_caps = message.num_caps;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t ChannelCreate(ZChannelCreateReq* resp);
|
||||||
|
z_err_t ChannelSend(ZChannelSendReq* req);
|
||||||
|
z_err_t ChannelRecv(ZChannelRecvReq* req);
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "syscall/debug.h"
|
||||||
|
|
||||||
|
#include "debug/debug.h"
|
||||||
|
|
||||||
|
z_err_t Debug(ZDebugReq* req) {
|
||||||
|
dbgln("[Debug] %s", req->message);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t Debug(ZDebugReq* req);
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include "syscall/memory_object.h"
|
||||||
|
|
||||||
|
#include "boot/acpi.h"
|
||||||
|
#include "memory/physical_memory.h"
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
|
z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
|
MakeRefCounted<MemoryObject>(req->size), ZC_WRITE);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
uint64_t paddr = req->paddr;
|
||||||
|
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
||||||
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
uint64_t paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1);
|
||||||
|
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
||||||
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
|
*req->paddr = paddr;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t TempPcieConfigObjectCreate(ZTempPcieConfigObjectCreateReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
uint64_t pci_base, pci_size;
|
||||||
|
RET_ERR(GetPciExtendedConfiguration(&pci_base, &pci_size));
|
||||||
|
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(pci_base, pci_size);
|
||||||
|
*req->vmmo_cap = curr_proc.AddNewCapability(
|
||||||
|
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
||||||
|
*req->vmmo_size = pci_size;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req);
|
||||||
|
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req);
|
||||||
|
z_err_t MemoryObjectCreateContiguous(ZMemoryObjectCreateContiguousReq* req);
|
||||||
|
z_err_t TempPcieConfigObjectCreate(ZTempPcieConfigObjectCreateReq* req);
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "syscall/port.h"
|
||||||
|
|
||||||
|
#include "interrupt/interrupt.h"
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
|
z_err_t PortCreate(ZPortCreateReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
auto port = MakeRefCounted<Port>();
|
||||||
|
*req->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);
|
||||||
|
ZMessage message{
|
||||||
|
.num_bytes = req->num_bytes,
|
||||||
|
.data = const_cast<void*>(req->data),
|
||||||
|
.num_caps = req->num_caps,
|
||||||
|
.caps = req->caps,
|
||||||
|
};
|
||||||
|
return port->Write(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t PortRecv(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);
|
||||||
|
ZMessage message{
|
||||||
|
.num_bytes = *req->num_bytes,
|
||||||
|
.data = const_cast<void*>(req->data),
|
||||||
|
.num_caps = *req->num_caps,
|
||||||
|
.caps = req->caps,
|
||||||
|
};
|
||||||
|
RET_ERR(port->Read(message));
|
||||||
|
*req->num_bytes = message.num_bytes;
|
||||||
|
*req->num_caps = message.num_caps;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t PortPoll(ZPortPollReq* 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;
|
||||||
|
}
|
||||||
|
ZMessage message{
|
||||||
|
.num_bytes = *req->num_bytes,
|
||||||
|
.data = const_cast<void*>(req->data),
|
||||||
|
.num_caps = *req->num_caps,
|
||||||
|
.caps = req->caps,
|
||||||
|
};
|
||||||
|
RET_ERR(port->Read(message));
|
||||||
|
*req->num_bytes = message.num_bytes;
|
||||||
|
*req->num_caps = message.num_caps;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t IrqRegister(ZIrqRegisterReq* req) {
|
||||||
|
auto& proc = gScheduler->CurrentProcess();
|
||||||
|
if (req->irq_num != Z_IRQ_PCI_BASE) {
|
||||||
|
// FIXME: Don't hardcode this nonsense.
|
||||||
|
return Z_ERR_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
RefPtr<Port> port = MakeRefCounted<Port>();
|
||||||
|
*req->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
|
||||||
|
RegisterPciPort(port);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t PortCreate(ZPortCreateReq* req);
|
||||||
|
z_err_t PortSend(ZPortSendReq* req);
|
||||||
|
z_err_t PortRecv(ZPortRecvReq* req);
|
||||||
|
z_err_t PortPoll(ZPortPollReq* req);
|
||||||
|
z_err_t IrqRegister(ZIrqRegisterReq* req);
|
|
@ -0,0 +1,38 @@
|
||||||
|
#include "syscall/process.h"
|
||||||
|
|
||||||
|
#include "scheduler/process_manager.h"
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
|
z_err_t ProcessExit(ZProcessExitReq* req) {
|
||||||
|
auto curr_thread = gScheduler->CurrentThread();
|
||||||
|
dbgln("Exit code: %x", req->code);
|
||||||
|
// FIXME: kill process here.
|
||||||
|
curr_thread->Exit();
|
||||||
|
panic("Returned from thread exit");
|
||||||
|
return Z_ERR_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t ProcessSpawn(ZProcessSpawnReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto cap = curr_proc.GetCapability(req->proc_cap);
|
||||||
|
RET_ERR(ValidateCap(cap, ZC_PROC_SPAWN_PROC));
|
||||||
|
|
||||||
|
RefPtr<Process> proc = Process::Create();
|
||||||
|
gProcMan->InsertProcess(proc);
|
||||||
|
|
||||||
|
*req->new_proc_cap = curr_proc.AddNewCapability(
|
||||||
|
proc, ZC_PROC_SPAWN_PROC | ZC_PROC_SPAWN_THREAD | ZC_WRITE);
|
||||||
|
*req->new_vmas_cap = curr_proc.AddNewCapability(proc->vmas(), ZC_WRITE);
|
||||||
|
|
||||||
|
if (req->bootstrap_cap != 0) {
|
||||||
|
auto cap = curr_proc.ReleaseCapability(req->bootstrap_cap);
|
||||||
|
if (!cap) {
|
||||||
|
return Z_ERR_CAP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
// FIXME: Check permissions.
|
||||||
|
*req->new_bootstrap_cap = proc->AddExistingCapability(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Z_OK;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t ProcessExit(ZProcessExitReq* req);
|
||||||
|
z_err_t ProcessSpawn(ZProcessSpawnReq* req);
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "boot/acpi.h"
|
|
||||||
#include "common/msr.h"
|
#include "common/msr.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "include/zcall.h"
|
#include "include/zcall.h"
|
||||||
|
@ -13,15 +12,16 @@
|
||||||
#include "object/process.h"
|
#include "object/process.h"
|
||||||
#include "scheduler/process_manager.h"
|
#include "scheduler/process_manager.h"
|
||||||
#include "scheduler/scheduler.h"
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/address_space.h"
|
||||||
|
#include "syscall/capability.h"
|
||||||
|
#include "syscall/channel.h"
|
||||||
|
#include "syscall/debug.h"
|
||||||
|
#include "syscall/memory_object.h"
|
||||||
|
#include "syscall/port.h"
|
||||||
|
#include "syscall/process.h"
|
||||||
|
#include "syscall/thread.h"
|
||||||
#include "usr/zcall_internal.h"
|
#include "usr/zcall_internal.h"
|
||||||
|
|
||||||
#define RET_IF_NULL(expr) \
|
|
||||||
{ \
|
|
||||||
if (!expr) { \
|
|
||||||
return Z_ERR_CAP_TYPE; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EFER 0xC0000080
|
#define EFER 0xC0000080
|
||||||
#define STAR 0xC0000081
|
#define STAR 0xC0000081
|
||||||
#define LSTAR 0xC0000082
|
#define LSTAR 0xC0000082
|
||||||
|
@ -65,263 +65,41 @@ z_err_t ValidateCap(const RefPtr<Capability>& cap, uint64_t permissions) {
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
z_err_t ProcessSpawn(ZProcessSpawnReq* req, ZProcessSpawnResp* resp) {
|
#define CASE(name) \
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
case kZion##name: \
|
||||||
auto cap = curr_proc.GetCapability(req->proc_cap);
|
return name(reinterpret_cast<Z##name##Req*>(req));
|
||||||
RET_ERR(ValidateCap(cap, ZC_PROC_SPAWN_PROC));
|
|
||||||
|
|
||||||
RefPtr<Process> proc = Process::Create();
|
|
||||||
gProcMan->InsertProcess(proc);
|
|
||||||
|
|
||||||
resp->proc_cap = curr_proc.AddNewCapability(
|
|
||||||
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) {
|
|
||||||
auto cap = curr_proc.ReleaseCapability(req->bootstrap_cap);
|
|
||||||
if (!cap) {
|
|
||||||
return Z_ERR_CAP_NOT_FOUND;
|
|
||||||
}
|
|
||||||
// FIXME: Check permissions.
|
|
||||||
resp->bootstrap_cap = proc->AddExistingCapability(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ThreadCreate(ZThreadCreateReq* req, ZThreadCreateResp* resp) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
auto cap = curr_proc.GetCapability(req->proc_cap);
|
|
||||||
RET_ERR(ValidateCap(cap, ZC_PROC_SPAWN_THREAD));
|
|
||||||
|
|
||||||
auto parent_proc = cap->obj<Process>();
|
|
||||||
RET_IF_NULL(parent_proc);
|
|
||||||
auto thread = parent_proc->CreateThread();
|
|
||||||
resp->thread_cap = curr_proc.AddNewCapability(thread, ZC_WRITE);
|
|
||||||
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ThreadStart(ZThreadStartReq* req) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
auto cap = curr_proc.GetCapability(req->thread_cap);
|
|
||||||
RET_ERR(ValidateCap(cap, ZC_WRITE));
|
|
||||||
|
|
||||||
auto thread = cap->obj<Thread>();
|
|
||||||
RET_IF_NULL(thread);
|
|
||||||
// FIXME: validate entry point is in user space.
|
|
||||||
thread->Start(req->entry, req->arg1, req->arg2);
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t AddressSpaceMap(ZAddressSpaceMapReq* req, ZAddressSpaceMapResp* resp) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
auto vmas_cap = curr_proc.GetCapability(req->vmas_cap);
|
|
||||||
auto vmmo_cap = curr_proc.GetCapability(req->vmmo_cap);
|
|
||||||
RET_ERR(ValidateCap(vmas_cap, ZC_WRITE));
|
|
||||||
RET_ERR(ValidateCap(vmmo_cap, ZC_WRITE));
|
|
||||||
|
|
||||||
auto vmas = vmas_cap->obj<AddressSpace>();
|
|
||||||
auto vmmo = vmmo_cap->obj<MemoryObject>();
|
|
||||||
RET_IF_NULL(vmas);
|
|
||||||
RET_IF_NULL(vmmo);
|
|
||||||
|
|
||||||
// FIXME: Validation necessary.
|
|
||||||
if (req->vmas_offset != 0) {
|
|
||||||
vmas->MapInMemoryObject(req->vmas_offset, vmmo);
|
|
||||||
resp->vaddr = req->vmas_offset;
|
|
||||||
} else {
|
|
||||||
resp->vaddr = vmas->MapInMemoryObject(vmmo);
|
|
||||||
}
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t MemoryObjectCreate(ZMemoryObjectCreateReq* req,
|
|
||||||
ZMemoryObjectCreateResp* resp) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
resp->vmmo_cap = curr_proc.AddNewCapability(
|
|
||||||
MakeRefCounted<MemoryObject>(req->size), ZC_WRITE);
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t MemoryObjectCreatePhysical(ZMemoryObjectCreatePhysicalReq* req,
|
|
||||||
ZMemoryObjectCreatePhysicalResp* resp) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
uint64_t paddr = req->paddr;
|
|
||||||
if (paddr == 0) {
|
|
||||||
paddr = phys_mem::AllocateContinuous(((req->size - 1) / 0x1000) + 1);
|
|
||||||
}
|
|
||||||
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(paddr, req->size);
|
|
||||||
resp->vmmo_cap = curr_proc.AddNewCapability(
|
|
||||||
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
|
||||||
resp->paddr = paddr;
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t TempPcieConfigObjectCreate(ZTempPcieConfigObjectCreateResp* resp) {
|
|
||||||
auto& curr_proc = gScheduler->CurrentProcess();
|
|
||||||
uint64_t pci_base, pci_size;
|
|
||||||
RET_ERR(GetPciExtendedConfiguration(&pci_base, &pci_size));
|
|
||||||
auto vmmo_ref = MakeRefCounted<FixedMemoryObject>(pci_base, pci_size);
|
|
||||||
resp->vmmo_cap = curr_proc.AddNewCapability(
|
|
||||||
StaticCastRefPtr<MemoryObject>(vmmo_ref), ZC_WRITE);
|
|
||||||
resp->vmmo_size = pci_size;
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ChannelCreate(ZChannelCreateResp* resp) {
|
|
||||||
auto& proc = gScheduler->CurrentProcess();
|
|
||||||
auto chan_pair = Channel::CreateChannelPair();
|
|
||||||
resp->chan_cap1 =
|
|
||||||
proc.AddNewCapability(chan_pair.first(), ZC_WRITE | ZC_READ);
|
|
||||||
resp->chan_cap2 =
|
|
||||||
proc.AddNewCapability(chan_pair.second(), ZC_WRITE | ZC_READ);
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ChannelSend(ZChannelSendReq* req) {
|
|
||||||
auto& proc = gScheduler->CurrentProcess();
|
|
||||||
auto chan_cap = proc.GetCapability(req->chan_cap);
|
|
||||||
RET_ERR(ValidateCap(chan_cap, ZC_WRITE));
|
|
||||||
|
|
||||||
auto chan = chan_cap->obj<Channel>();
|
|
||||||
RET_IF_NULL(chan);
|
|
||||||
chan->Write(req->message);
|
|
||||||
return Z_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ChannelRecv(ZChannelRecvReq* req) {
|
|
||||||
auto& proc = gScheduler->CurrentProcess();
|
|
||||||
auto chan_cap = proc.GetCapability(req->chan_cap);
|
|
||||||
RET_ERR(ValidateCap(chan_cap, ZC_READ));
|
|
||||||
|
|
||||||
auto chan = chan_cap->obj<Channel>();
|
|
||||||
RET_IF_NULL(chan);
|
|
||||||
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);
|
|
||||||
RET_ERR(ValidateCap(port_cap, ZC_READ));
|
|
||||||
|
|
||||||
auto port = port_cap->obj<Port>();
|
|
||||||
RET_IF_NULL(port);
|
|
||||||
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) {
|
|
||||||
// FIXME: Don't hardcode this nonsense.
|
|
||||||
return Z_ERR_UNIMPLEMENTED;
|
|
||||||
}
|
|
||||||
RefPtr<Port> port = MakeRefCounted<Port>();
|
|
||||||
resp->port_cap = proc.AddNewCapability(port, ZC_READ | ZC_WRITE);
|
|
||||||
RegisterPciPort(port);
|
|
||||||
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) {
|
extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req, void* resp) {
|
||||||
RefPtr<Thread> thread = gScheduler->CurrentThread();
|
RefPtr<Thread> thread = gScheduler->CurrentThread();
|
||||||
switch (call_id) {
|
switch (call_id) {
|
||||||
case Z_PROCESS_EXIT:
|
// syscall/process.h
|
||||||
// FIXME: kill process here.
|
CASE(ProcessExit);
|
||||||
dbgln("Exit code: %x", req);
|
CASE(ProcessSpawn);
|
||||||
thread->Exit();
|
// syscall/thread.h
|
||||||
panic("Returned from thread exit");
|
CASE(ThreadCreate);
|
||||||
break;
|
CASE(ThreadStart);
|
||||||
case Z_PROCESS_SPAWN:
|
CASE(ThreadExit);
|
||||||
return ProcessSpawn(reinterpret_cast<ZProcessSpawnReq*>(req),
|
// syscall/address_space.h
|
||||||
reinterpret_cast<ZProcessSpawnResp*>(resp));
|
CASE(AddressSpaceMap);
|
||||||
case Z_THREAD_CREATE:
|
// syscall/memory_object.h
|
||||||
return ThreadCreate(reinterpret_cast<ZThreadCreateReq*>(req),
|
CASE(MemoryObjectCreate);
|
||||||
reinterpret_cast<ZThreadCreateResp*>(resp));
|
CASE(MemoryObjectCreatePhysical);
|
||||||
case Z_THREAD_START:
|
CASE(MemoryObjectCreateContiguous);
|
||||||
return ThreadStart(reinterpret_cast<ZThreadStartReq*>(req));
|
CASE(TempPcieConfigObjectCreate);
|
||||||
case Z_THREAD_EXIT:
|
// syscall/channel.h
|
||||||
thread->Exit();
|
CASE(ChannelCreate);
|
||||||
panic("Returned from thread exit");
|
CASE(ChannelSend);
|
||||||
break;
|
CASE(ChannelRecv);
|
||||||
|
// syscall/port.h
|
||||||
case Z_ADDRESS_SPACE_MAP:
|
CASE(PortCreate);
|
||||||
return AddressSpaceMap(reinterpret_cast<ZAddressSpaceMapReq*>(req),
|
CASE(PortSend);
|
||||||
reinterpret_cast<ZAddressSpaceMapResp*>(resp));
|
CASE(PortRecv);
|
||||||
case Z_MEMORY_OBJECT_CREATE:
|
CASE(PortPoll);
|
||||||
return MemoryObjectCreate(
|
CASE(IrqRegister);
|
||||||
reinterpret_cast<ZMemoryObjectCreateReq*>(req),
|
// syscall/capability.h
|
||||||
reinterpret_cast<ZMemoryObjectCreateResp*>(resp));
|
CASE(CapDuplicate);
|
||||||
case Z_MEMORY_OBJECT_CREATE_PHYSICAL:
|
// syscall/debug.h
|
||||||
return MemoryObjectCreatePhysical(
|
CASE(Debug);
|
||||||
reinterpret_cast<ZMemoryObjectCreatePhysicalReq*>(req),
|
|
||||||
reinterpret_cast<ZMemoryObjectCreatePhysicalResp*>(resp));
|
|
||||||
case Z_TEMP_PCIE_CONFIG_OBJECT_CREATE:
|
|
||||||
return TempPcieConfigObjectCreate(
|
|
||||||
reinterpret_cast<ZTempPcieConfigObjectCreateResp*>(resp));
|
|
||||||
case Z_CHANNEL_CREATE:
|
|
||||||
return ChannelCreate(reinterpret_cast<ZChannelCreateResp*>(resp));
|
|
||||||
case Z_CHANNEL_SEND:
|
|
||||||
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;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
panic("Unhandled syscall number: %x", call_id);
|
panic("Unhandled syscall number: %x", call_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "capability/capability.h"
|
||||||
|
#include "include/ztypes.h"
|
||||||
|
|
||||||
void InitSyscall();
|
void InitSyscall();
|
||||||
|
|
||||||
|
// FIXME: This probably belongs in capability.h
|
||||||
|
z_err_t ValidateCap(const RefPtr<Capability>& cap, uint64_t permissions);
|
||||||
|
|
||||||
|
#define RET_IF_NULL(expr) \
|
||||||
|
{ \
|
||||||
|
if (!expr) { \
|
||||||
|
return Z_ERR_CAP_TYPE; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "syscall/thread.h"
|
||||||
|
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
|
z_err_t ThreadCreate(ZThreadCreateReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto cap = curr_proc.GetCapability(req->proc_cap);
|
||||||
|
RET_ERR(ValidateCap(cap, ZC_PROC_SPAWN_THREAD));
|
||||||
|
|
||||||
|
auto parent_proc = cap->obj<Process>();
|
||||||
|
RET_IF_NULL(parent_proc);
|
||||||
|
auto thread = parent_proc->CreateThread();
|
||||||
|
*req->thread_cap = curr_proc.AddNewCapability(thread, ZC_WRITE);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t ThreadStart(ZThreadStartReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto cap = curr_proc.GetCapability(req->thread_cap);
|
||||||
|
RET_ERR(ValidateCap(cap, ZC_WRITE));
|
||||||
|
|
||||||
|
auto thread = cap->obj<Thread>();
|
||||||
|
RET_IF_NULL(thread);
|
||||||
|
// FIXME: validate entry point is in user space.
|
||||||
|
thread->Start(req->entry, req->arg1, req->arg2);
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t ThreadExit(ZThreadExitReq*) {
|
||||||
|
auto curr_thread = gScheduler->CurrentThread();
|
||||||
|
curr_thread->Exit();
|
||||||
|
panic("Returned from thread exit");
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t ThreadCreate(ZThreadCreateReq* req);
|
||||||
|
z_err_t ThreadStart(ZThreadStartReq* req);
|
||||||
|
z_err_t ThreadExit(ZThreadExitReq*);
|
|
@ -8,6 +8,7 @@ _start:
|
||||||
_exit:
|
_exit:
|
||||||
// EXIT syscall.
|
// EXIT syscall.
|
||||||
mov $1, %rdi
|
mov $1, %rdi
|
||||||
// Return code as a param.
|
// Return code as a "struct" on the stack.
|
||||||
mov %rax, %rsi
|
push %rax
|
||||||
|
mov %rsp, %rsi
|
||||||
syscall
|
syscall
|
||||||
|
|
|
@ -4,236 +4,8 @@
|
||||||
|
|
||||||
#include "usr/zcall_internal.h"
|
#include "usr/zcall_internal.h"
|
||||||
|
|
||||||
z_err_t SysCall2(uint64_t number, const void* first, const void* second) {
|
z_err_t SysCall1(uint64_t number, const void* first) {
|
||||||
z_err_t return_code;
|
z_err_t return_code;
|
||||||
asm("syscall"
|
asm("syscall" : "=a"(return_code) : "D"(number), "S"(first) : "rcx", "r11");
|
||||||
: "=a"(return_code)
|
|
||||||
: "D"(number), "S"(first), "d"(second)
|
|
||||||
: "rcx", "r11");
|
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
z_err_t SysCall0(uint64_t number) { return SysCall2(number, 0, 0); }
|
|
||||||
|
|
||||||
z_err_t SysCall1(uint64_t number, const void* first) {
|
|
||||||
return SysCall2(number, first, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZProcessExit(uint64_t code) {
|
|
||||||
SysCall1(Z_PROCESS_EXIT, reinterpret_cast<void*>(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
ZProcessSpawnResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_PROCESS_SPAWN, &req, &resp);
|
|
||||||
*new_proc_cap = resp.proc_cap;
|
|
||||||
*new_vmas_cap = resp.vmas_cap;
|
|
||||||
*new_bootstrap_cap = resp.bootstrap_cap;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZThreadCreate(z_cap_t proc_cap, z_cap_t* thread_cap) {
|
|
||||||
ZThreadCreateReq req{
|
|
||||||
.proc_cap = proc_cap,
|
|
||||||
};
|
|
||||||
ZThreadCreateResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_THREAD_CREATE, &req, &resp);
|
|
||||||
*thread_cap = resp.thread_cap;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZThreadStart(z_cap_t thread_cap, uint64_t entry, uint64_t arg1,
|
|
||||||
uint64_t arg2) {
|
|
||||||
ZThreadStartReq req{
|
|
||||||
.thread_cap = thread_cap,
|
|
||||||
.entry = entry,
|
|
||||||
.arg1 = arg1,
|
|
||||||
.arg2 = arg2,
|
|
||||||
};
|
|
||||||
return SysCall1(Z_THREAD_START, &req);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZThreadExit() { SysCall0(Z_THREAD_EXIT); }
|
|
||||||
|
|
||||||
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,
|
|
||||||
.vmmo_cap = vmmo_cap,
|
|
||||||
};
|
|
||||||
ZAddressSpaceMapResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_ADDRESS_SPACE_MAP, &req, &resp);
|
|
||||||
*vaddr = resp.vaddr;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZMemoryObjectCreate(uint64_t size, z_cap_t* vmmo_cap) {
|
|
||||||
ZMemoryObjectCreateReq req{
|
|
||||||
.size = size,
|
|
||||||
};
|
|
||||||
ZMemoryObjectCreateResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE, &req, &resp);
|
|
||||||
*vmmo_cap = resp.vmmo_cap;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZMemoryObjectCreatePhysical(uint64_t paddr, uint64_t size,
|
|
||||||
z_cap_t* vmmo_cap) {
|
|
||||||
ZMemoryObjectCreatePhysicalReq req{
|
|
||||||
.paddr = paddr,
|
|
||||||
.size = size,
|
|
||||||
};
|
|
||||||
ZMemoryObjectCreatePhysicalResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE_PHYSICAL, &req, &resp);
|
|
||||||
*vmmo_cap = resp.vmmo_cap;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZMemoryObjectCreateContiguous(uint64_t size, z_cap_t* vmmo_cap,
|
|
||||||
uint64_t* paddr) {
|
|
||||||
ZMemoryObjectCreatePhysicalReq req{
|
|
||||||
.paddr = 0,
|
|
||||||
.size = size,
|
|
||||||
};
|
|
||||||
ZMemoryObjectCreatePhysicalResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_MEMORY_OBJECT_CREATE_PHYSICAL, &req, &resp);
|
|
||||||
*vmmo_cap = resp.vmmo_cap;
|
|
||||||
*paddr = resp.paddr;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
*vmmo_size = resp.vmmo_size;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
*channel2 = resp.chan_cap2;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZChannelSend(z_cap_t chan_cap, uint64_t num_bytes, const void* data,
|
|
||||||
uint64_t num_caps, const z_cap_t* caps) {
|
|
||||||
ZChannelSendReq req{
|
|
||||||
.chan_cap = chan_cap,
|
|
||||||
.message =
|
|
||||||
{
|
|
||||||
.num_bytes = num_bytes,
|
|
||||||
.data = const_cast<void*>(data),
|
|
||||||
.num_caps = num_caps,
|
|
||||||
.caps = const_cast<z_cap_t*>(caps),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return SysCall1(Z_CHANNEL_SEND, &req);
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZChannelRecv(z_cap_t chan_cap, uint64_t num_bytes, void* data,
|
|
||||||
uint64_t num_caps, z_cap_t* caps, uint64_t* actual_bytes,
|
|
||||||
uint64_t* actual_caps) {
|
|
||||||
ZChannelRecvReq req{
|
|
||||||
.chan_cap = chan_cap,
|
|
||||||
.message =
|
|
||||||
{
|
|
||||||
.num_bytes = num_bytes,
|
|
||||||
.data = data,
|
|
||||||
.num_caps = num_caps,
|
|
||||||
.caps = caps,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
z_err_t ret = SysCall1(Z_CHANNEL_RECV, &req);
|
|
||||||
*actual_bytes = req.message.num_bytes;
|
|
||||||
*actual_caps = req.message.num_caps;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 void* data,
|
|
||||||
uint64_t num_caps, z_cap_t* caps) {
|
|
||||||
ZPortSendReq req{.port_cap = port_cap,
|
|
||||||
.message = {
|
|
||||||
.num_bytes = num_bytes,
|
|
||||||
.data = const_cast<void*>(data),
|
|
||||||
.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, void* data,
|
|
||||||
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,
|
|
||||||
.data = data,
|
|
||||||
.num_caps = num_caps,
|
|
||||||
.caps = caps,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
z_err_t ret = SysCall1(Z_PORT_RECV, &req);
|
|
||||||
*actual_bytes = req.message.num_bytes;
|
|
||||||
*actual_caps = req.message.num_caps;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
z_err_t ZPortPoll(z_cap_t port_cap, uint64_t num_bytes, void* data,
|
|
||||||
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,
|
|
||||||
.data = data,
|
|
||||||
.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,
|
|
||||||
};
|
|
||||||
ZIrqRegisterResp resp;
|
|
||||||
z_err_t ret = SysCall2(Z_IRQ_REGISTER, &req, &resp);
|
|
||||||
*port_cap = resp.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); }
|
|
||||||
|
|
|
@ -4,70 +4,6 @@
|
||||||
|
|
||||||
#include "include/ztypes.h"
|
#include "include/ztypes.h"
|
||||||
|
|
||||||
struct ZProcessSpawnReq {
|
|
||||||
z_cap_t proc_cap;
|
|
||||||
z_cap_t bootstrap_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZProcessSpawnResp {
|
|
||||||
z_cap_t proc_cap;
|
|
||||||
z_cap_t vmas_cap;
|
|
||||||
z_cap_t bootstrap_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZThreadCreateReq {
|
|
||||||
z_cap_t proc_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZThreadCreateResp {
|
|
||||||
z_cap_t thread_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZThreadStartReq {
|
|
||||||
z_cap_t thread_cap;
|
|
||||||
uint64_t entry;
|
|
||||||
uint64_t arg1;
|
|
||||||
uint64_t arg2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZAddressSpaceMapReq {
|
|
||||||
z_cap_t vmas_cap;
|
|
||||||
z_cap_t vmas_offset;
|
|
||||||
z_cap_t vmmo_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZAddressSpaceMapResp {
|
|
||||||
uint64_t vaddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZMemoryObjectCreateReq {
|
|
||||||
uint64_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZMemoryObjectCreateResp {
|
|
||||||
z_cap_t vmmo_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZMemoryObjectCreatePhysicalReq {
|
|
||||||
uint64_t paddr;
|
|
||||||
uint64_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZMemoryObjectCreatePhysicalResp {
|
|
||||||
z_cap_t vmmo_cap;
|
|
||||||
uint64_t paddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZTempPcieConfigObjectCreateResp {
|
|
||||||
z_cap_t vmmo_cap;
|
|
||||||
uint64_t vmmo_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZChannelCreateResp {
|
|
||||||
z_cap_t chan_cap1;
|
|
||||||
z_cap_t chan_cap2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZMessage {
|
struct ZMessage {
|
||||||
uint64_t num_bytes;
|
uint64_t num_bytes;
|
||||||
void* data;
|
void* data;
|
||||||
|
@ -75,43 +11,3 @@ struct ZMessage {
|
||||||
uint64_t num_caps;
|
uint64_t num_caps;
|
||||||
z_cap_t* caps;
|
z_cap_t* caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ZChannelSendReq {
|
|
||||||
z_cap_t chan_cap;
|
|
||||||
ZMessage message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZChannelRecvReq {
|
|
||||||
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 {
|
|
||||||
z_cap_t port_cap;
|
|
||||||
ZMessage message;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZIrqRegisterReq {
|
|
||||||
uint64_t irq_num;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZIrqRegisterResp {
|
|
||||||
z_cap_t port_cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZCapDuplicateReq {
|
|
||||||
z_cap_t cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZCapDuplicateResp {
|
|
||||||
z_cap_t cap;
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue