From: Amelia Coutard Date: Mon, 13 Mar 2023 14:22:22 +0000 (+0100) Subject: Wrote a new spec for the syscalls X-Git-Url: https://git.ameliathe1st.gay/?a=commitdiff_plain;h=900b22cb4d697a7901eb4d007c3d2a5362c73568;p=voyage-au-centre-des-fichiers.git Wrote a new spec for the syscalls --- diff --git a/doc.txt b/doc.txt index 61b3dcc..800e7ae 100644 --- 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