LekKit / RVVM

The RISC-V Virtual Machine
GNU General Public License v3.0
939 stars 66 forks source link

Userland emulation, API #56

Open LekKit opened 2 years ago

LekKit commented 2 years ago

RVVM is usable as a generic CPU execution engine, not just as a complete machine. This suggests for working userspace emulation, which runs RISC-V code inside a host process, directly accesses it's memory and defers syscall execution to the host kernel. For convenience, it's also great to expose an API for that, there is a working project that already needs that (https://github.com/X547/UserlandVM), which uses RVVM for HaikuOS RISC-V userland emulation.

Progress tracking:

Discussions & suggestions are welcome.

X547 commented 2 years ago

Is it possible to build librvvm.a with pkg-config information?

X547 commented 2 years ago

I tried to adapt UserlandVM to new librvvm API and it currently crash in riscv_mmu_op.

LekKit commented 2 years ago

I tried to adapt UserlandVM to new librvvm API and it currently crash in riscv_mmu_op.

Can you give a backtrace?

LekKit commented 2 years ago

Is it possible to build librvvm.a with pkg-config information?

Will do. I have no experience with pkg-config however 😅

X547 commented 2 years ago

Some obvious fixes:

diff --git a/src/rvvm.c b/src/rvvm.c
index c782080..a3427af 100644
--- a/src/rvvm.c
+++ b/src/rvvm.c
@@ -707,11 +707,15 @@ PUBLIC rvvm_cpu_handle_t rvvm_create_user_thread(rvvm_machine_t* machine)
     vector_emplace_back(machine->harts);
     rvvm_hart_t* vm = &vector_at(machine->harts, vector_size(machine->harts) - 1);
     riscv_hart_init(vm, machine->rv64);
+    vm->machine = machine;
+    vm->mem = machine->mem;
 #ifdef USE_FPU
     // Initialize FPU properly
 #endif
     return (rvvm_cpu_handle_t)vm;
 }
@@ -743,8 +747,9 @@ PUBLIC rvvm_addr_t rvvm_read_cpu_reg(rvvm_cpu_handle_t cpu, size_t reg_id)
         return vm->csr.cause[PRIVILEGE_USER];
     } else if (reg_id == RVVM_REGID_TVAL) {
         return vm->csr.tval[PRIVILEGE_USER];
+    } else {
+        rvvm_warn("Unknown register %d in rvvm_read_cpu_reg()!", (uint32_t)reg_id);
     }
-    rvvm_warn("Unknown register %d in rvvm_read_cpu_reg()!", (uint32_t)reg_id);
     return 0;
 }

@@ -763,6 +768,7 @@ PUBLIC void rvvm_write_cpu_reg(rvvm_cpu_handle_t cpu, size_t reg_id, rvvm_addr_t
         vm->csr.cause[PRIVILEGE_USER] = reg;
     } else if (reg_id == RVVM_REGID_TVAL) {
         vm->csr.tval[PRIVILEGE_USER] = reg;
+    } else {
+        rvvm_warn("Unknown register %d in rvvm_write_cpu_reg()!", (uint32_t)reg_id);
     }
-    rvvm_warn("Unknown register %d in rvvm_write_cpu_reg()!", (uint32_t)reg_id);
 }
LekKit commented 2 years ago

Some obvious fixes:

diff --git a/src/rvvm.c b/src/rvvm.c
index c782080..a3427af 100644
--- a/src/rvvm.c
+++ b/src/rvvm.c
@@ -707,11 +707,15 @@ PUBLIC rvvm_cpu_handle_t rvvm_create_user_thread(rvvm_machine_t* machine)
     vector_emplace_back(machine->harts);
     rvvm_hart_t* vm = &vector_at(machine->harts, vector_size(machine->harts) - 1);
     riscv_hart_init(vm, machine->rv64);
+    vm->machine = machine;
+    vm->mem = machine->mem;
 #ifdef USE_FPU
     // Initialize FPU properly
 #endif
     return (rvvm_cpu_handle_t)vm;
 }
