00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "ki.h"
00026
00027 #define Cx486_SLC 0x0
00028 #define Cx486_DLC 0x1
00029 #define Cx486_SLC2 0x2
00030 #define Cx486_DLC2 0x3
00031 #define Cx486_SRx 0x4 // Retail Upgrade Cx486SLC
00032 #define Cx486_DRx 0x5 // Retail Upgrade Cx486DLC
00033 #define Cx486_SRx2 0x6 // Retail Upgrade 2x Cx486SLC
00034 #define Cx486_DRx2 0x7 // Retail Upgrade 2x Cx486DLC
00035 #define Cx486DX 0x1a
00036 #define Cx486DX2 0x1b
00037 #define M1 0x30
00038
00039 #define CCR0 0xC0
00040 #define CCR1 0xC1
00041 #define CCR2 0xC2
00042 #define CCR3 0xC3
00043
00044 #define DIR0 0xFE
00045 #define DIR1 0xFF
00046
00047
00048
00049 #define CCR0_NC0 0x01 // No cache 64k @ 1M boundaries
00050 #define CCR0_NC1 0x02 // No cache 640k - 1M
00051 #define CCR0_A20M 0x04 // Enables A20M#
00052 #define CCR0_KEN 0x08 // Enables KEN#
00053 #define CCR0_FLUSH 0x10 // Enables FLUSH#
00054
00055
00056 #define CCR1_NO_LOCK 0x10 // Ignore lock prefixes
00057
00058
00059 ULONG
00060
Ke386CyrixId (
00061 VOID
00062 );
00063
00064 UCHAR
00065
ReadCyrixRegister (
00066 IN UCHAR Register
00067 );
00068
00069
VOID
00070
WriteCyrixRegister (
00071 IN UCHAR Register,
00072 IN UCHAR Value
00073 );
00074
00075
VOID
00076
Ke386ConfigureCyrixProcessor (
00077 VOID
00078 );
00079
00080
#ifdef ALLOC_PRAGMA
00081
#pragma alloc_text(PAGE,Ke386CyrixId)
00082
#pragma alloc_text(PAGELK,Ke386ConfigureCyrixProcessor)
00083
#endif
00084
00085
00086 extern UCHAR
CmpCyrixID[];
00087
00088
00089
00090 ULONG
00091 Ke386CyrixId (
00092 VOID
00093 )
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 {
00120 ULONG CyrixID;
00121 UCHAR r3,
c;
00122 UCHAR flags;
00123 PKPRCB Prcb;
00124
00125 CyrixID = 0;
00126
00127 Prcb =
KeGetCurrentPrcb();
00128
if (Prcb->CpuID && strcmp (Prcb->VendorString,
CmpCyrixID)) {
00129
00130
00131
00132
00133
00134
return 0;
00135 }
00136
00137
00138
00139
00140
00141
00142 _asm {
00143 xor eax, eax
00144 sahf ; flags = ah
00145
00146 lahf ; ah = flags
00147 mov flags, ah ; save flags
00148
00149 mov eax, 5
00150 mov ecx, 2
00151 div cl ; 5 / 2 = ?
00152
00153 lahf
00154 sub flags, ah ; flags = orig_flags - new_flags
00155 }
00156
00157
if (flags == 0) {
00158
00159
00160
00161
00162
00163 r3 =
ReadCyrixRegister(
CCR3);
00164
c = r3 ^ 0x80;
00165
WriteCyrixRegister(
CCR3,
c);
00166
ReadCyrixRegister(
CCR0);
00167
c =
ReadCyrixRegister(
CCR3);
00168
00169
if (
ReadCyrixRegister(
CCR3) != r3) {
00170
00171
00172
00173
00174
00175 CyrixID =
ReadCyrixRegister(
DIR0) + 1;
00176 }
00177
00178
WriteCyrixRegister(
CCR3, r3);
00179 }
00180
00181
if (CyrixID > 0x7f) {
00182
00183 CyrixID = 0;
00184 }
00185
00186
return CyrixID;
00187 }
00188
00189
static UCHAR
00190 ReadCyrixRegister (
00191 IN UCHAR Register
00192 )
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 {
00215 UCHAR Value;
00216
00217 _asm {
00218 mov al, Register
00219 cli
00220
out 22h, al
00221 in al, 23h
00222 sti
00223 mov Value, al
00224 }
00225
return Value;
00226 }
00227
00228
00229
static VOID
00230 WriteCyrixRegister (
00231 IN UCHAR Register,
00232 IN UCHAR Value
00233 )
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 {
00257 _asm {
00258 mov al, Register
00259 mov cl, Value
00260 cli
00261
out 22h, al
00262 mov al, cl
00263
out 23h, al
00264 sti
00265 }
00266 }
00267
00268
00269
VOID
00270 Ke386ConfigureCyrixProcessor (
00271 VOID
00272 )
00273 {
00274 UCHAR r0, r1;
00275 ULONG
id, rev;
00276 PVOID LockHandle;
00277
00278
00279
PAGED_CODE();
00280
00281
id =
Ke386CyrixId();
00282
if (
id) {
00283
00284 LockHandle = MmLockPagableCodeSection (&
Ke386ConfigureCyrixProcessor);
00285
00286
id =
id - 1;
00287 rev =
ReadCyrixRegister(
DIR1);
00288
00289
if ((
id >= 0x20 &&
id <= 0x27) ||
00290 ((
id & 0xF0) ==
M1 && rev < 0x17)) {
00291
00292
00293
00294
00295
00296
00297
00298 _asm {
00299 cli
00300
00301 mov eax, cr0
00302 or eax, CR0_NW
00303 mov cr0, eax
00304
00305 sti
00306 }
00307 }
00308
00309
00310
switch (
id) {
00311
case Cx486_SRx:
00312
case Cx486_DRx:
00313
case Cx486_SRx2:
00314
case Cx486_DRx2:
00315
00316
00317
00318
00319
00320
00321 r0 =
ReadCyrixRegister(
CCR0);
00322 r0 |=
CCR0_NC1 |
CCR0_FLUSH;
00323 r0 &= ~
CCR0_NC0;
00324
WriteCyrixRegister(
CCR0, r0);
00325
00326
00327
WriteCyrixRegister(0xC4, 0);
00328
WriteCyrixRegister(0xC5, 0);
00329
WriteCyrixRegister(0xC6, 0);
00330
break;
00331
00332
case Cx486DX:
00333
case Cx486DX2:
00334
00335
00336
00337
00338
00339 r1 =
ReadCyrixRegister(
CCR1);
00340 r1 |=
CCR1_NO_LOCK;
00341
if (
KeNumberProcessors > 1) {
00342 r1 &= ~
CCR1_NO_LOCK;
00343 }
00344
WriteCyrixRegister(
CCR1, r1);
00345
break;
00346 }
00347
00348
MmUnlockPagableImageSection (LockHandle);
00349 }
00350 }