Skip to content

Commit 81f5d15

Browse files
committed
LoongArch: Add adaptive CSR accessors for 32BIT/64BIT
32BIT platforms only have 32bit CSR/IOCSR registers, 64BIT platforms have both 32bit/64bit CSR/IOCSR registers. Now there are both 32bit and 64bit CSR accessors: csr_read32()/csr_write32()/csr_xchg32(); csr_read64()/csr_write64()/csr_xchg64(); Some CSR registers (address and timer registers) are 32bit length on 32BIT platform and 64bit length on 64BIT platform. To avoid #ifdefs here and there, they need adaptive accessors, so we define and use: csr_read()/csr_write()/csr_xchg(); IOCSR doesn't have a "natural length", which means a 64bit register can be treated as two 32bit registers, so we just use two 32bit accessors to emulate a 64bit accessors. Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 79974cc commit 81f5d15

10 files changed

Lines changed: 81 additions & 59 deletions

File tree

arch/loongarch/include/asm/loongarch.h

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@
182182
#define csr_xchg32(val, mask, reg) __csrxchg_w(val, mask, reg)
183183
#define csr_xchg64(val, mask, reg) __csrxchg_d(val, mask, reg)
184184

185+
#ifdef CONFIG_32BIT
186+
#define csr_read(reg) csr_read32(reg)
187+
#define csr_write(val, reg) csr_write32(val, reg)
188+
#define csr_xchg(val, mask, reg) csr_xchg32(val, mask, reg)
189+
#else
190+
#define csr_read(reg) csr_read64(reg)
191+
#define csr_write(val, reg) csr_write64(val, reg)
192+
#define csr_xchg(val, mask, reg) csr_xchg64(val, mask, reg)
193+
#endif
194+
185195
/* IOCSR */
186196
#define iocsr_read32(reg) __iocsrrd_w(reg)
187197
#define iocsr_read64(reg) __iocsrrd_d(reg)
@@ -1223,6 +1233,7 @@ static inline unsigned int get_csr_cpuid(void)
12231233
return csr_read32(LOONGARCH_CSR_CPUID);
12241234
}
12251235

