| ... | @@ -1,38 +1,55 @@ | ... | @@ -1,38 +1,55 @@ |
| | 1 | const std = @import("../index.zig"); |
| | 2 | const assert = std.debug.assert; |
| | 3 | |
| 1 | ////////////////////////// | 4 | ////////////////////////// |
| 2 | //// IPC structures //// | 5 | //// IPC structures //// |
| 3 | ////////////////////////// | 6 | ////////////////////////// |
| 4 | | 7 | |
| 5 | pub const Message = struct { | 8 | pub const Message = struct { |
| 6 | sender: MailboxId, | 9 | sender: MailboxId, |
| 7 | receiver: MailboxId, | 10 | receiver: MailboxId, |
| 8 | type: usize, | 11 | code: usize, |
| 9 | payload: usize, | 12 | args: [5]usize, |
| | 13 | payload: ?[]const u8, |
| 10 | | 14 | |
| 11 | pub fn from(mailbox_id: *const MailboxId) Message { | 15 | pub fn from(mailbox_id: *const MailboxId) Message { |
| 12 | return Message{ | 16 | return Message { |
| 13 | .sender = MailboxId.Undefined, | 17 | .sender = MailboxId.Undefined, |
| 14 | .receiver = *mailbox_id, | 18 | .receiver = mailbox_id.*, |
| 15 | .type = 0, | 19 | .code = undefined, |
| 16 | .payload = 0, | 20 | .args = undefined, |
| | 21 | .payload = null, |
| 17 | }; | 22 | }; |
| 18 | } | 23 | } |
| 19 | | 24 | |
| 20 | pub fn to(mailbox_id: *const MailboxId, msg_type: usize) Message { | 25 | pub fn to(mailbox_id: *const MailboxId, msg_code: usize, args: ...) Message { |
| 21 | return Message{ | 26 | var message = Message { |
| 22 | .sender = MailboxId.This, | 27 | .sender = MailboxId.This, |
| 23 | .receiver = *mailbox_id, | 28 | .receiver = mailbox_id.*, |
| 24 | .type = msg_type, | 29 | .code = msg_code, |
| 25 | .payload = 0, | 30 | .args = undefined, |
| | 31 | .payload = null, |
| 26 | }; | 32 | }; |
| | 33 | |
| | 34 | assert (args.len <= message.args.len); |
| | 35 | comptime var i = 0; |
| | 36 | inline while (i < args.len) : (i += 1) { |
| | 37 | message.args[i] = args[i]; |
| | 38 | } |
| | 39 | |
| | 40 | return message; |
| 27 | } | 41 | } |
| 28 | | 42 | |
| 29 | pub fn withData(mailbox_id: *const MailboxId, msg_type: usize, payload: usize) Message { | 43 | pub fn as(self: *const Message, sender: *const MailboxId) Message { |
| 30 | return Message{ | 44 | var message = self.*; |
| 31 | .sender = MailboxId.This, | 45 | message.sender = sender.*; |
| 32 | .receiver = *mailbox_id, | 46 | return message; |
| 33 | .type = msg_type, | 47 | } |
| 34 | .payload = payload, | 48 | |
| 35 | }; | 49 | pub fn withPayload(self: *const Message, payload: []const u8) Message { |
| | 50 | var message = self.*; |
| | 51 | message.payload = payload; |
| | 52 | return message; |
| 36 | } | 53 | } |
| 37 | }; | 54 | }; |
| 38 | | 55 | |
| ... | @@ -63,21 +80,26 @@ pub const STDOUT_FILENO = 1; | ... | @@ -63,21 +80,26 @@ pub const STDOUT_FILENO = 1; |
| 63 | pub const STDERR_FILENO = 2; | 80 | pub const STDERR_FILENO = 2; |
| 64 | | 81 | |
| 65 | // FIXME: let's borrow Linux's error numbers for now. | 82 | // FIXME: let's borrow Linux's error numbers for now. |
| 66 | pub const getErrno = @import("linux/index.zig").getErrno; | | |
| 67 | use @import("linux/errno.zig"); | 83 | use @import("linux/errno.zig"); |
| | 84 | // Get the errno from a syscall return value, or 0 for no error. |
| | 85 | pub fn getErrno(r: usize) usize { |
| | 86 | const signed_r = @bitCast(isize, r); |
| | 87 | return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; |
| | 88 | } |
| 68 | | 89 | |
| 69 | // TODO: implement this correctly. | 90 | // TODO: implement this correctly. |
| 70 | pub fn read(fd: i32, buf: *u8, count: usize) usize { | 91 | pub fn read(fd: i32, buf: [*]u8, count: usize) usize { |
| 71 | switch (fd) { | 92 | switch (fd) { |
| 72 | STDIN_FILENO => { | 93 | STDIN_FILENO => { |
| 73 | var i: usize = 0; | 94 | var i: usize = 0; |
| 74 | while (i < count) : (i += 1) { | 95 | while (i < count) : (i += 1) { |
| 75 | send(Message.to(Server.Keyboard, 0)); | 96 | send(Message.to(Server.Keyboard, 0)); |
| 76 | | 97 | |
| | 98 | // FIXME: we should be certain that we are receiving from Keyboard. |
| 77 | var message = Message.from(MailboxId.This); | 99 | var message = Message.from(MailboxId.This); |
| 78 | receive(*message); | 100 | receive(&message); |
| 79 | | 101 | |
| 80 | buf[i] = u8(message.payload); | 102 | buf[i] = @intCast(u8, message.args[0]); |
| 81 | } | 103 | } |
| 82 | }, | 104 | }, |
| 83 | else => unreachable, | 105 | else => unreachable, |
| ... | @@ -86,13 +108,11 @@ pub fn read(fd: i32, buf: *u8, count: usize) usize { | ... | @@ -86,13 +108,11 @@ pub fn read(fd: i32, buf: *u8, count: usize) usize { |
| 86 | } | 108 | } |
| 87 | | 109 | |
| 88 | // TODO: implement this correctly. | 110 | // TODO: implement this correctly. |
| 89 | pub fn write(fd: i32, buf: *const u8, count: usize) usize { | 111 | pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { |
| 90 | switch (fd) { | 112 | switch (fd) { |
| 91 | STDOUT_FILENO, STDERR_FILENO => { | 113 | STDOUT_FILENO, STDERR_FILENO => { |
| 92 | var i: usize = 0; | 114 | send(Message.to(Server.Terminal, 1) |
| 93 | while (i < count) : (i += 1) { | 115 | .withPayload(buf[0..count])); |
| 94 | send(Message.withData(Server.Terminal, 1, buf[i])); | | |
| 95 | } | | |
| 96 | }, | 116 | }, |
| 97 | else => unreachable, | 117 | else => unreachable, |
| 98 | } | 118 | } |
| ... | @@ -104,17 +124,14 @@ pub fn write(fd: i32, buf: *const u8, count: usize) usize { | ... | @@ -104,17 +124,14 @@ pub fn write(fd: i32, buf: *const u8, count: usize) usize { |
| 104 | /////////////////////////// | 124 | /////////////////////////// |
| 105 | | 125 | |
| 106 | pub const Syscall = enum(usize) { | 126 | pub const Syscall = enum(usize) { |
| 107 | exit = 0, | 127 | exit = 0, |
| 108 | createPort = 1, | 128 | send = 1, |
| 109 | send = 2, | 129 | receive = 2, |
| 110 | receive = 3, | 130 | subscribeIRQ = 3, |
| 111 | subscribeIRQ = 4, | 131 | inb = 4, |
| 112 | inb = 5, | 132 | outb = 5, |
| 113 | map = 6, | 133 | map = 6, |
| 114 | createThread = 7, | 134 | createThread = 7, |
| 115 | createProcess = 8, | | |
| 116 | wait = 9, | | |
| 117 | portReady = 10, | | |
| 118 | }; | 135 | }; |
| 119 | | 136 | |
| 120 | //////////////////// | 137 | //////////////////// |
| ... | @@ -126,13 +143,6 @@ pub fn exit(status: i32) noreturn { | ... | @@ -126,13 +143,6 @@ pub fn exit(status: i32) noreturn { |
| 126 | unreachable; | 143 | unreachable; |
| 127 | } | 144 | } |
| 128 | | 145 | |
| 129 | pub fn createPort(mailbox_id: *const MailboxId) void { | | |
| 130 | _ = switch (*mailbox_id) { | | |
| 131 | MailboxId.Port => |id| syscall1(Syscall.createPort, id), | | |
| 132 | else => unreachable, | | |
| 133 | }; | | |
| 134 | } | | |
| 135 | | | |
| 136 | pub fn send(message: *const Message) void { | 146 | pub fn send(message: *const Message) void { |
| 137 | _ = syscall1(Syscall.send, @ptrToInt(message)); | 147 | _ = syscall1(Syscall.send, @ptrToInt(message)); |
| 138 | } | 148 | } |
| ... | @@ -146,29 +156,21 @@ pub fn subscribeIRQ(irq: u8, mailbox_id: *const MailboxId) void { | ... | @@ -146,29 +156,21 @@ pub fn subscribeIRQ(irq: u8, mailbox_id: *const MailboxId) void { |
| 146 | } | 156 | } |
| 147 | | 157 | |
| 148 | pub fn inb(port: u16) u8 { | 158 | pub fn inb(port: u16) u8 { |
| 149 | return u8(syscall1(Syscall.inb, port)); | 159 | return @intCast(u8, syscall1(Syscall.inb, port)); |
| | 160 | } |
| | 161 | |
| | 162 | pub fn outb(port: u16, value: u8) void { |
| | 163 | _ = syscall2(Syscall.outb, port, value); |
| 150 | } | 164 | } |
| 151 | | 165 | |
| 152 | pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool { | 166 | pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool { |
| 153 | return syscall4(Syscall.map, v_addr, p_addr, size, usize(writable)) != 0; | 167 | return syscall4(Syscall.map, v_addr, p_addr, size, @boolToInt(writable)) != 0; |
| 154 | } | 168 | } |
| 155 | | 169 | |
| 156 | pub fn createThread(function: fn () void) u16 { | 170 | pub fn createThread(function: fn () void) u16 { |
| 157 | return u16(syscall1(Syscall.createThread, @ptrToInt(function))); | 171 | return u16(syscall1(Syscall.createThread, @ptrToInt(function))); |
| 158 | } | 172 | } |
| 159 | | 173 | |
| 160 | pub fn createProcess(elf_addr: usize) u16 { | | |
| 161 | return u16(syscall1(Syscall.createProcess, elf_addr)); | | |
| 162 | } | | |
| 163 | | | |
| 164 | pub fn wait(tid: u16) void { | | |
| 165 | _ = syscall1(Syscall.wait, tid); | | |
| 166 | } | | |
| 167 | | | |
| 168 | pub fn portReady(port: u16) bool { | | |
| 169 | return syscall1(Syscall.portReady, port) != 0; | | |
| 170 | } | | |
| 171 | | | |
| 172 | ///////////////////////// | 174 | ///////////////////////// |
| 173 | //// Syscall stubs //// | 175 | //// Syscall stubs //// |
| 174 | ///////////////////////// | 176 | ///////////////////////// |