@@ -743,8 +747,9 @@ PUBLIC rvvm_addr_t rvvm_read_cpu_reg(rvvm_cpu_handle_t cpu, size_t reg_id)
         return vm->csr.cause[PRIVILEGE_USER];
     } else if (reg_id == RVVM_REGID_TVAL) {
         return vm->csr.tval[PRIVILEGE_USER];
+    } else {
+        rvvm_warn("Unknown register %d in rvvm_read_cpu_reg()!", (uint32_t)reg_id);
     }
-    rvvm_warn("Unknown register %d in rvvm_read_cpu_reg()!", (uint32_t)reg_id);
     return 0;
 }

@@ -763,6 +768,7 @@ PUBLIC void rvvm_write_cpu_reg(rvvm_cpu_handle_t cpu, size_t reg_id, rvvm_addr_t
         vm->csr.cause[PRIVILEGE_USER] = reg;
     } else if (reg_id == RVVM_REGID_TVAL) {
         vm->csr.tval[PRIVILEGE_USER] = reg;
+    } else {
+        rvvm_warn("Unknown register %d in rvvm_write_cpu_reg()!", (uint32_t)reg_id);
     }
-    rvvm_warn("Unknown register %d in rvvm_write_cpu_reg()!", (uint32_t)reg_id);
 }

Oh... Silly me Does it work now?

LekKit commented 2 years ago

Apart from the possible explosions from RVJIT and my poor checking of my own code, I tried to copy your approach and also used some proper functions for FPU enablement and other cpu state setup

X547 commented 2 years ago

Does it work now?

Not yet. Crash after first syscall with NULL guest dereference. Maybe my fault, need to debug more. TinyEMU engine still working.

LekKit commented 2 years ago

Does it work now?

Not yet. Crash after first syscall with NULL guest dereference. Maybe my fault, need to debug more. TinyEMU engine still working.

See my comment from d20c2d2 (Concern about PC increment behavior)

Where should the PC increment happen? In UserlandVM, merely returning from riscv_trap() means we land on a next instruction after the one that triggered the trap. This implementation preserves this behavior, but may need some re-arrangement. For example, we can increment the PC on the next entry to riscv_hart_run_userland(), or perhaps defer this to outside code (Will require changes on UserlandVM side)

This part should be more explicit and well documented. I'm not sure if this is the thing that broke for you, but just be aware. As for now, I'm not sure how do i set up UserlandVM to debug this myself, and not sure if any intervention is needed. There isn't much code changed so maybe you can wriggle around it and see potential fixes.

X547 commented 2 years ago

PC register is 4 inside syscall handler.

> UserlandVM /boot/home/Tests/UserlandVM/apps/StyledEdit
syscall 193(_kern_create_area)
  PC: 4
[!] unhandled trap: Hart 0x7fda61ed74d0 trap at 00000000, cause 1, tval 0x000004
FP: 0x138f4fc8fd0, PC: 0
FP: 0x138f4fc9000, PC: 0xf6ae739332
FP: 0, PC: 0x209fe946018
X547 commented 2 years ago

Virtual CPU still try to jump at TVEC that is zero. It should be not done for userland emulation mode.

LekKit commented 2 years ago

Virtual CPU still try to jump at TVEC that is zero. It should be not done for userland emulation mode.

Weird. I'm not sure how that's happening (Unless you are calling riscv_hart_run() or clearing vm->user_traps), I grep'ed the source tree for manupulations on REGISTER_PC and did not see any other way.

X547 commented 2 years ago

I used older version of riscv_hart.c 😅.

Now it seems crash on FPU instruction:

syscall 223(_kern_write_port_etc)
  PC: 1052861742872
syscall 219(_kern_port_buffer_size_etc)
  PC: 1052861742808
syscall 221(_kern_read_port_etc)
  PC: 1052861742840
