M pc/clock.c => pc/clock.c +30 -0
@@ 82,6 82,36 @@ clock(Ureg *ur, void *arg)
splhi();
}
+/*
+ * experimentally determined and justified by counting cycles in
+ * delay()'s inner loop
+ */
+enum
+{
+ mul386= 380,
+ mul486= 121,
+};
+
+void
+printcpufreq(void)
+{
+ ulong freq;
+ int cpu;
+
+ switch(cpu = x86()){
+ default:
+ case 486:
+ freq = mul486;
+ break;
+ case 386:
+ freq = mul386;
+ break;
+ }
+ freq *= delayloop;
+ freq /= 10000;
+ print("CPU is a %ud MHz %d\n", freq, cpu);
+}
+
void
clockinit(void)
{
M pc/fns.h => pc/fns.h +3 -0
@@ 66,6 66,7 @@ void pcmspecialclose(int);
long pcmwrite(int, int, void*, long, ulong);
void prflush(void);
void prhex(ulong);
+void printcpufreq(void);
void procrestore(Proc*);
void procsave(Proc*);
void procsetup(Proc*);
@@ 86,6 87,8 @@ void trapinit(void);
int tas(void*);
void uartclock(void);
void vgainit(void);
+int x86(void);
+
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
#define kmapperm(x) kmap(x)
#define getcallerpc(x) (*(ulong*)(x))
M pc/l.s => pc/l.s +23 -1
@@ 54,7 54,7 @@ setpte:
MOVL AX,CR3
MOVL CR0,AX
ORL $0X80010000,AX
- ANDL $~(0x8|0x2),AX /* TS=0, MP=0 */
+ ANDL $~(0x40000000|0x20000000|0x8|0x2),AX /* CD=0, NW=0, TS=0, MP=0 */
MOVL AX,CR0
/*
@@ 567,6 567,28 @@ TEXT idle(SB),$0
RET
/*
+ * return cpu type (what is a pentium?)
+ */
+TEXT x86(SB),$0
+
+ PUSHFL
+ MOVL 0(SP),AX
+ ORL $0x40000,AX
+ PUSHL AX
+ POPFL
+ PUSHFL
+ POPL AX
+ ANDL $0x40000,AX
+ JZ is386
+ MOVL $486,AX
+ JMP done
+is386:
+ MOVL $386,AX
+done:
+ POPFL
+ RET
+
+/*
* label consists of a stack pointer and a PC
*/
TEXT gotolabel(SB),$0
M pc/main.c => pc/main.c +10 -1
@@ 58,6 58,7 @@ main(void)
procinit0();
initseg();
links();
+ printcpufreq();
chandevreset();
swapinit();
userinit();
@@ 391,7 392,15 @@ confinit(void)
conf.monitor = 1;
conf.nswap = conf.nproc*80;
conf.nimage = 50;
- conf.copymode = 0; /* copy on write */
+ switch(x86()){
+ case 386:
+ conf.copymode = 1; /* copy on reference */
+ break;
+ default:
+ case 486:
+ conf.copymode = 0; /* copy on write */
+ break;
+ }
conf.nfloppy = 2;
conf.nhard = 2;
conf.nmach = 1;
M port/portfns.h => port/portfns.h +1 -1
@@ 218,7 218,7 @@ void sched(void);
void schedinit(void);
int screenbits(void);
void screenupdate(void);
-int scsiexec(Target*, int, uchar*, int, void*, int);
+int scsiexec(Target*, int, uchar*, int, void*, int*);
int scsiinv(int, int, Target**, uchar**, char*);
Target* scsiunit(int, int);
long seconds(void);