RPMsg inter-partition messaging
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at cf32026a492707522ba0fb4e67acf6d7da8d5e4e 107 lines 3.3 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Thomas Gazagnaire. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** {1 RPMsg endpoint info struct} 7 8 Matches Linux kernel [struct rpmsg_endpoint_info]: 9 {v 10 struct rpmsg_endpoint_info { 11 char name[32]; /* endpoint name */ 12 __u32 src; /* source address */ 13 __u32 dst; /* destination address */ 14 }; 15 v} 16 17 Encoded via Wire.Codec to avoid manual C struct packing. *) 18 19type endpoint_info = { name : string; src : int; dst : int } 20 21let f_ei_name = Wire.Field.v "name" (Wire.byte_array ~size:(Wire.int 32)) 22let f_ei_src = Wire.Field.v "src" Wire.uint32 23let f_ei_dst = Wire.Field.v "dst" Wire.uint32 24 25let endpoint_info_codec = 26 Wire.Codec.v "rpmsg_endpoint_info" 27 (fun name src dst -> { name; src; dst }) 28 Wire.Codec. 29 [ 30 ( f_ei_name $ fun t -> 31 (* Pad/truncate name to exactly 32 bytes *) 32 let b = Bytes.make 32 '\x00' in 33 let len = min (String.length t.name) 31 in 34 Bytes.blit_string t.name 0 b 0 len; 35 Bytes.to_string b ); 36 (f_ei_src $ fun t -> t.src); 37 (f_ei_dst $ fun t -> t.dst); 38 ] 39 40let endpoint_info_size = Wire.Codec.wire_size endpoint_info_codec 41 42(** RPMSG ioctl commands. 43 44 [RPMSG_CREATE_EPT_IOCTL = _IOW(0xb5, 0x1, struct rpmsg_endpoint_info)] 45 [RPMSG_DESTROY_EPT_IOCTL = _IOW(0xb5, 0x2, struct rpmsg_endpoint_info)] 46 47 _IOW(type, nr, size) = (1 << 30) | (size << 16) | (type << 8) | nr *) 48let iow typ nr size = (1 lsl 30) lor (size lsl 16) lor (typ lsl 8) lor nr 49 50let ept_ioctl = iow 0xb5 0x1 endpoint_info_size 51let destroy_ept_ioctl = iow 0xb5 0x2 endpoint_info_size 52 53external ioctl : Unix.file_descr -> int -> bytes -> int = "caml_rpmsg_ioctl" 54 55module Ctrl = struct 56 type t = { fd : Unix.file_descr } 57 58 let open_ ?(index = 0) () = 59 let path = Fmt.str "/dev/rpmsg_ctrl%d" index in 60 let fd = Unix.openfile path [ Unix.O_RDWR ] 0 in 61 { fd } 62 63 let encode_info ~name ~src ~dst = 64 let info = { name; src; dst } in 65 let buf = Bytes.create endpoint_info_size in 66 Wire.Codec.encode endpoint_info_codec info buf 0; 67 buf 68 69 let create_endpoint t ~name ~src ~dst = 70 let buf = encode_info ~name ~src ~dst in 71 ioctl t.fd ept_ioctl buf 72 73 let destroy_endpoint t ~name ~src ~dst = 74 let buf = encode_info ~name ~src ~dst in 75 ignore (ioctl t.fd destroy_ept_ioctl buf) 76 77 let close t = Unix.close t.fd 78end 79 80module Endpoint = struct 81 type t = { 82 recv_fn : max_size:int -> string option; 83 send_fn : string -> unit; 84 close_fn : unit -> unit; 85 } 86 87 let max_message_size = 496 88 89 let of_source_sink ~source ~sink = 90 let recv_fn ~max_size = 91 let buf = Cstruct.create max_size in 92 match Eio.Flow.single_read source buf with 93 | n -> Some (Cstruct.to_string ~len:n buf) 94 | exception End_of_file -> None 95 in 96 let send_fn msg = Eio.Flow.copy_string msg sink in 97 { recv_fn; send_fn; close_fn = ignore } 98 99 let open_ index = 100 let path = Fmt.str "/dev/rpmsg%d" index in 101 let fd = Unix.openfile path [ Unix.O_RDWR ] 0 in 102 fd 103 104 let recv t = t.recv_fn 105 let send t msg = t.send_fn msg 106 let close t = t.close_fn () 107end