From f554a154b7bd8da51ffc211aed52be64882f1b14 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Tue, 28 May 2024 18:12:14 +0200 Subject: [PATCH] WIP --- configuration.nix | 18 ++- flake.lock | 20 ++-- flake.nix | 30 +++-- fpga/fpgactl | 2 +- fpga/upload.sh | 4 + lagarto-hun.nix | 12 +- opensbi-lagarto-hun.patch | 8 +- overlay.nix | 32 +++++ unalign.c | 239 ++++++++++++++++++++++++++++++++++++++ vm.nix | 14 ++- 10 files changed, 341 insertions(+), 38 deletions(-) create mode 100644 unalign.c diff --git a/configuration.nix b/configuration.nix index 92656d0..7337141 100644 --- a/configuration.nix +++ b/configuration.nix @@ -6,13 +6,18 @@ #"${modulesPath}/profiles/minimal.nix" ]; - nixpkgs.crossSystem = { - system = "riscv64-linux"; - }; + nixpkgs = { + crossSystem = { + system = "riscv64-linux"; + }; - nixpkgs.overlays = [ - self.inputs.bscpkgs.bscOverlay - ]; + overlays = [ + self.inputs.bscpkgs.bscOverlay + (import ./overlay.nix) + ]; + + config.allowUnsupportedSystem = true; + }; networking.hostName = "nixos-riscv"; @@ -31,4 +36,5 @@ }; #environment.systemPackages = with pkgs; [ vim gdb neofetch gcc bintools ]; + environment.systemPackages = with pkgs; [ rvb unalignedCheck ]; } diff --git a/flake.lock b/flake.lock index c5ce3d9..5e898fe 100644 --- a/flake.lock +++ b/flake.lock @@ -5,10 +5,10 @@ "nixpkgs": "nixpkgs" }, "locked": { - "dirtyRev": "e605f7dfad67a6bf15c1f1ff83e0c8a1c9ee42b9-dirty", - "dirtyShortRev": "e605f7d-dirty", - "lastModified": 1715179381, - "narHash": "sha256-487pg/odvGPcEVpCBDS3gVmK/4o3Yv7S/uvI2HYECGM=", + "dirtyRev": "15c8a61d1787d52f904755bee9b1840ce8823525-dirty", + "dirtyShortRev": "15c8a61-dirty", + "lastModified": 1715619485, + "narHash": "sha256-zgwnjGVBXTvItXIYtaMIdf2acHiNQOJ6Fba4OFZRYT4=", "type": "git", "url": "file:///home/Computational/rarias/bscpkgs" }, @@ -32,17 +32,17 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1706092046, - "narHash": "sha256-Cbethl95Cu+WVIWfaAnRRBZiz5PmXxQvg4vXNqIZQUg=", - "owner": "rodarima", + "lastModified": 1700390070, + "narHash": "sha256-de9KYi8rSJpqvBfNwscWdalIJXPo8NjdIZcEJum1mH0=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "57e7c8fa4fdc414a936ce83afd0c70fb0a3a31d5", + "rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb", "type": "github" }, "original": { - "owner": "rodarima", - "ref": "fix-pkgs-static-gcc-march", + "owner": "NixOS", "repo": "nixpkgs", + "rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 9ffb77f..3dc1bfb 100644 --- a/flake.nix +++ b/flake.nix @@ -1,19 +1,33 @@ { - inputs.nixpkgs.url = "github:rodarima/nixpkgs/fix-pkgs-static-gcc-march"; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/e4ad989506ec7d71f7302cc3067abd82730a4beb"; #inputs.bscpkgs.url = "path:/home/Computational/rarias/bscpkgs"; inputs.bscpkgs.url = "/home/Computational/rarias/bscpkgs"; - outputs = { self, nixpkgs, bscpkgs, ... }: + outputs = {self,...}@inputs: let system = "x86_64-linux"; - #overlay = import ./overlay.nix; - #pkgs = import nixpkgs { inherit system; }; + remoteNixpkgsPatches = [ + { + meta.description = "sha256-ZCDQ7SpGhH8JvAwWzdcyrc68RFEWHxxAj0M2+AvEzIg="; + url = "https://github.com/NixOS/nixpkgs/pull/283460.diff"; + sha256 = "sha256-g6o4rqkOOYZ6OJTzv9kTPq9Zsu5Z1QXZmPLC3Q7Sq6w="; + } + ]; + originPkgs = inputs.nixpkgs.legacyPackages."x86_64-linux"; + nixpkgs = originPkgs.applyPatches { + name = "nixpkgs-patched"; + src = inputs.nixpkgs; + patches = map originPkgs.fetchpatch remoteNixpkgsPatches; + }; + nixosSystem = import (nixpkgs + "/nixos/lib/eval-config.nix"); + + in { #overlay = import ./overlay.nix; nixosConfigurations = { # The qemu configuration defines a system that runs in the RISC-V # architecture, but is build from an x86 host machine. - qemu = nixpkgs.lib.nixosSystem { + qemu = nixosSystem { specialArgs = { inherit self; }; system = "${system}"; modules = [ @@ -23,7 +37,7 @@ }; # Same, but disable compressed instructions - qemu-nc = nixpkgs.lib.nixosSystem { + qemu-nc = nixosSystem { specialArgs = { inherit self; }; system = "${system}"; modules = [ @@ -34,7 +48,7 @@ }; # FPGA Lagarto Hun CPU - lagarto-hun = nixpkgs.lib.nixosSystem { + lagarto-hun = nixosSystem { specialArgs = { inherit self; }; system = "${system}"; modules = [ @@ -54,7 +68,7 @@ toplevel = nixosconf.config.system.build.toplevel; in syspkgs.mkShell { pname = "qemu-shell"; - buildInputs = with syspkgs; [ qemu e2fsprogs ]; + nativeBuildInputs = with syspkgs; [ qemu e2fsprogs ]; # Here we tell the run script where to find the system NIXOS_SYSTEM_TOPLEVEL = toplevel; OPENSBI = syspkgs.opensbi-uboot; diff --git a/fpga/fpgactl b/fpga/fpgactl index 2e0ac2c..c14c323 100755 --- a/fpga/fpgactl +++ b/fpga/fpgactl @@ -273,7 +273,7 @@ verbose= bootloader_addr=0x80000000 kernel_addr=0x84000000 initrd_addr=0x8c300000 -rootfs_addr=0x180000000 +rootfs_addr=0x140000000 function usage() { diff --git a/fpga/upload.sh b/fpga/upload.sh index 191e3cc..a47a667 100755 --- a/fpga/upload.sh +++ b/fpga/upload.sh @@ -5,6 +5,10 @@ set -x dst=femu:nixos/ +if [ "$1" != "" ]; then + dst="$1" +fi + rsync -a fpga/fpgactl "$dst" rsync -a fpga/boot.sh "$dst" rsync -a fpga/env.sh "$dst" diff --git a/lagarto-hun.nix b/lagarto-hun.nix index d366809..51359ba 100644 --- a/lagarto-hun.nix +++ b/lagarto-hun.nix @@ -102,13 +102,13 @@ initrd = "${config.system.build.initialRamdisk}/initrd"; in prev.runCommand "uboot.txt" {} '' cat > $out < + # Create pmem of 3 GiB [0x140000000, 0x200000000) + fdt mknode / pmem@0x140000000 + fdt set /pmem@0x140000000 compatible "pmem-region" + fdt set /pmem@0x140000000 reg <0x1 0x40000000 0x0 0xc0000000> - # Reduce memory - fdt set /memory@80000000 reg <0x00000000 0x80000000 0x00000001 0x00000000> + # Reduce memory to 3 GiB [0x80000000, 0x140000000) + fdt set /memory@80000000 reg <0x0 0x80000000 0x0 0xc0000000> # Set kernel options setenv bootargs "root=/dev/ram0 loglevel=7 debug rw earlycon=sbi boot.trace console=hvc0 init=${init}" diff --git a/opensbi-lagarto-hun.patch b/opensbi-lagarto-hun.patch index cbc1dc6..f7e938c 100644 --- a/opensbi-lagarto-hun.patch +++ b/opensbi-lagarto-hun.patch @@ -1,9 +1,9 @@ --- a/platform/fpga/openpiton/platform.c 2024-03-12 16:27:13.886525365 +0100 -+++ b/platform/fpga/openpiton/platform.c 2024-03-12 16:28:40.598403778 +0100 -@@ -26,8 +26,8 @@ ++++ b/platform/fpga/openpiton/platform.c 2024-05-27 11:42:47.748244398 +0200 +@@ -24,8 +24,8 @@ + #define OPENPITON_DEFAULT_UART_REG_WIDTH 1 + #define OPENPITON_DEFAULT_UART_REG_OFFSET 0 #define OPENPITON_DEFAULT_PLIC_ADDR 0xfff1100000 - #define OPENPITON_DEFAULT_PLIC_SIZE (0x200000 + \ - (OPENPITON_DEFAULT_HART_COUNT * 0x1000)) -#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 2 -#define OPENPITON_DEFAULT_HART_COUNT 3 +#define OPENPITON_DEFAULT_PLIC_NUM_SOURCES 3 diff --git a/overlay.nix b/overlay.nix index b3686b6..55d58ec 100644 --- a/overlay.nix +++ b/overlay.nix @@ -3,5 +3,37 @@ final: prev: # Changes to packages from nixpkgs { + blis = ((prev.blis.override { + blas64 = true; + withArchitecture = "generic"; + }).overrideAttrs (old: { + nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ + prev.buildPackages.gfortran + ]; + })).overrideDerivation (old : { + configureFlags = [ + "--enable-cblas" + "--blas-int-size=64" + "--enable-threading=openmp" + #"--build=x86_64-unknown-linux-gnu" + #"--host=riscv64-unknown-linux-gnu" + "generic" + ]; + }); + unalignedCheck = prev.stdenv.mkDerivation { + name = "unaligned-check"; + src = ./unalign.c; + unpackPhase = '' + cp ${./unalign.c} unalign.c + ''; + dontConfigure = true; + buildPhase = '' + $CC unalign.c -o unalign_check + ''; + installPhase = '' + mkdir -p $out/bin + cp unalign_check $out/bin/ + ''; + }; } diff --git a/unalign.c b/unalign.c new file mode 100644 index 0000000..8e575cd --- /dev/null +++ b/unalign.c @@ -0,0 +1,239 @@ +/* + * unalign_check - check the CPU behaviour on different alignments + * Copyright (C) 2021 Matteo Croce + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#define ACT_READ 0 +#define ACT_WRITE 1 +#define ACT_XOR 2 +#define ACT_COPY 3 + +#define READ(SIZE) \ + case SIZE / 8: { \ + volatile uint##SIZE##_t *buf2 = (uint##SIZE##_t *)buf; \ + int i; \ + for (i = 0; i < count; i++) \ + (void)buf2[i]; \ + break; \ + } + +#define WRITE(SIZE) \ + case SIZE / 8: { \ + volatile uint##SIZE##_t *buf2 = (uint##SIZE##_t *)buf; \ + int i; \ + for (i = 0; i < count; i++) \ + buf2[i] = (uint##SIZE##_t)0xaabbccdd11223344; \ + break; \ + } + +#define XOR(SIZE) \ + case SIZE / 8: { \ + volatile uint##SIZE##_t *buf2 = (uint##SIZE##_t *)buf; \ + int i; \ + for (i = 0; i < count; i++) \ + buf2[i] = ~buf2[i]; \ + break; \ + } + +#define COPY(SIZE) \ + case SIZE / 8: { \ + volatile uint##SIZE##_t *buf2 = (uint##SIZE##_t *)buf; \ + int i; \ + for (i = 0; i < count / 2; i++) \ + buf2[i] = buf2[i + count / 2]; \ + for (i = count / 2; i < count; i++) \ + buf2[i] = buf2[i - count / 2]; \ + break; \ + } + +static void do_read(void *buf, size_t count, int size) +{ + switch (size) { + READ(8); + READ(16); + READ(32); + READ(64); + } +} + +static void do_write(void *buf, size_t count, int size) +{ + switch (size) { + WRITE(8); + WRITE(16); + WRITE(32); + WRITE(64); + } +} + +static void do_xor(void *buf, size_t count, int size) +{ + switch (size) { + XOR(8); + XOR(16); + XOR(32); + XOR(64); + } +} + +static void do_copy(void *buf, size_t count, int size) +{ + switch (size) { + COPY(8); + COPY(16); + COPY(32); + COPY(64); + } +} + +static uint64_t time_sub(struct timespec *since, struct timespec *to) +{ + if (to->tv_sec == since->tv_sec) + return to->tv_nsec - since->tv_nsec; + + return (to->tv_sec - since->tv_sec) * 1000000000 + to->tv_nsec - since->tv_nsec; +} + +static void __attribute__ ((noreturn)) usage(char *argv0, int ret) +{ + fprintf(ret ? stderr : stdout, + "usage: %s [-rwxc1234h] [-l length] [-u unalignment]\n" + "\n" + "Options:\n" + " -r read memory (default)\n" + " -w write memory\n" + " -x xor memory\n" + " -c copy memory\n" + " -l SIZE use SIZE Mb for the test (default 100)\n" + " -u BYTE unalign buffer by BYTE bytes (default 0)\n" + " -1 read 1 byte at time\n" + " -2 read 2 bytes at time\n" + " -4 read 4 bytes at time (default)\n" + " -8 read 8 bytes at time\n" + " -h this help\n", + argv0); + exit(ret); +} + +static const char *actions[] = { + "read", + "write", + "xor", + "copy", +}; + +int main(int argc, char *argv[]) +{ + struct timespec before, after; + uint64_t elapsed; + int action = ACT_READ; + size_t len = 100 * 1024 * 1024; + int shift = 0; + int size = sizeof(long); + char *buf; + int c; + + while((c = getopt(argc, argv, "hrwxc1248l:u:")) != -1) { + switch (c) { + case 'r': + action = ACT_READ; + break; + case 'w': + action = ACT_WRITE; + break; + case 'x': + action = ACT_XOR; + break; + case 'c': + action = ACT_COPY; + break; + case 'l': + len = atol(optarg) * 1024 * 1024; + if (len <= 0) { + fprintf(stderr, "Invalid size %s\n", optarg); + return 1; + } + break; + case 'u': + shift = atoi(optarg); + break; + case '1': + case '2': + case '4': + case '8': + size = c - '0'; + break; + case 'h': + default: + usage(argv[0], c != 'h'); + } + } + + shift %= size; + + if (optind != argc) + usage(argv[0], 1); + + buf = malloc(len); + if (!buf) { + perror("malloc"); + return 1; + } + + if (mlock(buf, len)) { + perror("mlock"); + return 1; + } + + clock_gettime(CLOCK_MONOTONIC, &before); + switch (action) { + case ACT_READ: + do_read(buf + shift, (len - shift) / size, size); + break; + case ACT_WRITE: + do_write(buf + shift, (len - shift) / size, size); + break; + case ACT_XOR: + do_xor(buf + shift, (len - shift) / size, size); + break; + case ACT_COPY: + do_copy(buf + shift, (len - shift) / size, size); + break; + } + clock_gettime(CLOCK_MONOTONIC, &after); + + elapsed = time_sub(&before, &after); + + printf( "size: %lu Mb\n" + "%s size: %d bit\n" + "unalignment: %d byte\n" + "elapsed time: %.2f sec\n" + "throughput: %.2f Mb/s\n", + len / 1024 / 1024, + actions[action], size * 8, + shift, + elapsed / 1E9, + (len / 1024 / 1024) / (elapsed / 1E9)); + + return 0; +} diff --git a/vm.nix b/vm.nix index ff03e65..b6a356f 100644 --- a/vm.nix +++ b/vm.nix @@ -47,8 +47,8 @@ INET y NETWORK_FILESYSTEMS y OVERLAY_FS y - "9P_FS" y - "9P_FS_POSIX_ACL" y + #"9P_FS" y + #"9P_FS_POSIX_ACL" y PCI y VIRTIO_PCI y PCI_HOST_GENERIC y @@ -63,7 +63,15 @@ nixpkgs.overlays = [ (final: prev: { - qemu = prev.qemu.override { rutabagaSupport = false; }; + qemu = prev.qemu.override { + pulseSupport = false; + pipewireSupport = false; + sdlSupport = false; + jackSupport = false; + gtkSupport = false; + vncSupport = false; + smartcardSupport = false; + }; uboot-custom = prev.ubootQemuRiscv64Smode.override { # Override preboot to set 'bootcmd' directly to the kernel address in RAM