diff --git a/repos/base-hw/include/spec/arm/cpu/vm_state_trustzone.h b/repos/base-hw/include/spec/arm/cpu/vm_state_trustzone.h index de28e7a174..47548d7185 100644 --- a/repos/base-hw/include/spec/arm/cpu/vm_state_trustzone.h +++ b/repos/base-hw/include/spec/arm/cpu/vm_state_trustzone.h @@ -28,6 +28,7 @@ namespace Genode { */ struct Vm_state; using Vm_data = Vm_state; + struct Vcpu_state; } @@ -46,4 +47,6 @@ struct Genode::Vm_state : Genode::Cpu_state_modes Genode::addr_t irq_injection; }; +struct Genode::Vcpu_state : Genode::Vm_state { }; + #endif /* _INCLUDE__SPEC__IMX53__VM_STATE_H_ */ diff --git a/repos/os/src/server/tz_vmm/block_driver.cc b/repos/os/src/server/tz_vmm/block_driver.cc index 17da39dbed..2b7ef71a51 100644 --- a/repos/os/src/server/tz_vmm/block_driver.cc +++ b/repos/os/src/server/tz_vmm/block_driver.cc @@ -1,11 +1,12 @@ /* * \brief Paravirtualized access to block devices for VMs * \author Martin Stein + * \author Benjamin Lamowski * \date 2015-10-23 */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -99,58 +100,58 @@ Block_driver::Block_driver(Env &env, } -void Block_driver::_name(Vm_base &vm) +void Block_driver::_name(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, + _dev_apply(Device::Id { state.r2 }, [&] (Device &dev) { copy_cstring((char *)_buf, dev.name().string(), _buf_size); }, [&] () { ((char *)_buf)[0] = 0; }); } -void Block_driver::_block_count(Vm_base &vm) +void Block_driver::_block_count(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, - [&] (Device &dev) { vm.smc_ret(dev.block_count()); }, - [&] () { vm.smc_ret(0); }); + _dev_apply(Device::Id { state.r2 }, + [&] (Device &dev) { state.r0 = dev.block_count(); }, + [&] () { state.r0 = 0; }); } -void Block_driver::_block_size(Vm_base &vm) +void Block_driver::_block_size(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, - [&] (Device &dev) { vm.smc_ret(dev.block_size()); }, - [&] () { vm.smc_ret(0); }); + _dev_apply(Device::Id { state.r2 }, + [&] (Device &dev) { state.r0 = dev.block_size(); }, + [&] () { state.r0 = 0; }); } -void Block_driver::_queue_size(Vm_base &vm) +void Block_driver::_queue_size(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, - [&] (Device &dev) { vm.smc_ret(dev.session().tx()->bulk_buffer_size()); }, - [&] () { vm.smc_ret(0); }); + _dev_apply(Device::Id { state.r2 }, + [&] (Device &dev) { state.r0 = dev.session().tx()->bulk_buffer_size(); }, + [&] () { state.r0 = 0; }); } -void Block_driver::_writeable(Vm_base &vm) +void Block_driver::_writeable(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, - [&] (Device &dev) { vm.smc_ret(dev.writeable()); }, - [&] () { vm.smc_ret(false); }); + _dev_apply(Device::Id { state.r2 }, + [&] (Device &dev) { state.r0 = dev.writeable(); }, + [&] () { state.r0 = false; }); } -void Block_driver::_irq(Vm_base &vm) +void Block_driver::_irq(Vm_base &vm, Vcpu_state &state) { - _dev_apply(Device::Id { vm.smc_arg_2() }, - [&] (Device &dev) { vm.smc_ret(dev.irq()); }, - [&] () { vm.smc_ret(~(unsigned)0); }); + _dev_apply(Device::Id { state.r2 }, + [&] (Device &dev) { state.r0 = dev.irq(); }, + [&] () { state.r0 = ~(unsigned)0; }); } -void Block_driver::_buffer(Vm_base &vm) +void Block_driver::_buffer(Vm_base &vm, Vcpu_state &state) { - addr_t const buf_base = vm.smc_arg_2(); - _buf_size = vm.smc_arg_3(); + addr_t const buf_base = state.r2; + _buf_size = state.r3; addr_t const buf_top = buf_base + _buf_size; Ram const &ram = vm.ram(); addr_t const ram_top = ram.base() + ram.size(); @@ -168,17 +169,18 @@ void Block_driver::_buffer(Vm_base &vm) } -void Block_driver::_new_request(Vm_base &vm) +void Block_driver::_new_request(Vm_base &vm, Vcpu_state &state) { auto dev_func = [&] (Device &dev) { try { - size_t const size = vm.smc_arg_3(); - void *const req = (void*)vm.smc_arg_4(); + size_t const size = state.r3; + void *const req = (void*)state.r4; Packet_descriptor pkt = dev.session().alloc_packet(size); void *addr = dev.session().tx()->packet_content(pkt); dev.cache().insert(addr, req); - vm.smc_ret((long)addr, pkt.offset()); + state.r0 = (long)addr; + state.r1 = pkt.offset(); } catch (Request_cache::Full) { error("block request cache full"); @@ -189,20 +191,23 @@ void Block_driver::_new_request(Vm_base &vm) throw Device_function_failed(); } }; - _dev_apply(Device::Id { vm.smc_arg_2() }, dev_func, [&] () { vm.smc_ret(0, 0); }); + _dev_apply(Device::Id { state.r2 }, dev_func, [&] () { + state.r0 = 0; + state.r1 = 0; + }); } -void Block_driver::_submit_request(Vm_base &vm) +void Block_driver::_submit_request(Vm_base &vm, Vcpu_state &state) { auto dev_func = [&] (Device &dev) { - off_t const queue_offset = vm.smc_arg_3(); - size_t const size = vm.smc_arg_4(); - bool const write = vm.smc_arg_7(); - void *const dst = (void *)vm.smc_arg_8(); + off_t const queue_offset = state.r3; + size_t const size = state.r4; + bool const write = state.r7; + void *const dst = (void *)state.r8; unsigned long long const disc_offset = - (unsigned long long)vm.smc_arg_5() << 32 | vm.smc_arg_6(); + (unsigned long long)state.r5 << 32 | state.r6; if (write) { if (size > _buf_size) { @@ -220,11 +225,11 @@ void Block_driver::_submit_request(Vm_base &vm) dev.session().tx()->submit_packet(pkt); }; - _dev_apply(Device::Id { vm.smc_arg_2() }, dev_func, [] () { }); + _dev_apply(Device::Id { state.r2 }, dev_func, [] () { }); } -void Block_driver::_collect_reply(Vm_base &vm) +void Block_driver::_collect_reply(Vm_base &vm, Vcpu_state &state) { auto dev_func = [&] (Device &dev) { @@ -250,7 +255,7 @@ void Block_driver::_collect_reply(Vm_base &vm) /* check for packets and tell VM to stop if none available */ if (!dev.session().tx()->ack_avail()) { - vm.smc_ret(0); + state.r0 = 0; return; } /* lookup request of next packet and free cache slot */ @@ -269,13 +274,13 @@ void Block_driver::_collect_reply(Vm_base &vm) } construct_at(_buf, req, write, dat_size, dat); dev.session().tx()->release_packet(pkt); - vm.smc_ret(1); + state.r0 = 1; }; - _dev_apply(Device::Id { vm.smc_arg_2() }, dev_func, [&] () { vm.smc_ret(-1); }); + _dev_apply(Device::Id { state.r2 }, dev_func, [&] () { state.r0 = -1; }); } -void Block_driver::handle_smc(Vm_base &vm) +void Block_driver::handle_smc(Vm_base &vm, Vcpu_state &state) { enum { DEVICE_COUNT = 0, @@ -291,22 +296,22 @@ void Block_driver::handle_smc(Vm_base &vm) BUFFER = 10, NAME = 11, }; - switch (vm.smc_arg_1()) { - case DEVICE_COUNT: vm.smc_ret(_dev_count); break; - case BLOCK_COUNT: _block_count(vm); break; - case BLOCK_SIZE: _block_size(vm); break; - case WRITEABLE: _writeable(vm); break; - case QUEUE_SIZE: _queue_size(vm); break; - case IRQ: _irq(vm); break; + switch (state.r1) { + case DEVICE_COUNT: state.r0 = _dev_count; break; + case BLOCK_COUNT: _block_count(vm, state); break; + case BLOCK_SIZE: _block_size(vm, state); break; + case WRITEABLE: _writeable(vm, state); break; + case QUEUE_SIZE: _queue_size(vm, state); break; + case IRQ: _irq(vm, state); break; case START_CALLBACK: _devs.for_each([&] (Device &dev) { dev.start_irq_handling(); }); break; - case NEW_REQUEST: _new_request(vm); break; - case SUBMIT_REQUEST: _submit_request(vm); break; - case COLLECT_REPLY: _collect_reply(vm); break; - case BUFFER: _buffer(vm); break; - case NAME: _name(vm); break; + case NEW_REQUEST: _new_request(vm, state); break; + case SUBMIT_REQUEST: _submit_request(vm, state); break; + case COLLECT_REPLY: _collect_reply(vm, state); break; + case BUFFER: _buffer(vm, state); break; + case NAME: _name(vm, state); break; default: - error("unknown block-driver function ", vm.smc_arg_1()); + error("unknown block-driver function ", state.r1); throw Vm_base::Exception_handling_failed(); } } diff --git a/repos/os/src/server/tz_vmm/include/block_driver.h b/repos/os/src/server/tz_vmm/include/block_driver.h index 894744541c..a38bf5ded7 100644 --- a/repos/os/src/server/tz_vmm/include/block_driver.h +++ b/repos/os/src/server/tz_vmm/include/block_driver.h @@ -1,11 +1,12 @@ /* * \brief Paravirtualized access to block devices for VMs * \author Martin Stein + * \author Benjamin Lamowski * \date 2015-10-23 */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -119,17 +120,17 @@ class Genode::Block_driver Allocator_avl _dev_alloc; void _buf_to_pkt(void *dst, size_t sz); - void _name(Vm_base &vm); - void _block_count(Vm_base &vm); - void _block_size(Vm_base &vm); - void _queue_size(Vm_base &vm); - void _writeable(Vm_base &vm); - void _irq(Vm_base &vm); - void _buffer(Vm_base &vm); - void _device_count(Vm_base &vm); - void _new_request(Vm_base &vm); - void _submit_request(Vm_base &vm); - void _collect_reply(Vm_base &vm); + void _name(Vm_base &vm, Vcpu_state &state); + void _block_count(Vm_base &vm, Vcpu_state &state); + void _block_size(Vm_base &vm, Vcpu_state &state); + void _queue_size(Vm_base &vm, Vcpu_state &state); + void _writeable(Vm_base &vm, Vcpu_state &state); + void _irq(Vm_base &vm, Vcpu_state &state); + void _buffer(Vm_base &vm, Vcpu_state &state); + void _device_count(Vm_base &vm, Vcpu_state &state); + void _new_request(Vm_base &vm, Vcpu_state &state); + void _submit_request(Vm_base &vm, Vcpu_state &state); + void _collect_reply(Vm_base &vm, Vcpu_state &state); template void _dev_apply(Device::Id id, @@ -146,7 +147,7 @@ class Genode::Block_driver public: - void handle_smc(Vm_base &vm); + void handle_smc(Vm_base &vm, Vcpu_state &state); Block_driver(Env &env, Xml_node config, diff --git a/repos/os/src/server/tz_vmm/include/serial_driver.h b/repos/os/src/server/tz_vmm/include/serial_driver.h index b3ce8453a8..98b2e4be46 100644 --- a/repos/os/src/server/tz_vmm/include/serial_driver.h +++ b/repos/os/src/server/tz_vmm/include/serial_driver.h @@ -1,11 +1,12 @@ /* * \brief Paravirtualized access to serial device for a Trustzone VM * \author Martin Stein + * \author Benjamin Lamowski * \date 2015-10-23 */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -34,11 +35,11 @@ class Genode::Serial_driver void _push(char c) { _buf.local_addr()[_off++] = c; } void _flush(); - void _send(Vm_base &vm); + void _send(Vm_base &vm, Vcpu_state &state); public: - void handle_smc(Vm_base &vm); + void handle_smc(Vm_base &vm, Vcpu_state &state); Serial_driver(Ram_allocator &ram, Region_map &local_rm) : _buf(ram, local_rm, BUF_SIZE) { } diff --git a/repos/os/src/server/tz_vmm/include/vm_base.h b/repos/os/src/server/tz_vmm/include/vm_base.h index 76daefe584..c8e682458b 100644 --- a/repos/os/src/server/tz_vmm/include/vm_base.h +++ b/repos/os/src/server/tz_vmm/include/vm_base.h @@ -2,11 +2,12 @@ * \brief Virtual Machine Monitor VM definition * \author Stefan Kalkowski * \author Martin Stein + * \author Benjamin Lamowski * \date 2012-06-25 */ /* - * Copyright (C) 2012-2017 Genode Labs GmbH + * Copyright (C) 2012-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -74,9 +75,8 @@ class Genode::Vm_base : Noncopyable, Interface Vm_connection _vm { _env }; Vm_connection::Exit_config _exit_config { }; Vm_connection::Vcpu _vcpu; - Vm_state &_state { *(Vm_state *)&_vcpu.state() }; - void _load_kernel(); + void _load_kernel(Vcpu_state &); virtual void _load_kernel_surroundings() = 0; virtual addr_t _board_info_offset() const = 0; @@ -97,30 +97,18 @@ class Genode::Vm_base : Noncopyable, Interface Allocator &alloc, Vcpu_handler_base &handler); - void run() { _vcpu.run(); } - void pause() { _vcpu.pause(); } - - void start(); - void dump(); + void start(Vcpu_state &); + void dump(Vcpu_state &); void inject_irq(unsigned irq); - addr_t va_to_pa(addr_t va); + addr_t va_to_pa(Vcpu_state &state, addr_t va); - Vm_state const &state() const { return _state; } Ram const &ram() const { return _ram; } - addr_t smc_arg_0() { return _state.r0; } - addr_t smc_arg_1() { return _state.r1; } - addr_t smc_arg_2() { return _state.r2; } - addr_t smc_arg_3() { return _state.r3; } - addr_t smc_arg_4() { return _state.r4; } - addr_t smc_arg_5() { return _state.r5; } - addr_t smc_arg_6() { return _state.r6; } - addr_t smc_arg_7() { return _state.r7; } - addr_t smc_arg_8() { return _state.r8; } - addr_t smc_arg_9() { return _state.r9; } - - void smc_ret(addr_t const ret_0) { _state.r0 = ret_0; } - void smc_ret(addr_t const ret_0, addr_t const ret_1); + template + void with_state(FN const & fn) + { + _vcpu.with_state(fn); + } }; #endif /* _VM_BASE_H_ */ diff --git a/repos/os/src/server/tz_vmm/serial_driver.cc b/repos/os/src/server/tz_vmm/serial_driver.cc index 1486746338..e09de2c5c9 100644 --- a/repos/os/src/server/tz_vmm/serial_driver.cc +++ b/repos/os/src/server/tz_vmm/serial_driver.cc @@ -1,11 +1,12 @@ /* * \brief Paravirtualized access to serial device for a Trustzone VM * \author Martin Stein + * \author Benjamin Lamowski * \date 2015-10-23 */ /* - * Copyright (C) 2015-2017 Genode Labs GmbH + * Copyright (C) 2015-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -25,9 +26,9 @@ void Serial_driver::_flush() } -void Serial_driver::_send(Vm_base &vm) +void Serial_driver::_send(Vm_base &vm, Vcpu_state &state) { - char const c = vm.smc_arg_2(); + char const c = state.r2; if (c == '\n') { _flush(); } else { @@ -38,10 +39,10 @@ void Serial_driver::_send(Vm_base &vm) } -void Serial_driver::handle_smc(Vm_base &vm) +void Serial_driver::handle_smc(Vm_base &vm, Vcpu_state &state) { enum { SEND = 0 }; - switch (vm.smc_arg_1()) { - case SEND: _send(vm); break; - default: error("unknown serial-driver function ", vm.smc_arg_1()); } + switch (state.r1) { + case SEND: _send(vm, state); break; + default: error("unknown serial-driver function ", state.r1); } } diff --git a/repos/os/src/server/tz_vmm/spec/imx53/main.cc b/repos/os/src/server/tz_vmm/spec/imx53/main.cc index 26f3806013..45ab0f73a4 100644 --- a/repos/os/src/server/tz_vmm/spec/imx53/main.cc +++ b/repos/os/src/server/tz_vmm/spec/imx53/main.cc @@ -2,11 +2,12 @@ * \brief Virtual Machine Monitor * \author Stefan Kalkowski * \author Martin Stein + * \author Benjamin Lamowski * \date 2012-06-25 */ /* - * Copyright (C) 2008-2017 Genode Labs GmbH + * Copyright (C) 2008-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -58,7 +59,7 @@ class Main Serial_driver _serial { _env.ram(), _env.rm() }; Block_driver _block { _env, _config.xml(), _heap, _vm }; - void _handle_smc() + void _handle_smc(Vcpu_state &state) { enum { FRAMEBUFFER = 0, @@ -66,13 +67,13 @@ class Main SERIAL = 2, BLOCK = 3, }; - switch (_vm.smc_arg_0()) { + switch (state.r0) { case FRAMEBUFFER: break; case INPUT: break; - case SERIAL: _serial.handle_smc(_vm); break; - case BLOCK: _block.handle_smc(_vm); break; + case SERIAL: _serial.handle_smc(_vm, state); break; + case BLOCK: _block.handle_smc(_vm, state); break; default: - error("unknown hypervisor call ", _vm.smc_arg_0()); + error("unknown hypervisor call ", state.r0); throw Vm::Exception_handling_failed(); }; } @@ -85,19 +86,22 @@ class Main void _handle_exception() { - _vm.on_vmm_entry(); - try { - switch (_vm.state().cpu_exception) { - case Cpu_state::DATA_ABORT: _handle_data_abort(); break; - case Cpu_state::SUPERVISOR_CALL: _handle_smc(); break; - default: - error("unknown exception ", _vm.state().cpu_exception); - throw Vm::Exception_handling_failed(); + _vm.with_state([this](Vcpu_state &state) { + _vm.on_vmm_entry(); + try { + switch (state.cpu_exception) { + case Cpu_state::DATA_ABORT: _handle_data_abort(); break; + case Cpu_state::SUPERVISOR_CALL: _handle_smc(state); break; + case VCPU_EXCEPTION_STARTUP: _vm.start(state); break; + default: + error("unknown exception ", state.cpu_exception); + throw Vm::Exception_handling_failed(); + } } - _vm.run(); - } - catch (Vm::Exception_handling_failed) { _vm.dump(); } - _vm.on_vmm_exit(); + catch (Vm::Exception_handling_failed) { _vm.dump(state); } + _vm.on_vmm_exit(); + return true; + }); }; public: @@ -107,8 +111,6 @@ class Main log("Start virtual machine ..."); _m4if.set_region0(Trustzone::SECURE_RAM_BASE, Trustzone::SECURE_RAM_SIZE); - _vm.start(); - _vm.run(); } }; diff --git a/repos/os/src/server/tz_vmm/vm_base.cc b/repos/os/src/server/tz_vmm/vm_base.cc index 3f179035b3..b0e451b1a8 100644 --- a/repos/os/src/server/tz_vmm/vm_base.cc +++ b/repos/os/src/server/tz_vmm/vm_base.cc @@ -2,11 +2,12 @@ * \brief Virtual Machine Monitor VM definition * \author Stefan Kalkowski * \author Martin Stein + * \author Benjamin Lamowski * \date 2012-06-25 */ /* - * Copyright (C) 2012-2017 Genode Labs GmbH + * Copyright (C) 2012-2023 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -22,12 +23,12 @@ using namespace Genode; -void Vm_base::_load_kernel() +void Vm_base::_load_kernel(Vcpu_state &state) { Attached_rom_dataspace kernel(_env, _kernel.string()); memcpy((void*)(_ram.local() + _kernel_off), kernel.local_addr(), kernel.size()); - _state.ip = _ram.base() + _kernel_off; + state.ip = _ram.base() + _kernel_off; } @@ -45,31 +46,33 @@ Vm_base::Vm_base(Env &env, _env(env), _kernel(kernel), _cmdline(cmdline), _kernel_off(kernel_off), _machine(machine), _board(board), _ram(env, ram_base, ram_size), _vcpu(_vm, alloc, handler, _exit_config) -{ - _state.irq_injection = 0; -} +{ } -void Vm_base::start() +void Vm_base::start(Vcpu_state &state) { - memset((void*)&_state, 0, sizeof(Vm_state)); - _load_kernel(); + memset((void*)&state, 0, sizeof(Vm_state)); + _load_kernel(state); _load_kernel_surroundings(); - _state.cpsr = 0x93; /* SVC mode and IRQs disabled */ - _state.r0 = 0; - _state.r1 = _machine.value; - _state.r2 = _ram.base() + _board_info_offset(); + state.cpsr = 0x93; /* SVC mode and IRQs disabled */ + state.r0 = 0; + state.r1 = _machine.value; + state.r2 = _ram.base() + _board_info_offset(); + state.irq_injection = 0; } void Vm_base::inject_irq(unsigned irq) { - if (_state.irq_injection) { throw Inject_irq_failed(); } - _state.irq_injection = irq; + with_state([this,irq](Vcpu_state &state) { + if (state.irq_injection) { throw Inject_irq_failed(); } + state.irq_injection = irq; + return true; + }); } -void Vm_base::dump() +void Vm_base::dump(Vcpu_state &state) { char const *mod[] = { "und", "svc", "abt", "irq", "fiq" }; char const *exc[] = { "invalid", "reset", "undefined", "smc", @@ -77,56 +80,49 @@ void Vm_base::dump() auto log_adr_reg = [&] (char const *reg, addr_t val) { log(" ", reg, " = ", Hex(val, Hex::PREFIX, Hex::PAD), " ", - Hex(va_to_pa(val), Hex::PREFIX, Hex::PAD)); }; + Hex(va_to_pa(state, val), Hex::PREFIX, Hex::PAD)); }; auto log_mod_reg = [&] (char const *reg, addr_t val, char const *mod) { log(" ", reg, "_", mod, " = ", Hex(val, Hex::PREFIX, Hex::PAD), " ", - Hex(va_to_pa(val), Hex::PREFIX, Hex::PAD)); }; + Hex(va_to_pa(state, val), Hex::PREFIX, Hex::PAD)); }; log("Cpu state:"); log(" Register Virt Phys"); log("------------------------------------"); - log_adr_reg("r0 ", _state.r0); - log_adr_reg("r1 ", _state.r1); - log_adr_reg("r2 ", _state.r2); - log_adr_reg("r3 ", _state.r3); - log_adr_reg("r4 ", _state.r4); - log_adr_reg("r5 ", _state.r5); - log_adr_reg("r6 ", _state.r6); - log_adr_reg("r7 ", _state.r7); - log_adr_reg("r8 ", _state.r8); - log_adr_reg("r9 ", _state.r9); - log_adr_reg("r10 ", _state.r10); - log_adr_reg("r11 ", _state.r11); - log_adr_reg("r12 ", _state.r12); - log_adr_reg("sp ", _state.sp); - log_adr_reg("lr ", _state.lr); - log_adr_reg("ip ", _state.ip); - log_adr_reg("cpsr ", _state.cpsr); + log_adr_reg("r0 ", state.r0); + log_adr_reg("r1 ", state.r1); + log_adr_reg("r2 ", state.r2); + log_adr_reg("r3 ", state.r3); + log_adr_reg("r4 ", state.r4); + log_adr_reg("r5 ", state.r5); + log_adr_reg("r6 ", state.r6); + log_adr_reg("r7 ", state.r7); + log_adr_reg("r8 ", state.r8); + log_adr_reg("r9 ", state.r9); + log_adr_reg("r10 ", state.r10); + log_adr_reg("r11 ", state.r11); + log_adr_reg("r12 ", state.r12); + log_adr_reg("sp ", state.sp); + log_adr_reg("lr ", state.lr); + log_adr_reg("ip ", state.ip); + log_adr_reg("cpsr ", state.cpsr); for (unsigned i = 0; i < Vm_state::Mode_state::MAX; i++) { - log_mod_reg("sp ", _state.mode[i].sp, mod[i]); - log_mod_reg("lr ", _state.mode[i].lr, mod[i]); - log_mod_reg("spsr ", _state.mode[i].spsr, mod[i]); + log_mod_reg("sp ", state.mode[i].sp, mod[i]); + log_mod_reg("lr ", state.mode[i].lr, mod[i]); + log_mod_reg("spsr ", state.mode[i].spsr, mod[i]); } - log(" ttbr0 = ", Hex(_state.ttbr[0], Hex::PREFIX, Hex::PAD)); - log(" ttbr1 = ", Hex(_state.ttbr[1], Hex::PREFIX, Hex::PAD)); - log(" ttbrc = ", Hex(_state.ttbrc , Hex::PREFIX, Hex::PAD)); - log_adr_reg("dfar ", _state.dfar); - log(" exception = ", exc[_state.cpu_exception]); + log(" ttbr0 = ", Hex(state.ttbr[0], Hex::PREFIX, Hex::PAD)); + log(" ttbr1 = ", Hex(state.ttbr[1], Hex::PREFIX, Hex::PAD)); + log(" ttbrc = ", Hex(state.ttbrc , Hex::PREFIX, Hex::PAD)); + log_adr_reg("dfar ", state.dfar); + log(" exception = ", exc[state.cpu_exception]); } -void Vm_base::smc_ret(addr_t const ret_0, addr_t const ret_1) -{ - _state.r0 = ret_0; - _state.r1 = ret_1; -} - - -addr_t Vm_base::va_to_pa(addr_t va) +addr_t Vm_base::va_to_pa(Vcpu_state & state, addr_t va) { try { - Mmu mmu(_state, _ram); + Mmu mmu(state, _ram); return mmu.phys_addr(va); } catch(Ram::Invalid_addr) { }