diff mbox series

[v2,05/22] target/loongarch: Add memory management support

Message ID 1626861198-6133-6-git-send-email-gaosong@loongson.cn
State New
Headers show
Series Add LoongArch linux-user emulation support | expand

Commit Message

Song Gao July 21, 2021, 9:53 a.m. UTC
This patch introduces one memory-management-related functions
- loongarch_cpu_tlb_fill()

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/cpu.c        |   1 +
 target/loongarch/cpu.h        |   9 ++++
 target/loongarch/tlb_helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 target/loongarch/tlb_helper.c

Comments

Richard Henderson July 22, 2021, 10:48 p.m. UTC | #1
On 7/20/21 11:53 PM, Song Gao wrote:
> This patch introduces one memory-management-related functions
> - loongarch_cpu_tlb_fill()
> 
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
>   target/loongarch/cpu.c        |   1 +
>   target/loongarch/cpu.h        |   9 ++++
>   target/loongarch/tlb_helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 113 insertions(+)
>   create mode 100644 target/loongarch/tlb_helper.c
> 
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index 8eaa778..6269dd9 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -269,6 +269,7 @@ static struct TCGCPUOps loongarch_tcg_ops = {
>       .initialize = loongarch_tcg_init,
>       .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
>       .cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
> +    .tlb_fill = loongarch_cpu_tlb_fill,
>   };
>   #endif /* CONFIG_TCG */
>   
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index 1db8bb5..5c06122 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -287,4 +287,13 @@ static inline void compute_hflags(CPULoongArchState *env)
>   
>   const char *loongarch_exception_name(int32_t exception);
>   
> +/* tlb_helper.c */
> +bool loongarch_cpu_tlb_fill(CPUState *cs,
> +                            vaddr address,
> +                            int size,
> +                            MMUAccessType access_type,
> +                            int mmu_idx,
> +                            bool probe,
> +                            uintptr_t retaddr);
> +
>   #endif /* LOONGARCH_CPU_H */
> diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
> new file mode 100644
> index 0000000..b59a995
> --- /dev/null
> +++ b/target/loongarch/tlb_helper.c
> @@ -0,0 +1,103 @@
> +/*
> + * LoongArch tlb emulation helpers for qemu.
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + *
> + * SPDX-License-Identifier: LGPL-2.1+
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
> +#include "cpu-csr.h"
> +#include "exec/helper-proto.h"
> +#include "exec/exec-all.h"
> +#include "exec/cpu_ldst.h"
> +#include "exec/log.h"
> +
> +enum {
> +    TLBRET_PE = -7,
> +    TLBRET_XI = -6,
> +    TLBRET_RI = -5,
> +    TLBRET_DIRTY = -4,
> +    TLBRET_INVALID = -3,
> +    TLBRET_NOMATCH = -2,
> +    TLBRET_BADADDR = -1,
> +    TLBRET_MATCH = 0
> +};
> +
> +static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
> +                                MMUAccessType access_type, int tlb_error)
> +{
> +    CPUState *cs = env_cpu(env);
> +    int exception = 0, error_code = 0;
> +
> +    if (access_type == MMU_INST_FETCH) {
> +        error_code |= INST_INAVAIL;
> +    }
> +
> +    switch (tlb_error) {
> +    default:
> +    case TLBRET_BADADDR:
> +        exception = EXCP_ADE;
> +        break;
> +    case TLBRET_NOMATCH:
> +        /* No TLB match for a mapped address */
> +        if (access_type == MMU_DATA_STORE) {
> +            exception = EXCP_TLBS;
> +        } else {
> +            exception = EXCP_TLBL;
> +        }
> +        error_code |= TLB_NOMATCH;
> +        break;
> +    case TLBRET_INVALID:
> +        /* TLB match with no valid bit */
> +        if (access_type == MMU_DATA_STORE) {
> +            exception = EXCP_TLBS;
> +        } else {
> +            exception = EXCP_TLBL;
> +        }
> +        break;
> +    case TLBRET_DIRTY:
> +        exception = EXCP_TLBM;
> +        break;
> +    case TLBRET_XI:
> +        /* Execute-Inhibit Exception */
> +        exception = EXCP_TLBXI;
> +        break;
> +    case TLBRET_RI:
> +        /* Read-Inhibit Exception */
> +        exception = EXCP_TLBRI;
> +        break;
> +    case TLBRET_PE:
> +        /* Privileged Exception */
> +        exception = EXCP_TLBPE;
> +        break;
> +    }
> +
> +    if (tlb_error == TLBRET_NOMATCH) {
> +        env->CSR_TLBRBADV = address;
> +        env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1);
> +        cs->exception_index = exception;
> +        env->error_code = error_code;
> +        return;
> +    }
> +
> +    /* Raise exception */
> +    env->CSR_BADV = address;
> +    cs->exception_index = exception;
> +    env->error_code = error_code;
> +    env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1);
> +}
> +
> +bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> +                       MMUAccessType access_type, int mmu_idx,
> +                       bool probe, uintptr_t retaddr)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +    CPULoongArchState *env = &cpu->env;
> +    int ret = TLBRET_BADADDR;
> +
> +    /* data access */
> +    raise_mmu_exception(env, address, access_type, ret);
> +    do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
> +}