[!] unhandled trap: Hart 0x7f314e9fc940 trap at 0x193b9f4cc70, cause 2, tval 0x102773
FP: 0xb4e19de740, PC: </boot/home/Tests/UserlandVM/apps/lib/libbe.so> 0x193c70
FP: 0xb4e19de7e0, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0x11362a
FP: 0xb4e19de820, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0x11392e
FP: 0xb4e19de8c0, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0xe30ce
FP: 0xb4e19dead0, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0xe4738
FP: 0xb4e19dec50, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0xe53ac
FP: 0xb4e19ded20, PC: </boot/home/Tests/UserlandVM/apps/lib/libtracker.so> 0xe0156
FP: 0xb4e19dedf0, PC: </boot/home/Tests/UserlandVM/apps/StyledEdit> 0x152c0
FP: 0xb4e19defa0, PC: </boot/home/Tests/UserlandVM/apps/StyledEdit> 0x12100
FP: 0xb4e19defd0, PC: </boot/home/Tests/UserlandVM/apps/StyledEdit> 0x121f6
FP: 0xb4e19df000, PC: 0x9476af3370
FP: 0, PC: 0x10e62d5e018
X547 commented 2 years ago

It started after recovering my old HART state initialization code:

    maxlen_t mstatus = 0xA00000000 + (FS_INITIAL << 13);
    riscv_csr_op(vm, 0x300, &mstatus, CSR_SWAP);

screenshot492

LekKit commented 2 years ago

It started after recovering my old HART state initialization code:

Neat! I will provide upstream fixes soon. Does RVJIT work? 😅

X547 commented 2 years ago

Seems yes, but not with all programs.

screenshot493

LekKit commented 2 years ago

Seems yes, but not with all programs.

Well, considering the absolute lack of cache coherence in userland mode, it's understandable. I think there are places where you could've missed the need to call rvvm_icache_flush(), for example munmap syscalls and other stuff that invalidates the code in memory. Alas, rvvm_icache_flush() is also potentially racy. I don't know for sure, would need to have your environment & working ThreadSanitizer. I remember you tried wrapping cpu runner in a lock for TEmu, so maybe you can try the same & see if it fixes anything.

X547 commented 2 years ago

Something wrong is happening with multiple threads (host heap corruption etc.).

X547 commented 2 years ago

This part should be more explicit and well documented. I'm not sure if this is the thing that broke for you, but just be aware.

Real RISC-V behavior is not incrementing PC on ECALL trap. This is also what TinyEMU does: https://github.com/X547/UserlandVM/blob/master/VirtualCpuRiscVTemu.cpp#L48.

LekKit commented 2 years ago

Real RISC-V behavior is not incrementing PC on ECALL trap. This is also what TinyEMU does: https://github.com/X547/UserlandVM/blob/master/VirtualCpuRiscVTemu.cpp#L48.

I know, it's just an implementation detail (And optimization) of RVVM interpreter that leaked when we abandoned machine mode. After each interpreted instruction it increments PC by instruction size, but the trap handling jumps to TVEC which makes the PC increment invisible to the guest.

Omitting the increment for userland emulation also adds confusion when it's not the ECALL instruction: we aren't sure what's the size of the instruction (Which is why it was initially done this way internally)

X547 commented 2 years ago

rvvm_create_user_thread have no machine->harts thread protection and rvvm_free_user_thread do not remove hart from list.

LekKit commented 2 years ago

rvvm_create_user_thread have no machine->harts thread protection and rvvm_free_user_thread do not remove hart from list.

There are some disastrous things from that vector manipulation already with CPU hotplug, a patch is on the way. You can try placing spin_lock(&global_lock) there, but another horrific issue arises from the vector reallocation which moves our cpus in memory (OH GOD). So heh, i think another round or two of patches is expected.

LekKit commented 2 years ago

Just looked at my git diff --stat

21 files changed, 3502 insertions(+), 3152 deletions(-) Oh... Poor networking, hid & fb stuff... I probably should start upstreaming them somehow

X547 commented 2 years ago

