-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ARM: added a configurable machine * Small fixes * Fixed compilation error * Support for system-wide named semaphores * Added support for message queues * IPC: fixes permission on message queues and semaphores creation * Message queues: non-blocking Conflicts: include/qemu/thread-posix.h * Avatar: Modifications to the IPC interface Extracted from 6e31210a3c13f4b6db7d7db5262cc47278e1f693 * Started the memory forwarder device * Configurable: entry address and endianness * somewhat working remotememoryreadrequests * RemoteMemory! * Experimental removal of ram-resizable flag * Small fixes on the configurable machine * error handling in remote memory * integrated change in qapi * Hotfix: Don't bail out on failed rmr/rmw * Fixed bug regarding entrypoint, removed load_kernel and set_endianness from configurable machine * Cleaned up configurable machine and added MIPS-support * Adjusted RMemory to hold pc * bugfix in configurable machine * Banked registers! * move header files to include/hw/avatar * Refactored avatar mqueueing * starting on interrupt-injection * Unclean hackish commit to be squashed later * WIP: interrupt_exec and avatar_log * added log_item for avatar * minimal changes * nvic-related changes (untested!) * bugfixes * Banked registers! * nvic-write-forward update * let\'s return xpsr and not cpsr * Refactored avatar mqueueing * new logging for interrupts * move header files to include/hw/avatar * minor fixes * ignore/unignore irq returns * not enabling - stuff should be fine * additional interrupt notifications and acks * bugfix * Allow board init for more than armv7m * format strings are hard * Add set_nvic_base to qmp * I meant vector table base, not nvic base * fix compile on 18.04 * Update to comply with qemu-3.1 * cpu-model -> cpu-type * make usage of the new ARM_CPU_TYPE_NAME macro * temporary race condition hotfix: don't emit qapi_resume/stop
- Loading branch information
Showing
15 changed files
with
6,775 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
obj-$(TARGET_ARM) += avatar_posix.o configurable_machine.o remote_memory.o arm_helper.o | ||
obj-$(TARGET_MIPS) += avatar_posix.o configurable_machine.o remote_memory.o | ||
obj-$(CONFIG_SOFTMMU) += interrupts.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
|
||
#include "qemu/osdep.h" | ||
#include "qemu/log.h" | ||
#include "qemu/error-report.h" | ||
#include "qemu-common.h" | ||
#include "qapi/qapi-commands-avatar.h" | ||
#include "qapi/error.h" | ||
|
||
#include "hw/sysbus.h" | ||
#include "sysemu/sysemu.h" | ||
|
||
#ifdef TARGET_ARM | ||
#include "target/arm/cpu.h" | ||
#elif TARGET_MIPS | ||
#include "target/mips/cpu.h" | ||
#endif | ||
|
||
#include "hw/avatar/interrupts.h" | ||
#include "hw/avatar/avatar_posix.h" | ||
#include "hw/avatar/remote_memory.h" | ||
|
||
|
||
static QemuAvatarMessageQueue *irq_rx_queue_ref = NULL; | ||
static QemuAvatarMessageQueue *irq_tx_queue_ref = NULL; | ||
|
||
extern QemuAvatarMessageQueue *rmem_rx_queue_ref; | ||
extern QemuAvatarMessageQueue *rmem_tx_queue_ref; | ||
|
||
static uint64_t req_id; | ||
|
||
static bool armv7m_exception_handling_enabled = false; | ||
static uint8_t ignore_irq_return_map[32] = {0}; | ||
|
||
|
||
void qmp_avatar_armv7m_set_vector_table_base(int64_t num_cpu, int64_t base, Error **errp) | ||
{ | ||
#ifdef TARGET_ARM | ||
qemu_log_mask(LOG_AVATAR, "Changing NVIC base to%lx\n", base & 0xffffff80); | ||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(num_cpu)); | ||
/* MM: qemu now has multiple vecbases, we may need to fix this */ | ||
armcpu->env.v7m.vecbase[armcpu->env.v7m.secure] = base & 0xffffff80; | ||
#endif | ||
} | ||
|
||
|
||
void avatar_armv7m_nvic_forward_write(uint32_t offset, uint32_t value, unsigned size){ | ||
int ret; | ||
RemoteMemoryResp resp; | ||
|
||
qemu_log_mask(LOG_AVATAR, "armv7m nvic write at offset 0x%x\n", offset); | ||
qemu_log_flush(); | ||
if(!armv7m_exception_handling_enabled){ | ||
return; | ||
} | ||
|
||
memset(&resp, 0, sizeof(resp)); | ||
|
||
uint64_t pc = get_current_pc(); | ||
|
||
//for now, assusme nvic at the standard location at 0xE000E000 | ||
MemoryForwardReq request = {req_id++, pc, 0xe000e000+offset, value, size, AVATAR_WRITE}; | ||
|
||
qemu_avatar_mq_send(rmem_tx_queue_ref, &request, sizeof(request)); | ||
ret = qemu_avatar_mq_receive(rmem_rx_queue_ref, &resp, sizeof(resp)); | ||
if(!resp.success || (resp.id != request.id)){ | ||
|
||
error_report("RemoteMemoryWrite for NVIC failed (%d)!\n", ret); | ||
exit(1); | ||
} | ||
} | ||
|
||
void qmp_avatar_armv7m_enable_irq(const char *irq_rx_queue_name, | ||
const char *irq_tx_queue_name, | ||
const char *rmem_rx_queue_name, | ||
const char *rmem_tx_queue_name, Error **errp) | ||
{ | ||
if(irq_rx_queue_ref == NULL){ | ||
irq_rx_queue_ref = malloc(sizeof(QemuAvatarMessageQueue)); | ||
qemu_avatar_mq_open_read(irq_rx_queue_ref, irq_rx_queue_name, | ||
sizeof(V7MInterruptResp)); | ||
} | ||
if(irq_tx_queue_ref == NULL){ | ||
irq_tx_queue_ref = malloc(sizeof(QemuAvatarMessageQueue)); | ||
qemu_avatar_mq_open_write(irq_tx_queue_ref, irq_tx_queue_name, | ||
sizeof(V7MInterruptReq)); | ||
} | ||
|
||
if(rmem_rx_queue_ref == NULL){ | ||
rmem_rx_queue_ref = malloc(sizeof(QemuAvatarMessageQueue)); | ||
qemu_avatar_mq_open_read(rmem_rx_queue_ref, rmem_rx_queue_name, sizeof(RemoteMemoryResp)); | ||
} | ||
if(rmem_tx_queue_ref == NULL){ | ||
rmem_tx_queue_ref = malloc(sizeof(QemuAvatarMessageQueue)); | ||
qemu_avatar_mq_open_write(rmem_tx_queue_ref, rmem_tx_queue_name, sizeof(MemoryForwardReq)); | ||
} | ||
|
||
armv7m_exception_handling_enabled = true; | ||
qemu_log_mask(LOG_AVATAR, "armv7m interrupt injection enabled\n"); | ||
qemu_log_flush(); | ||
} | ||
|
||
|
||
void qmp_avatar_armv7m_disable_irq(Error **errp) | ||
{ | ||
qemu_log_mask(LOG_AVATAR, "armv7m interrupt injection disabled\n"); | ||
armv7m_exception_handling_enabled = false; | ||
qemu_log_flush(); | ||
} | ||
|
||
|
||
void qmp_avatar_armv7m_ignore_irq_return(int64_t num_irq, Error **errp) | ||
{ | ||
ignore_irq_return_map[num_irq/8] |= 1 << num_irq % 8; | ||
} | ||
|
||
void qmp_avatar_armv7m_unignore_irq_return(int64_t num_irq, Error **errp) | ||
{ | ||
ignore_irq_return_map[num_irq/8] &= 0 << num_irq % 8; | ||
} | ||
|
||
void qmp_avatar_armv7m_inject_irq(int64_t num_cpu,int64_t num_irq, Error **errp) | ||
{ | ||
#ifdef TARGET_ARM | ||
qemu_log_mask(LOG_AVATAR, "Injecting exception 0x%lx\n", num_irq); | ||
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(num_cpu)); | ||
CPUARMState *env = &armcpu->env; | ||
/* MM: for now, we can only inject non-secure irqs */ | ||
armv7m_nvic_set_pending(env->nvic, num_irq, false); | ||
#endif | ||
} | ||
|
||
|
||
void avatar_armv7m_exception_exit(int irq, uint32_t type) | ||
{ | ||
int ret; | ||
V7MInterruptResp resp; | ||
V7MInterruptReq request = {req_id++, irq, INTERRUPT_EXIT, type}; | ||
|
||
if( (ignore_irq_return_map[irq/8] & 1 << irq % 8) || !armv7m_exception_handling_enabled) | ||
{ | ||
qemu_log_mask(LOG_AVATAR, "Returning form 0x%x - Ignored by avatar\n", irq); | ||
} | ||
else{ | ||
qemu_log_mask(LOG_AVATAR, "Returning form 0x%x\n", irq); | ||
memset(&resp, 0, sizeof(resp)); | ||
|
||
qemu_avatar_mq_send(irq_tx_queue_ref, &request, sizeof(request)); | ||
ret = qemu_avatar_mq_receive(irq_rx_queue_ref, &resp, sizeof(resp)); | ||
|
||
if(!resp.success || (resp.id != request.id) || (resp.operation != INTERRUPT_EXIT) ){ | ||
error_report("ARMv7mInterruptRequest failed (%d)!\n", ret); | ||
exit(1); | ||
} | ||
} | ||
} | ||
|
||
void avatar_armv7m_exception_enter(int irq) | ||
{ | ||
int ret; | ||
V7MInterruptResp resp; | ||
V7MInterruptReq request = {req_id++, irq, INTERRUPT_ENTER, 0}; | ||
|
||
if( (ignore_irq_return_map[irq/8] & 1 << irq % 8) || !armv7m_exception_handling_enabled) | ||
{ | ||
qemu_log_mask(LOG_AVATAR, "Entered IRQ 0x%x - Ignored by avatar\n", irq); | ||
} | ||
else{ | ||
qemu_log_mask(LOG_AVATAR, "Entering IRQ 0x%x\n", irq); | ||
memset(&resp, 0, sizeof(resp)); | ||
|
||
qemu_avatar_mq_send(irq_tx_queue_ref, &request, sizeof(request)); | ||
ret = qemu_avatar_mq_receive(irq_rx_queue_ref, &resp, sizeof(resp)); | ||
|
||
if(!resp.success || (resp.id != request.id) || (resp.operation != INTERRUPT_ENTER)){ | ||
error_report("ARMv7mInterruptRequest failed (%d)!\n", ret); | ||
exit(1); | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef HW_AVATAR_INTERRUPTS_H | ||
#define HW_AVATAR_INTERRUPTS_H | ||
|
||
enum RemoteInterruptOperation{ | ||
INTERRUPT_ENTER, | ||
INTERRUPT_EXIT, | ||
}; | ||
|
||
typedef struct V7MInterruptReq{ | ||
uint64_t id; | ||
uint32_t num_irq; | ||
uint32_t operation; | ||
uint32_t type; | ||
} V7MInterruptReq; | ||
|
||
typedef struct V7MInterruptResp{ | ||
uint64_t id; | ||
bool success; | ||
uint32_t operation; | ||
} V7MInterruptResp; | ||
|
||
void avatar_armv7m_exception_exit(int irq, uint32_t type); | ||
void avatar_armv7m_exception_enter(int irq); | ||
void avatar_armv7m_nvic_forward_write(uint32_t offset, uint32_t value,unsigned size); | ||
|
||
#endif |
Oops, something went wrong.