-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LoongArch: Add CPU definition headers
Add common headers (CPU definition and address space layout) for basic LoongArch support. Reviewed-by: WANG Xuerui <git@xen0n.name> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
- Loading branch information
Huacai Chen
committed
Jun 3, 2022
1 parent
fa96b57
commit f2ac457
Showing
8 changed files
with
2,191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited | ||
* | ||
* Derived from MIPS: | ||
* Copyright (C) 1996, 99 Ralf Baechle | ||
* Copyright (C) 2000, 2002 Maciej W. Rozycki | ||
* Copyright (C) 1990, 1999 by Silicon Graphics, Inc. | ||
*/ | ||
#ifndef _ASM_ADDRSPACE_H | ||
#define _ASM_ADDRSPACE_H | ||
|
||
#include <linux/const.h> | ||
|
||
#include <asm/loongarch.h> | ||
|
||
/* | ||
* This gives the physical RAM offset. | ||
*/ | ||
#ifndef __ASSEMBLY__ | ||
#ifndef PHYS_OFFSET | ||
#define PHYS_OFFSET _AC(0, UL) | ||
#endif | ||
extern unsigned long vm_map_base; | ||
#endif /* __ASSEMBLY__ */ | ||
|
||
#ifndef IO_BASE | ||
#define IO_BASE CSR_DMW0_BASE | ||
#endif | ||
|
||
#ifndef CACHE_BASE | ||
#define CACHE_BASE CSR_DMW1_BASE | ||
#endif | ||
|
||
#ifndef UNCACHE_BASE | ||
#define UNCACHE_BASE CSR_DMW0_BASE | ||
#endif | ||
|
||
#define DMW_PABITS 48 | ||
#define TO_PHYS_MASK ((1ULL << DMW_PABITS) - 1) | ||
|
||
/* | ||
* Memory above this physical address will be considered highmem. | ||
*/ | ||
#ifndef HIGHMEM_START | ||
#define HIGHMEM_START (_AC(1, UL) << _AC(DMW_PABITS, UL)) | ||
#endif | ||
|
||
#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK)) | ||
#define TO_CACHE(x) (CACHE_BASE | ((x) & TO_PHYS_MASK)) | ||
#define TO_UNCACHE(x) (UNCACHE_BASE | ((x) & TO_PHYS_MASK)) | ||
|
||
/* | ||
* This handles the memory map. | ||
*/ | ||
#ifndef PAGE_OFFSET | ||
#define PAGE_OFFSET (CACHE_BASE + PHYS_OFFSET) | ||
#endif | ||
|
||
#ifndef FIXADDR_TOP | ||
#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) | ||
#endif | ||
|
||
#ifdef __ASSEMBLY__ | ||
#define _ATYPE_ | ||
#define _ATYPE32_ | ||
#define _ATYPE64_ | ||
#define _CONST64_(x) x | ||
#else | ||
#define _ATYPE_ __PTRDIFF_TYPE__ | ||
#define _ATYPE32_ int | ||
#define _ATYPE64_ __s64 | ||
#ifdef CONFIG_64BIT | ||
#define _CONST64_(x) x ## L | ||
#else | ||
#define _CONST64_(x) x ## LL | ||
#endif | ||
#endif | ||
|
||
/* | ||
* 32/64-bit LoongArch address spaces | ||
*/ | ||
#ifdef __ASSEMBLY__ | ||
#define _ACAST32_ | ||
#define _ACAST64_ | ||
#else | ||
#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ | ||
#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ | ||
#endif | ||
|
||
#ifdef CONFIG_32BIT | ||
|
||
#define UVRANGE 0x00000000 | ||
#define KPRANGE0 0x80000000 | ||
#define KPRANGE1 0xa0000000 | ||
#define KVRANGE 0xc0000000 | ||
|
||
#else | ||
|
||
#define XUVRANGE _CONST64_(0x0000000000000000) | ||
#define XSPRANGE _CONST64_(0x4000000000000000) | ||
#define XKPRANGE _CONST64_(0x8000000000000000) | ||
#define XKVRANGE _CONST64_(0xc000000000000000) | ||
|
||
#endif | ||
|
||
/* | ||
* Returns the physical address of a KPRANGEx / XKPRANGE address | ||
*/ | ||
#define PHYSADDR(a) ((_ACAST64_(a)) & TO_PHYS_MASK) | ||
|
||
#endif /* _ASM_ADDRSPACE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited | ||
* | ||
* Derived from MIPS: | ||
* Copyright (C) 2003, 2004 Ralf Baechle | ||
* Copyright (C) 2004 Maciej W. Rozycki | ||
*/ | ||
#ifndef __ASM_CPU_FEATURES_H | ||
#define __ASM_CPU_FEATURES_H | ||
|
||
#include <asm/cpu.h> | ||
#include <asm/cpu-info.h> | ||
|
||
#define cpu_opt(opt) (cpu_data[0].options & (opt)) | ||
#define cpu_has(feat) (cpu_data[0].options & BIT_ULL(feat)) | ||
|
||
#define cpu_has_loongarch (cpu_has_loongarch32 | cpu_has_loongarch64) | ||
#define cpu_has_loongarch32 (cpu_data[0].isa_level & LOONGARCH_CPU_ISA_32BIT) | ||
#define cpu_has_loongarch64 (cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT) | ||
|
||
#define cpu_icache_line_size() cpu_data[0].icache.linesz | ||
#define cpu_dcache_line_size() cpu_data[0].dcache.linesz | ||
#define cpu_vcache_line_size() cpu_data[0].vcache.linesz | ||
#define cpu_scache_line_size() cpu_data[0].scache.linesz | ||
|
||
#ifdef CONFIG_32BIT | ||
# define cpu_has_64bits (cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT) | ||
# define cpu_vabits 31 | ||
# define cpu_pabits 31 | ||
#endif | ||
|
||
#ifdef CONFIG_64BIT | ||
# define cpu_has_64bits 1 | ||
# define cpu_vabits cpu_data[0].vabits | ||
# define cpu_pabits cpu_data[0].pabits | ||
# define __NEED_ADDRBITS_PROBE | ||
#endif | ||
|
||
/* | ||
* SMP assumption: Options of CPU 0 are a superset of all processors. | ||
* This is true for all known LoongArch systems. | ||
*/ | ||
#define cpu_has_cpucfg cpu_opt(LOONGARCH_CPU_CPUCFG) | ||
#define cpu_has_lam cpu_opt(LOONGARCH_CPU_LAM) | ||
#define cpu_has_ual cpu_opt(LOONGARCH_CPU_UAL) | ||
#define cpu_has_fpu cpu_opt(LOONGARCH_CPU_FPU) | ||
#define cpu_has_lsx cpu_opt(LOONGARCH_CPU_LSX) | ||
#define cpu_has_lasx cpu_opt(LOONGARCH_CPU_LASX) | ||
#define cpu_has_complex cpu_opt(LOONGARCH_CPU_COMPLEX) | ||
#define cpu_has_crypto cpu_opt(LOONGARCH_CPU_CRYPTO) | ||
#define cpu_has_lvz cpu_opt(LOONGARCH_CPU_LVZ) | ||
#define cpu_has_lbt_x86 cpu_opt(LOONGARCH_CPU_LBT_X86) | ||
#define cpu_has_lbt_arm cpu_opt(LOONGARCH_CPU_LBT_ARM) | ||
#define cpu_has_lbt_mips cpu_opt(LOONGARCH_CPU_LBT_MIPS) | ||
#define cpu_has_lbt (cpu_has_lbt_x86|cpu_has_lbt_arm|cpu_has_lbt_mips) | ||
#define cpu_has_csr cpu_opt(LOONGARCH_CPU_CSR) | ||
#define cpu_has_tlb cpu_opt(LOONGARCH_CPU_TLB) | ||
#define cpu_has_watch cpu_opt(LOONGARCH_CPU_WATCH) | ||
#define cpu_has_vint cpu_opt(LOONGARCH_CPU_VINT) | ||
#define cpu_has_csripi cpu_opt(LOONGARCH_CPU_CSRIPI) | ||
#define cpu_has_extioi cpu_opt(LOONGARCH_CPU_EXTIOI) | ||
#define cpu_has_prefetch cpu_opt(LOONGARCH_CPU_PREFETCH) | ||
#define cpu_has_pmp cpu_opt(LOONGARCH_CPU_PMP) | ||
#define cpu_has_perf cpu_opt(LOONGARCH_CPU_PMP) | ||
#define cpu_has_scalefreq cpu_opt(LOONGARCH_CPU_SCALEFREQ) | ||
#define cpu_has_flatmode cpu_opt(LOONGARCH_CPU_FLATMODE) | ||
#define cpu_has_eiodecode cpu_opt(LOONGARCH_CPU_EIODECODE) | ||
#define cpu_has_guestid cpu_opt(LOONGARCH_CPU_GUESTID) | ||
#define cpu_has_hypervisor cpu_opt(LOONGARCH_CPU_HYPERVISOR) | ||
|
||
|
||
#endif /* __ASM_CPU_FEATURES_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited | ||
*/ | ||
#ifndef __ASM_CPU_INFO_H | ||
#define __ASM_CPU_INFO_H | ||
|
||
#include <linux/cache.h> | ||
#include <linux/types.h> | ||
|
||
#include <asm/loongarch.h> | ||
|
||
/* | ||
* Descriptor for a cache | ||
*/ | ||
struct cache_desc { | ||
unsigned int waysize; /* Bytes per way */ | ||
unsigned short sets; /* Number of lines per set */ | ||
unsigned char ways; /* Number of ways */ | ||
unsigned char linesz; /* Size of line in bytes */ | ||
unsigned char waybit; /* Bits to select in a cache set */ | ||
unsigned char flags; /* Flags describing cache properties */ | ||
}; | ||
|
||
struct cpuinfo_loongarch { | ||
u64 asid_cache; | ||
unsigned long asid_mask; | ||
|
||
/* | ||
* Capability and feature descriptor structure for LoongArch CPU | ||
*/ | ||
unsigned long long options; | ||
unsigned int processor_id; | ||
unsigned int fpu_vers; | ||
unsigned int fpu_csr0; | ||
unsigned int fpu_mask; | ||
unsigned int cputype; | ||
int isa_level; | ||
int tlbsize; | ||
int tlbsizemtlb; | ||
int tlbsizestlbsets; | ||
int tlbsizestlbways; | ||
struct cache_desc icache; /* Primary I-cache */ | ||
struct cache_desc dcache; /* Primary D or combined I/D cache */ | ||
struct cache_desc vcache; /* Victim cache, between pcache and scache */ | ||
struct cache_desc scache; /* Secondary cache */ | ||
struct cache_desc tcache; /* Tertiary/split secondary cache */ | ||
int core; /* physical core number in package */ | ||
int package;/* physical package number */ | ||
int vabits; /* Virtual Address size in bits */ | ||
int pabits; /* Physical Address size in bits */ | ||
unsigned int ksave_mask; /* Usable KSave mask. */ | ||
unsigned int watch_dreg_count; /* Number data breakpoints */ | ||
unsigned int watch_ireg_count; /* Number instruction breakpoints */ | ||
unsigned int watch_reg_use_cnt; /* min(NUM_WATCH_REGS, watch_dreg_count + watch_ireg_count), Usable by ptrace */ | ||
} __aligned(SMP_CACHE_BYTES); | ||
|
||
extern struct cpuinfo_loongarch cpu_data[]; | ||
#define boot_cpu_data cpu_data[0] | ||
#define current_cpu_data cpu_data[smp_processor_id()] | ||
#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] | ||
|
||
extern void cpu_probe(void); | ||
|
||
extern const char *__cpu_family[]; | ||
extern const char *__cpu_full_name[]; | ||
#define cpu_family_string() __cpu_family[raw_smp_processor_id()] | ||
#define cpu_full_name_string() __cpu_full_name[raw_smp_processor_id()] | ||
|
||
struct seq_file; | ||
struct notifier_block; | ||
|
||
extern int register_proc_cpuinfo_notifier(struct notifier_block *nb); | ||
extern int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v); | ||
|
||
#define proc_cpuinfo_notifier(fn, pri) \ | ||
({ \ | ||
static struct notifier_block fn##_nb = { \ | ||
.notifier_call = fn, \ | ||
.priority = pri \ | ||
}; \ | ||
\ | ||
register_proc_cpuinfo_notifier(&fn##_nb); \ | ||
}) | ||
|
||
struct proc_cpuinfo_notifier_args { | ||
struct seq_file *m; | ||
unsigned long n; | ||
}; | ||
|
||
static inline bool cpus_are_siblings(int cpua, int cpub) | ||
{ | ||
struct cpuinfo_loongarch *infoa = &cpu_data[cpua]; | ||
struct cpuinfo_loongarch *infob = &cpu_data[cpub]; | ||
|
||
if (infoa->package != infob->package) | ||
return false; | ||
|
||
if (infoa->core != infob->core) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
static inline unsigned long cpu_asid_mask(struct cpuinfo_loongarch *cpuinfo) | ||
{ | ||
return cpuinfo->asid_mask; | ||
} | ||
|
||
static inline void set_cpu_asid_mask(struct cpuinfo_loongarch *cpuinfo, | ||
unsigned long asid_mask) | ||
{ | ||
cpuinfo->asid_mask = asid_mask; | ||
} | ||
|
||
#endif /* __ASM_CPU_INFO_H */ |
Oops, something went wrong.