I removed hart registration in machine and more complex applications started working (no JIT).

screenshot494

X547 commented 2 years ago

It also works with JIT. hart registration is currently main problem of multi-thread app failures.

LekKit commented 2 years ago

It also works with JIT. hart registration is currently main problem of multi-thread app failures.

Hmm, thanks. I will switch from this task for a bit if you're alright with that, have some more stuff to do (Both related and unrelated to RVVM). I also have some questions about Haiku networking, and some HID API design decisions which need approval, but I'm not sure if that's related to any of the opened issues.

LekKit commented 2 years ago

@X547 Can you make some kind of torture test for this API that will work outside of Haiku? I need that so I can test it using ThreadSanitizer & other stuff.

X547 commented 2 years ago

I made UserlandVM for Haiku only. Currently I have no tests that will work on Linux. There is a project that implement Haiku syscalls on Linux at library level (_kern_* functions in libroot.so), maybe it can be used to run something like 7z b or JavaScript/Lua JIT.

Maybe it is not too hard to make some basic userland VM for Linux, but I am not familiar with Linux syscalls.

Can you fix multiple virtual HART registration/unregistration first? I think it can be done without advanced debugging tools like ThreadSatinizer.

LekKit commented 2 years ago

Can you fix multiple virtual HART registration/unregistration first? I think it can be done without advanced debugging tools like ThreadSatinizer.

Done, see staging branch. Be aware I've been committing code without any testing because I have no idea how to get this working. It compiles & passes static analysis at least, but otherwise you're the only user of this API who can confirm if I did things right.

LekKit commented 2 years ago

There is a project that implement Haiku syscalls on Linux at library level (_kern_* functions in libroot.so), maybe it can be used to run something like 7z b or JavaScript/Lua JIT.

Where do I get it? Sounds good

Maybe it is not too hard to make some basic userland VM for Linux, but I am not familiar with Linux syscalls.

Will be implemented at some point, but right now I'm more focused at upstreaming machine-related stuff (Networking) and helping you with existing userland emulator instead of writing one from scratch.

X547 commented 2 years ago

Latest version fails to build for me:

> git log
commit 3e970a388d333e3933c36437a6cf855b7d9626ff (HEAD -> master3, origin/staging)
Author: LekKit <50500857+LekKit@users.noreply.github.com>
Date:   Sun Nov 20 13:20:32 2022 +0200

    Use machine->harts pointers properly in PLIC

