1384740dcSRalf Baechle /*
2384740dcSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public
3384740dcSRalf Baechle * License. See the file "COPYING" in the main directory of this archive
4384740dcSRalf Baechle * for more details.
5384740dcSRalf Baechle *
6384740dcSRalf Baechle * Copyright (C) 1994 Waldorf GMBH
7384740dcSRalf Baechle * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
8384740dcSRalf Baechle * Copyright (C) 1996 Paul M. Antoine
9384740dcSRalf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
10384740dcSRalf Baechle * Copyright (C) 2004 Maciej W. Rozycki
11384740dcSRalf Baechle */
12384740dcSRalf Baechle #ifndef __ASM_CPU_INFO_H
13384740dcSRalf Baechle #define __ASM_CPU_INFO_H
14384740dcSRalf Baechle
15294d6274SRalf Baechle #include <linux/cache.h>
166aa3524cSDavid Daney #include <linux/types.h>
176aa3524cSDavid Daney
18856fbceeSPaul Burton #include <asm/mipsregs.h>
19856fbceeSPaul Burton
20384740dcSRalf Baechle /*
21384740dcSRalf Baechle * Descriptor for a cache
22384740dcSRalf Baechle */
23384740dcSRalf Baechle struct cache_desc {
24384740dcSRalf Baechle unsigned int waysize; /* Bytes per way */
25384740dcSRalf Baechle unsigned short sets; /* Number of lines per set */
26384740dcSRalf Baechle unsigned char ways; /* Number of ways */
27384740dcSRalf Baechle unsigned char linesz; /* Size of line in bytes */
28384740dcSRalf Baechle unsigned char waybit; /* Bits to select in a cache set */
29384740dcSRalf Baechle unsigned char flags; /* Flags describing cache properties */
30384740dcSRalf Baechle };
31384740dcSRalf Baechle
326ad816e7SJames Hogan struct guest_info {
336ad816e7SJames Hogan unsigned long ases;
346ad816e7SJames Hogan unsigned long ases_dyn;
356ad816e7SJames Hogan unsigned long long options;
366ad816e7SJames Hogan unsigned long long options_dyn;
37372582a6SJames Hogan int tlbsize;
386ad816e7SJames Hogan u8 conf;
396ad816e7SJames Hogan u8 kscratch_mask;
406ad816e7SJames Hogan };
416ad816e7SJames Hogan
42384740dcSRalf Baechle /*
43384740dcSRalf Baechle * Flag definitions
44384740dcSRalf Baechle */
45384740dcSRalf Baechle #define MIPS_CACHE_NOT_PRESENT 0x00000001
46384740dcSRalf Baechle #define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */
47384740dcSRalf Baechle #define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
48384740dcSRalf Baechle #define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
49384740dcSRalf Baechle #define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
50384740dcSRalf Baechle #define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
51384740dcSRalf Baechle
52384740dcSRalf Baechle struct cpuinfo_mips {
53ff4dd232SPaul Burton u64 asid_cache;
542db003a5SPaul Burton #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
552db003a5SPaul Burton unsigned long asid_mask;
562db003a5SPaul Burton #endif
57384740dcSRalf Baechle
58384740dcSRalf Baechle /*
59384740dcSRalf Baechle * Capability and feature descriptor structure for MIPS CPU
60384740dcSRalf Baechle */
61384740dcSRalf Baechle unsigned long ases;
6203a58777SMarkos Chandras unsigned long long options;
63e5eb925aSRalf Baechle unsigned int udelay_val;
64384740dcSRalf Baechle unsigned int processor_id;
65384740dcSRalf Baechle unsigned int fpu_id;
669b26616cSMaciej W. Rozycki unsigned int fpu_csr31;
679b26616cSMaciej W. Rozycki unsigned int fpu_msk31;
68a5e9a69eSPaul Burton unsigned int msa_id;
69384740dcSRalf Baechle unsigned int cputype;
70384740dcSRalf Baechle int isa_level;
71384740dcSRalf Baechle int tlbsize;
7275b5b5e0SLeonid Yegoshin int tlbsizevtlb;
7375b5b5e0SLeonid Yegoshin int tlbsizeftlbsets;
7475b5b5e0SLeonid Yegoshin int tlbsizeftlbways;
75384740dcSRalf Baechle struct cache_desc icache; /* Primary I-cache */
76384740dcSRalf Baechle struct cache_desc dcache; /* Primary D or combined I/D cache */
77b2edcfc8SHuacai Chen struct cache_desc vcache; /* Victim cache, between pcache and scache */
78384740dcSRalf Baechle struct cache_desc scache; /* Secondary cache */
79384740dcSRalf Baechle struct cache_desc tcache; /* Tertiary/split secondary cache */
80384740dcSRalf Baechle int srsets; /* Shadow register sets */
81bda4584cSHuacai Chen int package;/* physical package number */
82856fbceeSPaul Burton unsigned int globalnumber;
8391dfc423SGuenter Roeck #ifdef CONFIG_64BIT
8491dfc423SGuenter Roeck int vmbits; /* Virtual memory size in bits */
8591dfc423SGuenter Roeck #endif
86384740dcSRalf Baechle void *data; /* Additional data */
876aa3524cSDavid Daney unsigned int watch_reg_count; /* Number that exist */
886aa3524cSDavid Daney unsigned int watch_reg_use_cnt; /* Usable by ptrace */
896aa3524cSDavid Daney #define NUM_WATCH_REGS 4
906aa3524cSDavid Daney u16 watch_reg_masks[NUM_WATCH_REGS];
91e77c32feSDavid Daney unsigned int kscratch_mask; /* Usable KScratch mask. */
924f12b91dSMarkos Chandras /*
934f12b91dSMarkos Chandras * Cache Coherency attribute for write-combine memory writes.
944f12b91dSMarkos Chandras * (shifted by _CACHE_SHIFT)
954f12b91dSMarkos Chandras */
964f12b91dSMarkos Chandras unsigned int writecombine;
97ed4cbc81SMarkos Chandras /*
98ed4cbc81SMarkos Chandras * Simple counter to prevent enabling HTW in nested
99ed4cbc81SMarkos Chandras * htw_start/htw_stop calls
100ed4cbc81SMarkos Chandras */
101ed4cbc81SMarkos Chandras unsigned int htw_seq;
1026ad816e7SJames Hogan
1036ad816e7SJames Hogan /* VZ & Guest features */
1046ad816e7SJames Hogan struct guest_info guest;
1056ad816e7SJames Hogan unsigned int gtoffset_mask;
1066ad816e7SJames Hogan unsigned int guestid_mask;
107c992a4f6SJames Hogan unsigned int guestid_cache;
108ec7a9318SWANG Xuerui
109ec7a9318SWANG Xuerui #ifdef CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION
110ec7a9318SWANG Xuerui /* CPUCFG data for this CPU, synthesized at probe time.
111ec7a9318SWANG Xuerui *
112ec7a9318SWANG Xuerui * CPUCFG select 0 is PRId, 4 and above are unimplemented for now.
113ec7a9318SWANG Xuerui * So the only stored values are for CPUCFG selects 1-3 inclusive.
114ec7a9318SWANG Xuerui */
115ec7a9318SWANG Xuerui u32 loongson3_cpucfg_data[3];
116ec7a9318SWANG Xuerui #endif
117384740dcSRalf Baechle } __attribute__((aligned(SMP_CACHE_BYTES)));
118384740dcSRalf Baechle
119384740dcSRalf Baechle extern struct cpuinfo_mips cpu_data[];
120384740dcSRalf Baechle #define current_cpu_data cpu_data[smp_processor_id()]
121384740dcSRalf Baechle #define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
122c5f66596SRalf Baechle #define boot_cpu_data cpu_data[0]
123384740dcSRalf Baechle
124384740dcSRalf Baechle extern void cpu_probe(void);
125384740dcSRalf Baechle extern void cpu_report(void);
126384740dcSRalf Baechle
127384740dcSRalf Baechle extern const char *__cpu_name[];
128e95008a1SJames Hogan #define cpu_name_string() __cpu_name[raw_smp_processor_id()]
129384740dcSRalf Baechle
130d6d3c9afSRalf Baechle struct seq_file;
131d6d3c9afSRalf Baechle struct notifier_block;
132d6d3c9afSRalf Baechle
133d6d3c9afSRalf Baechle extern int register_proc_cpuinfo_notifier(struct notifier_block *nb);
134d6d3c9afSRalf Baechle extern int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v);
135d6d3c9afSRalf Baechle
136d6d3c9afSRalf Baechle #define proc_cpuinfo_notifier(fn, pri) \
137d6d3c9afSRalf Baechle ({ \
138d6d3c9afSRalf Baechle static struct notifier_block fn##_nb = { \
139d6d3c9afSRalf Baechle .notifier_call = fn, \
140d6d3c9afSRalf Baechle .priority = pri \
141d6d3c9afSRalf Baechle }; \
142d6d3c9afSRalf Baechle \
143d6d3c9afSRalf Baechle register_proc_cpuinfo_notifier(&fn##_nb); \
144d6d3c9afSRalf Baechle })
145d6d3c9afSRalf Baechle
146d6d3c9afSRalf Baechle struct proc_cpuinfo_notifier_args {
147d6d3c9afSRalf Baechle struct seq_file *m;
148d6d3c9afSRalf Baechle unsigned long n;
149d6d3c9afSRalf Baechle };
150d6d3c9afSRalf Baechle
cpu_cluster(struct cpuinfo_mips * cpuinfo)1515616897eSPaul Burton static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo)
1525616897eSPaul Burton {
1535616897eSPaul Burton /* Optimisation for systems where multiple clusters aren't used */
154ab7c01fdSSerge Semin if (!IS_ENABLED(CONFIG_CPU_MIPSR5) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
1555616897eSPaul Burton return 0;
1565616897eSPaul Burton
1575616897eSPaul Burton return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >>
1585616897eSPaul Burton MIPS_GLOBALNUMBER_CLUSTER_SHF;
1595616897eSPaul Burton }
1605616897eSPaul Burton
cpu_core(struct cpuinfo_mips * cpuinfo)161f875a832SPaul Burton static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
162f875a832SPaul Burton {
163856fbceeSPaul Burton return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
164856fbceeSPaul Burton MIPS_GLOBALNUMBER_CORE_SHF;
165f875a832SPaul Burton }
166f875a832SPaul Burton
cpu_vpe_id(struct cpuinfo_mips * cpuinfo)167f875a832SPaul Burton static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
168f875a832SPaul Burton {
169856fbceeSPaul Burton /* Optimisation for systems where VP(E)s aren't used */
170856fbceeSPaul Burton if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
171f875a832SPaul Burton return 0;
172856fbceeSPaul Burton
173856fbceeSPaul Burton return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
174856fbceeSPaul Burton MIPS_GLOBALNUMBER_VP_SHF;
175f875a832SPaul Burton }
176f875a832SPaul Burton
1775616897eSPaul Burton extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster);
178856fbceeSPaul Burton extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
179856fbceeSPaul Burton extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
180b86c2247SPaul Burton
cpus_are_siblings(int cpua,int cpub)181fe7a38c6SPaul Burton static inline bool cpus_are_siblings(int cpua, int cpub)
182fe7a38c6SPaul Burton {
183fe7a38c6SPaul Burton struct cpuinfo_mips *infoa = &cpu_data[cpua];
184fe7a38c6SPaul Burton struct cpuinfo_mips *infob = &cpu_data[cpub];
185fe7a38c6SPaul Burton unsigned int gnuma, gnumb;
186fe7a38c6SPaul Burton
187fe7a38c6SPaul Burton if (infoa->package != infob->package)
188fe7a38c6SPaul Burton return false;
189fe7a38c6SPaul Burton
190fe7a38c6SPaul Burton gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
191fe7a38c6SPaul Burton gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
192fe7a38c6SPaul Burton if (gnuma != gnumb)
193fe7a38c6SPaul Burton return false;
194fe7a38c6SPaul Burton
195fe7a38c6SPaul Burton return true;
196fe7a38c6SPaul Burton }
197fe7a38c6SPaul Burton
cpu_asid_inc(void)1984edf00a4SPaul Burton static inline unsigned long cpu_asid_inc(void)
1994edf00a4SPaul Burton {
2004edf00a4SPaul Burton return 1 << CONFIG_MIPS_ASID_SHIFT;
2014edf00a4SPaul Burton }
2024edf00a4SPaul Burton
cpu_asid_mask(struct cpuinfo_mips * cpuinfo)2034edf00a4SPaul Burton static inline unsigned long cpu_asid_mask(struct cpuinfo_mips *cpuinfo)
2044edf00a4SPaul Burton {
2052db003a5SPaul Burton #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
2062db003a5SPaul Burton return cpuinfo->asid_mask;
2072db003a5SPaul Burton #endif
2084edf00a4SPaul Burton return ((1 << CONFIG_MIPS_ASID_BITS) - 1) << CONFIG_MIPS_ASID_SHIFT;
2094edf00a4SPaul Burton }
2104edf00a4SPaul Burton
set_cpu_asid_mask(struct cpuinfo_mips * cpuinfo,unsigned long asid_mask)2112db003a5SPaul Burton static inline void set_cpu_asid_mask(struct cpuinfo_mips *cpuinfo,
2122db003a5SPaul Burton unsigned long asid_mask)
2132db003a5SPaul Burton {
2142db003a5SPaul Burton #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
2152db003a5SPaul Burton cpuinfo->asid_mask = asid_mask;
2162db003a5SPaul Burton #endif
2172db003a5SPaul Burton }
2182db003a5SPaul Burton
219384740dcSRalf Baechle #endif /* __ASM_CPU_INFO_H */
220