Re: [PATCH v1 20/36] target/riscv: Add support for virtual interrupt setting

2020-01-10 Thread Palmer Dabbelt

On Wed, 08 Jan 2020 18:33:40 PST (-0800), richard.hender...@linaro.org wrote:

On 1/9/20 11:49 AM, Palmer Dabbelt wrote:

+    irqs = (pending & ~env->mideleg & -mie) | (pending &  env->mideleg & -sie);


Isn't "-unsigned" implementation defined?  I can't get GCC to throw a warning
and it was already there, so maybe I'm just wrong?


(1) You're confusing implementation defined with undefined, and unsigned
arithmetic is the former not the latter.

(2) There is no such thing as ones-compliment or sign-magnitude integer
hardware anymore, so for this case "implementation defined" is in fact 
universal.

(3) We build with -fwrapv, so we're explicitly asking for sane behaviour from
our signed types as well.


Ah, thanks -- I didn't know we had -fwrapv.  In that case we're safe!




r~




Re: [PATCH v1 20/36] target/riscv: Add support for virtual interrupt setting

2020-01-08 Thread Richard Henderson
On 1/9/20 11:49 AM, Palmer Dabbelt wrote:
>> +    irqs = (pending & ~env->mideleg & -mie) | (pending &  env->mideleg & 
>> -sie);
> 
> Isn't "-unsigned" implementation defined?  I can't get GCC to throw a warning
> and it was already there, so maybe I'm just wrong?

(1) You're confusing implementation defined with undefined, and unsigned
arithmetic is the former not the latter.

(2) There is no such thing as ones-compliment or sign-magnitude integer
hardware anymore, so for this case "implementation defined" is in fact 
universal.

(3) We build with -fwrapv, so we're explicitly asking for sane behaviour from
our signed types as well.


r~



Re: [PATCH v1 20/36] target/riscv: Add support for virtual interrupt setting

2020-01-08 Thread Palmer Dabbelt

On Mon, 09 Dec 2019 10:11:32 PST (-0800), Alistair Francis wrote:

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 63439c9370..85eed5d885 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -37,13 +37,36 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
+target_ulong irqs;
+
 target_ulong mstatus_mie = get_field(*env->mstatus, MSTATUS_MIE);
 target_ulong mstatus_sie = get_field(*env->mstatus, MSTATUS_SIE);
-target_ulong pending = env->mip & env->mie;
-target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
-target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
-target_ulong irqs = (pending & ~env->mideleg & -mie) |
-(pending &  env->mideleg & -sie);
+target_ulong hs_mstatus_sie = get_field(env->mstatus_novirt, MSTATUS_SIE);
+
+target_ulong pending = env->mip & env->mie &
+   ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
+target_ulong vspending = (env->mip & env->mie &
+  (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) >> 1;
+
+target_ulong mie= env->priv < PRV_M ||
+  (env->priv == PRV_M && mstatus_mie);
+target_ulong sie= env->priv < PRV_S ||
+  (env->priv == PRV_S && mstatus_sie);
+target_ulong hs_sie = env->priv < PRV_S ||
+  (env->priv == PRV_S && hs_mstatus_sie);
+
+if (riscv_cpu_virt_enabled(env)) {
+target_ulong pending_hs_irq = pending & -hs_sie;
+
+if (pending_hs_irq) {
+riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP);
+return ctz64(pending_hs_irq);
+}
+
+pending = vspending;
+}
+
+irqs = (pending & ~env->mideleg & -mie) | (pending &  env->mideleg & -sie);


Isn't "-unsigned" implementation defined?  I can't get GCC to throw a warning
and it was already there, so maybe I'm just wrong?



 if (irqs) {
 return ctz64(irqs); /* since non-zero */


Reviewed-by: Palmer Dabbelt 



[PATCH v1 20/36] target/riscv: Add support for virtual interrupt setting

2019-12-09 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 33 -
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 63439c9370..85eed5d885 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -37,13 +37,36 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #ifndef CONFIG_USER_ONLY
 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
+target_ulong irqs;
+
 target_ulong mstatus_mie = get_field(*env->mstatus, MSTATUS_MIE);
 target_ulong mstatus_sie = get_field(*env->mstatus, MSTATUS_SIE);
-target_ulong pending = env->mip & env->mie;
-target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
-target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
-target_ulong irqs = (pending & ~env->mideleg & -mie) |
-(pending &  env->mideleg & -sie);
+target_ulong hs_mstatus_sie = get_field(env->mstatus_novirt, MSTATUS_SIE);
+
+target_ulong pending = env->mip & env->mie &
+   ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
+target_ulong vspending = (env->mip & env->mie &
+  (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) >> 1;
+
+target_ulong mie= env->priv < PRV_M ||
+  (env->priv == PRV_M && mstatus_mie);
+target_ulong sie= env->priv < PRV_S ||
+  (env->priv == PRV_S && mstatus_sie);
+target_ulong hs_sie = env->priv < PRV_S ||
+  (env->priv == PRV_S && hs_mstatus_sie);
+
+if (riscv_cpu_virt_enabled(env)) {
+target_ulong pending_hs_irq = pending & -hs_sie;
+
+if (pending_hs_irq) {
+riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP);
+return ctz64(pending_hs_irq);
+}
+
+pending = vspending;
+}
+
+irqs = (pending & ~env->mideleg & -mie) | (pending &  env->mideleg & -sie);
 
 if (irqs) {
 return ctz64(irqs); /* since non-zero */
-- 
2.24.0