> git diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 749cfbe..faddc34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -161,9 +161,9 @@ list(REMOVE_ITEM RVVM_DEVICES_SRC

 if (RVVM_USE_FB)
        if (HAIKU)
-               target_sources(rvvm PRIVATE "${RVVM_HAIKU_SRC}")
+               target_sources(rvvm_common INTERFACE "${RVVM_HAIKU_SRC}")
                find_library(RVVM_BE_LIB be REQUIRED)
-               target_link_libraries(rvvm PRIVATE ${RVVM_BE_LIB})
+               target_link_libraries(rvvm_common INTERFACE ${RVVM_BE_LIB})
        elseif (UNIX)
                find_package(X11)
                if (NOT TARGET X11::X11)
> cmake .. -DRVVM_USE_FB=ON -DRVVM_USE_JIT=ON -DCMAKE_BUILD_TYPE=Release -G Ninja
> ninja
[0/2] Re-checking globbed directories...
[56/56] Linking CXX executable rvvm
FAILED: rvvm 
: && /bin/c++ -O3 -DNDEBUG -flto -fno-fat-lto-objects -flto=auto CMakeFiles/rvvm_bin.dir/src/main.c.o CMakeFiles/rvvm_bin.dir/src/devices/haiku_window.cpp.o -o rvvm  -Wl,-rpath,/boot/system/lib  librvvm.a  librvvm_cpu32.a  librvvm_cpu64.a  librvjit.a  librvvm_cpu32.a  librvvm_cpu64.a  librvjit.a  /boot/system/lib/libatomic.so  /boot/system/develop/lib/libm.a  /boot/system/lib/libbe.so && :
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: /tmp//ccUAaQQJ.ltrans3.ltrans.o: in function `rvjit_ctx_free':
<artificial>:(.text+0x1ab): undefined reference to `hashmap_clear'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x1b5): undefined reference to `hashmap_destroy'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x1bd): undefined reference to `hashmap_destroy'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: /tmp//ccUAaQQJ.ltrans3.ltrans.o: in function `rvjit_block_lookup':
<artificial>:(.text+0x3e1): undefined reference to `hashmap_rebalance'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x49b): undefined reference to `hashmap_rebalance'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x4ed): undefined reference to `hashmap_shrink'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x501): undefined reference to `hashmap_shrink'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: /tmp//ccUAaQQJ.ltrans3.ltrans.o: in function `rvjit_flush_cache':
<artificial>:(.text+0x857): undefined reference to `hashmap_clear'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x898): undefined reference to `hashmap_clear'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: /tmp//ccUAaQQJ.ltrans3.ltrans.o: in function `rvjit_ctx_init':
<artificial>:(.text+0xed7): undefined reference to `hashmap_init'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0xee5): undefined reference to `hashmap_init'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: /tmp//ccUAaQQJ.ltrans3.ltrans.o: in function `rvjit_block_finalize':
<artificial>:(.text+0x352f): undefined reference to `hashmap_rebalance'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x3620): undefined reference to `hashmap_grow'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x3656): undefined reference to `hashmap_shrink'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x366d): undefined reference to `hashmap_rebalance'
/boot/system/develop/tools/bin/../lib/gcc/x86_64-unknown-haiku/11.2.0/../../../../x86_64-unknown-haiku/bin/ld: <artificial>:(.text+0x368e): undefined reference to `hashmap_grow'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
X547 commented 2 years ago

But compiled fine with Clang, strange... Some LTO-related trouble?

Confirmed that UserlandVM works with JIT and multiple threads with latest RVVM version.

X547 commented 2 years ago

Where do I get it? Sounds good

https://github.com/trungnt2910/hyclone

LekKit commented 2 years ago

But compiled fine with Clang, strange... Some LTO-related trouble?

What's even weirder, I managed to reproduce this on Linux where it surely should not hit that if (HAIKU) branch. This still happens after rolling CMakeLists back, which means either it was broken all this time or I somehow broke it by source tree changes (???). This happens regardless of LTO and only with GCC, not with Clang or MSVC. Reminds me of similar issue in GCC related to inline functions: if you ever define an inline function without static attribute, it will later fail at link stage with optimizations disabled. We sure are not violating this rule though, since otherwise make CFLAGS=-O0 would also fail.

LekKit commented 2 years ago

I summoned the CMake Wizard, @cerg2010cerg2010 to help with this. He mentions that his initial logic to separate librvjit from librvvm may have been broken due to the fact we include librvvm parts from there (hashmap, etc)

X547 commented 2 years ago

What's even weirder, I managed to reproduce this on Linux where it surely should not hit that if (HAIKU) branch.

It can be link order trouble. GNU ld is sensitive to object files link order, but LLVM lld isn't.

LekKit commented 2 years ago

Latest version fails to build for me:

Fixed in 7b9b375

LekKit commented 2 years ago

This issue remains as a tracker. If any app doesn't work under UserlandVM and you believe it to be RVVM bug, please report here (With additional information, does it break with JIT or completely, etc). Thanks.

The remaining tasks in this issue are postponed to collect more information first.

X547 commented 2 years ago

I found one regression with new librvvm: menu windows are displayed at wrong position and size. Issue is not present with old embedded RVVM code and with TinyEMU code. Probably FPU related because float type is used in GUI coordinates.

rvvm: screenshot495

rvvm2 (note grey thin rectangle at screen left side): screenshot496

LekKit commented 2 years ago

Probably FPU related because float type is used in GUI coordinates.

