diff mbox series

[v3,6/6] target/loongarch: Support LoongArch32 VPPN

Message ID 20230807094505.2030603-7-c@jia.je
State New
Headers show
Series Add loongarch32 mode for loongarch64-softmmu | expand

Commit Message

Jiajie Chen Aug. 7, 2023, 9:45 a.m. UTC
VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.

Signed-off-by: Jiajie Chen <c@jia.je>
---
 target/loongarch/cpu-csr.h    |  6 ++++--
 target/loongarch/tlb_helper.c | 23 ++++++++++++++++++-----
 2 files changed, 22 insertions(+), 7 deletions(-)

Comments

Jiajie Chen Aug. 7, 2023, 9:48 a.m. UTC | #1
On 2023/8/7 17:45, Jiajie Chen wrote:
> VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.
>
> Signed-off-by: Jiajie Chen <c@jia.je>
> ---
>   target/loongarch/cpu-csr.h    |  6 ++++--
>   target/loongarch/tlb_helper.c | 23 ++++++++++++++++++-----
>   2 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
> index b93f99a9ef..9501a969af 100644
> --- a/target/loongarch/cpu-csr.h
> +++ b/target/loongarch/cpu-csr.h
> @@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
>   FIELD(CSR_TLBIDX, NE, 31, 1)
>   
>   #define LOONGARCH_CSR_TLBEHI         0x11 /* TLB EntryHi */
> -FIELD(CSR_TLBEHI, VPPN, 13, 35)
> +FIELD(CSR_TLBEHI_32, VPPN, 13, 35)
> +FIELD(CSR_TLBEHI_64, VPPN, 13, 19)
Sorry, the bit width is wrong.
>   
>   #define LOONGARCH_CSR_TLBELO0        0x12 /* TLB EntryLo0 */
>   #define LOONGARCH_CSR_TLBELO1        0x13 /* TLB EntryLo1 */
> @@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
>   #define LOONGARCH_CSR_TLBRELO1       0x8d /* TLB refill entrylo1 */
>   #define LOONGARCH_CSR_TLBREHI        0x8e /* TLB refill entryhi */
>   FIELD(CSR_TLBREHI, PS, 0, 6)
> -FIELD(CSR_TLBREHI, VPPN, 13, 35)
> +FIELD(CSR_TLBREHI_32, VPPN, 13, 35)
> +FIELD(CSR_TLBREHI_64, VPPN, 13, 19)
>   #define LOONGARCH_CSR_TLBRPRMD       0x8f /* TLB refill mode info */
>   FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
>   FIELD(CSR_TLBRPRMD, PIE, 2, 1)
> diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
> index cf6f5863f9..7926c40252 100644
> --- a/target/loongarch/tlb_helper.c
> +++ b/target/loongarch/tlb_helper.c
> @@ -305,8 +305,13 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>   
>       if (tlb_error == TLBRET_NOMATCH) {
>           env->CSR_TLBRBADV = address;
> -        env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
> -                                      extract64(address, 13, 35));
> +        if (env->mode == LA64) {
> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
> +                                        VPPN, extract64(address, 13, 35));
> +        } else {
> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
> +                                        VPPN, extract64(address, 13, 19));
> +        }
>       } else {
>           if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
>               env->CSR_BADV = address;
> @@ -371,12 +376,20 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
>   
>       if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
>           csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
> -        csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
> +        if (env->mode == LA64) {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
> +        } else {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
> +        }
>           lo0 = env->CSR_TLBRELO0;
>           lo1 = env->CSR_TLBRELO1;
>       } else {
>           csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
> -        csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
> +        if (env->mode == LA64) {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
> +        } else {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
> +        }
>           lo0 = env->CSR_TLBELO0;
>           lo1 = env->CSR_TLBELO1;
>       }
> @@ -496,7 +509,7 @@ void helper_tlbfill(CPULoongArchState *env)
>   
>       if (pagesize == stlb_ps) {
>           /* Only write into STLB bits [47:13] */
> -        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
> +        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
>   
>           /* Choose one set ramdomly */
>           set = get_random_tlb(0, 7);
Song Gao Aug. 7, 2023, 11:53 a.m. UTC | #2
在 2023/8/7 下午5:45, Jiajie Chen 写道:
> VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.
> 
> Signed-off-by: Jiajie Chen <c@jia.je>
> ---
>   target/loongarch/cpu-csr.h    |  6 ++++--
>   target/loongarch/tlb_helper.c | 23 ++++++++++++++++++-----
>   2 files changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
> index b93f99a9ef..9501a969af 100644
> --- a/target/loongarch/cpu-csr.h
> +++ b/target/loongarch/cpu-csr.h
> @@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
>   FIELD(CSR_TLBIDX, NE, 31, 1)
>   
>   #define LOONGARCH_CSR_TLBEHI         0x11 /* TLB EntryHi */
> -FIELD(CSR_TLBEHI, VPPN, 13, 35)
> +FIELD(CSR_TLBEHI_32, VPPN, 13, 35)
> +FIELD(CSR_TLBEHI_64, VPPN, 13, 19)
> 

FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
FIELD(CSR_TLBEHI_64, VPPN, 13, 35)

>   #define LOONGARCH_CSR_TLBELO0        0x12 /* TLB EntryLo0 */
>   #define LOONGARCH_CSR_TLBELO1        0x13 /* TLB EntryLo1 */
> @@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
>   #define LOONGARCH_CSR_TLBRELO1       0x8d /* TLB refill entrylo1 */
>   #define LOONGARCH_CSR_TLBREHI        0x8e /* TLB refill entryhi */
>   FIELD(CSR_TLBREHI, PS, 0, 6)
> -FIELD(CSR_TLBREHI, VPPN, 13, 35)
> +FIELD(CSR_TLBREHI_32, VPPN, 13, 35)
> +FIELD(CSR_TLBREHI_64, VPPN, 13, 19)

FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
FIELD(CSR_TLBREHI_64, VPPN, 13, 35)

We should test booting a 64 bit kernel or system,
and adding a 32bit example in patch0 would be more useful.


Thanks.
Song Gao

>   #define LOONGARCH_CSR_TLBRPRMD       0x8f /* TLB refill mode info */
>   FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
>   FIELD(CSR_TLBRPRMD, PIE, 2, 1)
> diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
> index cf6f5863f9..7926c40252 100644
> --- a/target/loongarch/tlb_helper.c
> +++ b/target/loongarch/tlb_helper.c
> @@ -305,8 +305,13 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>   
>       if (tlb_error == TLBRET_NOMATCH) {
>           env->CSR_TLBRBADV = address;
> -        env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
> -                                      extract64(address, 13, 35));
> +        if (env->mode == LA64) {
> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
> +                                        VPPN, extract64(address, 13, 35));
> +        } else {
> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
> +                                        VPPN, extract64(address, 13, 19));
> +        }
>       } else {
>           if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
>               env->CSR_BADV = address;
> @@ -371,12 +376,20 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
>   
>       if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
>           csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
> -        csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
> +        if (env->mode == LA64) {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
> +        } else {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
> +        }
>           lo0 = env->CSR_TLBRELO0;
>           lo1 = env->CSR_TLBRELO1;
>       } else {
>           csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
> -        csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
> +        if (env->mode == LA64) {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
> +        } else {
> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
> +        }
>           lo0 = env->CSR_TLBELO0;
>           lo1 = env->CSR_TLBELO1;
>       }
> @@ -496,7 +509,7 @@ void helper_tlbfill(CPULoongArchState *env)
>   
>       if (pagesize == stlb_ps) {
>           /* Only write into STLB bits [47:13] */
> -        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
> +        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
>   
>           /* Choose one set ramdomly */
>           set = get_random_tlb(0, 7);
>
Jiajie Chen Aug. 7, 2023, 11:56 a.m. UTC | #3
On 2023/8/7 19:53, gaosong wrote:
> 在 2023/8/7 下午5:45, Jiajie Chen 写道:
>> VPPN of TLBEHI/TLBREHI is limited to 19 bits in LA32.
>>
>> Signed-off-by: Jiajie Chen <c@jia.je>
>> ---
>>   target/loongarch/cpu-csr.h    |  6 ++++--
>>   target/loongarch/tlb_helper.c | 23 ++++++++++++++++++-----
>>   2 files changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
>> index b93f99a9ef..9501a969af 100644
>> --- a/target/loongarch/cpu-csr.h
>> +++ b/target/loongarch/cpu-csr.h
>> @@ -57,7 +57,8 @@ FIELD(CSR_TLBIDX, PS, 24, 6)
>>   FIELD(CSR_TLBIDX, NE, 31, 1)
>>     #define LOONGARCH_CSR_TLBEHI         0x11 /* TLB EntryHi */
>> -FIELD(CSR_TLBEHI, VPPN, 13, 35)
>> +FIELD(CSR_TLBEHI_32, VPPN, 13, 35)
>> +FIELD(CSR_TLBEHI_64, VPPN, 13, 19)
>>
>
> FIELD(CSR_TLBEHI_32, VPPN, 13, 19)
> FIELD(CSR_TLBEHI_64, VPPN, 13, 35)
Thanks for correction.
>
>>   #define LOONGARCH_CSR_TLBELO0 0x12 /* TLB EntryLo0 */
>>   #define LOONGARCH_CSR_TLBELO1        0x13 /* TLB EntryLo1 */
>> @@ -164,7 +165,8 @@ FIELD(CSR_TLBRERA, PC, 2, 62)
>>   #define LOONGARCH_CSR_TLBRELO1       0x8d /* TLB refill entrylo1 */
>>   #define LOONGARCH_CSR_TLBREHI        0x8e /* TLB refill entryhi */
>>   FIELD(CSR_TLBREHI, PS, 0, 6)
>> -FIELD(CSR_TLBREHI, VPPN, 13, 35)
>> +FIELD(CSR_TLBREHI_32, VPPN, 13, 35)
>> +FIELD(CSR_TLBREHI_64, VPPN, 13, 19)
>
> FIELD(CSR_TLBREHI_32, VPPN, 13, 19)
> FIELD(CSR_TLBREHI_64, VPPN, 13, 35)
Thanks for correction.
>
> We should test booting a 64 bit kernel or system,
> and adding a 32bit example in patch0 would be more useful.
I have tested booting a bare-metal supervisor: 
https://github.com/jiegec/supervisor-la32.
>
>
> Thanks.
> Song Gao
>
>>   #define LOONGARCH_CSR_TLBRPRMD 0x8f /* TLB refill mode info */
>>   FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
>>   FIELD(CSR_TLBRPRMD, PIE, 2, 1)
>> diff --git a/target/loongarch/tlb_helper.c 
>> b/target/loongarch/tlb_helper.c
>> index cf6f5863f9..7926c40252 100644
>> --- a/target/loongarch/tlb_helper.c
>> +++ b/target/loongarch/tlb_helper.c
>> @@ -305,8 +305,13 @@ static void 
>> raise_mmu_exception(CPULoongArchState *env, target_ulong address,
>>         if (tlb_error == TLBRET_NOMATCH) {
>>           env->CSR_TLBRBADV = address;
>> -        env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, 
>> VPPN,
>> -                                      extract64(address, 13, 35));
>> +        if (env->mode == LA64) {
>> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, 
>> CSR_TLBREHI_64,
>> +                                        VPPN, extract64(address, 13, 
>> 35));
>> +        } else {
>> +            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, 
>> CSR_TLBREHI_32,
>> +                                        VPPN, extract64(address, 13, 
>> 19));
>> +        }
>>       } else {
>>           if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
>>               env->CSR_BADV = address;
>> @@ -371,12 +376,20 @@ static void fill_tlb_entry(CPULoongArchState 
>> *env, int index)
>>         if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
>>           csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
>> -        csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
>> +        if (env->mode == LA64) {
>> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, 
>> VPPN);
>> +        } else {
>> +            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, 
>> VPPN);
>> +        }
>>           lo0 = env->CSR_TLBRELO0;
>>           lo1 = env->CSR_TLBRELO1;
>>       } else {
>>           csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
>> -        csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
>> +        if (env->mode == LA64) {
>> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, 
>> VPPN);
>> +        } else {
>> +            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, 
>> VPPN);
>> +        }
>>           lo0 = env->CSR_TLBELO0;
>>           lo1 = env->CSR_TLBELO1;
>>       }
>> @@ -496,7 +509,7 @@ void helper_tlbfill(CPULoongArchState *env)
>>         if (pagesize == stlb_ps) {
>>           /* Only write into STLB bits [47:13] */
>> -        address = entryhi & ~MAKE_64BIT_MASK(0, 
>> R_CSR_TLBEHI_VPPN_SHIFT);
>> +        address = entryhi & ~MAKE_64BIT_MASK(0, 
>> R_CSR_TLBEHI_64_VPPN_SHIFT);
>>             /* Choose one set ramdomly */
>>           set = get_random_tlb(0, 7);
>>
>
diff mbox series

Patch

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index b93f99a9ef..9501a969af 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -57,7 +57,8 @@  FIELD(CSR_TLBIDX, PS, 24, 6)
 FIELD(CSR_TLBIDX, NE, 31, 1)
 
 #define LOONGARCH_CSR_TLBEHI         0x11 /* TLB EntryHi */
-FIELD(CSR_TLBEHI, VPPN, 13, 35)
+FIELD(CSR_TLBEHI_32, VPPN, 13, 35)
+FIELD(CSR_TLBEHI_64, VPPN, 13, 19)
 
 #define LOONGARCH_CSR_TLBELO0        0x12 /* TLB EntryLo0 */
 #define LOONGARCH_CSR_TLBELO1        0x13 /* TLB EntryLo1 */
@@ -164,7 +165,8 @@  FIELD(CSR_TLBRERA, PC, 2, 62)
 #define LOONGARCH_CSR_TLBRELO1       0x8d /* TLB refill entrylo1 */
 #define LOONGARCH_CSR_TLBREHI        0x8e /* TLB refill entryhi */
 FIELD(CSR_TLBREHI, PS, 0, 6)
-FIELD(CSR_TLBREHI, VPPN, 13, 35)
+FIELD(CSR_TLBREHI_32, VPPN, 13, 35)
+FIELD(CSR_TLBREHI_64, VPPN, 13, 19)
 #define LOONGARCH_CSR_TLBRPRMD       0x8f /* TLB refill mode info */
 FIELD(CSR_TLBRPRMD, PPLV, 0, 2)
 FIELD(CSR_TLBRPRMD, PIE, 2, 1)
diff --git a/target/loongarch/tlb_helper.c b/target/loongarch/tlb_helper.c
index cf6f5863f9..7926c40252 100644
--- a/target/loongarch/tlb_helper.c
+++ b/target/loongarch/tlb_helper.c
@@ -305,8 +305,13 @@  static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
 
     if (tlb_error == TLBRET_NOMATCH) {
         env->CSR_TLBRBADV = address;
-        env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN,
-                                      extract64(address, 13, 35));
+        if (env->mode == LA64) {
+            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64,
+                                        VPPN, extract64(address, 13, 35));
+        } else {
+            env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32,
+                                        VPPN, extract64(address, 13, 19));
+        }
     } else {
         if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
             env->CSR_BADV = address;
@@ -371,12 +376,20 @@  static void fill_tlb_entry(CPULoongArchState *env, int index)
 
     if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
         csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS);
-        csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, VPPN);
+        if (env->mode == LA64) {
+            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN);
+        } else {
+            csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN);
+        }
         lo0 = env->CSR_TLBRELO0;
         lo1 = env->CSR_TLBRELO1;
     } else {
         csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
-        csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI, VPPN);
+        if (env->mode == LA64) {
+            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN);
+        } else {
+            csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN);
+        }
         lo0 = env->CSR_TLBELO0;
         lo1 = env->CSR_TLBELO1;
     }
@@ -496,7 +509,7 @@  void helper_tlbfill(CPULoongArchState *env)
 
     if (pagesize == stlb_ps) {
         /* Only write into STLB bits [47:13] */
-        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_VPPN_SHIFT);
+        address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
 
         /* Choose one set ramdomly */
         set = get_random_tlb(0, 7);