Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cortex-m arm-support for s2e #13

Open
wants to merge 8 commits into
base: v3.0.0-se
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
roms/vgabios/
qemu.creator
qemu.files
qemu.includes
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,6 @@ distclean: clean
rm -f qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc qemu-doc.tp
rm -f qemu-doc.vr qemu-doc.txt
rm -f config.log
rm -f linux-headers/asm
rm -f docs/version.texi
rm -f docs/interop/qemu-ga-qapi.texi docs/interop/qemu-qmp-qapi.texi
rm -f docs/interop/qemu-qmp-ref.7 docs/interop/qemu-ga-ref.7
Expand Down
2 changes: 1 addition & 1 deletion Makefile.target
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak

$(call set-vpath, $(SRC_PATH):$(BUILD_DIR))
ifdef CONFIG_LINUX
QEMU_CFLAGS += -I../linux-headers
QEMU_CFLAGS += -Ilinux-headers
endif
QEMU_CFLAGS += -iquote .. -iquote $(SRC_PATH)/target/$(TARGET_BASE_ARCH) -DNEED_CPU_H

Expand Down
35 changes: 28 additions & 7 deletions accel/kvm/kvm-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@

#include "hw/boards.h"

#include "kvm_arm.h"

/* This check must be after config-host.h is included */
#ifdef CONFIG_EVENTFD
#include <sys/eventfd.h>
Expand Down Expand Up @@ -2265,12 +2267,23 @@ int kvm_cpu_exec(CPUState *cpu)
break;
case KVM_EXIT_MMIO:
DPRINTF("handle_mmio\n");
/* Called outside BQL */
address_space_rw(&address_space_memory,
run->mmio.phys_addr, attrs,
run->mmio.data,
run->mmio.len,
run->mmio.is_write);
qemu_mutex_lock_iothread();
/* SCS region in armv7m space memory */
if (run->mmio.phys_addr > 0xe0000000) {
address_space_rw(&armv7m_space_memory,
run->mmio.phys_addr, attrs,
run->mmio.data,
run->mmio.len,
run->mmio.is_write);
}
else {
address_space_rw(&address_space_memory,
run->mmio.phys_addr, attrs,
run->mmio.data,
run->mmio.len,
run->mmio.is_write);
}
qemu_mutex_unlock_iothread();
ret = 0;
break;
case KVM_EXIT_IRQ_WINDOW_OPEN:
Expand Down Expand Up @@ -2336,6 +2349,12 @@ int kvm_cpu_exec(CPUState *cpu)
qemu_mutex_unlock_iothread();
ret = 0;
break;
case KVM_EXIT_SYNC_ARM_V7M_SREGS:
qemu_mutex_lock_iothread();
kvm_cortex_m_get_regs(cpu);
qemu_mutex_unlock_iothread();
ret = 0;
break;
default:
DPRINTF("kvm_arch_handle_exit\n");
ret = kvm_arch_handle_exit(cpu, run);
Expand Down Expand Up @@ -2819,15 +2838,17 @@ bool kvm_device_supported(int vmfd, uint64_t type)
return false;
}


return (ioctl(vmfd, KVM_CREATE_DEVICE, &create_dev) >= 0);
}

int kvm_set_one_reg(CPUState *cs, uint64_t id, void *source)
{
struct kvm_one_reg reg;
int r;

reg.id = id;

reg.addr = (uintptr_t) source;
r = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
if (r) {
Expand Down
24 changes: 15 additions & 9 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ supported_kvm_target() {
test "$kvm" = "yes" || return 1
glob "$1" "*-softmmu" || return 1
case "${1%-softmmu}:$cpu" in
arm:arm | aarch64:aarch64 | \
arm:arm | aarch64:aarch64 | arm:x86_64 |\
i386:i386 | i386:x86_64 | i386:x32 | \
x86_64:i386 | x86_64:x86_64 | x86_64:x32 | \
mips:mips | mipsel:mips | \
Expand Down Expand Up @@ -1908,6 +1908,7 @@ EOF
if compile_prog "-fPIE -DPIE" "-pie"; then
QEMU_CFLAGS="-fPIE -DPIE $QEMU_CFLAGS"
LDFLAGS="-pie $LDFLAGS"
LDFLAGS="-rdynamic $LDFLAGS"
pie="yes"
if compile_prog "" "-Wl,-z,relro -Wl,-z,now" ; then
LDFLAGS="-Wl,-z,relro -Wl,-z,now $LDFLAGS"
Expand Down Expand Up @@ -6846,10 +6847,16 @@ if test "$docker" != "no"; then
echo "HAVE_USER_DOCKER=y" >> $config_host_mak
fi

for target in $target_list; do
target_dir="$target"
config_target_mak=$target_dir/config-target.mak
target_name=$(echo $target | cut -d '-' -f 1)
target_bigendian="no"

# use included Linux headers
if test "$linux" = "yes" ; then
mkdir -p linux-headers
case "$cpu" in
mkdir -p $target_dir/linux-headers
case "$target_name" in
i386|x86_64|x32)
linux_arch=x86
;;
Expand All @@ -6865,22 +6872,21 @@ if test "$linux" = "yes" ; then
mips64)
linux_arch=mips
;;
arm)
linux_arch=arm
;;
*)
# For most CPUs the kernel architecture name and QEMU CPU name match.
linux_arch="$cpu"
;;
esac
# For non-KVM architectures we will not have asm headers
if [ -e "$source_path/linux-headers/asm-$linux_arch" ]; then
symlink "$source_path/linux-headers/asm-$linux_arch" linux-headers/asm
symlink "$source_path/linux-headers/asm-$linux_arch" $target_dir/linux-headers/asm
fi
fi