Again, almost all of this does not apply for user-only.

r~

>
Song Gao July 26, 2021, 9:25 a.m. UTC | #2
Hi, Richard.

On 07/23/2021 06:48 AM, Richard Henderson wrote:
> On 7/20/21 11:53 PM, Song Gao wrote:
>> This patch introduces one memory-management-related functions
>> - loongarch_cpu_tlb_fill()
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>>   target/loongarch/cpu.c        |   1 +
>>   target/loongarch/cpu.h        |   9 ++++
>>   target/loongarch/tlb_helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 113 insertions(+)
>>   create mode 100644 target/loongarch/tlb_helper.c
>>
>> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
>> index 8eaa778..6269dd9 100644
>> --- a/target/loongarch/cpu.c
>> +++ b/target/loongarch/cpu.c
>> @@ -269,6 +269,7 @@ static struct TCGCPUOps loongarch_tcg_ops = {
>>       .initialize = loongarch_tcg_init,
>>       .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
>>       .cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
>> +    .tlb_fill = loongarch_cpu_tlb_fill,
>>   };
>>   #endif /* CONFIG_TCG */
>>   diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
>> index 1db8bb5..5c06122 100644
>> --- a/target/loongarch/cpu.h
>> +++ b/target/loongarch/cpu.h
>> @@ -287,4 +287,13 @@ static inline void compute_hflags(CPULoongArchState *env)
>>     const char *loongarch_exception_name(int32_t exception);
>>   +/* tlb_helper.c */
>> +bool loongarch_cpu_tlb_fill(CPUState *cs,
>> +                            vaddr address,
>> +                            int size,
>> +                            MMUAccessType access_type,
>> +                            int mmu_idx,
>> +                            bool probe,
>> +                            uintptr_t retaddr);
>> +
>>   #endif /* LOONGARCH_CPU_H */
>> diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
>> new file mode 100644
>> index 0000000..b59a995
>> --- /dev/null
>> +++ b/target/loongarch/tlb_helper.c
>> @@ -0,0 +1,103 @@
>> +/*
>> + * LoongArch tlb emulation helpers for qemu.
>> + *
>> + * Copyright (c) 2021 Loongson Technology Corporation Limited
>> + *
>> + * SPDX-License-Identifier: LGPL-2.1+
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "cpu.h"
>> +#include "cpu-csr.h"
>> +#include "exec/helper-proto.h"
>> +#include "exec/exec-all.h"
>> +#include "exec/cpu_ldst.h"
>> +#include "exec/log.h"
>> +
>> +enum {
>> +    TLBRET_PE = -7,
>> +    TLBRET_XI = -6,
>> +    TLBRET_RI = -5,
>> +    TLBRET_DIRTY = -4,
>> +    TLBRET_INVALID = -3,
>> +    TLBRET_NOMATCH = -2,
>> +    TLBRET_BADADDR = -1,
>> +    TLBRET_MATCH = 0
>> +};
>> +
>> +static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>> +                                MMUAccessType access_type, int tlb_error)
>> +{
>> +    CPUState *cs = env_cpu(env);
>> +    int exception = 0, error_code = 0;
>> +
>> +    if (access_type == MMU_INST_FETCH) {
>> +        error_code |= INST_INAVAIL;
>> +    }
>> +
>> +    switch (tlb_error) {
>> +    default:
>> +    case TLBRET_BADADDR:
>> +        exception = EXCP_ADE;
>> +        break;
>> +    case TLBRET_NOMATCH:
>> +        /* No TLB match for a mapped address */
>> +        if (access_type == MMU_DATA_STORE) {
>> +            exception = EXCP_TLBS;
>> +        } else {
>> +            exception = EXCP_TLBL;
>> +        }
>> +        error_code |= TLB_NOMATCH;
>> +        break;
>> +    case TLBRET_INVALID:
>> +        /* TLB match with no valid bit */
>> +        if (access_type == MMU_DATA_STORE) {
>> +            exception = EXCP_TLBS;
>> +        } else {
>> +            exception = EXCP_TLBL;
>> +        }
>> +        break;
>> +    case TLBRET_DIRTY:
>> +        exception = EXCP_TLBM;
>> +        break;
>> +    case TLBRET_XI:
>> +        /* Execute-Inhibit Exception */
>> +        exception = EXCP_TLBXI;
>> +        break;
>> +    case TLBRET_RI:
>> +        /* Read-Inhibit Exception */
>> +        exception = EXCP_TLBRI;
>> +        break;
>> +    case TLBRET_PE:
>> +        /* Privileged Exception */
>> +        exception = EXCP_TLBPE;
>> +        break;
>> +    }
>> +
>> +    if (tlb_error == TLBRET_NOMATCH) {
>> +        env->CSR_TLBRBADV = address;
>> +        env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1);
>> +        cs->exception_index = exception;
>> +        env->error_code = error_code;
>> +        return;
>> +    }
>> +
>> +    /* Raise exception */
>> +    env->CSR_BADV = address;
>> +    cs->exception_index = exception;
>> +    env->error_code = error_code;
>> +    env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1);
>> +}
>> +
>> +bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
>> +                       MMUAccessType access_type, int mmu_idx,
>> +                       bool probe, uintptr_t retaddr)
>> +{
>> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
>> +    CPULoongArchState *env = &cpu->env;
>> +    int ret = TLBRET_BADADDR;
>> +
>> +    /* data access */
>> +    raise_mmu_exception(env, address, access_type, ret);
>> +    do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
>> +}
> 
> Again, almost all of this does not apply for user-only.
> 
> r~
> 
>>

