aboutsummaryrefslogtreecommitdiff
path: root/platform_impl.ml
diff options
context:
space:
mode:
authorPrashanth Mundkur <prashanth.mundkur@gmail.com>2018-05-21 15:33:02 -0700
committerPrashanth Mundkur <prashanth.mundkur@gmail.com>2018-05-21 18:00:03 -0700
commit7e27f37d83c1f8001b2aa906f854995ca1cd5031 (patch)
tree6eb76a58bb3cff3abf6921ffc83e8e64f07aca46 /platform_impl.ml
parent276f51e8d0d3b9eda3406a1720a58b309abf84d8 (diff)
downloadsail-riscv-7e27f37d83c1f8001b2aa906f854995ca1cd5031.zip
sail-riscv-7e27f37d83c1f8001b2aa906f854995ca1cd5031.tar.gz
sail-riscv-7e27f37d83c1f8001b2aa906f854995ca1cd5031.tar.bz2
Add in the platform files and update the ocaml build. Disable the isabelle build until we add suitable platform definitions/stubs.
The platform bits are not yet hooked into the model, but only into the build, so are untested.
Diffstat (limited to 'platform_impl.ml')
-rw-r--r--platform_impl.ml155
1 files changed, 155 insertions, 0 deletions
diff --git a/platform_impl.ml b/platform_impl.ml
new file mode 100644
index 0000000..342eab3
--- /dev/null
+++ b/platform_impl.ml
@@ -0,0 +1,155 @@
+(* FIXME: copyright header *)
+
+(* int->byte converters in little-endian order *)
+
+let uint32_to_bytes u = let open Int32 in
+ List.map to_int
+ [ logand u 0xffl;
+ logand (shift_right u 8) 0xffl;
+ logand (shift_right u 16) 0xffl;
+ logand (shift_right u 24) 0xffl;
+ ]
+
+let uint64_to_bytes u = let open Int64 in
+ List.map to_int
+ [ logand u 0xffL;
+ logand (shift_right u 8) 0xffL;
+ logand (shift_right u 16) 0xffL;
+ logand (shift_right u 24) 0xffL;
+ logand (shift_right u 32) 0xffL;
+ logand (shift_right u 40) 0xffL;
+ logand (shift_right u 48) 0xffL;
+ logand (shift_right u 56) 0xffL;
+ ]
+
+(* reset vector for the rom *)
+
+let reset_vec_size = 8l;;
+
+let reset_vec_int start_pc = [
+ 0x267l; (* auipc t0, 0x0 *)
+ (let open Int32 in
+ add 0x28593l (shift_left (mul reset_vec_size 4l) 20)); (* addi a1, t0, ofs(dtb) *)
+ 0xf1402573l; (* csrr a0, mhartid *)
+ 0x0182b283l; (* ld t0, 24(t0) *)
+ 0x28067l; (* jr t0 *)
+ 0x0l;
+ (let open Int64 in to_int32 (logand start_pc 0xffffffffL));
+ (let open Int64 in to_int32 (shift_right_logical start_pc 32));
+]
+
+(* address map *)
+
+let dram_base = 0x80000000L;; (* Spike::DRAM_BASE *)
+let dram_size = Int64.(shift_left 2048L 20)
+let clint_base = 0x02000000L;; (* Spike::CLINT_BASE *)
+let clint_size = 0x000c0000L;; (* Spike::CLINT_SIZE *)
+let rom_base = 0x00001000L;; (* Spike::DEFAULT_RSTVEC *)
+
+type mem_region = {
+ addr : Int64.t;
+ size : Int64.t
+}
+
+(* dts from spike *)
+let spike_dts isa_spec cpu_hz insns_per_rtc_tick mems =
+ "/dts-v1/;\n"
+ ^ "\n"
+ ^ "/ {\n"
+ ^ " #address-cells = <2>;\n"
+ ^ " #size-cells = <2>;\n"
+ ^ " compatible = \"ucbbar,spike-bare-dev\";\n"
+ ^ " model = \"ucbbar,spike-bare\";\n"
+ ^ " cpus {\n"
+ ^ " #address-cells = <1>;\n"
+ ^ " #size-cells = <0>;\n"
+ ^ " timebase-frequency = <" ^ string_of_int (cpu_hz/insns_per_rtc_tick) ^ ">;\n"
+ ^ " CPU0: cpu@0 {\n"
+ ^ " device_type = \"cpu\";\n"
+ ^ " reg = <0>;\n"
+ ^ " status = \"okay\";\n"
+ ^ " compatible = \"riscv\";\n"
+ ^ " riscv,isa = \"" ^ isa_spec ^ "\";\n"
+ ^ " mmu-type = \"riscv,sv39\";\n"
+ ^ " clock-frequency = <" ^ string_of_int cpu_hz ^ ">;\n"
+ ^ " CPU0_intc: interrupt-controller {\n"
+ ^ " #interrupt-cells = <1>;\n"
+ ^ " interrupt-controller;\n"
+ ^ " compatible = \"riscv,cpu-intc\";\n"
+ ^ " };\n"
+ ^ " };\n"
+ ^ " };\n"
+ ^ (List.fold_left (^) ""
+ (List.map (fun m ->
+ " memory@" ^ Printf.sprintf "%Lx" m.addr ^ " {\n"
+ ^ " device_type = \"memory\";\n"
+ ^ " reg = <0x" ^ Printf.sprintf "%Lx" Int64.(shift_right_logical m.addr 32) ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(logand m.addr 0xffffffffL)
+ ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(shift_right_logical m.size 32) ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(logand m.size 0xffffffffL) ^ ">;\n"
+ ^ " };\n") mems))
+ ^ " soc {\n"
+ ^ " #address-cells = <2>;\n"
+ ^ " #size-cells = <2>;\n"
+ ^ " compatible = \"ucbbar,spike-bare-soc\", \"simple-bus\";\n"
+ ^ " ranges;\n"
+ ^ " clint@" ^ Printf.sprintf "%Lx" clint_base ^ " {\n"
+ ^ " compatible = \"riscv,clint0\";\n"
+ ^ " interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7 >;\n"
+ ^ " reg = <0x" ^ Printf.sprintf "%Lx" Int64.(shift_right_logical clint_base 32) ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(logand clint_base 0xffffffffL)
+ ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(shift_right_logical clint_size 32) ^ " 0x" ^ Printf.sprintf "%Lx" Int64.(logand clint_size 0xffffffffL) ^ ">;\n"
+ ^ " };\n"
+ ^ " };\n"
+ ^ " htif {\n"
+ ^ " compatible = \"ucb,htif0\";\n"
+ ^ " };\n"
+ ^ "};\n"
+
+let cpu_hz = 1000000000;;
+let insns_per_tick = 100;;
+
+let mems = [ { addr = dram_base;
+ size = dram_size } ];;
+let dts = spike_dts "rv64imac" cpu_hz insns_per_tick mems;;
+
+let bytes_to_string bytes =
+ String.init (List.length bytes) (fun i -> Char.chr (List.nth bytes i))
+
+let make_dtb dts = (* Call the dtc compiler, assumed to be at /usr/bin/dtc *)
+ try
+ let (cfrom, cto, cerr) =
+ Unix.open_process_full "/usr/bin/dtc -I dts" [||]
+ in (
+ output_string cto dts;
+ (* print_endline " sent dts to dtc ..."; *)
+ close_out cto;
+ (* simple and stupid for now *)
+ let rec accum_bytes cin acc =
+ match (
+ try Some (input_byte cfrom)
+ with End_of_file -> None
+ ) with
+ | Some b -> accum_bytes cin (b :: acc)
+ | None -> List.rev acc
+ in
+ (* let _ = print_endline " accumulating dtb ..." in *)
+ let dtb = accum_bytes cfrom [] in
+ (* let _ = print_endline " accumulating emsg ..." in *)
+ let emsg = bytes_to_string (accum_bytes cerr []) in
+ match Unix.close_process_full (cfrom, cto, cerr) with
+ | Unix.WEXITED 0 -> dtb
+ | _ -> (Printf.printf "%s\n" ("Error executing dtc: " ^ emsg);
+ exit 1)
+ )
+ with Unix.Unix_error (e, fn, _) ->
+ (Printf.printf "%s\n" ("Error executing dtc: " ^ fn ^ ": " ^ Unix.error_message e);
+ exit 1)
+
+(*
+let save_string_to_file s fname =
+ let out = open_out fname in
+ output_string out s;
+ close_out out;;
+
+let _ =
+ save_string_to_file dts "/tmp/platform.dts";
+ save_string_to_file (bytes_to_string (get_dtb dts)) "/tmp/platform.dtb";
+ *)