From 596537fc594911e530db6702027251b8301560d2 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 23 Sep 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-09-23 --- pc/archgeneric.c | 25 ++++++++++ pc/archncr3170.c | 49 ++++++++++++++++++++ pc/{pmu.c => archnsx20.c} | 62 ++++++++++++++++++++----- pc/clock.c | 50 ++++++++++++-------- pc/dat.h | 23 ++++++++-- pc/ether509.c | 62 +++++++++++++++---------- pc/fns.h | 7 --- pc/headland.c | 37 --------------- pc/main.c | 97 ++++++++++++--------------------------- port/sysproc.c | 1 + power/mem.h | 2 +- 11 files changed, 242 insertions(+), 173 deletions(-) create mode 100644 pc/archgeneric.c create mode 100644 pc/archncr3170.c rename pc/{pmu.c => archnsx20.c} (75%) delete mode 100644 pc/headland.c diff --git a/pc/archgeneric.c b/pc/archgeneric.c new file mode 100644 index 0000000000000000000000000000000000000000..1c74267eb719ba151b90d411c0380f275b803ac4 --- /dev/null +++ b/pc/archgeneric.c @@ -0,0 +1,25 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +static void +genericreset(void) +{ + print("Reset the machine!\n"); + for(;;); +} + +PCArch generic = +{ + "generic", + genericreset, + 0, + 0, + 0, + 0, + 0, + 0, +}; diff --git a/pc/archncr3170.c b/pc/archncr3170.c new file mode 100644 index 0000000000000000000000000000000000000000..685ab7faad3164537be272fa4943616e68316f9f --- /dev/null +++ b/pc/archncr3170.c @@ -0,0 +1,49 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +enum +{ + Pindex= 0x198, + Pdata= 0x199, +}; + +static Lock pmulock; +static int +pmuwrbit(int index, int bit, int pos) +{ + uchar x; + + lock(&pmulock); + outb(Pindex, index); + x = inb(Pdata); + if(bit) + x |= 1<>1)&1), 1); /* mail */ } + +/* + * headland system controller (ht21) + */ +enum +{ + /* + * system control port + */ + Head= 0x92, /* control port */ + Reset= (1<<0), /* reset the 386 */ + A20ena= (1<<1), /* enable address line 20 */ +}; + +/* + * reset machine + */ +static void +headreset(void) +{ + outb(Head, Reset); +} + +PCArch nsx20 = +{ + "AT&TNSX", + headreset, + nsx20cpuspeed, + nsx20buzz, + nsx20lights, + nsx20serialpower, + nsx20modempower, + 0, +}; diff --git a/pc/clock.c b/pc/clock.c index 3bd8d793c730b31629be93f5d6059f33e9d1f07b..e3ce7b1be26b22a7eaeb8f30da19bfb3482b8a56 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -16,32 +16,36 @@ enum T2cntr= 0x42, /* ... */ Tmode= 0x43, /* mode port */ - Load0square= 0x36, /* load counter 0 with 2 bytes, - * output a square wave whose - * period is the counter period - */ - Latch0= 0x06, - Freq= 1193182, /* Real clock frequency */ + /* commands */ + Latch0= 0x00, /* latch counter 0's value */ + Load0= 0x30, /* load counter 0 with 2 bytes */ + + /* modes */ + Square= 0x36, /* perioic square wave */ + + Freq= 1193182, /* Real clock frequency */ }; +static ulong delayloop = 1000; + /* - * delay for l milliseconds + * delay for l milliseconds more or less. delayloop is set by + * clockinit() to match the actual CPU speed. */ void delay(int l) { - int i; + ulong i; - while(--l){ - for(i=0; i < 404; i++) + while(l-- > 0) + for(i=0; i < delayloop; i++) ; - } } void clockinit(void) { - ulong dc; /* change in counter */ + ulong x, y; /* change in counter */ /* * set vector for clock interrupts @@ -51,18 +55,28 @@ clockinit(void) /* * make clock output a square wave with a 1/HZ period */ - outb(Tmode, Load0square); + outb(Tmode, Load0|Square); outb(T0cntr, (Freq/HZ)); /* low byte */ outb(T0cntr, (Freq/HZ)>>8); /* high byte */ /* - * measure cpu speed to make delay() system - * independent + * measure time for delay(10) with current delayloop count */ - delay(100); outb(Tmode, Latch0); - dc = inb(T0cntr); - dc |= inb(T0cntr)<<8; + x = inb(T0cntr); + x |= inb(T0cntr)<<8; + delay(10); + outb(Tmode, Latch0); + y = inb(T0cntr); + y |= inb(T0cntr)<<8; + x -= y; + + /* + * fix count, the factor of 2 is a hack + */ + delayloop = (delayloop*1193*10)/x; + if(delayloop == 0) + delayloop = 1; } void diff --git a/pc/dat.h b/pc/dat.h index 5ecfd65ebe804584a8a9f329610fe85790b07483..2dbf95e5279a0ecd5c292d019680cf3b92c8ef91 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -4,6 +4,7 @@ typedef struct Label Label; typedef struct Lock Lock; typedef struct MMU MMU; typedef struct Mach Mach; +typedef struct PCArch PCArch; typedef struct Page Page; typedef struct PMMU PMMU; typedef struct Segdesc Segdesc; @@ -177,14 +178,26 @@ struct short exiting; }active; +/* + * routines for things outside the PC model, like power management + */ +struct PCArch +{ + char *id; + void (*reset)(void); /* this should be in the model */ + int (*cpuspeed)(int); /* 0 = low, 1 = high */ + void (*buzz)(int, int); /* make a noise */ + void (*lights)(int); /* turn lights or icons on/off */ + int (*serialpower)(int); /* 1 == on, 0 == off */ + int (*modempower)(int); /* 1 == on, 0 == off */ + int (*extvga)(int); /* 1 == external, 0 == internal */ +}; + extern Mach *m; extern User *u; extern int flipD[]; /* for flipping bitblt destination polarity */ -/* - * bootline passed by boot program - */ -#define BOOTLINE ((char *)0x80000100) +#define BOOTLINE ((char *)0x80000100) /* bootline passed by boot program */ -extern char machtype[]; +extern PCArch *arch; /* PC architecture */ diff --git a/pc/ether509.c b/pc/ether509.c index f4db22f66eae3da3424075b3268547cbbd12bfc0..1c4146b245c29a4303d9fef90a653a8c67d4b1aa 100644 --- a/pc/ether509.c +++ b/pc/ether509.c @@ -77,6 +77,30 @@ enum { #define COMMAND(hw, cmd, a) outs(hw->addr+Command, ((cmd)<<11)|(a)) +/* + * Write two 0 bytes to idnetify the IDport and them reset the + * ID sequence. Then send the ID sequenced to the card to get + * the card it into command state. + */ +void +idseq(void) +{ + int i; + uchar al; + + outb(IDport, 0); + outb(IDport, 0); + for(al = 0xFF, i = 0; i < 255; i++){ + outb(IDport, al); + if(al & 0x80){ + al <<= 1; + al ^= 0xCF; + } + else + al <<= 1; + } +} + /* * get configuration parameters */ @@ -85,8 +109,7 @@ reset(EtherCtlr *cp) { EtherHw *hw = cp->hw; int i, ea; - ushort acr; - uchar al; + ushort x, acr; cp->rb = xspanalloc(sizeof(EtherBuf)*Nrb, BY2PG, 0); cp->nrb = Nrb; @@ -98,23 +121,12 @@ reset(EtherCtlr *cp) * at the first board that responds, if we ever have more * than one we'll need to modify this sequence. * - * 2. Write two 0 bytes then the ID sequence to the IDport. + * 2. get to cammand state, reset, then return to command state */ - outb(IDport, 0); - outb(IDport, 0); - outb(IDport, 0xc0); - delay(100) - outb(IDport, 0); - outb(IDport, 0); - for(al = 0xFF, i = 0; i < 255; i++){ - outb(IDport, al); - if(al & 0x80){ - al <<= 1; - al ^= 0xCF; - } - else - al <<= 1; - } + idseq(); + outb(IDport, 0xC1); + delay(2); + idseq(); /* * 3. Read the Product ID from the EEPROM. @@ -128,12 +140,12 @@ reset(EtherCtlr *cp) * probably isn't there, so barf. */ outb(IDport, 0x83); - for(acr = 0, i = 0; i < 16; i++){ + for(x = 0, i = 0; i < 16; i++){ delay(5); - acr <<= 1; - acr |= inb(IDport) & 0x01; + x <<= 1; + x |= inb(IDport) & 0x01; } - if((acr & 0xF0FF) != 0x9050) + if((x & 0xF0FF) != 0x9050) return -1; /* @@ -172,9 +184,9 @@ reset(EtherCtlr *cp) outs(hw->addr+EEPROMcmd, (2<<6)|i); while(ins(hw->addr+EEPROMcmd) & 0x8000) ; - acr = ins(hw->addr+EEPROMdata); - cp->ea[ea] = (acr>>8) & 0xFF; - cp->ea[ea+1] = acr & 0xFF; + x = ins(hw->addr+EEPROMdata); + cp->ea[ea] = (x>>8) & 0xFF; + cp->ea[ea+1] = x & 0xFF; } /* diff --git a/pc/fns.h b/pc/fns.h index cb9678a7e3b8fa664fa7b94510759a0811c6808a..ebe7b22b03d579eaca9e3a1a25d10893bffbb647 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -24,8 +24,6 @@ void fpsave(FPsave*); ulong fpstatus(void); ulong getcr0(void); ulong getcr2(void); -void heada20(void); -void headreset(void); void i8042a20(void); void i8042reset(void); void ident(void); @@ -47,11 +45,6 @@ void outb(int, int); void outs(int, ushort); void outss(int, void*, int); void outsl(int, void*, int); -void pmubuzz(int, int); -int pmucpuspeed(int); -void pmulights(int); -int pmumodem(int); -int pmuserial(int); void prhex(ulong); void procrestore(Proc*); void procsave(Proc*); diff --git a/pc/headland.c b/pc/headland.c deleted file mode 100644 index 09e77c0a1959130b5cf624559b3b58cc6ae85b67..0000000000000000000000000000000000000000 --- a/pc/headland.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -/* - * headland system controller (ht21) - */ -enum -{ - /* - * system control port - */ - Head= 0x92, /* control port */ - Reset= (1<<0), /* reset the 386 */ - A20ena= (1<<1), /* enable address line 20 */ -}; - -/* - * enable address bit 20 - */ -void -heada20(void) -{ - outb(Head, A20ena); -} - -/* - * reset machine - */ -void -headreset(void) -{ - outb(Head, Reset); -} diff --git a/pc/main.c b/pc/main.c index 9ce724601c1269c76bf1cf550d7c5c32a7df8862..73d2d96345728fd6259bfd6115b0eb5b6cefc98e 100644 --- a/pc/main.c +++ b/pc/main.c @@ -8,24 +8,19 @@ #include "init.h" #include -/* configuration parameters */ -enum -{ - /* what kind of power management */ - PMUother= 0, - PMUnsx20= 1, - - /* how to reset the processor */ - Resetother= 0, - Reset8042= 1, - Resetheadland= 2, -}; -int pmutype; -int resettype; -char machtype[9]; uchar *sp; /* stack pointer for /boot */ +extern PCArch nsx20, generic, ncr3170; + +PCArch *arch; +PCArch *knownarch[] = +{ + &nsx20, + &ncr3170, + &generic, +}; + void main(void) { @@ -51,7 +46,6 @@ main(void) streaminit(); swapinit(); userinit(); - schedinit(); } @@ -64,21 +58,12 @@ void ident(void) { char *id = (char*)(ROMBIOS + 0xFF40); - int i; + PCArch **p; - for(i = 0; i < 8; i++){ - if(isprint(id[i]) == 0) + for(p = knownarch; *p != &generic; p++) + if(strncmp((*p)->id, id, strlen((*p)->id)) == 0) break; - machtype[i] = id[i]; - } - if(i == 0) - strcpy(machtype, "generic"); - if(strcmp(machtype, "AT&TNSX") == 0){ - pmutype = PMUnsx20; - resettype = Resetheadland; - }else if(strcmp(machtype, "NCRD.0") == 0){ - resettype = Reset8042; - } + arch = *p; } void @@ -117,7 +102,7 @@ init0(void) chandevinit(); if(!waserror()){ - strcpy(tstr, machtype); + strcpy(tstr, arch->id); strcat(tstr, " %s"); ksetterm(tstr); ksetenv("cputype", "386"); @@ -447,15 +432,7 @@ exit(int ispanic) if(ispanic) for(;;); - switch(resettype){ - case Resetheadland: - headreset(); - case Reset8042: - i8042reset(); /* via keyboard controller */ - default: - print("Reset the machine!\n"); - for(;;); - } + (*arch->reset)(); } /* @@ -466,12 +443,10 @@ exit(int ispanic) int cpuspeed(int speed) { - switch(pmutype){ - case PMUnsx20: - return pmucpuspeed(speed); - default: + if(arch->cpuspeed) + return (*arch->cpuspeed)(speed); + else return 0; - } } /* @@ -481,13 +456,8 @@ cpuspeed(int speed) void buzz(int f, int d) { - switch(pmutype){ - case PMUnsx20: - pmubuzz(f, d); - break; - default: - break; - } + if(arch->buzz) + (*arch->buzz)(f, d); } /* @@ -496,13 +466,8 @@ buzz(int f, int d) void lights(int val) { - switch(pmutype){ - case PMUnsx20: - pmulights(val); - break; - default: - break; - } + if(arch->lights) + (*arch->lights)(val); } /* @@ -513,12 +478,10 @@ lights(int val) int serial(int onoff) { - switch(pmutype){ - case PMUnsx20: - return pmuserial(onoff); - default: + if(arch->serialpower) + return (*arch->serialpower)(onoff); + else return 0; - } } /* @@ -529,10 +492,8 @@ serial(int onoff) int modem(int onoff) { - switch(pmutype){ - case PMUnsx20: - return pmumodem(onoff); - default: + if(arch->modempower) + return (*arch->modempower)(onoff); + else return 0; - } } diff --git a/port/sysproc.c b/port/sysproc.c index 7be02418e3daf70573d813758e42f6064cbba649..dadb33c0c72cdb1112d6c2683ba78ac281b6a023 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -308,6 +308,7 @@ sysexec(ulong *arg) nargs++; } ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); + /* * 8-byte align SP for those (e.g. sparc) that need it. * execregs() will subtract another 4 bytes for argc. diff --git a/power/mem.h b/power/mem.h index 3bf43f9349777bc2ce86dc2270f4d3734ec22dd7..a996417647c5744bc5606ace40c0c418d861b17d 100644 --- a/power/mem.h +++ b/power/mem.h @@ -120,7 +120,7 @@ #define UTZERO (UZERO+BY2PG) /* first address in user text */ #define USTKTOP KZERO /* byte just beyond user stack */ #define TSTKTOP (USERADDR+USTKSIZE) /* top of temporary stack */ -#define TSTKSIZ 100 +#define TSTKSIZ 500 #define KZERO KSEG0 /* base of kernel address space */ #define KTZERO (KZERO+0x20000) /* first address in kernel text */ #define USTKSIZE (4*1024*1024) /* size of user stack */