* [Qemu-devel] [PATCH 1/4] target-arm: Fix soft interrupt in GIC distributor
2011-03-05 12:51 [Qemu-devel] [PATCH 0/4] ARM additions and fixes Adam Lackorzynski
@ 2011-03-05 12:51 ` Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 2/4] target-arm: Don't decode old cp15 WFI instructions on v7 cores Adam Lackorzynski
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adam Lackorzynski @ 2011-03-05 12:51 UTC (permalink / raw)
To: qemu-devel
Fix selection of target list filter mode.
Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index e6b1953..0e934ec 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -549,10 +549,10 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
mask = (value >> 16) & ALL_CPU_MASK;
break;
case 1:
- mask = 1 << cpu;
+ mask = ALL_CPU_MASK ^ (1 << cpu);
break;
case 2:
- mask = ALL_CPU_MASK ^ (1 << cpu);
+ mask = 1 << cpu;
break;
default:
DPRINTF("Bad Soft Int target filter\n");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 2/4] target-arm: Don't decode old cp15 WFI instructions on v7 cores
2011-03-05 12:51 [Qemu-devel] [PATCH 0/4] ARM additions and fixes Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 1/4] target-arm: Fix soft interrupt in GIC distributor Adam Lackorzynski
@ 2011-03-05 12:51 ` Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 3/4] target-arm: Implement cp15 VA->PA translation Adam Lackorzynski
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Adam Lackorzynski @ 2011-03-05 12:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
In v7 of the ARM architecture, WFI (wait for interrupt) is a first-class
instruction, but in previous versions this functionality was provided
via a cp15 coprocessor register. Add correct feature checks to the
decoding of the cp15 WFI instructions so that they behave correctly
for newer cores. In particular, the old 0,c7,c8,2 encoding used on
ARM940 has been reused for VA-to-PA translation in v6 and v7.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
---
target-arm/translate.c | 35 ++++++++++++++++++++++++++++++-----
1 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 5abf4d4..a684067 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -2538,13 +2538,38 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
if (IS_USER(s) && !cp15_user_ok(insn)) {
return 1;
}
- if ((insn & 0x0fff0fff) == 0x0e070f90
- || (insn & 0x0fff0fff) == 0x0e070f58) {
- /* Wait for interrupt. */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_WFI;
+
+ /* Pre-v7 versions of the architecture implemented WFI via coprocessor
+ * instructions rather than a separate instruction.
+ */
+ if ((insn & 0x0fff0fff) == 0x0e070f90) {
+ /* 0,c7,c0,4: Standard v6 WFI (also used in some pre-v6 cores).
+ * In v7, this must NOP.
+ */
+ if (!arm_feature(env, ARM_FEATURE_V7)) {
+ /* Wait for interrupt. */
+ gen_set_pc_im(s->pc);
+ s->is_jmp = DISAS_WFI;
+ }
return 0;
}
+
+ if ((insn & 0x0fff0fff) == 0x0e070f58) {
+ /* 0,c7,c8,2: Not all pre-v6 cores implemented this WFI,
+ * so this is slightly over-broad.
+ */
+ if (!arm_feature(env, ARM_FEATURE_V6)) {
+ /* Wait for interrupt. */
+ gen_set_pc_im(s->pc);
+ s->is_jmp = DISAS_WFI;
+ return 0;
+ }
+ /* Otherwise fall through to handle via helper function.
+ * In particular, on v7 and some v6 cores this is one of
+ * the VA-PA registers.
+ */
+ }
+
rd = (insn >> 12) & 0xf;
if (cp15_tls_load_store(env, s, insn, rd))
--
1.7.4.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 3/4] target-arm: Implement cp15 VA->PA translation
2011-03-05 12:51 [Qemu-devel] [PATCH 0/4] ARM additions and fixes Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 1/4] target-arm: Fix soft interrupt in GIC distributor Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 2/4] target-arm: Don't decode old cp15 WFI instructions on v7 cores Adam Lackorzynski
@ 2011-03-05 12:51 ` Adam Lackorzynski
2011-03-05 12:51 ` [Qemu-devel] [PATCH 4/4] target-arm: Integrate secondary CPU reset in arm_boot Adam Lackorzynski
2011-03-07 8:25 ` [Qemu-devel] [PATCH 0/4] ARM additions and fixes Aurelien Jarno
4 siblings, 0 replies; 6+ messages in thread
From: Adam Lackorzynski @ 2011-03-05 12:51 UTC (permalink / raw)
To: qemu-devel
Implement VA->PA translations by cp15-c7 that went through unchanged
previously.
Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
---
target-arm/cpu.h | 3 ++-
target-arm/helper.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
target-arm/machine.c | 2 ++
3 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c9febfa..1ae7982 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -126,6 +126,7 @@ typedef struct CPUARMState {
uint32_t c6_region[8]; /* MPU base/size registers. */
uint32_t c6_insn; /* Fault address registers. */
uint32_t c6_data;
+ uint32_t c7_par; /* Translation result. */
uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data;
uint32_t c13_fcse; /* FCSE PID. */
@@ -428,7 +429,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
#define cpu_signal_handler cpu_arm_signal_handler
#define cpu_list arm_cpu_list
-#define CPU_SAVE_VERSION 2
+#define CPU_SAVE_VERSION 3
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _kernel
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1852352..d360121 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1456,8 +1456,49 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
case 7: /* Cache control. */
env->cp15.c15_i_max = 0x000;
env->cp15.c15_i_min = 0xff0;
- /* No cache, so nothing to do. */
- /* ??? MPCore has VA to PA translation functions. */
+ if (op1 != 0) {
+ goto bad_reg;
+ }
+ /* No cache, so nothing to do except VA->PA translations. */
+ if (arm_feature(env, ARM_FEATURE_V6K)) {
+ switch (crm) {
+ case 4:
+ if (arm_feature(env, ARM_FEATURE_V7)) {
+ env->cp15.c7_par = val & 0xfffff6ff;
+ } else {
+ env->cp15.c7_par = val & 0xfffff1ff;
+ }
+ break;
+ case 8: {
+ uint32_t phys_addr;
+ target_ulong page_size;
+ int prot;
+ int ret, is_user = op2 & 2;
+ int access_type = op2 & 1;
+
+ if (op2 & 4) {
+ /* Other states are only available with TrustZone */
+ goto bad_reg;
+ }
+ ret = get_phys_addr(env, val, access_type, is_user,
+ &phys_addr, &prot, &page_size);
+ if (ret == 0) {
+ /* We do not set any attribute bits in the PAR */
+ if (page_size == (1 << 24)
+ && arm_feature(env, ARM_FEATURE_V7)) {
+ env->cp15.c7_par = (phys_addr & 0xff000000) | 1 << 1;
+ } else {
+ env->cp15.c7_par = phys_addr & 0xfffff000;
+ }
+ } else {
+ env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |
+ ((ret & (12 << 1)) >> 6) |
+ ((ret & 0xf) << 1) | 1;
+ }
+ break;
+ }
+ }
+ }
break;
case 8: /* MMU TLB control. */
switch (op2) {
@@ -1789,6 +1830,9 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
}
}
case 7: /* Cache control. */
+ if (crm == 4 && op1 == 0 && op2 == 0) {
+ return env->cp15.c7_par;
+ }
/* FIXME: Should only clear Z flag if destination is r15. */
env->ZF = 0;
return 0;
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 3925d3a..a18b7dc 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -41,6 +41,7 @@ void cpu_save(QEMUFile *f, void *opaque)
}
qemu_put_be32(f, env->cp15.c6_insn);
qemu_put_be32(f, env->cp15.c6_data);
+ qemu_put_be32(f, env->cp15.c7_par);
qemu_put_be32(f, env->cp15.c9_insn);
qemu_put_be32(f, env->cp15.c9_data);
qemu_put_be32(f, env->cp15.c13_fcse);
@@ -148,6 +149,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
}
env->cp15.c6_insn = qemu_get_be32(f);
env->cp15.c6_data = qemu_get_be32(f);
+ env->cp15.c7_par = qemu_get_be32(f);
env->cp15.c9_insn = qemu_get_be32(f);
env->cp15.c9_data = qemu_get_be32(f);
env->cp15.c13_fcse = qemu_get_be32(f);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 4/4] target-arm: Integrate secondary CPU reset in arm_boot
2011-03-05 12:51 [Qemu-devel] [PATCH 0/4] ARM additions and fixes Adam Lackorzynski
` (2 preceding siblings ...)
2011-03-05 12:51 ` [Qemu-devel] [PATCH 3/4] target-arm: Implement cp15 VA->PA translation Adam Lackorzynski
@ 2011-03-05 12:51 ` Adam Lackorzynski
2011-03-07 8:25 ` [Qemu-devel] [PATCH 0/4] ARM additions and fixes Aurelien Jarno
4 siblings, 0 replies; 6+ messages in thread
From: Adam Lackorzynski @ 2011-03-05 12:51 UTC (permalink / raw)
To: qemu-devel
Integrate secondary CPU reset into arm_boot, removing it from realview.c.
On non-Linux systems secondary CPUs start with the same entry as the boot
CPU.
Signed-off-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
---
hw/arm_boot.c | 23 +++++++++++++++--------
hw/realview.c | 14 --------------
2 files changed, 15 insertions(+), 22 deletions(-)
diff --git a/hw/arm_boot.c b/hw/arm_boot.c
index 620550b..41e99d1 100644
--- a/hw/arm_boot.c
+++ b/hw/arm_boot.c
@@ -175,7 +175,7 @@ static void set_kernel_args_old(struct arm_boot_info *info,
}
}
-static void main_cpu_reset(void *opaque)
+static void do_cpu_reset(void *opaque)
{
CPUState *env = opaque;
struct arm_boot_info *info = env->boot_info;
@@ -187,16 +187,20 @@ static void main_cpu_reset(void *opaque)
env->regs[15] = info->entry & 0xfffffffe;
env->thumb = info->entry & 1;
} else {
- env->regs[15] = info->loader_start;
- if (old_param) {
- set_kernel_args_old(info, info->initrd_size,
+ if (env == first_cpu) {
+ env->regs[15] = info->loader_start;
+ if (old_param) {
+ set_kernel_args_old(info, info->initrd_size,
+ info->loader_start);
+ } else {
+ set_kernel_args(info, info->initrd_size,
info->loader_start);
+ }
} else {
- set_kernel_args(info, info->initrd_size, info->loader_start);
+ env->regs[15] = info->smp_loader_start;
}
}
}
- /* TODO: Reset secondary CPUs. */
}
void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
@@ -217,7 +221,6 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
if (info->nb_cpus == 0)
info->nb_cpus = 1;
- env->boot_info = info;
#ifdef TARGET_WORDS_BIGENDIAN
big_endian = 1;
@@ -279,5 +282,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
info->initrd_size = initrd_size;
}
info->is_linux = is_linux;
- qemu_register_reset(main_cpu_reset, env);
+
+ for (; env; env = env->next_cpu) {
+ env->boot_info = info;
+ qemu_register_reset(do_cpu_reset, env);
+ }
}
diff --git a/hw/realview.c b/hw/realview.c
index 6eb6c6a..fae444a 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -104,17 +104,6 @@ static struct arm_boot_info realview_binfo = {
.smp_loader_start = SMP_BOOT_ADDR,
};
-static void secondary_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
-
- cpu_reset(env);
- /* Set entry point for secondary CPUs. This assumes we're using
- the init code from arm_boot.c. Real hardware resets all CPUs
- the same. */
- env->regs[15] = SMP_BOOT_ADDR;
-}
-
/* The following two lists must be consistent. */
enum realview_board_type {
BOARD_EB,
@@ -176,9 +165,6 @@ static void realview_init(ram_addr_t ram_size,
}
irqp = arm_pic_init_cpu(env);
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
- if (n > 0) {
- qemu_register_reset(secondary_cpu_reset, env);
- }
}
if (arm_feature(env, ARM_FEATURE_V7)) {
if (is_mpcore) {
--
1.7.4.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH 0/4] ARM additions and fixes
2011-03-05 12:51 [Qemu-devel] [PATCH 0/4] ARM additions and fixes Adam Lackorzynski
` (3 preceding siblings ...)
2011-03-05 12:51 ` [Qemu-devel] [PATCH 4/4] target-arm: Integrate secondary CPU reset in arm_boot Adam Lackorzynski
@ 2011-03-07 8:25 ` Aurelien Jarno
4 siblings, 0 replies; 6+ messages in thread
From: Aurelien Jarno @ 2011-03-07 8:25 UTC (permalink / raw)
To: Adam Lackorzynski; +Cc: qemu-devel
On Sat, Mar 05, 2011 at 01:51:41PM +0100, Adam Lackorzynski wrote:
> The following patches fix and enhance ARM related functionality.
>
> Adam Lackorzynski (3):
> target-arm: Fix soft interrupt in GIC distributor
> target-arm: Implement cp15 VA->PA translation
> target-arm: Integrate secondary CPU reset in arm_boot
>
> Peter Maydell (1):
> target-arm: Don't decode old cp15 WFI instructions on v7 cores
>
> hw/arm_boot.c | 23 +++++++++++++++--------
> hw/arm_gic.c | 4 ++--
> hw/realview.c | 14 --------------
> target-arm/cpu.h | 3 ++-
> target-arm/helper.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++--
> target-arm/machine.c | 2 ++
> target-arm/translate.c | 35 ++++++++++++++++++++++++++++++-----
> 7 files changed, 97 insertions(+), 32 deletions(-)
>
Thanks, all applied (patch 2 was actually already applied separately).
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 6+ messages in thread