~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/loongson64/cpucfg-emul.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/mips/loongson64/cpucfg-emul.c (Architecture m68k) and /arch/mips/loongson64/cpucfg-emul.c (Architecture mips)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2                                                     2 
  3 #include <linux/smp.h>                              3 #include <linux/smp.h>
  4 #include <linux/types.h>                            4 #include <linux/types.h>
  5 #include <asm/cpu.h>                                5 #include <asm/cpu.h>
  6 #include <asm/cpu-info.h>                           6 #include <asm/cpu-info.h>
  7 #include <asm/elf.h>                                7 #include <asm/elf.h>
  8                                                     8 
  9 #include <loongson_regs.h>                          9 #include <loongson_regs.h>
 10 #include <cpucfg-emul.h>                           10 #include <cpucfg-emul.h>
 11                                                    11 
 12 static bool is_loongson(struct cpuinfo_mips *c     12 static bool is_loongson(struct cpuinfo_mips *c)
 13 {                                                  13 {
 14         switch (c->processor_id & PRID_COMP_MA     14         switch (c->processor_id & PRID_COMP_MASK) {
 15         case PRID_COMP_LEGACY:                     15         case PRID_COMP_LEGACY:
 16                 return ((c->processor_id & PRI     16                 return ((c->processor_id & PRID_IMP_MASK) ==
 17                         PRID_IMP_LOONGSON_64C)     17                         PRID_IMP_LOONGSON_64C);
 18                                                    18 
 19         case PRID_COMP_LOONGSON:                   19         case PRID_COMP_LOONGSON:
 20                 return true;                       20                 return true;
 21                                                    21 
 22         default:                                   22         default:
 23                 return false;                      23                 return false;
 24         }                                          24         }
 25 }                                                  25 }
 26                                                    26 
 27 static u32 get_loongson_fprev(struct cpuinfo_m     27 static u32 get_loongson_fprev(struct cpuinfo_mips *c)
 28 {                                                  28 {
 29         return c->fpu_id & LOONGSON_FPREV_MASK     29         return c->fpu_id & LOONGSON_FPREV_MASK;
 30 }                                                  30 }
 31                                                    31 
 32 static bool cpu_has_uca(void)                      32 static bool cpu_has_uca(void)
 33 {                                                  33 {
 34         u32 diag = read_c0_diag();                 34         u32 diag = read_c0_diag();
 35         u32 new_diag;                              35         u32 new_diag;
 36                                                    36 
 37         if (diag & LOONGSON_DIAG_UCAC)             37         if (diag & LOONGSON_DIAG_UCAC)
 38                 /* UCA is already enabled. */      38                 /* UCA is already enabled. */
 39                 return true;                       39                 return true;
 40                                                    40 
 41         /* See if UCAC bit can be flipped on.      41         /* See if UCAC bit can be flipped on. This should be safe. */
 42         new_diag = diag | LOONGSON_DIAG_UCAC;      42         new_diag = diag | LOONGSON_DIAG_UCAC;
 43         write_c0_diag(new_diag);                   43         write_c0_diag(new_diag);
 44         new_diag = read_c0_diag();                 44         new_diag = read_c0_diag();
 45         write_c0_diag(diag);                       45         write_c0_diag(diag);
 46                                                    46 
 47         return (new_diag & LOONGSON_DIAG_UCAC)     47         return (new_diag & LOONGSON_DIAG_UCAC) != 0;
 48 }                                                  48 }
 49                                                    49 
 50 static void probe_uca(struct cpuinfo_mips *c)      50 static void probe_uca(struct cpuinfo_mips *c)
 51 {                                                  51 {
 52         if (cpu_has_uca())                         52         if (cpu_has_uca())
 53                 c->loongson3_cpucfg_data[0] |=     53                 c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_LSUCA;
 54 }                                                  54 }
 55                                                    55 
 56 static void decode_loongson_config6(struct cpu     56 static void decode_loongson_config6(struct cpuinfo_mips *c)
 57 {                                                  57 {
 58         u32 config6 = read_c0_config6();           58         u32 config6 = read_c0_config6();
 59                                                    59 
 60         if (config6 & LOONGSON_CONF6_SFBEN)        60         if (config6 & LOONGSON_CONF6_SFBEN)
 61                 c->loongson3_cpucfg_data[0] |=     61                 c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_SFBP;
 62         if (config6 & LOONGSON_CONF6_LLEXC)        62         if (config6 & LOONGSON_CONF6_LLEXC)
 63                 c->loongson3_cpucfg_data[0] |=     63                 c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_LLEXC;
 64         if (config6 & LOONGSON_CONF6_SCRAND)       64         if (config6 & LOONGSON_CONF6_SCRAND)
 65                 c->loongson3_cpucfg_data[0] |=     65                 c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_SCRAND;
 66 }                                                  66 }
 67                                                    67 
 68 static void patch_cpucfg_sel1(struct cpuinfo_m     68 static void patch_cpucfg_sel1(struct cpuinfo_mips *c)
 69 {                                                  69 {
 70         u64 ases = c->ases;                        70         u64 ases = c->ases;
 71         u64 options = c->options;                  71         u64 options = c->options;
 72         u32 data = c->loongson3_cpucfg_data[0]     72         u32 data = c->loongson3_cpucfg_data[0];
 73                                                    73 
 74         if (options & MIPS_CPU_FPU) {              74         if (options & MIPS_CPU_FPU) {
 75                 data |= LOONGSON_CFG1_FP;          75                 data |= LOONGSON_CFG1_FP;
 76                 data |= get_loongson_fprev(c)      76                 data |= get_loongson_fprev(c) << LOONGSON_CFG1_FPREV_OFFSET;
 77         }                                          77         }
 78         if (ases & MIPS_ASE_LOONGSON_MMI)          78         if (ases & MIPS_ASE_LOONGSON_MMI)
 79                 data |= LOONGSON_CFG1_MMI;         79                 data |= LOONGSON_CFG1_MMI;
 80         if (ases & MIPS_ASE_MSA)                   80         if (ases & MIPS_ASE_MSA)
 81                 data |= LOONGSON_CFG1_MSA1;        81                 data |= LOONGSON_CFG1_MSA1;
 82                                                    82 
 83         c->loongson3_cpucfg_data[0] = data;        83         c->loongson3_cpucfg_data[0] = data;
 84 }                                                  84 }
 85                                                    85 
 86 static void patch_cpucfg_sel2(struct cpuinfo_m     86 static void patch_cpucfg_sel2(struct cpuinfo_mips *c)
 87 {                                                  87 {
 88         u64 ases = c->ases;                        88         u64 ases = c->ases;
 89         u64 options = c->options;                  89         u64 options = c->options;
 90         u32 data = c->loongson3_cpucfg_data[1]     90         u32 data = c->loongson3_cpucfg_data[1];
 91                                                    91 
 92         if (ases & MIPS_ASE_LOONGSON_EXT)          92         if (ases & MIPS_ASE_LOONGSON_EXT)
 93                 data |= LOONGSON_CFG2_LEXT1;       93                 data |= LOONGSON_CFG2_LEXT1;
 94         if (ases & MIPS_ASE_LOONGSON_EXT2)         94         if (ases & MIPS_ASE_LOONGSON_EXT2)
 95                 data |= LOONGSON_CFG2_LEXT2;       95                 data |= LOONGSON_CFG2_LEXT2;
 96         if (options & MIPS_CPU_LDPTE)              96         if (options & MIPS_CPU_LDPTE)
 97                 data |= LOONGSON_CFG2_LSPW;        97                 data |= LOONGSON_CFG2_LSPW;
 98                                                    98 
 99         if (ases & MIPS_ASE_VZ)                    99         if (ases & MIPS_ASE_VZ)
100                 data |= LOONGSON_CFG2_LVZP;       100                 data |= LOONGSON_CFG2_LVZP;
101         else                                      101         else
102                 data &= ~LOONGSON_CFG2_LVZREV;    102                 data &= ~LOONGSON_CFG2_LVZREV;
103                                                   103 
104         c->loongson3_cpucfg_data[1] = data;       104         c->loongson3_cpucfg_data[1] = data;
105 }                                                 105 }
106                                                   106 
107 static void patch_cpucfg_sel3(struct cpuinfo_m    107 static void patch_cpucfg_sel3(struct cpuinfo_mips *c)
108 {                                                 108 {
109         u64 ases = c->ases;                       109         u64 ases = c->ases;
110         u32 data = c->loongson3_cpucfg_data[2]    110         u32 data = c->loongson3_cpucfg_data[2];
111                                                   111 
112         if (ases & MIPS_ASE_LOONGSON_CAM) {       112         if (ases & MIPS_ASE_LOONGSON_CAM) {
113                 data |= LOONGSON_CFG3_LCAMP;      113                 data |= LOONGSON_CFG3_LCAMP;
114         } else {                                  114         } else {
115                 data &= ~LOONGSON_CFG3_LCAMREV    115                 data &= ~LOONGSON_CFG3_LCAMREV;
116                 data &= ~LOONGSON_CFG3_LCAMNUM    116                 data &= ~LOONGSON_CFG3_LCAMNUM;
117                 data &= ~LOONGSON_CFG3_LCAMKW;    117                 data &= ~LOONGSON_CFG3_LCAMKW;
118                 data &= ~LOONGSON_CFG3_LCAMVW;    118                 data &= ~LOONGSON_CFG3_LCAMVW;
119         }                                         119         }
120                                                   120 
121         c->loongson3_cpucfg_data[2] = data;       121         c->loongson3_cpucfg_data[2] = data;
122 }                                                 122 }
123                                                   123 
124 void loongson3_cpucfg_synthesize_data(struct c    124 void loongson3_cpucfg_synthesize_data(struct cpuinfo_mips *c)
125 {                                                 125 {
126         /* Only engage the logic on Loongson p    126         /* Only engage the logic on Loongson processors. */
127         if (!is_loongson(c))                      127         if (!is_loongson(c))
128                 return;                           128                 return;
129                                                   129 
130         /* CPUs with CPUCFG support don't need    130         /* CPUs with CPUCFG support don't need to synthesize anything. */
131         if (cpu_has_cfg())                        131         if (cpu_has_cfg())
132                 goto have_cpucfg_now;             132                 goto have_cpucfg_now;
133                                                   133 
134         c->loongson3_cpucfg_data[0] = 0;          134         c->loongson3_cpucfg_data[0] = 0;
135         c->loongson3_cpucfg_data[1] = 0;          135         c->loongson3_cpucfg_data[1] = 0;
136         c->loongson3_cpucfg_data[2] = 0;          136         c->loongson3_cpucfg_data[2] = 0;
137                                                   137 
138         /* Add CPUCFG features non-discoverabl    138         /* Add CPUCFG features non-discoverable otherwise. */
139         switch (c->processor_id & (PRID_IMP_MA    139         switch (c->processor_id & (PRID_IMP_MASK | PRID_REV_MASK)) {
140         case PRID_IMP_LOONGSON_64R | PRID_REV_    140         case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_0:
141         case PRID_IMP_LOONGSON_64R | PRID_REV_    141         case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_1:
142         case PRID_IMP_LOONGSON_64R | PRID_REV_    142         case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_2:
143         case PRID_IMP_LOONGSON_64R | PRID_REV_    143         case PRID_IMP_LOONGSON_64R | PRID_REV_LOONGSON2K_R1_3:
144                 decode_loongson_config6(c);       144                 decode_loongson_config6(c);
145                 probe_uca(c);                     145                 probe_uca(c);
146                                                   146 
147                 c->loongson3_cpucfg_data[0] |=    147                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
148                         LOONGSON_CFG1_LSSYNCI     148                         LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LLSYNC |
149                         LOONGSON_CFG1_TGTSYNC)    149                         LOONGSON_CFG1_TGTSYNC);
150                 c->loongson3_cpucfg_data[1] |=    150                 c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
151                         LOONGSON_CFG2_LBT2 | L    151                         LOONGSON_CFG2_LBT2 | LOONGSON_CFG2_LPMP |
152                         LOONGSON_CFG2_LPM_REV2    152                         LOONGSON_CFG2_LPM_REV2);
153                 c->loongson3_cpucfg_data[2] =     153                 c->loongson3_cpucfg_data[2] = 0;
154                 break;                            154                 break;
155                                                   155 
156         case PRID_IMP_LOONGSON_64C | PRID_REV_    156         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R1:
157                 c->loongson3_cpucfg_data[0] |=    157                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
158                         LOONGSON_CFG1_LSSYNCI     158                         LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
159                         LOONGSON_CFG1_LLSYNC |    159                         LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
160                 c->loongson3_cpucfg_data[1] |=    160                 c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
161                         LOONGSON_CFG2_LPMP | L    161                         LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1);
162                 c->loongson3_cpucfg_data[2] |=    162                 c->loongson3_cpucfg_data[2] |= (
163                         LOONGSON_CFG3_LCAM_REV    163                         LOONGSON_CFG3_LCAM_REV1 |
164                         LOONGSON_CFG3_LCAMNUM_    164                         LOONGSON_CFG3_LCAMNUM_REV1 |
165                         LOONGSON_CFG3_LCAMKW_R    165                         LOONGSON_CFG3_LCAMKW_REV1 |
166                         LOONGSON_CFG3_LCAMVW_R    166                         LOONGSON_CFG3_LCAMVW_REV1);
167                 break;                            167                 break;
168                                                   168 
169         case PRID_IMP_LOONGSON_64C | PRID_REV_    169         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R1:
170         case PRID_IMP_LOONGSON_64C | PRID_REV_    170         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3B_R2:
171                 c->loongson3_cpucfg_data[0] |=    171                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_LSLDR0 |
172                         LOONGSON_CFG1_LSSYNCI     172                         LOONGSON_CFG1_LSSYNCI | LOONGSON_CFG1_LSUCA |
173                         LOONGSON_CFG1_LLSYNC |    173                         LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
174                 c->loongson3_cpucfg_data[1] |=    174                 c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
175                         LOONGSON_CFG2_LPMP | L    175                         LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1);
176                 c->loongson3_cpucfg_data[2] |=    176                 c->loongson3_cpucfg_data[2] |= (
177                         LOONGSON_CFG3_LCAM_REV    177                         LOONGSON_CFG3_LCAM_REV1 |
178                         LOONGSON_CFG3_LCAMNUM_    178                         LOONGSON_CFG3_LCAMNUM_REV1 |
179                         LOONGSON_CFG3_LCAMKW_R    179                         LOONGSON_CFG3_LCAMKW_REV1 |
180                         LOONGSON_CFG3_LCAMVW_R    180                         LOONGSON_CFG3_LCAMVW_REV1);
181                 break;                            181                 break;
182                                                   182 
183         case PRID_IMP_LOONGSON_64C | PRID_REV_    183         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0:
184         case PRID_IMP_LOONGSON_64C | PRID_REV_    184         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_1:
185         case PRID_IMP_LOONGSON_64C | PRID_REV_    185         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_0:
186         case PRID_IMP_LOONGSON_64C | PRID_REV_    186         case PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R3_1:
187                 decode_loongson_config6(c);       187                 decode_loongson_config6(c);
188                 probe_uca(c);                     188                 probe_uca(c);
189                                                   189 
190                 c->loongson3_cpucfg_data[0] |=    190                 c->loongson3_cpucfg_data[0] |= (LOONGSON_CFG1_CNT64 |
191                         LOONGSON_CFG1_LSLDR0 |    191                         LOONGSON_CFG1_LSLDR0 | LOONGSON_CFG1_LSPREF |
192                         LOONGSON_CFG1_LSPREFX     192                         LOONGSON_CFG1_LSPREFX | LOONGSON_CFG1_LSSYNCI |
193                         LOONGSON_CFG1_LLSYNC |    193                         LOONGSON_CFG1_LLSYNC | LOONGSON_CFG1_TGTSYNC);
194                 c->loongson3_cpucfg_data[1] |=    194                 c->loongson3_cpucfg_data[1] |= (LOONGSON_CFG2_LBT1 |
195                         LOONGSON_CFG2_LBT2 | L    195                         LOONGSON_CFG2_LBT2 | LOONGSON_CFG2_LBTMMU |
196                         LOONGSON_CFG2_LPMP | L    196                         LOONGSON_CFG2_LPMP | LOONGSON_CFG2_LPM_REV1 |
197                         LOONGSON_CFG2_LVZ_REV1    197                         LOONGSON_CFG2_LVZ_REV1);
198                 c->loongson3_cpucfg_data[2] |=    198                 c->loongson3_cpucfg_data[2] |= (LOONGSON_CFG3_LCAM_REV1 |
199                         LOONGSON_CFG3_LCAMNUM_    199                         LOONGSON_CFG3_LCAMNUM_REV1 |
200                         LOONGSON_CFG3_LCAMKW_R    200                         LOONGSON_CFG3_LCAMKW_REV1 |
201                         LOONGSON_CFG3_LCAMVW_R    201                         LOONGSON_CFG3_LCAMVW_REV1);
202                 break;                            202                 break;
203                                                   203 
204         default:                                  204         default:
205                 /* It is possible that some fu    205                 /* It is possible that some future Loongson cores still do
206                  * not have CPUCFG, so do not     206                  * not have CPUCFG, so do not emulate anything for these
207                  * cores.                         207                  * cores.
208                  */                               208                  */
209                 return;                           209                 return;
210         }                                         210         }
211                                                   211 
212         /* This feature is set by firmware, bu    212         /* This feature is set by firmware, but all known Loongson-64 systems
213          * are configured this way.               213          * are configured this way.
214          */                                       214          */
215         c->loongson3_cpucfg_data[0] |= LOONGSO    215         c->loongson3_cpucfg_data[0] |= LOONGSON_CFG1_CDMAP;
216                                                   216 
217         /* Patch in dynamically probed bits. *    217         /* Patch in dynamically probed bits. */
218         patch_cpucfg_sel1(c);                     218         patch_cpucfg_sel1(c);
219         patch_cpucfg_sel2(c);                     219         patch_cpucfg_sel2(c);
220         patch_cpucfg_sel3(c);                     220         patch_cpucfg_sel3(c);
221                                                   221 
222 have_cpucfg_now:                                  222 have_cpucfg_now:
223         /* We have usable CPUCFG now, emulated    223         /* We have usable CPUCFG now, emulated or not.
224          * Announce CPUCFG availability to use    224          * Announce CPUCFG availability to userspace via hwcap.
225          */                                       225          */
226         elf_hwcap |= HWCAP_LOONGSON_CPUCFG;       226         elf_hwcap |= HWCAP_LOONGSON_CPUCFG;
227 }                                                 227 }
228                                                   228 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php