OK, I‘ll remove it .

Thanks
Song Gao.
diff mbox series

Patch

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 8eaa778..6269dd9 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -269,6 +269,7 @@  static struct TCGCPUOps loongarch_tcg_ops = {
     .initialize = loongarch_tcg_init,
     .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
     .cpu_exec_interrupt = loongarch_cpu_exec_interrupt,
+    .tlb_fill = loongarch_cpu_tlb_fill,
 };
 #endif /* CONFIG_TCG */
 
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 1db8bb5..5c06122 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -287,4 +287,13 @@  static inline void compute_hflags(CPULoongArchState *env)
 
 const char *loongarch_exception_name(int32_t exception);
 
+/* tlb_helper.c */
+bool loongarch_cpu_tlb_fill(CPUState *cs,
+                            vaddr address,
+                            int size,
+                            MMUAccessType access_type,
+                            int mmu_idx,
+                            bool probe,
+                            uintptr_t retaddr);
+
 #endif /* LOONGARCH_CPU_H */
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
new file mode 100644
index 0000000..b59a995
--- /dev/null
+++ b/target/loongarch/tlb_helper.c
@@ -0,0 +1,103 @@ 
+/*
+ * LoongArch tlb emulation helpers for qemu.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "cpu-csr.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "exec/log.h"
+
+enum {
+    TLBRET_PE = -7,
+    TLBRET_XI = -6,
+    TLBRET_RI = -5,
+    TLBRET_DIRTY = -4,
+    TLBRET_INVALID = -3,
+    TLBRET_NOMATCH = -2,
+    TLBRET_BADADDR = -1,
+    TLBRET_MATCH = 0
+};
+
+static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
+                                MMUAccessType access_type, int tlb_error)
+{
+    CPUState *cs = env_cpu(env);
+    int exception = 0, error_code = 0;
+
+    if (access_type == MMU_INST_FETCH) {
+        error_code |= INST_INAVAIL;
+    }
+
+    switch (tlb_error) {
+    default:
+    case TLBRET_BADADDR:
+        exception = EXCP_ADE;
+        break;
+    case TLBRET_NOMATCH:
+        /* No TLB match for a mapped address */
+        if (access_type == MMU_DATA_STORE) {
+            exception = EXCP_TLBS;
+        } else {
+            exception = EXCP_TLBL;
+        }
+        error_code |= TLB_NOMATCH;
+        break;
+    case TLBRET_INVALID:
+        /* TLB match with no valid bit */
+        if (access_type == MMU_DATA_STORE) {
+            exception = EXCP_TLBS;
+        } else {
+            exception = EXCP_TLBL;
+        }
+        break;
+    case TLBRET_DIRTY:
+        exception = EXCP_TLBM;
+        break;
+    case TLBRET_XI:
+        /* Execute-Inhibit Exception */
+        exception = EXCP_TLBXI;
+        break;
+    case TLBRET_RI:
+        /* Read-Inhibit Exception */
+        exception = EXCP_TLBRI;
+        break;
+    case TLBRET_PE:
+        /* Privileged Exception */
+        exception = EXCP_TLBPE;
+        break;
+    }
+
+    if (tlb_error == TLBRET_NOMATCH) {
+        env->CSR_TLBRBADV = address;
+        env->CSR_TLBREHI = address & (TARGET_PAGE_MASK << 1);
+        cs->exception_index = exception;
+        env->error_code = error_code;
+        return;
+    }
+
+    /* Raise exception */
+    env->CSR_BADV = address;
+    cs->exception_index = exception;
+    env->error_code = error_code;
+    env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1);
+}
+
+bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+                       MMUAccessType access_type, int mmu_idx,
+                       bool probe, uintptr_t retaddr)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    CPULoongArchState *env = &cpu->env;
+    int ret = TLBRET_BADADDR;
+
+    /* data access */
+    raise_mmu_exception(env, address, access_type, ret);
+    do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
+}