sylveos

Toy Operating System
Log | Files | Refs

net.zig (2334B)


      1 const std = @import("std");
      2 
      3 pub const Message = enum(u32) {
      4     GET_PROG_INFO = 0x11112222,
      5     PUT_PROG_INFO = 0x33334444,
      6 
      7     GET_CODE = 0x55556666,
      8     PUT_CODE = 0x77778888,
      9 
     10     BOOT_SUCCESS = 0x9999AAAA,
     11     BAD_CODE_ADDR = 0xDEADBEEF,
     12     BAD_CODE_CKSUM = 0xFEEDFACE,
     13 };
     14 
     15 pub const Error = error{
     16     BadAddress,
     17     BadChecksum,
     18     Timeout,
     19 };
     20 
     21 pub const Header = struct {
     22     arm_base: u32,
     23     n_bytes: u32,
     24     checksum: u32,
     25 };
     26 
     27 pub fn get_u32(r: *std.Io.Reader) !u32 {
     28     var buffer: [@sizeOf(u32)]u8 = undefined;
     29     try r.readSliceAll(&buffer);
     30     const v = std.mem.readInt(u32, &buffer, .little);
     31 
     32     return v;
     33 }
     34 
     35 pub fn get_u8(r: *std.Io.Reader) !u8 {
     36     var buffer: [1]u8 = undefined;
     37     try r.readSliceAll(&buffer);
     38     return buffer[0];
     39 }
     40 
     41 pub fn put_u32(w: *std.Io.Writer, v: u32) !void {
     42     var buffer: [@sizeOf(u32)]u8 = undefined;
     43     std.mem.writeInt(u32, &buffer, v, .little);
     44     try w.writeAll(&buffer);
     45     try w.flush();
     46 }
     47 
     48 pub fn put_u8(w: *std.Io.Writer, v: u8) !void {
     49     try w.writeByte(v);
     50     try w.flush();
     51 }
     52 
     53 pub fn put_message(w: *std.Io.Writer, message: Message) !void {
     54     try put_u32(w, @intFromEnum(message));
     55 }
     56 
     57 pub fn transmit_header(w: *std.Io.Writer, header: Header) !void {
     58     try put_message(w, .PUT_PROG_INFO);
     59     try put_u32(w, header.arm_base);
     60     try put_u32(w, header.n_bytes);
     61     try put_u32(w, header.checksum);
     62 }
     63 
     64 pub fn receive_header(r: *std.Io.Reader, max_addr: u32) !Header {
     65     const arm_base = try get_u32(r);
     66     const n_bytes = try get_u32(r);
     67     const checksum = try get_u32(r);
     68 
     69     // TODO; better check
     70     if (arm_base + n_bytes >= max_addr) {
     71         return Error.BadAddress;
     72     }
     73 
     74     return .{ .arm_base = arm_base, .checksum = checksum, .n_bytes = n_bytes };
     75 }
     76 
     77 pub fn transmit_code(w: *std.Io.Writer, progress: std.Progress.Node, code: []const u8) !void {
     78     defer progress.end();
     79     try put_message(w, .PUT_CODE);
     80     for (code) |byte| {
     81         try put_u8(w, byte);
     82         progress.completeOne();
     83     }
     84 }
     85 
     86 pub fn receive_code(r: *std.Io.Reader, buffer: []u8, header: Header) !void {
     87     try r.readSliceAll(buffer);
     88 
     89     if (std.hash.Crc32.hash(buffer) != header.checksum) {
     90         return Error.BadChecksum;
     91     }
     92 }
     93 
     94 pub fn request_code(w: *std.Io.Writer, crc: u32) !void {
     95     try put_message(w, .GET_CODE);
     96     try put_u32(w, crc);
     97 }