for target in $target_list; do
target_dir="$target"
config_target_mak=$target_dir/config-target.mak
target_name=$(echo $target | cut -d '-' -f 1)
target_bigendian="no"


case "$target_name" in
armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
Expand Down
12 changes: 7 additions & 5 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ static MemoryRegion *system_io;
AddressSpace address_space_io;
AddressSpace address_space_memory;

AddressSpace armv7m_space_memory;

MemoryRegion io_mem_rom, io_mem_notdirty;
static MemoryRegion io_mem_unassigned;

Expand Down Expand Up @@ -898,20 +900,20 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr)
{
CPUAddressSpace *newas;
AddressSpace *as = g_new0(AddressSpace, 1);
char *as_name;

assert(mr);
as_name = g_strdup_printf("%s-%d", prefix, cpu->cpu_index);
address_space_init(as, mr, as_name);
//armv7m_space_memory is only for cortex-m SCS memory region map
address_space_init(&armv7m_space_memory, mr, as_name);
g_free(as_name);

/* Target code should have set num_ases before calling us */
assert(asidx < cpu->num_ases);

if (asidx == 0) {
/* address space 0 gets the convenience alias */
cpu->as = as;
cpu->as = &armv7m_space_memory;
}

/* KVM cannot currently support multiple address spaces. */
Expand All @@ -923,10 +925,10 @@ void cpu_address_space_init(CPUState *cpu, int asidx,

newas = &cpu->cpu_ases[asidx];
newas->cpu = cpu;
newas->as = as;
newas->as = &armv7m_space_memory;
if (tcg_enabled()) {
newas->tcg_as_listener.commit = tcg_commit;
memory_listener_register(&newas->tcg_as_listener, as);
memory_listener_register(&newas->tcg_as_listener, &armv7m_space_memory);
}
}

Expand Down
7 changes: 7 additions & 0 deletions hw/arm/mps2.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "hw/misc/mps2-scc.h"
#include "hw/devices.h"
#include "net/net.h"
#include "sysemu/kvm.h"

typedef enum MPS2FPGAType {
FPGA_AN385,
Expand Down Expand Up @@ -147,6 +148,8 @@ static void mps2_common_init(MachineState *machine)
NULL, "mps.ram", 0x1000000);
memory_region_add_subregion(system_memory, 0x21000000, &mms->psram);

kvm_register_fixed_memory_region("mps.ram", (uintptr_t) memory_region_get_ram_ptr(&mms->psram),0x1000000, 0);

switch (mmc->fpga_type) {
case FPGA_AN385:
make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
Expand All @@ -164,9 +167,13 @@ static void mps2_common_init(MachineState *machine)
break;
case FPGA_AN511:
make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
kvm_register_fixed_memory_region("mps.blockram", (uintptr_t) memory_region_get_ram_ptr(&mms->blockram),0x40000, 1);
make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
kvm_register_fixed_memory_region("mps.ssram1", (uintptr_t) memory_region_get_ram_ptr(&mms->ssram1),0x00800000, 1);
make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
kvm_register_fixed_memory_region("mps.sram", (uintptr_t) memory_region_get_ram_ptr(&mms->sram),0x20000, 0);
make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
kvm_register_fixed_memory_region("mps.ssram23", (uintptr_t) memory_region_get_ram_ptr(&mms->ssram23),0x400000, 0);
break;
default:
g_assert_not_reached();
Expand Down
15 changes: 9 additions & 6 deletions hw/intc/armv7m_nvic.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,6 @@ static inline int nvic_exec_prio(NVICState *s)
if (env->v7m.faultmask[M_REG_S]) {
running = (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -1;
}

/* consider priority of active handler */
return MIN(running, s->exception_prio);
}
Expand Down Expand Up @@ -400,8 +399,9 @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
bool armv7m_nvic_can_take_pending_exception(void *opaque)
{
NVICState *s = opaque;

return nvic_exec_prio(s) > nvic_pending_prio(s);
const int running = nvic_exec_prio(s);
const int vectpending_prio = s->vectpending_prio;
return running > vectpending_prio;
}

int armv7m_nvic_raw_execution_priority(void *opaque)
Expand Down Expand Up @@ -657,7 +657,7 @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
void armv7m_nvic_acknowledge_irq(void *opaque)
{
NVICState *s = (NVICState *)opaque;
CPUARMState *env = &s->cpu->env;
/* CPUARMState *env = &s->cpu->env; */
const int pending = s->vectpending;
const int running = nvic_exec_prio(s);
VecInfo *vec;
Expand All @@ -672,15 +672,18 @@ void armv7m_nvic_acknowledge_irq(void *opaque)

assert(vec->enabled);
assert(vec->pending);

// printf("check vectpending_prio=0x%x\n",s->vectpending_prio);
// printf("check running=0x%x\n",running);
assert(s->vectpending_prio < running);

trace_nvic_acknowledge_irq(pending, s->vectpending_prio);

vec->active = 1;
vec->pending = 0;

write_v7m_exception(env, s->vectpending);
/*IoT s2e move to do_interrupt_v7m comment this function*/
/* write_v7m_exception(env, s->vectpending); */


nvic_irq_update(s);
}
Expand Down
1 change: 1 addition & 0 deletions include/exec/address-spaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ MemoryRegion *get_system_memory(void);
MemoryRegion *get_system_io(void);

extern AddressSpace address_space_memory;
extern AddressSpace armv7m_space_memory;
extern AddressSpace address_space_io;

#endif
Expand Down
74 changes: 74 additions & 0 deletions include/nvic/nvic_interfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <stdbool.h>
/* Interface between CPU and Interrupt controller. */
/**
* armv7m_nvic_set_pending: mark the specified exception as pending
* @opaque: the NVIC
* @irq: the exception number to mark pending
* @secure: false for non-banked exceptions or for the nonsecure
* version of a banked exception, true for the secure version of a banked
* exception.
*
* Marks the specified exception as pending. Note that we will assert()
* if @secure is true and @irq does not specify one of the fixed set
* of architecturally banked exceptions.
*/
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
/**
* armv7m_nvic_set_pending_derived: mark this derived exception as pending
* @opaque: the NVIC
* @irq: the exception number to mark pending
* @secure: false for non-banked exceptions or for the nonsecure
* version of a banked exception, true for the secure version of a banked
* exception.
*
* Similar to armv7m_nvic_set_pending(), but specifically for derived
* exceptions (exceptions generated in the course of trying to take
* a different exception).
*/
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
/**
* armv7m_nvic_get_pending_irq_info: return highest priority pending
* exception, and whether it targets Secure state
* @opaque: the NVIC
* @pirq: set to pending exception number
* @ptargets_secure: set to whether pending exception targets Secure
*
* This function writes the number of the highest priority pending
* exception (the one which would be made active by
* armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
* to true if the current highest priority pending exception should
* be taken to Secure state, false for NS.
*/
void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
bool *ptargets_secure);
/**
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
* @opaque: the NVIC
*
* Move the current highest priority pending exception from the pending
* state to the active state, and update v7m.exception to indicate that
* it is the exception currently being handled.
*/
void armv7m_nvic_acknowledge_irq(void *opaque);
/**
* armv7m_nvic_complete_irq: complete specified interrupt or exception
* @opaque: the NVIC
* @irq: the exception number to complete
* @secure: true if this exception was secure
*
* Returns: -1 if the irq was not active
* 1 if completing this irq brought us back to base (no active irqs)
* 0 if there is still an irq active after this one was completed
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
*/
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);

/* Interface between CPU and Interrupt controller. */
#ifndef CONFIG_USER_ONLY
bool armv7m_nvic_can_take_pending_exception(void *opaque);
#else
static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
{
return true;
}
#endif
17 changes: 16 additions & 1 deletion linux-headers/asm-arm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include <linux/types.h>
#include <linux/psci.h>
#include <asm/ptrace.h>
#include <asm/ptracearm.h>

#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
Expand Down Expand Up @@ -104,8 +104,23 @@ struct kvm_vcpu_init {
__u32 target;
__u32 features[7];
};
struct kvm_m_regs {
__u32 regs[16];
};

struct kvm_m_sregs {
__u32 other_sp;
__u32 vecbase;
__u32 basepri;
__u32 control;
int current_sp;
int exception;
int pending_exception;
__u32 thumb;
void *nvic;
};
struct kvm_sregs {

};

struct kvm_fpu {
Expand Down
Loading