diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/mpc | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/mpc')
| -rw-r--r-- | os/mpc/800io.h | 666 | ||||
| -rw-r--r-- | os/mpc/clock.c | 145 | ||||
| -rw-r--r-- | os/mpc/cpm.c | 695 | ||||
| -rw-r--r-- | os/mpc/cpmtimer.c | 179 | ||||
| -rw-r--r-- | os/mpc/devata.c | 1194 | ||||
| -rw-r--r-- | os/mpc/devbench.c | 243 | ||||
| -rw-r--r-- | os/mpc/devboot.c | 132 | ||||
| -rw-r--r-- | os/mpc/devether.c | 617 | ||||
| -rw-r--r-- | os/mpc/devpcmcia.c | 1076 | ||||
| -rw-r--r-- | os/mpc/devrtc.c | 258 | ||||
| -rw-r--r-- | os/mpc/devtouch.c | 497 | ||||
| -rw-r--r-- | os/mpc/devuart.c | 1450 | ||||
| -rw-r--r-- | os/mpc/dsp.c | 289 | ||||
| -rw-r--r-- | os/mpc/dsp.h | 62 | ||||
| -rw-r--r-- | os/mpc/etherif.h | 37 | ||||
| -rw-r--r-- | os/mpc/etherscc.c | 528 | ||||
| -rw-r--r-- | os/mpc/faultpower.c | 49 | ||||
| -rw-r--r-- | os/mpc/fp.s | 205 | ||||
| -rw-r--r-- | os/mpc/fpi.h | 61 | ||||
| -rw-r--r-- | os/mpc/fpipower.c | 970 | ||||
| -rw-r--r-- | os/mpc/i2c.c | 439 | ||||
| -rw-r--r-- | os/mpc/i2c_spi.srx | 149 | ||||
| -rw-r--r-- | os/mpc/inb.s | 120 | ||||
| -rw-r--r-- | os/mpc/kbd.c | 20 | ||||
| -rw-r--r-- | os/mpc/l.s | 685 | ||||
| -rw-r--r-- | os/mpc/nofp.s | 31 | ||||
| -rw-r--r-- | os/mpc/pcmcia.h | 19 | ||||
| -rw-r--r-- | os/mpc/pit.c | 68 | ||||
| -rw-r--r-- | os/mpc/powerbreak.c | 123 | ||||
| -rw-r--r-- | os/mpc/rmap.c | 106 | ||||
| -rw-r--r-- | os/mpc/screen.c | 832 | ||||
| -rw-r--r-- | os/mpc/screen.h | 60 | ||||
| -rw-r--r-- | os/mpc/spi.c | 243 | ||||
| -rw-r--r-- | os/mpc/trap.c | 554 | ||||
| -rw-r--r-- | os/mpc/usb.h | 62 |
35 files changed, 0 insertions, 12864 deletions
diff --git a/os/mpc/800io.h b/os/mpc/800io.h deleted file mode 100644 index c67ced41..00000000 --- a/os/mpc/800io.h +++ /dev/null @@ -1,666 +0,0 @@ -typedef struct BD BD; -typedef struct CPMdev CPMdev; -typedef struct GTimer GTimer; -typedef struct I2Cdev I2Cdev; -typedef struct PCMconftab PCMconftab; -typedef struct PCMmap PCMmap; -typedef struct PCMslot PCMslot; -typedef struct Ring Ring; - -/* - * MPC800 series IO structures - */ - -enum -{ - /* interrupt vectors (SIU and CPM) */ - VectorPIC= 0, /* level 0 to level 7, assigned by software */ - /* vector assignments are determined by the assignments here */ - PITlevel= 2, - CPIClevel= 4, - PCMCIAio= 5, - PCMCIAstatus= 6, - RTClevel= 7, - VectorIRQ= VectorPIC+8, /* IRQ0 to IRQ7 */ - VectorCPIC= VectorIRQ+8, /* 32 CPM interrupts: 0 (error) to 0x1F (PC15) */ - MaxVector= VectorCPIC+32, -}; - -/* - * these are defined to keep the interface compatible with other - * architectures, but only BUSUNKNOWN is currently used - */ -#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8)) -#define BUSFNO(tbdf) (((tbdf)>>8)&0x07) -#define BUSDNO(tbdf) (((tbdf)>>11)&0x1F) -#define BUSBNO(tbdf) (((tbdf)>>16)&0xFF) -#define BUSTYPE(tbdf) ((tbdf)>>24) -#define BUSBDF(tbdf) ((tbdf)&0x00FFFF00) -#define BUSUNKNOWN (-1) - -/* - * Buffer Descriptors and IO Rings - */ - -struct BD { - ushort status; - ushort length; - ulong addr; -}; - -BD* bdalloc(int); -void bdfree(BD*, int); -void dumpbd(char*, BD*, int); - -enum { - /* Rx BDs, bits common to all protocols */ - BDEmpty= 1<<15, - BDWrap= 1<<13, - BDInt= 1<<12, - BDLast= 1<<11, - BDFirst= 1<<10, - - /* Tx BDs */ - BDReady= 1<<15, - /* BDWrap, BDInt, BDLast */ -}; - - -struct Ring { - BD* rdr; /* receive descriptor ring */ - void* rrb; /* receive ring buffers */ - int rdrx; /* index into rdr */ - int nrdre; /* length of rdr */ - - BD* tdr; /* transmit descriptor ring */ - Block** txb; /* corresponding transmit ring buffers */ - int tdrh; /* host index into tdr */ - int tdri; /* interface index into tdr */ - int ntdre; /* length of tdr */ - int ntq; /* pending transmit requests */ -}; - -#define NEXT(x, l) (((x)+1)%(l)) -#define PREV(x, l) (((x) == 0) ? (l)-1: (x)-1) -#define HOWMANY(x, y) (((x)+((y)-1))/(y)) -#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) - -int ioringinit(Ring*, int, int, int); - -/* - * CPM - */ -enum { - /* commands */ - InitRxTx = 0, - InitRx = 1, - InitTx = 2, - EnterHunt= 3, - StopTx= 4, - GracefulStopTx = 5, - InitIDMA = 5, - RestartTx = 6, - CloseRxBD = 7, - SetGroupAddr = 8, - SetTimer = 8, - GCITimeout = 9, - GCIAbort = 10, - StopIDMA = 11, - StartDSP = 12, - ArmIDMA = 13, - InitDSP = 13, - USBCmd = 15, - - /* bgcr */ - BaudEnable = 1<<16, - - /* sicr */ - CLK1 = 4, /* SCC1,2 */ - CLK2 = 5, - CLK3 = 6, - CLK4 = 7, - CLK5 = CLK1, /* SCC3,4 */ - CLK6 = CLK2, - CLK7 = CLK3, - CLK8 = CLK4, - - /* logical channel IDs mapped to channel ID by cpm.c */ - CPnone = 0, - CPscc1, - CPscc2, - CPscc3, - CPscc4, - CPsmc1, - CPsmc2, - CPdsp1, - CPdsp2, - CPidma1, - CPidma2, - CPtimer, - CPspi, - CPi2c, - CPmax, -}; - -struct CPMdev { - int id; /* CPM channel number */ - int irq; /* CPIC interrupt number */ - int rbase; /* register offset in IO mem */ - int pbase; /* parameter offset in IO mem */ - void* regs; /* kernel address of registers */ - void* param; /* kernel address of parameters */ -}; - -CPMdev* cpmdev(int); -void cpmop(CPMdev*, int, int); -void* cpmalloc(int, int); -void cpmfree(void*, int); -IMM* ioplock(void); -void iopunlock(void); - -int cpmidopen(int, void*); -void cpmidclose(int); -void sccnmsi(int, int, int); -void sccxstop(CPMdev*); -void smcnmsi(int, int); -void smcxstop(CPMdev*); - -/* - * CPM timers - */ -enum { - /* timer modes */ - CaptureRise= 1<<6, - CaptureFall= 2<<6, - CaptureEdge= 3<<6, - TimerToggle= 1<<5, /* toggle TOUTx* pin */ - TimerORI= 1<<4, /* Output Reference Interrupt */ - TimerRestart= 1<<3, - TimerSclk= 1<<1, - TimerSclk16= 2<<1, - TimerTIN= 3<<1, /* clock by falling edge of TINx */ - TimerGate= 1<<0, /* TGATE1* controls timer */ - - /* timer events */ - TimerREF= 1<<1, - TimerCAP= 1<<0 -}; - -struct GTimer{ - int x; - int inuse; - int event; - ushort* tmr; - ushort* trr; - ushort* tcr; - ushort* tcn; - ushort* ter; - void* arg; - void (*interrupt)(Ureg*, void*, GTimer*); -}; -GTimer* gtimer(ushort, ushort, void (*)(Ureg*,void*,GTimer*), void*); -void gtimerset(GTimer*, ushort, int); -void gtimerstart(GTimer*); -void gtimerstop(GTimer*); -void gtimerfree(GTimer*); - -/* - * the structures below follow hardware/firmware layouts in the 8xx manuals: - * mind the data types, offsets and alignment - */ - -/* - * basic IO controller parameters (SMC and SCC) - */ -typedef struct IOCparam IOCparam; -struct IOCparam { - ushort rbase; - ushort tbase; - uchar rfcr; - uchar tfcr; - ushort mrblr; - ulong rstate; - ulong rptr; - ushort rbptr; - ushort rcnt; - ulong rtmp; - ulong tstate; - ulong tptr; - ushort tbptr; - ushort tcnt; - ulong ttmp; -}; - -typedef struct SCCparam SCCparam; -struct SCCparam { - IOCparam; - ulong rcrc; - ulong tcrc; -}; - -typedef struct SCC SCC; -struct SCC { - ulong gsmrl; - ulong gsmrh; - ushort psmr; - uchar rsvscc0[2]; - ushort todr; - ushort dsr; - ushort scce; - uchar rsvscc1[2]; - ushort sccm; - uchar rsvscc3; - uchar sccs; - ushort irmode; - ushort irsip; -}; - -typedef struct SMC SMC; -struct SMC { - uchar pad1[2]; - ushort smcmr; - uchar pad2[2]; - uchar smce; - uchar pad3[3]; - uchar smcm; - uchar pad4[5]; -}; - -typedef struct SPI SPI; -struct SPI { - ushort spmode; - uchar res1[4]; - uchar spie; - uchar res2[3]; - uchar spim; - uchar res3[2]; - uchar spcom; - uchar res4[10]; -}; - -typedef struct USB USB; -struct USB { /* 823 only */ - uchar usmod; - uchar usadr; - uchar uscom; - uchar rsvu1; - ushort usep[4]; - uchar rsvu2[4]; - ushort usber; - uchar rsvu3[2]; - ushort usbmr; - uchar rsvu4; - uchar usbs; - uchar rsvu5[8]; -}; - -typedef struct IMM IMM; -struct IMM { - struct { /* general SIU */ - ulong siumcr; - ulong sypcr; - uchar rsv0[0xE-0x8]; - ushort swsr; - ulong sipend; - ulong simask; - ulong siel; - uchar sivec; - uchar padv[3]; - ulong tesr; - uchar rsv1[0x30-0x24]; - ulong sdcr; - uchar rsv2[0x80-0x34]; - }; - struct { /* PCMCIA */ - struct { - ulong base; - ulong option; - } pcmr[8]; - uchar rsv3[0xe0-0xc0]; - ulong pgcr[2]; - ulong pscr; - uchar rsv4[0xf0-0xec]; - ulong pipr; - uchar rsv5[4]; - ulong per; - uchar rsv6[4]; - }; - struct { /* MEMC */ - struct { - ulong base; - ulong option; - } memc[8]; - uchar rsv7a[0x24]; - ulong mar; - ulong mcr; - uchar rsv7b[4]; - ulong mamr; - ulong mbmr; - ushort mstat; - ushort mptpr; - ulong mdr; - uchar rsv7c[0x80]; - }; - struct { /* system integration timers */ - ushort tbscr; - uchar rsv8a[2]; - ulong tbrefu; - ulong tbrefl; - uchar rsv8b[0x14]; - ushort rtcsc; - uchar rsv8c[2]; - ulong rtc; - ulong rtsec; - ulong rtcal; - uchar rsv8d[0x10]; - ushort piscr; - ushort rsv8e; - ulong pitc; - ulong pitr; - uchar rsv8f[0x34]; - }; - struct { /* 280: clocks and resets */ - ulong sccr; - ulong plprcr; - ulong rsr; - uchar rsv9[0x300-0x28c]; - }; - struct { /* 300: system integration timers keys */ - ulong tbscrk; - ulong tbrefuk; - ulong tbreflk; - ulong tbk; - uchar rsv10a[0x10]; - ulong rtcsck; - ulong rtck; - ulong rtseck; - ulong rtcalk; - uchar rsv10b[0x10]; - ulong piscrk; - ulong pitck; - uchar rsv10c[0x38]; - }; - struct { /* 380: clocks and resets keys */ - ulong sccrk; - ulong plprcrk; - ulong rsrk; - uchar rsv11[0x800-0x38C]; - }; - struct { /* 800: video controller */ - ushort vccr; - ushort pad11a; - uchar vsr; - uchar pad11b; - uchar vcmr; - uchar pad11c; - ulong vbcb; - ulong pad11d; - ulong vfcr0; - ulong vfaa0; - ulong vfba0; - ulong vfcr1; - ulong vfaa1; - ulong vfba1; - uchar rsv11a[0x840-0x828]; - }; - struct { /* 840: LCD */ - ulong lccr; - ulong lchcr; - ulong lcvcr; - ulong rsv11b; - ulong lcfaa; - ulong lcfba; - uchar lcsr; - uchar rsv11c[0x860-0x859]; - }; - struct { /* 860: I2C */ - uchar i2mod; - uchar rsv12a[3]; - uchar i2add; - uchar rsv12b[3]; - uchar i2brg; - uchar rsv12c[3]; - uchar i2com; - uchar rsv12d[3]; - uchar i2cer; - uchar rsv12e[3]; - uchar i2cmr; - uchar rsv12[0x900-0x875]; - }; - struct { /* 900: DMA */ - uchar rsv13[4]; - ulong sdar; - uchar sdsr; - uchar pad1[3]; - uchar sdmr; - uchar pad2[3]; - uchar idsr1; - uchar pad3[3]; - uchar idmr1; - uchar pad4[3]; - uchar idsr2; - uchar pad5[3]; - uchar idmr2; - uchar pad6[0x930-0x91D]; - }; - struct { /* CPM interrupt control */ - ushort civr; - uchar pad7[0x940-0x932]; - ulong cicr; - ulong cipr; - ulong cimr; - ulong cisr; - }; - struct { /* input/output port */ - ushort padir; - ushort papar; - ushort paodr; - ushort padat; - uchar pad8[8]; - ushort pcdir; - ushort pcpar; - ushort pcso; - ushort pcdat; - ushort pcint; - uchar pad9[6]; - ushort pddir; - ushort pdpar; - ushort rsv14a; - ushort pddat; - uchar rsv14[0x980-0x978]; - }; - struct { /* CPM timers */ - ushort tgcr; - uchar rsv15a[0x990-0x982]; - ushort tmr1; - ushort tmr2; - ushort trr1; - ushort trr2; - ushort tcr1; - ushort tcr2; - ushort tcn1; - ushort tcn2; - ushort tmr3; - ushort tmr4; - ushort trr3; - ushort trr4; - ushort tcr3; - ushort tcr4; - ushort tcn3; - ushort tcn4; - ushort ter1; - ushort ter2; - ushort ter3; - ushort ter4; - uchar rsv15[0x9C0-0x9B8]; - }; - struct { /* CPM */ - ushort cpcr; - uchar res0[2]; - ushort rccr; - uchar res1; - uchar rmds; - uchar res2a[4]; - ushort rctr1; - ushort rctr2; - ushort rctr3; - ushort rctr4; - uchar res2[2]; - ushort rter; - uchar res3[2]; - ushort rtmr; - uchar rsv16[0x9F0-0x9DC]; - }; - union { /* BRG */ - struct { - ulong brgc1; - ulong brgc2; - ulong brgc3; - ulong brgc4; - }; - ulong brgc[4]; - }; - uchar skip0[0xAB2-0xA00]; /* USB, SCC, SMC, SPI: address using cpmdev(CP...)->regs */ - struct { /* PIP */ - ushort pipc; /* not 823 */ - ushort ptpr; /* not 823 */ - ulong pbdir; - ulong pbpar; - uchar pad10[2]; - ushort pbodr; - ulong pbdat; - uchar pad11[0xAE0-0xAC8]; - }; - struct { /* SI */ - ulong simode; - uchar sigmr; - uchar pad12; - uchar sistr; - uchar sicmr; - uchar pad13[4]; - ulong sicr; - ulong sirp; - uchar pad14[0xB00-0xAF4]; - }; - ulong vcram[64]; - ushort siram[256]; - ushort lcdmap[256]; -}; - -/* - * PCMCIA structures known by both ../port/cis.c and the pcmcia driver - */ - -/* - * Map between physical memory space and PCMCIA card memory space. - */ -struct PCMmap { - ulong ca; /* card address */ - ulong cea; /* card end address */ - ulong isa; /* local virtual address */ - int len; /* length of the ISA area */ - int attr; /* attribute memory */ - int slotno; /* owning slot */ - int ref; -}; - -/* - * a PCMCIA configuration entry - */ -struct PCMconftab -{ - int index; - ushort irqs; /* legal irqs */ - uchar irqtype; - uchar bit16; /* true for 16 bit access */ - uchar nlines; - struct { - ulong start; - ulong len; - PCMmap* map; - } io[16]; - int nio; - int vcc; - int vpp1; - int vpp2; - uchar memwait; - ulong maxwait; - ulong readywait; - ulong otherwait; -}; - -/* - * PCMCIA card slot - */ -struct PCMslot -{ -// RWlock; - -// Ref ref; -Ref; - - void* ctlr; /* controller for this slot */ - - long memlen; /* memory length */ - uchar slotno; /* slot number */ - uchar slotshift; /* >> register to meet mask; << mask to meet register */ - void *regs; /* i/o registers */ - void *mem; /* memory */ - void *attr; /* attribute memory */ - - /* status */ - uchar occupied; /* card in the slot */ - uchar configed; /* card configured */ - uchar busy; - uchar powered; - uchar battery; - uchar wrprot; - uchar enabled; - uchar special; - uchar dsize; - uchar v3_3; - uchar voltage; - - /* cis info */ - int cisread; /* set when the cis has been read */ - char verstr[512]; /* version string */ - uchar cpresent; /* config registers present */ - ulong caddr; /* relative address of config registers */ - int nctab; /* number of config table entries */ - PCMconftab ctab[8]; - PCMconftab *def; /* default conftab */ - - /* maps are fixed */ - PCMmap memmap; - PCMmap attrmap; - - struct { - void (*f)(Ureg*, void*); - void *arg; - } intr; - struct { - void (*f)(void*, int); - void *arg; - } notify; -}; - -/* ../port/cis.c */ -void pcmcisread(PCMslot*); -int pcmcistuple(int, int, int, void*, int); - -/* devpcmcia.c */ -PCMmap* pcmmap(int, ulong, int, int); -void pcmunmap(int, PCMmap*); - -/* - * used by ../port/devi2c.c and i2c.c - */ -struct I2Cdev { - int addr; - int salen; /* length in bytes of subaddress, if used; 0 otherwise */ - int tenbit; /* 10-bit addresses */ -}; - -long i2crecv(I2Cdev*, void*, long, ulong); -long i2csend(I2Cdev*, void*, long, ulong); -void i2csetup(int); diff --git a/os/mpc/clock.c b/os/mpc/clock.c deleted file mode 100644 index f8ed362f..00000000 --- a/os/mpc/clock.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -#include <isa.h> -#include <interp.h> - -typedef struct Clock0link Clock0link; -typedef struct Clock0link { - void (*clock)(void); - Clock0link* link; -} Clock0link; - -static Clock0link *clock0link; -static Lock clock0lock; -ulong clkrelinq; -void (*kproftick)(ulong); /* set by devkprof.c when active */ -void (*archclocktick)(void); /* set by arch*.c when desired */ - -Timer* -addclock0link(void (*clock)(void), int) -{ - Clock0link *lp; - - if((lp = malloc(sizeof(Clock0link))) == 0){ - print("addclock0link: too many links\n"); - return nil; - } - ilock(&clock0lock); - lp->clock = clock; - lp->link = clock0link; - clock0link = lp; - iunlock(&clock0lock); - return nil; -} - -void -delay(int l) -{ - ulong i, j; - - j = m->delayloop; - while(l-- > 0) - for(i=0; i < j; i++) - ; -} - -void -microdelay(int l) -{ - ulong i; - - l *= m->delayloop; - l /= 1000; - if(l <= 0) - l = 1; - for(i = 0; i < l; i++) - ; -} - -enum { - Timebase = 4, /* system clock cycles per time base cycle */ -}; - -static ulong clkreload; - -void -clockinit(void) -{ - long x; - - m->delayloop = m->cpuhz/1000; /* initial estimate */ - do { - x = gettbl(); - delay(10); - x = gettbl() - x; - } while(x < 0); - - /* - * fix count - */ - m->delayloop = ((vlong)m->delayloop*(10*m->clockgen/1000))/(x*Timebase); - if(m->delayloop == 0) - m->delayloop = 1; - - clkreload = (m->clockgen/Timebase)/HZ-1; - putdec(clkreload); -} - -void -clockintr(Ureg *ur) -{ - Clock0link *lp; - long v; - - v = -getdec(); - if(v > clkreload/2){ - if(v > clkreload) - m->ticks += v/clkreload; - v = 0; - } - putdec(clkreload-v); - - /* watchdog */ - if(m->iomem->sypcr & (1<<2)){ - m->iomem->swsr = 0x556c; - m->iomem->swsr = 0xaa39; - } - - m->ticks++; - if(archclocktick != nil) - archclocktick(); - - if(up) - up->pc = ur->pc; - - checkalarms(); - if(m->machno == 0) { - if(kproftick != nil) - (*kproftick)(ur->pc); - if(canlock(&clock0lock)){ - for(lp = clock0link; lp; lp = lp->link) - lp->clock(); - unlock(&clock0lock); - } - } - - if(up && up->state == Running){ - if(cflag && up->type == Interp && tready(nil)) - ur->cr |= 1; /* set flag in condition register for ../../libinterp/comp-power.c:/^schedcheck */ - } - /* other preemption checks are done by trap.c */ -} - -uvlong -fastticks(uvlong *hz) -{ - if(hz) - *hz = HZ; - return m->ticks; -} diff --git a/os/mpc/cpm.c b/os/mpc/cpm.c deleted file mode 100644 index e985d947..00000000 --- a/os/mpc/cpm.c +++ /dev/null @@ -1,695 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -typedef struct Chanuse Chanuse; -struct Chanuse { - Lock; - void* owner; -} ; - -enum { - BDSIZE= 1024, /* IO memory reserved for buffer descriptors */ - CPMSIZE= 1024, /* IO memory reserved for other uses */ - - /* channel IDs */ - SCC1ID= 0, - I2CID= 1, - IDMA1ID= 1, - SCC2ID= 4, - SPIID= 5, - IDMA2ID= 5, - TIMERID= 5, - SCC3ID= 8, - SMC1ID= 9, - DSP1ID= 9, - SCC4ID= 12, - SMC2ID= 13, - DSP2ID= 13, - NCPMID= 16, - - NSCC = 4, - - /* SCC.gsmr_l */ - ENR = 1<<5, /* enable receiver */ - ENT = 1<<4, /* enable transmitter */ - - NSMC = 2, - - /* SMC.smcmr */ - TEN = 1<<1, /* transmitter enable */ - REN = 1<<0, /* receiver enable */ -}; - -static Map bdmapv[BDSIZE/sizeof(BD)]; -static RMap bdmap = {"buffer descriptors"}; - -static Map cpmmapv[CPMSIZE/sizeof(ulong)]; -static RMap cpmmap = {"CPM memory"}; - -static Lock cpmlock; - -static struct { - Lock; - ulong avail; -} brgens; - -static Chanuse cpmids[NCPMID]; -static CPMdev cpmdevinfo[] = { - [CPscc1] {SCC1ID, 0x1E, 0xA00, 0x3C00}, - [CPscc2] {SCC2ID, 0x1D, 0xA20, 0x3D00}, - [CPscc3] {SCC3ID, 0x1C, 0xA40, 0x3E00}, - [CPscc4] {SCC4ID, 0x1B, 0xA60, 0x3F00}, - [CPsmc1] {SMC1ID, 0x04, 0xA80, 0x3E80}, - [CPsmc2] {SMC2ID, 0x03, 0xA90, 0x3F80}, - [CPdsp1] {DSP1ID, 0x16, 0, 0x3EC0}, - [CPdsp2] {DSP2ID, 0x16, 0, 0x3FC0}, - [CPidma1] {IDMA1ID, 0x15, 0, 0x3CC0}, - [CPidma2] {IDMA2ID, 0x14, 0, 0x3DC0}, - [CPtimer] {TIMERID, 0x11, 0, 0x3DB0}, - [CPspi] {SPIID, 0x05, 0xAA0, 0x3D80}, /* parameters relocated below */ - [CPi2c] {I2CID, 0x10, 0x860, 0x3C80}, /* parameters relocated below */ -}; - -static void i2cspireloc(void); -static void* relocateparam(ulong, int); - -/* - * initialise the communications processor module - * and associated device registers - */ -void -cpminit(void) -{ - IMM *io; - - io = m->iomem; - io->sdcr = 1; - io->rccr = 0; - io->rmds = 0; - io->lccr = 0; /* disable LCD */ - io->vccr = 0; /* disable video */ - io->i2mod = 0; /* stop I2C */ - io->pcint = 0; /* disable all port C interrupts */ - io->pcso = 0; - io->pcdir =0; - io->pcpar = 0; - io->pcdat = 0; - io->papar = 0; - io->padir = 0; - io->paodr = 0; - io->padat = 0; - io->pbpar = 0; - io->pbdir = 0; - io->pbodr = 0; - io->pbdat = 0; - io->tgcr = 0x2222; /* reset timers, low-power stop */ - eieio(); - - for(io->cpcr = 0x8001; io->cpcr & 1;) /* reset all CPM channels */ - eieio(); - - mapinit(&bdmap, bdmapv, sizeof(bdmapv)); - mapfree(&bdmap, DPBASE, BDSIZE); - mapinit(&cpmmap, cpmmapv, sizeof(cpmmapv)); - mapfree(&cpmmap, DPBASE+BDSIZE, CPMSIZE); - - if(m->cputype == 0x50 && (getimmr() & 0xFFFF) <= 0x2001) - brgens.avail = 0x3; - else - brgens.avail = 0xF; - i2cspireloc(); -} - -/* - * return parameters defining a CPM device, given logical ID - */ -CPMdev* -cpmdev(int n) -{ - CPMdev *d; - - if(n < 0 || n >= nelem(cpmdevinfo)) - panic("cpmdev"); - d = &cpmdevinfo[n]; - if(d->param == nil && d->pbase != 0){ - if((n == CPi2c || n == CPspi)){ - d->param = relocateparam(d->pbase, 0xB0-0x80); /* relocate */ - if(d->param == nil) - return nil; - } else - d->param = (char*)m->iomem+d->pbase; - } - if(d->rbase != 0) - d->regs = (char*)m->iomem+d->rbase; - return d; -} - -/* - * issue a request to a CPM device - */ -void -cpmop(CPMdev *cpd, int op, int param) -{ - IMM *io; - - ilock(&cpmlock); - io = m->iomem; - while(io->cpcr & 1) - eieio(); - io->cpcr = (op<<8)|(cpd->id<<4)|(param<<1)|1; - eieio(); - while(io->cpcr & 1) - eieio(); - iunlock(&cpmlock); -} - -/* - * lock the shared IO memory and return a reference to it - */ -IMM* -ioplock(void) -{ - ilock(&cpmlock); - return m->iomem; -} - -/* - * release the lock on the shared IO memory - */ -void -iopunlock(void) -{ - eieio(); - iunlock(&cpmlock); -} - -/* - * connect SCCx clocks in NSMI mode (x=1 for USB) - */ -void -sccnmsi(int x, int rcs, int tcs) -{ - IMM *io; - ulong v; - int sh; - - sh = (x-1)*8; /* each SCCx field in sicr is 8 bits */ - v = (((rcs&7)<<3) | (tcs&7)) << sh; - io = ioplock(); - io->sicr = (io->sicr & ~(0xFF<<sh)) | v; - iopunlock(); -} - -/* - * connect SMCx clock in NSMI mode - */ -void -smcnmsi(int x, int cs) -{ - IMM *io; - ulong v; - int sh; - - if(x == 1) - sh = 0; - else - sh = 16; - v = cs << (12+sh); - io = ioplock(); - io->simode = (io->simode & ~(0xF000<<sh)) | v; /* SMCx to NMSI mode, set Tx/Rx clock */ - iopunlock(); -} - -/* - * claim the use of a CPM ID (SCC, SMC) that might be used by two mutually exclusive devices, - * for the caller determined by the given parameter (which must be unique). - * returns non-zero if the resource is already in use. - */ -int -cpmidopen(int id, void *owner) -{ - Chanuse *use; - - use = &cpmids[id]; - ilock(use); - if(use->owner != nil && use->owner != owner){ - iunlock(use); - return -1; - } - use->owner = owner; - iunlock(use); - return 0; -} - -/* - * release a previously claimed CPM ID - */ -void -cpmidclose(int id) -{ - Chanuse *use; - - use = &cpmids[id]; - ilock(use); - use->owner = nil; - iunlock(use); -} - -/* - * if SCC d is currently enabled, shut it down - */ -void -sccxstop(CPMdev *d) -{ - SCC *scc; - - if(d == nil) - return; - scc = d->regs; - if(scc->gsmrl & (ENT|ENR)){ - if(scc->gsmrl & ENT) - cpmop(d, GracefulStopTx, 0); - if(scc->gsmrl & ENR) - cpmop(d, CloseRxBD, 0); - delay(1); - scc->gsmrl &= ~(ENT|ENR); /* disable current use */ - eieio(); - } - scc->sccm = 0; /* mask interrupts */ -} - -/* - * if SMC d is currently enabled, shut it down - */ -void -smcxstop(CPMdev *d) -{ - SMC *smc; - - if(d == nil) - return; - smc = d->regs; - if(smc->smcmr & (TEN|REN)){ - if(smc->smcmr & TEN) - cpmop(d, StopTx, 0); - if(smc->smcmr & REN) - cpmop(d, CloseRxBD, 0); - delay(1); - smc->smcmr &= ~(TEN|REN); - eieio(); - } - smc->smcm = 0; /* mask interrupts */ -} - -/* - * allocate a buffer descriptor - */ -BD * -bdalloc(int n) -{ - ulong a; - - a = rmapalloc(&bdmap, 0, n*sizeof(BD), sizeof(BD)); - if(a == 0) - panic("bdalloc"); - return KADDR(a); -} - -/* - * free a buffer descriptor - */ -void -bdfree(BD *b, int n) -{ - if(b){ - eieio(); - mapfree(&bdmap, PADDR(b), n*sizeof(BD)); - } -} - -/* - * print a buffer descriptor and its data (when debugging) - */ -void -dumpbd(char *name, BD *b, int maxn) -{ - uchar *d; - int i; - - print("%s #%4.4lux: s=#%4.4ux l=%ud a=#%8.8lux", name, PADDR(b)&0xFFFF, b->status, b->length, b->addr); - if(maxn > b->length) - maxn = b->length; - if(b->addr != 0){ - d = KADDR(b->addr); - for(i=0; i<maxn; i++) - print(" %2.2ux", d[i]); - if(i < b->length) - print(" ..."); - } - print("\n"); -} - -/* - * allocate memory from the shared IO memory space - */ -void * -cpmalloc(int n, int align) -{ - ulong a; - - a = rmapalloc(&cpmmap, 0, n, align); - if(a == 0) - panic("cpmalloc"); - return KADDR(a); -} - -/* - * free previously allocated shared memory - */ -void -cpmfree(void *p, int n) -{ - if(p != nil && n > 0){ - eieio(); - mapfree(&cpmmap, PADDR(p), n); - } -} - -/* - * allocate a baud rate generator, returning its index - * (or -1 if none is available) - */ -int -brgalloc(void) -{ - int n; - - lock(&brgens); - for(n=0; brgens.avail!=0; n++) - if(brgens.avail & (1<<n)){ - brgens.avail &= ~(1<<n); - unlock(&brgens); - return n; - } - unlock(&brgens); - return -1; -} - -/* - * free a previously allocated baud rate generator - */ -void -brgfree(int n) -{ - if(n >= 0){ - if(n > 3 || brgens.avail & (1<<n)) - panic("brgfree"); - lock(&brgens); - brgens.avail |= 1 << n; - unlock(&brgens); - } -} - -/* - * return a value suitable for loading into a baud rate - * generator to produce the given rate if the generator - * is prescaled by the given amount (typically 16). - * the value must be or'd with BaudEnable to start the generator. - */ -ulong -baudgen(int rate, int scale) -{ - int d; - - rate *= scale; - d = (2*m->cpuhz+rate)/(2*rate) - 1; - if(d < 0) - d = 0; - if(d >= (1<<12)) - return ((d+15)>>(4-1))|1; /* divider too big: enable prescale by 16 */ - return d<<1; -} - -/* - * initialise receive and transmit buffer rings. - */ -int -ioringinit(Ring* r, int nrdre, int ntdre, int bufsize) -{ - int i, x; - - /* the ring entries must be aligned on sizeof(BD) boundaries */ - r->nrdre = nrdre; - if(r->rdr == nil) - r->rdr = bdalloc(nrdre); - /* the buffer size must align with cache lines since the cache doesn't snoop */ - bufsize = (bufsize+CACHELINESZ-1)&~(CACHELINESZ-1); - if(r->rrb == nil) - r->rrb = malloc(nrdre*bufsize); - if(r->rdr == nil || r->rrb == nil) - return -1; - dcflush(r->rrb, nrdre*bufsize); - x = PADDR(r->rrb); - for(i = 0; i < nrdre; i++){ - r->rdr[i].length = 0; - r->rdr[i].addr = x; - r->rdr[i].status = BDEmpty|BDInt; - x += bufsize; - } - r->rdr[i-1].status |= BDWrap; - r->rdrx = 0; - - r->ntdre = ntdre; - if(r->tdr == nil) - r->tdr = bdalloc(ntdre); - if(r->txb == nil) - r->txb = malloc(ntdre*sizeof(Block*)); - if(r->tdr == nil || r->txb == nil) - return -1; - for(i = 0; i < ntdre; i++){ - r->txb[i] = nil; - r->tdr[i].addr = 0; - r->tdr[i].length = 0; - r->tdr[i].status = 0; - } - r->tdr[i-1].status |= BDWrap; - r->tdrh = 0; - r->tdri = 0; - r->ntq = 0; - return 0; -} - -/* - * Allocate a new parameter block for I2C or SPI, - * and plant a pointer to it for the microcode, returning the kernel address. - * See Motorola errata and microcode package: - * the design botch is that the parameters for the SCC2 ethernet overlap the - * SPI/I2C parameter space; this compensates by relocating the latter. - * This routine may be used iff i2cspireloc is used (and it is, above). - */ -static void* -relocateparam(ulong olda, int nb) -{ - void *p; - - if(olda < (ulong)m->iomem) - olda += (ulong)m->iomem; - p = cpmalloc(nb, 32); /* ``RPBASE must be multiple of 32'' */ - if(p == nil) - return p; - *(ushort*)KADDR(olda+0x2C) = PADDR(p); /* set RPBASE */ - eieio(); - return p; -} - -/* - * I2C/SPI microcode package from Motorola - * (to relocate I2C/SPI parameters), which was distributed - * on their web site in S-record format. - * - * May 1998 - */ - -/*S00600004844521B*/ -static ulong ubase1 = 0x2000; -static ulong ucode1[] = { - /* #02202000 */ 0x7FFFEFD9, - /* #02202004 */ 0x3FFD0000, - /* #02202008 */ 0x7FFB49F7, - /* #0220200C */ 0x7FF90000, - /* #02202010 */ 0x5FEFADF7, - /* #02202014 */ 0x5F89ADF7, - /* #02202018 */ 0x5FEFAFF7, - /* #0220201C */ 0x5F89AFF7, - /* #02202020 */ 0x3A9CFBC8, - /* #02202024 */ 0xE7C0EDF0, - /* #02202028 */ 0x77C1E1BB, - /* #0220202C */ 0xF4DC7F1D, - /* #02202030 */ 0xABAD932F, - /* #02202034 */ 0x4E08FDCF, - /* #02202038 */ 0x6E0FAFF8, - /* #0220203C */ 0x7CCF76CF, - /* #02202040 */ 0xFD1FF9CF, - /* #02202044 */ 0xABF88DC6, - /* #02202048 */ 0xAB5679F7, - /* #0220204C */ 0xB0937383, - /* #02202050 */ 0xDFCE79F7, - /* #02202054 */ 0xB091E6BB, - /* #02202058 */ 0xE5BBE74F, - /* #0220205C */ 0xB3FA6F0F, - /* #02202060 */ 0x6FFB76CE, - /* #02202064 */ 0xEE0DF9CF, - /* #02202068 */ 0x2BFBEFEF, - /* #0220206C */ 0xCFEEF9CF, - /* #02202070 */ 0x76CEAD24, - /* #02202074 */ 0x90B2DF9A, - /* #02202078 */ 0x7FDDD0BF, - /* #0220207C */ 0x4BF847FD, - /* #02202080 */ 0x7CCF76CE, - /* #02202084 */ 0xCFEF7E1F, - /* #02202088 */ 0x7F1D7DFD, - /* #0220208C */ 0xF0B6EF71, - /* #02202090 */ 0x7FC177C1, - /* #02202094 */ 0xFBC86079, - /* #02202098 */ 0xE722FBC8, - /* #0220209C */ 0x5FFFDFFF, - /* #022020A0 */ 0x5FB2FFFB, - /* #022020A4 */ 0xFBC8F3C8, - /* #022020A8 */ 0x94A67F01, - /* #022020AC */ 0x7F1D5F39, - /* #022020B0 */ 0xAFE85F5E, - /* #022020B4 */ 0xFFDFDF96, - /* #022020B8 */ 0xCB9FAF7D, - /* #022020BC */ 0x5FC1AFED, - /* #022020C0 */ 0x8C1C5FC1, - /* #022020C4 */ 0xAFDD5FC3, - /* #022020C8 */ 0xDF9A7EFD, - /* #022020CC */ 0xB0B25FB2, - /* #022020D0 */ 0xFFFEABAD, - /* #022020D4 */ 0x5FB2FFFE, - /* #022020D8 */ 0x5FCE600B, - /* #022020DC */ 0xE6BB600B, - /* #022020E0 */ 0x5FCEDFC6, - /* #022020E4 */ 0x27FBEFDF, - /* #022020E8 */ 0x5FC8CFDE, - /* #022020EC */ 0x3A9CE7C0, - /* #022020F0 */ 0xEDF0F3C8, - /* #022020F4 */ 0x7F0154CD, - /* #022020F8 */ 0x7F1D2D3D, - /* #022020FC */ 0x363A7570, - /* #02202100 */ 0x7E0AF1CE, - /* #02202104 */ 0x37EF2E68, - /* #02202108 */ 0x7FEE10EC, - /* #0220210C */ 0xADF8EFDE, - /* #02202110 */ 0xCFEAE52F, - /* #02202114 */ 0x7D0FE12B, - /* #02202118 */ 0xF1CE5F65, - /* #0220211C */ 0x7E0A4DF8, - /* #02202120 */ 0xCFEA5F72, - /* #02202124 */ 0x7D0BEFEE, - /* #02202128 */ 0xCFEA5F74, - /* #0220212C */ 0xE522EFDE, - /* #02202130 */ 0x5F74CFDA, - /* #02202134 */ 0x0B627385, - /* #02202138 */ 0xDF627E0A, - /* #0220213C */ 0x30D8145B, - /* #02202140 */ 0xBFFFF3C8, - /* #02202144 */ 0x5FFFDFFF, - /* #02202148 */ 0xA7F85F5E, - /* #0220214C */ 0xBFFE7F7D, - /* #02202150 */ 0x10D31450, - /* #02202154 */ 0x5F36BFFF, - /* #02202158 */ 0xAF785F5E, - /* #0220215C */ 0xBFFDA7F8, - /* #02202160 */ 0x5F36BFFE, - /* #02202164 */ 0x77FD30C0, - /* #02202168 */ 0x4E08FDCF, - /* #0220216C */ 0xE5FF6E0F, - /* #02202170 */ 0xAFF87E1F, - /* #02202174 */ 0x7E0FFD1F, - /* #02202178 */ 0xF1CF5F1B, - /* #0220217C */ 0xABF80D5E, - /* #02202180 */ 0x5F5EFFEF, - /* #02202184 */ 0x79F730A2, - /* #02202188 */ 0xAFDD5F34, - /* #0220218C */ 0x47F85F34, - /* #02202190 */ 0xAFED7FDD, - /* #02202194 */ 0x50B24978, - /* #02202198 */ 0x47FD7F1D, - /* #0220219C */ 0x7DFD70AD, - /* #022021A0 */ 0xEF717EC1, - /* #022021A4 */ 0x6BA47F01, - /* #022021A8 */ 0x2D267EFD, - /* #022021AC */ 0x30DE5F5E, - /* #022021B0 */ 0xFFFD5F5E, - /* #022021B4 */ 0xFFEF5F5E, - /* #022021B8 */ 0xFFDF0CA0, - /* #022021BC */ 0xAFED0A9E, - /* #022021C0 */ 0xAFDD0C3A, - /* #022021C4 */ 0x5F3AAFBD, - /* #022021C8 */ 0x7FBDB082, - /* #022021CC */ 0x5F8247F8, -}; - -/*S00600004844521B*/ -static ulong ubase2 = 0x2F00; -static ulong ucode2[] = { - /* #02202F00 */ 0x3E303430, - /* #02202F04 */ 0x34343737, - /* #02202F08 */ 0xABF7BF9B, - /* #02202F0C */ 0x994B4FBD, - /* #02202F10 */ 0xBD599493, - /* #02202F14 */ 0x349FFF37, - /* #02202F18 */ 0xFB9B177D, - /* #02202F1C */ 0xD9936956, - /* #02202F20 */ 0xBBFDD697, - /* #02202F24 */ 0xBDD2FD11, - /* #02202F28 */ 0x31DB9BB3, - /* #02202F2C */ 0x63139637, - /* #02202F30 */ 0x93733693, - /* #02202F34 */ 0x193137F7, - /* #02202F38 */ 0x331737AF, - /* #02202F3C */ 0x7BB9B999, - /* #02202F40 */ 0xBB197957, - /* #02202F44 */ 0x7FDFD3D5, - /* #02202F48 */ 0x73B773F7, - /* #02202F4C */ 0x37933B99, - /* #02202F50 */ 0x1D115316, - /* #02202F54 */ 0x99315315, - /* #02202F58 */ 0x31694BF4, - /* #02202F5C */ 0xFBDBD359, - /* #02202F60 */ 0x31497353, - /* #02202F64 */ 0x76956D69, - /* #02202F68 */ 0x7B9D9693, - /* #02202F6C */ 0x13131979, - /* #02202F70 */ 0x79376935, -}; - -/* - * compensate for chip design botch by installing - * microcode to relocate I2C and SPI parameters away - * from the ethernet parameters - */ -static void -i2cspireloc(void) -{ - IMM *io; - static int done; - - if(done) - return; - io = m->iomem; - io->rccr &= ~3; - memmove((uchar*)m->iomem+ubase1, ucode1, sizeof(ucode1)); - memmove((uchar*)m->iomem+ubase2, ucode2, sizeof(ucode2)); - io->rctr1 = 0x802a; /* relocate SPI */ - io->rctr2 = 0x8028; /* relocate SPI */ - io->rctr3 = 0x802e; /* relocate I2C */ - io->rctr4 = 0x802c; /* relocate I2C */ - io->rccr |= 1; - done = 1; -} diff --git a/os/mpc/cpmtimer.c b/os/mpc/cpmtimer.c deleted file mode 100644 index bda25dcf..00000000 --- a/os/mpc/cpmtimer.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -enum { - Ntimer = 4 /* maximum allowed by hardware */ -}; - -static struct { - Lock; - int init; - int ntimer; /* actual timers on this chip revision */ - GTimer t[Ntimer]; -} cpmtimers; - -static uchar timerirq[] = {0x19, 0x12, 0x0C, 0x07}; - -static void gtimerinit(int, ushort*, ushort*); - -static void -gtimerreset(void) -{ - IMM *io; - int i; - - ilock(&cpmtimers); - if(!cpmtimers.init){ - if(m->cputype == 0x50 && (getimmr() & 0xFFFF) <= 0x2001) - cpmtimers.ntimer = 2; - else - cpmtimers.ntimer = Ntimer; - io = m->iomem; - io->tgcr = 0x2222; /* reset timers, low-power stop */ - for(i=0; i<cpmtimers.ntimer; i++) - gtimerinit(i, &io->tmr1+i, &io->ter1+i); - cpmtimers.init = 1; - } - iunlock(&cpmtimers); -} - -static void -gtimerintr(Ureg *ur, void *arg) -{ - GTimer *t; - - t = arg; - t->event = *t->ter; - *t->ter = t->event; - if(t->inuse && t->interrupt != nil) - t->interrupt(ur, t->arg, t); -} - -static void -gtimerinit(int i, ushort *tmr, ushort *ter) -{ - GTimer *t; - char name[KNAMELEN]; - - snprint(name, sizeof(name), "timer.%d", i); - t = &cpmtimers.t[i]; - t->x = i*4; /* field in tgcr */ - t->inuse = 0; - t->interrupt = nil; - t->tmr = tmr; - t->trr = tmr+2; - t->tcr = tmr+4; - t->tcn = tmr+6; - t->ter = ter; - intrenable(VectorCPIC+timerirq[i], gtimerintr, t, BUSUNKNOWN, name); -} - -GTimer* -gtimer(ushort mode, ushort ref, void (*intr)(Ureg*,void*,GTimer*), void *arg) -{ - GTimer *t; - int i; - - t = cpmtimers.t; - if(!cpmtimers.init) - gtimerreset(); - ilock(&cpmtimers); - for(i=0; ; i++){ - if(i >= cpmtimers.ntimer){ - iunlock(&cpmtimers); - return nil; - } - if(t->inuse == 0) - break; - t++; - } - t->inuse = 1; - t->interrupt = intr; - t->arg = arg; - m->iomem->tgcr &= ~(0xF<<t->x); /* reset */ - *t->tmr = mode; - *t->tcn = 0; - *t->trr = ref; - *t->ter = 0xFFFF; - iunlock(&cpmtimers); - return t; -} - -void -gtimerset(GTimer *t, ushort mode, int usec) -{ - ulong ref, ps; - int clk; - - if(usec <= 0) - return; - ref = usec*m->speed; - clk = mode & (3<<1); - if(ref >= 0x1000000 && clk == TimerSclk){ - mode = (mode & ~clk) | TimerSclk16; - ref >>= 4; - } else if(clk == TimerSclk16) - ref >>= 4; - ps = (ref+(1<<16))/(1<<16); /* round up */ - ref /= ps; - *t->tmr = ((ps-1)<<8) | (mode&0xFF); - *t->trr = ref; -} - -void -gtimerstart(GTimer *t) -{ - if(t){ - ilock(&cpmtimers); - m->iomem->tgcr = (m->iomem->tgcr & ~(0xF<<t->x)) | (1<<t->x); /* enable */ - iunlock(&cpmtimers); - } -} - -void -gtimerstop(GTimer *t) -{ - if(t){ - ilock(&cpmtimers); - m->iomem->tgcr |= 2<<t->x; /* stop */ - iunlock(&cpmtimers); - } -} - -void -gtimerfree(GTimer *t) -{ - if(t){ - ilock(&cpmtimers); - t->inuse = 0; - *t->tmr = 0; /* disable interrupts */ - *t->ter = 0xFFFF; - m->iomem->tgcr = (m->iomem->tgcr & ~(0xF<<t->x)) | (2<<t->x); /* reset and stop */ - iunlock(&cpmtimers); - } -} - -#ifdef GTIMETEST -static void -gtintr(Ureg*, void*, GTimer*) -{ - m->bcsr[4] ^= DisableVideoLamp; /* toggle an LED */ -} - -void -gtimetest(void) -{ - GTimer *g; - - g = gtimer(0, 0, gtintr, nil); - gtimerset(g, TimerORI|TimerRestart|TimerSclk, 64000); - gtimerstart(g); - delay(1); -print("started timer: #%4.4ux #%4.4ux %8.8lux #%4.4ux #%4.4ux\n", *g->tmr, *g->trr, m->iomem->tgcr, *g->tcn, *g->ter); -print("ter=#%8.8lux tmr=#%8.8lux trr=#%8.8lux\n", g->ter, g->tmr, g->trr); -} -#endif diff --git a/os/mpc/devata.c b/os/mpc/devata.c deleted file mode 100644 index 69665e38..00000000 --- a/os/mpc/devata.c +++ /dev/null @@ -1,1194 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "pcmcia.h" - -#define DPRINT if(0)print - -typedef struct Drive Drive; -typedef struct Ident Ident; -typedef struct Controller Controller; -typedef struct Partition Partition; -typedef struct Repl Repl; - -enum -{ - /* ports */ - Pbase= 0x1F0, - Pdata= 0, /* data port (16 bits) */ - Perror= 1, /* error port (read) */ - Pprecomp= 1, /* buffer mode port (write) */ - Pcount= 2, /* sector count port */ - Psector= 3, /* sector number port */ - Pcyllsb= 4, /* least significant byte cylinder # */ - Pcylmsb= 5, /* most significant byte cylinder # */ - Pdh= 6, /* drive/head port */ - Pstatus= 7, /* status port (read) */ - Sbusy= (1<<7), - Sready= (1<<6), - Sdrq= (1<<3), - Serr= (1<<0), - Pcmd= 7, /* cmd port (write) */ - - /* commands */ - Crecal= 0x10, - Cread= 0x20, - Cwrite= 0x30, - Cident= 0xEC, - Cident2= 0xFF, /* pseudo command for post Cident interrupt */ - Csetbuf= 0xEF, - Cinitparam= 0x91, - - /* conner specific commands */ - Cstandby= 0xE2, - Cidle= 0xE1, - Cpowerdown= 0xE3, - - /* disk states */ - Sspinning, - Sstandby, - Sidle, - Spowerdown, - - /* something we have to or into the drive/head reg */ - DHmagic= 0xA0, - - /* file types */ - Qdir= 0, - - Maxxfer= BY2PG, /* maximum transfer size/cmd */ - Npart= 8+2, /* 8 sub partitions, disk, and partition */ - Nrepl= 64, /* maximum replacement blocks */ -}; -#define PART(x) ((x)&0xF) -#define DRIVE(x) (((x)>>4)&0x7) -#define MKQID(d,p) (((d)<<4) | (p)) - -struct Partition -{ - ulong start; - ulong end; - char name[NAMELEN+1]; -}; - -struct Repl -{ - Partition *p; - int nrepl; - ulong blk[Nrepl]; -}; - -#define PARTMAGIC "plan9 partitions" -#define REPLMAGIC "block replacements" - -/* - * an ata drive - */ -struct Drive -{ - QLock; - - Controller *cp; - int drive; - int confused; /* needs to be recalibrated (or worse) */ - int online; - int npart; /* number of real partitions */ - Partition p[Npart]; - Repl repl; - ulong usetime; - int state; - char vol[NAMELEN]; - - ulong cap; /* total bytes */ - int bytes; /* bytes/sector */ - int sectors; /* sectors/track */ - int heads; /* heads/cyl */ - long cyl; /* cylinders/drive */ - - char lba; /* true if drive has logical block addressing */ - char multi; /* non-zero if drive does multiple block xfers */ -}; - -/* - * a controller for 2 drives - */ -struct Controller -{ - QLock; /* exclusive access to the controller */ - ISAConf; /* interface to pcmspecial */ - - Lock reglock; /* exclusive access to the registers */ - - int confused; /* needs to be recalibrated (or worse) */ - ulong pbase; /* base port (copied from ISAConf) */ - - /* - * current operation - */ - int cmd; /* current command */ - int lastcmd; /* debugging info */ - Rendez r; /* wait here for command termination */ - char *buf; /* xfer buffer */ - int nsecs; /* length of transfer (sectors) */ - int sofar; /* sectors transferred so far */ - int status; - int error; - Drive *dp; /* drive being accessed */ -}; - -Controller *atac; -Drive *ata; -static char* ataerr; -static int nhard; -static int spindowntime; - -static void ataintr(Ureg*, void*); -static long ataxfer(Drive*, Partition*, int, long, long, char*); -static void ataident(Drive*); -static void atasetbuf(Drive*, int); -static void ataparams(Drive*); -static void atapart(Drive*); -static int ataprobe(Drive*, int, int, int); - -static int -atagen(Chan *c, Dirtab*, int, int s, Dir *dirp) -{ - Qid qid; - int drive; - Drive *dp; - Partition *pp; - ulong l; - - qid.vers = 0; - drive = s/Npart; - s = s % Npart; - if(drive >= nhard) - return -1; - dp = &ata[drive]; - - if(dp->online == 0 || s >= dp->npart) - return 0; - - pp = &dp->p[s]; - sprint(up->genbuf, "%s%s", dp->vol, pp->name); - qid.path = MKQID(drive, s); - l = (pp->end - pp->start) * dp->bytes; - devdir(c, qid, up->genbuf, l, eve, 0660, dirp); - return 1; -} - -static void -atainit(void) -{ - Drive *dp; - Controller *cp; - uchar equip; - int pcmslot; - - if (atac) - return; /* already done */ - - equip = 0x10; /* hard coded */ - - print("ata init\n"); - cp = malloc(sizeof(*cp)); - if (!cp) - error(Enomem); - - cp->port = Pbase; - cp->irq = 14; - - if((pcmslot = pcmspecial("SunDisk", cp)) < 0) { - print("No ATA card\n"); - free(cp); - ataerr = Enoifc; - return; - } - ata = malloc(2 * sizeof(*ata)); - if(ata == nil) { - pcmspecialclose(pcmslot); - free(cp); - error(Enomem); - } - - atac = cp; - cp->buf = 0; - cp->lastcmd = cp->cmd; - cp->cmd = 0; - cp->pbase = cp->port; - pcmintrenable(pcmslot, ataintr, cp); - - dp = ata; - if(equip & 0xf0){ - dp->drive = 0; - dp->online = 0; - dp->cp = cp; - dp++; - } - if((equip & 0x0f)){ - dp->drive = 1; - dp->online = 0; - dp->cp = cp; - dp++; - } - nhard = dp - ata; - - spindowntime = 1; -} - - -/* - * Get the characteristics of each drive. Mark unresponsive ones - * off line. - */ -static Chan* -ataattach(char *spec) -{ - Drive *dp; - - atainit(); - if (!ata) - error(ataerr ? ataerr : Enoifc); - for(dp = ata; dp < &ata[nhard]; dp++){ - if(waserror()){ - dp->online = 0; - qunlock(dp); - continue; - } - qlock(dp); - if(!dp->online){ - /* - * Make sure ataclock() doesn't - * interfere. - */ - dp->usetime = m->ticks; - ataparams(dp); - dp->online = 1; - atasetbuf(dp, 1); - } - - /* - * read Plan 9 partition table - */ - atapart(dp); - qunlock(dp); - poperror(); - } - return devattach('H', spec); -} - -static int -atawalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, atagen); -} - -static void -atastat(Chan *c, char *dp) -{ - devstat(c, dp, 0, 0, atagen); -} - -static Chan* -ataopen(Chan *c, int omode) -{ - return devopen(c, omode, 0, 0, atagen); -} - -static void -ataclose(Chan *c) -{ - Drive *d; - Partition *p; - - if(c->mode != OWRITE && c->mode != ORDWR) - return; - - d = &ata[DRIVE(c->qid.path)]; - p = &d->p[PART(c->qid.path)]; - if(strcmp(p->name, "partition") != 0) - return; - - if(waserror()){ - qunlock(d); - nexterror(); - } - qlock(d); - atapart(d); - qunlock(d); - poperror(); -} - -static long -ataread(Chan *c, void *a, long n, vlong offset) -{ - Drive *dp; - long rv, i; - int skip; - uchar *aa = a; - Partition *pp; - char *buf; - - if(c->qid.path == CHDIR) - return devdirread(c, a, n, 0, 0, atagen); - - buf = smalloc(Maxxfer); - if(waserror()){ - free(buf); - nexterror(); - } - - dp = &ata[DRIVE(c->qid.path)]; - pp = &dp->p[PART(c->qid.path)]; - - skip = offset % dp->bytes; - for(rv = 0; rv < n; rv += i){ - i = ataxfer(dp, pp, Cread, offset+rv-skip, n-rv+skip, buf); - if(i == 0) - break; - i -= skip; - if(i > n - rv) - i = n - rv; - memmove(aa+rv, buf + skip, i); - skip = 0; - } - - free(buf); - poperror(); - - return rv; -} - -static long -atawrite(Chan *c, void *a, long n, vlong offset) -{ - Drive *dp; - long rv, i, partial; - uchar *aa = a; - Partition *pp; - char *buf; - - if(c->qid.path == CHDIR) - error(Eisdir); - - dp = &ata[DRIVE(c->qid.path)]; - pp = &dp->p[PART(c->qid.path)]; - buf = smalloc(Maxxfer); - if(waserror()){ - free(buf); - nexterror(); - } - - /* - * if not starting on a sector boundary, - * read in the first sector before writing - * it out. - */ - partial = offset % dp->bytes; - if(partial){ - ataxfer(dp, pp, Cread, offset-partial, dp->bytes, buf); - if(partial+n > dp->bytes) - rv = dp->bytes - partial; - else - rv = n; - memmove(buf+partial, aa, rv); - ataxfer(dp, pp, Cwrite, offset-partial, dp->bytes, buf); - } else - rv = 0; - - /* - * write out the full sectors - */ - partial = (n - rv) % dp->bytes; - n -= partial; - for(; rv < n; rv += i){ - i = n - rv; - if(i > Maxxfer) - i = Maxxfer; - memmove(buf, aa+rv, i); - i = ataxfer(dp, pp, Cwrite, offset+rv, i, buf); - if(i == 0) - break; - } - - /* - * if not ending on a sector boundary, - * read in the last sector before writing - * it out. - */ - if(partial){ - ataxfer(dp, pp, Cread, offset+rv, dp->bytes, buf); - memmove(buf, aa+rv, partial); - ataxfer(dp, pp, Cwrite, offset+rv, dp->bytes, buf); - rv += partial; - } - - free(buf); - poperror(); - - return rv; -} - -/* - * did an interrupt happen? - */ -static int -cmddone(void *a) -{ - Controller *cp = a; - - return cp->cmd == 0; -} - -/* - * Wait for the controller to be ready to accept a command. - * This is protected from intereference by ataclock() by - * setting dp->usetime before it is called. - */ -static void -cmdreadywait(Drive *dp) -{ - long start; - int period; - Controller *cp = dp->cp; - - /* give it 2 seconds to spin down and up */ - if(dp->state == Sspinning) - period = 10; - else - period = 2000; - - start = m->ticks; - while((inb(cp->pbase+Pstatus) & (Sready|Sbusy)) != Sready) - if(TK2MS(m->ticks - start) > period){ - DPRINT("cmdreadywait failed\n"); - error(Eio); - } -} - -static void -atarepl(Drive *dp, long bblk) -{ - int i; - - if(dp->repl.p == 0) - return; - for(i = 0; i < dp->repl.nrepl; i++){ - if(dp->repl.blk[i] == bblk) - DPRINT("found bblk %ld at offset %ld\n", bblk, i); - } -} - -static void -atasleep(Controller *cp, int ms) -{ - tsleep(&cp->r, cmddone, cp, ms); - if(cp->cmd && cp->cmd != Cident2){ - DPRINT("ata: cmd 0x%uX timeout, status=%lux\n", - cp->cmd, inb(cp->pbase+Pstatus)); - error("ata drive timeout"); - } -} - -/* - * transfer a number of sectors. ataintr will perform all the iterative - * parts. - */ -static long -ataxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) -{ - Controller *cp; - long lblk; - int cyl, sec, head; - int loop, stat; - - if(dp->online == 0) - error(Eio); - - /* - * cut transfer size down to disk buffer size - */ - start = start / dp->bytes; - if(len > Maxxfer) - len = Maxxfer; - len = (len + dp->bytes - 1) / dp->bytes; - if(len == 0) - return 0; - - /* - * calculate physical address - */ - lblk = start + pp->start; - if(lblk >= pp->end) - return 0; - if(lblk+len > pp->end) - len = pp->end - lblk; - if(dp->lba){ - sec = lblk & 0xff; - cyl = (lblk>>8) & 0xffff; - head = (lblk>>24) & 0xf; - } else { - cyl = lblk/(dp->sectors*dp->heads); - sec = (lblk % dp->sectors) + 1; - head = ((lblk/dp->sectors) % dp->heads); - } - - DPRINT("<%s %d>", (cmd == Cwrite) ? "W" : "R", lblk); - cp = dp->cp; - qlock(cp); - if(waserror()){ - cp->buf = 0; - qunlock(cp); - nexterror(); - } - - /* - * Make sure hardclock() doesn't - * interfere. - */ - dp->usetime = m->ticks; - cmdreadywait(dp); - - ilock(&cp->reglock); - cp->sofar = 0; - cp->buf = buf; - cp->nsecs = len; - cp->cmd = cmd; - cp->dp = dp; - cp->status = 0; - - outb(cp->pbase+Pcount, cp->nsecs); - outb(cp->pbase+Psector, sec); - outb(cp->pbase+Pdh, DHmagic | (dp->drive<<4) | (dp->lba<<6) | head); - outb(cp->pbase+Pcyllsb, cyl); - outb(cp->pbase+Pcylmsb, cyl>>8); - outb(cp->pbase+Pcmd, cmd); - - if(cmd == Cwrite){ - loop = 0; - microdelay(1); - while((stat = inb(cp->pbase+Pstatus) & (Serr|Sdrq)) == 0) - if(++loop > 10000) - panic("ataxfer"); - outss(cp->pbase+Pdata, cp->buf, dp->bytes/2); - } else - stat = 0; - iunlock(&cp->reglock); - - if(stat & Serr) - error(Eio); - - /* - * wait for command to complete. if we get a note, - * remember it but keep waiting to let the disk finish - * the current command. - */ - loop = 0; - while(waserror()){ - DPRINT("interrupted ataxfer\n"); - if(loop++ > 10){ - print("ata disk error\n"); - nexterror(); - } - } - atasleep(cp, 3000); - dp->state = Sspinning; - dp->usetime = m->ticks; - poperror(); - if(loop) - nexterror(); - - if(cp->status & Serr){ - DPRINT("hd%d err: lblk %ld status %lux, err %lux\n", - dp-ata, lblk, cp->status, cp->error); - DPRINT("\tcyl %d, sec %d, head %d\n", cyl, sec, head); - DPRINT("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); - atarepl(dp, lblk+cp->sofar); - error(Eio); - } - cp->buf = 0; - len = cp->sofar*dp->bytes; - qunlock(cp); - poperror(); - - return len; -} - -/* - * set read ahead mode - */ -static void -atasetbuf(Drive *dp, int on) -{ - Controller *cp = dp->cp; - - qlock(cp); - if(waserror()){ - qunlock(cp); - nexterror(); - } - - cmdreadywait(dp); - - ilock(&cp->reglock); - cp->cmd = Csetbuf; - outb(cp->pbase+Pprecomp, on ? 0xAA : 0x55); /* read look ahead */ - outb(cp->pbase+Pdh, DHmagic | (dp->drive<<4)); - outb(cp->pbase+Pcmd, Csetbuf); - iunlock(&cp->reglock); - - atasleep(cp, 5000); - -/* if(cp->status & Serr) - DPRINT("hd%d setbuf err: status %lux, err %lux\n", - dp-ata, cp->status, cp->error);/**/ - - poperror(); - qunlock(cp); -} - -/* - * ident sector from drive. this is from ANSI X3.221-1994 - */ -struct Ident -{ - ushort config; /* general configuration info */ - ushort cyls; /* # of cylinders (default) */ - ushort reserved0; - ushort heads; /* # of heads (default) */ - ushort b2t; /* unformatted bytes/track */ - ushort b2s; /* unformated bytes/sector */ - ushort s2t; /* sectors/track (default) */ - ushort reserved1[3]; -/* 10 */ - ushort serial[10]; /* serial number */ - ushort type; /* buffer type */ - ushort bsize; /* buffer size/512 */ - ushort ecc; /* ecc bytes returned by read long */ - ushort firm[4]; /* firmware revision */ - ushort model[20]; /* model number */ -/* 47 */ - ushort s2i; /* number of sectors/interrupt */ - ushort dwtf; /* double word transfer flag */ - ushort capabilities; - ushort reserved2; - ushort piomode; - ushort dmamode; - ushort cvalid; /* (cvald&1) if next 4 words are valid */ - ushort ccyls; /* current # cylinders */ - ushort cheads; /* current # heads */ - ushort cs2t; /* current sectors/track */ - ushort ccap[2]; /* current capacity in sectors */ - ushort cs2i; /* current number of sectors/interrupt */ -/* 60 */ - ushort lbasecs[2]; /* # LBA user addressable sectors */ - ushort dmasingle; - ushort dmadouble; -/* 64 */ - ushort reserved3[64]; - ushort vendor[32]; /* vendor specific */ - ushort reserved4[96]; -}; - -/* - * get parameters from the drive - */ -static void -ataident(Drive *dp) -{ - Controller *cp; - char *buf; - Ident *ip; - char id[21]; - - cp = dp->cp; - buf = smalloc(Maxxfer); - qlock(cp); - if(waserror()){ - cp->buf = 0; - qunlock(cp); - free(buf); - nexterror(); - } - - cmdreadywait(dp); - - ilock(&cp->reglock); - cp->nsecs = 1; - cp->sofar = 0; - cp->cmd = Cident; - cp->dp = dp; - cp->buf = buf; - outb(cp->pbase+Pdh, DHmagic | (dp->drive<<4)); - outb(cp->pbase+Pcmd, Cident); - iunlock(&cp->reglock); - - atasleep(cp, 5000); - if(cp->status & Serr){ - DPRINT("bad disk ident status\n"); - error(Eio); - } - ip = (Ident*)buf; - - /* - * this function appears to respond with an extra interrupt after - * the ident information is read, except on the safari. The following - * delay gives this extra interrupt a chance to happen while we are quiet. - * Otherwise, the interrupt may come during a subsequent read or write, - * causing a panic and much confusion. - */ - if (cp->cmd == Cident2) - tsleep(&cp->r, return0, 0, 10); - - memmove(id, ip->model, sizeof(id)-1); - id[sizeof(id)-1] = 0; - - if(ip->capabilities & (1<<9)){ - dp->lba = 1; - dp->sectors = (ip->lbasecs[0]) | (ip->lbasecs[1]<<16); - dp->cap = dp->bytes * dp->sectors; -/*print("\nata%d model %s with %d lba sectors\n", dp->drive, id, dp->sectors);/**/ - } else { - dp->lba = 0; - - /* use default (unformatted) settings */ - dp->cyl = ip->cyls; - dp->heads = ip->heads; - dp->sectors = ip->s2t; -/*print("\nata%d model %s with default %d cyl %d head %d sec\n", dp->drive, - id, dp->cyl, dp->heads, dp->sectors);/**/ - - if(ip->cvalid&(1<<0)){ - /* use current settings */ - dp->cyl = ip->ccyls; - dp->heads = ip->cheads; - dp->sectors = ip->cs2t; -/*print("\tchanged to %d cyl %d head %d sec\n", dp->cyl, dp->heads, dp->sectors);/**/ - } - dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; - } - cp->lastcmd = cp->cmd; - cp->cmd = 0; - cp->buf = 0; - free(buf); - poperror(); - qunlock(cp); -} - -/* - * probe the given sector to see if it exists - */ -static int -ataprobe(Drive *dp, int cyl, int sec, int head) -{ - Controller *cp; - char *buf; - int rv; - - cp = dp->cp; - buf = smalloc(Maxxfer); - qlock(cp); - if(waserror()){ - free(buf); - qunlock(cp); - nexterror(); - } - - cmdreadywait(dp); - - ilock(&cp->reglock); - cp->cmd = Cread; - cp->dp = dp; - cp->status = 0; - cp->nsecs = 1; - cp->sofar = 0; - - outb(cp->pbase+Pcount, 1); - outb(cp->pbase+Psector, sec+1); - outb(cp->pbase+Pdh, DHmagic | head | (dp->lba<<6) | (dp->drive<<4)); - outb(cp->pbase+Pcyllsb, cyl); - outb(cp->pbase+Pcylmsb, cyl>>8); - outb(cp->pbase+Pcmd, Cread); - iunlock(&cp->reglock); - - atasleep(cp, 5000); - - if(cp->status & Serr) - rv = -1; - else - rv = 0; - - cp->buf = 0; - free(buf); - poperror(); - qunlock(cp); - return rv; -} - -/* - * figure out the drive parameters - */ -static void -ataparams(Drive *dp) -{ - int i, hi, lo; - - /* - * first try the easy way, ask the drive and make sure it - * isn't lying. - */ - dp->bytes = 512; - ataident(dp); - if(dp->lba){ - i = dp->sectors - 1; - if(ataprobe(dp, (i>>8)&0xffff, (i&0xff)-1, (i>>24)&0xf) == 0) - return; - } else { - if(ataprobe(dp, dp->cyl-1, dp->sectors-1, dp->heads-1) == 0) - return; - } - - /* - * the drive lied, determine parameters by seeing which ones - * work to read sectors. - */ - dp->lba = 0; - for(i = 0; i < 32; i++) - if(ataprobe(dp, 0, 0, i) < 0) - break; - dp->heads = i; - for(i = 0; i < 128; i++) - if(ataprobe(dp, 0, i, 0) < 0) - break; - dp->sectors = i; - for(i = 512; ; i += 512) - if(ataprobe(dp, i, dp->sectors-1, dp->heads-1) < 0) - break; - lo = i - 512; - hi = i; - for(; hi-lo > 1;){ - i = lo + (hi - lo)/2; - if(ataprobe(dp, i, dp->sectors-1, dp->heads-1) < 0) - hi = i; - else - lo = i; - } - dp->cyl = lo + 1; - dp->cap = dp->bytes * dp->cyl * dp->heads * dp->sectors; -} - -/* - * Read block replacement table. - * The table is just ascii block numbers. - */ -static void -atareplinit(Drive *dp) -{ - char *line[Nrepl+1]; - char *field[1]; - ulong n; - int i; - char *buf; - - /* - * check the partition is big enough - */ - if(dp->repl.p->end - dp->repl.p->start < Nrepl+1){ - dp->repl.p = 0; - return; - } - - buf = smalloc(Maxxfer); - if(waserror()){ - free(buf); - nexterror(); - } - - /* - * read replacement table from disk, null terminate - */ - ataxfer(dp, dp->repl.p, Cread, 0, dp->bytes, buf); - buf[dp->bytes-1] = 0; - - /* - * parse replacement table. - */ - n = getfields(buf, line, Nrepl+1, 1, "\n"); - if(strncmp(line[0], REPLMAGIC, sizeof(REPLMAGIC)-1)){ - dp->repl.p = 0; - } else { - for(dp->repl.nrepl = 0, i = 1; i < n; i++, dp->repl.nrepl++){ - if(getfields(line[i], field, 1, 1, " ") != 1) - break; - dp->repl.blk[dp->repl.nrepl] = strtoul(field[0], 0, 0); - if(dp->repl.blk[dp->repl.nrepl] <= 0) - break; - } - } - free(buf); - poperror(); -} - -/* - * read partition table. The partition table is just ascii strings. - */ -static void -atapart(Drive *dp) -{ - Partition *pp; - char *line[Npart+1]; - char *field[3]; - ulong n; - int i; - char *buf; - - sprint(dp->vol, "hd%d", dp - ata); - - /* - * we always have a partition for the whole disk - * and one for the partition table - */ - pp = &dp->p[0]; - strcpy(pp->name, "disk"); - pp->start = 0; - pp->end = dp->cap / dp->bytes; - pp++; - strcpy(pp->name, "partition"); - pp->start = dp->p[0].end - 1; - pp->end = dp->p[0].end; - pp++; - dp->npart = 2; - - /* - * initialise the bad-block replacement info - */ - dp->repl.p = 0; - - buf = smalloc(Maxxfer); - if(waserror()){ - free(buf); - nexterror(); - } - - /* - * read last sector from disk, null terminate. This used - * to be the sector we used for the partition tables. - * However, this sector is special on some PC's so we've - * started to use the second last sector as the partition - * table instead. To avoid reconfiguring all our old systems - * we first look to see if there is a valid partition - * table in the last sector. If so, we use it. Otherwise - * we switch to the second last. - */ - ataxfer(dp, dp->p+1, Cread, 0, dp->bytes, buf); - buf[dp->bytes-1] = 0; - n = getfields(buf, line, Npart+1, 1, "\n"); - if(n == 0 || strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1)){ - dp->p[0].end--; - dp->p[1].start--; - dp->p[1].end--; - ataxfer(dp, dp->p+1, Cread, 0, dp->bytes, buf); - buf[dp->bytes-1] = 0; - n = getfields(buf, line, Npart+1, 1, "\n"); - } - - /* - * parse partition table. - */ - if(n > 0 && strncmp(line[0], PARTMAGIC, sizeof(PARTMAGIC)-1) == 0){ - for(i = 1; i < n; i++){ - switch(getfields(line[i], field, 3, 1, " ")) { - case 2: - if(strcmp(field[0], "unit") == 0) - strncpy(dp->vol, field[1], NAMELEN); - break; - case 3: - strncpy(pp->name, field[0], NAMELEN); - if(strncmp(pp->name, "repl", NAMELEN) == 0) - dp->repl.p = pp; - pp->start = strtoul(field[1], 0, 0); - pp->end = strtoul(field[2], 0, 0); - if(pp->start > pp->end || pp->end > dp->p[0].end) - break; - dp->npart++; - pp++; - } - } - } - free(buf); - poperror(); - - if(dp->repl.p) - atareplinit(dp); -} - -enum -{ - Maxloop= 10000, -}; - -/* - * we get an interrupt for every sector transferred - */ -static void -ataintr(Ureg*, void *arg) -{ - Controller *cp; - Drive *dp; - long loop; - char *addr; - - cp = arg; - dp = cp->dp; - - ilock(&cp->reglock); - - loop = 0; - while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){ - if(++loop > Maxloop) { - DPRINT("cmd=%lux status=%lux\n", - cp->cmd, inb(cp->pbase+Pstatus)); - panic("ataintr: wait busy"); - } - } - - switch(cp->cmd){ - case Cwrite: - if(cp->status & Serr){ - cp->lastcmd = cp->cmd; - cp->cmd = 0; - cp->error = inb(cp->pbase+Perror); - wakeup(&cp->r); - break; - } - cp->sofar++; - if(cp->sofar < cp->nsecs){ - loop = 0; - while(((cp->status = inb(cp->pbase+Pstatus)) & Sdrq) == 0) - if(++loop > Maxloop) { - DPRINT("cmd=%lux status=%lux\n", - cp->cmd, inb(cp->pbase+Pstatus)); - panic("ataintr: write"); - } - addr = cp->buf; - if(addr){ - addr += cp->sofar*dp->bytes; - outss(cp->pbase+Pdata, addr, dp->bytes/2); - } - } else{ - cp->lastcmd = cp->cmd; - cp->cmd = 0; - wakeup(&cp->r); - } - break; - case Cread: - case Cident: - loop = 0; - while((cp->status & (Serr|Sdrq)) == 0){ - if(++loop > Maxloop) { - DPRINT("cmd=%lux status=%lux\n", - cp->cmd, inb(cp->pbase+Pstatus)); - panic("ataintr: read/ident"); - } - cp->status = inb(cp->pbase+Pstatus); - } - if(cp->status & Serr){ - cp->lastcmd = cp->cmd; - cp->cmd = 0; - cp->error = inb(cp->pbase+Perror); - wakeup(&cp->r); - break; - } - addr = cp->buf; - if(addr){ - addr += cp->sofar*dp->bytes; - inss(cp->pbase+Pdata, addr, dp->bytes/2); - } - cp->sofar++; - if(cp->sofar > cp->nsecs) - print("ataintr %d %d\n", cp->sofar, cp->nsecs); - if(cp->sofar >= cp->nsecs){ - cp->lastcmd = cp->cmd; - if (cp->cmd == Cread) - cp->cmd = 0; - else - cp->cmd = Cident2; - wakeup(&cp->r); - } - break; - case Cinitparam: - case Csetbuf: - case Cidle: - case Cstandby: - case Cpowerdown: - cp->lastcmd = cp->cmd; - cp->cmd = 0; - wakeup(&cp->r); - break; - case Cident2: - cp->lastcmd = cp->cmd; - cp->cmd = 0; - break; - default: - print("weird disk interrupt, cmd=%.2ux, lastcmd= %.2ux status=%.2ux\n", - cp->cmd, cp->lastcmd, cp->status); - break; - } - - iunlock(&cp->reglock); -} - -void -hardclock(void) -{ - int drive; - Drive *dp; - Controller *cp; - int diff; - - if(spindowntime <= 0) - return; - - for(drive = 0; drive < nhard; drive++){ - dp = &ata[drive]; - cp = dp->cp; - - diff = TK2SEC(m->ticks - dp->usetime); - if((dp->state == Sspinning) && (diff >= spindowntime)){ - ilock(&cp->reglock); - cp->cmd = Cstandby; - outb(cp->pbase+Pcount, 0); - outb(cp->pbase+Pdh, DHmagic | (dp->drive<<4) | 0); - outb(cp->pbase+Pcmd, cp->cmd); - iunlock(&cp->reglock); - dp->state = Sstandby; - } - } -} - -Dev atadevtab = { - 'H', - "ata", - - devreset, - atainit, - ataattach, - devdetach, - devclone, - atawalk, - atastat, - ataopen, - devcreate, - ataclose, - ataread, - devbread, - atawrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/mpc/devbench.c b/os/mpc/devbench.c deleted file mode 100644 index a35a57b0..00000000 --- a/os/mpc/devbench.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -typedef struct Psync Psync; - -enum { - Maxprocs=2, -}; - -struct Psync { - Rendez r; - int flag; -}; -static Psync timesync[Maxprocs]; -static Ref nactive; -static Ref nbusy; - -static int -timev(void *a) -{ - return *(int*)a; -} - -static void -timesched0(void *ap) -{ - long tot, t, i, lim, low, max; - Psync *ps; - - ps = ap; - sleep(&ps->r, timev, &ps->flag); - setpri(PriRealtime); - incref(&nbusy); - while(nbusy.ref < nactive.ref) - sched(); - lim = 1000; - low = 64000000; - max = 0; - tot = 0; - for(i=0; i<lim; i++){ -if(i<8)print("%lud\n", up->pid); - do{ - t = gettbl(); - sched(); - t = gettbl()-t; - }while(t < 0); - if(t < low) - low = t; - if(t > max) - max = t; - tot += t; - } - print("%lud %lud %lud %lud %lud\n", up->pid, lim, tot, low, max); - decref(&nactive); - pexit("", 0); -} - -static void -timesched(void) -{ - int i, np; - - for(np=1; np<=Maxprocs; np++){ - nactive.ref = np; - print("%d procs\n", np); - setpri(PriRealtime); - for(i=0; i<np; i++) - kproc("timesched", timesched0, ×ync[i], 0); - for(i=0; i<np; i++){ - timesync[i].flag = 1; - wakeup(×ync[i].r); - } - setpri(PriNormal); - while(nactive.ref>0) - sched(); - } -} - -typedef struct Ictr Ictr; -struct Ictr { - ulong base; - ulong sleep; - ulong spllo; - ulong intr; - ulong isave; - ulong arrive; - ulong wakeup; - ulong awake; -}; -static Ictr counters[100], *curct; -static int intrwant; -static Rendez vous; -int spltbl; /* set by spllo */ -int intrtbl; /* set by intrvec() */ -int isavetbl; /* set by intrvec() */ - -static void -intrwake(Ureg*, void*) -{ - m->iomem->tgcr &= ~1; /* reset the timer */ - curct->spllo = spltbl; - curct->intr = intrtbl; - curct->isave = isavetbl; - curct->arrive = gettbl(); - intrwant = 0; - wakeup(&vous); - curct->wakeup = gettbl(); -} - -/* - * sleep calls intrtest with splhi (under lock): - * provoke the interrupt now, so that it is guaranteed - * not to happen until sleep has queued the process, - * forcing wakeup to do something. - */ -static int -intrtest(void*) -{ - m->iomem->tgcr |= 1; /* enable timer: allow interrupt */ - curct->sleep = gettbl(); - return intrwant==0; -} - -static void -intrtime(void) -{ - IMM *io; - Ictr *ic; - long t; - int i; - - sched(); - curct = counters; - io = ioplock(); - io->tgcr &= ~3; - iopunlock(); - intrenable(VectorCPIC+0x19, intrwake, nil, BUSUNKNOWN, "bench"); - for(i=0; i<nelem(counters); i++){ - curct = &counters[i]; - //puttbl(0); - intrwant = 1; - io = m->iomem; /* don't lock, to save time */ - io->tmr1 = (0<<8)|TimerORI|TimerSclk; - io->trr1 = 1; - curct->base = gettbl(); - sleep(&vous, intrtest, nil); - curct->awake = gettbl(); - sched(); /* just to slow it down between trials */ - } - m->iomem->tmr1 = 0; - print("interrupt\n"); - for(i=0; i<20; i++){ - ic = &counters[i]; - t = ic->awake - ic->base; - ic->awake -= ic->wakeup; - ic->wakeup -= ic->arrive; - ic->arrive -= ic->isave; - ic->isave -= ic->intr; - ic->intr -= ic->spllo; - ic->spllo -= ic->sleep; - ic->sleep -= ic->base; - print("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t%ld\n", ic->sleep, ic->spllo, ic->intr, ic->isave, ic->arrive, ic->wakeup, ic->awake, t); - } -} - -static Chan* -benchattach(char *spec) -{ - timesched(); - intrtime(); - USED(spec); - error(Eperm); - return nil; -} - -static Walkqid* -benchwalk(Chan*, Chan*, char**, int) -{ - error(Enonexist); - return 0; -} - -static Chan* -benchopen(Chan*, int) -{ - error(Eperm); - return nil; -} - -static int -benchstat(Chan*, uchar*, int) -{ - error(Eperm); - return 0; -} - -static void -benchclose(Chan*) -{ -} - -static long -benchread(Chan *c, void *buf, long n, vlong offset) -{ - USED(c, buf, n, offset); - error(Eperm); - return 0; -} - -static long -benchwrite(Chan *c, void *buf, long n, vlong offset) -{ - USED(c, buf, n, offset); - error(Eperm); - return 0; -} - - -Dev benchdevtab = { - 'x', - "bench", - - devreset, - devinit, - devshutdown, - benchattach, - benchwalk, - benchstat, - benchopen, - devcreate, - benchclose, - benchread, - devbread, - benchwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/mpc/devboot.c b/os/mpc/devboot.c deleted file mode 100644 index 126fe6e6..00000000 --- a/os/mpc/devboot.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -enum{ - Qdir, - Qboot, - Qmem, -}; - -Dirtab bootdir[]={ - ".", {Qdir,0,QTDIR}, 0, 0555, - "boot", {Qboot}, 0, 0666, - "mem", {Qmem}, 0, 0666, -}; - -#define NBOOT (sizeof bootdir/sizeof(Dirtab)) - -static void -bootreset(void) -{ -} - -static Chan* -bootattach(char *spec) -{ - return devattach('B', spec); -} - -static Walkqid* -bootwalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, bootdir, NBOOT, devgen); -} - -static int -bootstat(Chan *c, uchar *dp, int n) -{ - return devstat(c, dp, n, bootdir, NBOOT, devgen); -} - -static Chan* -bootopen(Chan *c, int omode) -{ - return devopen(c, omode, bootdir, NBOOT, devgen); -} - -static void -bootclose(Chan*) -{ -} - -static long -bootread(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - - switch((ulong)c->qid.path){ - - case Qdir: - return devdirread(c, buf, n, bootdir, NBOOT, devgen); - - case Qmem: - /* kernel memory */ - if(offset>=KZERO && offset<KZERO+conf.npage*BY2PG){ - if(offset+n > KZERO+conf.npage*BY2PG) - n = KZERO+conf.npage*BY2PG - offset; - memmove(buf, (char*)offset, n); - return n; - } - error(Ebadarg); - } - - error(Egreg); - return 0; /* not reached */ -} - -static long -bootwrite(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - ulong pc; - uchar *p; - - switch((ulong)c->qid.path){ - case Qmem: - /* kernel memory */ - if(offset>=KZERO && offset<KZERO+conf.npage*BY2PG){ - if(offset+n > KZERO+conf.npage*BY2PG) - n = KZERO+conf.npage*BY2PG - offset; - memmove((char*)offset, buf, n); - segflush((void*)offset, n); - return n; - } - error(Ebadarg); - - case Qboot: - p = (uchar*)buf; - pc = (((((p[0]<<8)|p[1])<<8)|p[2])<<8)|p[3]; - if(pc < KZERO || pc >= KZERO+conf.npage*BY2PG) - error(Ebadarg); - splhi(); - segflush((void*)pc, 64*1024); - gotopc(pc); - } - error(Ebadarg); - return 0; /* not reached */ -} - -Dev bootdevtab = { - 'B', - "boot", - - bootreset, - devinit, - devshutdown, - bootattach, - bootwalk, - bootstat, - bootopen, - devcreate, - bootclose, - bootread, - devbread, - bootwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/mpc/devether.c b/os/mpc/devether.c deleted file mode 100644 index eb4ed283..00000000 --- a/os/mpc/devether.c +++ /dev/null @@ -1,617 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "etherif.h" - -static Ether *etherxx[MaxEther]; - -Chan* -etherattach(char* spec) -{ - ulong ctlrno; - char *p; - Chan *chan; - Ether *ether; - - ctlrno = 0; - if(spec && *spec){ - ctlrno = strtoul(spec, &p, 0); - if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) - error(Ebadarg); - } - if((ether = etherxx[ctlrno]) == 0) - error(Enodev); - rlock(ether); - if(waserror()){ - runlock(ether); - nexterror(); - } - chan = devattach('l', spec); - chan->dev = ctlrno; - if(ether->attach) - ether->attach(etherxx[ctlrno]); - poperror(); - runlock(ether); - return chan; -} - -static void -ethershutdown(void) -{ - Ether *ether; - int i; - - for(i=0; i<MaxEther; i++){ - ether = etherxx[i]; - if(ether != nil && ether->detach != nil) - ether->detach(ether); - } -} - -static Walkqid* -etherwalk(Chan* chan, Chan *nchan, char **name, int nname) -{ - Walkqid *wq; - Ether *ether; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - wq = netifwalk(etherxx[chan->dev], chan, nchan, name, nname); - poperror(); - runlock(ether); - return wq; -} - -static int -etherstat(Chan* chan, uchar* dp, int n) -{ - int s; - Ether *ether; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - s = netifstat(ether, chan, dp, n); - poperror(); - runlock(ether); - return s; -} - -static Chan* -etheropen(Chan* chan, int omode) -{ - Chan *c; - Ether *ether; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - c = netifopen(ether, chan, omode); - poperror(); - runlock(ether); - return c; -} - -static void -ethercreate(Chan*, char*, int, ulong) -{ -} - -static void -etherclose(Chan* chan) -{ - Ether *ether; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - netifclose(ether, chan); - poperror(); - runlock(ether); -} - -static long -etherread(Chan* chan, void* buf, long n, vlong off) -{ - Ether *ether; - ulong offset = off; - long r; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - if((chan->qid.type & QTDIR) == 0 && ether->ifstat){ - /* - * With some controllers it is necessary to reach - * into the chip to extract statistics. - */ - if(NETTYPE(chan->qid.path) == Nifstatqid){ - r = ether->ifstat(ether, buf, n, offset); - goto out; - } - if(NETTYPE(chan->qid.path) == Nstatqid) - ether->ifstat(ether, buf, 0, offset); - } - r = netifread(ether, chan, buf, n, offset); -out: - poperror(); - runlock(ether); - return r; -} - -static Block* -etherbread(Chan* chan, long n, ulong offset) -{ - Block *b; - Ether *ether; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - b = netifbread(ether, chan, n, offset); - poperror(); - runlock(ether); - return b; -} - -static int -etherwstat(Chan* chan, uchar* dp, int n) -{ - Ether *ether; - int r; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - r = netifwstat(ether, chan, dp, n); - poperror(); - runlock(ether); - return r; -} - -static void -etherrtrace(Netfile* f, Etherpkt* pkt, int len) -{ - int i, n; - Block *bp; - - if(qwindow(f->in) <= 0) - return; - if(len > 58) - n = 58; - else - n = len; - bp = iallocb(64); - if(bp == nil) - return; - memmove(bp->wp, pkt->d, n); - i = TK2MS(MACHP(0)->ticks); - bp->wp[58] = len>>8; - bp->wp[59] = len; - bp->wp[60] = i>>24; - bp->wp[61] = i>>16; - bp->wp[62] = i>>8; - bp->wp[63] = i; - bp->wp += 64; - qpass(f->in, bp); -} - -Block* -etheriq(Ether* ether, Block* bp, int fromwire) -{ - Etherpkt *pkt; - ushort type; - int len, multi, tome, fromme; - Netfile **ep, *f, **fp, *fx; - Block *xbp; - - ether->inpackets++; - - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - type = (pkt->type[0]<<8)|pkt->type[1]; - fx = 0; - ep = ðer->f[Ntypes]; - - multi = pkt->d[0] & 1; - /* check for valid multcast addresses */ - if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){ - if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ - if(fromwire){ - freeb(bp); - bp = 0; - } - return bp; - } - } - - /* is it for me? */ - tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; - fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0; - - /* - * Multiplex the packet to all the connections which want it. - * If the packet is not to be used subsequently (fromwire != 0), - * attempt to simply pass it into one of the connections, thereby - * saving a copy of the data (usual case hopefully). - */ - for(fp = ether->f; fp < ep; fp++){ - if((f = *fp) && (f->type == type || f->type < 0)) - if(tome || multi || f->prom){ - /* Don't want to hear bridged packets */ - if(f->bridge && !fromwire && !fromme) - continue; - if(!f->headersonly){ - if(fromwire && fx == 0) - fx = f; - else if(xbp = iallocb(len)){ - memmove(xbp->wp, pkt, len); - xbp->wp += len; - if(qpass(f->in, xbp) < 0) - ether->soverflows++; - } - else - ether->soverflows++; - } - else - etherrtrace(f, pkt, len); - } - } - - if(fx){ - if(qpass(fx->in, bp) < 0) - ether->soverflows++; - return 0; - } - if(fromwire){ - freeb(bp); - return 0; - } - - return bp; -} - -static int -etheroq(Ether* ether, Block* bp) -{ - int len, loopback, s; - Etherpkt *pkt; - - ether->outpackets++; - - /* - * Check if the packet has to be placed back onto the input queue, - * i.e. if it's a loopback or broadcast packet or the interface is - * in promiscuous mode. - * If it's a loopback packet indicate to etheriq that the data isn't - * needed and return, etheriq will pass-on or free the block. - * To enable bridging to work, only packets that were originated - * by this interface are fed back. - */ - pkt = (Etherpkt*)bp->rp; - len = BLEN(bp); - loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0; - if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){ - s = splhi(); - etheriq(ether, bp, 0); - splx(s); - } - - if(!loopback){ - qbwrite(ether->oq, bp); - if(ether->transmit != nil) - ether->transmit(ether); - }else - freeb(bp); - - return len; -} - -static long -etherwrite(Chan* chan, void* buf, long n, vlong) -{ - Ether *ether; - Block *bp; - int onoff; - Cmdbuf *cb; - long l; - - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - if(NETTYPE(chan->qid.path) != Ndataqid) { - l = netifwrite(ether, chan, buf, n); - if(l >= 0) - goto out; - cb = parsecmd(buf, n); - if(strcmp(cb->f[0], "nonblocking") == 0){ - if(cb->nf <= 1) - onoff = 1; - else - onoff = atoi(cb->f[1]); - qnoblock(ether->oq, onoff); - free(cb); - goto out; - } - free(cb); - if(ether->ctl!=nil){ - l = ether->ctl(ether,buf,n); - goto out; - } - error(Ebadctl); - } - - if(n > ether->maxmtu) - error(Etoobig); - if(n < ether->minmtu) - error(Etoosmall); - bp = allocb(n); - if(waserror()){ - freeb(bp); - nexterror(); - } - memmove(bp->rp, buf, n); - memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen); - bp->wp += n; - poperror(); - - l = etheroq(ether, bp); -out: - poperror(); - runlock(ether); - return l; -} - -static long -etherbwrite(Chan* chan, Block* bp, ulong) -{ - Ether *ether; - long n; - - n = BLEN(bp); - if(NETTYPE(chan->qid.path) != Ndataqid){ - if(waserror()) { - freeb(bp); - nexterror(); - } - n = etherwrite(chan, bp->rp, n, 0); - poperror(); - freeb(bp); - return n; - } - ether = etherxx[chan->dev]; - rlock(ether); - if(waserror()) { - runlock(ether); - nexterror(); - } - if(n > ether->maxmtu){ - freeb(bp); - error(Etoobig); - } - if(n < ether->minmtu){ - freeb(bp); - error(Etoosmall); - } - n = etheroq(ether, bp); - poperror(); - runlock(ether); - return n; -} - -static struct { - char* type; - int (*reset)(Ether*); -} cards[MaxEther+1]; - -void -addethercard(char* t, int (*r)(Ether*)) -{ - static int ncard; - - if(ncard == MaxEther) - panic("too many ether cards"); - cards[ncard].type = t; - cards[ncard].reset = r; - ncard++; -} - -int -parseether(uchar *to, char *from) -{ - char nip[4]; - char *p; - int i; - - p = from; - for(i = 0; i < Eaddrlen; i++){ - if(*p == 0) - return -1; - nip[0] = *p++; - if(*p == 0) - return -1; - nip[1] = *p++; - nip[2] = 0; - to[i] = strtoul(nip, 0, 16); - if(*p == ':') - p++; - } - return 0; -} - -static void -etherreset(void) -{ - Ether *ether; - int i, n, ctlrno; - char name[KNAMELEN], buf[128]; - - for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){ - if(ether == 0) - ether = malloc(sizeof(Ether)); - memset(ether, 0, sizeof(Ether)); - ether->ctlrno = ctlrno; - ether->mbps = 10; - ether->minmtu = ETHERMINTU; - ether->maxmtu = ETHERMAXTU; - ether->tbdf = BUSUNKNOWN; - - if(archether(ctlrno, ether) <= 0) - continue; - - for(n = 0; cards[n].type; n++){ - if(cistrcmp(cards[n].type, ether->type)) - continue; - for(i = 0; i < ether->nopt; i++){ - if(cistrncmp(ether->opt[i], "ea=", 3) == 0){ - if(parseether(ether->ea, ðer->opt[i][3]) == -1) - memset(ether->ea, 0, Eaddrlen); - }else if(cistrcmp(ether->opt[i], "fullduplex") == 0 || - cistrcmp(ether->opt[i], "10BASE-TFD") == 0) - ether->fullduplex = 1; - else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0) - ether->mbps = 100; - } - if(cards[n].reset(ether)) - break; - snprint(name, sizeof(name), "ether%d", ctlrno); - - if(ether->interrupt != nil) - intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name); - - i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud", - ctlrno, ether->type, ether->mbps, ether->port, ether->irq); - if(ether->mem) - i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem)); - if(ether->size) - i += sprint(buf+i, " size 0x%luX", ether->size); - i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX", - ether->ea[0], ether->ea[1], ether->ea[2], - ether->ea[3], ether->ea[4], ether->ea[5]); - sprint(buf+i, "\n"); - print(buf); - - if(ether->mbps == 100){ - netifinit(ether, name, Ntypes, 256*1024); - if(ether->oq == 0) - ether->oq = qopen(256*1024, Qmsg, 0, 0); - } - else{ - netifinit(ether, name, Ntypes, 64*1024); - if(ether->oq == 0) - ether->oq = qopen(64*1024, Qmsg, 0, 0); - } - if(ether->oq == 0) - panic("etherreset %s", name); - ether->alen = Eaddrlen; - memmove(ether->addr, ether->ea, Eaddrlen); - memset(ether->bcast, 0xFF, Eaddrlen); - - etherxx[ctlrno] = ether; - ether = 0; - break; - } - } - if(ether) - free(ether); -} - -static void -etherpower(int on) -{ - int i; - Ether *ether; - - for(i = 0; i < MaxEther; i++){ - if((ether = etherxx[i]) == nil || ether->power == nil) - continue; - if(on){ - if(canrlock(ether)) - continue; - if(ether->power != nil) - ether->power(ether, on); - wunlock(ether); - }else{ - if(!canrlock(ether)) - continue; - wlock(ether); - if(ether->power != nil) - ether->power(ether, on); - /* Keep locked until power goes back on */ - } - } -} - -#define POLY 0xedb88320 - -/* really slow 32 bit crc for ethers */ -ulong -ethercrc(uchar *p, int len) -{ - int i, j; - ulong crc, b; - - crc = 0xffffffff; - for(i = 0; i < len; i++){ - b = *p++; - for(j = 0; j < 8; j++){ - crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0); - b >>= 1; - } - } - return crc; -} - -Dev etherdevtab = { - 'l', - "ether", - - etherreset, - devinit, - ethershutdown, - etherattach, - etherwalk, - etherstat, - etheropen, - ethercreate, - etherclose, - etherread, - etherbread, - etherwrite, - etherbwrite, - devremove, - etherwstat, - etherpower, -}; diff --git a/os/mpc/devpcmcia.c b/os/mpc/devpcmcia.c deleted file mode 100644 index 4c1d8311..00000000 --- a/os/mpc/devpcmcia.c +++ /dev/null @@ -1,1076 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -/* - * MPC821/3 PCMCIA driver (prototype) - * - * unlike the i82365 adapter, there isn't an offset register: - * card addresses are simply the lower order 26 bits of the host address. - * - * to do: - * split allocation of memory/attrib (all 26 bits valid) and io space (typically 10 or 12 bits) - * correct config - * interrupts and i/o space access - * DMA? - * power control - */ - -enum -{ - Maxctlr= 1, - Maxslot= 2, - Slotashift= 16, - - /* pipr */ - Cbvs1= 1<<15, - Cbvs2= 1<<14, - Cbwp= 1<<13, - Cbcd2= 1<<12, - Cbcd1= 1<<11, - Cbbvd2= 1<<10, - Cbbvd1= 1<<9, - Cbrdy= 1<<8, - - /* pscr and per */ - Cbvs1_c= 1<<15, - Cbvs2_c= 1<<14, - Cbwp_c= 1<<13, - Cbcd2_c= 1<<12, - Cbcd1_c= 1<<11, - Cbbvd2_c= 1<<10, - Cbbvd1_c= 1<<9, - Cbrdy_l= 1<<7, - Cbrdy_h= 1<<6, - Cbrdy_r= 1<<5, - Cbrdy_f= 1<<4, - - /* pgcr[n] */ - Cbdreq_int= 0<<14, - Cbdreq_iois16= 2<<14, - Cbdreq_spkr= 3<<14, - Cboe= 1<<7, - Cbreset= 1<<6, - - /* porN */ - Rport8= 0<<6, - Rport16= 1<<6, - Rmtype= 7<<3, /* memory type field */ - Rmem= 0<<3, /* common memory space */ - Rattrib= 2<<3, /* attribute space */ - Rio= 3<<3, - Rdma= 4<<3, /* normal DMA */ - Rdmalx= 5<<3, /* DMA, last transaction */ - RA22_23= 6<<3, /* ``drive A22 and A23 signals on CE2 and CE1'' */ - RslotB= 1<<2, /* select slot B (always, on MPC823) */ - Rwp= 1<<1, /* write protect */ - Rvalid= 1<<0, /* region valid */ - - Nmap= 8, /* max number of maps to use */ - - /* - * configuration registers - they start at an offset in attribute - * memory found in the CIS. - */ - Rconfig= 0, - Creset= (1<<7), /* reset device */ - Clevel= (1<<6), /* level sensitive interrupt line */ - Rccsr= 2, - Ciack = (1<<0), - Cipend = (1<<1), - Cpwrdown= (1<<2), - Caudioen= (1<<3), - Ciois8= (1<<5), - Cchgena= (1<<6), - Cchange= (1<<7), - Rpin= 4, /* pin replacement register */ - Rscpr= 6, /* socket and copy register */ - Riob0= 10, - Riob1= 12, - Riob2= 14, - Riob3= 16, - Riolim= 18, - - Maxctab= 8, /* maximum configuration table entries */ - MaxCIS = 8192, /* maximum CIS size in bytes */ - Mgran = 8192, /* maximum size of reads and writes */ - - Statusbounce=20, /* msec debounce time */ -}; - -typedef struct Ctlr Ctlr; - -/* a controller (there's only one) */ -struct Ctlr -{ - int dev; - int nslot; - - /* memory maps */ - Lock mlock; /* lock down the maps */ - PCMmap mmap[Nmap]; /* maps */ - - /* IO port allocation */ - ulong nextport; -}; -static Ctlr controller[Maxctlr]; - -static PCMslot *slot; -static PCMslot *lastslot; -static int nslot; - -static Map pcmmapv[Nmap+1]; -static RMap pcmmaps = {"PCMCIA mappings"}; - -static void pcmciaintr(Ureg*, void*); -static void pcmciareset(void); -static int pcmio(int, ISAConf*); -static long pcmread(int, int, void*, long, ulong); -static long pcmwrite(int, int, void*, long, ulong); -static void slotdis(PCMslot*); - -static ulong pcmmalloc(ulong, long); -static void pcmfree(ulong, long); -static void pcmciaproc(void*); - -static void pcmciadump(PCMslot*); - -/* - * get info about card - */ -static void -slotinfo(PCMslot *pp) -{ - ulong pipr; - - pipr = (m->iomem->pipr >> pp->slotshift) & 0xFF00; -print("pipr=%8.8lux/%lux\n", m->iomem->pipr, pipr); - pp->v3_3 = (pipr&Cbvs1)!=0; - pp->voltage = (((pipr & Cbvs2)!=0)<<1) | ((pipr & Cbvs1)!=0); - pp->occupied = (pipr&(Cbcd1|Cbcd2))==0; - pp->powered = pcmpowered(pp->slotno); - pp->battery = (pipr & (Cbbvd1|Cbbvd2))>>9; - pp->wrprot = (pipr&Cbwp)!=0; - pp->busy = (pipr&Cbrdy)==0; -} - -static void -pcmdelay(int ms) -{ - if(up == nil) - delay(ms); - else - tsleep(&up->sleep, return0, nil, ms); -} - -/* - * enable the slot card - */ -static void -slotena(PCMslot *pp) -{ - IMM *io; - - if(pp->enabled) - return; - m->iomem->pgcr[pp->slotno] &= ~Cboe; - pcmpower(pp->slotno, 1); - eieio(); - pcmdelay(300); - io = m->iomem; - io->pgcr[pp->slotno] |= Cbreset; /* active high */ - eieio(); - pcmdelay(100); - io->pgcr[pp->slotno] &= ~Cbreset; - eieio(); - pcmdelay(500); /* ludicrous delay */ - - /* get configuration */ - slotinfo(pp); - if(pp->occupied){ - if(pp->cisread == 0){ - pcmcisread(pp); - pp->cisread = 1; - } - pp->enabled = 1; - } else{ - print("empty slot\n"); - slotdis(pp); - } -} - -/* - * disable the slot card - */ -static void -slotdis(PCMslot *pp) -{ - int i; - Ctlr *ctlr; - PCMmap *pm; - -iprint("slotdis %d\n", pp->slotno); - pcmpower(pp->slotno, 0); - m->iomem->pgcr[pp->slotno] |= Cboe; - ctlr = pp->ctlr; - for(i = 0; i < nelem(ctlr->mmap); i++){ - pm = &ctlr->mmap[i]; - if(m->iomem->pcmr[i].option & Rvalid && pm->slotno == pp->slotno) - pcmunmap(pp->slotno, pm); - } - pp->enabled = 0; - pp->cisread = 0; -} - -static void -pcmciardy(Ureg *ur, void *a) -{ - PCMslot *pp; - ulong w; - - pp = a; - w = (m->iomem->pipr >> pp->slotshift) & 0xFF00; - if(pp->occupied && (w & Cbrdy) == 0){ /* interrupt */ -print("PCM.%dI#%lux|", pp->slotno, w); - if(pp->intr.f != nil) - pp->intr.f(ur, pp->intr.arg); - } -} - -void -pcmintrenable(int slotno, void (*f)(Ureg*, void*), void *arg) -{ - PCMslot *pp; - IMM *io; - char name[KNAMELEN]; - - if(slotno < 0 || slotno >= nslot) - panic("pcmintrenable"); - snprint(name, sizeof(name), "pcmcia.irq%d", slotno); - io = ioplock(); - pp = slot+slotno; - pp->intr.f = f; - pp->intr.arg = arg; - intrenable(PCMCIAio, pcmciardy, pp, BUSUNKNOWN, name); - io->per |= Cbrdy_l; /* assumes used for irq, not rdy; assumes level interrupt always right */ - iopunlock(); -} - -void -pcmintrdisable(int slotno, void (*f)(Ureg*, void*), void *arg) -{ - PCMslot *pp; - IMM *io; - char name[KNAMELEN]; - - if(slotno < 0 || slotno >= nslot) - panic("pcmintrdisable"); - snprint(name, sizeof(name), "pcmcia.irq%d", slotno); - io = ioplock(); - pp = slot+slotno; - if(pp->intr.f == f && pp->intr.arg == arg){ - pp->intr.f = nil; - pp->intr.arg = nil; - intrdisable(PCMCIAio, pcmciardy, pp, BUSUNKNOWN, name); - io->per &= ~Cbrdy_l; - } - iopunlock(); -} - -/* - * status change interrupt - * - * this wakes a monitoring process to read the CIS, - * rather than holding other interrupts out here. - */ - -static Rendez pcmstate; - -static int -statechanged(void *a) -{ - PCMslot *pp; - int in; - - pp = a; - in = (m->iomem->pipr & (Cbcd1|Cbcd2))==0; - return in != pp->occupied; -} - -static void -pcmciaintr(Ureg*, void*) -{ - ulong events; - - if(slot == 0) - return; - events = m->iomem->pscr & (Cbvs1_c|Cbvs2_c|Cbwp_c|Cbcd2_c|Cbcd1_c|Cbbvd2_c|Cbbvd1_c); - eieio(); - m->iomem->pscr = events; - /* TO DO: other slot */ -iprint("PCM: #%lux|", events); -iprint("pipr=#%lux|", m->iomem->pipr & 0xFF00); - wakeup(&pcmstate); -} - -static void -pcmciaproc(void*) -{ - ulong csc; - PCMslot *pp; - int was; - - for(;;){ - sleep(&pcmstate, statechanged, slot+1); - tsleep(&up->sleep, return0, nil, Statusbounce); - /* - * voltage change 1,2 - * write protect change - * card detect 1,2 - * battery voltage 1 change (or SPKR-bar) - * battery voltage 2 change (or STSCHG-bar) - * card B rdy / IRQ-bar low - * card B rdy / IRQ-bar high - * card B rdy / IRQ-bar rising edge - * card B rdy / IRQ-bar falling edge - * - * TO DO: currently only handle card-present changes - */ - - for(pp = slot; pp < lastslot; pp++){ - if(pp->memlen == 0) - continue; - csc = (m->iomem->pipr>>pp->slotshift) & (Cbcd1|Cbcd2); - was = pp->occupied; - slotinfo(pp); - if(csc == 0 && was != pp->occupied){ - if(!pp->occupied){ - slotdis(pp); - if(pp->special && pp->notify.f != nil) - pp->notify.f(pp->notify.arg, 1); - } - } - } - } -} - -static uchar greycode[] = { - 0, 1, 3, 2, 6, 7, 5, 4, 014, 015, 017, 016, 012, 013, 011, 010, - 030, 031, 033, 032, 036, 037, 035, 034, 024, 025, 027 -}; - -/* - * get a map for pc card region, return corrected len - */ -PCMmap* -pcmmap(int slotno, ulong offset, int len, int attr) -{ - Ctlr *ctlr; - PCMslot *pp; - PCMmap *pm, *nm; - IMM *io; - int i; - ulong e, bsize, code, opt; - - if(0) - print("pcmmap: %d #%lux %d #%x\n", slotno, offset, len, attr); - pp = slot + slotno; - if(!pp->occupied) - return nil; - if(attr == 1){ /* account for ../port/cis.c's conventions */ - attr = Rattrib; - if(len <= 0) - len = MaxCIS*2; /* TO DO */ - } - ctlr = pp->ctlr; - - /* convert offset to granularity */ - if(len <= 0) - len = 1; - e = offset+len; - for(i=0;; i++){ - if(i >= nelem(greycode)) - return nil; - bsize = 1<<i; - offset &= ~(bsize-1); - if(e <= offset+bsize) - break; - } - code = greycode[i]; - if(0) - print("i=%d bsize=%lud code=0%luo\n", i, bsize, code); - e = offset+bsize; - len = bsize; - - lock(&ctlr->mlock); - - /* look for an existing map that covers the right area */ - io = m->iomem; - nm = nil; - for(i=0; i<Nmap; i++){ - pm = &ctlr->mmap[i]; - if(io->pcmr[i].option & Rvalid && - pm->slotno == slotno && - pm->attr == attr && - offset >= pm->ca && e <= pm->cea){ - pm->ref++; - unlock(&ctlr->mlock); - return pm; - } - if(nm == 0 && pm->ref == 0) - nm = pm; - } - pm = nm; - if(pm == nil){ - unlock(&ctlr->mlock); - return nil; - } - - /* set up new map */ - pm->isa = pcmmalloc(offset, len); - if(pm->isa == 0){ - /* address not available: in use, or too much to map */ - unlock(&ctlr->mlock); - return 0; - } - if(0) - print("mx=%d isa=#%lux\n", (int)(pm - ctlr->mmap), pm->isa); - - pm->len = len; - pm->ca = offset; - pm->cea = pm->ca + pm->len; - pm->attr = attr; - i = pm - ctlr->mmap; - io->pcmr[i].option &= ~Rvalid; /* disable map before changing it */ - io->pcmr[i].base = pm->isa; - opt = attr; - opt |= code<<27; - if((attr&Rmtype) == Rio){ - opt |= 4<<12; /* PSST */ - opt |= 8<<7; /* PSL */ - opt |= 2<<16; /* PSHT */ - }else{ - opt |= 6<<12; /* PSST */ - opt |= 24<<7; /* PSL */ - opt |= 8<<16; /* PSHT */ - } - if((attr & Rport16) == 0) - opt |= Rport8; - if(slotno == 1) - opt |= RslotB; - io->pcmr[i].option = opt | Rvalid; - pm->slotno = slotno; - pm->ref = 1; - - unlock(&ctlr->mlock); - return pm; -} - -static void -pcmiomap(PCMslot *pp, PCMconftab *ct, int i) -{ - int n, attr; - Ctlr *ctlr; - - if(0) - print("pcm iomap #%lux %lud\n", ct->io[i].start, ct->io[i].len); - if(ct->io[i].len <= 0) - return; - if(ct->io[i].start == 0){ - n = 1<<ct->nlines; - ctlr = pp->ctlr; - lock(&ctlr->mlock); - if(ctlr->nextport == 0) - ctlr->nextport = 0xF000; - ctlr->nextport = (ctlr->nextport + n - 1) & ~(n-1); - ct->io[i].start = ctlr->nextport; - ct->io[i].len = n; - ctlr->nextport += n; - unlock(&ctlr->mlock); - } - attr = Rio; - if(ct->bit16) - attr |= Rport16; - ct->io[i].map = pcmmap(pp->slotno, ct->io[i].start, ct->io[i].len, attr); -} - -void -pcmunmap(int slotno, PCMmap* pm) -{ - int i; - PCMslot *pp; - Ctlr *ctlr; - - pp = slot + slotno; - if(pp->memlen == 0) - return; - ctlr = pp->ctlr; - lock(&ctlr->mlock); - if(pp->slotno == pm->slotno && --pm->ref == 0){ - i = pm - ctlr->mmap; - m->iomem->pcmr[i].option = 0; - m->iomem->pcmr[i].base = 0; - pcmfree(pm->isa, pm->len); - } - unlock(&ctlr->mlock); -} - -static void -increfp(PCMslot *pp) -{ - if(incref(pp) == 1) - slotena(pp); -} - -static void -decrefp(PCMslot *pp) -{ - if(decref(pp) == 0) - slotdis(pp); -} - -/* - * look for a card whose version contains 'idstr' - */ -int -pcmspecial(char *idstr, ISAConf *isa) -{ - PCMslot *pp; - extern char *strstr(char*, char*); - - pcmciareset(); - for(pp = slot; pp < lastslot; pp++){ - if(pp->special || pp->memlen == 0) - continue; /* already taken */ - increfp(pp); - if(pp->occupied && strstr(pp->verstr, idstr)){ - print("PCMslot #%d: Found %s - ",pp->slotno, idstr); - if(isa == 0 || pcmio(pp->slotno, isa) == 0){ - print("ok.\n"); - pp->special = 1; - return pp->slotno; - } - print("error with isa io\n"); - } - decrefp(pp); - } - return -1; -} - -void -pcmspecialclose(int slotno) -{ - PCMslot *pp; - - if(slotno >= nslot) - panic("pcmspecialclose"); - pp = slot + slotno; - pp->special = 0; - decrefp(pp); -} - -void -pcmnotify(int slotno, void (*f)(void*, int), void* a) -{ - PCMslot *pp; - - if(slotno < 0 || slotno >= nslot) - panic("pcmnotify"); - pp = slot + slotno; - if(pp->occupied && pp->special){ - pp->notify.f = f; - pp->notify.arg = a; - } -} - -/* - * reserve pcmcia slot address space [addr, addr+size[, - * returning a pointer to it, or nil if the space was already reserved. - */ -static ulong -pcmmalloc(ulong addr, long size) -{ - return rmapalloc(&pcmmaps, PHYSPCMCIA+addr, size, size); -} - -static void -pcmfree(ulong a, long size) -{ - if(a != 0 && size > 0) - mapfree(&pcmmaps, a, size); -} - -enum -{ - Qdir, - Qmem, - Qattr, - Qctl, -}; - -#define SLOTNO(c) ((c->qid.path>>8)&0xff) -#define TYPE(c) (c->qid.path&0xff) -#define QID(s,t) (((s)<<8)|(t)) - -static int -pcmgen(Chan *c, char*, Dirtab*, int, int i, Dir *dp) -{ - int slotno; - Qid qid; - long len; - PCMslot *pp; - - if(i>=3*nslot) - return -1; - slotno = i/3; - pp = slot + slotno; - if(pp->memlen == 0) - return 0; - len = 0; - switch(i%3){ - case 0: - qid.path = QID(slotno, Qmem); - sprint(up->genbuf, "pcm%dmem", slotno); - len = pp->memlen; - break; - case 1: - qid.path = QID(slotno, Qattr); - sprint(up->genbuf, "pcm%dattr", slotno); - len = pp->memlen; - break; - case 2: - qid.path = QID(slotno, Qctl); - sprint(up->genbuf, "pcm%dctl", slotno); - break; - } - qid.vers = 0; - devdir(c, qid, up->genbuf, len, eve, 0660, dp); - return 1; -} - -/* - * used only when debugging - */ -static void -pcmciadump(PCMslot *) -{ - IMM *io; - int i; - - io = m->iomem; - print("pipr #%4.4lux pscr #%4.4lux per #%4.4lux pgcr[1] #%8.8lux\n", - io->pipr & 0xFFFF, io->pscr & 0xFFFF, io->per & 0xFFFF, io->pgcr[1]); - for(i=0; i<8; i++) - print("pbr%d #%8.8lux por%d #%8.8lux\n", i, io->pcmr[i].base, i, io->pcmr[i].option); -} - -/* - * set up for slot cards - */ -static void -pcmciareset(void) -{ - static int already; - int i; - Ctlr *cp; - IMM *io; - PCMslot *pp; - - if(already) - return; - already = 1; - - cp = controller; - /* TO DO: set low power mode? ... */ - - mapinit(&pcmmaps, pcmmapv, sizeof(pcmmapv)); - mapfree(&pcmmaps, PHYSPCMCIA, PCMCIALEN); - - io = m->iomem; - - for(i=0; i<8; i++){ - io->pcmr[i].option = 0; - io->pcmr[i].base = 0; - } - - io->pscr = ~0; /* reset status */ - /* TO DO: Cboe, Cbreset */ - /* TO DO: two slots except on 823 */ - pcmenable(); - /* TO DO: if the card is there turn on 5V power to keep its battery alive */ - slot = xalloc(Maxslot * sizeof(PCMslot)); - lastslot = slot; - slot[0].slotshift = Slotashift; - slot[1].slotshift = 0; - for(i=0; i<Maxslot; i++){ - pp = &slot[i]; - if(!pcmslotavail(i)){ - pp->memlen = 0; - continue; - } - io->per |= (Cbvs1_c|Cbvs2_c|Cbwp_c|Cbcd2_c|Cbcd1_c|Cbbvd2_c|Cbbvd1_c)<<pp->slotshift; /* enable status interrupts */ - io->pgcr[i] = (1<<(31-PCMCIAio)) | (1<<(23-PCMCIAstatus)); - pp->slotno = i; - pp->memlen = 8*MB; - pp->ctlr = cp; - //slotdis(pp); - lastslot = slot; - nslot = i+1; - } - if(1) - pcmciadump(slot); - intrenable(PCMCIAstatus, pcmciaintr, cp, BUSUNKNOWN, "pcmcia"); - print("pcmcia reset\n"); -} - -static void -pcmciainit(void) -{ - kproc("pcmcia", pcmciaproc, nil, 0); -} - -static Chan* -pcmciaattach(char *spec) -{ - return devattach('y', spec); -} - -static Walkqid* -pcmciawalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, 0, 0, pcmgen); -} - -static int -pcmciastat(Chan *c, uchar *dp, int n) -{ - return devstat(c, dp, n, 0, 0, pcmgen); -} - -static Chan* -pcmciaopen(Chan *c, int omode) -{ - if(c->qid.type & QTDIR){ - if(omode != OREAD) - error(Eperm); - } else - increfp(slot + SLOTNO(c)); - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -static void -pcmciaclose(Chan *c) -{ - if(c->flag & COPEN) - if((c->qid.type & QTDIR) == 0) - decrefp(slot+SLOTNO(c)); -} - -/* a memmove using only bytes */ -static void -memmoveb(uchar *to, uchar *from, int n) -{ - while(n-- > 0) - *to++ = *from++; -} - -static long -pcmread(int slotno, int attr, void *a, long n, ulong offset) -{ - int i, len; - PCMmap *m; - void *ka; - uchar *ac; - PCMslot *pp; - - pp = slot + slotno; - if(pp->memlen < offset) - return 0; - if(pp->memlen < offset + n) - n = pp->memlen - offset; - - ac = a; - for(len = n; len > 0; len -= i){ - if((i = len) > Mgran) - i = Mgran; - m = pcmmap(pp->slotno, offset, i, attr? Rattrib: Rmem); - if(m == 0) - error("can't map PCMCIA card"); - if(waserror()){ - if(m) - pcmunmap(pp->slotno, m); - nexterror(); - } - if(offset + len > m->cea) - i = m->cea - offset; - else - i = len; - ka = (char*)KADDR(m->isa) + (offset - m->ca); - memmoveb(ac, ka, i); - poperror(); - pcmunmap(pp->slotno, m); - offset += i; - ac += i; - } - - return n; -} - -static long -pcmciaread(Chan *c, void *a, long n, vlong offset) -{ - char *cp, *buf; - ulong p; - PCMslot *pp; - - p = TYPE(c); - switch(p){ - case Qdir: - return devdirread(c, a, n, 0, 0, pcmgen); - case Qmem: - case Qattr: - return pcmread(SLOTNO(c), p==Qattr, a, n, offset); - case Qctl: - buf = malloc(READSTR); - if(buf == nil) - error(Enomem); - if(waserror()){ - free(buf); - nexterror(); - } - cp = buf; - pp = slot + SLOTNO(c); - if(pp->occupied) - cp += sprint(cp, "occupied\n"); - if(pp->enabled) - cp += sprint(cp, "enabled\n"); - if(pp->powered) - cp += sprint(cp, "powered\n"); - if(pp->configed) - cp += sprint(cp, "configed\n"); - if(pp->wrprot) - cp += sprint(cp, "write protected\n"); - if(pp->busy) - cp += sprint(cp, "busy\n"); - if(pp->v3_3) - cp += sprint(cp, "3.3v ok\n"); - cp += sprint(cp, "battery lvl %d\n", pp->battery); - cp += sprint(cp, "voltage select %d\n", pp->voltage); - /* TO DO: could return pgcr[] values for debugging */ - *cp = 0; - n = readstr(offset, a, n, buf); - poperror(); - free(buf); - break; - default: - n=0; - break; - } - return n; -} - -static long -pcmwrite(int dev, int attr, void *a, long n, ulong offset) -{ - int i, len; - PCMmap *m; - void *ka; - uchar *ac; - PCMslot *pp; - - pp = slot + dev; - if(pp->memlen < offset) - return 0; - if(pp->memlen < offset + n) - n = pp->memlen - offset; - - ac = a; - for(len = n; len > 0; len -= i){ - if((i = len) > Mgran) - i = Mgran; - m = pcmmap(pp->slotno, offset, i, attr? Rattrib: Rmem); - if(m == 0) - error("can't map PCMCIA card"); - if(waserror()){ - if(m) - pcmunmap(pp->slotno, m); - nexterror(); - } - if(offset + len > m->cea) - i = m->cea - offset; - else - i = len; - ka = (char*)KADDR(m->isa) + (offset - m->ca); - memmoveb(ka, ac, i); - poperror(); - pcmunmap(pp->slotno, m); - offset += i; - ac += i; - } - - return n; -} - -static long -pcmciawrite(Chan *c, void *a, long n, vlong offset) -{ - ulong p; - PCMslot *pp; - char buf[32]; - - p = TYPE(c); - switch(p){ - case Qctl: - if(n >= sizeof(buf)) - n = sizeof(buf) - 1; - strncpy(buf, a, n); - buf[n] = 0; - pp = slot + SLOTNO(c); - if(!pp->occupied) - error(Eio); - - /* set vpp on card */ - if(strncmp(buf, "vpp", 3) == 0){ - p = strtol(buf+3, nil, 0); - pcmsetvpp(pp->slotno, p); - } - break; - case Qmem: - case Qattr: - pp = slot + SLOTNO(c); - if(pp->occupied == 0 || pp->enabled == 0) - error(Eio); - n = pcmwrite(pp->slotno, p == Qattr, a, n, offset); - if(n < 0) - error(Eio); - break; - default: - error(Ebadusefd); - } - return n; -} - -Dev pcmciadevtab = { - 'y', - "pcmcia", - - pcmciareset, - pcmciainit, - devshutdown, - pcmciaattach, - pcmciawalk, - pcmciastat, - pcmciaopen, - devcreate, - pcmciaclose, - pcmciaread, - devbread, - pcmciawrite, - devbwrite, - devremove, - devwstat, -}; - -/* - * configure the PCMslot for IO. We assume very heavily that we can read - * configuration info from the CIS. If not, we won't set up correctly. - */ -static int -pcmio(int slotno, ISAConf *isa) -{ - PCMslot *pp; - PCMconftab *ct, *et, *t; - PCMmap *pm; - uchar *p; - int irq, i, x; - - irq = isa->irq; - if(irq == 2) - irq = 9; - - if(slotno > nslot) - return -1; - pp = slot + slotno; - - if(!pp->occupied) - return -1; - - et = &pp->ctab[pp->nctab]; - - /* assume default is right */ - if(pp->def) - ct = pp->def; - else - ct = pp->ctab; - /* try for best match */ - if(ct->nlines == 0 || ct->io[0].start != isa->port || ((1<<irq) & ct->irqs) == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nlines && t->io[0].start == isa->port && ((1<<irq) & t->irqs)){ - ct = t; - break; - } - } - if(ct->nlines == 0 || ((1<<irq) & ct->irqs) == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nlines && ((1<<irq) & t->irqs)){ - ct = t; - break; - } - } - if(ct->nlines == 0){ - for(t = pp->ctab; t < et; t++) - if(t->nlines){ - ct = t; - break; - } - } -print("slot %d: nlines=%d iolen=%lud irq=%d ct->index=%d nport=%d ct->port=#%lux/%lux\n", slotno, ct->nlines, ct->io[0].len, irq, ct->index, ct->nio, ct->io[0].start, isa->port); - if(ct == et || ct->nlines == 0) - return -1; - /* route interrupts */ - isa->irq = irq; - //wrreg(pp, Rigc, irq | Fnotreset | Fiocard); - delay(2); - - /* set power and enable device */ - pcmsetvcc(pp->slotno, ct->vcc); - pcmsetvpp(pp->slotno, ct->vpp1); - - delay(2); /* could poll BSY during power change */ - - for(i=0; i<ct->nio; i++) - pcmiomap(pp, ct, i); - - if(ct->nio) - isa->port = ct->io[0].start; - - /* only touch Rconfig if it is present */ - if(pp->cpresent & (1<<Rconfig)){ -print("Rconfig present: #%lux\n", pp->caddr+Rconfig); - /* Reset adapter */ - pm = pcmmap(slotno, pp->caddr + Rconfig, 1, Rattrib); - if(pm == nil) - return -1; - - p = (uchar*)KADDR(pm->isa) + (pp->caddr + Rconfig - pm->ca); - - /* set configuration and interrupt type */ - x = ct->index; - if((ct->irqtype & 0x20) && ((ct->irqtype & 0x40)==0 || isa->irq>7)) - x |= Clevel; - *p = x; - delay(5); - - pcmunmap(pp->slotno, pm); -print("Adapter reset\n"); - } - - return 0; -} diff --git a/os/mpc/devrtc.c b/os/mpc/devrtc.c deleted file mode 100644 index 90193764..00000000 --- a/os/mpc/devrtc.c +++ /dev/null @@ -1,258 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#include "io.h" - -/* - * MPC8xx real time clock - * optional board option switch - * optional nvram - * interrupt statistics - */ - -enum{ - Qdir, - Qrtc, - Qswitch, - Qnvram, - Qintstat, - - Qporta, - Qportb, - Qportc, - - /* sccr */ - RTDIV= 1<<24, - RTSEL= 1<<23, - - /* rtcsc */ - RTE= 1<<0, - R38K= 1<<4, -}; - -static QLock rtclock; /* mutex on clock operations */ - -static Dirtab rtcdir[]={ - ".", {Qdir,0,QTDIR}, 0, 0555, - "rtc", {Qrtc, 0}, 12, 0664, - "switch", {Qswitch, 0}, 0, 0444, - "intstat", {Qintstat, 0}, 0, 0444, - "porta", {Qporta, 0}, 0, 0444, - "portb", {Qportb, 0}, 0, 0444, - "portc", {Qportc, 0}, 0, 0444, - "nvram", {Qnvram, 0}, 0, 0660, -}; -static long nrtc = nelem(rtcdir)-1; /* excludes nvram */ - -static long readport(int, ulong, char*, long); - -static void -rtcreset(void) -{ - IMM *io; - int n; - - io = m->iomem; - io->rtcsck = KEEP_ALIVE_KEY; - n = (RTClevel<<8)|RTE; - if(m->clockgen == 5*MHz) - n |= R38K; - io->rtcsc = n; - io->rtcsck = ~KEEP_ALIVE_KEY; - if(conf.nvramsize != 0){ - rtcdir[nrtc].length = conf.nvramsize; - nrtc++; - } -} - -static Chan* -rtcattach(char *spec) -{ - return devattach('r', spec); -} - -static Walkqid* -rtcwalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, rtcdir, nrtc, devgen); -} - -static int -rtcstat(Chan *c, uchar *dp, int n) -{ - return devstat(c, dp, n, rtcdir, nrtc, devgen); -} - -static Chan* -rtcopen(Chan *c, int omode) -{ - return devopen(c, omode, rtcdir, nrtc, devgen); -} - -static void -rtcclose(Chan*) -{ -} - -static long -rtcread(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - ulong t; - char *b; - - if(c->qid.type & QTDIR) - return devdirread(c, buf, n, rtcdir, nrtc, devgen); - - switch((ulong)c->qid.path){ - case Qrtc: - t = m->iomem->rtc; - n = readnum(offset, buf, n, t, 12); - return n; - case Qswitch: - return readnum(offset, buf, n, archoptionsw(), 12); - case Qintstat: - b = malloc(2048); - if(waserror()){ - free(b); - nexterror(); - } - intrstats(b, 2048); - t = readstr(offset, buf, n, b); - poperror(); - free(b); - return t; - case Qporta: - case Qportb: - case Qportc: - return readport(c->qid.path, offset, buf, n); - case Qnvram: - if(offset < 0 || offset >= conf.nvramsize) - return 0; - if(offset + n > conf.nvramsize) - n = conf.nvramsize - offset; - memmove(buf, (char*)conf.nvrambase+offset, n); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -static long -rtcwrite(Chan *c, void *buf, long n, vlong off) -{ - ulong offset = off; - ulong secs; - char *cp, sbuf[32]; - IMM *io; - - switch((ulong)c->qid.path){ - case Qrtc: - /* - * read the time - */ - if(offset != 0 || n >= sizeof(sbuf)-1) - error(Ebadarg); - memmove(sbuf, buf, n); - sbuf[n] = '\0'; - cp = sbuf; - while(*cp){ - if(*cp>='0' && *cp<='9') - break; - cp++; - } - secs = strtoul(cp, 0, 0); - /* - * set it - */ - io = ioplock(); - io->rtck = KEEP_ALIVE_KEY; - io->rtc = secs; - io->rtck = ~KEEP_ALIVE_KEY; - iopunlock(); - return n; - case Qnvram: - if(offset < 0 || offset >= conf.nvramsize) - return 0; - if(offset + n > conf.nvramsize) - n = conf.nvramsize - offset; - memmove((char*)conf.nvrambase+offset, buf, n); - return n; - } - error(Egreg); - return 0; /* not reached */ -} - -static long -readport(int p, ulong offset, char *buf, long n) -{ - long t; - char *b; - int v[4], i; - IMM *io; - - io = m->iomem; - for(i=0;i<nelem(v); i++) - v[i] = 0; - switch(p){ - case Qporta: - v[0] = io->padat; - v[1] = io->padir; - v[2] = io->papar; - break; - case Qportb: - v[0] = io->pbdat; - v[1] = io->pbdir; - v[2] = io->pbpar; - break; - case Qportc: - v[0] = io->pcdat; - v[1] = io->pcdir; - v[2] = io->pcpar; - v[3] = io->pcso; - break; - } - b = malloc(READSTR); - if(waserror()){ - free(b); - nexterror(); - } - t = 0; - for(i=0; i<nelem(v); i++) - t += snprint(b+t, READSTR-t, " %8.8ux", v[i]); - t = readstr(offset, buf, n, b); - poperror(); - free(b); - return t; -} - -long -rtctime(void) -{ - return m->iomem->rtc; -} - -Dev rtcdevtab = { - 'r', - "rtc", - - rtcreset, - devinit, - devshutdown, - rtcattach, - rtcwalk, - rtcstat, - rtcopen, - devcreate, - rtcclose, - rtcread, - devbread, - rtcwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/mpc/devtouch.c b/os/mpc/devtouch.c deleted file mode 100644 index b11aecc8..00000000 --- a/os/mpc/devtouch.c +++ /dev/null @@ -1,497 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#define DPRINT if(0)print -#define THREEBUT 0 /* !=0, enable 3-button emulation (see below) */ - -/* - * DynaPro touch panel and Maxim MAX192 A/D converter on - * York Electronics Centre's BRD/98/024 (Version A) interface, - * accessed via mpc8xx SPI interface (see spi.c). - * - * The highest level of the driver is derived from the ARM/UCB touch panel driver, - * simplified because of the differences between the panels. - */ - -/* - * Values determined by interface board - */ -enum { - /* MAX192 control words */ - MeasureX = (1<<7)|(0<<6)|(1<<3)|(1<<2)|3, /* start, channel 0, unipolar, single-ended, external clock */ - MeasureY = (1<<7)|(1<<6)|(1<<3)|(1<<2)|3, /* start, channel 1, unipolar, single-ended, external clock */ - - /* port B bits */ - ADselect = IBIT(16), /* chip select to MAX192, active low */ - - /* port C bits */ - Xenable = 1<<2, /* PC13: TOUCH_XEN, active low */ - Yenable = 1<<3, /* PC12: TOUCH_YEN, active low */ - Touched = 1<<10, /* PC5: contact detect, active low */ - - /* interrupt control via port C */ - TouchIRQ= 2, /* parallel i/o - PC5 */ - TouchEnable= 1<<TouchIRQ, /* mask for cimr */ - - /* other parameters */ - Nconverge = 10, /* maximum iterations for convergence */ - MaxDelta = 2, /* acceptable change in X/Y between iterations */ -}; - -/* - * ADC interface via SPI (see MAX192 data sheet) - * select the ADC - * send 8-bit control word and two zero bytes to clock the conversion - * receive three data bytes - * deselect the ADC and return the result - */ -static int -getcoord(int cw) -{ - uchar tbuf[3], rbuf[3]; - IMM *io; - int nr; - - tbuf[0] = cw; - tbuf[1] = 0; - tbuf[2] = 0; - io = ioplock(); - io->pbdat &= ~ADselect; - iopunlock(); - nr = spioutin(tbuf, sizeof(tbuf), rbuf); - io = ioplock(); - io->pbdat |= ADselect; - iopunlock(); - if(nr != 3) - return -1; - return ((rbuf[1]<<8)|rbuf[2])>>5; -} - -/* - * keep reading the a/d until the value stabilises - */ -static int -dejitter(int enable, int cw) -{ - int i, diff, prev, v; - IMM *io; - - io = ioplock(); - io->pcdat &= ~enable; /* active low */ - iopunlock(); - - i = 0; - v = getcoord(cw); - do{ - prev = v; - v = getcoord(cw); - diff = v - prev; - if(diff < 0) - diff = -diff; - }while(diff >= MaxDelta && ++i <= Nconverge); - - io = ioplock(); - io->pcdat |= enable; - iopunlock(); - return v; -} - -static void -adcreset(void) -{ - IMM *io; - - /* select port pins */ - io = ioplock(); - io->pcdir &= ~(Xenable|Yenable); /* ensure set to input before changing state */ - io->pcpar &= ~(Xenable|Yenable); - io->pcdat |= Xenable|Yenable; - io->pcdir |= Xenable; /* change enable bits to output one at a time to avoid both being low at once (could damage panel) */ - io->pcdat |= Xenable; /* ensure it's high after making it an output */ - io->pcdir |= Yenable; - io->pcdat |= Yenable; /* ensure it's high after making it an output */ - io->pcso &= ~(Xenable|Yenable); - io->pbdat |= ADselect; - io->pbpar &= ~ADselect; - io->pbdir |= ADselect; - iopunlock(); -} - -/* - * high-level touch panel interface - */ - -/* to and from fixed point */ -#define FX(n) ((n)<<16) -#define XF(v) ((v)>>16) - -typedef struct Touch Touch; - -struct Touch { - Lock; - Rendez r; - int m[2][3]; /* transformation matrix */ - int rate; - int down; - int raw_count; - int valid_count; - int wake_time; - int sleep_time; -}; - -static Touch touch = { - {0}, - .r {0}, - .m {{FX(1), 0, 0},{0, FX(1), 0}}, /* default is 1:1 */ - .rate 20, /* milliseconds */ -}; - -/* - * panel-touched state and interrupt - */ - -static int -touching(void) -{ - eieio(); - return (m->iomem->pcdat & Touched) == 0; -} - -static int -ispendown(void*) -{ - return touch.down || touching(); -} - -static void -touchintr(Ureg*, void*) -{ - if((m->iomem->pcdat & Touched) == 0){ - m->iomem->cimr &= ~TouchEnable; /* mask interrupts when reading pen */ - touch.down = 1; - wakeup(&touch.r); - } -} - -static void -touchenable(void) -{ - IMM *io; - - io = ioplock(); - io->cimr |= TouchEnable; - iopunlock(); -} - -/* - * touchctl commands: - * X a b c - set X transformation - * Y d e f - set Y transformation - * s<delay> - set sample delay in millisec per sample - * r<delay> - set read delay in microsec - * R<l2nr> - set log2 of number of readings to average - */ - -enum{ - Qdir, - Qtouchctl, - Qtouchstat, - Qtouch, -}; - -Dirtab touchdir[]={ - ".", {Qdir, 0, QTDIR}, 0, 0555, - "touchctl", {Qtouchctl, 0}, 0, 0666, - "touchstat", {Qtouchstat, 0}, 0, 0444, - "touch", {Qtouch, 0}, 0, 0444, -}; - -static int -ptmap(int *m, int x, int y) -{ - return XF(m[0]*x + m[1]*y + m[2]); -} - -/* - * read a point from the touch panel; - * returns true iff the point is valid, otherwise x, y aren't changed - */ -static int -touchreadxy(int *fx, int *fy) -{ - int rx, ry; - - if(touching()){ - rx = dejitter(Xenable, MeasureX); - ry = dejitter(Yenable, MeasureY); - microdelay(40); - if(rx >=0 && ry >= 0){ - if(0) - print("touch %d %d\n", rx, ry); - *fx = ptmap(touch.m[0], rx, ry); - *fy = ptmap(touch.m[1], rx, ry); - touch.raw_count++; - return 1; - } - } - return 0; -} - -#define timer_start() 0 /* could use TBL if necessary */ -#define tmr2us(n) 0 - -static void -touchproc(void*) -{ - int b, i, x, y; - ulong t1, t2; - - t1 = timer_start(); - b = 1; - for(;;) { - //setpri(PriHi); - do{ - touch.down = 0; - touch.wake_time += (t2 = timer_start())-t1; - touchenable(); - sleep(&touch.r, ispendown, nil); - touch.sleep_time += (t1 = timer_start())-t2; - }while(!touchreadxy(&x, &y)); - - /* 640x480-specific 3-button emulation hack: */ - if(THREEBUT){ - if(y > 481) { - b = ((639-x) >> 7); - continue; - } else if(y < -2) { - b = (x >> 7)+3; - continue; - } - } - - DPRINT("#%d %d", x, y); - mousetrack(b, x, y, 0); - setpri(PriNormal); - while(touching()) { - for(i=0; i<3; i++) - if(touchreadxy(&x, &y)) { - DPRINT("*%d %d", x, y); - mousetrack(b, x, y, 0); - break; - } - touch.wake_time += (t2 = timer_start())-t1; - tsleep(&touch.r, return0, nil, touch.rate); - touch.sleep_time += (t1 = timer_start())-t2; - } - mousetrack(0, x, y, 0); - b = 1; /* go back to just button one for next press */ - } -} - -static void -touchreset(void) -{ - IMM *io; - - spireset(); - adcreset(); - intrenable(VectorCPIC+TouchIRQ, touchintr, &touch, BUSUNKNOWN, "touch"); - - /* set i/o pin to interrupt when panel touched */ - io = ioplock(); - io->pcdat &= ~Touched; - io->pcpar &= ~Touched; - io->pcdir &= ~Touched; - io->pcso &= ~Touched; - io->pcint |= Touched; /* high-to-low trigger */ - io->cimr &= ~TouchEnable; /* touchproc will enable when ready */ - iopunlock(); -} - -static void -touchinit(void) -{ - static int done; - - if(!done){ - done = 1; - kproc( "touchscreen", touchproc, nil, 0); - } -} - -static Chan* -touchattach(char* spec) -{ - return devattach('T', spec); -} - -static Walkqid* -touchwalk(Chan* c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, touchdir, nelem(touchdir), devgen); -} - -static int -touchstat(Chan* c, uchar* dp, int n) -{ - return devstat(c, dp, n, touchdir, nelem(touchdir), devgen); -} - -static Chan* -touchopen(Chan* c, int omode) -{ - omode = openmode(omode); - switch((ulong)c->qid.path){ - case Qtouchctl: - case Qtouchstat: - if(!iseve()) - error(Eperm); - break; - } - return devopen(c, omode, touchdir, nelem(touchdir), devgen); -} - -static void -touchclose(Chan*) -{ -} - -static long -touchread(Chan* c, void* buf, long n, vlong offset) -{ - char *tmp; - int x, y; - - if(c->qid.type & QTDIR) - return devdirread(c, buf, n, touchdir, nelem(touchdir), devgen); - - tmp = malloc(READSTR); - if(waserror()){ - free(tmp); - nexterror(); - } - switch((ulong)c->qid.path){ - case Qtouch: - if(!touchreadxy(&x, &y)) - x = y = -1; - snprint(tmp, READSTR, "%d %d", x, y); - break; - case Qtouchctl: - snprint(tmp, READSTR, "s%d\nr%d\nR%d\nX %d %d %d\nY %d %d %d\n", - touch.rate, 0, 1, - touch.m[0][0], touch.m[0][1], touch.m[0][2], - touch.m[1][0], touch.m[1][1], touch.m[1][2]); - break; - case Qtouchstat: - snprint(tmp, READSTR, "%d %d\n%d %d\n", - touch.raw_count, touch.valid_count, tmr2us(touch.sleep_time), tmr2us(touch.wake_time)); - touch.raw_count = 0; - touch.valid_count = 0; - touch.sleep_time = 0; - touch.wake_time = 0; - break; - default: - error(Ebadarg); - return 0; - } - n = readstr(offset, buf, n, tmp); - poperror(); - free(tmp); - return n; -} - -static void -dotouchwrite(Chan *c, char *buf) -{ - char *field[8]; - int nf, cmd, pn, m[3], n; - - nf = getfields(buf, field, nelem(field), 1, " \t\n"); - if(nf <= 0) - return; - switch((ulong)c->qid.path){ - case Qtouchctl: - cmd = *(field[0])++; - pn = *field[0] == 0; - switch(cmd) { - case 's': - n = strtol(field[pn], 0, 0); - if(n <= 0) - error(Ebadarg); - touch.rate = n; - break; - case 'r': - /* touch read delay */ - break; - case 'X': - case 'Y': - if(nf < pn+2) - error(Ebadarg); - m[0] = strtol(field[pn], 0, 0); - m[1] = strtol(field[pn+1], 0, 0); - m[2] = strtol(field[pn+2], 0, 0); - memmove(touch.m[cmd=='Y'], m, sizeof(touch.m[0])); - break; - case 'c': - case 'C': - case 'v': - case 't': - case 'e': - /* not used */ - /* break; */ - default: - error(Ebadarg); - } - break; - default: - error(Ebadarg); - return; - } -} - -static long -touchwrite(Chan* c, void* vp, long n, vlong) -{ - char buf[64]; - char *cp, *a; - int n0 = n; - int bn; - - a = vp; - while(n) { - bn = (cp = memchr(a, '\n', n))!=nil ? cp-a+1 : n; - n -= bn; - bn = bn > sizeof(buf)-1 ? sizeof(buf)-1 : bn; - memmove(buf, a, bn); - buf[bn] = '\0'; - a = cp; - dotouchwrite(c, buf); - } - return n0-n; -} - -Dev touchdevtab = { - 'T', - "touch", - - touchreset, - touchinit, - devshutdown, - touchattach, - touchwalk, - touchstat, - touchopen, - devcreate, - touchclose, - touchread, - devbread, - touchwrite, - devbwrite, - devremove, - devwstat, -}; diff --git a/os/mpc/devuart.c b/os/mpc/devuart.c deleted file mode 100644 index 13adf351..00000000 --- a/os/mpc/devuart.c +++ /dev/null @@ -1,1450 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "../port/netif.h" - -enum { - Nbuf= 2, /* double buffered */ - Rbufsize= 512, - Bufsize= (Rbufsize+CACHELINESZ-1)&~(CACHELINESZ-1), - Nuart= 2+4, /* max in any 8xx architecture (2xSMC, 4xSCC) */ - CTLS= 's'&037, - CTLQ= 'q'&037, -}; - -enum { - /* status bits in SCC receive buffer descriptors */ - RxBRK= 1<<7, /* break ended frame (async hdlc) */ - RxDE= 1<<7, /* DPLL error (hdlc) */ - RxBOF= 1<<6, /* BOF ended frame (async hdlc) */ - RxLG= 1<<5, /* frame too large (hdlc) */ - RxNO= 1<<4, /* bad bit alignment (hdlc) */ - RxBR= 1<<5, /* break received during frame (uart) */ - RxFR= 1<<4, /* framing error (uart) */ - RxPR= 1<<3, /* parity error (uart) */ - RxAB= 1<<3, /* frame aborted (hdlc, async hdlc) */ - RxCR= 1<<2, /* bad CRC (hdlc, async hdlc) */ - RxOV= 1<<1, /* receiver overrun (all) */ - RxCD= 1<<0, /* CD lost (all) */ - - /* hdlc-specific Rx/Tx BDs */ - TxTC= 1<<10, -}; - -/* - * SMC in UART mode - */ - -typedef struct Uartsmc Uartsmc; -struct Uartsmc { - IOCparam; - ushort maxidl; - ushort idlc; - ushort brkln; - ushort brkec; - ushort brkcr; - ushort rmask; -}; - -/* - * SCC2 UART parameters - */ -enum { - /* special mode bits */ - SccAHDLC = 1<<0, - SccHDLC = 1<<1, - SccIR = 1<<2, - SccPPP = 1<<3, -}; - -typedef struct Uartscc Uartscc; -struct Uartscc { - SCCparam; - uchar rsvd[8]; - ushort max_idl; - ushort idlc; - ushort brkcr; - ushort parec; - ushort frmec; - ushort nosec; - ushort brkec; - ushort brkln; - ushort uaddr1; - ushort uaddr2; - ushort rtemp; - ushort toseq; - ushort character[8]; - ushort rccm; - ushort rccrp; - ushort rlbc; -}; - -typedef struct UartAHDLC UartAHDLC; -struct UartAHDLC { - SCCparam; - ulong rsvd1; - ulong c_mask; - ulong c_pres; - ushort bof; - ushort eof; - ushort esc; - ushort rsvd2[2]; - ushort zero; - ushort rsvd3; - ushort rfthr; - ushort resvd4[2]; - ulong txctl_tbl; - ulong rxctl_tbl; - ushort nof; - ushort rsvd5; -}; - -typedef struct UartHDLC UartHDLC; -struct UartHDLC { - SCCparam; - ulong rsvd1; - ulong c_mask; - ulong c_pres; - ushort disfc; - ushort crcec; - ushort abtsc; - ushort nmarc; - ushort retrc; - ushort mflr; - ushort max_cnt; - ushort rfthr; - ushort rfcnt; - ushort hmask; - ushort haddr[4]; - ushort tmp; - ushort tmp_mb; -}; - -enum { - /* SCC events of possible interest here eventually */ - AB= 1<<9, /* autobaud detected */ - GRA= 1<<7, /* graceful stop completed */ - CCR= 1<<3, /* control character detected */ - - /* SCC, SMC common interrupt events */ - BSY= 1<<2, /* receive buffer was busy (overrun) */ - TXB= 1<<1, /* block sent */ - RXB= 1<<0, /* block received */ - - /* SCC events */ - TXE = 1<<4, /* transmission error */ - RXF = 1<<3, /* final block received */ - - /* gsmr_l */ - ENR = 1<<5, /* enable receiver */ - ENT = 1<<4, /* enable transmitter */ - - /* port A */ - RXD1= SIBIT(15), - TXD1= SIBIT(14), - - /* port B */ - RTS1B= IBIT(19), - - /* port C */ - RTS1C= SIBIT(15), - CTS1= SIBIT(11), - CD1= SIBIT(10), -}; - -typedef struct Uart Uart; -struct Uart -{ - QLock; - - Uart *elist; /* next enabled interface */ - char name[KNAMELEN]; - - int x; /* index: x in SMCx or SCCx */ - int cpmid; /* eg, SCC1ID, SMC1ID */ - CPMdev* cpm; - int opens; - uchar bpc; /* bits/char */ - uchar parity; - uchar stopb; - uchar setup; - uchar enabled; - int dev; - - ulong frame; /* framing errors */ - ulong perror; - ulong overrun; /* rcvr overruns */ - ulong crcerr; - ulong interrupts; - int baud; /* baud rate */ - - /* flow control */ - int xonoff; /* software flow control on */ - int blocked; - int modem; /* hardware flow control on */ - int cts; /* ... cts state */ - int rts; /* ... rts state */ - Rendez r; - - /* buffers */ - int (*putc)(Queue*, int); - Queue *iq; - Queue *oq; - - /* staging areas to avoid some of the per character costs */ - /* TO DO: should probably use usual Ring */ - Block* istage[Nbuf]; /* double buffered */ - int rdrx; /* last buffer read */ - - Lock plock; /* for output variables */ - Block* outb; /* currently transmitting Block */ - - BD* rxb; - BD* txb; - - SMC* smc; - SCC* scc; - IOCparam* param; - ushort* brkcr; /* brkcr location in appropriate block */ - int brgc; - int mode; - Block* partial; - int loopback; -}; - -static Uart *uart[Nuart]; -static int nuart; - -struct Uartalloc { - Lock; - Uart *elist; /* list of enabled interfaces */ -} uartalloc; - -static void uartintr(Uart*, int); -static void smcuintr(Ureg*, void*); -static void sccuintr(Ureg*, void*); - -static void -uartsetbuf(Uart *up) -{ - IOCparam *p; - BD *bd; - int i; - Block *bp; - - p = up->param; - p->rfcr = 0x18; - p->tfcr = 0x18; - p->mrblr = Rbufsize; - - if((bd = up->rxb) == nil){ - bd = bdalloc(Nbuf); - up->rxb = bd; - } - p->rbase = (ushort)bd; - for(i=0; i<Nbuf; i++){ - bd->status = BDEmpty|BDInt; - bd->length = 0; - if((bp = up->istage[i]) == nil) - up->istage[i] = bp = allocb(Bufsize); - bd->addr = PADDR(bp->wp); - dcflush(bp->wp, Bufsize); - bd++; - } - (bd-1)->status |= BDWrap; - up->rdrx = 0; - - if((bd = up->txb) == nil){ - bd = bdalloc(1); - up->txb = bd; - } - p->tbase = (ushort)bd; - bd->status = BDWrap|BDInt; - bd->length = 0; - bd->addr = 0; -} - -static void -smcsetup(Uart *up) -{ - IMM *io; - Uartsmc *p; - SMC *smc; - ulong txrx; - - archdisableuart(up->cpmid); - up->brgc = brgalloc(); - if(up->brgc < 0) - error(Eio); - m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; - smcnmsi(up->x, up->brgc); - - archenableuart(up->cpmid, 0); - - if(up->x == 1) - txrx = IBIT(24)|IBIT(25); /* SMC1 RX/TX */ - else - txrx = IBIT(20)|IBIT(21); /* SMC2 */ - io = ioplock(); - io->pbpar |= txrx; - io->pbdir &= ~txrx; - iopunlock(); - - up->param = up->cpm->param; - uartsetbuf(up); - - cpmop(up->cpm, InitRxTx, 0); - - /* SMC protocol parameters */ - p = (Uartsmc*)up->param; - up->brkcr = &p->brkcr; - p->maxidl = 1; /* non-zero so buffer closes when idle before mrblr reached */ - p->brkln = 0; - p->brkec = 0; - p->brkcr = 1; - smc = up->cpm->regs; - smc->smce = 0xff; /* clear events */ - smc->smcm = BSY|RXB|TXB; /* enable all possible interrupts */ - up->smc = smc; - smc->smcmr = ((1+8+1-1)<<11)|(2<<4); /* 8-bit, 1 stop, no parity; UART mode */ - intrenable(VectorCPIC+up->cpm->irq, smcuintr, up, BUSUNKNOWN, up->name); - /* enable when device opened */ -} - -static void -smcuintr(Ureg*, void *a) -{ - Uart *up; - int events; - - up = a; - events = up->smc->smce; - eieio(); - up->smc->smce = events; - uartintr(up, events&(BSY|RXB|TXB)); -} - -/* - * set the IO ports to enable the control signals for SCCx - */ -static void -sccuartpins(int x, int mode) -{ - IMM *io; - int i, w; - - x--; - io = ioplock(); - i = 2*x; - w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ - io->papar |= w; /* enable TXDn and RXDn pins */ - io->padir &= ~w; - if((mode & SccIR) == 0) - io->paodr |= TXD1<<i; - else - io->paodr &= ~w; /* not open drain */ - - w = (CD1|CTS1)<<i; /* CDn and CTSn in port C */ - io->pcpar &= ~w; - io->pcdir &= ~w; - if(conf.nocts2 || mode) - io->pcso &= ~w; /* force CTS and CD on */ - else - io->pcso |= w; - - w = RTS1B<<x; - io->pbpar &= ~w; - io->pbdir &= ~w; - - w = RTS1C<<x; /* RTSn~ */ - if((mode & SccIR) == 0) - io->pcpar |= w; - else - io->pcpar &= ~w; /* don't use for IR */ - iopunlock(); -} - -static void -sccsetup(Uart *up) -{ - SCC *scc; - int i; - - scc = up->cpm->regs; - up->scc = scc; - up->param = up->cpm->param; - sccxstop(up->cpm); - archdisableuart(up->cpmid); - if(up->brgc < 0){ - up->brgc = brgalloc(); - if(up->brgc < 0) - error(Eio); - } - m->iomem->brgc[up->brgc] = baudgen(up->baud, 16) | BaudEnable; - sccnmsi(up->x, up->brgc, up->brgc); - sccuartpins(up->x, up->mode); - - uartsetbuf(up); - - cpmop(up->cpm, InitRxTx, 0); - - /* SCC protocol parameters */ - if((up->mode & (SccAHDLC|SccHDLC)) == 0){ - Uartscc *sp; - sp = (Uartscc*)up->param; - sp->max_idl = 1; - sp->brkcr = 1; - sp->parec = 0; - sp->frmec = 0; - sp->nosec = 0; - sp->brkec = 0; - sp->brkln = 0; - sp->brkec = 0; - sp->uaddr1 = 0; - sp->uaddr2 = 0; - sp->toseq = 0; - for(i=0; i<8; i++) - sp->character[i] = 0x8000; - sp->rccm = 0xC0FF; - up->brkcr = &sp->brkcr; - scc->irmode = 0; - scc->dsr = ~0; - scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ - scc->gsmrl = 0x28004; /* UART mode */ - }else{ - UartAHDLC *hp; - hp = (UartAHDLC*)up->param; - hp->c_mask = 0x0000F0B8; - hp->c_pres = 0x0000FFFF; - if(up->mode & SccIR){ - hp->bof = 0xC0; - hp->eof = 0xC1; - //scc->dsr = 0xC0C0; - scc->dsr = 0x7E7E; - }else{ - hp->bof = 0x7E; - hp->eof = 0x7E; - scc->dsr = 0x7E7E; - } - hp->esc = 0x7D; - hp->zero = 0; - if(up->mode & SccHDLC) - hp->rfthr = 1; - else - hp->rfthr = 0; /* receive threshold of 1 doesn't work properly for Async HDLC */ - hp->txctl_tbl = 0; - hp->rxctl_tbl = 0; - if(up->mode & SccIR){ - /* low-speed infrared */ - hp->nof = 12-1; /* 12 flags */ - scc->irsip = 0; - scc->irmode = (2<<8) | 1; - archsetirxcvr(0); - if(up->loopback) - scc->irmode = (3<<4)|1; /* loopback */ - }else{ - scc->irmode = 0; - hp->txctl_tbl = ~0; - hp->rxctl_tbl = ~0; - hp->nof = 1-1; /* one opening flag */ - } - up->brkcr = nil; - scc->gsmrh = 1<<5; /* 8-bit oriented receive fifo */ - if(up->mode & SccHDLC) - scc->gsmrl = 0x28000; /* HDLC */ - else - scc->gsmrl = 0x28006; /* async HDLC/IrDA */ - } - archenableuart(up->cpmid, (up->mode&SccIR)!=0); - scc->scce = ~0; /* clear events */ - scc->sccm = TXE|BSY|RXF|TXB|RXB; /* enable all interesting interrupts */ - intrenable(VectorCPIC+up->cpm->irq, sccuintr, up, BUSUNKNOWN, up->name); - scc->psmr = 3<<12; /* 8-bit, 1 stop, no parity; UART mode */ - if(up->loopback && (up->mode & SccIR) == 0) - scc->gsmrl |= 1<<6; /* internal loop back */ - scc->gsmrl |= ENT|ENR; /* enable rx/tx */ - if(0){ - print("gsmrl=%8.8lux gsmrh=%8.8lux dsr=%4.4ux irmode=%4.4ux\n", scc->gsmrl, scc->gsmrh, scc->dsr, scc->irmode); - for(i=0; i<sizeof(Uartscc); i+=4) - print("%2.2ux %8.8lux\n", i, *(ulong*)((uchar*)up->param+i)); - } -} - -static void -sccuintr(Ureg*, void *a) -{ - Uart *up; - int events; - - up = a; - if(up->scc == nil) - return; - events = up->scc->scce; - eieio(); - up->scc->scce = events; - if(up->enabled){ - if(0) - print("#%ux|", events); - uartintr(up, events); - } -} - -static void -uartsetbaud(Uart *p, int rate) -{ - if(rate <= 0 || p->brgc < 0) - return; - p->baud = rate; - m->iomem->brgc[p->brgc] = baudgen(rate, 16) | BaudEnable; -} - -static void -uartsetmode(Uart *p) -{ - int r, clen; - - ilock(&p->plock); - clen = p->bpc; - if(p->parity == 'e' || p->parity == 'o') - clen++; - clen++; /* stop bit */ - if(p->stopb == 2) - clen++; - if(p->smc){ - r = p->smc->smcmr & 0x3F; /* keep mode, enable bits */ - r |= (clen<<11); - if(p->parity == 'e') - r |= 3<<8; - else if(p->parity == 'o') - r |= 2<<8; - if(p->stopb == 2) - r |= 1<<10; - eieio(); - p->smc->smcmr = r; - }else if(p->scc && p->mode == 0){ - r = p->scc->psmr & 0x8FE0; /* keep mode bits */ - r |= ((p->bpc-5)&3)<<12; - if(p->parity == 'e') - r |= (6<<2)|2; - else if(p->parity == 'o') - r |= (4<<2)|0; - if(p->stopb == 2) - r |= 1<<14; - eieio(); - p->scc->psmr = r; - } - iunlock(&p->plock); -} - -static void -uartparity(Uart *p, char type) -{ - ilock(&p->plock); - p->parity = type; - iunlock(&p->plock); - uartsetmode(p); -} - -/* - * set bits/character - */ -static void -uartbits(Uart *p, int bits) -{ - if(bits < 5 || bits > 14 || bits > 8 && p->scc) - error(Ebadarg); - - ilock(&p->plock); - p->bpc = bits; - iunlock(&p->plock); - uartsetmode(p); -} - - -/* - * toggle DTR - */ -static void -uartdtr(Uart *p, int n) -{ - if(p->scc == nil) - return; /* not possible */ - USED(n); /* not possible on FADS */ -} - -/* - * toggle RTS - */ -static void -uartrts(Uart *p, int n) -{ - p->rts = n; - if(p->scc == nil) - return; /* not possible */ - USED(n); /* not possible on FADS */ -} - -/* - * send break - */ -static void -uartbreak(Uart *p, int ms) -{ - if(p->brkcr == nil) - return; - - if(ms <= 0) - ms = 200; - - if(waserror()){ - ilock(&p->plock); - *p->brkcr = 1; - cpmop(p->cpm, RestartTx, 0); - iunlock(&p->plock); - nexterror(); - } - ilock(&p->plock); - *p->brkcr = ((p->baud/(p->bpc+2))*ms+500)/1000; - cpmop(p->cpm, StopTx, 0); - iunlock(&p->plock); - - tsleep(&up->sleep, return0, 0, ms); - - poperror(); - ilock(&p->plock); - *p->brkcr = 1; - cpmop(p->cpm, RestartTx, 0); - iunlock(&p->plock); -} - -/* - * modem flow control on/off (rts/cts) - */ -static void -uartmflow(Uart *p, int n) -{ - if(p->scc == nil) - return; /* not possible */ - if(n){ - p->modem = 1; - /* enable status interrupts ... */ - p->scc->psmr |= 1<<15; /* enable async flow control */ - p->cts = 1; - /* could change maxidl */ - }else{ - p->modem = 0; - /* stop status interrupts ... */ - p->scc->psmr &= ~(1<<15); - p->cts = 1; - } -} - -/* - * turn on a port's interrupts. set DTR and RTS - */ -void -uartenable(Uart *p) -{ - Uart **l; - - if(p->enabled) - return; - - if(p->setup == 0){ - if(p->cpmid == CPsmc1 || p->cpmid == CPsmc2) - smcsetup(p); - else - sccsetup(p); - p->setup = 1; - } - - /* - * turn on interrupts - */ - if(p->smc){ - cpmop(p->cpm, RestartTx, 0); - p->smc->smcmr |= 3; - p->smc->smcm = BSY|TXB|RXB; - eieio(); - }else if(p->scc){ - cpmop(p->cpm, RestartTx, 0); - p->scc->gsmrl |= ENT|ENR; - p->scc->sccm = BSY|TXB|RXB; - eieio(); - } - - /* - * turn on DTR and RTS - */ - uartdtr(p, 1); - uartrts(p, 1); - - /* - * assume we can send - */ - p->cts = 1; - p->blocked = 0; - - /* - * set baud rate to the last used - */ - uartsetbaud(p, p->baud); - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p) - break; - } - if(*l == 0){ - p->elist = uartalloc.elist; - uartalloc.elist = p; - } - p->enabled = 1; - unlock(&uartalloc); - p->cts = 1; - p->blocked = 0; - p->xonoff = 0; - p->enabled = 1; -} - -/* - * turn off a port's interrupts. reset DTR and RTS - */ -void -uartdisable(Uart *p) -{ - Uart **l; - - /* - * turn off interrpts - */ - if(p->smc) - smcxstop(p->cpm); - else if(p->scc) - sccxstop(p->cpm); - - /* - * revert to default settings - */ - p->bpc = 8; - p->parity = 0; - p->stopb = 0; - - /* - * turn off DTR, RTS, hardware flow control & fifo's - */ - uartdtr(p, 0); - uartrts(p, 0); - uartmflow(p, 0); - p->xonoff = p->blocked = 0; - - lock(&uartalloc); - for(l = &uartalloc.elist; *l; l = &(*l)->elist){ - if(*l == p){ - *l = p->elist; - break; - } - } - p->enabled = 0; - unlock(&uartalloc); -} - -/* - * set the next output buffer going - */ -static void -txstart(Uart *p) -{ - Block *b; - int n, flags; - - if(!p->cts || p->blocked || p->txb->status & BDReady) - return; - if((b = p->outb) == nil){ - if((b = qget(p->oq)) == nil) - return; - if(p->mode & SccPPP && - p->mode & SccAHDLC && - BLEN(b) >= 8){ /* strip framing data */ - UartAHDLC *hp; - hp = (UartAHDLC*)p->param; - if(hp != nil && (p->mode & SccIR) == 0){ - hp->txctl_tbl = nhgetl(b->rp); - hp->rxctl_tbl = nhgetl(b->rp+4); - } - b->rp += 8; - if(0) - print("tx #%lux rx #%lux\n", hp->txctl_tbl, hp->rxctl_tbl); - } - } - n = BLEN(b); - if(n <= 0) - print("txstart: 0\n"); - if(p->bpc > 8){ - /* half-word alignment and length if chars are long */ - if(PADDR(b->rp)&1){ /* must be even if chars are long */ - memmove(b->base, b->rp, n); - b->rp = b->base; - b->wp = b->rp+n; - } - if(n & 1) - n++; - } - dcflush(b->rp, n); - p->outb = b; - if(n > 0xFFFF) - n = 0xFFFE; - if(p->mode & SccHDLC) - flags = BDLast | TxTC; - else if(p->mode) - flags = BDLast; - else - flags = 0; - p->txb->addr = PADDR(b->rp); - p->txb->length = n; - eieio(); - p->txb->status = (p->txb->status & BDWrap) | flags | BDReady|BDInt; - eieio(); -} - -/* - * (re)start output - */ -static void -uartkick(void *v) -{ - Uart *p; - - p = v; - ilock(&p->plock); - if(p->outb == nil) - txstart(p); - iunlock(&p->plock); -} - -/* - * restart input if it's off - */ -static void -uartflow(void *v) -{ - Uart *p; - - p = v; - if(p->modem) - uartrts(p, 1); -} - -static void -uartsetup(int x, int lid, char *name) -{ - Uart *p; - - if(nuart >= Nuart) - return; - - p = xalloc(sizeof(Uart)); - uart[nuart] = p; - strcpy(p->name, name); - p->dev = nuart; - nuart++; - p->x = x; - p->cpmid = lid; - p->cpm = cpmdev(lid); - p->brgc = -1; - p->mode = 0; - - /* - * set rate to 9600 baud. - * 8 bits/character. - * 1 stop bit. - * interrupts enabled. - */ - p->bpc = 8; - p->parity = 0; - p->baud = 9600; - - p->iq = qopen(4*1024, Qcoalesce, uartflow, p); - p->oq = qopen(4*1024, 0, uartkick, p); -} - -/* - * called by main() to configure a duart port as a console or a mouse - */ -void -uartspecial(int port, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int)) -{ - Uart *p; - - if(port < 0 || port >= nuart || (p = uart[port]) == nil) - return; /* specified port not implemented */ - uartenable(p); - if(baud) - uartsetbaud(p, baud); - p->putc = putc; - if(in) - *in = p->iq; - if(out) - *out = p->oq; - p->opens++; -} - -static int -uartinput(Uart *p, BD *bd) -{ - int ch, dokick, i, l; - uchar *bp; - - dokick = 0; - if(bd->status & RxFR) - p->frame++; - if(bd->status & RxOV) - p->overrun++; - l = bd->length; - if(bd->status & RxPR){ - p->perror++; - l--; /* it's the last character */ - } - bp = KADDR(bd->addr); - if(p->xonoff || p->putc && p->opens==1){ - for(i=0; i<l; i++){ - ch = bp[i]; - if(p->xonoff){ - if(ch == CTLS){ - p->blocked = 1; - cpmop(p->cpm, StopTx, 0); - }else if (ch == CTLQ){ - p->blocked = 0; - dokick = 1; - } - /* BUG? should discard on/off char? */ - } - if(p->putc) - (*p->putc)(p->iq, ch); - } - } - if(l > 0 && (p->putc == nil || p->opens>1)) - qproduce(p->iq, bp, l); - return dokick; -} - -static void -framedinput(Uart *p, BD *bd) -{ - Block *pkt; - int l; - - pkt = p->partial; - p->partial = nil; - if(bd->status & RxOV){ - p->overrun++; - goto Discard; - } - if(bd->status & (RxAB|RxCR|RxCD|RxLG|RxNO|RxDE|RxBOF|RxBRK)){ - if(bd->status & RxCR) - p->crcerr++; - else - p->frame++; - goto Discard; - } - if(pkt == nil){ - pkt = iallocb(1500); /* TO DO: allocate less if possible */ - if(pkt == nil) - return; - } - l = bd->length; - if(bd->status & BDLast) - l -= BLEN(pkt); /* last one gives size of entire frame */ - if(l > 0){ - if(pkt->wp+l > pkt->lim) - goto Discard; - memmove(pkt->wp, KADDR(bd->addr), l); - pkt->wp += l; - } - if(0) - print("#%ux|", bd->status); - if(bd->status & BDLast){ - if(p->mode & (SccHDLC|SccAHDLC)){ - if(BLEN(pkt) <= 2){ - p->frame++; - goto Discard; - } - pkt->wp -= 2; /* strip CRC */ - } - qpass(p->iq, pkt); - }else - p->partial = pkt; - return; - -Discard: - if(pkt != nil) - freeb(pkt); -} - -/* - * handle an interrupt to a single uart - */ -static void -uartintr(Uart *p, int events) -{ - int dokick; - BD *bd; - Block *b; - - if(events & BSY) - p->overrun++; - p->interrupts++; - dokick = 0; - while(p->rxb != nil && ((bd = &p->rxb[p->rdrx])->status & BDEmpty) == 0){ - dcinval(KADDR(bd->addr), bd->length); - if(p->mode) - framedinput(p, bd); - else if(uartinput(p, bd)) - dokick = 1; - bd->status = (bd->status & BDWrap) | BDEmpty|BDInt; - eieio(); - if(++p->rdrx >= Nbuf) - p->rdrx = 0; - } - if((bd = p->txb) != nil){ - if((bd->status & BDReady) == 0){ - ilock(&p->plock); - if((b = p->outb) != nil){ - b->rp += bd->length; - if(b->rp >= b->wp){ - p->outb = nil; - freeb(b); - } - } - txstart(p); - iunlock(&p->plock); - } - } - eieio(); - /* TO DO: modem status isn't available on 82xFADS */ - if(dokick && p->cts && !p->blocked){ - if(p->outb == nil){ - ilock(&p->plock); - txstart(p); - iunlock(&p->plock); - } - cpmop(p->cpm, RestartTx, 0); - } else if (events & TXE) - cpmop(p->cpm, RestartTx, 0); -} - -/* - * used to ensure uart console output when debugging - */ -void -uartwait(void) -{ - Uart *p = uart[0]; - int s; - - while(p && (p->outb||qlen(p->oq))){ - if(islo()) - continue; - s = splhi(); - if((p->txb->status & BDReady) == 0){ - p->blocked = 0; - p->cts = 1; - if(p->scc == nil) - smcuintr(nil, p); - else - sccuintr(nil, p); - } - splx(s); - } -} - -static Dirtab *uartdir; -static int ndir; - -static void -setlength(int i) -{ - Uart *p; - - if(i >= 0){ - p = uart[i]; - if(p && p->opens && p->iq) - uartdir[1+4*i].length = qlen(p->iq); - } else for(i = 0; i < nuart; i++){ - p = uart[i]; - if(p && p->opens && p->iq) - uartdir[1+4*i].length = qlen(p->iq); - } - -} - -void -uartinstall(void) -{ - static int already; - int i, n; - char name[2*KNAMELEN]; - if(already) - return; - already = 1; - n = 0; - for(i=0; i<2; i++) - if(conf.smcuarts & (1<<i)){ - snprint(name, sizeof(name), "eia%d", n++); - uartsetup(i+1, CPsmc1+i, name); - } - n = 2; - for(i=0; i<conf.nscc; i++) - if(conf.sccuarts & (1<<i)){ - snprint(name, sizeof(name), "eia%d", n++); - uartsetup(i+1, CPscc1+i, name); - } -} - -/* - * all uarts must be uartsetup() by this point or inside of uartinstall() - */ -static void -uartreset(void) -{ - int i; - Dirtab *dp; - - uartinstall(); /* architecture specific */ - - ndir = 1+4*nuart; - uartdir = xalloc(ndir * sizeof(Dirtab)); - dp = uartdir; - strcpy(dp->name, "."); - mkqid(&dp->qid, 0, 0, QTDIR); - dp->length = 0; - dp->perm = DMDIR|0555; - dp++; - for(i = 0; i < nuart; i++){ - /* 4 directory entries per port */ - strcpy(dp->name, uart[i]->name); - dp->qid.path = NETQID(i, Ndataqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sctl", uart[i]->name); - dp->qid.path = NETQID(i, Nctlqid); - dp->perm = 0660; - dp++; - sprint(dp->name, "%sstatus", uart[i]->name); - dp->qid.path = NETQID(i, Nstatqid); - dp->perm = 0444; - dp++; - sprint(dp->name, "%smode", uart[i]->name); - dp->qid.path = NETQID(i, Ntypeqid); - dp->perm = 0660; - dp++; - } -} - -static Chan* -uartattach(char *spec) -{ - return devattach('t', spec); -} - -static Walkqid* -uartwalk(Chan *c, Chan *nc, char **name, int nname) -{ - return devwalk(c, nc, name, nname, uartdir, ndir, devgen); -} - -static int -uartstat(Chan *c, uchar *dp, int n) -{ - if(NETTYPE(c->qid.path) == Ndataqid) - setlength(NETID(c->qid.path)); - return devstat(c, dp, n, uartdir, ndir, devgen); -} - -static Chan* -uartopen(Chan *c, int omode) -{ - Uart *p; - - c = devopen(c, omode, uartdir, ndir, devgen); - - switch(NETTYPE(c->qid.path)){ - case Nctlqid: - case Ndataqid: - p = uart[NETID(c->qid.path)]; - qlock(p); - if(p->opens++ == 0){ - uartenable(p); - qreopen(p->iq); - qreopen(p->oq); - } - qunlock(p); - break; - } - - return c; -} - -static void -uartclose(Chan *c) -{ - Uart *p; - - if(c->qid.type & QTDIR) - return; - if((c->flag & COPEN) == 0) - return; - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - case Nctlqid: - p = uart[NETID(c->qid.path)]; - qlock(p); - if(--(p->opens) == 0){ - uartdisable(p); - qclose(p->iq); - qclose(p->oq); - } - qunlock(p); - break; - } -} - -static long -uartstatus(Chan*, Uart *p, void *buf, long n, long offset) -{ - IMM *io; - char str[256]; - -// TO DO: change to standard format for first line: -//"b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n" - sprint(str, "opens %d ferr %lud oerr %lud crcerr %lud baud %ud perr %lud intr %lud", p->opens, - p->frame, p->overrun, p->crcerr, p->baud, p->perror, p->interrupts); - /* TO DO: cts, dsr, ring, dcd, dtr, rts aren't all available on 82xFADS */ - io = m->iomem; - if(p->scc){ - if((io->pcdat & SIBIT(9)) == 0) - strcat(str, " cts"); - if((io->pcdat & SIBIT(8)) == 0) - strcat(str, " dcd"); - if((io->pbdat & IBIT(22)) == 0) - strcat(str, " dtr"); - }else if(p->smc){ - if((io->pbdat & IBIT(23)) == 0) - strcat(str, " dtr"); - } - strcat(str, "\n"); - return readstr(offset, buf, n, str); -} - -static long -uartread(Chan *c, void *buf, long n, vlong offset) -{ - Uart *p; - - if(c->qid.type & QTDIR){ - setlength(-1); - return devdirread(c, buf, n, uartdir, ndir, devgen); - } - - p = uart[NETID(c->qid.path)]; - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qread(p->iq, buf, n); - case Nctlqid: - return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); - case Nstatqid: - return uartstatus(c, p, buf, n, offset); - case Ntypeqid: - return readnum(offset, buf, n, p->mode, NUMSIZE); - } - - return 0; -} - -static Block* -uartbread(Chan *c, long n, ulong offset) -{ - if(c->qid.type & QTDIR || NETTYPE(c->qid.path) != Ndataqid) - return devbread(c, n, offset); - return qbread(uart[NETID(c->qid.path)]->iq, n); -} - -static void -uartctl(Uart *p, char *cmd) -{ - int i, n; - - /* let output drain for a while */ - for(i = 0; i < 16 && qlen(p->oq); i++) - tsleep(&p->r, (int(*)(void*))qlen, p->oq, 125); - - if(strncmp(cmd, "break", 5) == 0){ - uartbreak(p, 0); - return; - } - - n = atoi(cmd+1); - switch(*cmd){ - case 'B': - case 'b': - uartsetbaud(p, n); - break; - case 'D': - case 'd': - uartdtr(p, n); - break; - case 'f': - case 'F': - qflush(p->oq); - break; - case 'H': - case 'h': - qhangup(p->iq, 0); - qhangup(p->oq, 0); - break; - case 'L': - case 'l': - uartbits(p, n); - break; - case 'm': - case 'M': - uartmflow(p, n); - break; - case 'n': - case 'N': - qnoblock(p->oq, n); - break; - case 'P': - case 'p': - uartparity(p, *(cmd+1)); - break; - case 'K': - case 'k': - uartbreak(p, n); - break; - case 'R': - case 'r': - uartrts(p, n); - break; - case 'Q': - case 'q': - qsetlimit(p->iq, n); - qsetlimit(p->oq, n); - break; - case 'W': - case 'w': - /* obsolete */ - break; - case 'X': - case 'x': - p->xonoff = n; - break; - case 'Z': - case 'z': - p->loopback = n; - break; - } -} - -static long -uartwrite(Chan *c, void *buf, long n, vlong offset) -{ - Uart *p; - char cmd[32]; - int m, inuse; - - USED(offset); - - if(c->qid.type & QTDIR) - error(Eperm); - - p = uart[NETID(c->qid.path)]; - - switch(NETTYPE(c->qid.path)){ - case Ndataqid: - return qwrite(p->oq, buf, n); - case Nctlqid: - if(n >= sizeof(cmd)) - n = sizeof(cmd)-1; - memmove(cmd, buf, n); - cmd[n] = 0; - uartctl(p, cmd); - return n; - case Ntypeqid: - if(p->smc || p->putc) - error(Ebadarg); - if(n >= sizeof(cmd)) - n = sizeof(cmd)-1; - memmove(cmd, buf, n); - cmd[n] = 0; - m = strtoul(cmd, nil, 0); - inuse = 0; - qlock(p); - if(p->opens == 0){ - p->mode = m & 0x7F; - p->loopback = (m&0x80)!=0; - p->setup = 0; - }else - inuse = 1; - qunlock(p); - if(inuse) - error(Einuse); - return n; - } -} - -static long -uartbwrite(Chan *c, Block *bp, ulong offset) -{ - if(c->qid.type & QTDIR || NETTYPE(c->qid.path) != Ndataqid) - return devbwrite(c, bp, offset); - return qbwrite(uart[NETID(c->qid.path)]->oq, bp); -} - -static int -uartwstat(Chan *c, uchar *dp, int n) -{ - Dir d; - Dirtab *dt; - - if(!iseve()) - error(Eperm); - if(c->qid.type & QTDIR) - error(Eperm); - if(NETTYPE(c->qid.path) == Nstatqid) - error(Eperm); - - dt = &uartdir[1+4 * NETID(c->qid.path)]; - n = convM2D(dp, n, &d, nil); - if(d.mode != ~0UL){ - d.mode &= 0666; - dt[0].perm = dt[1].perm = d.mode; - } - return n; -} - -Dev uartdevtab = { - 't', - "uart", - - uartreset, - devinit, - devshutdown, - uartattach, - uartwalk, - uartstat, - uartopen, - devcreate, - uartclose, - uartread, - uartbread, - uartwrite, - uartbwrite, - devremove, - uartwstat, -}; diff --git a/os/mpc/dsp.c b/os/mpc/dsp.c deleted file mode 100644 index ffe906e9..00000000 --- a/os/mpc/dsp.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * DSP support functions - */ - -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#include "io.h" - -#include "dsp.h" - -enum { - Ndsp = 2, /* determined by hardware */ - - NHOLES= 64 -}; - -typedef struct DSPparam DSPparam; -struct DSPparam { - ulong fdbase; /* function descriptor table physical base address */ - ulong fd_ptr; /* function descriptor pointer */ - ulong dstate; /* DSP state */ - ulong resvd[2]; - ushort dstatus; /* current function descriptor status */ - ushort i; /* number of iterations */ - ushort tap; /* number of TAPs */ - ushort cbase; - ushort anon1; /* sample buffer size-1 */ - ushort xptr; /* pointer to sample */ - ushort anon2; /* output buffer size-1 */ - ushort yptr; /* pointer to output */ - ushort m; /* sample buffer size-1 */ - ushort anon3; /* sample buffer pointer */ - ushort n; /* output buffer size -1 */ - ushort anon4; /* output buffer pointer */ - ushort k; /* coefficient buffer size - 1 */ - ushort anon5; /* coefficient buffer pointer */ -}; - -struct DSP { - Lock; /* protects state */ - void (*done)(void*); - void* arg; - DSPparam* par; - CPMdev* cpm; - - QLock; /* protects busyr */ - int busy; - Rendez busyr; -}; - -static DSP dsps[Ndsp]; -static Lock dsplock; -static int dspinit; -static struct { - QLock; - ulong avail; - Rendez wantr; -} dspalloc; - -static Map fndmapv[NHOLES]; -static RMap fndmap = {"DSP function descriptors"}; - -static void -dspinterrupt(Ureg*, void*) -{ - int i; - ushort events; - DSP *dsp; - - events = m->iomem->sdsr; - m->iomem->sdsr = events; - if(events & (1<<7)) - panic("dsp: SDMA channel bus error sdar=#%lux", m->iomem->sdar); - for(i=0; i<Ndsp; i++) - if(events & (1<<i)){ - dsp = &dsps[i]; - if(dsp->busy){ - dsp->busy = 0; - if(dsp->done) - dsp->done(dsp->arg); - else - wakeup(&dsp->busyr); - }else - print("dsp%d: empty interrupt\n", i); - } -} - -/* - * called by system initialisation to set up the DSPs - */ -void -dspinitialise(void) -{ - CPMdev *d; - - ilock(&dsplock); - if(dspinit == 0){ - mapinit(&fndmap, fndmapv, sizeof(fndmapv)); - d = cpmdev(CPdsp1); - dsps[0].cpm = d; - dsps[0].par = d->param; - d = cpmdev(CPdsp2); - dsps[1].cpm = d; - dsps[1].par = d->param; - intrenable(VectorCPIC+d->irq, dspinterrupt, nil, BUSUNKNOWN, "dsp"); - dspalloc.avail = (1<<Ndsp)-1; - dspinit = 1; - } - iunlock(&dsplock); -} - -static int -dspavail(void*) -{ - return dspalloc.avail != 0; -} - -/* - * wait for a DSP to become available, and return a reference to it. - * if done is not nil, it will be called (with the given arg) when that - * DSP completes each function (if set to interrupt). - */ -DSP* -dspacquire(void (*done)(void*), void *arg) -{ - DSP *dsp; - int i; - - if(dspinit == 0) - dspinitialise(); - qlock(&dspalloc); - if(waserror()){ - qunlock(&dspalloc); - nexterror(); - } - for(i=0;; i++){ - if(i >= Ndsp){ - sleep(&dspalloc.wantr, dspavail, nil); - i = 0; - } - if(dspalloc.avail & (1<<i)) - break; - } - dsp = &dsps[i]; - if(dsp->busy) - panic("dspacquire"); - dsp->done = done; - dsp->arg = arg; - poperror(); - qunlock(&dspalloc); - return dsp; -} - -/* - * relinquish access to the given DSP - */ -void -dsprelease(DSP *dsp) -{ - ulong bit; - - if(dsp == nil) - return; - bit = 1 << (dsp-dsps); - if(dspalloc.avail & bit) - panic("dsprelease"); - dspalloc.avail |= bit; - wakeup(&dspalloc.wantr); -} - -/* - * execute f[0] to f[n-1] on the given DSP - */ -void -dspexec(DSP *dsp, FnD *f, ulong n) -{ - dspsetfn(dsp, f, n); - dspstart(dsp); -} - -/* - * set the DSP to execute f[0] to f[n-1] - */ -void -dspsetfn(DSP *dsp, FnD *f, ulong n) -{ - f[n-1].status |= FnWrap; - ilock(dsp); - dsp->par->fdbase = PADDR(f); - iunlock(dsp); - cpmop(dsp->cpm, InitDSP, 0); -} - -/* - * start execution of the preset function(s) - */ -void -dspstart(DSP *dsp) -{ - ilock(dsp); - dsp->busy = 1; - iunlock(dsp); - cpmop(dsp->cpm, StartDSP, 0); -} - -static int -dspdone(void *a) -{ - return ((DSP*)a)->busy; -} - -/* - * wait until the DSP has completed execution - */ -void -dspsleep(DSP *dsp) -{ - sleep(&dsp->busyr, dspdone, dsp); -} - -/* - * allocate n function descriptors - */ -FnD* -fndalloc(ulong n) -{ - ulong a, nb, pgn; - FnD *f; - - if(n == 0) - return nil; - if(dspinit == 0) - dspinitialise(); - nb = n*sizeof(FnD); - while((a = rmapalloc(&fndmap, 0, nb, sizeof(FnD))) != 0){ - /* expected to loop just once, but might lose a race with another dsp user */ - pgn = (nb+BY2PG-1)&~(BY2PG-1); - a = PADDR(xspanalloc(pgn, sizeof(FnD), 0)); - if(a == 0) - return nil; - mapfree(&fndmap, a, pgn); - } - f = KADDR(a); - f[n-1].status = FnWrap; - return f; -} - -/* - * free n function descriptors - */ -void -fndfree(FnD *f, ulong n) -{ - if(f != nil) - mapfree(&fndmap, PADDR(f), n*sizeof(FnD)); -} - -/* - * allocate an IO buffer region in shared memory for use by the DSP - */ -void* -dspmalloc(ulong n) -{ - ulong i; - - n = (n+3)&~4; - i = n; - if(n & (n-1)){ - /* align on a power of two */ - for(i=1; i < n; i <<= 1) - ; - } - return cpmalloc(n, i); /* this seems to be what 16.3.3.2 is trying to say */ -} - -/* - * free DSP buffer memory - */ -void -dspfree(void *p, ulong n) -{ - if(p != nil) - cpmfree(p, (n+3)&~4); -} diff --git a/os/mpc/dsp.h b/os/mpc/dsp.h deleted file mode 100644 index 9838757f..00000000 --- a/os/mpc/dsp.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * MPC82x/QUICC DSP support - */ - -typedef struct DSP DSP; -typedef struct FnD FnD; - -typedef short Real; -typedef struct Complex Complex; - -struct Complex { - Real im; - Real re; -}; - -struct FnD { - ushort status; - ushort param[7]; -}; - -enum { - FnDsize = 8*2, /* each function descriptor is 8 shorts */ - - /* standard bits in FnD.status */ - FnStop = 1<<15, - FnWrap = 1<<13, - FnInt = 1<<12, - - /* optional bits */ - FnZ = 1<<11, /* FIR[35], MOD */ - FnIALL = 1<<10, /* FIRx */ - FnXinc0 = 0<<8, /* FIRx, IRR */ - FnXinc1 = 1<<8, - FnXinc2 = 2<<8, - FnXinc3 = 3<<8, - FnPC = 1<<7, /* FIRx */ - - - /* DSP functions (table 16-6) */ - FnFIR1 = 0x01, - FnFIR2 = 0x02, - FnFIR3 = 0x03, - FnFIR5 = 0x03, - FnFIR6 = 0x06, - FnIIR = 0x07, - FnMOD = 0x08, - FnDEMOD = 0x09, - FnLMS1 = 0x0A, - FnLMS2 = 0x0B, - FnWADD = 0x0C, -}; - -void dspinitialise(void); -DSP* dspacquire(void (*)(void*), void*); -void dspexec(DSP*, FnD*, ulong); -void* dspmalloc(ulong); -void dspfree(void*, ulong); -void dspsetfn(DSP*, FnD*, ulong); -void dspstart(DSP*); -void dsprelease(DSP*); -FnD* fndalloc(ulong); -void fndfree(FnD*, ulong); diff --git a/os/mpc/etherif.h b/os/mpc/etherif.h deleted file mode 100644 index 65b22c40..00000000 --- a/os/mpc/etherif.h +++ /dev/null @@ -1,37 +0,0 @@ -enum { - MaxEther = 6, - Ntypes = 8, -}; - -typedef struct Ether Ether; -struct Ether { -RWlock; /* TO DO */ - ISAConf; /* hardware info */ - int ctlrno; - int tbdf; /* type+busno+devno+funcno */ - int minmtu; - int maxmtu; - uchar ea[Eaddrlen]; - int encry; - - void (*attach)(Ether*); /* filled in by reset routine */ - void (*closed)(Ether*); - void (*detach)(Ether*); - void (*transmit)(Ether*); - void (*interrupt)(Ureg*, void*); - long (*ifstat)(Ether*, void*, long, ulong); - long (*ctl)(Ether*, void*, long); /* custom ctl messages */ - void (*power)(Ether*, int); /* power on/off */ - void (*shutdown)(Ether*); /* shutdown hardware before reboot */ - void *ctlr; - int pcmslot; /* PCMCIA */ - int fullduplex; /* non-zero if full duplex */ - - Queue* oq; - - Netif; -}; - -extern Block* etheriq(Ether*, Block*, int); -extern void addethercard(char*, int(*)(Ether*)); -extern int archether(int, Ether*); diff --git a/os/mpc/etherscc.c b/os/mpc/etherscc.c deleted file mode 100644 index 8180140e..00000000 --- a/os/mpc/etherscc.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * SCCn ethernet - */ - -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" -#include "../port/netif.h" - -#include "etherif.h" - -enum { - Nrdre = 16, /* receive descriptor ring entries */ - Ntdre = 16, /* transmit descriptor ring entries */ - - Rbsize = ETHERMAXTU+4, /* ring buffer size (+4 for CRC) */ - Bufsize = (Rbsize+7)&~7, /* aligned */ -}; - -enum { - /* ether-specific Rx BD bits */ - RxMiss= 1<<8, - RxeLG= 1<<5, - RxeNO= 1<<4, - RxeSH= 1<<3, - RxeCR= 1<<2, - RxeOV= 1<<1, - RxeCL= 1<<0, - RxError= (RxeLG|RxeNO|RxeSH|RxeCR|RxeOV|RxeCL), /* various error flags */ - - /* ether-specific Tx BD bits */ - TxPad= 1<<14, /* pad short frames */ - TxTC= 1<<10, /* transmit CRC */ - TxeDEF= 1<<9, - TxeHB= 1<<8, - TxeLC= 1<<7, - TxeRL= 1<<6, - TxeUN= 1<<1, - TxeCSL= 1<<0, - - /* scce */ - RXB= 1<<0, - TXB= 1<<1, - BSY= 1<<2, - RXF= 1<<3, - TXE= 1<<4, - - /* psmr */ - PRO= 1<<9, /* promiscuous mode */ - - /* gsmrl */ - ENR= 1<<5, - ENT= 1<<4, - - /* port A */ - RXD1= SIBIT(15), - TXD1= SIBIT(14), - - /* port B */ - RTS1= IBIT(19), - - /* port C */ - CTS1= SIBIT(11), - CD1= SIBIT(10), -}; - -typedef struct Etherparam Etherparam; -struct Etherparam { - SCCparam; - ulong c_pres; /* preset CRC */ - ulong c_mask; /* constant mask for CRC */ - ulong crcec; /* CRC error counter */ - ulong alec; /* alighnment error counter */ - ulong disfc; /* discard frame counter */ - ushort pads; /* short frame PAD characters */ - ushort ret_lim; /* retry limit threshold */ - ushort ret_cnt; /* retry limit counter */ - ushort mflr; /* maximum frame length reg */ - ushort minflr; /* minimum frame length reg */ - ushort maxd1; /* maximum DMA1 length reg */ - ushort maxd2; /* maximum DMA2 length reg */ - ushort maxd; /* rx max DMA */ - ushort dma_cnt; /* rx dma counter */ - ushort max_b; /* max bd byte count */ - ushort gaddr[4]; /* group address filter */ - ulong tbuf0_data0; /* save area 0 - current frm */ - ulong tbuf0_data1; /* save area 1 - current frm */ - ulong tbuf0_rba0; - ulong tbuf0_crc; - ushort tbuf0_bcnt; - ushort paddr[3]; /* physical address LSB to MSB increasing */ - ushort p_per; /* persistence */ - ushort rfbd_ptr; /* rx first bd pointer */ - ushort tfbd_ptr; /* tx first bd pointer */ - ushort tlbd_ptr; /* tx last bd pointer */ - ulong tbuf1_data0; /* save area 0 - next frame */ - ulong tbuf1_data1; /* save area 1 - next frame */ - ulong tbuf1_rba0; - ulong tbuf1_crc; - ushort tbuf1_bcnt; - ushort tx_len; /* tx frame length counter */ - ushort iaddr[4]; /* individual address filter*/ - ushort boff_cnt; /* back-off counter */ - ushort taddr[3]; /* temp address */ -}; - -typedef struct { - Lock; - int port; - int init; - int active; - SCC* scc; - CPMdev* cpm; - - Ring; - - ulong interrupts; /* statistics */ - ulong deferred; - ulong heartbeat; - ulong latecoll; - ulong retrylim; - ulong underrun; - ulong overrun; - ulong carrierlost; - ulong retrycount; -} Ctlr; - -static int sccid[] = {-1, CPscc1, CPscc2, CPscc3, CPscc4}; - -static void -attach(Ether *ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ctlr->active = 1; - ctlr->scc->gsmrl |= ENR|ENT; - eieio(); -} - -static void -closed(Ether *ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - if(ctlr->active){ - sccxstop(ctlr->cpm); - ilock(ctlr); - ctlr->active = 0; - iunlock(ctlr); - } -} - -static void -promiscuous(void* arg, int on) -{ - Ether *ether; - Ctlr *ctlr; - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(on || ether->nmaddr) - ctlr->scc->psmr |= PRO; - else - ctlr->scc->psmr &= ~PRO; - iunlock(ctlr); -} - -static void -multicast(void* arg, uchar *addr, int on) -{ - Ether *ether; - Ctlr *ctlr; - - USED(addr, on); /* if on, could SetGroupAddress; if !on, it's hard */ - - ether = (Ether*)arg; - ctlr = ether->ctlr; - - ilock(ctlr); - if(ether->prom || ether->nmaddr) - ctlr->scc->psmr |= PRO; - else - ctlr->scc->psmr &= ~PRO; - iunlock(ctlr); -} - -static void -txstart(Ether *ether) -{ - int len; - Ctlr *ctlr; - Block *b; - BD *dre; - - ctlr = ether->ctlr; - while(ctlr->ntq < Ntdre-1){ - b = qget(ether->oq); - if(b == 0) - break; - - dre = &ctlr->tdr[ctlr->tdrh]; - if(dre->status & BDReady) - panic("ether: txstart"); - - /* - * Give ownership of the descriptor to the chip, increment the - * software ring descriptor pointer and tell the chip to poll. - */ - len = BLEN(b); - dcflush(b->rp, len); - if(ctlr->txb[ctlr->tdrh] != nil) - panic("scc/ether: txstart"); - ctlr->txb[ctlr->tdrh] = b; - if((ulong)b->rp&1) - panic("scc/ether: txstart align"); /* TO DO: ensure alignment */ - dre->addr = PADDR(b->rp); - dre->length = len; - eieio(); - dre->status = (dre->status & BDWrap) | BDReady|TxPad|BDInt|BDLast|TxTC; - eieio(); - ctlr->scc->todr = 1<<15; /* transmit now */ - eieio(); - ctlr->ntq++; - ctlr->tdrh = NEXT(ctlr->tdrh, Ntdre); - } -} - -static void -transmit(Ether* ether) -{ - Ctlr *ctlr; - - ctlr = ether->ctlr; - ilock(ctlr); - txstart(ether); - iunlock(ctlr); -} - -static void -interrupt(Ureg*, void *arg) -{ - Ether *ether; - int len, events, status; - Ctlr *ctlr; - BD *dre; - Block *b; - - ether = arg; - ctlr = ether->ctlr; - if(!ctlr->active) - return; /* not ours */ - - /* - * Acknowledge all interrupts and whine about those that shouldn't - * happen. - */ - events = ctlr->scc->scce; - eieio(); - ctlr->scc->scce = events; - eieio(); - ctlr->interrupts++; - - if(events & (TXE|BSY|RXB)){ - if(events & RXB) - ctlr->overrun++; - if(events & TXE) - ether->oerrs++; - if(0 || events & TXE) - print("ETHER.SCC#%d: scce = 0x%uX\n", ether->ctlrno, events); - } - /* - * Receiver interrupt: run round the descriptor ring logging - * errors and passing valid receive data up to the higher levels - * until we encounter a descriptor still owned by the chip. - */ - if(events & (RXF|RXB) || 1){ - dre = &ctlr->rdr[ctlr->rdrx]; - while(((status = dre->status) & BDEmpty) == 0){ - if(status & RxError || (status & (BDFirst|BDLast)) != (BDFirst|BDLast)){ - if(status & (RxeLG|RxeSH)) - ether->buffs++; - if(status & RxeNO) - ether->frames++; - if(status & RxeCR) - ether->crcs++; - if(status & RxeOV) - ether->overflows++; - //print("eth rx: %ux\n", status); - } - else{ - /* - * We have a packet. Read it in. - */ - len = dre->length-4; - if((b = iallocb(len)) != 0){ - dcinval(KADDR(dre->addr), len); - memmove(b->wp, KADDR(dre->addr), len); - b->wp += len; - etheriq(ether, b, 1); - }else - ether->soverflows++; - } - - /* - * Finished with this descriptor, reinitialise it, - * give it back to the chip, then on to the next... - */ - dre->length = 0; - dre->status = (status & BDWrap) | BDEmpty | BDInt; - eieio(); - - ctlr->rdrx = NEXT(ctlr->rdrx, Nrdre); - dre = &ctlr->rdr[ctlr->rdrx]; - } - } - - /* - * Transmitter interrupt: handle anything queued for a free descriptor. - */ - if(events & TXB){ - lock(ctlr); - while(ctlr->ntq){ - dre = &ctlr->tdr[ctlr->tdri]; - status = dre->status; - if(status & BDReady) - break; - if(status & TxeDEF) - ctlr->deferred++; - if(status & TxeHB) - ctlr->heartbeat++; - if(status & TxeLC) - ctlr->latecoll++; - if(status & TxeRL) - ctlr->retrylim++; - if(status & TxeUN) - ctlr->underrun++; - if(status & TxeCSL) - ctlr->carrierlost++; - ctlr->retrycount += (status>>2)&0xF; - b = ctlr->txb[ctlr->tdri]; - if(b == nil) - panic("scce/interrupt: bufp"); - ctlr->txb[ctlr->tdri] = nil; - freeb(b); - ctlr->ntq--; - ctlr->tdri = NEXT(ctlr->tdri, Ntdre); - } - txstart(ether); - unlock(ctlr); - } - if(events & TXE) - cpmop(ctlr->cpm, RestartTx, 0); -} - -static long -ifstat(Ether* ether, void* a, long n, ulong offset) -{ - char *p; - int len; - Ctlr *ctlr; - - if(n == 0) - return 0; - - ctlr = ether->ctlr; - - p = malloc(READSTR); - len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); - len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); - len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); - len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); - len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); - len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); - len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); - snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); - n = readstr(offset, a, n, p); - free(p); - - return n; -} - -/* - * This follows the MPC823 user guide: section16.9.23.7's initialisation sequence, - * except that it sets the right bits for the MPC823ADS board when SCC2 is used, - * and those for the 860/821 development board for SCC1. - */ -static void -sccsetup(Ctlr *ctlr, SCC *scc, Ether *ether) -{ - int i, rcs, tcs, w; - Etherparam *p; - IMM *io; - - - i = 2*(ctlr->port-1); - io = ioplock(); - w = (TXD1|RXD1)<<i; /* TXDn and RXDn in port A */ - io->papar |= w; /* enable TXDn and RXDn pins */ - io->padir &= ~w; - io->paodr &= ~w; /* not open drain */ - - w = (CD1|CTS1)<<i; /* CLSN and RENA: CDn and CTSn in port C */ - io->pcpar &= ~w; /* enable CLSN (CTSn) and RENA (CDn) */ - io->pcdir &= ~w; - io->pcso |= w; - iopunlock(); - - /* clocks and transceiver control: details depend on the board's wiring */ - archetherenable(sccid[ctlr->port], &rcs, &tcs, ether->mbps, ether->fullduplex); - - sccnmsi(ctlr->port, rcs, tcs); /* connect the clocks */ - - p = ctlr->cpm->param; - memset(p, 0, sizeof(*p)); - p->rfcr = 0x18; - p->tfcr = 0x18; - p->mrblr = Bufsize; - p->rbase = PADDR(ctlr->rdr); - p->tbase = PADDR(ctlr->tdr); - - cpmop(ctlr->cpm, InitRxTx, 0); - - p->c_pres = ~0; - p->c_mask = 0xDEBB20E3; - p->crcec = 0; - p->alec = 0; - p->disfc = 0; - p->pads = 0x8888; - p->ret_lim = 0xF; - p->mflr = Rbsize; - p->minflr = ETHERMINTU+4; - p->maxd1 = Bufsize; - p->maxd2 = Bufsize; - p->p_per = 0; /* only moderate aggression */ - - for(i=0; i<Eaddrlen; i+=2) - p->paddr[2-i/2] = (ether->ea[i+1]<<8)|ether->ea[i]; /* it's not the obvious byte order */ - - scc->psmr = (2<<10)|(5<<1); /* 32-bit CRC, ignore 22 bits before SFD */ - scc->dsr = 0xd555; - scc->gsmrh = 0; /* normal operation */ - scc->gsmrl = (1<<28)|(4<<21)|(1<<19)|0xC; /* transmit clock invert, 48 bit preamble, repetitive 10 preamble, ethernet */ - eieio(); - scc->scce = ~0; /* clear all events */ - eieio(); - scc->sccm = TXE | RXF | TXB; /* enable interrupts */ - eieio(); - - io = ioplock(); - w = RTS1<<(ctlr->port-1); /* enable TENA pin (RTSn) */ - io->pbpar |= w; - io->pbdir |= w; - iopunlock(); - - /* gsmrl enable is deferred until attach */ -} - -static int -reset(Ether* ether) -{ - uchar ea[Eaddrlen]; - CPMdev *cpm; - Ctlr *ctlr; - SCC *scc; - - if(m->speed < 24){ - print("%s ether: system speed must be >= 24MHz for ether use\n", ether->type); - return -1; - } - - if(!(ether->port >= 1 && ether->port <= 4)){ - print("%s ether: no SCC port %lud\n", ether->type, ether->port); - return -1; - } - - /* - * Insist that the platform-specific code provide the Ethernet address - */ - memset(ea, 0, Eaddrlen); - if(memcmp(ea, ether->ea, Eaddrlen) == 0){ - print("no ether address"); - return -1; - } - - cpm = cpmdev(sccid[ether->port]); - if(cpm == nil) - return -1; - ether->irq = VectorCPIC + cpm->irq; - scc = cpm->regs; - ctlr = malloc(sizeof(*ctlr)); - ether->ctlr = ctlr; - memset(ctlr, 0, sizeof(*ctlr)); - ctlr->cpm = cpm; - ctlr->scc = scc; - ctlr->port = ether->port; - - if(ioringinit(ctlr, Nrdre, Ntdre, Bufsize) < 0) - panic("etherscc init"); - - sccsetup(ctlr, scc, ether); - - ether->attach = attach; - ether->closed = closed; - ether->transmit = transmit; - ether->interrupt = interrupt; - ether->ifstat = ifstat; - - ether->arg = ether; - ether->promiscuous = promiscuous; - ether->multicast = multicast; - - return 0; -} - -void -etherscclink(void) -{ - addethercard("SCC", reset); -} diff --git a/os/mpc/faultpower.c b/os/mpc/faultpower.c deleted file mode 100644 index 6d3b163b..00000000 --- a/os/mpc/faultpower.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" - -enum -{ - MC_IFETCH = (1<<30), - MC_STORE = (1<<11), /* bit 23 if X-form, bit 3 if D-form => write */ - DSI_STORE = (1<<25), - DSI_PROT = (1<<27), -}; - -void -faultpower(Ureg *ur) -{ - ulong addr; - char buf[ERRMAX]; - int read, i; - - addr = ur->pc; /* assume instr. exception */ - read = 1; - i = ur->cause >> 8; - if(i == CDSI || i == CDTLBE || i == CMCHECK && (ur->status&MC_IFETCH) == 0) { /* data access error including machine check load/store */ - addr = getdar(); - if(getdsisr() & (DSI_STORE|MC_STORE)) - read = 0; - } else if(i == CDMISS) /* DTLB miss */ - addr = getdepn() & ~0x3FF; /* can't distinguish read/write, but Inferno doesn't care */ -/* -print("fault %lux %lux %lux %d\n", ur->pc, ur->cause, addr, read); -print("imiss %lux dmiss %lux hash1 %lux dcmp %lux hash2 %lux\n", - getimiss(), getdmiss(), gethash1(), getdcmp(), gethash2()); -print("up %lux %lux %lux\n", m->upage, m->upage->virt, m->upage->phys); -*/ - - up->dbgreg = ur; /* For remote ACID */ - - spllo(); - sprint(buf, "trap: fault %s pc=0x%lux addr=0x%lux", - read ? "read" : "write", ur->pc, addr); - if(up->type == Interp) - disfault(ur, buf); - dumpregs(ur); - panic("fault: %s\n", buf); -} diff --git a/os/mpc/fp.s b/os/mpc/fp.s deleted file mode 100644 index e37bb63a..00000000 --- a/os/mpc/fp.s +++ /dev/null @@ -1,205 +0,0 @@ -/* - * support for floating-point hardware - */ - -#include "mem.h" - -/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ -#define MSRSYNC SYNC; ISYNC - -#define FPON(X, Y)\ - MOVW MSR, X;\ - OR $FPE, X, Y;\ - SYNC;\ - ISYNC;\ - MOVW Y, MSR;\ - MSRSYNC - -#define FPOFF(X,Y)\ - MOVW MSR, X;\ - RLWNM $0, X, $~FPE, Y;\ - SYNC;\ - ISYNC;\ - MOVW Y, MSR;\ - MSRSYNC - -#define FPPREV(X)\ - SYNC;\ - ISYNC;\ - MOVW X, MSR;\ - MSRSYNC - -TEXT kfpinit(SB), $0 - MOVFL $0,FPSCR(7) - MOVFL $0xD,FPSCR(6) /* VE, OE, ZE */ - MOVFL $0, FPSCR(5) - MOVFL $0, FPSCR(3) - MOVFL $0, FPSCR(2) - MOVFL $0, FPSCR(1) - MOVFL $0, FPSCR(0) - - FMOVD $4503601774854144.0, F27 - FMOVD $0.5, F29 - FSUB F29, F29, F28 - FADD F29, F29, F30 - FADD F30, F30, F31 - FMOVD F28, F0 - FMOVD F28, F1 - FMOVD F28, F2 - FMOVD F28, F3 - FMOVD F28, F4 - FMOVD F28, F5 - FMOVD F28, F6 - FMOVD F28, F7 - FMOVD F28, F8 - FMOVD F28, F9 - FMOVD F28, F10 - FMOVD F28, F11 - FMOVD F28, F12 - FMOVD F28, F13 - FMOVD F28, F14 - FMOVD F28, F15 - FMOVD F28, F16 - FMOVD F28, F17 - FMOVD F28, F18 - FMOVD F28, F19 - FMOVD F28, F20 - FMOVD F28, F21 - FMOVD F28, F22 - FMOVD F28, F23 - FMOVD F28, F24 - FMOVD F28, F25 - FMOVD F28, F26 - RETURN - -TEXT getfpscr(SB), $8 - FPON(R4, R5) - MOVFL FPSCR, F3 - FMOVD F3, -8(SP) - MOVW -4(SP), R3 - FPPREV(R4) - RETURN - -TEXT fpsave(SB), $0 - FPON(R4, R4) - - FMOVD F0,0(R3) - FMOVD F1,8(R3) - FMOVD F2,16(R3) - FMOVD F3,24(R3) - FMOVD F4,32(R3) - FMOVD F5,40(R3) - FMOVD F6,48(R3) - FMOVD F7,56(R3) - FMOVD F8,64(R3) - FMOVD F9,72(R3) - FMOVD F10,80(R3) - FMOVD F11,88(R3) - FMOVD F12,96(R3) - FMOVD F13,104(R3) - FMOVD F14,112(R3) - FMOVD F15,120(R3) - FMOVD F16,128(R3) - FMOVD F17,136(R3) - FMOVD F18,144(R3) - FMOVD F19,152(R3) - FMOVD F20,160(R3) - FMOVD F21,168(R3) - FMOVD F22,176(R3) - FMOVD F23,184(R3) - FMOVD F24,192(R3) - FMOVD F25,200(R3) - FMOVD F26,208(R3) - FMOVD F27,216(R3) - FMOVD F28,224(R3) - FMOVD F29,232(R3) - FMOVD F30,240(R3) - FMOVD F31,248(R3) - - MOVFL FPSCR, F0 - FMOVD F0, 256(R3) - MOVFL $0,FPSCR(7) - MOVFL $0xD,FPSCR(6) /* VE, OE, ZE */ - MOVFL $0, FPSCR(5) - MOVFL $0, FPSCR(4) - MOVFL $0, FPSCR(3) - MOVFL $0, FPSCR(2) - MOVFL $0, FPSCR(1) - MOVFL $0, FPSCR(0) - - FPOFF(R4, R4) - RETURN - -TEXT fprestore(SB), $0 - FPON(R4, R4) - - FMOVD 256(R3), F0 - MOVFL F0, FPSCR - FMOVD 0(R3), F0 - FMOVD 8(R3), F1 - FMOVD 16(R3), F2 - FMOVD 24(R3), F3 - FMOVD 32(R3), F4 - FMOVD 40(R3), F5 - FMOVD 48(R3), F6 - FMOVD 56(R3), F7 - FMOVD 64(R3), F8 - FMOVD 72(R3), F9 - FMOVD 80(R3), F10 - FMOVD 88(R3), F11 - FMOVD 96(R3), F12 - FMOVD 104(R3), F13 - FMOVD 112(R3), F14 - FMOVD 120(R3), F15 - FMOVD 128(R3), F16 - FMOVD 136(R3), F17 - FMOVD 144(R3), F18 - FMOVD 152(R3), F19 - FMOVD 160(R3), F20 - FMOVD 168(R3), F21 - FMOVD 176(R3), F22 - FMOVD 184(R3), F23 - FMOVD 192(R3), F24 - FMOVD 200(R3), F25 - FMOVD 208(R3), F26 - FMOVD 216(R3), F27 - FMOVD 224(R3), F28 - FMOVD 232(R3), F29 - FMOVD 240(R3), F30 - FMOVD 248(R3), F31 - - RETURN - -TEXT clrfptrap(SB), $0 - FPON(R4, R5) - MOVFL $0, FPSCR(5) - MOVFL $0, FPSCR(3) - MOVFL $0, FPSCR(2) - MOVFL $0, FPSCR(1) - MOVFL $0, FPSCR(0) - FPPREV(R4) - RETURN - -TEXT fpinit(SB), $0 - FPON(R4, R5) - BL kfpinit(SB) - RETURN - -TEXT fpoff(SB), $0 - FPOFF(R4, R5) - RETURN - - -TEXT FPsave(SB), 1, $0 - FPON(R4, R5) - MOVFL FPSCR, F0 - FMOVD F0, 0(R3) - FPPREV(R4) - RETURN - -TEXT FPrestore(SB), 1, $0 - FPON(R4, R5) - FMOVD 0(R3), F0 - MOVFL F0, FPSCR - FPPREV(R4) - RETURN diff --git a/os/mpc/fpi.h b/os/mpc/fpi.h deleted file mode 100644 index dfb9b1df..00000000 --- a/os/mpc/fpi.h +++ /dev/null @@ -1,61 +0,0 @@ -typedef long Word; -typedef unsigned long Single; -typedef struct { - unsigned long h; - unsigned long l; -} Double; - -enum { - FractBits = 28, - CarryBit = 0x10000000, - HiddenBit = 0x08000000, - MsBit = HiddenBit, - NGuardBits = 3, - GuardMask = 0x07, - LsBit = (1<<NGuardBits), - - SingleExpBias = 127, - SingleExpMax = 255, - DoubleExpBias = 1023, - DoubleExpMax = 2047, - - ExpBias = DoubleExpBias, - ExpInfinity = DoubleExpMax, -}; - -typedef struct { - unsigned char s; - short e; - long l; /* 0000FFFFFFFFFFFFFFFFFFFFFFFFFGGG */ - long h; /* 0000HFFFFFFFFFFFFFFFFFFFFFFFFFFF */ -} Internal; - -#define IsWeird(n) ((n)->e >= ExpInfinity) -#define IsInfinity(n) (IsWeird(n) && (n)->h == HiddenBit && (n)->l == 0) -#define SetInfinity(n) ((n)->e = ExpInfinity, (n)->h = HiddenBit, (n)->l = 0) -#define IsNaN(n) (IsWeird(n) && (((n)->h & ~HiddenBit) || (n)->l)) -#define SetQNaN(n) ((n)->s = 0, (n)->e = ExpInfinity, \ - (n)->h = HiddenBit|(LsBit<<1), (n)->l = 0) -#define IsZero(n) ((n)->e == 1 && (n)->h == 0 && (n)->l == 0) -#define SetZero(n) ((n)->e = 1, (n)->h = 0, (n)->l = 0) - -/* - * fpi.c - */ -extern void fpiround(Internal *); -extern void fpiadd(Internal *, Internal *, Internal *); -extern void fpisub(Internal *, Internal *, Internal *); -extern void fpimul(Internal *, Internal *, Internal *); -extern void fpidiv(Internal *, Internal *, Internal *); -extern int fpicmp(Internal *, Internal *); -extern void fpinormalise(Internal*); - -/* - * fpimem.c - */ -extern void fpis2i(Internal *, void *); -extern void fpid2i(Internal *, void *); -extern void fpiw2i(Internal *, void *); -extern void fpii2s(void *, Internal *); -extern void fpii2d(void *, Internal *); -extern void fpii2w(Word *, Internal *); diff --git a/os/mpc/fpipower.c b/os/mpc/fpipower.c deleted file mode 100644 index ec4363b2..00000000 --- a/os/mpc/fpipower.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * this doesn't attempt to implement Power architecture floating-point properties - * that aren't visible in the Inferno environment. - * all arithmetic is done in double precision. - * the FP trap status isn't updated. - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" - -#include "ureg.h" - -#include "fpi.h" - -#define REG(x) (*(long*)(((char*)em->ur)+roff[(x)])) -#define FR(x) (*(Internal*)em->fr[(x)&0x1F]) -#define REGSP 1 /* stack pointer */ - -/* BUG: check fetch (not worthwhile in Inferno) */ -#define getulong(a) (*(ulong*)(a)) - -enum { - CRLT = 1<<31, - CRGT = 1<<30, - CREQ = 1<<29, - CRSO = 1<<28, - CRFU = CRSO, - - CRFX = 1<<27, - CRFEX = 1<<26, - CRVX = 1<<25, - CROX = 1<<24, -}; - -#define getCR(x,w) (((w)>>(28-(x*4)))&0xF) -#define mkCR(x,v) (((v)&0xF)<<(28-(x*4))) - -#define simm(xx, ii) xx = (short)(ii&0xFFFF); -#define getairr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; simm(imm,i) -#define getarrr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; rb = (i>>11)&0x1f; -#define getop(i) ((i>>26)&0x3F) -#define getxo(i) ((i>>1)&0x3FF) - -#define FPS_FX (1<<31) /* exception summary (sticky) */ -#define FPS_EX (1<<30) /* enabled exception summary */ -#define FPS_VX (1<<29) /* invalid operation exception summary */ -#define FPS_OX (1<<28) /* overflow exception OX (sticky) */ -#define FPS_UX (1<<27) /* underflow exception UX (sticky) */ -#define FPS_ZX (1<<26) /* zero divide exception ZX (sticky) */ -#define FPS_XX (1<<25) /* inexact exception XX (sticky) */ -#define FPS_VXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ -#define FPS_VXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ -#define FPS_VXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ -#define FPS_VXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ -#define FPS_VXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ -#define FPS_VXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ -#define FPS_FR (1<<18) /* fraction rounded */ -#define FPS_FI (1<<17) /* fraction inexact */ -#define FPS_FPRF (1<<16) /* floating point result class */ -#define FPS_FPCC (0xF<<12) /* <, >, =, unordered */ -#define FPS_VXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ -#define FPS_VE (1<<7) /* invalid operation exception enable */ -#define FPS_OE (1<<6) /* enable overflow exceptions */ -#define FPS_UE (1<<5) /* enable underflow */ -#define FPS_ZE (1<<4) /* enable zero divide */ -#define FPS_XE (1<<3) /* enable inexact exceptions */ -#define FPS_RN (3<<0) /* rounding mode */ - -typedef struct Emreg Emreg; - -struct Emreg { - Ureg* ur; - ulong (*fr)[3]; - FPenv* ufp; - ulong ir; - char* name; -}; - -int fpemudebug = 0; - -#undef OFR -#define OFR(X) ((ulong)&((Ureg*)0)->X) - -static int roff[] = { - OFR(r0), OFR(r1), OFR(r2), OFR(r3), - OFR(r4), OFR(r5), OFR(r6), OFR(r7), - OFR(r8), OFR(r9), OFR(r10), OFR(r11), - OFR(r12), OFR(r13), OFR(r14), OFR(r15), - OFR(r16), OFR(r17), OFR(r18), OFR(r19), - OFR(r20), OFR(r21), OFR(r22), OFR(r23), - OFR(r24), OFR(r25), OFR(r26), OFR(r27), - OFR(r28), OFR(r29), OFR(r30), OFR(r31), -}; - -/* - * initial FP register values assumed by qc's code - */ -static Internal fpreginit[] = { - /* s, e, l, h */ - {0, 0x400, 0x00000000, 0x08000000}, /* F31=2.0 */ - {0, 0x3FF, 0x00000000, 0x08000000}, /* F30=1.0 */ - {0, 0x3FE, 0x00000000, 0x08000000}, /* F29=0.5 */ - {0, 0x1, 0x00000000, 0x00000000}, /* F28=0.0 */ - {0, 0x433, 0x00000000, 0x08000040}, /* F27=FREGCVI */ -}; - -static void -fadd(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - (a.s == b.s? fpiadd: fpisub)(&b, &a, d); -} - -static void -fsub(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - b.s ^= 1; - (b.s == a.s? fpiadd: fpisub)(&b, &a, d); -} - -static void -fmul(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - fpimul(&b, &a, d); -} - -static void -fdiv(Emreg *em, Internal *d, int ra, int rb) -{ - Internal a, b; - - a = FR(ra); - b = FR(rb); - fpidiv(&b, &a, d); -} - -static void -fmsub(Emreg *em, Internal *d, int ra, int rc, int rb) -{ - Internal a, c, b, t; - - a = FR(ra); - c = FR(rc); - b = FR(rb); - fpimul(&a, &c, &t); - b.s ^= 1; - (b.s == t.s? fpiadd: fpisub)(&b, &t, d); -} - -static void -fmadd(Emreg *em, Internal *d, int ra, int rc, int rb) -{ - Internal a, c, b, t; - - a = FR(ra); - c = FR(rc); - b = FR(rb); - fpimul(&a, &c, &t); - (t.s == b.s? fpiadd: fpisub)(&b, &t, d); -} - -static ulong setfpscr(Emreg*); -static void setfpcc(Emreg*, int); - -static void -unimp(Emreg *em, ulong op) -{ - char buf[60]; - - snprint(buf, sizeof(buf), "sys: fp: pc=%lux unimp fp 0x%.8lux", em->ur->pc, op); - if(fpemudebug) - print("FPE: %s\n", buf); - error(buf); - /* no return */ -} - -/* - * floating load/store - */ - -static void -fpeairr(Emreg *em, ulong ir, void **eap, int *rdp) -{ - ulong ea; - long imm; - int ra, rd, upd; - - getairr(ir); - ea = imm; - upd = (ir&(1L<<26))!=0; - if(ra) { - ea += REG(ra); - if(upd){ - if(ra == REGSP) - panic("fpemu: r1 update"); /* can't do it because we're running on the same stack */ - REG(ra) = ea; - } - } else { - if(upd) - unimp(em, ir); - } - *rdp = rd; - *eap = (void*)ea; - if(fpemudebug) - print("%8.8lux %s\tf%d,%ld(r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, imm, ra, ea, upd); -} - -static void -fpearrr(Emreg *em, ulong ir, int upd, void **eap, int *rdp) -{ - ulong ea; - int ra, rb, rd; - - getarrr(ir); - ea = REG(rb); - if(ra){ - ea += REG(ra); - if(upd){ - if(ra == REGSP) - panic("fpemu: r1 update"); - REG(ra) = ea; - } - if(fpemudebug) - print("%8.8lux %s\tf%d,(r%d+r%d) ea=%lux upd=%d\n", em->ur->pc, em->name, rd, ra, rb, ea, upd); - } else { - if(upd) - unimp(em, ir); - if(fpemudebug) - print("%8.8lux %s\tf%d,(r%d) ea=%lux\n", em->ur->pc, em->name, rd, rb, ea); - } - *eap = (void*)ea; - *rdp = rd; -} - -static void -lfs(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfs"; - fpeairr(em, ir, &ea, &rd); - fpis2i(&FR(rd), (void*)ea); -} - -static void -lfsx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfsx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==567, &ea, &rd); - fpis2i(&FR(rd), (void*)ea); -} - -static void -lfd(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfd"; - fpeairr(em, ir, &ea, &rd); - fpid2i(&FR(rd), (void*)ea); -} - -static void -lfdx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - - em->name = "lfdx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==631, &ea, &rd); - fpid2i(&FR(rd), (void*)ea); -} - -static void -stfs(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfs"; - fpeairr(em, ir, &ea, &rd); - tmp = FR(rd); - fpii2s(ea, &tmp); -} - -static void -stfsx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfsx"; - fpearrr(em, ir, getxo(ir)==695, &ea, &rd); - tmp = FR(rd); - fpii2s(ea, &tmp); -} - -static void -stfd(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfd"; - fpeairr(em, ir, &ea, &rd); - tmp = FR(rd); - fpii2d(ea, &tmp); -} - -static void -stfdx(Emreg *em, ulong ir) -{ - void *ea; - int rd; - Internal tmp; - - em->name = "stfdx"; - fpearrr(em, ir, ((ir>>1)&0x3FF)==759, &ea, &rd); - tmp = FR(rd); - fpii2d(ea, &tmp); -} - -static void -mcrfs(Emreg *em, ulong ir) -{ - int rd, ra, rb; - static ulong fpscr0[] ={ - FPS_FX|FPS_OX, - FPS_UX|FPS_ZX|FPS_XX|FPS_VXSNAN, - FPS_VXISI|FPS_VXIDI|FPS_VXZDZ|FPS_VXIMZ, - FPS_VXVC, - 0, - FPS_VXCVI, - }; - - getarrr(ir); - if(rb || ra&3 || rd&3) - unimp(em, ir); - ra >>= 2; - rd >>= 2; - em->ur->cr = (em->ur->cr & ~mkCR(rd, 0xF)) | mkCR(rd, getCR(ra, em->ufp->fpscr)); - em->ufp->fpscr &= ~fpscr0[ra]; - if(fpemudebug) - print("%8.8lux mcrfs\tcrf%d,crf%d\n", em->ur->pc, rd, ra); -} - -static void -mffs(Emreg *em, ulong ir) -{ - int rd, ra, rb; - Double dw; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - dw.h = 0; - dw.l = ((uvlong)0xFFF8000L<<16)|em->ufp->fpscr; - fpid2i(&FR(rd), &dw); - /* it's anyone's guess how CR1 should be set when ir&1 */ - em->ur->cr &= ~mkCR(1, 0xE); /* leave SO, reset others */ - if(fpemudebug) - print("%8.8lux mffs%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsb1(Emreg *em, ulong ir) -{ - int rd, ra, rb; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - em->ufp->fpscr |= (1L << (31-rd)); - /* BUG: should set summary bits */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsb1%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsb0(Emreg *em, ulong ir) -{ - int rd, ra, rb; - - getarrr(ir); - if(ra || rb) - unimp(em, ir); - em->ufp->fpscr &= ~(1L << (31-rd)); - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsb0%s\tfr%d\n", em->ur->pc, ir&1?".":"", rd); -} - -static void -mtfsf(Emreg *em, ulong ir) -{ - int fm, rb, i; - ulong v; - Internal b; - Double db; - - if(ir & ((1L << 25)|(1L << 16))) - unimp(em, ir); - rb = (ir >> 11) & 0x1F; - fm = (ir >> 17) & 0xFF; - b = FR(rb); - fpii2d(&db, &b); /* reconstruct hi/lo format to recover low word */ - v = db.l; - for(i=0; i<8; i++) - if(fm & (1 << (7-i))) - em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(i, 0xF)) | mkCR(i, getCR(i, v)); - /* BUG: should set FEX and VX `according to the usual rule' */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsf%s\t#%.2x,fr%d\n", em->ur->pc, ir&1?".":"", fm, rb); -} - -static void -mtfsfi(Emreg *em, ulong ir) -{ - int imm, rd; - - if(ir & ((0x7F << 16)|(1L << 11))) - unimp(em, ir); - rd = (ir >> 23) & 0xF; - imm = (ir >> 12) & 0xF; - em->ufp->fpscr = (em->ufp->fpscr & ~mkCR(rd, 0xF)) | mkCR(rd, imm); - /* BUG: should set FEX and VX `according to the usual rule' */ - if(ir & 1) - em->ur->cr &= ~mkCR(1, 0xE); /* BUG: manual unclear: leave SO, reset others? */ - if(fpemudebug) - print("%8.8lux mtfsfi%s\tcrf%d,#%x\n", em->ur->pc, ir&1?".":"", rd, imm); -} - -static void -fcmp(Emreg *em, ulong ir) -{ - int fc, rd, ra, rb, sig, i; - - getarrr(ir); - if(rd & 3) - unimp(em, ir); - rd >>= 2; - sig = 0; - switch(getxo(ir)) { - default: - unimp(em, ir); - case 32: - if(fpemudebug) - print("%8.8lux fcmpo\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb); - sig = 1; - break; - case 0: - if(fpemudebug) - print("%8.8lux fcmpu\tcr%d,f%d,f%d\n", em->ur->pc, rd, ra, rb); - break; - } - if(IsWeird(&FR(ra)) || IsWeird(&FR(rb))) { - if(sig){ - ; /* BUG: should trap if not masked ... */ - } - fc = CRFU; - } else { - i = fpicmp(&FR(ra), &FR(rb)); - if(i > 0) - fc = CRGT; - else if(i == 0) - fc = CREQ; - else - fc = CRLT; - } - fc >>= 28; - em->ur->cr = (em->ur->cr & ~mkCR(rd,~0)) | mkCR(rd, fc); - em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (fc<<11); - /* BUG: update FX, VXSNAN, VXVC */ -} - -static void -fariths(Emreg *em, ulong ir) -{ - int rd, ra, rb, rc, fmt; - char *cc, *n; - ulong fpscr; - Internal *d; - - fmt = 0; - rc = (ir>>6)&0x1F; - getarrr(ir); - d = &FR(rd); - switch(getxo(ir)&0x1F) { /* partial XO decode */ - case 22: /* fsqrts */ - case 24: /* fres */ - default: - unimp(em, ir); - return; - case 18: - if(IsZero(&FR(rb))) { - em->ufp->fpscr |= FPS_ZX | FPS_FX; - error("sys: fp: zero divide"); - } - fdiv(em, d, ra, rb); - n = "fdivs"; - break; - case 20: - fsub(em, d, ra, rb); - n = "fsubs"; - break; - case 21: - fadd(em, d, ra, rb); - n = "fadds"; - break; - case 25: - fmul(em, d, ra, rc); - rb = rc; - n = "fmuls"; - break; - case 28: - fmsub(em, d, ra, rc, rb); - fmt = 2; - n = "fmsubs"; - break; - case 29: - fmadd(em, d, ra, rc, rb); - fmt = 2; - n = "fmadds"; - break; - case 30: - fmsub(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmsubs"; - break; - case 31: - fmadd(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmadds"; - break; - } - if(fmt==1 && ra) - unimp(em, ir); - fpscr = setfpscr(em); - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) { - switch(fmt) { - case 0: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb); - break; - case 1: - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); - break; - case 2: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb); - break; - } - } -} - -static void -farith(Emreg *em, ulong ir) -{ - Word w; - Double dv; - int rd, ra, rb, rc, fmt; - char *cc, *n; - ulong fpscr; - int nocc; - Internal *d; - - fmt = 0; - nocc = 0; - rc = (ir>>6)&0x1F; - getarrr(ir); - d = &FR(rd); - switch(getxo(ir)&0x1F) { /* partial XO decode */ - case 22: /* frsqrt */ - case 23: /* fsel */ - case 26: /* fsqrte */ - default: - unimp(em, ir); - return; - case 12: /* frsp */ - *d = FR(rb); /* BUG: doesn't round to single precision */ - fmt = 1; - n = "frsp"; - break; - case 14: /* fctiw */ /* BUG: ignores rounding mode */ - case 15: /* fctiwz */ - fpii2w(&w, &FR(rb)); - dv.h = 0; - dv.l = w; - fpid2i(d, &dv); - fmt = 1; - nocc = 1; - n = "fctiw"; - break; - case 18: - if(IsZero(&FR(rb))) { - em->ufp->fpscr |= FPS_ZX | FPS_FX; - error("sys: fp: zero divide"); - } - fdiv(em, d, ra, rb); - n = "fdiv"; - break; - case 20: - fsub(em, d, ra, rb); - n = "fsub"; - break; - case 21: - fadd(em, d, ra, rb); - n = "fadd"; - break; - case 25: - fmul(em, d, ra, rc); - rb = rc; - n = "fmul"; - break; - case 28: - fmsub(em, d, ra, rc, rb); - fmt = 2; - n = "fmsub"; - break; - case 29: - fmadd(em, d, ra, rc, rb); - fmt = 2; - n = "fmadd"; - break; - case 30: - fmsub(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmsub"; - break; - case 31: - fmadd(em, d, ra, rc, rb); - d->s ^= 1; - fmt = 2; - n = "fnmadd"; - break; - } - if(fmt==1 && ra) - unimp(em, ir); - fpscr = setfpscr(em); - if(nocc == 0) - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) { - switch(fmt) { - case 0: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rb); - break; - case 1: - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); - break; - case 2: - print("%8.8lux %s%s\tfr%d,fr%d,fr%d,fr%d\n", em->ur->pc, n, cc, rd, ra, rc, rb); - break; - } - } -} - -static void -farith2(Emreg *em, ulong ir) -{ - int rd, ra, rb; - char *cc, *n; - ulong fpscr; - Internal *d, *b; - - getarrr(ir); - if(ra) - unimp(em, ir); - d = &FR(rd); - b = &FR(rb); - switch(getxo(ir)) { /* full XO decode */ - default: - unimp(em, ir); - case 40: - *d = *b; - d->s ^= 1; - n = "fneg"; - break; - case 72: - *d = *b; - n = "fmr"; - break; - case 136: - *d = *b; - d->s = 1; - n = "fnabs"; - break; - case 264: - *d = *b; - d->s = 0; - n = "fabs"; - break; - } - fpscr = setfpscr(em); - setfpcc(em, rd); - cc = ""; - if(ir & 1) { - cc = "."; - em->ur->cr = (em->ur->cr & ~mkCR(1, ~0)) | mkCR(1, (fpscr>>28)); - } - if(fpemudebug) - print("%8.8lux %s%s\tfr%d,fr%d\n", em->ur->pc, n, cc, rd, rb); -} - -static ulong -setfpscr(Emreg *em) -{ - ulong fps, fpscr; - - fps = 0; /* BUG: getfsr() */ - fpscr = em->ufp->fpscr; - if(fps & FPAOVFL) - fpscr |= FPS_OX; - if(fps & FPAINEX) - fpscr |= FPS_XX; - if(fps & FPAUNFL) - fpscr |= FPS_UX; - if(fps & FPAZDIV) - fpscr |= FPS_ZX; - if(fpscr != em->ufp->fpscr) { - fpscr |= FPS_FX; - em->ufp->fpscr = fpscr; - } - return fpscr; -} - -static void -setfpcc(Emreg *em, int r) -{ - int c; - Internal *d; - - d = &FR(r); - c = 0; - if(IsZero(d)) - c |= 2; - else if(d->s == 1) - c |= 4; - else - c |= 8; - if(IsNaN(d)) - c |= 1; - em->ufp->fpscr = (em->ufp->fpscr & ~0xF800) | (0<<15) | (c<<11); /* unsure about class bit */ -} - -static uchar op63flag[32] = { -[12] 1, [14] 1, [15] 1, [18] 1, [20] 1, [21] 1, [22] 1, -[23] 1, [25] 1, [26] 1, [28] 1, [29] 1, [30] 1, [31] 1, -}; - -/* - * returns the number of FP instructions emulated - */ -int -fpipower(Ureg *ur) -{ - ulong op; - int xo; - Emreg emreg, *em; - FPenv *ufp; - int n; - - ufp = &up->env->fpu; /* because all the state is in Osenv, it need not be saved/restored */ - em = &emreg; - em->ur = ur; - em->fr = ufp->emreg; - em->ufp = ufp; - em->name = nil; - if(em->ufp->fpistate != FPACTIVE) { - em->ufp->fpistate = FPACTIVE; - em->ufp->fpscr = 0; /* TO DO */ - for(n = 0; n < nelem(fpreginit); n++) - FR(31-n) = fpreginit[n]; - } - for(n=0;;n++){ - op = getulong(ur->pc); - em->ir = op; - if(fpemudebug > 1) - print("%8.8lux %8.8lux: ", ur->pc, op); - switch(op>>26){ - default: - return n; - case 48: /* lfs */ - case 49: /* lfsu */ - lfs(em, op); - break; - case 50: /* lfd */ - case 51: /* lfdu */ - lfd(em, op); - break; - case 52: /* stfs */ - case 53: /* stfsu */ - stfs(em, op); - break; - case 54: /* stfd */ - case 55: /* stfdu */ - stfd(em, op); - break; - case 31: /* indexed load/store */ - xo = getxo(op); - if((xo & 0x300) != 0x200) - return n; - switch(xo){ - default: - return n; - case 535: /* lfsx */ - case 567: /* lfsux */ - lfsx(em, op); - break; - case 599: /* lfdx */ - case 631: /* lfdux */ - lfdx(em, op); - break; - case 663: /* stfsx */ - case 695: /* stfsux */ - stfsx(em, op); - break; - case 727: /* stfdx */ - case 759: /* stfdux */ - stfdx(em, op); - break; - } - break; - case 63: /* double precision */ - xo = getxo(op); - if(op63flag[xo & 0x1F]){ - farith(em, op); - break; - } - switch(xo){ - default: - return n; - case 0: /* fcmpu */ - case 32: /* fcmpo */ - fcmp(em, op); - break; - case 40: /* fneg */ - case 72: /* fmr */ - case 136: /* fnabs */ - case 264: /* fabs */ - farith2(em, op); - break; - case 38: - mtfsb1(em, op); - break; - case 64: - mcrfs(em, op); - break; - case 70: - mtfsb0(em, op); - break; - case 134: - mtfsfi(em, op); - break; - case 583: - mffs(em, op); - break; - case 711: - mtfsf(em, op); - break; - } - break; - case 59: /* single precision */ - fariths(em, op); - break; - } - ur->pc += 4; - if(anyhigher()) - sched(); - } - return n; -} - -/* -50: lfd frD,d(rA) -51: lfdu frD,d(rA) -31,631: lfdux frD,rA,rB -31,599: lfdx frD,rA,rB -48: lfs frD,d(rA) -49: lfsu frD,d(rA) -31,567: lfsux frD,rA,rB -31,535: lfsx frD,rA,rB - -54: stfd frS,d(rA) -55: stfdu frS,d(rA) -31,759: stfdux frS,rA,rB -31,727: stfdx frS,rA,rB -52: stfs frS,d(rA) -53: stfsu frS,d(rA) -31,695: stfsux frS,rA,rB -31,663: stfsx frS,rA,rB - -63,64: mcrfs crfD,crfS -63,583: mffs[.] frD -63,70: mtfsb0[.] crbD -63,38: mtfsb1[.] crbD -63,711: mtfsf[.] FM,frB -63,134: mtfsfi[.] crfD,IMM -*/ - -/* -float to int: - FMOVD g+0(SB),F1 - FCTIWZ F1,F4 - FMOVD F4,.rathole+0(SB) - MOVW .rathole+4(SB),R7 - MOVW R7,l+0(SB) -*/ - -/* -int to float: - MOVW $1127219200,R9 - MOVW l+0(SB),R7 - MOVW R9,.rathole+0(SB) - XOR $-2147483648,R7,R6 - MOVW R6,.rathole+4(SB) - FMOVD .rathole+0(SB),F0 - FSUB F27,F0 - -unsigned to float: - MOVW ul+0(SB),R5 - MOVW R9,.rathole+0(SB) - XOR $-2147483648,R5,R4 - MOVW R4,.rathole+4(SB) - FMOVD .rathole+0(SB),F3 - FSUB F27,F3 - FCMPU F3,F28 - BGE ,3(PC) - FMOVD $4.29496729600000000e+09,F2 - FADD F2,F3 - FMOVD F3,g+0(SB) -*/ diff --git a/os/mpc/i2c.c b/os/mpc/i2c.c deleted file mode 100644 index 5218b1c0..00000000 --- a/os/mpc/i2c.c +++ /dev/null @@ -1,439 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -/* - * basic read/write interface to mpc8xx I2C bus (master mode) - */ - -typedef struct Ctlr Ctlr; -typedef struct I2C I2C; - -struct I2C { - uchar i2mod; - uchar rsv12a[3]; - uchar i2add; - uchar rsv12b[3]; - uchar i2brg; - uchar rsv12c[3]; - uchar i2com; - uchar rsv12d[3]; - uchar i2cer; - uchar rsv12e[3]; - uchar i2cmr; -}; - -enum { - /* i2c-specific BD flags */ - RxeOV= 1<<1, /* overrun */ - TxS= 1<<10, /* transmit start condition */ - TxeNAK= 1<<2, /* last transmitted byte not acknowledged */ - TxeUN= 1<<1, /* underflow */ - TxeCL= 1<<0, /* collision */ - TxERR= (TxeNAK|TxeUN|TxeCL), - - /* i2cmod */ - REVD= 1<<5, /* =1, LSB first */ - GCD= 1<<4, /* =1, general call address disabled */ - FLT= 1<<3, /* =0, not filtered; =1, filtered */ - PDIV= 3<<1, /* predivisor field */ - EN= 1<<0, /* enable */ - - /* i2com */ - STR= 1<<7, /* start transmit */ - I2CM= 1<<0, /* master */ - I2CS= 0<<0, /* slave */ - - /* i2cer */ - TXE = 1<<4, - BSY = 1<<2, - TXB = 1<<1, - RXB = 1<<0, - - /* port B bits */ - I2CSDA = IBIT(27), - I2CSCL = IBIT(26), - - Rbit = 1<<0, /* bit in address byte denoting read */ - - /* maximum I2C I/O (can change) */ - MaxIO = 128, - MaxSA = 2, /* longest subaddress */ - Bufsize = (MaxIO+MaxSA+1+4)&~3, /* extra space for subaddress/clock bytes and alignment */ - Freq = 100000, - I2CTimeout = 250, /* msec */ - - Chatty = 0, -}; - -#define DPRINT if(Chatty)print - -/* data cache needn't be flushed if buffers allocated in uncached PHYSIMM */ -#define DCFLUSH(a,n) - -/* - * I2C software structures - */ - -struct Ctlr { - Lock; - QLock io; - int init; - int busywait; /* running before system set up */ - I2C* i2c; - IOCparam* sp; - - BD* rd; - BD* td; - int phase; - Rendez r; - char* addr; - char* txbuf; - char* rxbuf; -}; - -static Ctlr i2ctlr[1]; - -static void interrupt(Ureg*, void*); - -static void -enable(void) -{ - I2C *i2c; - - i2c = i2ctlr->i2c; - i2c->i2cer = ~0; /* clear events */ - eieio(); - i2c->i2mod |= EN; - eieio(); - i2c->i2cmr = TXE|BSY|TXB|RXB; /* enable all interrupts */ - eieio(); -} - -static void -disable(void) -{ - I2C *i2c; - - i2c = i2ctlr->i2c; - i2c->i2cmr = 0; /* mask all interrupts */ - i2c->i2mod &= ~EN; -} - -/* - * called by the reset routine of any driver using the I2C - */ -void -i2csetup(int busywait) -{ - IMM *io; - I2C *i2c; - IOCparam *sp; - CPMdev *cpm; - Ctlr *ctlr; - long f, e, emin; - int p, d, dmax; - - ctlr = i2ctlr; - ctlr->busywait = busywait; - if(ctlr->init) - return; - print("i2c setup...\n"); - ctlr->init = 1; - cpm = cpmdev(CPi2c); - i2c = cpm->regs; - ctlr->i2c = i2c; - sp = cpm->param; - if(sp == nil) - panic("I2C: can't allocate new parameter memory\n"); - ctlr->sp = sp; - disable(); - - if(ctlr->txbuf == nil){ - ctlr->txbuf = cpmalloc(Bufsize, 2); - ctlr->addr = ctlr->txbuf+MaxIO; - } - if(ctlr->rxbuf == nil) - ctlr->rxbuf = cpmalloc(Bufsize, 2); - if(ctlr->rd == nil){ - ctlr->rd = bdalloc(1); - ctlr->rd->addr = PADDR(ctlr->rxbuf); - ctlr->rd->length = 0; - ctlr->rd->status = BDWrap; - } - if(ctlr->td == nil){ - ctlr->td = bdalloc(2); - ctlr->td->addr = PADDR(ctlr->txbuf); - ctlr->td->length = 0; - ctlr->td->status = BDWrap|BDLast; - } - - /* select port pins */ - io = ioplock(); - io->pbdir |= I2CSDA | I2CSCL; - io->pbodr |= I2CSDA | I2CSCL; - io->pbpar |= I2CSDA | I2CSCL; - iopunlock(); - - /* explicitly initialise parameters, because InitRxTx can't be used (see i2c/spi relocation errata) */ - sp = ctlr->sp; - sp->rbase = PADDR(ctlr->rd); - sp->tbase = PADDR(ctlr->td); - sp->rfcr = 0x18; - sp->tfcr = 0x18; - sp->mrblr = Bufsize; - sp->rstate = 0; - sp->rptr = 0; - sp->rbptr = sp->rbase; - sp->rcnt = 0; - sp->tstate = 0; - sp->tbptr = sp->tbase; - sp->tptr = 0; - sp->tcnt = 0; - eieio(); - - i2c->i2com = I2CM; - i2c->i2mod = 0; /* normal mode */ - i2c->i2add = 0; - - emin = Freq; - dmax = (m->cpuhz/Freq)/2-3; - for(d=0; d < dmax; d++){ - for(p=3; p>=0; p--){ - f = (m->cpuhz>>(p+2))/(2*(d+3)); - e = Freq - f; - if(e < 0) - e = -e; - if(e < emin){ - emin = e; - i2c->i2brg = d; - i2c->i2mod = (i2c->i2mod&~PDIV)|((3-p)<<1); /* set PDIV */ - } - } - } - //print("i2brg=%d i2mod=#%2.2ux\n", i2c->i2brg, i2c->i2mod); - intrenable(VectorCPIC+cpm->irq, interrupt, i2ctlr, BUSUNKNOWN, "i2c"); -} - -enum { - Idling, - Done, - Busy, - Sending, - Recving, -}; - -static void -interrupt(Ureg*, void *arg) -{ - int events; - Ctlr *ctlr; - I2C *i2c; - - ctlr = arg; - i2c = ctlr->i2c; - events = i2c->i2cer; - eieio(); - i2c->i2cer = events; - if(events & (BSY|TXE)){ - //print("I2C#%x\n", events); - if(ctlr->phase != Idling){ - ctlr->phase = Idling; - wakeup(&ctlr->r); - } - }else{ - if(events & TXB){ - //print("i2c: xmt %d %4.4ux %4.4ux\n", ctlr->phase, ctlr->td->status, ctlr->td[1].status); - if(ctlr->phase == Sending){ - ctlr->phase = Done; - wakeup(&ctlr->r); - } - } - if(events & RXB){ - //print("i2c: rcv %d %4.4ux %d\n", ctlr->phase, ctlr->rd->status, ctlr->rd->length); - if(ctlr->phase == Recving){ - ctlr->phase = Done; - wakeup(&ctlr->r); - } - } - } -} - -static int -done(void *a) -{ - return ((Ctlr*)a)->phase < Busy; -} - -static void -i2cwait(Ctlr *ctlr) -{ - int i; - - if(up == nil || ctlr->busywait){ - for(i=0; i < 5 && !done(ctlr); i++){ - delay(2); - interrupt(nil, ctlr); - } - }else - tsleep(&ctlr->r, done, ctlr, I2CTimeout); -} - -static int -i2cerror(char *s) -{ - if(up) - error(s); - /* no current process, don't call error */ - DPRINT("i2c error: %s\n", s); - return -1; -} - -long -i2csend(I2Cdev *d, void *buf, long n, ulong offset) -{ - Ctlr *ctlr; - int i, p, s; - - ctlr = i2ctlr; - if(up){ - if(n > MaxIO) - error(Etoobig); - qlock(&ctlr->io); - if(waserror()){ - qunlock(&ctlr->io); - nexterror(); - } - } - ctlr->txbuf[0] = d->addr<<1; - i = 1; - if(d->salen > 1) - ctlr->txbuf[i++] = offset>>8; - if(d->salen) - ctlr->txbuf[i++] = offset; - memmove(ctlr->txbuf+i, buf, n); - if(Chatty){ - print("tx: %8.8lux: ", PADDR(ctlr->txbuf)); - for(s=0; s<n+i; s++) - print(" %.2ux", ctlr->txbuf[s]&0xFF); - print("\n"); - } - DCFLUSH(ctlr->txbuf, Bufsize); - ilock(ctlr); - ctlr->phase = Sending; - ctlr->rd->status = BDEmpty|BDWrap|BDInt; - ctlr->td->addr = PADDR(ctlr->txbuf); - ctlr->td->length = n+i; - ctlr->td->status = BDReady|BDWrap|BDLast|BDInt; - enable(); - ctlr->i2c->i2com = STR|I2CM; - eieio(); - iunlock(ctlr); - i2cwait(ctlr); - disable(); - p = ctlr->phase; - s = ctlr->td->status; - if(up){ - poperror(); - qunlock(&ctlr->io); - } - if(s & BDReady) - return i2cerror("timed out"); - if(s & TxERR){ - sprint(up->genbuf, "write error: status %.4ux", s); - return i2cerror(up->genbuf); - } - if(p != Done) - return i2cerror("phase error"); - return n; -} - -long -i2crecv(I2Cdev *d, void *buf, long n, ulong offset) -{ - Ctlr *ctlr; - int p, s, flag, i; - BD *td; - long nr; - - ctlr = i2ctlr; - if(up){ - if(n > MaxIO) - error(Etoobig); - qlock(&ctlr->io); - if(waserror()){ - qunlock(&ctlr->io); - nexterror(); - } - } - ctlr->txbuf[0] = (d->addr<<1)|Rbit; - if(d->salen){ /* special write to set address */ - ctlr->addr[0] = d->addr<<1; - i = 1; - if(d->salen > 1) - ctlr->addr[i++] = offset >> 8; - ctlr->addr[i] = offset; - } - DCFLUSH(ctlr->txbuf, Bufsize); - DCFLUSH(ctlr->rxbuf, Bufsize); - ilock(ctlr); - ctlr->phase = Recving; - ctlr->rd->addr = PADDR(ctlr->rxbuf); - ctlr->rd->status = BDEmpty|BDWrap|BDInt; - flag = 0; - td = ctlr->td; - td[1].status = 0; - if(d->salen){ - /* special select sequence */ - td->addr = PADDR(ctlr->addr); - i = d->salen+1; - if(i > 3) - i = 3; - td->length = i; - /* td->status made BDReady below */ - td++; - flag = TxS; - } - td->addr = PADDR(ctlr->txbuf); - td->length = n+1; - td->status = BDReady|BDWrap|BDLast | flag; /* not BDInt: leave that to receive */ - if(flag) - ctlr->td->status = BDReady; - enable(); - ctlr->i2c->i2com = STR|I2CM; - eieio(); - iunlock(ctlr); - i2cwait(ctlr); - disable(); - p = ctlr->phase; - s = ctlr->td->status; - if(flag) - s |= ctlr->td[1].status; - nr = ctlr->rd->length; - if(up){ - poperror(); - qunlock(&ctlr->io); - } - DPRINT("nr=%ld %4.4ux %8.8lux\n", nr, ctlr->rd->status, ctlr->rd->addr); - if(nr > n) - nr = n; /* shouldn't happen */ - if(s & TxERR){ - sprint(up->genbuf, "read: tx status: %.4ux", s); - return i2cerror(up->genbuf); - } - if(s & BDReady || ctlr->rd->status & BDEmpty) - return i2cerror("timed out"); - if(p != Done) - return i2cerror("phase error"); - memmove(buf, ctlr->rxbuf, nr); - if(Chatty){ - for(s=0; s<nr; s++) - print(" %2.2ux", ctlr->rxbuf[s]&0xFF); - print("\n"); - } - return nr; -} diff --git a/os/mpc/i2c_spi.srx b/os/mpc/i2c_spi.srx deleted file mode 100644 index 6587549d..00000000 --- a/os/mpc/i2c_spi.srx +++ /dev/null @@ -1,149 +0,0 @@ -S00600004844521B -S309022020007FFFEFD96E -S309022020043FFD000074 -S309022020087FFB49F7F2 -S3090220200C7FF9000030 -S309022020105FEFADF7B2 -S309022020145F89ADF714 -S309022020185FEFAFF7A8 -S3090220201C5F89AFF70A -S309022020203A9CFBC8FB -S30902202024E7C0EDF00C -S3090220202877C1E1BBB8 -S3090220202CF4DC7F1D1C -S30902202030ABAD932F6A -S309022020344E08FDCF5E -S309022020386E0FAFF858 -S3090220203C7CCF76CFE8 -S30902202040FD1FF9CF90 -S30902202044ABF88DC67A -S30902202048AB5679F7FB -S3090220204CB09373832F -S30902202050DFCE79F747 -S30902202054B091E6BB7E -S30902202058E5BBE74F86 -S3090220205CB3FA6F0F2D -S309022020606FFB76CEA6 -S30902202064EE0DF9CF8D -S309022020682BFBEFEF48 -S3090220206CCFEEF9CFC3 -S3090220207076CEAD242F -S3090220207490B2DF9A85 -S309022020787FDDD0BF51 -S3090220207C4BF847FDB1 -S309022020807CCF76CEA5 -S30902202084CFEF7E1FD5 -S309022020887F1D7DFD16 -S3090220208CF0B6EF7122 -S309022020907FC177C1AC -S30902202094FBC8607984 -S30902202098E722FBC850 -S3090220209C5FFFDFFFDC -S309022020A05FB2FFFB09 -S309022020A4FBC8F3C892 -S309022020A894A67F0152 -S309022020AC7F1D5F39D4 -S309022020B0AFE85F5EB0 -S309022020B4FFDFDF96AD -S309022020B8CB9FAF7D66 -S309022020BC5FC1AFED3C -S309022020C08C1C5FC12C -S309022020C4AFDD5FC342 -S309022020C8DF9A7EFDF8 -S309022020CCB0B25FB275 -S309022020D0FFFEABAD8F -S309022020D45FB2FFFED2 -S309022020D85FCE600B44 -S309022020DCE6BB600BCC -S309022020E05FCEDFC602 -S309022020E427FBEFDFE0 -S309022020E85FC8CFDEF8 -S309022020EC3A9CE7C04B -S309022020F0EDF0F3C82C -S309022020F47F0154CD1F -S309022020F87F1D2D3DB6 -S309022020FC363A757063 -S309022021007E0AF1CE6C -S3090220210437EF2E68F3 -S309022021087FEE10EC42 -S3090220210CADF8EFDE35 -S30902202110CFEAE52FD6 -S309022021147D0FE12B07 -S30902202118F1CE5F6518 -S3090220211C7E0A4DF8CA -S30902202120CFEA5F7209 -S309022021247D0BEFEE2A -S30902202128CFEA5F74FF -S3090220212CE522EFDEB3 -S309022021305F74CFDA07 -S309022021340B6273851A -S30902202138DF627E0AB2 -S3090220213C30D8145B00 -S30902202140BFFFF3C8FA -S309022021445FFFDFFF33 -S30902202148A7F85F5E0F -S3090220214CBFFE7F7DAE -S3090220215010D314501C -S309022021545F36BFFF0C -S30902202158AF785F5E77 -S3090220215CBFFDA7F8FC -S309022021605F36BFFE01 -S3090220216477FD30C0EB -S309022021684E08FDCF29 -S3090220216CE5FF6E0FE6 -S30902202170AFF87E1FFF -S309022021747E0FFD1F96 -S30902202178F1CF5F1B01 -S3090220217CABF80D5E29 -S309022021805F5EFFEF88 -S3090220218479F730A2ED -S30902202188AFDD5F340C -S3090220218C47F85F3455 -S30902202190AFED7FDD2B -S3090220219450B249785C -S3090220219847FD7F1D3B -S3090220219C7DFD70AD80 -S309022021A0EF717EC174 -S309022021A46BA47F0180 -S309022021A82D267EFD3D -S309022021AC30DE5F5E3C -S309022021B0FFFD5F5E4A -S309022021B4FFEF5F5E54 -S309022021B8FFDF0CA071 -S309022021BCAFED0A9EB3 -S309022021C0AFDD0C3A21 -S309022021C45F3AAFBDEA -S309022021C87FBDB0827D -S309022021CC5F8247F8C7 -S9030000FC -S00600004844521B -S30902202F003E303430D3 -S30902202F0434343737CB -S30902202F08ABF7BF9BA1 -S30902202F0C994B4FBDA9 -S30902202F10BD59949358 -S30902202F14349FFF3788 -S30902202F18FB9B177D63 -S30902202F1CD99369565E -S30902202F20BBFDD69760 -S30902202F24BDD2FD11E4 -S30902202F2831DB9BB323 -S30902202F2C6313963736 -S30902202F3093733693A6 -S30902202F34193137F7F9 -S30902202F38331737AF3D -S30902202F3C7BB9B999E3 -S30902202F40BB197957C1 -S30902202F447FDFD3D55B -S30902202F4873B773F7C9 -S30902202F4C37933B99BB -S30902202F501D115316BE -S30902202F54993153151F -S30902202F5831694BF474 -S30902202F5CFBDBD35947 -S30902202F603149735305 -S30902202F6476956D6960 -S30902202F687B9D9693FC -S30902202F6C1313197981 -S30902202F7079376935E7 -S9030000FC
\ No newline at end of file diff --git a/os/mpc/inb.s b/os/mpc/inb.s deleted file mode 100644 index 4dcd7fe4..00000000 --- a/os/mpc/inb.s +++ /dev/null @@ -1,120 +0,0 @@ -#include "mem.h" - -#define BDNZ BC 16,0, - -TEXT inb(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVBZ (R3), R3 - RETURN - -TEXT insb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $1, R4 -insb1: - EIEIO - MOVBZ (R3), R7 - MOVBU R7, 1(R4) - BDNZ insb1 - RETURN - -TEXT outb(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVB R4, (R3) - RETURN - -TEXT outsb(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $1, R4 -outsb1: - EIEIO - MOVBZU 1(R4), R7 - MOVB R7, (R3) - BDNZ outsb1 - RETURN - -TEXT ins(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVHBR (R3), R3 - RETURN - -TEXT inss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $2, R4 -inss1: - EIEIO - MOVHZ (R3), R7 - MOVHU R7, 2(R4) - BDNZ inss1 - RETURN - -TEXT outs(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVHBR R4, (R3) - RETURN - -TEXT outss(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $2, R4 -outss1: - EIEIO - MOVHZU 2(R4), R7 - MOVH R7, (R3) - BDNZ outss1 - RETURN - -TEXT inl(SB), $0 - OR $ISAIO, R3 - EIEIO - MOVWBR (R3), R3 - RETURN - -TEXT insl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $4, R4 -insl1: - EIEIO - MOVW (R3), R7 - MOVWU R7, 4(R4) - BDNZ insl1 - RETURN - -TEXT outl(SB), $0 - MOVW v+4(FP), R4 - OR $ISAIO, R3 - EIEIO - MOVWBR R4, (R3) - RETURN - -TEXT outsl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - MOVW R5, CTR - OR $ISAIO, R3 - SUB $4, R4 -outsl1: - EIEIO - MOVWU 4(R4), R7 - MOVW R7, (R3) - BDNZ outsl1 - RETURN diff --git a/os/mpc/kbd.c b/os/mpc/kbd.c deleted file mode 100644 index 81e2384c..00000000 --- a/os/mpc/kbd.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -/* - * initialise the keyboard Queue if uartinstall hasn't already done so - */ -void -kbdinit(void) -{ - if(kbdq == nil){ - kbdq = qopen(4*1024, 0, 0, 0); - qnoblock(kbdq, 1); - } - archkbdinit(); -} diff --git a/os/mpc/l.s b/os/mpc/l.s deleted file mode 100644 index 8a2ae66d..00000000 --- a/os/mpc/l.s +++ /dev/null @@ -1,685 +0,0 @@ -#include "mem.h" - -#define MB (1024*1024) - -/* - * options - */ -#undef MMUTWC /* we don't map enough memory to need table walk */ -#undef SHOWCYCLE /* might be needed for BDM debugger to keep control */ - -/* - * common ppc special purpose registers - */ -#define DSISR 18 -#define DAR 19 /* Data Address Register */ -#define DEC 22 /* Decrementer */ -#define SRR0 26 /* Saved Registers (exception) */ -#define SRR1 27 -#define SPRG0 272 /* Supervisor Private Registers */ -#define SPRG1 273 -#define SPRG2 274 -#define SPRG3 275 -#define TBRU 269 /* Time base Upper/Lower (Reading) */ -#define TBRL 268 -#define TBWU 285 /* Time base Upper/Lower (Writing) */ -#define TBWL 284 -#define PVR 287 /* Processor Version */ - -/* - * mpc8xx-specific special purpose registers of interest here - */ -#define EIE 80 -#define EID 81 -#define NRI 82 -#define IMMR 638 -#define IC_CSR 560 -#define IC_ADR 561 -#define IC_DAT 562 -#define DC_CSR 568 -#define DC_ADR 569 -#define DC_DAT 570 -#define MI_CTR 784 -#define MI_AP 786 -#define MI_EPN 787 -#define MI_TWC 789 -#define MI_RPN 790 -#define MI_DBCAM 816 -#define MI_DBRAM0 817 -#define MI_DBRAM1 818 -#define MD_CTR 792 -#define M_CASID 793 -#define MD_AP 794 -#define MD_EPN 795 -#define M_TWB 796 -#define MD_TWC 797 -#define MD_RPN 798 -#define M_TW 799 -#define MD_DBCAM 824 -#define MD_DBRAM0 825 -#define MD_DBRAM1 826 - -/* use of SPRG registers in save/restore */ -#define SAVER0 SPRG0 -#define SAVER1 SPRG1 -#define SAVELR SPRG2 -#define SAVEXX SPRG3 - -/* special instruction definitions */ -#define BDNZ BC 16,0, -#define BDNE BC 0,2, -#define TLBIA WORD $((31<<26)|(370<<1)) -#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1)) - -/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ -#define MSRSYNC SYNC; ISYNC - -#define UREGSPACE (UREGSIZE+8) - -/* could define STEP to set an LED to mark progress */ -#define STEP(x) - -/* - * Boot first processor - */ - TEXT start(SB), $-4 - - MOVW MSR, R3 - RLWNM $0, R3, $~EE, R3 - RLWNM $0, R3, $~FPE, R3 - OR $ME, R3 - ISYNC - MOVW R3, MSR /* turn off interrupts but enable traps */ - MSRSYNC - MOVW $0, R0 /* except during trap handling, R0 is zero from now on */ - MOVW R0, CR - MOVW $setSB(SB), R2 - -/* - * reset the caches and disable them for now - */ - MOVW SPR(IC_CSR), R4 /* read and clear */ - MOVW $(5<<25), R4 - MOVW R4, SPR(IC_CSR) /* unlock all */ - ISYNC - MOVW $(6<<25), R4 - MOVW R4, SPR(IC_CSR) /* invalidate all */ - ISYNC - MOVW $(2<<25), R4 - MOVW R4, SPR(IC_CSR) /* disable i-cache */ - ISYNC - - SYNC - MOVW SPR(DC_CSR), R4 /* read and clear */ - MOVW $(10<<24), R4 - SYNC - MOVW R4, SPR(DC_CSR) /* unlock all */ - ISYNC - MOVW $(12<<24), R4 - SYNC - MOVW R4, SPR(DC_CSR) /* invalidate all */ - ISYNC - MOVW $(4<<24), R4 - SYNC - MOVW R4, SPR(DC_CSR) /* disable d-cache */ - ISYNC - -#ifdef SHOWCYCLE - MOVW $0, R4 -#else - MOVW $7, R4 -#endif - MOVW R4, SPR(158) /* cancel `show cycle' for normal instruction execution */ - ISYNC - -/* - * set other system configuration values - */ - MOVW $PHYSIMM, R4 - MOVW R4, SPR(IMMR) /* set internal memory base */ - -STEP(1) - - BL kernelmmu(SB) - -STEP(2) - /* no kfpinit on 82x */ - - MOVW $mach0(SB), R(MACH) - ADD $(MACHSIZE-8), R(MACH), R1 - SUB $4, R(MACH), R3 - ADD $4, R1, R4 -clrmach: - MOVWU R0, 4(R3) - CMP R3, R4 - BNE clrmach - - MOVW R0, R(USER) - MOVW R0, 0(R(MACH)) - - MOVW $edata(SB), R3 - MOVW $end(SB), R4 - ADD $4, R4 - SUB $4, R3 -clrbss: - MOVWU R0, 4(R3) - CMP R3, R4 - BNE clrbss - -STEP(3) - BL main(SB) - BR 0(PC) - -TEXT kernelmmu(SB), $0 - TLBIA - ISYNC - - MOVW $0, R4 - MOVW R4, SPR(M_CASID) /* set supervisor space */ - MOVW $(0<<29), R4 /* allow i-cache when IR=0 */ - MOVW R4, SPR(MI_CTR) /* i-mmu control */ - ISYNC - MOVW $((1<<29)|(1<<28)), R4 /* cache inhibit when DR=0, write-through */ - SYNC - MOVW R4, SPR(MD_CTR) /* d-mmu control */ - ISYNC - TLBIA - - /* map various things 1:1 */ - MOVW $tlbtab-KZERO(SB), R4 - MOVW $tlbtabe-KZERO(SB), R5 - SUB R4, R5 - MOVW $(3*4), R6 - DIVW R6, R5 - SUB $4, R4 - MOVW R5, CTR -ltlb: - MOVWU 4(R4), R5 - MOVW R5, SPR(MD_EPN) - MOVW R5, SPR(MI_EPN) - MOVWU 4(R4), R5 - MOVW R5, SPR(MI_TWC) - MOVW R5, SPR(MD_TWC) - MOVWU 4(R4), R5 - MOVW R5, SPR(MD_RPN) - MOVW R5, SPR(MI_RPN) - BDNZ ltlb - - MOVW $(1<<25), R4 - MOVW R4, SPR(IC_CSR) /* enable i-cache */ - ISYNC - - MOVW $(3<<24), R4 - SYNC - MOVW R4, SPR(DC_CSR) /* clear force write through mode */ - MOVW $(2<<24), R4 - SYNC - MOVW R4, SPR(DC_CSR) /* enable d-cache */ - ISYNC - - /* enable MMU and set kernel PC to virtual space */ - MOVW $((0<<29)|(0<<28)), R4 /* cache when DR=0, write back */ - SYNC - MOVW R4, SPR(MD_CTR) /* d-mmu control */ - MOVW LR, R3 - OR $KZERO, R3 - MOVW R3, SPR(SRR0) - MOVW MSR, R4 - OR $(ME|IR|DR), R4 /* had ME|FPE|FE0|FE1 */ - MOVW R4, SPR(SRR1) - RFI /* resume in kernel mode in caller */ - -TEXT splhi(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $~EE, R4 - SYNC - MOVW R4, MSR - MSRSYNC - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ - RETURN - -TEXT splx(SB), $0 - MOVW MSR, R4 - RLWMI $0, R3, $EE, R4 - RLWNMCC $0, R3, $EE, R5 - BNE splx0 - MOVW LR, R31 - MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ -splx0: - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT splxpc(SB), $0 - MOVW MSR, R4 - RLWMI $0, R3, $EE, R4 - RLWNMCC $0, R3, $EE, R5 - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spllo(SB), $0 - MFTB(TBRL, 3) - MOVW R3, spltbl(SB) - MOVW MSR, R3 - OR $EE, R3, R4 - SYNC - MOVW R4, MSR - MSRSYNC - RETURN - -TEXT spldone(SB), $0 - RETURN - -TEXT islo(SB), $0 - MOVW MSR, R3 - RLWNM $0, R3, $EE, R3 - RETURN - -TEXT setlabel(SB), $-4 - MOVW LR, R31 - MOVW R1, 0(R3) - MOVW R31, 4(R3) - MOVW $0, R3 - RETURN - -TEXT gotolabel(SB), $-4 - MOVW 4(R3), R31 - MOVW R31, LR - MOVW 0(R3), R1 - MOVW $1, R3 - RETURN - -/* - * enter with stack set and mapped. - * on return, SB (R2) has been set, and R3 has the Ureg*, - * the MMU has been re-enabled, kernel text and PC are in KSEG, - * R(MACH) has been set, and R0 contains 0. - * - * this can be simplified in the Inferno regime - */ -TEXT saveureg(SB), $-4 -/* - * save state - */ - MOVMW R2, 48(R1) /* r2:r31 */ - MOVW $setSB(SB), R2 - MOVW SPR(SAVER1), R4 - MOVW R4, 44(R1) - MOVW SPR(SAVER0), R5 - MOVW R5, 40(R1) - MOVW CTR, R6 - MOVW R6, 36(R1) - MOVW XER, R4 - MOVW R4, 32(R1) - MOVW CR, R5 - MOVW R5, 28(R1) - MOVW SPR(SAVELR), R6 /* LR */ - MOVW R6, 24(R1) - /* pad at 20(R1) */ - /* old PC(16) and status(12) saved earlier */ - MOVW SPR(SAVEXX), R0 - MOVW R0, 8(R1) /* cause/vector */ - ADD $8, R1, R3 /* Ureg* */ - STWCCC R3, (R1) /* break any pending reservations */ - MOVW $0, R0 /* compiler/linker expect R0 to be zero */ - - MOVW MSR, R5 - OR $(IR|DR), R5 /* enable MMU */ - MOVW R5, SPR(SRR1) - MOVW LR, R31 - OR $KZERO, R31 /* return PC in KSEG0 */ - MOVW R31, SPR(SRR0) - SYNC - ISYNC - RFI /* returns to trap handler */ - -TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -icf0: ICBI (R5) - ADD $CACHELINESZ, R5 - BDNZ icf0 - ISYNC - RETURN - -/* - * flush to store and invalidate globally - */ -TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ - SYNC - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - CMP R4, $0 - BLE dcf1 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -dcf0: DCBF (R5) - ADD $CACHELINESZ, R5 - BDNZ dcf0 - SYNC - ISYNC -dcf1: - RETURN - -/* - * invalidate without flush, globally - */ -TEXT dcinval(SB), $-4 /* dcinval(virtaddr, count) */ - SYNC - MOVW n+4(FP), R4 - RLWNM $0, R3, $~(CACHELINESZ-1), R5 - CMP R4, $0 - BLE dci1 - SUB R5, R3 - ADD R3, R4 - ADD $(CACHELINESZ-1), R4 - SRAW $CACHELINELOG, R4 - MOVW R4, CTR -dci0: DCBI (R5) - ADD $CACHELINESZ, R5 - BDNZ dci0 - SYNC - ISYNC -dci1: - RETURN - -TEXT _tas(SB), $0 - SYNC - MOVW R3, R4 - MOVW $0xdeaddead,R5 -tas1: - DCBF (R4) /* fix for 603x bug */ - LWAR (R4), R3 - CMP R3, $0 - BNE tas0 - STWCCC R5, (R4) - BNE tas1 -tas0: - SYNC - ISYNC - RETURN - -TEXT gettbl(SB), $0 - MFTB(TBRL, 3) - RETURN - -TEXT gettbu(SB), $0 - MFTB(TBRU, 3) - RETURN - -TEXT getpvr(SB), $0 - MOVW SPR(PVR), R3 - RETURN - -TEXT getimmr(SB), $0 - MOVW SPR(IMMR), R3 - RETURN - -TEXT getdec(SB), $0 - MOVW SPR(DEC), R3 - RETURN - -TEXT putdec(SB), $0 - MOVW R3, SPR(DEC) - RETURN - -TEXT getcallerpc(SB), $-4 - MOVW 0(R1), R3 - RETURN - -TEXT getdar(SB), $0 - MOVW SPR(DAR), R3 - RETURN - -TEXT getdsisr(SB), $0 - MOVW SPR(DSISR), R3 - RETURN - -TEXT getdepn(SB), $0 - MOVW SPR(MD_EPN), R3 - RETURN - -TEXT getmsr(SB), $0 - MOVW MSR, R3 - RETURN - -TEXT putmsr(SB), $0 - SYNC - MOVW R3, MSR - MSRSYNC - RETURN - -TEXT eieio(SB), $0 - EIEIO - RETURN - -TEXT gotopc(SB), $0 - MOVW R3, CTR - MOVW LR, R31 /* for trace back */ - BR (CTR) - -TEXT firmware(SB), $0 - MOVW MSR, R3 - MOVW $(EE|ME), R4 - ANDN R4, R3 - OR $(MSR_IP), R3 - ISYNC - MOVW R3, MSR /* turn off interrupts and machine checks */ - MSRSYNC - MOVW $(RI|IR|DR|ME), R4 - ANDN R4, R3 - MOVW R3, SPR(SRR1) - MOVW $(0xFF00<<16), R4 - MOVW R4, SPR(IMMR) - MOVW $(0x0800<<16), R4 - MOVW R4, SPR(SRR0) /* force bad address */ - MOVW R0, SPR(149) /* ensure checkstop on machine check */ - MOVW R4, R1 - MOVW R4, R2 - EIEIO - ISYNC - RFI - -/* - * byte swapping of arrays of long and short; - * could possibly be avoided with more changes to drivers - */ -TEXT swabl(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $2, R5, R5 - MOVW R5, CTR - SUB $4, R4 - SUB $4, R3 -swabl1: - ADD $4, R3 - MOVWU 4(R4), R7 - MOVWBR R7, (R3) - BDNZ swabl1 - RETURN - -TEXT swabs(SB), $0 - MOVW v+4(FP), R4 - MOVW n+8(FP), R5 - SRAW $1, R5, R5 - MOVW R5, CTR - SUB $2, R4 - SUB $2, R3 -swabs1: - ADD $2, R3 - MOVHZU 2(R4), R7 - MOVHBR R7, (R3) - BDNZ swabs1 - RETURN - -TEXT legetl(SB), $0 - MOVWBR (R3), R3 - RETURN - -TEXT lesetl(SB), $0 - MOVW v+4(FP), R4 - MOVWBR R4, (R3) - RETURN - -TEXT legets(SB), $0 - MOVHBR (R3), R3 - RETURN - -TEXT lesets(SB), $0 - MOVW v+4(FP), R4 - MOVHBR R4, (R3) - RETURN - -#ifdef MMUTWC -/* - * ITLB miss - * avoid references that might need the right SB value; - * IR and DR are off. - */ -TEXT itlbmiss(SB), $-4 - MOVW R1, SPR(M_TW) - MOVW SPR(SRR0), R1 /* instruction miss address */ - MOVW R1, SPR(MD_EPN) - MOVW SPR(M_TWB), R1 /* level one pointer */ - MOVW (R1), R1 - MOVW R1, SPR(MI_TWC) /* save level one attributes */ - MOVW R1, SPR(MD_TWC) /* save base and attributes */ - MOVW SPR(MD_TWC), R1 /* level two pointer */ - MOVW (R1), R1 /* level two entry */ - MOVW R1, SPR(MI_RPN) /* write TLB */ - MOVW SPR(M_TW), R1 - RFI - -/* - * DTLB miss - * avoid references that might need the right SB value; - * IR and DR are off. - */ -TEXT dtlbmiss(SB), $-4 - MOVW R1, SPR(M_TW) - MOVW SPR(M_TWB), R1 /* level one pointer */ - MOVW (R1), R1 /* level one entry */ - MOVW R1, SPR(MD_TWC) /* save base and attributes */ - MOVW SPR(MD_TWC), R1 /* level two pointer */ - MOVW (R1), R1 /* level two entry */ - MOVW R1, SPR(MD_RPN) /* write TLB */ - MOVW SPR(M_TW), R1 - RFI -#else -TEXT itlbmiss(SB), $-4 - BR traps -TEXT dtlbmiss(SB), $-4 - BR traps -#endif - -/* - * traps force memory mapping off. - * this code goes to too much effort (for the Inferno environment) to restore it. - */ -TEXT trapvec(SB), $-4 -traps: - MOVW LR, R0 - -pagefault: - -/* - * map data virtually and make space to save - */ - MOVW R0, SPR(SAVEXX) /* vector */ - MOVW R1, SPR(SAVER1) - SYNC - ISYNC - MOVW MSR, R0 - OR $(DR|ME), R0 /* make data space usable */ - SYNC - MOVW R0, MSR - MSRSYNC - SUB $UREGSPACE, R1 - - MOVW SPR(SRR0), R0 /* save SRR0/SRR1 now, since DLTB might be missing stack page */ - MOVW R0, LR - MOVW SPR(SRR1), R0 - MOVW R0, 12(R1) /* save status: could take DLTB miss here */ - MOVW LR, R0 - MOVW R0, 16(R1) /* old PC */ - BL saveureg(SB) - BL trap(SB) - BR restoreureg - -TEXT intrvec(SB), $-4 - MOVW LR, R0 - -/* - * map data virtually and make space to save - */ - MOVW R0, SPR(SAVEXX) /* vector */ - MOVW R1, SPR(SAVER1) - SYNC - ISYNC - MOVW MSR, R0 - OR $DR, R0 /* make data space usable */ - SYNC - MOVW R0, MSR - MSRSYNC - SUB $UREGSPACE, R1 - - MFTB(TBRL, 0) - MOVW R0, intrtbl(SB) - - MOVW SPR(SRR0), R0 - MOVW R0, LR - MOVW SPR(SRR1), R0 - MOVW R0, 12(R1) - MOVW LR, R0 - MOVW R0, 16(R1) - BL saveureg(SB) - - MFTB(TBRL, 5) - MOVW R5, isavetbl(SB) - - BL intr(SB) - -/* - * restore state from Ureg and return from trap/interrupt - */ -restoreureg: - MOVMW 48(R1), R2 /* r2:r31 */ - /* defer R1 */ - MOVW 40(R1), R0 - MOVW R0, SPR(SAVER0) - MOVW 36(R1), R0 - MOVW R0, CTR - MOVW 32(R1), R0 - MOVW R0, XER - MOVW 28(R1), R0 - MOVW R0, CR /* CR */ - MOVW 24(R1), R0 - MOVW R0, SPR(SAVELR) /* LR */ - /* pad, skip */ - MOVW 16(R1), R0 - MOVW R0, SPR(SRR0) /* old PC */ - MOVW 12(R1), R0 - MOVW R0, SPR(SRR1) /* old MSR */ - /* cause, skip */ - MOVW 44(R1), R1 /* old SP */ - MOVW SPR(SAVELR), R0 - MOVW R0, LR - MOVW SPR(SAVER0), R0 - RFI - -GLOBL mach0+0(SB), $MACHSIZE -GLOBL spltbl+0(SB), $4 -GLOBL intrtbl+0(SB), $4 -GLOBL isavetbl+0(SB), $4 diff --git a/os/mpc/nofp.s b/os/mpc/nofp.s deleted file mode 100644 index f23d49b0..00000000 --- a/os/mpc/nofp.s +++ /dev/null @@ -1,31 +0,0 @@ -/* - * stubs when no floating-point hardware - */ - -TEXT kfpinit(SB), $0 - RETURN - -TEXT getfpscr(SB), $8 - MOVW $0, R3 - RETURN - -TEXT fpsave(SB), $0 - RETURN - -TEXT fprestore(SB), $0 - RETURN - -TEXT clrfptrap(SB), $0 - RETURN - -TEXT fpinit(SB), $0 - RETURN - -TEXT fpoff(SB), $0 - RETURN - -TEXT FPsave(SB), 1, $0 - RETURN - -TEXT FPrestore(SB), 1, $0 - RETURN diff --git a/os/mpc/pcmcia.h b/os/mpc/pcmcia.h deleted file mode 100644 index 2e22042f..00000000 --- a/os/mpc/pcmcia.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * PCMCIA support code. - */ -int inb(int); -int inb(int); -ulong inl(int); -ushort ins(int); -void insb(int, void*, int); -void insl(int, void*, int); -void inss(int, void*, int); -void outb(int, int); -void outl(int, ulong); -void outs(int, ushort); -void outsb(int, void*, int); -void outsl(int, void*, int); -void outss(int, void*, int); -void pcmintrenable(int, void(*)(Ureg*,void*), void*); -int pcmspecial(char*, ISAConf*); -void pcmspecialclose(int); diff --git a/os/mpc/pit.c b/os/mpc/pit.c deleted file mode 100644 index bfc8bc8d..00000000 --- a/os/mpc/pit.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * programmable interrupt timer - */ - -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "ureg.h" - -enum { - /* piscr */ - PTE = 1<<0, - PITF = 1<<1, - PIE = 1<<2, - PS = 1<<7, -}; - -static void -pitinterrupt(Ureg*, void*) -{ - IMM *io; - - io = m->iomem; - if(io->piscr & PS){ - io->piscr |= PS; /* clear by writing 1 */ - /* do whatever is required */ - } -} - -static void -pitreset(void) -{ - IMM *io; - - io = ioplock(); - io->piscrk = KEEP_ALIVE_KEY; - io->piscr = (PITlevel<<8) | PS | PITF; - if(0) - io->piscrk = ~KEEP_ALIVE_KEY; - /* piscrk is left unlocked for interrupt routine */ - iopunlock(); - intrenable(PITlevel, pitinterrupt, nil, BUSUNKNOWN, "pit"); -} - -static ulong -pitload(ulong usec) -{ - IMM *io; - ulong v; - - v = ((usec*m->oscclk)/512); - if(v == 0 || v >= (1<<16)) - return 0; /* can't do */ - io = ioplock(); - io->pitck = KEEP_ALIVE_KEY; - io->pitc = (v-1)<<16; - io->pitck = ~KEEP_ALIVE_KEY; - io->piscrk = KEEP_ALIVE_KEY; - io->piscr = (PITlevel<<8) | PS | PIE | PITF | PTE; - if(0) - io->piscrk = ~KEEP_ALIVE_KEY; - /* piscrk is left unlocked for interrupt routine */ - iopunlock(); - return (v*512)/m->oscclk; -} diff --git a/os/mpc/powerbreak.c b/os/mpc/powerbreak.c deleted file mode 100644 index fc5970ef..00000000 --- a/os/mpc/powerbreak.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "ureg.h" - -extern int (*breakhandler)(Ureg *ur, Proc*); /* trap.c */ -extern Instr BREAK; /* trap.c */ -extern void portbreakinit(void); - -#define getop(i) ((i>>26)&0x3F) -#define getxo(i) ((i>>1)&0x3FF) -#define getbobi(i) bo = (i>>21)&0x1f; bi = (i>>16)&0x1f; xx = (i>>11)&0x1f; - -void -machbreakinit(void) -{ - portbreakinit(); - breakhandler = breakhit; -} - -Instr -machinstr(ulong addr) -{ - if (addr < KTZERO) - error(Ebadarg); - return *(Instr*)addr; -} - -void -machbreakset(ulong addr) -{ - if (addr < KTZERO) - error(Ebadarg); - *(Instr*)addr = BREAK; - segflush((void*)addr, sizeof(Instr)); -} - -void -machbreakclear(ulong addr, Instr i) -{ - if (addr < KTZERO) - error(Ebadarg); - *(Instr*)addr = i; - segflush((void*)addr, sizeof(Instr)); -} - -static int -condok(Ureg *ur, ulong ir, int ctrok) -{ - int bo, bi, xx; - ulong ctrval; - - ctrval = ur->ctr; - getbobi(ir); - if(xx) - return 0; /* illegal */ - if((bo & 0x4) == 0) { - if(!ctrok) - return 0; /* illegal */ - ctrval--; - } - if(bo & 0x4 || (ctrval!=0)^((bo>>1)&1)) { - if(bo & 0x10 || (((ur->cr & (1L<<(31-bi))!=0)==((bo>>3)&1)))) - return 1; - } - return 0; -} - -/* - * Return the address of the instruction that will be executed after the - * instruction at ur->pc, accounting for current branch conditions. - */ -ulong -machnextaddr(Ureg *ur) -{ - long imm; - ulong ir; - - ir = *(ulong*)ur->pc; - switch(getop(ir)) { - case 18: /* branch */ - imm = ir & 0x03FFFFFC; - if(ir & 0x02000000) - imm |= 0xFC000000; /* sign extended */ - if((ir & 2) == 0) /* relative address */ - return ur->pc + imm; - return imm; - - case 16: /* conditional branch */ - if(condok(ur, ir&0xFFFF0000, 1)){ - imm = ir & 0xFFFC; - if(ir & 0x08000) - imm |= 0xFFFF0000; /* sign extended */ - if((ir & 2) == 0) /* relative address */ - return ur->pc + imm; - return imm; - } - break; - - case 19: /* conditional branch to register */ - switch(getxo(ir)){ - case 528: /* bcctr */ - if(condok(ur, ir, 0)) - return ur->ctr & ~3; - break; - case 16: /* bclr */ - if(condok(ur, ir, 1)) - return ur->lr & ~3; - break; - } - break; - } - return ur->pc+4; /* next instruction */ -} - -int -isvalid_va(void *v) -{ - return (ulong)v >= KTZERO; -} diff --git a/os/mpc/rmap.c b/os/mpc/rmap.c deleted file mode 100644 index f521c24d..00000000 --- a/os/mpc/rmap.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "u.h" -#include "lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" - -void -mapinit(RMap *rmap, Map *map, int size) -{ - lock(rmap); - rmap->map = map; - rmap->mapend = map+(size/sizeof(Map)); - unlock(rmap); -} - -void -mapfree(RMap* rmap, ulong addr, int size) -{ - Map *mp; - ulong t; - - if(size <= 0) - return; - - lock(rmap); - for(mp = rmap->map; mp->addr <= addr && mp->size; mp++) - ; - - if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){ - (mp-1)->size += size; - if(addr+size == mp->addr){ - (mp-1)->size += mp->size; - while(mp->size){ - mp++; - (mp-1)->addr = mp->addr; - (mp-1)->size = mp->size; - } - } - } - else{ - if(addr+size == mp->addr && mp->size){ - mp->addr -= size; - mp->size += size; - } - else do{ - if(mp >= rmap->mapend){ - print("mapfree: %s: losing 0x%luX, %d\n", - rmap->name, addr, size); - break; - } - t = mp->addr; - mp->addr = addr; - addr = t; - t = mp->size; - mp->size = size; - mp++; - }while(size = t); - } - unlock(rmap); -} - -ulong -rmapalloc(RMap* rmap, ulong addr, int size, int align) -{ - Map *mp; - ulong maddr, oaddr; - - lock(rmap); - for(mp = rmap->map; mp->size; mp++){ - maddr = mp->addr; - - if(addr){ - if(maddr > addr) - break; - if(maddr+mp->size < addr) - continue; - if(addr+size > maddr+mp->size) - break; - maddr = addr; - } - - if(align > 0) - maddr = ((maddr+align-1)/align)*align; - if(mp->addr+mp->size-maddr < size) - continue; - - oaddr = mp->addr; - mp->addr = maddr+size; - mp->size -= maddr-oaddr+size; - if(mp->size == 0){ - do{ - mp++; - (mp-1)->addr = mp->addr; - }while((mp-1)->size = mp->size); - } - - unlock(rmap); - if(oaddr != maddr) - mapfree(rmap, oaddr, maddr-oaddr); - - return maddr; - } - unlock(rmap); - - return 0; -} diff --git a/os/mpc/screen.c b/os/mpc/screen.c deleted file mode 100644 index 59fff7f6..00000000 --- a/os/mpc/screen.c +++ /dev/null @@ -1,832 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include <draw.h> -#include <memdraw.h> -#include <cursor.h> - -#include "screen.h" - -enum { - Backgnd = 0xFF, /* white */ - Foregnd = 0x00, /* black */ -}; - -Cursor arrow = { - { -1, -1 }, - { 0xFF, 0xFF, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0C, - 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, - 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8C, 0x04, - 0x92, 0x08, 0x91, 0x10, 0xA0, 0xA0, 0xC0, 0x40, - }, - { 0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF0, - 0x7F, 0xE0, 0x7F, 0xE0, 0x7F, 0xF0, 0x7F, 0xF8, - 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFC, 0x73, 0xF8, - 0x61, 0xF0, 0x60, 0xE0, 0x40, 0x40, 0x00, 0x00, - }, -}; - -static Memdata xgdata; -static Memimage xgscreen = -{ - {0, 0, 0, 0}, /* r */ - {0, 0, 0, 0}, /* clipr */ - 8, /* depth */ - 1, /* nchan */ - CMAP8, /* chan */ - nil, /* cmap */ - &xgdata, /* data */ - 0, /* zero */ - 0, /* width */ - nil, /* layer */ - 0, /* flags */ -}; - -int novgascreen; /* optionally set by configuration file */ -static int lcdpdpar; /* value to load into io->pdpar */ - -Memimage *gscreen; -Memimage *conscol; -Memimage *back; - -static Memsubfont *memdefont; -static Lock palettelock; /* access to DAC registers */ -static Lock screenlock; -static int h; -static Point curpos; -static Rectangle window; - -typedef struct SWcursor SWcursor; -static SWcursor *swc = nil; -SWcursor* swcurs_create(ulong *, int, int, Rectangle, int); -void swcurs_destroy(SWcursor*); -void swcurs_enable(SWcursor*); -void swcurs_disable(SWcursor*); -void swcurs_hide(SWcursor*); -void swcurs_unhide(SWcursor*); -void swcurs_load(SWcursor*, Cursor*); - -static void screenputc(char*); -static void scroll(void); -static void setscreen(Mode*); -static void cursorlock(Rectangle); -static void cursorunlock(void); -static void lcdinit(Mode*); -static void lcdsetrgb(int, ulong, ulong, ulong); - -/* - * Called by main(). - */ -void -screeninit(void) -{ - Mode m; - -novgascreen=1; return; - - /* default size and parameters */ - memset(&m.lcd, 0, sizeof(m.lcd)); - m.x = 640; - m.y = 480; - m.d = 3; - if(novgascreen == 0 && archlcdmode(&m) >= 0){ - memdefont = getmemdefont(); - setscreen(&m); - } -} - -/* - * On 8 bit displays, load the default color map - */ -void -graphicscmap(int invert) -{ - int num, den, i, j; - int r, g, b, cr, cg, cb, v; - - for(r=0,i=0;r!=4;r++) for(v=0;v!=4;v++,i+=16){ - for(g=0,j=v-r;g!=4;g++) for(b=0;b!=4;b++,j++){ - den=r; - if(g>den) den=g; - if(b>den) den=b; - if(den==0) /* divide check -- pick grey shades */ - cr=cg=cb=v*17; - else{ - num=17*(4*den+v); - cr=r*num/den; - cg=g*num/den; - cb=b*num/den; - } - if(invert) - setcolor(255-i-(j&15), - cr*0x01010101, cg*0x01010101, cb*0x01010101); - else - setcolor(i+(j&15), - cr*0x01010101, cg*0x01010101, cb*0x01010101); - } - } -} - -/* - * reconfigure screen shape - */ -static void -setscreen(Mode *mode) -{ - int h; - - if(swc) - swcurs_destroy(swc); - - gscreen = &xgscreen; - xgdata.ref = 1; - lcdinit(mode); - xgdata.bdata = (uchar*)mode->aperture; - if(xgdata.bdata == nil) - panic("setscreen: vga soft memory"); - - gscreen->r = Rect(0, 0, mode->x, mode->y); - gscreen->clipr = gscreen->r; - gscreen->depth = 1<<mode->d; - gscreen->width = wordsperline(gscreen->r, gscreen->depth); - memimageinit(); - memdefont = getmemdefont(); - - memsetchan(gscreen, CMAP8); - back = memwhite; - conscol = memblack; - memimagedraw(gscreen, gscreen->r, memwhite, ZP, memopaque, ZP, SoverD); - graphicscmap(0); - - /* get size for a system window */ - h = memdefont->height; - window = insetrect(gscreen->r, 4); - window.max.y = window.min.y+(Dy(window)/h)*h; - curpos = window.min; -// screenclear(); - - graphicscmap(0); - -// swc = swcurs_create(gscreendata.data, gscreen.width, gscreen.ldepth, gscreen.r, 1); - - drawcursor(nil); -} - -enum { - ScreenCached = 1 /* non-zero if screen region not write-through */ -}; - -void -flushmemscreen(Rectangle r) -{ - if(rectclip(&r, gscreen->r) == 0) - return; - if(r.min.x >= r.max.x || r.min.y >= r.max.y) - return; - if(ScreenCached) - dcflush((ulong*)gscreen->data->bdata + gscreen->width*r.min.y, gscreen->width*Dy(r)); -} - -/* - * export screen to interpreter - */ -uchar* -attachscreen(Rectangle *r, ulong *chan, int* d, int *width, int *softscreen) -{ - *r = gscreen->r; - *d = gscreen->depth; - *chan = gscreen->chan; - *width = gscreen->width; - *softscreen = ScreenCached; - - return (uchar*)gscreen->data->bdata; -} - -void -detachscreen(void) -{ -} - -/* - * write a string to the screen - */ -void -screenputs(char *s, int n) -{ - int i; - Rune r; - char buf[4]; - - if(novgascreen || xgdata.bdata == nil || memdefont == nil) - return; - if(islo() == 0) { - /* don't deadlock trying to print in interrupt */ - if(!canlock(&screenlock)) - return; - } else - lock(&screenlock); - - while(n > 0) { - i = chartorune(&r, s); - if(i == 0){ - s++; - --n; - continue; - } - memmove(buf, s, i); - buf[i] = 0; - n -= i; - s += i; - screenputc(buf); - } - /* Only OK for now */ - flushmemscreen(gscreen->r); - - unlock(&screenlock); -} - -static void -scroll(void) -{ - int o; - Point p; - Rectangle r; - - o = 4*memdefont->height; - r = Rpt(window.min, Pt(window.max.x, window.max.y-o)); - p = Pt(window.min.x, window.min.y+o); - memimagedraw(gscreen, r, gscreen, p, nil, p, SoverD); - flushmemscreen(r); - r = Rpt(Pt(window.min.x, window.max.y-o), window.max); - memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); - flushmemscreen(r); - - curpos.y -= o; -} - -static void -clearline(void) -{ - Rectangle r; - int yloc = curpos.y; - - r = Rpt(Pt(window.min.x, window.min.y + yloc), - Pt(window.max.x, window.min.y+yloc+memdefont->height)); - memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); -} - -static void -screenputc(char *buf) -{ - Point p; - int h, w, pos; - Rectangle r; - static int *xp; - static int xbuf[256]; - - h = memdefont->height; - if(xp < xbuf || xp >= &xbuf[sizeof(xbuf)]) - xp = xbuf; - - switch(buf[0]) { - case '\n': - if(curpos.y+h >= window.max.y) - scroll(); - curpos.y += h; - /* fall through */ - case '\r': - xp = xbuf; - curpos.x = window.min.x; - break; - case '\t': - if(curpos.x == window.min.x) - clearline(); - p = memsubfontwidth(memdefont, " "); - w = p.x; - *xp++ = curpos.x; - pos = (curpos.x-window.min.x)/w; - pos = 8-(pos%8); - r = Rect(curpos.x, curpos.y, curpos.x+pos*w, curpos.y+h); - memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); - flushmemscreen(r); - curpos.x += pos*w; - break; - case '\b': - if(xp <= xbuf) - break; - xp--; - r = Rpt(Pt(*xp, curpos.y), Pt(curpos.x, curpos.y + h)); - memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); - flushmemscreen(r); - curpos.x = *xp; - break; - case '\0': - break; - default: - p = memsubfontwidth(memdefont, buf); - w = p.x; - - if(curpos.x >= window.max.x-w) - screenputc("\n"); - - if(curpos.x == window.min.x) - clearline(); - if(xp < xbuf+nelem(xbuf)) - *xp++ = curpos.x; - r = Rect(curpos.x, curpos.y, curpos.x+w, curpos.y+h); - memimagedraw(gscreen, r, back, ZP, nil, ZP, SoverD); - memimagestring(gscreen, curpos, conscol, ZP, memdefont, buf); - flushmemscreen(r); - curpos.x += w; - } -} - -int -setcolor(ulong p, ulong r, ulong g, ulong b) -{ - ulong x; - - if(gscreen->depth >= 8) - x = 0xFF; - else - x = 0xF; - p &= x; - p ^= x; - lock(&palettelock); - lcdsetrgb(p, r, g, b); - unlock(&palettelock); - return ~0; -} - -void -getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) -{ - /* TO DO */ - *pr = *pg = *pb = 0; -} - -/* - * See section 5.2.1 (page 5-6) of the MPC823 manual - */ -static uchar lcdclock[17] = { /* (a<<2)|b => divisor of (1<<a)*((b<<1)+1) */ - 0, 0, (1<<2), 1, - (2<<2), 2, (1<<2)|1, 3, - (3<<2), (1<<2)|2, (1<<2)|2, (2<<2)|1, - (2<<2)|1, (1<<2)|3, (1<<2)|3, (4<<2), - (4<<2) -}; - -enum { - /* lccr */ - Enable = 1<<0, - - /* lchcr */ - BigEndian = 1<<24, - AT7 = 7<<21, /* access type */ - - /* sdcr */ - LAM = 1<<6, /* ``LCD aggressive mode'' */ -}; - -/* - * initialise MPC8xx LCD controller incorporating board or display-specific values in Mode.lcd - */ -static void -lcdinit(Mode *mode) -{ - IMM *io; - int i, d; - long hz; - - io = m->iomem; - mode->aperture = xspanalloc(mode->x*mode->y, 16, 0); - mode->apsize = mode->x*mode->y; - - io->sdcr = 1; /* MPC823 errata: turn off LAM before disabling controller */ - eieio(); - io->lcfaa = PADDR(mode->aperture); - io->lccr = (((mode->x*mode->y*(1<<mode->d)+127)/128) << 17) | (mode->d << 5) | mode->lcd.flags; - switch(mode->d){ - default: - case 0: - /* monochrome/greyscale identity map */ - for(i=0; i<16; i++) - io->lcdmap[i] = i; - break; - case 2: - /* 4-bit grey scale map */ - for(i=0; i<16; i++) - io->lcdmap[0] = (i<<8)|(i<<4)|i; - break; - case 3: - /* 8-bit linear map */ - for(i=0; i<256; i++) - io->lcdmap[i] = (i<<8)|(i<<4)|i; - break; - } - - io->lcvcr = (mode->y << 11) | (mode->lcd.vpw<<28) | (mode->lcd.ac<<21) | mode->lcd.wbf; - io->lchcr = (mode->x<<10) | BigEndian | mode->lcd.wbl; - - hz = m->cpuhz; - d = hz/mode->lcd.freq; - if(hz/d > mode->lcd.freq) - d++; - if(d >= 16) - d = 16; - - /* - * enable LCD outputs - */ - io->pddat = 0; - lcdpdpar = 0x1fff & ~mode->lcd.notpdpar; - io->pdpar = lcdpdpar; - io->pddir = 0x1fff; - io->pbpar |= IBIT(31) | IBIT(19) | IBIT(17); - io->pbdir |= IBIT(31) | IBIT(19) | IBIT(17); - io->pbodr &= ~(IBIT(31) | IBIT(19) | IBIT(17)); - - /* - * with the data cache off, early revisions of the 823 did not require - * the `aggressive' DMA priority to avoid flicker, but flicker is obvious - * on the 823A when the cache is on, so LAM is now set - */ - io->sdcr = (io->sdcr & ~0xF) | LAM; /* LAM=1, LAID=0, RAID=0 */ - -// gscreen.width = gscreen.width; /* access external memory before enabling (mpc823 errata) */ - eieio(); - io->sccrk = KEEP_ALIVE_KEY; - eieio(); - io->sccr = (io->sccr & ~0x1F) | lcdclock[d]; - eieio(); - io->sccrk= ~KEEP_ALIVE_KEY; - io->lcsr = 7; /* clear status */ - eieio(); - io->lccr |= Enable; - archbacklight(1); -} - -static void -lcdsetrgb(int p, ulong r, ulong g, ulong b) -{ - r >>= 28; - g >>= 28; - b >>= 28; - m->iomem->lcdmap[p&0xFF] = (r<<8) | (g<<4) | b; -} - -void -blankscreen(int blank) -{ - USED(blank); /* TO DO */ -} - -/* - * enable/disable LCD panel (eg, when using video subsystem) - */ -void -lcdpanel(int on) -{ - IMM *io; - - if(on){ - archbacklight(1); - io = ioplock(); - io->pddat = 0; - io->pdpar = lcdpdpar; - io->pddir = 0x1fff; - io->lccr |= Enable; - iopunlock(); - }else{ - io = ioplock(); - io->sdcr = 1; /* MPC823 errata: turn off LAM before disabling controller */ - eieio(); - io->pddir = 0; - eieio(); - io->lccr &= ~Enable; - iopunlock(); - archbacklight(0); - } -} - -/* - * Software cursor code. Interim version (for baseline). - * we may want to replace code here by memdraw primitives. - */ - -enum { - CUR_ENA = 0x01, /* cursor is enabled */ - CUR_DRW = 0x02, /* cursor is currently drawn */ - CUR_SWP = 0x10, /* bit swap */ - CURSWID = 16, - CURSHGT = 16, -}; - -typedef struct SWcursor { - ulong *fb; /* screen frame buffer */ - Rectangle r; - int d; /* ldepth of screen */ - int width; /* width of screen in ulongs */ - int x; - int y; - int hotx; - int hoty; - uchar cbwid; /* cursor byte width */ - uchar f; /* flags */ - uchar cwid; - uchar chgt; - int hidecount; - uchar data[CURSWID*CURSHGT]; - uchar mask[CURSWID*CURSHGT]; - uchar save[CURSWID*CURSHGT]; -} SWcursor; - -static Rectangle cursoroffrect; -static int cursorisoff; - -static void swcursorflush(int, int); -static void swcurs_draw_or_undraw(SWcursor *); - -static void -cursorupdate0(void) -{ - int inrect, x, y; - Point m; - - m = mousexy(); - x = m.x - swc->hotx; - y = m.y - swc->hoty; - inrect = (x >= cursoroffrect.min.x && x < cursoroffrect.max.x - && y >= cursoroffrect.min.y && y < cursoroffrect.max.y); - if (cursorisoff == inrect) - return; - cursorisoff = inrect; - if (inrect) - swcurs_hide(swc); - else { - swc->hidecount = 0; - swcurs_draw_or_undraw(swc); - } - swcursorflush(m.x, m.y); -} - -void -cursorupdate(Rectangle r) -{ - lock(&screenlock); - r.min.x -= 16; - r.min.y -= 16; - cursoroffrect = r; - if (swc) - cursorupdate0(); - unlock(&screenlock); -} - -void -cursorenable(void) -{ - Point m; - - lock(&screenlock); - if(swc) { - swcurs_enable(swc); - m = mousexy(); - swcursorflush(m.x, m.y); - } - unlock(&screenlock); -} - -void -cursordisable(void) -{ - Point m; - - lock(&screenlock); - if(swc) { - swcurs_disable(swc); - m = mousexy(); - swcursorflush(m.x, m.y); - } - unlock(&screenlock); -} - -void -drawcursor(Drawcursor* c) -{ - Point p; - Cursor curs, *cp; - int j, i, h, bpl; - uchar *bc, *bs, *cclr, *cset; - - if(!swc) - return; - - /* Set the default system cursor */ - if(!c || c->data == nil) - cp = &arrow /*&crosshair_black*/; - else { - cp = &curs; - p.x = c->hotx; - p.y = c->hoty; - cp->offset = p; - bpl = bytesperline(Rect(c->minx, c->miny, c->maxx, c->maxy), 1); - - h = (c->maxy-c->miny)/2; - if(h > 16) - h = 16; - - bc = c->data; - bs = c->data + h*bpl; - - cclr = cp->clr; - cset = cp->set; - for(i = 0; i < h; i++) { - for(j = 0; j < 2; j++) { - cclr[j] = bc[j]; - cset[j] = bs[j]; - } - bc += bpl; - bs += bpl; - cclr += 2; - cset += 2; - } - } - - if(swc) { - swcurs_load(swc, cp); - p = mousexy(); - swcursorflush(p.x, p.y); - } -} - -SWcursor* -swcurs_create(ulong *fb, int width, int ldepth, Rectangle r, int bitswap) -{ - SWcursor *swc = (SWcursor*)malloc(sizeof(SWcursor)); - swc->fb = fb; - swc->r = r; - swc->d = ldepth; - swc->width = width; - swc->f = bitswap ? CUR_SWP : 0; - swc->x = swc->y = 0; - swc->hotx = swc->hoty = 0; - swc->hidecount = 0; - return swc; -} - -void -swcurs_destroy(SWcursor *swc) -{ - swcurs_disable(swc); - free(swc); -} - -static void -swcursorflush(int x, int y) -{ - Rectangle r; - - /* XXX a little too paranoid here */ - r.min.x = x-16; - r.min.y = y-16; - r.max.x = x+17; - r.max.y = y+17; - flushmemscreen(r); -} - -static void -swcurs_draw_or_undraw(SWcursor *swc) -{ - uchar *p; - uchar *cs; - int w, vw; - int x1 = swc->r.min.x; - int y1 = swc->r.min.y; - int x2 = swc->r.max.x; - int y2 = swc->r.max.y; - int xp = swc->x - swc->hotx; - int yp = swc->y - swc->hoty; - int ofs; - - if(((swc->f & CUR_ENA) && (swc->hidecount <= 0)) - == ((swc->f & CUR_DRW) != 0)) - return; - w = swc->cbwid*BI2BY/(1 << swc->d); - x1 = xp < x1 ? x1 : xp; - y1 = yp < y1 ? y1 : yp; - x2 = xp+w >= x2 ? x2 : xp+w; - y2 = yp+swc->chgt >= y2 ? y2 : yp+swc->chgt; - if(x2 <= x1 || y2 <= y1) - return; - p = (uchar*)(swc->fb + swc->width*y1) - + x1*(1 << swc->d)/BI2BY; - y2 -= y1; - x2 = (x2-x1)*(1 << swc->d)/BI2BY; - vw = swc->width*BY2WD - x2; - w = swc->cbwid - x2; - ofs = swc->cbwid*(y1-yp)+(x1-xp); - cs = swc->save + ofs; - if((swc->f ^= CUR_DRW) & CUR_DRW) { - uchar *cm = swc->mask + ofs; - uchar *cd = swc->data + ofs; - while(y2--) { - x1 = x2; - while(x1--) { - *p = ((*cs++ = *p) & *cm++) ^ *cd++; - p++; - } - cs += w; - cm += w; - cd += w; - p += vw; - } - } else { - while(y2--) { - x1 = x2; - while(x1--) - *p++ = *cs++; - cs += w; - p += vw; - } - } -} - -void -swcurs_hide(SWcursor *swc) -{ - ++swc->hidecount; - swcurs_draw_or_undraw(swc); -} - -void -swcurs_unhide(SWcursor *swc) -{ - if (--swc->hidecount < 0) - swc->hidecount = 0; - swcurs_draw_or_undraw(swc); -} - -void -swcurs_enable(SWcursor *swc) -{ - swc->f |= CUR_ENA; - swcurs_draw_or_undraw(swc); -} - -void -swcurs_disable(SWcursor *swc) -{ - swc->f &= ~CUR_ENA; - swcurs_draw_or_undraw(swc); -} - -void -swcurs_load(SWcursor *swc, Cursor *c) -{ - int i, k; - uchar *bc, *bs, *cd, *cm; - static uchar bdv[4] = {0,Backgnd,Foregnd,0xff}; - static uchar bmv[4] = {0xff,0,0,0xff}; - int bits = 1<<swc->d; - uchar mask = (1<<bits)-1; - int bswp = (swc->f&CUR_SWP) ? 8-bits : 0; - - bc = c->clr; - bs = c->set; - - swcurs_hide(swc); - cd = swc->data; - cm = swc->mask; - swc->hotx = c->offset.x; - swc->hoty = c->offset.y; - swc->chgt = CURSHGT; - swc->cwid = CURSWID; - swc->cbwid = CURSWID*(1<<swc->d)/BI2BY; - for(i = 0; i < CURSWID/BI2BY*CURSHGT; i++) { - uchar bcb = *bc++; - uchar bsb = *bs++; - for(k=0; k<BI2BY;) { - uchar cdv = 0; - uchar cmv = 0; - int z; - for(z=0; z<BI2BY; z += bits) { - int n = ((bsb&(0x80))|((bcb&(0x80))<<1))>>7; - int s = z^bswp; - cdv |= (bdv[n]&mask) << s; - cmv |= (bmv[n]&mask) << s; - bcb <<= 1; - bsb <<= 1; - k++; - } - *cd++ = cdv; - *cm++ = cmv; - } - } - swcurs_unhide(swc); -} - diff --git a/os/mpc/screen.h b/os/mpc/screen.h deleted file mode 100644 index 8f8288a8..00000000 --- a/os/mpc/screen.h +++ /dev/null @@ -1,60 +0,0 @@ -enum { - Pcolours = 256, /* Palette */ - Pred = 0, - Pgreen = 1, - Pblue = 2, - - Pblack = 0x00, - Pwhite = 0xFF, -}; - -typedef struct Cursor Cursor; -struct Cursor -{ - Point offset; - uchar clr[2*16]; - uchar set[2*16]; -}; - -/* - * MPC8xx LCD controller - */ -typedef struct LCDconfig { - long freq; /* ideal panel frequency in Hz */ - int wbl; /* wait between lines (shift/clk cycles) */ - int vpw; /* vertical sync pulse width (lines) */ - int wbf; /* wait between frames (lines) */ - int ac; /* AC timing (frames) */ - ulong flags; - ulong notpdpar; /* reset mask for pdpar */ -} LCDconfig; - -enum { - /* lccr flags stored in LCDconfig.flags */ - ClockLow = 1<<11, - OELow = 1<<10, - HsyncLow = 1<<9, - VsyncLow = 1<<8, - DataLow = 1<<7, - Passive8 = 1<<4, - DualScan = 1<<3, - IsColour = 1<<2, - IsTFT = 1<<1, -}; - -/* - * physical graphics device properties set by archlcdmode - */ -typedef struct Mode { - int x; - int y; - int d; - - uchar* aperture; - int apsize; - LCDconfig lcd; -} Mode; - -int archlcdmode(Mode*); -extern Point mousexy(void); -extern void blankscreen(int);
\ No newline at end of file diff --git a/os/mpc/spi.c b/os/mpc/spi.c deleted file mode 100644 index ce662533..00000000 --- a/os/mpc/spi.c +++ /dev/null @@ -1,243 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -/* - * basic read/write interface to mpc8xx Serial Peripheral Interface; - * used by devtouch.c and devspi.c - */ - -typedef struct Ctlr Ctlr; - -enum { - /* spi-specific BD flags */ - BDContin= 1<<9, /* continuous mode */ - RxeOV= 1<<1, /* overrun */ - TxeUN= 1<<1, /* underflow */ - BDme= 1<<0, /* multimaster error */ - BDrxerr= RxeOV|BDme, - BDtxerr= TxeUN|BDme, - - /* spmod */ - MLoop= 1<<14, /* loopback mode */ - MClockInv= 1<<13, /* inactive state of SPICLK is high */ - MClockPhs= 1<<12, /* SPCLK starts toggling at beginning of transfer */ - MDiv16= 1<<11, /* use BRGCLK/16 as input to SPI baud rate */ - MRev= 1<<10, /* normal operation */ - MMaster= 1<<9, - MSlave= 0<<9, - MEnable= 1<<8, - /* LEN, PS fields */ - - /* spcom */ - STR= 1<<7, /* start transmit */ - - /* spie */ - MME = 1<<5, - TXE = 1<<4, - BSY = 1<<2, - TXB = 1<<1, - RXB = 1<<0, - - /* port B bits */ - SPIMISO = IBIT(28), /* master mode input */ - SPIMOSI = IBIT(29), /* master mode output */ - SPICLK = IBIT(30), - - /* maximum SPI I/O (can change) */ - Bufsize = 64, -}; - -/* - * SPI software structures - */ - -struct Ctlr { - Lock; - QLock io; - int init; - SPI* spi; - IOCparam* sp; - - BD* rd; - BD* td; - int phase; - Rendez r; - char* txbuf; - char* rxbuf; -}; - -static Ctlr spictlr[1]; - -/* dcflush isn't needed if rxbuf and txbuf allocated in uncached IMMR memory */ -#define DCFLUSH(a,n) - -static void interrupt(Ureg*, void*); - -/* - * called by the reset routine of any driver using the SPI - */ -void -spireset(void) -{ - IMM *io; - SPI *spi; - IOCparam *sp; - CPMdev *cpm; - Ctlr *ctlr; - - ctlr = spictlr; - if(ctlr->init) - return; - ctlr->init = 1; - cpm = cpmdev(CPspi); - spi = cpm->regs; - ctlr->spi = spi; - sp = cpm->param; - if(sp == nil){ - print("SPI: can't allocate new parameter memory\n"); - return; - } - ctlr->sp = sp; - - if(ctlr->rxbuf == nil) - ctlr->rxbuf = cpmalloc(Bufsize, 2); - if(ctlr->txbuf == nil) - ctlr->txbuf = cpmalloc(Bufsize, 2); - - if(ctlr->rd == nil){ - ctlr->rd = bdalloc(1); - ctlr->rd->addr = PADDR(ctlr->rxbuf); - ctlr->rd->length = 0; - ctlr->rd->status = BDWrap; - } - if(ctlr->td == nil){ - ctlr->td = bdalloc(1); - ctlr->td->addr = PADDR(ctlr->txbuf); - ctlr->td->length = 0; - ctlr->td->status = BDWrap|BDLast; - } - - /* select port pins */ - io = ioplock(); - io->pbdir |= SPICLK | SPIMOSI | SPIMISO; - io->pbpar |= SPICLK | SPIMOSI | SPIMISO; - iopunlock(); - - /* explicitly initialise parameters, because InitRxTx can't be used (see i2c/spi relocation errata) */ - sp = ctlr->sp; - sp->rbase = PADDR(ctlr->rd); - sp->tbase = PADDR(ctlr->td); - sp->rfcr = 0x18; - sp->tfcr = 0x18; - sp->mrblr = Bufsize; - sp->rstate = 0; - sp->rptr = 0; - sp->rbptr = sp->rbase; - sp->rcnt = 0; - sp->tstate = 0; - sp->tbptr = sp->tbase; - sp->tptr = 0; - sp->tcnt = 0; - eieio(); - - spi->spmode = MDiv16 | MRev | MMaster | ((8-1)<<4) | 1; /* 8 bit characters */ - if(0) - spi->spmode |= MLoop; /* internal loop back mode for testing */ - - spi->spie = ~0; /* clear events */ - eieio(); - spi->spim = MME|TXE|BSY|TXB|RXB; - eieio(); - spi->spmode |= MEnable; - - intrenable(VectorCPIC+cpm->irq, interrupt, spictlr, BUSUNKNOWN, "spi"); - -} - -enum { - Idling, - Waitval, - Readyval -}; - -static void -interrupt(Ureg*, void *arg) -{ - int events; - Ctlr *ctlr; - SPI *spi; - - ctlr = arg; - spi = ctlr->spi; - events = spi->spie; - eieio(); - spi->spie = events; - if(events & (MME|BSY|TXE)){ - print("SPI#%x\n", events); - if(ctlr->phase != Idling){ - ctlr->phase = Idling; - wakeup(&ctlr->r); - } - }else if(events & RXB){ - if(ctlr->phase == Waitval){ - ctlr->phase = Readyval; - wakeup(&ctlr->r); - } - } -} - -static int -done(void *a) -{ - return ((Ctlr*)a)->phase != Waitval; -} - -/* - * send `nout' bytes on SPI from `out' and read as many bytes of reply into buffer `in'; - * return the number of bytes received, or -1 on error. - */ -long -spioutin(void *out, long nout, void *in) -{ - Ctlr *ctlr; - int nb, p; - - ctlr = spictlr; - if(nout > Bufsize) - return -1; - qlock(&ctlr->io); - if(waserror()){ - qunlock(&ctlr->io); - return -1; - } - if(ctlr->phase != Idling) - sleep(&ctlr->r, done, ctlr); - memmove(ctlr->txbuf, out, nout); - DCFLUSH(ctlr->txbuf, Bufsize); - DCFLUSH(ctlr->rxbuf, Bufsize); - ilock(ctlr); - ctlr->phase = Waitval; - ctlr->td->length = nout; - ctlr->rd->status = BDEmpty|BDWrap|BDInt; - ctlr->td->status = BDReady|BDWrap|BDLast; - eieio(); - ctlr->spi->spcom = STR; - eieio(); - iunlock(ctlr); - sleep(&ctlr->r, done, ctlr); - nb = ctlr->rd->length; - if(nb > nout) - nb = nout; /* shouldn't happen */ - p = ctlr->phase; - poperror(); - qunlock(&ctlr->io); - if(p != Readyval) - return -1; - memmove(in, ctlr->rxbuf, nb); - return nb; -} diff --git a/os/mpc/trap.c b/os/mpc/trap.c deleted file mode 100644 index 843d7ad4..00000000 --- a/os/mpc/trap.c +++ /dev/null @@ -1,554 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "ureg.h" -#include "io.h" -#include "../port/error.h" - - -enum -{ - Maxhandler= MaxVector /* max number of interrupt handlers */ -}; - -typedef struct Handler Handler; -struct Handler -{ - void (*r)(Ureg*, void*); - void *arg; - char name[KNAMELEN]; - Handler *next; - ulong nintr; - ulong ticks; - int maxtick; -}; - -struct -{ - Handler *ivec[MaxVector]; - Handler h[Maxhandler]; - int free; - Handler* freelist; -} halloc; - -Instr BREAK = 0x7fe00008; -int (*breakhandler)(Ureg*, Proc*); - -void kernfault(Ureg*, int); - -char *excname[] = -{ - "reserved 0", - "system reset", - "machine check", - "data access", - "instruction access", - "external interrupt", - "alignment", - "program exception", - "floating-point unavailable", - "decrementer", - "i/o controller interface error", - "reserved B", - "system call", - "trace trap", - "floating point assist", - "reserved F", - "software emulation", - "ITLB miss", - "DTLB miss", - "ITLB error", - "DTLB error", - "reserved 15", - "reserved 16", - "reserved 17", - "reserved 18", - "reserved 19", - "reserved 1A", - "reserved 1B", - "data breakpoint", - "instruction breakpoint", - "peripheral breakpoint", - "development port", - /* the following are made up on a program exception */ - "floating point exception", /* 20: FPEXC */ - "illegal instruction", /* 21 */ - "privileged instruction", /* 22 */ - "trap", /* 23 */ - "illegal operation", /* 24 */ - "breakpoint", /* 25 */ -}; - -char *fpcause[] = -{ - "inexact operation", - "division by zero", - "underflow", - "overflow", - "invalid operation", -}; -char *fpexcname(Ureg*, ulong, char*); -#define FPEXPMASK 0xfff80300 /* Floating exception bits in fpscr */ - - -char *regname[]={ - "CAUSE", "SRR1", - "PC", "GOK", - "LR", "CR", - "XER", "CTR", - "R0", "R1", - "R2", "R3", - "R4", "R5", - "R6", "R7", - "R8", "R9", - "R10", "R11", - "R12", "R13", - "R14", "R15", - "R16", "R17", - "R18", "R19", - "R20", "R21", - "R22", "R23", - "R24", "R25", - "R26", "R27", - "R28", "R29", - "R30", "R31", -}; - -void -sethvec(int v, void (*r)(void)) -{ - ulong *vp, pa, o; - - vp = (ulong*)KADDR(v); - vp[0] = 0x7c1043a6; /* MOVW R0, SPR(SPRG0) */ - vp[1] = 0x7c0802a6; /* MOVW LR, R0 */ - vp[2] = 0x7c1243a6; /* MOVW R0, SPR(SPRG2) */ - pa = PADDR(r); - o = pa >> 25; - if(o != 0 && o != 0x7F){ - /* a branch too far: running from ROM */ - vp[3] = (15<<26)|(pa>>16); /* MOVW $r&~0xFFFF, R0 */ - vp[4] = (24<<26)|(pa&0xFFFF); /* OR $r&0xFFFF, R0 */ - vp[5] = 0x7c0803a6; /* MOVW R0, LR */ - vp[6] = 0x4e800021; /* BL (LR) */ - }else - vp[3] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ - dcflush(vp, 8*sizeof(ulong)); -} - -void -sethvec2(int v, void (*r)(void)) -{ - ulong *vp; - - vp = (ulong*)KADDR(v); - vp[0] = (18<<26)|((ulong)r&~KSEGM)|2; /* ba */ - dcflush(vp, sizeof(*vp)); -} - -void -trap(Ureg *ur) -{ - int ecode, s; - ulong w; - char buf[ERRMAX]; - - ecode = ur->cause >> 8; - if(ecode < 0 || ecode >= 0x1F) - ecode = 0x1F; - switch(ecode){ - case CDEC: - clockintr(ur); - preemption(1); - break; - - case CMCHECK: - case CDSI: - case CISI: - case CIMISS: - case CDMISS: - case CITLBE: - case CDTLBE: - faultpower(ur); - break; - - case CEMU: - if(up == nil) - goto Default; - if((ulong)(ur+1) != ur->r1) - panic("fp emu stack"); - spllo(); - if(waserror()){ - if(up->type == Interp) - disfault(ur, up->env->errstr); - panic("%s", up->env->errstr); - } - if(fpipower(ur) == 0){ - splhi(); - poperror(); - print("pc=#%lux op=#%8.8lux\n", ur->pc, *(ulong*)ur->pc); - goto Default; - } - poperror(); - break; - - case CPROG: - if(ur->status & (1<<19)) { - ecode = 0x20; - w = ur->pc; - if(ur->status & (1<<16)) - w += 4; - if(*(ulong*)w == 0x7fe00008){ /* tw 31,0,0 */ - if(breakhandler){ - s = (*breakhandler)(ur, up); - if(s == BrkSched){ - if(up){ - up->preempted = 0; - sched(); - splhi(); - } - }else if(s == BrkNoSched){ - if(up){ - up->preempted = 1; /* stop it being preempted until next instruction */ - up->dbgreg = 0; - } - } - break; - } - ecode = 0x1D; /* breakpoint */ - } - } - if(ur->status & (1<<18)) - ecode = 0x21; - if(ur->status & (1<<17)) - ecode = 0x22; - /* FALL THROUGH */ - - Default: - default: - if(up && up->type == Interp) { - spllo(); - snprint(buf, sizeof buf, "sys: trap: %s pc=0x%lux", excname[ecode], ur->pc); - error(buf); - break; - } - print("kernel %s pc=0x%lux\n", excname[ecode], ur->pc); - dumpregs(ur); - dumpstack(); - if(m->machno == 0) - spllo(); - exit(1); - } - - splhi(); -} - -void -spurious(Ureg *ur, void *a) -{ - USED(a); - print("SPURIOUS interrupt pc=0x%lux cause=0x%lux\n", - ur->pc, ur->cause); - panic("bad interrupt"); -} - -#define LEV(n) (((n)<<1)|1) -#define IRQ(n) (((n)<<1)|0) - -Lock veclock; - -void -trapinit(void) -{ - int i; - IMM *io; - - - io = m->iomem; - io->simask = 0; /* mask all */ - io->siel = ~0; /* edge sensitive, wake on all */ - io->cicr = 0; /* disable CPM interrupts */ - io->cipr = ~0; /* clear all interrupts */ - io->cimr = 0; /* mask all events */ - io->cicr = (0xE1<<16)|(CPIClevel<<13)|(0x1F<<8); - io->cicr |= 1 << 7; /* enable */ - io->tbscrk = KEEP_ALIVE_KEY; - io->tbscr = 1; /* TBE */ - io->simask |= 1<<(31-LEV(CPIClevel)); /* CPM's level */ - io->tbk = KEEP_ALIVE_KEY; - eieio(); - putdec(~0); - - /* - * set all exceptions to trap - */ - for(i = 0x0; i < 0x3000; i += 0x100) - sethvec(i, trapvec); - - sethvec(CEI<<8, intrvec); - //sethvec2(CIMISS<<8, itlbmiss); - //sethvec2(CDMISS<<8, dtlbmiss); -} - -void -intrenable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) -{ - Handler *h; - IMM *io; - - v -= VectorPIC; - if(v < 0 || v >= nelem(halloc.ivec)) - panic("intrenable(%d)", v+VectorPIC); - ilock(&veclock); - if((h = halloc.freelist) == nil){ - if(halloc.free >= Maxhandler){ - iunlock(&veclock); - panic("out of interrupt handlers"); - } - h = &halloc.h[halloc.free++]; - }else - halloc.freelist = h->next; - h->r = r; - h->arg = arg; - strncpy(h->name, name, KNAMELEN-1); - h->name[KNAMELEN-1] = 0; - h->next = halloc.ivec[v]; - halloc.ivec[v] = h; - - /* - * enable corresponding interrupt in SIU/CPM - */ - - eieio(); - io = m->iomem; - if(v >= VectorCPIC){ - v -= VectorCPIC; - io->cimr |= 1<<(v&0x1F); - } - else if(v >= VectorIRQ) - io->simask |= 1<<(31-IRQ(v&7)); - else - io->simask |= 1<<(31-LEV(v)); - eieio(); - iunlock(&veclock); -} - -static void -irqdisable(int v) -{ - IMM *io; - - io = m->iomem; - if(v >= VectorCPIC){ - v -= VectorCPIC; - io->cimr &= ~(1<<(v&0x1F)); - } - else if(v >= VectorIRQ) - io->simask &= ~(1<<(31-IRQ(v&7))); - else - io->simask &= ~(1<<(31-LEV(v))); -} - -void -intrdisable(int v, void (*r)(Ureg*, void*), void *arg, int, char *name) -{ - Handler *h, **hp; - - v -= VectorPIC; - if(v < 0 || v >= nelem(halloc.ivec)) - panic("intrenable(%d)", v+VectorPIC); - ilock(&veclock); - for(hp = &halloc.ivec[v]; (h = *hp) != nil; hp = &h->next) - if(h->r == r && h->arg == arg && strcmp(h->name, name) == 0){ - *hp = h->next; - h->next = halloc.freelist; - halloc.freelist = h; - break; - } - if(halloc.ivec[v] == nil) - irqdisable(v); - iunlock(&veclock); -} - -/* - * called directly by l.s:/intrvec. on a multiprocessor we'd need to lock veclock. - */ -void -intr(Ureg *ur) -{ - int b, v; - IMM *io; - Handler *h; - long t0; - Proc *oup; - - ur->cause &= ~0xff; - io = m->iomem; - b = io->sivec>>2; - v = b>>1; - if(b & 1) { - if(v == CPIClevel){ - io->civr = 1; - eieio(); - v = VectorCPIC+(io->civr>>11); - } - }else{ - v += VectorIRQ; - if(io->siel & (1<<(31-b))){ - io->sipend |= 1<<(31-b); - eieio(); - } - } - - ur->cause |= v; - h = halloc.ivec[v]; - if(h == nil){ - iprint("unknown interrupt %d pc=0x%lux\n", v, ur->pc); - irqdisable(v); - return; - } - - /* - * call the interrupt handlers - */ - oup = up; - up = nil; /* no process at interrupt level */ - do { - h->nintr++; - t0 = getdec(); - (*h->r)(ur, h->arg); - t0 -= getdec(); - h->ticks += t0; - if(h->maxtick < t0) - h->maxtick = t0; - h = h->next; - } while(h != nil); - if(v >= VectorCPIC) - io->cisr |= 1<<(v-VectorCPIC); - eieio(); - up = oup; - preemption(0); -} - -int -intrstats(char *buf, int bsize) -{ - Handler *h; - int i, n; - - n = 0; - for(i=0; i<nelem(halloc.ivec) && n < bsize; i++) - if((h = halloc.ivec[i]) != nil && h->nintr) - n += snprint(buf+n, bsize-n, "%3d %lud %lud %ud\n", i, h->nintr, h->ticks, h->maxtick); - return n; -} - -char* -fpexcname(Ureg *ur, ulong fpscr, char *buf) -{ - int i; - char *s; - ulong fppc; - - fppc = ur->pc; - s = 0; - fpscr >>= 3; /* trap enable bits */ - fpscr &= (fpscr>>22); /* anded with exceptions */ - for(i=0; i<5; i++) - if(fpscr & (1<<i)) - s = fpcause[i]; - if(s == 0) - return "no floating point exception"; - sprint(buf, "%s fppc=0x%lux", s, fppc); - return buf; -} - -#define KERNPC(x) (KTZERO<(ulong)(x)&&(ulong)(x)<(ulong)etext) - -void -kernfault(Ureg *ur, int code) -{ - Label l; - - print("panic: kfault %s dar=0x%lux\n", excname[code], getdar()); - print("u=0x%lux status=0x%lux pc=0x%lux sp=0x%lux\n", - up, ur->status, ur->pc, ur->sp); - dumpregs(ur); - l.sp = ur->sp; - l.pc = ur->pc; - dumpstack(); - setpri(PriBackground); /* Let the debugger in */ - for(;;) - sched(); -} - -void -dumpstack(void) -{ - ulong l, v; - int i; - - if(up == 0) - return; - i = 0; - for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){ - v = *(ulong*)l; - if(KTZERO < v && v < (ulong)etext){ - print("%lux=%lux, ", l, v); - if(i++ == 4){ - print("\n"); - i = 0; - } - } - } -} - -void -dumpregs(Ureg *ur) -{ - int i; - ulong *l; - if(up) { - print("registers for %s %ld\n", up->text, up->pid); - if(ur->usp < (ulong)up->kstack || - ur->usp > (ulong)up->kstack+KSTACK) - print("invalid stack ptr\n"); - } - else - print("registers for kernel\n"); - - l = &ur->cause; - for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2) - print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]); -} - -static void -linkproc(void) -{ - spllo(); - (*up->kpfun)(up->arg); - pexit("", 0); -} - -void -kprocchild(Proc *p, void (*func)(void*), void *arg) -{ - p->sched.pc = (ulong)linkproc; - p->sched.sp = (ulong)p->kstack+KSTACK; - - p->kpfun = func; - p->arg = arg; -} - -void -setpanic(void) -{ - consoleprint = 1; -} - -void -dumplongs(char*, ulong*, int) -{ -} diff --git a/os/mpc/usb.h b/os/mpc/usb.h deleted file mode 100644 index 1d750f3f..00000000 --- a/os/mpc/usb.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * USB packet definitions - */ - -#define GET2(p) ((((p)[1]&0xFF)<<8)|((p)[0]&0xFF)) -#define PUT2(p,v) {((p)[0] = (v)); ((p)[1] = (v)>>8);} - -enum { - /* request type */ - RH2D = 0<<7, - RD2H = 1<<7, - Rstandard = 0<<5, - Rclass = 1<<5, - Rvendor = 2<<5, - Rdevice = 0, - Rinterface = 1, - Rendpt = 2, - Rother = 3, - - /* standard requests */ - GET_STATUS = 0, - CLEAR_FEATURE = 1, - SET_FEATURE = 3, - SET_ADDRESS = 5, - GET_DESCRIPTOR = 6, - SET_DESCRIPTOR = 7, - GET_CONFIGURATION = 8, - SET_CONFIGURATION = 9, - GET_INTERFACE = 10, - SET_INTERFACE = 11, - SYNCH_FRAME = 12, - - /* hub class feature selectors */ - C_HUB_LOCAL_POWER = 0, - C_HUB_OVER_CURRENT, - PORT_CONNECTION = 0, - PORT_ENABLE = 1, - PORT_SUSPEND = 2, - PORT_OVER_CURRENT = 3, - PORT_RESET = 4, - PORT_POWER = 8, - PORT_LOW_SPEED = 9, - C_PORT_CONNECTION = 16, - C_PORT_ENABLE, - C_PORT_SUSPEND, - C_PORT_OVER_CURRENT, - C_PORT_RESET, - - /* descriptor types */ - DEVICE = 1, - CONFIGURATION = 2, - STRING = 3, - INTERFACE = 4, - ENDPOINT = 5, - HID = 0x21, - REPORT = 0x22, - PHYSICAL = 0x23, - - /* feature selectors */ - DEVICE_REMOTE_WAKEUP = 1, - ENDPOINT_STALL = 0, -}; |