You may try rolling back src/cpu/riscv_f.c to older commits, there weren't much breaking changes relative to the other code base. Be aware that it was also slightly broken previously (Explained in each commit). Notice also, our FPU needs CFLAG -frounding-math to pass RISC-V tests because compiler madness... and I don't see that CMake sets such flag. I also had reports that -frounding-math is unsupported on older Clang.

LekKit commented 2 years ago

Public CPU register accessors may also be at fault. They bitcast FPU registers into u64, and either this isn't right or you are misinterpreting that data

X547 commented 2 years ago

Public CPU register accessors may also be at fault. They bitcast FPU registers into u64, and either this isn't right or you are misinterpreting that data

I tried to turn off FPU registers access in rvvm2 engine add-on (UserlandVM currently do not touch FPU registers anyway) and it have no effect.

LekKit commented 2 years ago

Public CPU register accessors may also be at fault. They bitcast FPU registers into u64, and either this isn't right or you are misinterpreting that data

I tried to turn off FPU registers access in rvvm2 engine add-on (UserlandVM currently do not touch FPU registers anyway) and it have no effect.

Does it work for rvvm1 though? Just asking 😅 I guess this is either a regression (easily bisectable since the FPU is a single source with stable API), a broken build (Compilers sure hell like to break FPU code) or something in your code is messing up FPU env (rounding mode, exceptions). It could also be unrelated to FPU, although i'm not sure what changed in order for that to happen...

X547 commented 2 years ago

Does it work for rvvm1 though? Just asking 😅

Yes (first screenshot).

LekKit commented 2 years ago

Probably FPU related because float type is used in GUI coordinates.

Question: Does the software in question work properly inside Haiku RISC-V guest in RVVM machine instead of userland emulation?

X547 commented 2 years ago

Question: Does the software in question work properly inside Haiku RISC-V guest in RVVM machine instead of userland emulation?

Timer interrupts are currently broken in Haiku RVVM guest. I tried various combinations (OpenSBI timers and haiku_loader.riscv machine mode timer control code). Works with TinyEMU and QEmu.

LekKit commented 2 years ago

Question: Does the software in question work properly inside Haiku RISC-V guest in RVVM machine instead of userland emulation?

Timer interrupts are currently broken in Haiku RVVM guest. I tried various combinations (OpenSBI timers and haiku_loader.riscv machine mode timer control code). Works with TinyEMU and QEmu.

Can you give images for investigation?

X547 commented 2 years ago

Can you give a patch that restore ATA driver?

LekKit commented 2 years ago

Can you give a patch that restore ATA driver?

Sure thing

diff --git a/src/main.c b/src/main.c
index 3d66493..d2043a5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,8 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include "devices/nvme.h"
 #include "devices/eth-oc.h"

+#include "devices/ata.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
@@ -231,7 +233,8 @@ static int rvvm_main(int argc, const char** argv)
         } else if (cmp_arg(arg_name, "k") || cmp_arg(arg_name, "kernel")) {
             success = success && rvvm_load_kernel(machine, arg_val);
         } else if (cmp_arg(arg_name, "i") || cmp_arg(arg_name, "image")) {
-            success = success && nvme_init_auto(machine, arg_val, true);
+            //success = success && nvme_init_auto(machine, arg_val, true);
+            ata_init_auto(machine, rvvm_get_pci_bus(machine), blk_open(arg_val, BLKDEV_RW));
         } else if (cmp_arg(arg_name, "cmdline")) {
             rvvm_cmdline_set(machine, arg_val);
         } else if (cmp_arg(arg_name, "append")) {

I may bring back some kind of -ata option if you really need it. For now it's limited to librvvm as an API to create such devices.

X547 commented 2 years ago
WARN: Possible deadlock at /Haiku/data/packages/RVVM/src/devices/ns16550a.c@267
WARN: The lock was previously held at /Haiku/data/packages/RVVM/src/devices/ns16550a.c@168
WARN: Attempting to recover execution...
 * * * * * * *

Repeatedly displayed.