M carrera/dat.h => carrera/dat.h +2 -1
@@ 47,11 47,12 @@ struct Conf
ulong base0; /* base of bank 0 */
ulong base1; /* base of bank 1 */
ulong copymode; /* 0 is copy on write, 1 is copy on reference */
+ int monitor;
+
ulong ipif; /* Ip protocol interfaces */
ulong ip; /* Ip conversations per interface */
ulong arp; /* Arp table size */
ulong frag; /* Ip fragment assemble queue size */
- ulong debugger; /* use processor 1 as a kernel debugger */
};
/*
M carrera/devether.c => carrera/devether.c +227 -156
@@ 16,8 16,18 @@
#define SONICADDR ((Sonic*)Sonicbase)
#define RD(rn) (delay(1), *(ulong*)((ulong)&SONICADDR->rn^4))
-#define WR(rn, v) (delay(1), *(ulong*)((ulong)&SONICADDR->rn^4) = v)
-#define ISquad(s) if((ulong)s & 0x7) panic("sonoc: Quad alignment");
+#define WR(rn, v) (delay(1), *(ulong*)((ulong)&SONICADDR->rn^4) = (v))
+#define ISquad(s) if((ulong)s & 0x7) panic("sonic: Quad alignment");
+
+typedef struct Pbuf Pbuf;
+struct Pbuf
+{
+ uchar d[6];
+ uchar s[6];
+ uchar type[2];
+ uchar data[1500];
+ uchar crc[4];
+};
typedef struct
{
@@ 32,7 42,10 @@ typedef struct
ulong pad0x08[5]; /* */
ulong urda; /* upper receive descriptor address */
ulong crda; /* current receive descriptor address */
- ulong pad0x0F[4]; /* */
+ ulong crba0; /* DO NOT WRITE THESE */
+ ulong crba1;
+ ulong rbwc0;
+ ulong rbwc1;
ulong eobc; /* end of buffer word count */
ulong urra; /* upper receive resource address */
ulong rsa; /* resource start address */
@@ 111,6 124,9 @@ enum
Hbl = 0x2000, /* CD heartbeat lost */
Br = 0x4000, /* bus retry occurred */
AllIntr = 0x7771, /* all of the above */
+
+ Rxbuf = sizeof(Pbuf)+4,
+ Txbuf = sizeof(Pbuf),
};
/*
@@ 118,14 134,14 @@ enum
*/
typedef struct
{
- uchar pad0[2];
- ushort ptr0; /* buffer pointer in the RRA */
- uchar pad1[2];
- ushort ptr1;
- uchar pad2[2];
- ushort wc0; /* buffer word count in the RRA */
- uchar pad3[2];
- ushort wc1;
+ ushort pad1;
+ ushort ptr1; /* buffer pointer in the RRA */
+ ushort pad2;
+ ushort ptr0;
+ ushort pad3;
+ ushort wc1; /* buffer word count in the RRA */
+ ushort pad4;
+ ushort wc0;
} RXrsc;
/*
@@ 133,20 149,21 @@ typedef struct
*/
typedef struct
{
- uchar pad0[2];
- ushort status; /* receive status */
- uchar pad1[2];
- ushort count; /* packet byte count */
- uchar pad2[2];
- ushort ptr0; /* buffer pointer */
- uchar pad3[2];
- ushort ptr1;
- uchar pad4[2];
- ushort seqno; /* */
- uchar pad5[2];
- ushort link; /* descriptor link and EOL */
- uchar pad6[2];
- ushort owner; /* in use */
+ ushort pad0;
+ ushort count; /* packet byte count */
+ ushort pad1;
+ ushort status; /* receive status */
+ ushort pad2;
+ ushort ptr1; /* buffer pointer */
+ ushort pad3;
+ ushort ptr0;
+ ushort pad4;
+ ushort link; /* descriptor link and EOL */
+ ushort pad5;
+ ushort seqno; /* */
+ ulong pad6;
+ ushort pad7;
+ ushort owner; /* in use */
} RXpkt;
/*
@@ 154,22 171,22 @@ typedef struct
*/
typedef struct
{
- uchar pad0[2];
- ushort status; /* transmit status */
- uchar pad1[2];
- ushort config; /* */
- uchar pad2[2];
- ushort size; /* byte count of entire packet */
- uchar pad3[2];
- ushort count; /* fragment count */
- uchar pad4[2];
- ushort ptr0; /* packet pointer */
- uchar pad5[2];
- ushort ptr1;
- uchar pad6[2];
- ushort fsize; /* fragment size */
- uchar pad7[2];
- ushort link; /* descriptor link */
+ ushort pad1;
+ ushort config; /* */
+ ushort pad0;
+ ushort status; /* transmit status */
+ ushort pad3;
+ ushort count; /* fragment count */
+ ushort pad2;
+ ushort size; /* byte count of entire packet */
+ ushort pad5;
+ ushort ptr1;
+ ushort pad4;
+ ushort ptr0; /* packet pointer */
+ ushort pad7;
+ ushort link; /* descriptor link */
+ ushort pad6;
+ ushort fsize; /* fragment size */
} TXpkt;
enum{
@@ 186,16 203,17 @@ enum{
*/
typedef struct
{
- uchar pad0[2];
- ushort cep; /* CAM entry pointer */
- uchar pad1[2];
- ushort cap0; /* CAM address port 0 */
- uchar pad2[2];
- ushort cap1; /* CAM address port 1 */
- uchar pad3[2];
- ushort cap2; /* CAM address port 2 */
- uchar pad4[2];
- ushort ce; /* CAM enable */
+ ushort pad0;
+ ushort cap0; /* CAM address port 0 */
+ ushort pad1;
+ ushort cep; /* CAM entry pointer */
+ ushort pad2;
+ ushort cap2; /* CAM address port 2 */
+ ushort pad3;
+ ushort cap1; /* CAM address port 1 */
+ ulong pad4;
+ ushort pad5;
+ ushort ce; /* CAM enable */
} Cam;
typedef struct Ether Ether;
@@ 204,8 222,6 @@ struct Ether
uchar ea[6];
uchar ba[6];
- Sonic *sonic; /* SONIC registers */
-
QLock tlock; /* lock for grabbing transmitter queue */
Rendez tr; /* wait here for free xmit buffer */
int th; /* first transmit buffer owned by host */
@@ 214,12 230,13 @@ struct Ether
int rh; /* first receive buffer owned by host */
int ri; /* first receive buffer owned by interface */
- RXrsc rra[Nrb]; /* receive resource area */
- RXpkt rda[Nrb]; /* receive descriptor area */
- uchar rb[Nrb][sizeof(Etherpkt)+4]; /* receive buffer area */
- TXpkt tda[Ntb]; /* transmit descriptor area */
- uchar tb[Ntb][sizeof(Etherpkt)]; /* transmit buffer area */
- Cam cda; /* CAM descriptor area */
+ RXrsc *rra; /* receive resource area */
+ RXpkt *rda; /* receive descriptor area */
+ TXpkt *tda; /* transmit descriptor area */
+ Cam *cda; /* CAM descriptor area */
+
+ uchar *rb[Nrb]; /* receive buffer area */
+ uchar *tb[Ntb]; /* transmit buffer area */
Netif;
};
@@ 231,21 248,29 @@ Ether *ether[Nether];
#define LS16(addr) (PADDR(addr) & 0xFFFF)
#define MS16(addr) ((PADDR(addr)>>16) & 0xFFFF)
+void sonicswap(void*, int);
+
+static void
+wus(ushort *a, ushort v)
+{
+ a[0] = v;
+ a[-1] = v;
+}
+
static void
reset(Ether *ctlr)
{
int i;
+ ushort lolen, hilen, loadr, hiadr;
/*
* Reset the SONIC, toggle the Rst bit.
* Set the data config register for synchronous termination
* and 32-bit data-path width.
- * Clear the descriptor and buffer area.
+ * Setup the descriptor and buffer area.
*/
WR(cr, Rst);
WR(dcr, 0x2423); /* 5-19 Carrera manual */
-iprint("eobc #%lux\n", RD(eobc));
- WR(cr, 0);
/*
* Initialise the receive resource area (RRA) and
@@ 254,23 279,34 @@ iprint("eobc #%lux\n", RD(eobc));
* We use a simple scheme of one packet per descriptor.
* We achieve this by setting the EOBC register to be
* 2 (16-bit words) less than the buffer size;
- * thus the size of the receive buffers must be sizeof(Etherpkt)+4.
+ * thus the size of the receive buffers must be sizeof(Pbuf)+4.
* Set up the receive descriptors as a ring.
*/
+
+ lolen = (Rxbuf/2) & 0xFFFF;
+ hilen = ((Rxbuf/2)>>16) & 0xFFFF;
+
for(i = 0; i < Nrb; i++) {
- ctlr->rra[i].wc0 = (sizeof(ctlr->rb[0])/2) & 0xFFFF;
- ctlr->rra[i].wc1 = ((sizeof(ctlr->rb[0])/2)>>16) & 0xFFFF;
+ wus(&ctlr->rra[i].wc0, lolen);
+ wus(&ctlr->rra[i].wc1, hilen);
- ctlr->rda[i].link = LS16(&ctlr->rda[NEXT(i, Nrb)]);
+ ctlr->rda[i].link = LS16(&ctlr->rda[NEXT(i, Nrb)]);
ctlr->rda[i].owner = Interface;
- ctlr->rra[i].ptr0 = ctlr->rda[i].ptr0 = LS16(ctlr->rb[i]);
- ctlr->rra[i].ptr1 = ctlr->rda[i].ptr1 = MS16(ctlr->rb[i]);
+ loadr = LS16(ctlr->rb[i]);
+ wus(&ctlr->rra[i].ptr0, loadr);
+ wus(&ctlr->rda[i].ptr0, loadr);
+
+ hiadr = MS16(ctlr->rb[i]);
+ wus(&ctlr->rra[i].ptr1, hiadr);
+ wus(&ctlr->rda[i].ptr1, hiadr);
}
+ /*
+ * Check the important resources are QUAD aligned
+ */
ISquad(ctlr->rra);
ISquad(ctlr->rda);
- ISquad(ctlr->rb);
/*
* Terminate the receive descriptor ring
@@ 280,8 316,7 @@ iprint("eobc #%lux\n", RD(eobc));
WR(crda, LS16(ctlr->rda));
WR(urda, MS16(ctlr->rda));
- WR(eobc, sizeof(ctlr->rb[0])/2 - 2);
-iprint("eobc #%lux\n", RD(eobc));
+ WR(eobc, Rxbuf/2 - 2);
/*
* Load the SONIC registers to describe the RRA.
@@ 289,8 324,6 @@ iprint("eobc #%lux\n", RD(eobc));
* rea. This means that since we've already allocated all
* the buffers, we'll never get a 'receive buffer area
* exhausted' interrupt and the rrp will just wrap round.
- * Tell the SONIC to load the RRA and wait for
- * it to complete.
*/
WR(urra, MS16(&ctlr->rra[0]));
WR(rsa, LS16(&ctlr->rra[0]));
@@ 298,10 331,6 @@ iprint("eobc #%lux\n", RD(eobc));
WR(rea, LS16(&ctlr->rra[Nrb]));
WR(rwp, LS16(&ctlr->rra[Nrb+1]));
- WR(cr, Rrra);
- while(RD(cr) & Rrra)
- ;
-
/*
* Initialise the transmit descriptor area (TDA).
* Each descriptor describes one packet, we make no use
@@ 339,18 368,26 @@ iprint("eobc #%lux\n", RD(eobc));
* broadcast is defined by the SONIC as all 1s.
*
* Load the SONIC registers to describe the CDA.
- * Tell the SONIC to load the CDA and wait for it
- * to complete.
*/
- ctlr->cda.cep = 0;
- ctlr->cda.cap0 = (ctlr->ea[1]<<8)|ctlr->ea[0];
- ctlr->cda.cap1 = (ctlr->ea[3]<<8)|ctlr->ea[2];
- ctlr->cda.cap2 = (ctlr->ea[5]<<8)|ctlr->ea[4];
- ctlr->cda.ce = 1;
+ ctlr->cda->cep = 0;
+ ctlr->cda->cap0 = (ctlr->ea[1]<<8)|ctlr->ea[0];
+ ctlr->cda->cap1 = (ctlr->ea[3]<<8)|ctlr->ea[2];
+ ctlr->cda->cap2 = (ctlr->ea[5]<<8)|ctlr->ea[4];
+ ctlr->cda->ce = 1;
- WR(cdp, LS16(&ctlr->cda));
+ WR(cdp, LS16(ctlr->cda));
WR(cdc, 1);
+ /*
+ * End the reset
+ * Load the Resource Descriptors and Cam contents
+ */
+ WR(cr, 0);
+
+ WR(cr, Rrra);
+ while(RD(cr) & Rrra)
+ ;
+
WR(cr, Lcam);
while(RD(cr) & Lcam)
;
@@ 366,43 403,42 @@ iprint("eobc #%lux\n", RD(eobc));
}
void
-pxp(RXpkt *rxpkt)
+sonicpkt(Ether *ctlr, RXpkt *r, Pbuf *p)
{
- print("%lux %lux\n", rxpkt->pad0[0], rxpkt->pad0[1]);
- print("status %lux\n", rxpkt->status); /* receive status */
- print("%lux %lux\n", rxpkt->pad1[0], rxpkt->pad1[1]);
- print("count %lux\n", rxpkt->count); /* packet byte count */
- print("%lux %lux\n", rxpkt->pad2[0], rxpkt->pad2[1]);
- print("ptr0 %lux\n", rxpkt->ptr0); /* buffer pointer */
- print("%lux %lux\n", rxpkt->pad3[0], rxpkt->pad3[1]);
- print("ptr1 %lux\n", rxpkt->ptr1);
- print("%lux %lux\n", rxpkt->pad4[0], rxpkt->pad4[1]);
- print("seqno %lux\n", rxpkt->seqno); /* */
- print("%lux %lux\n", rxpkt->pad5[0], rxpkt->pad5[1]);
- print("link %lux\n", rxpkt->link); /* descriptor link and EOL */
- print("%lux %lux\n", rxpkt->pad6[0], rxpkt->pad6[1]);
- print("owner %lux\n", rxpkt->owner); /* in use */
+ int len;
+ ushort type;
+ Netfile *f, **fp, **ep;
+
+ /*
+ * Sonic delivers CRC as part of the packet count
+ */
+ len = (r->count & 0xFFFF)-4;
+
+ sonicswap(p, len);
+
+ type = (p->type[0]<<8) | p->type[1];
+ ep = &ctlr->f[Ntypes];
+ for(fp = ctlr->f; fp < ep; fp++) {
+ f = *fp;
+ if(f && (f->type == type || f->type < 0))
+ qproduce(f->in, p->d, len);
+ }
}
void
etherintr(void)
{
- int x;
- ushort t;
- Ether *ctlr;
+ Ether *c;
ulong status;
TXpkt *txpkt;
RXpkt *rxpkt;
- Etherpkt *p;
- Netfile *f, **fp;
- ctlr = ether[0];
+ c = ether[0];
for(;;) {
status = RD(isr) & AllIntr;
if(status == 0)
break;
-print("s %lux\n", status);
WR(isr, status);
@@ 410,7 446,7 @@ print("s %lux\n", status);
* Transmission complete, for good or bad.
*/
if(status & (Txdn|Txer)){
- txpkt = &ctlr->tda[ctlr->ti];
+ txpkt = &c->tda[c->ti];
while(txpkt->status != Host){
if(txpkt->status == Interface){
WR(ctda, LS16(txpkt));
@@ 419,11 455,11 @@ print("s %lux\n", status);
}
if((txpkt->status & Ptx) == 0)
- ctlr->oerrs++;
+ c->oerrs++;
txpkt->status = Host;
- ctlr->ti = NEXT(ctlr->ti, Ntb);
- txpkt = &ctlr->tda[ctlr->ti];
+ c->ti = NEXT(c->ti, Ntb);
+ txpkt = &c->tda[c->ti];
}
status &= ~(Txdn|Txer);
}
@@ 434,38 470,24 @@ print("s %lux\n", status);
/*
* A packet arrived or we ran out of descriptors.
*/
- rxpkt = &ctlr->rda[ctlr->rh];
-pxp(rxpkt);
+ rxpkt = &c->rda[c->rh];
while(rxpkt->owner == Host){
- ctlr->inpackets++;
+ c->inpackets++;
/*
* If the packet was received OK, pass it up,
* otherwise log the error.
- * SONIC gives us the CRC in the packet, so
- * remember to subtract it from the length.
*/
-
- if(rxpkt->status & Prx) {
- x = (rxpkt->count & 0xFFFF)-4;
- p = (Etherpkt*)ctlr->rb[ctlr->rh];
- t = (p->type[0]<<8) | p->type[1];
- for(fp = ctlr->f; fp < &ctlr->f[Ntypes]; fp++){
- f = *fp;
- if(f == 0)
- continue;
- if(f->type == t || f->type < 0)
- qproduce(f->in, p->d, x);
- }
- }
+ if(rxpkt->status & Prx)
+ sonicpkt(c, rxpkt, (Pbuf*)c->rb[c->rh]);
else
if(rxpkt->status & Fae)
- ctlr->frames++;
+ c->frames++;
else
if(rxpkt->status & Crc)
- ctlr->crcs++;
+ c->crcs++;
else
- ctlr->buffs++;
+ c->buffs++;
/*
* Finished with this packet, it becomes the
@@ 475,10 497,10 @@ pxp(rxpkt);
*/
rxpkt->link |= Eol;
rxpkt->owner = Interface;
- ctlr->rda[PREV(ctlr->rh, Nrb)].link &= ~Eol;
- ctlr->rh = NEXT(ctlr->rh, Nrb);
+ c->rda[PREV(c->rh, Nrb)].link &= ~Eol;
+ c->rh = NEXT(c->rh, Nrb);
- rxpkt = &ctlr->rda[ctlr->rh];
+ rxpkt = &c->rda[c->rh];
}
status &= ~(Pktrx|Rde);
@@ 494,16 516,16 @@ pxp(rxpkt);
* Warnings that something is afoot.
*/
if(status & Hbl){
- iprint("sonic: cd heartbeat lost\n");
+ print("sonic: cd heartbeat lost\n");
status &= ~Hbl;
}
if(status & Br){
- iprint("sonic: bus retry occurred\n");
+ print("sonic: bus retry occurred\n");
status &= ~Br;
}
if(status & AllIntr)
- iprint("sonic #%lux\n", status);
+ print("sonic #%lux\n", status);
}
}
@@ 524,6 546,47 @@ promiscuous(void *arg, int on)
WR(rcr, reg&~Pro);
}
+static void
+initbufs(Ether *c)
+{
+ int i;
+ uchar *mem;
+
+ mem = xspanalloc(64*1024, BY2PG, 0);
+ mem = CACHELINE(uchar, mem);
+
+ /*
+ * Descriptors must be built in uncached space
+ */
+ c->rra = UNCACHED(RXrsc, mem);
+ mem = QUAD(uchar, mem+Nrb*sizeof(RXrsc));
+
+ c->rda = UNCACHED(RXpkt, mem);
+ mem = QUAD(uchar, mem+Nrb*sizeof(RXpkt));
+
+ c->tda = UNCACHED(TXpkt, mem);
+ mem = QUAD(uchar, mem+Ntb*sizeof(TXpkt));
+
+ c->cda = UNCACHED(Cam, mem);
+
+ /*
+ * DMA buffers are cache coherent - but we must not straddle
+ * a cache line
+ */
+ mem = CACHELINE(uchar, mem+sizeof(Cam));
+
+ for(i = 0; i < Nrb; i++) {
+ c->rb[i] = UNCACHED(uchar, mem);
+ mem += sizeof(Pbuf)+4;
+ mem = QUAD(uchar, mem);
+ }
+ for(i = 0; i < Ntb; i++) {
+ c->tb[i] = UNCACHED(uchar, mem);
+ mem += sizeof(Pbuf);
+ mem = QUAD(uchar, mem);
+ }
+}
+
void
etherreset(void)
{
@@ 535,12 598,11 @@ etherreset(void)
* Set the physical ethernet address and
* prime the interrupt handler.
*/
- if(ether[0] == 0) {
- ether[0] = xspanalloc(sizeof(Ether), BY2PG, 64*1024);
-
- if(PADDR(ether[0])+sizeof(Ether) > Ntranslation*BY2PG)
- panic("sonic: 16M io map");
+ if(ether[0] == 0) {
+ ctlr = malloc(sizeof(Ether));
+ ether[0] = ctlr;
+ initbufs(ctlr);
enetaddr(ether[0]->ea);
}
ctlr = ether[0];
@@ 559,12 621,6 @@ etherreset(void)
}
void
-enab(void)
-{
- WR(cr, Rxen);
-}
-
-void
etherinit(void)
{
}
@@ 578,7 634,6 @@ etherattach(char *spec)
enable = 1;
WR(cr, Rxen);
}
-
return devattach('l', spec);
}
@@ 629,14 684,12 @@ isoutbuf(void *arg)
long
etherwrite(Chan *c, void *buf, long n, ulong offset)
{
- Etherpkt *p;
+ Pbuf *p;
TXpkt *txpkt;
Ether *ctlr = ether[0];
USED(offset);
-iprint("ether tx\n");
-
if(n > ETHERMAXTU)
error(Ebadarg);
@@ 651,13 704,14 @@ iprint("ether tx\n");
if(!isoutbuf(ctlr))
print("ether transmitter jammed\n");
else {
- p =(Etherpkt*)ctlr->tb[ctlr->th];
+ p =(Pbuf*)ctlr->tb[ctlr->th];
memmove(p->d, buf, n);
if(n < 60) {
memset(p->d+n, 0, 60-n);
n = 60;
}
memmove(p->s, ctlr->ea, sizeof(ctlr->ea));
+ sonicswap(p, n);
txpkt = &ctlr->tda[ctlr->th];
txpkt->size = n;
@@ 671,8 725,6 @@ iprint("ether tx\n");
}
qunlock(&ctlr->tlock);
-iprint("tx done %d\n", n);
-
return n;
}
@@ 693,3 745,22 @@ etherwstat(Chan *c, char *dp)
{
netifwstat(ether[0], c, dp);
}
+
+#define swiz(s) (s<<24)|((s>>8)&0xff00)|((s<<8)&0xff0000)|(s>>24)
+
+void
+sonicswap(void *a, int n)
+{
+ ulong *p, t0, t1;
+
+ n = ((n+8)/8)*8;
+ p = a;
+ while(n) {
+ t0 = p[0];
+ t1 = p[1];
+ p[0] = swiz(t1);
+ p[1] = swiz(t0);
+ p += 2;
+ n -= 8;
+ }
+}
M carrera/fns.h => carrera/fns.h +1 -7
@@ 78,14 78,8 @@ void* pxspanalloc(ulong, int, ulong);
ulong rdcount(void);
int readlog(ulong, char*, ulong);
void restfpregs(FPsave*, ulong);
-void screeninit(int);
+void screeninit(void);
#define screenputs
-void sethandler(int, void(*)(void));
-void setled(int);
-void setleveldest(int, int, uvlong*);
-void sinit(void);
-uchar* smap(int, uchar*);
-void sunmap(int, uchar*);
void syslog(char*, int);
void sysloginit(void);
int tas(ulong*);
M carrera/io.h => carrera/io.h +12 -2
@@ 4,6 4,7 @@
enum
{
Devicephys = 0x80000000,
+ Eisaphys = 0x90000000,
Devicevirt = 0xE0000000,
Dmabase = 0xE0000000,
Sonicbase = 0xE0001000,
@@ 17,11 18,13 @@ enum
Nvram = 0xE0009000,
NvramRW = 0xE000A000,
NvramRO = 0xE000B000,
+ Enetoffset = 0,
KeyboardIO = 0xE0005000,
MouseIO = 0xE0005000,
SoundIO = 0xE000C000,
EisaLatch = 0xE000E000,
Diag = 0xE000F000,
+ EisaControl = 0xE0010000, /* Second 64K Page from Devicevirt */
VideoCTL = 0x60000000,
VideoMEM = 0x40000000,
I386ack = 0xE000023f,
@@ 46,11 49,18 @@ enum
Ntranslation = 4096, /* Number of translation registers */
};
-#define IO(type, reg) (*(type*)reg)
-
typedef struct Tte Tte;
struct Tte
{
ulong hi;
ulong lo;
};
+
+#define IO(type, reg) (*(type*)reg)
+#define QUAD(type, v) (type*)(((ulong)(v)+7)&~7)
+#define CACHELINE(type, v) (type*)(((ulong)(v)+127)&~127)
+#define UNCACHED(type, v) (type*)((ulong)(v)|0xA0000000)
+
+#define EISAUNCACHED(v) (0xA0000000|0x10000000|(v))
+#define EISAOUTB(port, v) *(uchar*)((EisaControl+(port))^7) = v
+#define EISAINB(port) (*(uchar*)((EisaControl+(port))^7))
M carrera/main.c => carrera/main.c +25 -22
@@ 54,10 54,7 @@ main(void)
rootfiles();
swapinit();
userinit();
-enab();
-spllo();
-for(;;)
- ;
+screeninit();
schedinit();
}
@@ 166,31 163,44 @@ serialinit(void)
void
ioinit(void)
{
- ulong phys;
+ ulong devphys, isaphys, intphys;
/*
- * Map devices
+ * Map devices and the Eisa control space
*/
- phys = PPN(Devicephys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
- puttlbx(1, Devicevirt, phys, PTEGLOBL, PGSZ64K);
+ devphys = PPN(Devicephys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
+ isaphys = PPN(Eisaphys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
+
+ puttlbx(1, Devicevirt, devphys, isaphys, PGSZ64K);
/*
* Map Interrupt control
*/
- phys = PPN(Intctlphys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
- puttlbx(2, Intctlvirt, phys, PTEGLOBL, PGSZ4K);
+ intphys = PPN(Intctlphys)|PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED;
+ puttlbx(2, Intctlvirt, intphys, PTEGLOBL, PGSZ4K);
/* Enable all devce interrupt */
IO(ushort, Intenareg) = 0xffff;
}
+/*
+ * Pull the ethernet address out of NVRAM
+ */
void
enetaddr(uchar *ea)
{
- /** BUG get from PROM */
- static uchar tea[] = { 0x00, 0x00, 0x77, 0x01, 0xD2, 0xba };
+ int i;
+ uchar tbuf[8];
+
+ for(i = 0; i < 8; i++)
+ tbuf[i] = ((uchar*)(NvramRO+Enetoffset))[i];
- memmove(ea, tea, sizeof(tea));
+ print("ether:");
+ for(i = 0; i < 6; i++) {
+ ea[i] = tbuf[7-i];
+ print("%2.2ux", ea[i]);
+ }
+ print("\n");
}
/*
@@ 360,6 370,8 @@ confinit(void)
conf.arp = 32;
conf.frag = 32;
+ conf.monitor = 1;
+
conf.copymode = 0; /* copy on write */
}
@@ 379,12 391,3 @@ buzz(int f, int d)
USED(f);
USED(d);
}
-
-int
-mouseputc(IOQ *q, int c)
-{
- USED(q);
- USED(c);
- return 0;
-}
-
M carrera/mem.h => carrera/mem.h +5 -10
@@ 78,9 78,8 @@
#define CU1 0x20000000
/*
- * Traps
+ * Trap vectors
*/
-
#define UTLBMISS (KSEG0+0x000)
#define XEXCEPTION (KSEG0+0x80)
#define CACHETRAP (KSEG0+0x100)
@@ 89,7 88,6 @@
/*
* Magic registers
*/
-
#define USER 24 /* R24 is up-> */
#define MACH 25 /* R25 is m-> */
@@ 97,17 95,12 @@
* Fundamental addresses
*/
#define MACHADDR 0x80005000 /* Mach structures */
-/* Leave space below kmap for IO */
-#define KMAPADDR 0xE0040000
-/* Sizeof(Ureg)+space for retpc & ur */
-#define UREGSIZE 0xA0
+#define UREGSIZE 0xA0 /* Sizeof(Ureg)+retpc & ur */
#define MACHP(n) ((Mach *)(MACHADDR+(n)*BY2PG))
-
/*
* MMU
*/
-
#define PGSZ4K (0x00<<13)
#define PGSZ64K (0x0F<<13)
#define PGSZ256K (0x3F<<13)
@@ 121,9 114,11 @@
#define PIDXSHFT 12
#define PIDX (0x7<<PIDXSHFT)
+#define KMAPADDR 0xE1000000
+#define KMAPMASK 0xFF000000
#define KMAPSHIFT 15
#define NCOLOR 8
-#define getcolor(a) (((ulong)(a)>>PIDXSHFT)&7)
+#define getpgcolor(a) (((ulong)(a)>>PIDXSHFT)&7)
#define PTEGLOBL (1<<0)
#define PTEVALID (1<<1)
M carrera/mmu.c => carrera/mmu.c +5 -3
@@ 143,9 143,9 @@ void
kfault(ulong addr)
{
KMap *k, *f;
- ulong x, index;
+ ulong x, index, virt;
- index = (addr & ~KSEGM) >> KMAPSHIFT;
+ index = (addr & ~KMAPADDR) >> KMAPSHIFT;
if(index >= KPTESIZE)
panic("kmapfault: %lux", addr);
@@ 163,7 163,9 @@ kfault(ulong addr)
}
x = m->ktlbnext;
- puttlbx(x, (k->virt & ~BY2PG)|TLBPID(tlbvirt()), k->phys0, k->phys1, PGSZ4K);
+ virt = (k->virt&~BY2PG)|TLBPID(tlbvirt());
+ puttlbx(x, virt, k->phys0, k->phys1, PGSZ4K);
+
m->ktlbx[x] = 1;
if(++x >= NTLB)
m->ktlbnext = TLBROFF;
A carrera/screen.c => carrera/screen.c +438 -0
@@ 0,0 1,438 @@
+#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 <libg.h>
+#include <gnot.h>
+
+#define MINX 8
+
+enum
+{
+ EMISCR= 0x3CC, /* control sync polarity */
+ EMISCW= 0x3C2,
+ EFCW= 0x3DA, /* feature control */
+ EFCR= 0x3CA,
+ GRX= 0x3CE, /* index to graphics registers */
+ GR= 0x3CF, /* graphics registers */
+ Grms= 0x04, /* read map select register */
+ SRX= 0x3C4, /* index to sequence registers */
+ SR= 0x3C5, /* sequence registers */
+ Smmask= 0x02, /* map mask */
+ CRX= 0x3D4, /* index to crt registers */
+ CR= 0x3D5, /* crt registers */
+ Cvre= 0x11, /* vertical retrace end */
+ ARW= 0x3C0, /* attribute registers (writing) */
+ ARR= 0x3C1, /* attribute registers (reading) */
+ CMRX= 0x3C7, /* color map read index */
+ CMWX= 0x3C8, /* color map write index */
+ CM= 0x3C9, /* color map data reg */
+};
+
+typedef struct VGAmode VGAmode;
+struct VGAmode
+{
+ uchar general[2];
+ uchar sequencer[5];
+ uchar crt[0x19];
+ uchar graphics[9];
+ uchar attribute[0x15];
+ uchar special[12];
+};
+
+void setmode(VGAmode*);
+
+extern struct GBitmap gscreen;
+
+VGAmode dfltmode =
+{
+ /* general */
+ 0xef, 0x00,
+ /* sequence */
+ 0x03, 0x01, 0x0f, 0x00, 0x0e,
+ /* crt */
+ 0xa1, 0x7f, 0x7f, 0x85, 0x85, 0x96, 0x24, 0xf5,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0xff, 0x80, 0x60, 0xff, 0x25, 0xab,
+ 0xff,
+ /* graphics */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
+ 0xff,
+ /* attribute */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x01, 0x00, 0x0f, 0x00, 0x00,
+ /* special */
+ 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x28, 0x00,
+ 0x0a, 0x00, 0x43, 0x1f,
+};
+
+extern GSubfont defont0;
+GSubfont *defont;
+
+static ulong rep(ulong, int);
+
+struct{
+ Point pos;
+ int bwid;
+}out;
+
+Lock screenlock;
+
+GBitmap gscreen =
+{
+ EISAUNCACHED(0xA0000),
+ 0,
+ (1024*(1<<3))/32,
+ 3,
+ { 0, 0, 1024, 768 },
+ { 0, 0, 1024, 768 },
+ 0
+};
+
+static GBitmap hwcursor=
+{
+ 0, /* base filled in by malloc when needed */
+ 0,
+ 4,
+ 1,
+ {0, 0, 64, 64},
+ {0, 0, 64, 64}
+};
+
+uchar bdata[] =
+{
+ 0xC0,
+};
+
+GBitmap bgrnd =
+{
+ (ulong*)bdata,
+ 0,
+ 4,
+ 3,
+ { 0, 0, 1, 1 },
+ { 0, 0, 1, 1 },
+ 0
+};
+
+/*
+ * a fatter than usual cursor for the safari
+ */
+Cursor fatarrow = {
+ { -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 Rectangle window;
+static Point cursor;
+static int h, w;
+extern Cursor arrow;
+
+void
+gborder(GBitmap *l, Rectangle r, int i, Fcode c)
+{
+ if(i < 0){
+ r = inset(r, i);
+ i = -i;
+ }
+ gbitblt(l, r.min, l, Rect(r.min.x, r.min.y, r.max.x, r.min.y+i), c);
+ gbitblt(l, Pt(r.min.x, r.max.y-i),
+ l, Rect(r.min.x, r.max.y-i, r.max.x, r.max.y), c);
+ gbitblt(l, Pt(r.min.x, r.min.y+i),
+ l, Rect(r.min.x, r.min.y+i, r.min.x+i, r.max.y-i), c);
+ gbitblt(l, Pt(r.max.x-i, r.min.y+i),
+ l, Rect(r.max.x-i, r.min.y+i, r.max.x, r.max.y-i), c);
+}
+
+void
+screenwin(void)
+{
+ gtexture(&gscreen, gscreen.r, &bgrnd, S);
+ w = defont0.info[' '].width;
+ h = defont0.height;
+
+ window.min = Pt(100, 100);
+ window.max = add(window.min, Pt(10+w*120, 10+h*60));
+
+ gbitblt(&gscreen, window.min, &gscreen, window, Zero);
+ window = inset(window, 5);
+ cursor = window.min;
+ window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
+
+ hwcurs = 0;
+}
+
+void
+screeninit(void)
+{
+ setmode(&dfltmode);
+
+ memmove(&arrow, &fatarrow, sizeof(fatarrow));
+
+ /* save space; let bitblt do the conversion work */
+ defont = &defont0;
+ gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0);
+ out.pos.x = MINX;
+ out.pos.y = 0;
+ out.bwid = defont0.info[' '].width;
+
+ screenwin();
+}
+
+static void
+scroll(void)
+{
+ int o;
+ Rectangle r;
+
+ o = 5*h;
+ r = Rpt(Pt(window.min.x, window.min.y+o), window.max);
+ gbitblt(&gscreen, window.min, &gscreen, r, S);
+ r = Rpt(Pt(window.min.x, window.max.y-o), window.max);
+ gbitblt(&gscreen, r.min, &gscreen, r, Zero);
+ cursor.y -= o;
+}
+
+static void
+screenputc(char *buf)
+{
+ int pos;
+
+ switch(buf[0]) {
+ case '\n':
+ if(cursor.y+h >= window.max.y)
+ scroll();
+ cursor.y += h;
+ screenputc("\r");
+ break;
+ case '\r':
+ cursor.x = window.min.x;
+ break;
+ case '\t':
+ pos = (cursor.x-window.min.x)/w;
+ pos = 8-(pos%8);
+ cursor.x += pos*w;
+ break;
+ case '\b':
+ if(cursor.x-w >= 0)
+ cursor.x -= w;
+ break;
+ default:
+ if(cursor.x >= window.max.x-w)
+ screenputc("\n");
+ cursor = gsubfstring(&gscreen, cursor, &defont0, buf, S);
+ }
+}
+
+#ifdef USEME
+void
+screenputs(char *s, int n)
+{
+ int i;
+ Rune r;
+ char buf[4];
+
+ if((getstatus() & IEC) == 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);
+ }
+ unlock(&screenlock);
+}
+#endif
+
+/* replicate (from top) value in v (n bits) until it fills a ulong */
+static ulong
+rep(ulong v, int n)
+{
+ int o;
+ ulong rv;
+
+ rv = 0;
+ for(o = 32 - n; o >= 0; o -= n)
+ rv |= (v << o);
+ return rv;
+}
+
+void
+getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
+{
+ ulong ans;
+
+ /*
+ * The gnot says 0 is white (max intensity)
+ */
+ if(gscreen.ldepth == 0){
+ if(p == 0)
+ ans = ~0;
+ else
+ ans = 0;
+ }else{
+ switch(p){
+ case 0: ans = ~0; break;
+ case 1: ans = 0xAAAAAAAA; break;
+ case 2: ans = 0x55555555; break;
+ default: ans = 0; break;
+ }
+ }
+ *pr = *pg = *pb = ans;
+}
+
+int
+setcolor(ulong p, ulong r, ulong g, ulong b)
+{
+ USED(p, r, g, b);
+ return 0; /* can't change mono screen colormap */
+}
+
+void
+hwcursset(ulong *s, ulong *c, int ox, int oy)
+{
+ USED(s, c, ox, oy);
+}
+
+void
+hwcursmove(int x, int y)
+{
+ USED(x, y);
+}
+
+/* only 1 flavor mouse */
+void
+mousectl(char *x)
+{
+ USED(x);
+}
+
+/* bits per pixel */
+int
+screenbits(void)
+{
+ return 1<<gscreen.ldepth;
+}
+
+void
+mbbrect(Rectangle r)
+{
+ USED(r);
+}
+
+void
+mbbpt(Point p)
+{
+ USED(p);
+}
+
+void
+srout(int reg, int val)
+{
+ EISAOUTB(SRX, reg);
+ EISAOUTB(SR, val);
+}
+
+void
+grout(int reg, int val)
+{
+ EISAOUTB(GRX, reg);
+ EISAOUTB(GR, val);
+}
+
+void
+genout(int reg, int val)
+{
+ if(reg == 0)
+ EISAOUTB(EMISCW, val);
+ else if (reg == 1)
+ EISAOUTB(EFCW, val);
+}
+
+void
+arout(int reg, int val)
+{
+ uchar junk;
+
+ junk = EISAINB(0x3DA);
+ USED(junk);
+
+ if (reg <= 0xf) {
+ EISAOUTB(ARW, reg | 0x0);
+ EISAOUTB(ARW, val);
+ junk = EISAINB(0x3DA);
+ USED(junk);
+ EISAOUTB(ARW, reg | 0x20);
+ } else {
+ EISAOUTB(ARW, reg | 0x20);
+ EISAOUTB(ARW, val);
+ }
+}
+
+void
+crout(int reg, int val)
+{
+ EISAOUTB(CRX, reg);
+ EISAOUTB(CR, val);
+}
+
+void
+setmode(VGAmode *v)
+{
+ int i;
+
+ /* turn screen off (to avoid damage) */
+ srout(1, 0x21);
+
+ for(i = 0; i < sizeof(v->general); i++)
+ genout(i, v->general[i]);
+
+ for(i = 0; i < sizeof(v->sequencer); i++)
+ if(i == 1)
+ srout(i, v->sequencer[i]|0x20);
+ else
+ srout(i, v->sequencer[i]);
+
+ crout(Cvre, 0); /* allow writes to CRT registers 0-7 */
+ for(i = 0; i < sizeof(v->crt); i++)
+ crout(i, v->crt[i]);
+
+ for(i = 0; i < sizeof(v->graphics); i++)
+ grout(i, v->graphics[i]);
+
+ for(i = 0; i < sizeof(v->attribute); i++)
+ arout(i, v->attribute[i]);
+
+ /* turn screen on */
+ srout(1, v->sequencer[1]);
+}
A carrera/screen.h => carrera/screen.h +8 -0
@@ 0,0 1,8 @@
+extern void mouseupdate(int);
+
+#define hwscreenwrite(a, b)
+
+#define mbbpt(x)
+#define mbbrect(x)
+#define screenupdate()
+#define mousescreenupdate()
M carrera/trap.c => carrera/trap.c +2 -3
@@ 204,8 204,7 @@ trap(Ureg *ur)
if(up == 0)
kernfault(ur, ecode);
- if(!user && (ur->badvaddr & KSEGM) == KSEG3) {
-iprint("kf %lux %lux\n", ur->pc, ur->r31);
+ if(!user && (ur->badvaddr & KMAPMASK) == KMAPADDR) {
kfault(ur->badvaddr);
break;
}
@@ 392,7 391,7 @@ dumpregs(Ureg *ur)
l = &ur->status;
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]);
+ print("%s\t0x%.8lux\t%s\t0x%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
}
int
M port/devbit.c => port/devbit.c +94 -75
@@ 9,8 9,6 @@
#include "devtab.h"
-#include "screen.h"
-
/*
* Some monochrome screens are reversed from what we like:
* We want 0's bright and 1's dark.
@@ 104,11 102,37 @@ void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode);
void bitloadchar(GFont*, int, GSubfont*, int);
extern GBitmap gscreen;
+typedef struct Mouseinfo Mouseinfo;
+typedef struct Cursorinfo Cursorinfo;
+
+struct Mouseinfo{
+ /*
+ * First three fields are known in some l.s's
+ */
+ int dx;
+ int dy;
+ int track; /* l.s has updated dx & dy */
+ Mouse;
+ int redraw; /* update cursor on screen */
+ ulong counter; /* increments every update */
+ ulong lastcounter; /* value when /dev/mouse read */
+ Rendez r;
+};
+
+struct Cursorinfo{
+ Cursor;
+ Lock;
+ int visible; /* on screen */
+ int disable; /* from being used */
+ Rectangle r; /* location */
+};
+
Mouseinfo mouse;
Cursorinfo cursor;
int mouseshifted;
int mousetype;
int islittle;
+int hwcurs;
Cursor arrow =
{
@@ 269,6 293,7 @@ bitreset(void)
if(!conf.monitor)
return;
+
memmove(&bdefont0, defont, sizeof(*defont));
bdefont = &bdefont0;
bit.map = smalloc(DMAP*sizeof(GBitmap*));
@@ 291,6 316,7 @@ bitreset(void)
* Somewhat of a heuristic: start with three screensful and
* allocate single screensful dynamically if needed.
*/
+
ws = BI2WD>>gscreen.ldepth; /* pixels per word */
a->nwords = 3*(HDR + gscreen.r.max.y*gscreen.r.max.x/ws);
a->words = xalloc(a->nwords*sizeof(ulong));
@@ 524,21 550,16 @@ bitread(Chan *c, void *va, long n, ulong offset)
*/
if(n < 14)
error(Ebadblt);
- Again:
- while(mouse.changed == 0)
+ while(mousechanged(0) == 0)
sleep(&mouse.r, mousechanged, 0);
lock(&cursor);
- if(mouse.changed == 0){
- unlock(&cursor);
- goto Again;
- }
p = va;
p[0] = 'm';
p[1] = mouse.buttons;
BPLONG(p+2, mouse.xy.x);
BPLONG(p+6, mouse.xy.y);
BPLONG(p+10, TK2MS(MACHP(0)->ticks));
- mouse.changed = 0;
+ mouse.lastcounter = mouse.counter;
unlock(&cursor);
return 14;
}
@@ 546,7 567,7 @@ bitread(Chan *c, void *va, long n, ulong offset)
if(offset==0){
if(n < 5*12)
error(Eio);
- sprint(va, "%11d %11d %11d %11d %11d ",
+ sprint(va, "%11d %11d %11d %11d %11d",
gscreen.ldepth, gscreen.r.min.x,
gscreen.r.min.y, gscreen.r.max.x,
gscreen.r.max.y);
@@ 712,7 733,7 @@ bitread(Chan *c, void *va, long n, ulong offset)
error(Ebadblt);
for(j = 0; j < nw; j++){
if(bit.mid == 0){
- getcolor(flipping? ~j : j, &rv, &gv, &bv);
+ getcolor(flipping? nw-j-1 : j, &rv, &gv, &bv);
}else{
rv = j;
for(off = 32-l; off > 0; off -= l)
@@ 1566,8 1587,6 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
p += l;
m -= l;
}
- if(v == 0)
- hwscreenwrite(miny, maxy);
break;
case 'x':
@@ 1583,6 1602,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
pt1.y = BGLONG(p+5);
if(ptinrect(pt1, gscreen.r)){
mouse.xy = pt1;
+ mouse.redraw = 1;
mouse.track = 1;
mouseclock();
}
@@ 1991,6 2011,8 @@ Cursortocursor(Cursor *c)
*p = c->clr[2*i];
*(p+1) = c->clr[2*i+1];
}
+ if(hwcurs)
+ hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y);
unlock(&cursor);
}
@@ 2002,15 2024,19 @@ cursoron(int dolock)
if(dolock)
lock(&cursor);
if(cursor.visible++ == 0){
- cursor.r.min = mouse.xy;
- cursor.r.max = add(mouse.xy, Pt(16, 16));
- cursor.r = raddp(cursor.r, cursor.offset);
- gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
- gbitblt(&gscreen, cursor.r.min,
- &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S);
- gbitblt(&gscreen, cursor.r.min,
- &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D);
- mbbrect(cursor.r);
+ if(hwcurs)
+ hwcursmove(mouse.xy.x, mouse.xy.y);
+ else {
+ cursor.r.min = mouse.xy;
+ cursor.r.max = add(mouse.xy, Pt(16, 16));
+ cursor.r = raddp(cursor.r, cursor.offset);
+ gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S);
+ gbitblt(&gscreen, cursor.r.min,
+ &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S);
+ gbitblt(&gscreen, cursor.r.min,
+ &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D);
+ mbbrect(cursor.r);
+ }
}
if(dolock)
unlock(&cursor);
@@ 2024,69 2050,61 @@ cursoroff(int dolock)
if(dolock)
lock(&cursor);
if(--cursor.visible == 0) {
- gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
- mbbrect(cursor.r);
- mousescreenupdate();
+ if(!hwcurs) {
+ gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S);
+ mbbrect(cursor.r);
+ mousescreenupdate();
+ }
}
if(dolock)
unlock(&cursor);
}
+/*
+ * called by the clock routine to redraw the cursor
+ */
void
-mousedelta(int b, int dx, int dy) /* called at higher priority */
-{
- mouse.dx += dx;
- mouse.dy += dy;
- mouse.newbuttons = b;
- mouse.track = 1;
-}
-
-void
-mousebuttons(int b) /* called at higher priority */
+mouseclock(void)
{
- /*
- * It is possible if you click very fast and get bad luck
- * you could miss a button click (down up). Doesn't seem
- * likely or important enough to worry about.
- */
- mouse.newbuttons = b;
- mouse.track = 1; /* aggressive but o.k. */
- mouseclock();
+ if(mouse.track){
+ mousetrack(mouse.buttons, mouse.dx, mouse.dy);
+ mouse.track = 0;
+ mouse.dx = 0;
+ mouse.dy = 0;
+ }
+ if(mouse.redraw && canlock(&cursor)){
+ mouse.redraw = 0;
+ cursoroff(0);
+ cursoron(0);
+ mousescreenupdate();
+ unlock(&cursor);
+ }
}
+/*
+ * called at interrupt level to update the structure and
+ * awaken any waiting procs.
+ */
void
-mouseupdate(int dolock)
+mousetrack(int b, int dx, int dy)
{
int x, y;
- if(!mouse.track || (dolock && !canlock(&cursor)))
- return;
-
- x = mouse.xy.x + mouse.dx;
+ x = mouse.xy.x + dx;
if(x < gscreen.r.min.x)
x = gscreen.r.min.x;
if(x >= gscreen.r.max.x)
x = gscreen.r.max.x;
- y = mouse.xy.y + mouse.dy;
+ y = mouse.xy.y + dy;
if(y < gscreen.r.min.y)
y = gscreen.r.min.y;
if(y >= gscreen.r.max.y)
y = gscreen.r.max.y;
- cursoroff(0);
+ mouse.counter++;
mouse.xy = Pt(x, y);
- cursoron(0);
- mousescreenupdate();
- mouse.dx = 0;
- mouse.dy = 0;
- mouse.clock = 0;
- mouse.track = 0;
- mouse.buttons = mouse.newbuttons;
- mouse.changed = 1;
-
- if(dolock){
- unlock(&cursor);
- wakeup(&mouse.r);
- }
+ mouse.buttons = b;
+ mouse.redraw = 1;
+ wakeup(&mouse.r);
}
/*
@@ 2107,6 2125,7 @@ m3mouseputc(IOQ *q, int c)
static int middle;
static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 };
short x;
+ int dx, dy, newbuttons;
USED(q);
/*
@@ 2116,20 2135,20 @@ m3mouseputc(IOQ *q, int c)
if((c&0x40) == 0){
/* an extra byte gets sent for the middle button */
middle = (c&0x20) ? 2 : 0;
- mousebuttons((mouse.buttons & ~2) | middle);
+ newbuttons = (mouse.buttons & ~2) | middle;
+ mousetrack(newbuttons, 0, 0);
return 0;
}
}
msg[nb] = c;
if(++nb == 3){
nb = 0;
- mouse.newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
+ newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)];
x = (msg[0]&0x3)<<14;
- mouse.dx = (x>>8) | msg[1];
+ dx = (x>>8) | msg[1];
x = (msg[0]&0xc)<<12;
- mouse.dy = (x>>8) | msg[2];
- mouse.track = 1;
- mouseclock();
+ dy = (x>>8) | msg[2];
+ mousetrack(newbuttons, dx, dy);
}
return 0;
}
@@ 2145,6 2164,7 @@ mouseputc(IOQ *q, int c)
static short msg[5];
static int nb;
static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7};
+ int dx, dy, newbuttons;
USED(q);
if((c&0xF0) == 0x80)
@@ 2153,11 2173,10 @@ mouseputc(IOQ *q, int c)
if(c & 0x80)
msg[nb] |= ~0xFF; /* sign extend */
if(++nb == 5){
- mouse.newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
- mouse.dx = msg[1]+msg[3];
- mouse.dy = -(msg[2]+msg[4]);
- mouse.track = 1;
- mouseclock();
+ newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
+ dx = msg[1]+msg[3];
+ dy = -(msg[2]+msg[4]);
+ mousetrack(newbuttons, dx, dy);
nb = 0;
}
return 0;
@@ 2167,7 2186,7 @@ int
mousechanged(void *m)
{
USED(m);
- return mouse.changed;
+ return mouse.lastcounter != mouse.counter;
}
/*
M port/devcons.c => port/devcons.c +0 -1
@@ 122,7 122,6 @@ panic(char *fmt, ...)
strcpy(buf, "panic: ");
n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, (&fmt+1)) - buf;
buf[n] = '\n';
-iprint("%s\n", buf);
putstrn(buf, n+1);
prflush();
dumpstack();
M port/page.c => port/page.c +2 -2
@@ 71,7 71,7 @@ newpage(int clear, Segment **s, ulong va)
retry:
lock(&palloc);
- color = getcolor(va);
+ color = getpgcolor(va);
hw = swapalloc.highwater;
for(;;) {
if(palloc.freecol[color] > hw)
@@ 233,7 233,7 @@ duppage(Page *p) /* Always call with p locked */
return;
}
- color = getcolor(p->va);
+ color = getpgcolor(p->va);
for(np = palloc.head; np; np = np->next)
if(np->color == color)
break;
M port/portdat.h => port/portdat.h +1 -0
@@ 623,6 623,7 @@ extern Rune* devchar;
extern Dev devtab[];
extern char eve[];
extern char hostdomain[];
+extern int hwcurs;
extern uchar initcode[];
extern FPsave initfp;
extern Queue *kbdq;
M port/portfns.h => port/portfns.h +4 -2
@@ 81,13 81,14 @@ void freechan(Chan*);
void freepte(Segment*, Pte*);
void freesegs(int);
void freesession(Session*);
+void getcolor(ulong, ulong*, ulong*, ulong*);
int getfields(char*, char**, int, char);
void gotolabel(Label*);
int haswaitq(void*);
long hostdomainwrite(char*, int);
long hostownerwrite(char*, int);
-int hwcursmove(int, int);
-int hwcursset(uchar*, uchar*, int, int);
+void hwcursset(ulong*, ulong*, int, int);
+void hwcursmove(int, int);
void iallocinit(void);
long ibrk(ulong, int);
int incref(Ref*);
@@ 124,6 125,7 @@ void mmurelease(Proc*);
void mmuswitch(Proc*);
void mntdump(void);
void mntrepl(char*);
+void mousetrack(int, int, int);
int mount(Chan*, Chan*, int, char*);
void mountfree(Mount*);
void mousebuttons(int);