Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1994 Waldorf GMBH
0007  * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
0008  * Copyright (C) 1996 Paul M. Antoine
0009  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
0010  * Copyright (C) 2004  Maciej W. Rozycki
0011  */
0012 #ifndef __ASM_CPU_INFO_H
0013 #define __ASM_CPU_INFO_H
0014 
0015 #include <linux/cache.h>
0016 #include <linux/types.h>
0017 
0018 #include <asm/mipsregs.h>
0019 
0020 /*
0021  * Descriptor for a cache
0022  */
0023 struct cache_desc {
0024     unsigned int waysize;   /* Bytes per way */
0025     unsigned short sets;    /* Number of lines per set */
0026     unsigned char ways; /* Number of ways */
0027     unsigned char linesz;   /* Size of line in bytes */
0028     unsigned char waybit;   /* Bits to select in a cache set */
0029     unsigned char flags;    /* Flags describing cache properties */
0030 };
0031 
0032 struct guest_info {
0033     unsigned long       ases;
0034     unsigned long       ases_dyn;
0035     unsigned long long  options;
0036     unsigned long long  options_dyn;
0037     int         tlbsize;
0038     u8          conf;
0039     u8          kscratch_mask;
0040 };
0041 
0042 /*
0043  * Flag definitions
0044  */
0045 #define MIPS_CACHE_NOT_PRESENT  0x00000001
0046 #define MIPS_CACHE_VTAG     0x00000002  /* Virtually tagged cache */
0047 #define MIPS_CACHE_ALIASES  0x00000004  /* Cache could have aliases */
0048 #define MIPS_CACHE_IC_F_DC  0x00000008  /* Ic can refill from D-cache */
0049 #define MIPS_IC_SNOOPS_REMOTE   0x00000010  /* Ic snoops remote stores */
0050 #define MIPS_CACHE_PINDEX   0x00000020  /* Physically indexed cache */
0051 
0052 struct cpuinfo_mips {
0053     u64         asid_cache;
0054 #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
0055     unsigned long       asid_mask;
0056 #endif
0057 
0058     /*
0059      * Capability and feature descriptor structure for MIPS CPU
0060      */
0061     unsigned long       ases;
0062     unsigned long long  options;
0063     unsigned int        udelay_val;
0064     unsigned int        processor_id;
0065     unsigned int        fpu_id;
0066     unsigned int        fpu_csr31;
0067     unsigned int        fpu_msk31;
0068     unsigned int        msa_id;
0069     unsigned int        cputype;
0070     int         isa_level;
0071     int         tlbsize;
0072     int         tlbsizevtlb;
0073     int         tlbsizeftlbsets;
0074     int         tlbsizeftlbways;
0075     struct cache_desc   icache; /* Primary I-cache */
0076     struct cache_desc   dcache; /* Primary D or combined I/D cache */
0077     struct cache_desc   vcache; /* Victim cache, between pcache and scache */
0078     struct cache_desc   scache; /* Secondary cache */
0079     struct cache_desc   tcache; /* Tertiary/split secondary cache */
0080     int         srsets; /* Shadow register sets */
0081     int         package;/* physical package number */
0082     unsigned int        globalnumber;
0083 #ifdef CONFIG_64BIT
0084     int         vmbits; /* Virtual memory size in bits */
0085 #endif
0086     void            *data;  /* Additional data */
0087     unsigned int        watch_reg_count;   /* Number that exist */
0088     unsigned int        watch_reg_use_cnt; /* Usable by ptrace */
0089 #define NUM_WATCH_REGS 4
0090     u16         watch_reg_masks[NUM_WATCH_REGS];
0091     unsigned int        kscratch_mask; /* Usable KScratch mask. */
0092     /*
0093      * Cache Coherency attribute for write-combine memory writes.
0094      * (shifted by _CACHE_SHIFT)
0095      */
0096     unsigned int        writecombine;
0097     /*
0098      * Simple counter to prevent enabling HTW in nested
0099      * htw_start/htw_stop calls
0100      */
0101     unsigned int        htw_seq;
0102 
0103     /* VZ & Guest features */
0104     struct guest_info   guest;
0105     unsigned int        gtoffset_mask;
0106     unsigned int        guestid_mask;
0107     unsigned int        guestid_cache;
0108 
0109 #ifdef CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION
0110     /* CPUCFG data for this CPU, synthesized at probe time.
0111      *
0112      * CPUCFG select 0 is PRId, 4 and above are unimplemented for now.
0113      * So the only stored values are for CPUCFG selects 1-3 inclusive.
0114      */
0115     u32 loongson3_cpucfg_data[3];
0116 #endif
0117 } __attribute__((aligned(SMP_CACHE_BYTES)));
0118 
0119 extern struct cpuinfo_mips cpu_data[];
0120 #define current_cpu_data cpu_data[smp_processor_id()]
0121 #define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
0122 #define boot_cpu_data cpu_data[0]
0123 
0124 extern void cpu_probe(void);
0125 extern void cpu_report(void);
0126 
0127 extern const char *__cpu_name[];
0128 #define cpu_name_string()   __cpu_name[raw_smp_processor_id()]
0129 
0130 struct seq_file;
0131 struct notifier_block;
0132 
0133 extern int register_proc_cpuinfo_notifier(struct notifier_block *nb);
0134 extern int proc_cpuinfo_notifier_call_chain(unsigned long val, void *v);
0135 
0136 #define proc_cpuinfo_notifier(fn, pri)                  \
0137 ({                                  \
0138     static struct notifier_block fn##_nb = {            \
0139         .notifier_call = fn,                    \
0140         .priority = pri                     \
0141     };                              \
0142                                     \
0143     register_proc_cpuinfo_notifier(&fn##_nb);           \
0144 })
0145 
0146 struct proc_cpuinfo_notifier_args {
0147     struct seq_file *m;
0148     unsigned long n;
0149 };
0150 
0151 static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo)
0152 {
0153     /* Optimisation for systems where multiple clusters aren't used */
0154     if (!IS_ENABLED(CONFIG_CPU_MIPSR5) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
0155         return 0;
0156 
0157     return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >>
0158         MIPS_GLOBALNUMBER_CLUSTER_SHF;
0159 }
0160 
0161 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
0162 {
0163     return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
0164         MIPS_GLOBALNUMBER_CORE_SHF;
0165 }
0166 
0167 static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
0168 {
0169     /* Optimisation for systems where VP(E)s aren't used */
0170     if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
0171         return 0;
0172 
0173     return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
0174         MIPS_GLOBALNUMBER_VP_SHF;
0175 }
0176 
0177 extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster);
0178 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
0179 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
0180 
0181 static inline bool cpus_are_siblings(int cpua, int cpub)
0182 {
0183     struct cpuinfo_mips *infoa = &cpu_data[cpua];
0184     struct cpuinfo_mips *infob = &cpu_data[cpub];
0185     unsigned int gnuma, gnumb;
0186 
0187     if (infoa->package != infob->package)
0188         return false;
0189 
0190     gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
0191     gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
0192     if (gnuma != gnumb)
0193         return false;
0194 
0195     return true;
0196 }
0197 
0198 static inline unsigned long cpu_asid_inc(void)
0199 {
0200     return 1 << CONFIG_MIPS_ASID_SHIFT;
0201 }
0202 
0203 static inline unsigned long cpu_asid_mask(struct cpuinfo_mips *cpuinfo)
0204 {
0205 #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
0206     return cpuinfo->asid_mask;
0207 #endif
0208     return ((1 << CONFIG_MIPS_ASID_BITS) - 1) << CONFIG_MIPS_ASID_SHIFT;
0209 }
0210 
0211 static inline void set_cpu_asid_mask(struct cpuinfo_mips *cpuinfo,
0212                      unsigned long asid_mask)
0213 {
0214 #ifdef CONFIG_MIPS_ASID_BITS_VARIABLE
0215     cpuinfo->asid_mask = asid_mask;
0216 #endif
0217 }
0218 
0219 #endif /* __ASM_CPU_INFO_H */