1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4 */
5 #ifndef __ASM_CPU_INFO_H
6 #define __ASM_CPU_INFO_H
7
8 #include <linux/cache.h>
9 #include <linux/types.h>
10
11 #include <asm/loongarch.h>
12
13 /*
14 * Descriptor for a cache
15 */
16 struct cache_desc {
17 unsigned int waysize; /* Bytes per way */
18 unsigned short sets; /* Number of lines per set */
19 unsigned char ways; /* Number of ways */
20 unsigned char linesz; /* Size of line in bytes */
21 unsigned char waybit; /* Bits to select in a cache set */
22 unsigned char flags; /* Flags describing cache properties */
23 };
24
25 struct cpuinfo_loongarch {
26 u64 asid_cache;
27 unsigned long asid_mask;
28
29 /*
30 * Capability and feature descriptor structure for LoongArch CPU
31 */
32 unsigned long long options;
33 unsigned int processor_id;
34 unsigned int fpu_vers;
35 unsigned int fpu_csr0;
36 unsigned int fpu_mask;
37 unsigned int cputype;
38 int isa_level;
39 int tlbsize;
40 int tlbsizemtlb;
41 int tlbsizestlbsets;
42 int tlbsizestlbways;
43 struct cache_desc icache; /* Primary I-cache */
44 struct cache_desc dcache; /* Primary D or combined I/D cache */
45 struct cache_desc vcache; /* Victim cache, between pcache and scache */
46 struct cache_desc scache; /* Secondary cache */
47 struct cache_desc tcache; /* Tertiary/split secondary cache */
48 int core; /* physical core number in package */
49 int package;/* physical package number */
50 int vabits; /* Virtual Address size in bits */
51 int pabits; /* Physical Address size in bits */
52 unsigned int ksave_mask; /* Usable KSave mask. */
53 unsigned int watch_dreg_count; /* Number data breakpoints */
54 unsigned int watch_ireg_count; /* Number instruction breakpoints */
55 unsigned int watch_reg_use_cnt; /* min(NUM_WATCH_REGS, watch_dreg_count + watch_ireg_count), Usable by ptrace */
56 } __aligned(SMP_CACHE_BYTES);
57
58 extern struct cpuinfo_loongarch cpu_data[];
59 #define boot_cpu_data cpu_data[0]
60 #define current_cpu_data cpu_data[smp_processor_id()]
61 #define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
62
63 extern void cpu_probe(void);
64
65 extern const char *__cpu_family[];
66 extern const char *__cpu_full_name[];
67 #define cpu_family_string() __cpu_family[raw_smp_processor_id()]
68 #define cpu_full_name_string() __cpu_full_name[raw_smp_processor_id()]
69
70 struct seq_file;
71 struct notifier_block;
72
73 extern int register_proc_cpuinfo_notifier(struct notifier_block *nb);
74 extern int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v);
75
76 #define proc_cpuinfo_notifier(fn, pri) \
77 ({ \
78 static struct notifier_block fn##_nb = { \
79 .notifier_call = fn, \
80 .priority = pri \
81 }; \
82 \
83 register_proc_cpuinfo_notifier(&fn##_nb); \
84 })
85
86 struct proc_cpuinfo_notifier_args {
87 struct seq_file *m;
88 unsigned long n;
89 };
90
cpus_are_siblings(int cpua,int cpub)91 static inline bool cpus_are_siblings(int cpua, int cpub)
92 {
93 struct cpuinfo_loongarch *infoa = &cpu_data[cpua];
94 struct cpuinfo_loongarch *infob = &cpu_data[cpub];
95
96 if (infoa->package != infob->package)
97 return false;
98
99 if (infoa->core != infob->core)
100 return false;
101
102 return true;
103 }
104
cpu_asid_mask(struct cpuinfo_loongarch * cpuinfo)105 static inline unsigned long cpu_asid_mask(struct cpuinfo_loongarch *cpuinfo)
106 {
107 return cpuinfo->asid_mask;
108 }
109
set_cpu_asid_mask(struct cpuinfo_loongarch * cpuinfo,unsigned long asid_mask)110 static inline void set_cpu_asid_mask(struct cpuinfo_loongarch *cpuinfo,
111 unsigned long asid_mask)
112 {
113 cpuinfo->asid_mask = asid_mask;
114 }
115
116 #endif /* __ASM_CPU_INFO_H */
117