1236+
#ifdef CONFIG_64BIT
12261237
static inline void csr_any_send(unsigned int addr, unsigned int data,
12271238
unsigned int data_mask, unsigned int cpu)
12281239
{
@@ -1234,6 +1245,7 @@ static inline void csr_any_send(unsigned int addr, unsigned int data,
12341245
val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
12351246
iocsr_write64(val, LOONGARCH_IOCSR_ANY_SEND);
12361247
}
1248+
#endif
12371249

12381250
static inline unsigned int read_csr_excode(void)
12391251
{
@@ -1257,22 +1269,22 @@ static inline void write_csr_pagesize(unsigned int size)
12571269

12581270
static inline unsigned int read_csr_tlbrefill_pagesize(void)
12591271
{
1260-
return (csr_read64(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT;
1272+
return (csr_read(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT;
12611273
}
12621274

12631275
static inline void write_csr_tlbrefill_pagesize(unsigned int size)
12641276
{
1265-
csr_xchg64(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI);
1277+
csr_xchg(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI);
12661278
}
12671279

12681280
#define read_csr_asid() csr_read32(LOONGARCH_CSR_ASID)
12691281
#define write_csr_asid(val) csr_write32(val, LOONGARCH_CSR_ASID)
1270-
#define read_csr_entryhi() csr_read64(LOONGARCH_CSR_TLBEHI)
1271-
#define write_csr_entryhi(val) csr_write64(val, LOONGARCH_CSR_TLBEHI)
1272-
#define read_csr_entrylo0() csr_read64(LOONGARCH_CSR_TLBELO0)
1273-
#define write_csr_entrylo0(val) csr_write64(val, LOONGARCH_CSR_TLBELO0)
1274-
#define read_csr_entrylo1() csr_read64(LOONGARCH_CSR_TLBELO1)
1275-
#define write_csr_entrylo1(val) csr_write64(val, LOONGARCH_CSR_TLBELO1)
1282+
#define read_csr_entryhi() csr_read(LOONGARCH_CSR_TLBEHI)
1283+
#define write_csr_entryhi(val) csr_write(val, LOONGARCH_CSR_TLBEHI)
1284+
#define read_csr_entrylo0() csr_read(LOONGARCH_CSR_TLBELO0)
1285+
#define write_csr_entrylo0(val) csr_write(val, LOONGARCH_CSR_TLBELO0)
1286+
#define read_csr_entrylo1() csr_read(LOONGARCH_CSR_TLBELO1)
1287+
#define write_csr_entrylo1(val) csr_write(val, LOONGARCH_CSR_TLBELO1)
12761288
#define read_csr_ecfg() csr_read32(LOONGARCH_CSR_ECFG)
12771289
#define write_csr_ecfg(val) csr_write32(val, LOONGARCH_CSR_ECFG)
12781290
#define read_csr_estat() csr_read32(LOONGARCH_CSR_ESTAT)
@@ -1282,20 +1294,20 @@ static inline void write_csr_tlbrefill_pagesize(unsigned int size)
12821294
#define read_csr_euen() csr_read32(LOONGARCH_CSR_EUEN)
12831295
#define write_csr_euen(val) csr_write32(val, LOONGARCH_CSR_EUEN)
12841296
#define read_csr_cpuid() csr_read32(LOONGARCH_CSR_CPUID)
1285-
#define read_csr_prcfg1() csr_read64(LOONGARCH_CSR_PRCFG1)
1286-
#define write_csr_prcfg1(val) csr_write64(val, LOONGARCH_CSR_PRCFG1)
1287-
#define read_csr_prcfg2() csr_read64(LOONGARCH_CSR_PRCFG2)
1288-
#define write_csr_prcfg2(val) csr_write64(val, LOONGARCH_CSR_PRCFG2)
1289-
#define read_csr_prcfg3() csr_read64(LOONGARCH_CSR_PRCFG3)
1290-
#define write_csr_prcfg3(val) csr_write64(val, LOONGARCH_CSR_PRCFG3)
1297+
#define read_csr_prcfg1() csr_read(LOONGARCH_CSR_PRCFG1)
1298+
#define write_csr_prcfg1(val) csr_write(val, LOONGARCH_CSR_PRCFG1)
1299+
#define read_csr_prcfg2() csr_read(LOONGARCH_CSR_PRCFG2)
1300+
#define write_csr_prcfg2(val) csr_write(val, LOONGARCH_CSR_PRCFG2)
1301+
#define read_csr_prcfg3() csr_read(LOONGARCH_CSR_PRCFG3)
1302+
#define write_csr_prcfg3(val) csr_write(val, LOONGARCH_CSR_PRCFG3)
12911303
#define read_csr_stlbpgsize() csr_read32(LOONGARCH_CSR_STLBPGSIZE)
12921304
#define write_csr_stlbpgsize(val) csr_write32(val, LOONGARCH_CSR_STLBPGSIZE)
12931305
#define read_csr_rvacfg() csr_read32(LOONGARCH_CSR_RVACFG)
12941306
#define write_csr_rvacfg(val) csr_write32(val, LOONGARCH_CSR_RVACFG)
12951307
#define write_csr_tintclear(val) csr_write32(val, LOONGARCH_CSR_TINTCLR)
1296-
#define read_csr_impctl1() csr_read64(LOONGARCH_CSR_IMPCTL1)
1297-
#define write_csr_impctl1(val) csr_write64(val, LOONGARCH_CSR_IMPCTL1)
1298-
#define write_csr_impctl2(val) csr_write64(val, LOONGARCH_CSR_IMPCTL2)
1308+
#define read_csr_impctl1() csr_read(LOONGARCH_CSR_IMPCTL1)
1309+
#define write_csr_impctl1(val) csr_write(val, LOONGARCH_CSR_IMPCTL1)
1310+
#define write_csr_impctl2(val) csr_write(val, LOONGARCH_CSR_IMPCTL2)
12991311

13001312
#define read_csr_perfctrl0() csr_read64(LOONGARCH_CSR_PERFCTRL0)
13011313
#define read_csr_perfcntr0() csr_read64(LOONGARCH_CSR_PERFCNTR0)

arch/loongarch/include/asm/percpu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ register unsigned long __my_cpu_offset __asm__("$r21");
2727
static inline void set_my_cpu_offset(unsigned long off)
2828
{
2929
__my_cpu_offset = off;
30-
csr_write64(off, PERCPU_BASE_KS);
30+
csr_write(off, PERCPU_BASE_KS);
3131
}
3232

3333
#define __my_cpu_offset \

arch/loongarch/kernel/cpu-probe.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,15 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
298298
return;
299299
}
300300

301+
#ifdef CONFIG_64BIT
301302
*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
302303
*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
304+
#else
305+
*vendor = iocsr_read32(LOONGARCH_IOCSR_VENDOR) |
306+
(u64)iocsr_read32(LOONGARCH_IOCSR_VENDOR + 4) << 32;
307+
*cpuname = iocsr_read32(LOONGARCH_IOCSR_CPUNAME) |
308+
(u64)iocsr_read32(LOONGARCH_IOCSR_CPUNAME + 4) << 32;
309+
#endif
303310

304311
if (!__cpu_full_name[cpu]) {
305312
if (((char *)vendor)[0] == 0)

arch/loongarch/kernel/time.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
5050

5151
raw_spin_lock(&state_lock);
5252

53-
timer_config = csr_read64(LOONGARCH_CSR_TCFG);
53+
timer_config = csr_read(LOONGARCH_CSR_TCFG);
5454
timer_config |= CSR_TCFG_EN;
5555
timer_config &= ~CSR_TCFG_PERIOD;
56-
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
56+
csr_write(timer_config, LOONGARCH_CSR_TCFG);
5757

5858
raw_spin_unlock(&state_lock);
5959

@@ -70,7 +70,7 @@ static int constant_set_state_periodic(struct clock_event_device *evt)
7070
period = const_clock_freq / HZ;
7171
timer_config = period & CSR_TCFG_VAL;
7272
timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
73-
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
73+
csr_write(timer_config, LOONGARCH_CSR_TCFG);
7474

7575
raw_spin_unlock(&state_lock);
7676

@@ -83,9 +83,9 @@ static int constant_set_state_shutdown(struct clock_event_device *evt)
8383

8484
raw_spin_lock(&state_lock);
8585

86-
timer_config = csr_read64(LOONGARCH_CSR_TCFG);
86+
timer_config = csr_read(LOONGARCH_CSR_TCFG);
8787
timer_config &= ~CSR_TCFG_EN;
88-
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
88+
csr_write(timer_config, LOONGARCH_CSR_TCFG);
8989

9090
raw_spin_unlock(&state_lock);
9191

@@ -98,7 +98,7 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev
9898

9999
delta &= CSR_TCFG_VAL;
100100
timer_config = delta | CSR_TCFG_EN;
101-
csr_write64(timer_config, LOONGARCH_CSR_TCFG);
101+
csr_write(timer_config, LOONGARCH_CSR_TCFG);
102102

103103
return 0;
104104
}
@@ -137,7 +137,7 @@ void save_counter(void)
137137
void sync_counter(void)
138138
{
139139
/* Ensure counter begin at 0 */
140-
csr_write64(init_offset, LOONGARCH_CSR_CNTC);
140+
csr_write(init_offset, LOONGARCH_CSR_CNTC);
141141
}
142142

143143
int constant_clockevent_init(void)
@@ -235,7 +235,7 @@ void __init time_init(void)
235235
else
236236
const_clock_freq = calc_const_freq();
237237

238-
init_offset = -(drdtime() - csr_read64(LOONGARCH_CSR_CNTC));
238+
init_offset = -(drdtime() - csr_read(LOONGARCH_CSR_CNTC));
239239

240240
constant_clockevent_init();
241241
constant_clocksource_init();

arch/loongarch/kernel/traps.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs)
625625
bool user = user_mode(regs);
626626
bool pie = regs_irqs_disabled(regs);
627627
unsigned long era = exception_era(regs);
628-
u64 badv = 0, lower = 0, upper = ULONG_MAX;
628+
unsigned long badv = 0, lower = 0, upper = ULONG_MAX;
629629
union loongarch_instruction insn;
630630
irqentry_state_t state = irqentry_enter(regs);
631631

@@ -1070,10 +1070,13 @@ asmlinkage void noinstr do_reserved(struct pt_regs *regs)
10701070

10711071
asmlinkage void cache_parity_error(void)
10721072
{
1073+
u32 merrctl = csr_read32(LOONGARCH_CSR_MERRCTL);
1074+
unsigned long merrera = csr_read(LOONGARCH_CSR_MERRERA);
1075+
10731076
/* For the moment, report the problem and hang. */
10741077
pr_err("Cache error exception:\n");
1075-
pr_err("csr_merrctl == %08x\n", csr_read32(LOONGARCH_CSR_MERRCTL));
1076-
pr_err("csr_merrera == %016lx\n", csr_read64(LOONGARCH_CSR_MERRERA));
1078+
pr_err("csr_merrctl == %08x\n", merrctl);
1079+
pr_err("csr_merrera == %016lx\n", merrera);
10771080
panic("Can't handle the cache error!");
10781081
}
10791082

@@ -1130,9 +1133,9 @@ static void configure_exception_vector(void)
11301133
eentry = (unsigned long)exception_handlers;
11311134
tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE;
11321135

1133-
csr_write64(eentry, LOONGARCH_CSR_EENTRY);
1134-
csr_write64(__pa(eentry), LOONGARCH_CSR_MERRENTRY);
1135-
csr_write64(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY);
1136+
csr_write(eentry, LOONGARCH_CSR_EENTRY);
1137+
csr_write(__pa(eentry), LOONGARCH_CSR_MERRENTRY);
1138+
csr_write(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY);
11361139
}
11371140

11381141
void per_cpu_trap_init(int cpu)

arch/loongarch/lib/dump_tlb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ void dump_tlb_regs(void)
2020

2121
pr_info("Index : 0x%0x\n", read_csr_tlbidx());
2222
pr_info("PageSize : 0x%0x\n", read_csr_pagesize());
23-
pr_info("EntryHi : 0x%0*lx\n", field, read_csr_entryhi());
24-
pr_info("EntryLo0 : 0x%0*lx\n", field, read_csr_entrylo0());
25-
pr_info("EntryLo1 : 0x%0*lx\n", field, read_csr_entrylo1());
23+
pr_info("EntryHi : 0x%0*lx\n", field, (unsigned long)read_csr_entryhi());
24+
pr_info("EntryLo0 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo0());
25+
pr_info("EntryLo1 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo1());
2626
}
2727

2828
static void dump_tlb(int first, int last)

arch/loongarch/mm/tlb.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,11 @@ static void setup_ptwalker(void)
229229
if (cpu_has_ptw)
230230
pwctl1 |= CSR_PWCTL1_PTW;
231231

232-
csr_write64(pwctl0, LOONGARCH_CSR_PWCTL0);
233-
csr_write64(pwctl1, LOONGARCH_CSR_PWCTL1);
234-
csr_write64((long)swapper_pg_dir, LOONGARCH_CSR_PGDH);
235-
csr_write64((long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
236-
csr_write64((long)smp_processor_id(), LOONGARCH_CSR_TMID);
232+
csr_write(pwctl0, LOONGARCH_CSR_PWCTL0);
233+
csr_write(pwctl1, LOONGARCH_CSR_PWCTL1);
234+
csr_write((long)swapper_pg_dir, LOONGARCH_CSR_PGDH);
235+
csr_write((long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
236+
csr_write((long)smp_processor_id(), LOONGARCH_CSR_TMID);
237237
}
238238

239239
static void output_pgtable_bits_defines(void)

arch/loongarch/power/hibernate.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ static u32 saved_crmd;
1010
static u32 saved_prmd;
1111
static u32 saved_euen;
1212
static u32 saved_ecfg;
13-
static u64 saved_pcpu_base;
13+
static unsigned long saved_pcpu_base;
1414
struct pt_regs saved_regs;
1515

1616
void save_processor_state(void)
@@ -20,7 +20,7 @@ void save_processor_state(void)
2020
saved_prmd = csr_read32(LOONGARCH_CSR_PRMD);
2121
saved_euen = csr_read32(LOONGARCH_CSR_EUEN);
2222
saved_ecfg = csr_read32(LOONGARCH_CSR_ECFG);
23-
saved_pcpu_base = csr_read64(PERCPU_BASE_KS);
23+
saved_pcpu_base = csr_read(PERCPU_BASE_KS);
2424

2525
if (is_fpu_owner())
2626
save_fp(current);
@@ -33,7 +33,7 @@ void restore_processor_state(void)
3333
csr_write32(saved_prmd, LOONGARCH_CSR_PRMD);
3434
csr_write32(saved_euen, LOONGARCH_CSR_EUEN);
3535
csr_write32(saved_ecfg, LOONGARCH_CSR_ECFG);
36-
csr_write64(saved_pcpu_base, PERCPU_BASE_KS);
36+
csr_write(saved_pcpu_base, PERCPU_BASE_KS);
3737

3838
if (is_fpu_owner())
3939
restore_fp(current);

arch/loongarch/power/suspend.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,24 @@ u64 loongarch_suspend_addr;
2020
struct saved_registers {
2121
u32 ecfg;
2222
u32 euen;
23-
u64 pgd;
24-
u64 kpgd;
2523
u32 pwctl0;
2624
u32 pwctl1;
27-
u64 pcpu_base;
25+
unsigned long pgd;
26+
unsigned long kpgd;
27+
unsigned long pcpu_base;
2828
};
2929
static struct saved_registers saved_regs;
3030

3131
void loongarch_common_suspend(void)
3232
{
3333
save_counter();
34-
saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL);
35-
saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH);
34+
saved_regs.pgd = csr_read(LOONGARCH_CSR_PGDL);
35+
saved_regs.kpgd = csr_read(LOONGARCH_CSR_PGDH);
3636
saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0);
3737
saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1);
3838
saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG);
3939
saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN);
40-
saved_regs.pcpu_base = csr_read64(PERCPU_BASE_KS);
40+
saved_regs.pcpu_base = csr_read(PERCPU_BASE_KS);
4141

4242
loongarch_suspend_addr = loongson_sysconf.suspend_addr;
4343
}
@@ -46,17 +46,17 @@ void loongarch_common_resume(void)
4646
{
4747
sync_counter();
4848
local_flush_tlb_all();
49-
csr_write64(eentry, LOONGARCH_CSR_EENTRY);
50-
csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
51-
csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
49+
csr_write(eentry, LOONGARCH_CSR_EENTRY);
50+
csr_write(eentry, LOONGARCH_CSR_MERRENTRY);
51+
csr_write(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
5252

53-
csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL);
54-
csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH);
53+
csr_write(saved_regs.pgd, LOONGARCH_CSR_PGDL);
54+
csr_write(saved_regs.kpgd, LOONGARCH_CSR_PGDH);
5555
csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0);
5656
csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1);
5757
csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG);
5858
csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN);
59-
csr_write64(saved_regs.pcpu_base, PERCPU_BASE_KS);
59+
csr_write(saved_regs.pcpu_base, PERCPU_BASE_KS);
6060
}
6161

6262
int loongarch_acpi_suspend(void)

drivers/firmware/efi/libstub/loongarch.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
7272
desc_ver, priv.runtime_map);
7373

7474
/* Config Direct Mapping */
75-
csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
76-
csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
77-
csr_write64(CSR_DMW2_INIT, LOONGARCH_CSR_DMWIN2);
78-
csr_write64(CSR_DMW3_INIT, LOONGARCH_CSR_DMWIN3);
75+
csr_write(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
76+
csr_write(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
77+
csr_write(CSR_DMW2_INIT, LOONGARCH_CSR_DMWIN2);
78+
csr_write(CSR_DMW3_INIT, LOONGARCH_CSR_DMWIN3);
7979

8080
real_kernel_entry = (void *)kernel_entry_address(kernel_addr, image);
8181

0 commit comments

Comments
 (0)