]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Wrote a new spec for the syscalls
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Mon, 13 Mar 2023 14:22:22 +0000 (15:22 +0100)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Mon, 13 Mar 2023 14:22:22 +0000 (15:22 +0100)
doc.txt

diff --git a/doc.txt b/doc.txt
index 61b3dcc5420df68a622f75afb52c6b716724faea..800e7ae778c741de56a246abbfb4e371a77908e1 100644 (file)
--- a/doc.txt
+++ b/doc.txt
@@ -19,97 +19,83 @@ FFFF'FFFF'8000'0000 ↔10000'0000'0000'0000 - kernel: 2GiB
 
 ---------------------------
 
-A port is a non-0 64-bit integer, that refers to another port that could be a part of the same
-or a different process (however, since threads don't exist, sending a message through a port to
-your own process will block it forever).
-It allows for sending and receiving data through to its other side.
+The port is the IPC method of this kernel. There are two types of ports.
+Server ports are points where a server will receive a message. They can receive
+       a message from any number of client ports.
+Client ports are points where a client can send a message. A client port always points
+       to a single, specific, server port.
 
 ---------------------------
 
 Data types:
 
 port_t = uint64_t;
-byte = unsigned char;
 
 ---------------------------
 
 The system calls:
 
-If a syscall fails, it will return a negative value in %rax between -255 and -1, and the error code is -%rax. (like Linux)
-If it succeeds, if it returns a value, it returns it, otherwise it returns 0.
-Errors:
-       1: too many ports       // The process has reached it's maximumwatching number of allowed ports.
-       2: port doesn't exist   // This port isn't allocated in this process, or has already been closed on this side.
-       3: closed port  // The port has been closed on the other side.
-       4: other side refusal   // Error sent by the other side's program. Won't ever be generated by the kernel.
-
-// Create two connected infinite-use ports.
-// Possible errors:
-//     too many ports
-void mkport(port_t* port_a, port_t* port_b);
-
-// Closes a port. This port now doesn't exist and its id is available for recycling.
-// If the other side tries any operation but a close on this port, it shall fail with 'closed port'
-// The port on the other side isn't closed, and can't be recycled, until the other side also calls close.
-// Possible errors:
-//     port doesn't exist
-void close(port_t port);
-
-// Send a message to the other side of the port. Block until you receive an answer.
-// Returns the actual length of the reply (which can be more than what was written in
-// the reply buffer, if it was too short for it).
-// If no port was replied, *reply_port = 0.
-// While you technically cannot reply without a message, a 0 length message is the same
-// as no message (and allows for NULL as a pointer to the message).
-// Possible errors:
-//     port doesn't exist
-//     closed port
-//     other side refusal
-size_t call(port_t port, byte const* message, size_t message_size, byte* reply_message, size_t reply_message_size, port_t* reply_port);
-
-// Block until a message is being sent to port, then return it's length.
-// Possible errors:
-//     port doesn't exist
-//     closed port
-size_t recv_len(port_t port);
-
-// Block until a message is being sent to port, then copy its contents to message.
-// This should only be used after recv_len, lest you risk a buffer overflow.
-// Possible errors:
-//     port doesn't exist
-//     closed port
-void recv(byte* message);
-
-// Unblock the other side, loading up the corresponding values in the call arguments.
-// Doesn't block this side at all, unless it is sent without the other side having called.
-// If a port (!= 0) is sent, it no longer exists in this program.
-// If reply_message_size is 0, reply_message is allowed to be NULL.
-// reply_port is allowed to be a port closed on the other side, but it must be 0 or a port
-// that still exists in this process.
-// Possible errors:
-//     port doesn't exist
-//     closed port
-void reply(port_t port, byte const* reply_message, size_t reply_message_size, port_t reply_port);
-
-// Unblock the other side, erroring with error code "other side refusal"
-// Doesn't block this side at all, unless it is sent without the other side having called.
-// Possible errors:
-//     port doesn't exist
-//     closed port
-void reply_error(port_t port);
-
-// Block until any port receives a message, or is closed on the other side.
-// Returns the corresponding port_t.
-// No possible errors.
-port_t wait();
-
-
-Without comments:
-       void mkport(port_t* port_a, port_t* port_b);
-       void close(port_t port);
-       size_t call(port_t port, byte const* message, size_t message_size, byte* reply_message, size_t reply_message_size, port_t* reply_port);
-       size_t recv_len(port_t port);
-       void recv(byte* message);
-       void reply(port_t port, byte const* reply_message, size_t reply_message_size, port_t reply_port);
-       void reply_error(port_t port);
-       port_t wait();
+Input and output registers in order: %rdi, %rsi, %rdx, %r10, %r8, %r9.
+In %rax, the error code of the operation is stored. If it is non-zero,
+       none of the other registers have defined values.
+
+Error codes:
+       0: ERR_NONE:          no error
+       1: ERR_MANY_P:        too many ports
+       2: ERR_NOT_P:         port doesn't exist   -- developper error, i.e. a program bug
+       3: ERR_CLOSED_P:      port closed
+       4: ERR_WRONG_P:       wrong port type      -- developper error, i.e. a program bug
+       5: ERR_MEM_NOT_OWNED: send non-owned vaddr -- developper error, i.e. a program bug
+       6: ERR_IN_HANDLER:    recv without reply   -- developper error, i.e. a program bug
+       6: ERR_NIN_HANDLER:   reply without recv   -- developper error, i.e. a program bug
+
+mksport: () -> port_t
+       Creates a server port, with no associated clients. This absence of
+       clients does *not* cause any wait calls to end their wait.
+       *Possible errors:* ERR_MANY_P
+mkcport: port_t -> port_t
+       Creates a client port associated with the given server port.
+       *Possible errors:* ERR_MANY_P, ERR_NOT_P, ERR_WRONG_P
+cpcport: port_t -> port_t
+       Takes a client port, and returns a new client port that points to the same server port.
+       *Possible errors:* ERR_MANY_P, ERR_NOT_P, ERR_WRONG_P
+close: p: port_t -> ()
+       Close a port. It no longer exists in this process.
+       If it was a server port, any use of any of its client ports for the purpose
+               of communication will fail with ERR_CLOSED_P.
+       If it was a client port,
+               If it wasn't the server's last client, nothing happens.
+               If it was, however, the server will be notified by way of unfreezing
+                       a wait call (but that's it).
+       *Possible errors:* ERR_NOT_P
+call: (port_t, d1: uint64_t, d2: uint64_t, tp: port_t, mem: void*, mem_len: uint64_t)
+   -> (d1: uint64_t, d2: uint64_t, tp: port_t, mem: void*, mem_len: uint64_t)
+       Takes a client port, and sends data to the corresponding server port.
+       d1 and d2 are copied.
+       The argument tp must be either 0 or a client port.
+               If it is 0, then the value transmitted is simply 0.
+               If it is non-0, then it is removed from the current process' namespace
+               and added (without necessarily the same id) to the called process. The
+               value transmitted will be that new port id.
+       If mem_len is 0, there are no restrictions on the value of mem. In that case,
+               nothing happens, and then transmitted values are mem = NULL and mem_len = 0.
+       If mem_len is greater than 0, then it is required that the pages containing vadresses
+               [mem; mem + mem_len[ be all owned by the calling process. They are removed from
+               its page mappings, and added to the called process'. The new virtual address is
+               transmitted in mem, with the same mem_len.
+       *Possible errors:* ERR_NOT_P, ERR_CLOSED_P, ERR_WRONG_P, ERR_MEM_NOT_OWNED
+recv: port_t -> (d1: uint64_t, d2: uint64_t, tp: port_t, mem: void*, mem_len: uint64_t)
+       Takes a server port. Blocks until this server port is called, then receives the
+               message as described in call.
+       *Possible errors:* ERR_NOT_P, ERR_WRONG_P, ERR_IN_HANDLER
+reply: (d1: uint64_t, d2: uint64_t, tp: port_t, mem: void*, mem_len: uint64_t) -> ()
+       Sends a message back to the port that the latest recv got its message from,
+               as described in call.
+       *Possible errors:* ERR_NOT_P, ERR_WRONG_P, ERR_MEM_NOT_OWNED, ERR_NIN_HANDLER
+wait: () -> port_t
+       Block until one of the server ports of this process is called or loses its last client.
+       Returns the server port in question.
+       *This syscall cannot fail.*
+hascports: port_t -> bool
+       Takes a server port, and returns the number of clients linked to it.
+       *Possible errors:* ERR_NOT_P, ERR_WRONG_P