alpha updates. [jmk] --rw-rw-r-- M 436305 glenda sys 4618 Jan 13 14:19 sys/src/9/alphapc/io.h /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/io.h:127,136 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/io.h:127,140 ushort vid; /* vendor ID */ ushort did; /* device ID */ + ushort pcr; + uchar rid; uchar ccrp; uchar ccru; uchar ccrb; + uchar cls; + uchar ltr; struct { ulong bar; /* base address */ /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/io.h:147,153 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/io.h:151,158 ulong bar; int size; } ioa, mema; - ulong pcr; + + int pmrb; /* power management register block */ }; #define PCIWINDOW 0x40000000 [jmk] --rw-rw-r-- M 436305 glenda sys 9141 Jan 13 14:19 sys/src/9/alphapc/l.s /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:1,4 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:1,5 #include "mem.h" + #include "osf1pal.h" #define SP R30 /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:174,195 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:175,196 RET TEXT _xdec(SB), $-8 - MOVQ R0, R1 /* p */ + MOVQ R0, R1 /* p */ dec1: MOVLL (R1), R0 /* *p */ - SUBL $1, R0 + SUBL $1, R0 MOVQ R0, R2 MOVLC R2, (R1) /* --(*p) */ - BEQ R2, dec1 /* write failed, retry */ + BEQ R2, dec1 /* write failed, retry */ RET TEXT _xinc(SB), $-8 - MOVQ R0, R1 /* p */ + MOVQ R0, R1 /* p */ inc1: MOVLL (R1), R0 /* *p */ ADDL $1, R0 MOVLC R0, (R1) /* (*p)++ */ - BEQ R0, inc1 /* write failed, retry */ + BEQ R0, inc1 /* write failed, retry */ RET TEXT fpenab(SB), $-8 /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:222,246 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:223,247 SUBQ $(4*BY2WD+31*BY2V), R30 MOVQ R0, (4*BY2WD+4*BY2V)(R30) MOVQ $1, R0 - JMP trapcommon + JMP trapcommon TEXT illegal0(SB), $-8 SUBQ $(4*BY2WD+31*BY2V), R30 MOVQ R0, (4*BY2WD+4*BY2V)(R30) MOVQ $2, R0 - JMP trapcommon + JMP trapcommon TEXT fault0(SB), $-8 SUBQ $(4*BY2WD+31*BY2V), R30 MOVQ R0, (4*BY2WD+4*BY2V)(R30) MOVQ $4, R0 - JMP trapcommon + JMP trapcommon TEXT unaligned(SB), $-8 SUBQ $(4*BY2WD+31*BY2V), R30 MOVQ R0, (4*BY2WD+4*BY2V)(R30) MOVQ $6, R0 - JMP trapcommon + JMP trapcommon TEXT intr0(SB), $-8 SUBQ $(4*BY2WD+31*BY2V), R30 /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:283,294 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:284,295 MOVQ $HI_IPL, R16 CALL_PAL $PALswpipl - CALL_PAL $PALrdusp + CALL_PAL $PALrdusp MOVQ R0, (4*BY2WD+30*BY2V)(R30) /* save USP */ MOVQ $mach0(SB), R(MACH) MOVQ $(4*BY2WD)(R30), R0 - JSR trap(SB) + JSR trap(SB) trapret: MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */ CALL_PAL $PALwrusp /* ... */ /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:320,329 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:321,330 MOVQ (4*BY2WD+29*BY2V)(R30), R28 /* USP already restored from (4*BY2WD+30*BY2V)(R30) */ ADDQ $(4*BY2WD+31*BY2V), R30 - CALL_PAL $PALrti + CALL_PAL $PALrti TEXT forkret(SB), $0 - MOVQ R31, R0 /* Fake out system call return */ + MOVQ R31, R0 /* Fake out system call return */ JMP systrapret TEXT syscall0(SB), $-8 /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:339,348 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:340,349 JSR syscall(SB) systrapret: MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */ - CALL_PAL $PALwrusp /* consider doing this in execregs... */ + CALL_PAL $PALwrusp /* consider doing this in execregs... */ MOVQ (4*BY2WD+27*BY2V)(R30), R26 /* restore last return address */ ADDQ $(4*BY2WD+31*BY2V), R30 - CALL_PAL $PALretsys + CALL_PAL $PALretsys /* * Take first processor into user mode /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/l.s:355,361 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/l.s:356,362 SUBQ $(6*BY2V), R30 /* create frame for retsys */ MOVQ $(UTZERO+32), R26 /* header appears in text */ MOVQ R26, (1*BY2V)(R30) /* PC -- only reg that matters */ - CALL_PAL $PALretsys + CALL_PAL $PALretsys TEXT rfnote(SB), $0 SUBL $(2*BY2WD), R0, SP [jmk] --rw-rw-r-- M 436305 glenda sys 13675 Jan 13 14:19 sys/src/9/alphapc/main.c /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/main.c:134,140 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/main.c:134,140 Cpuhaltcoldboot = 0x20000, Cpuhaltwarmboot = 0x30000, Cpuhaltstayhalted = 0x40000, - Cpumustbezero = 0xffffffffff000000, /* 24:63 -- must be zero */ + Cpumustbezero = 0xffffffffff000000ULL, /* 24:63 -- must be zero */ }; /* [jmk] --rw-rw-r-- M 436305 glenda sys 2312 Jan 13 14:19 sys/src/9/alphapc/mem.h /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/mem.h:80,125 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/mem.h:80,85 #define USTKSIZE (4*1024*1024) /* size of user stack */ /* - * Palcode instructions a la OSF/1 - */ - #define PALbpt 0x80 - #define PALbugchk 0x81 - #define PALcallsys 0x83 - #define PALimb 0x86 - #define PALgentrap 0xaa - #define PALrdunique 0x9e - #define PALwrunique 0x9f - - #define PALhalt 0x00 - #define PALdraina 0x02 - #define PALcserve 0x09 - #define PALrdps 0x36 - #define PALrdusp 0x3a - #define PALrdval 0x32 - #define PALretsys 0x3d - #define PALrti 0x3f - #define PALswpctx 0x30 - #define PALswpipl 0x35 - #define PALtbi 0x33 - #define PALwhami 0x3c - #define PALwrent 0x34 - #define PALwrfen 0x2b - #define PALwrkgp 0x37 - #define PALwrusp 0x38 - #define PALwrval 0x31 - #define PALwrvptptr 0x2d - - /* - * Plus some useful VMS ones (needed at early boot time) - */ - #define PALmfpr_pcbb 0x12 - #define PALmfpr_ptbr 0x15 - #define PALmfpr_vptb 0x29 - #define PALldqp 0x03 - #define PALstqp 0x04 - #define PALswppal 0x0a - - /* * Processor Status (as returned by rdps) */ #define UMODE 0x8 [jmk] --rw-rw-r-- M 436305 jmk sys 1471 Jan 13 14:19 sys/src/9/alphapc/osf1pal.h [jmk] --rw-rw-r-- M 436305 glenda sys 55257 Jan 13 14:19 sys/src/9/alphapc/sd53c8xx.c /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:2,7 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2,9 * NCR/Symbios/LSI Logic 53c8xx driver for Plan 9 * Nigel Roles (nigel@9fs.org) * + * 27/5/02 Fixed problems with transfers >= 256 * 512 + * * 13/3/01 Fixed microcode to support targets > 7 * * 01/12/00 Removed previous comments. Fixed a small problem in /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:45,57 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:47,60 #define KPRINT oprint #define IPRINT intrprint - #define DEBUG(n) 0 + #define DEBUG(n) 1 #define IFLUSH() iflush() #else - #define KPRINT if(0)print - #define IPRINT if(0)print + static int idebug = 1; + #define KPRINT if(0) iprint + #define IPRINT if(idebug) iprint #define DEBUG(n) (0) #define IFLUSH() /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:205,211 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:208,217 uchar dmablks; uchar flag; /* setbyte(state,3,...) */ - uchar dmaaddr[4]; + union { + ulong dmancr; /* For block transfer: NCR order (little-endian) */ + uchar dmaaddr[4]; + }; uchar target; /* Target */ uchar pad0[3]; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:299,305 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:305,310 struct { Lock; uchar head[4]; /* head of free list (NCR byte order) */ - Dsa *tail; Dsa *freechain; } dsalist; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:378,383 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:383,417 #include "sd53c8xx.i" + /* + * We used to use a linked list of Dsas with nil as the terminator, + * but occasionally the 896 card seems not to notice that the 0 + * is really a 0, and then it tries to reference the Dsa at address 0. + * To address this, we use a sentinel dsa that links back to itself + * and has state A_STATE_END. If the card takes an iteration or + * two to notice that the state says A_STATE_END, that's no big + * deal. Clearly this isn't the right approach, but I'm just + * stumped. Even with this, we occasionally get prints about + * "WSR set", usually with about the same frequency that the + * card used to walk past 0. + */ + static Dsa *dsaend; + + static Dsa* + dsaallocnew(Controller *c) + { + Dsa *d; + + /* c->dsalist must be ilocked */ + d = xalloc(sizeof *d); + lesetl(d->next, legetl(c->dsalist.head)); + lesetl(&d->stateb, A_STATE_FREE); + coherence(); + lesetl(c->dsalist.head, DMASEG(d)); + coherence(); + return d; + } + static Dsa * dsaalloc(Controller *c, int target, int lun) { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:384,407 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:418,433 Dsa *d; ilock(&c->dsalist); - if ((d = c->dsalist.freechain) == 0) { - d = xalloc(sizeof(*d)); + if ((d = c->dsalist.freechain) != 0) { if (DEBUG(1)) - KPRINT(PRINTPREFIX "%d/%d: allocated new dsa %lux\n", target, lun, (ulong)d); - lesetl(d->next, 0); - lesetl(&d->stateb, A_STATE_ALLOCATED); - if (legetl(c->dsalist.head) == 0) - lesetl(c->dsalist.head, DMASEG(d)); /* ATOMIC?!? */ - else - lesetl(c->dsalist.tail->next, DMASEG(d)); /* ATOMIC?!? */ - c->dsalist.tail = d; - } - else { + IPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d); + } else { + d = dsaallocnew(c); if (DEBUG(1)) - KPRINT(PRINTPREFIX "%d/%d: reused dsa %lux\n", target, lun, (ulong)d); - c->dsalist.freechain = d->freechain; - lesetl(&d->stateb, A_STATE_ALLOCATED); + IPRINT(PRINTPREFIX "%d/%d: allocated dsa %lux\n", target, lun, (ulong)d); } + c->dsalist.freechain = d->freechain; + lesetl(&d->stateb, A_STATE_ALLOCATED); iunlock(&c->dsalist); d->target = target; d->lun = lun; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:418,428 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:444,493 iunlock(&c->dsalist); } + static void + dsadump(Controller *c) + { + Dsa *d; + u32int *a; + + iprint("dsa controller list: c=%p head=%.8lux\n", c, legetl(c->dsalist.head)); + for(d=KPTR(legetl(c->dsalist.head)); d != dsaend; d=KPTR(legetl(d->next))){ + if(d == (void*)-1){ + iprint("\t dsa %p\n", d); + break; + } + a = (u32int*)d; + iprint("\tdsa %p %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux\n", a, a[0], a[1], a[2], a[3], a[4], a[5]); + } + + /* + a = KPTR(c->scriptpa+E_dsa_addr); + iprint("dsa_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n", + a[0], a[1], a[2], a[3], a[4]); + a = KPTR(c->scriptpa+E_issue_addr); + iprint("issue_addr: %.8ux %.8ux %.8ux %.8ux %.8ux\n", + a[0], a[1], a[2], a[3], a[4]); + + a = KPTR(c->scriptpa+E_issue_test_begin); + e = KPTR(c->scriptpa+E_issue_test_end); + iprint("issue_test code (at offset %.8ux):\n", E_issue_test_begin); + + i = 0; + for(; adsalist.head)); d; d = KPTR(legetl(d->next))) { + for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) { if (d->target != 0xff && d->target != target) continue; if (lun != 0xff && d->lun != lun) /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:441,447 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:506,517 Ncr *n = c->n; int depth = c->v->registers / 4; - KPRINT("sa = %.8lux\n", c->scriptpa); + if (intr) { + IPRINT("sa = %.8lux\n", c->scriptpa); + } + else { + KPRINT("sa = %.8lux\n", c->scriptpa); + } for (i = 0; i < depth; i++) { int j; for (j = 0; j < 4; j++) { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:450,465 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:520,539 /* display little-endian to make 32-bit values readable */ p = (uchar*)n+k*4; - if (intr) + if (intr) { IPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80); - else + } + else { KPRINT(" %.2x%.2x%.2x%.2x %.2x %.2x", p[3], p[2], p[1], p[0], k * 4, (k * 4) + 0x80); + } USED(p); } - if (intr) + if (intr) { IPRINT("\n"); - else + } + else { KPRINT("\n"); + } } } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:748,753 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:822,828 c->running = 1; p = c->scriptpa + entry; lesetl(c->n->dsp, p); + coherence(); if (c->ssm) c->n->dcntl |= 0x4; /* start DMA in SSI mode */ } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:759,764 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:834,840 panic(PRINTPREFIX "ncrcontinue called while running"); /* set the start DMA bit to continue execution */ c->running = 1; + coherence(); c->n->dcntl |= 0x4; } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:999,1006 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1075,1081 d->dmaaddr[2] = base >> 16; d->dmaaddr[3] = base >> 24; setmovedata(&d->data_buf, base + blocks * A_BSIZE, count - blocks * A_BSIZE); - if (legetl(d->data_buf.dbc) == 0) - d->flag = 1; + d->flag = legetl(d->data_buf.dbc) == 0; } static ulong /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1111,1147 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1186,1228 int wakeme = 0; int cont = -1; Dsa *dsa; + ulong dsapa; Controller *c = a; Ncr *n = c->n; USED(ur); - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT(PRINTPREFIX "int\n"); + } ilock(c); istat = n->istat; if (istat & Intf) { Dsa *d; int wokesomething = 0; - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT(PRINTPREFIX "Intfly\n"); + } n->istat = Intf; /* search for structures in A_STATE_DONE */ - for (d = KPTR(legetl(c->dsalist.head)); d; d = KPTR(legetl(d->next))) { + for (d = KPTR(legetl(c->dsalist.head)); d != dsaend; d = KPTR(legetl(d->next))) { if (d->stateb == A_STATE_DONE) { d->p9status = d->status; - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT(PRINTPREFIX "waking up dsa %lux\n", (ulong)d); + } wakeup(d); wokesomething = 1; } } - if (!wokesomething) + if (!wokesomething) { IPRINT(PRINTPREFIX "nothing to wake up\n"); + } } if ((istat & (Sip | Dip)) == 0) { - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT(PRINTPREFIX "int end %x\n", istat); + } iunlock(c); return; } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1148,1158 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1229,1258 sist = (n->sist1<<8)|n->sist0; /* BUG? can two-byte read be inconsistent? */ dstat = n->dstat; - dsa = (Dsa *)DMASEG_TO_KADDR(legetl(n->dsa)); + dsapa = legetl(n->dsa); + + /* + * Can't compute dsa until we know that dsapa is valid. + */ + if(dsapa < -KZERO) + dsa = (Dsa*)DMASEG_TO_KADDR(dsapa); + else{ + dsa = nil; + /* + * happens at startup on some cards but we + * don't actually deref dsa because none of the + * flags we are about are set. + * still, print in case that changes and we're + * about to dereference nil. + */ + iprint("sd53c8xxinterrupt: dsa=%.8lux istat=%ux sist=%ux dstat=%ux\n", dsapa, istat, sist, dstat); + } + c->running = 0; if (istat & Sip) { - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT("sist = %.4x\n", sist); + } if (sist & 0x80) { ulong addr; ulong sa; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1163,1182 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1263,1291 addr = legetl(n->dsp); sa = addr - c->scriptpa; - if (DEBUG(1) || DEBUG(2)) + if (DEBUG(1) || DEBUG(2)) { IPRINT(PRINTPREFIX "%d/%d: Phase Mismatch sa=%.8lux\n", dsa->target, dsa->lun, sa); + } /* * now recover */ if (sa == E_data_in_mismatch) { + /* + * though this is a failure in the residue, there may have been blocks + * as well. if so, dmablks will not have been zeroed, since the state + * was not saved by the microcode. + */ dbc = read_mismatch_recover(c, n, dsa); tbc = legetl(dsa->data_buf.dbc) - dbc; + dsa->dmablks = 0; + n->scratcha[2] = 0; advancedata(&dsa->data_buf, tbc); - if (DEBUG(1) || DEBUG(2)) + if (DEBUG(1) || DEBUG(2)) { IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n", dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc)); - cont = E_to_decisions; + } + cont = E_data_mismatch_recover; } else if (sa == E_data_in_block_mismatch) { dbc = read_mismatch_recover(c, n, dsa); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1196,1212 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1305,1324 dsa->dmablks, legetl(dsa->dmaaddr), legetl(dsa->data_buf.pa), legetl(dsa->data_buf.dbc)); n->scratcha[2] = dsa->dmablks; - lesetl(n->scratchb, *(ulong*)dsa->dmaaddr); + lesetl(n->scratchb, dsa->dmancr); cont = E_data_block_mismatch_recover; } else if (sa == E_data_out_mismatch) { dbc = write_mismatch_recover(c, n, dsa); tbc = legetl(dsa->data_buf.dbc) - dbc; + dsa->dmablks = 0; + n->scratcha[2] = 0; advancedata(&dsa->data_buf, tbc); - if (DEBUG(1) || DEBUG(2)) + if (DEBUG(1) || DEBUG(2)) { IPRINT(PRINTPREFIX "%d/%d: transferred = %ld residue = %ld\n", dsa->target, dsa->lun, tbc, legetl(dsa->data_buf.dbc)); - cont = E_to_decisions; + } + cont = E_data_mismatch_recover; } else if (sa == E_data_out_block_mismatch) { dbc = write_mismatch_recover(c, n, dsa); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1223,1229 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1335,1341 dmablks * A_BSIZE - tbc + legetl(dsa->data_buf.dbc)); /* copy changes into scratch registers */ n->scratcha[2] = dsa->dmablks; - lesetl(n->scratchb, *(ulong*)dsa->dmaaddr); + lesetl(n->scratchb, dsa->dmancr); cont = E_data_block_mismatch_recover; } else if (sa == E_id_out_mismatch) { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1277,1286 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1389,1400 } } /*else*/ if (sist & 0x400) { - if (DEBUG(0)) + if (DEBUG(0)) { IPRINT(PRINTPREFIX "%d/%d Sto\n", dsa->target, dsa->lun); + } dsa->p9status = SDtimeout; dsa->stateb = A_STATE_DONE; + coherence(); softreset(c); cont = E_issue_check; wakeme = 1; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1298,1308 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1412,1422 } } if (istat & Dip) { - if (DEBUG(1)) + if (DEBUG(1)) { IPRINT("dstat = %.2x\n", dstat); + } /*else*/ if (dstat & Ssi) { - ulong *p = DMASEG_TO_KADDR(legetl(n->dsp)); - ulong w = (uchar *)p - (uchar *)c->script; + ulong w = legetl(n->dsp) - c->scriptpa; IPRINT("[%lux]", w); USED(w); cont = -2; /* restart */ /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1323,1334 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1437,1450 /* back up one in the data transfer */ IPRINT(PRINTPREFIX "%d/%d: ignore wide residue %d, WSR = %d\n", dsa->target, dsa->lun, n->scratcha[1], n->scntl2 & 1); - if (dsa->dmablks == 0 && dsa->flag) + if (dsa->flag == 2) { IPRINT(PRINTPREFIX "%d/%d: transfer over; residue ignored\n", dsa->target, dsa->lun); - else + } + else { calcblockdma(dsa, legetl(dsa->dmaaddr) - 1, dsa->dmablks * A_BSIZE + legetl(dsa->data_buf.dbc) + 1); + } cont = -2; break; case A_SIR_ERROR_NOT_MSG_IN_AFTER_RESELECT: /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1338,1343 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1454,1468 dumpncrregs(c, 1); wakeme = 1; break; + case A_SIR_NOTIFY_LOAD_STATE: + IPRINT(PRINTPREFIX ": load_state dsa=%p\n", dsa); + if (dsa == (void*)KZERO || dsa == (void*)-1) { + dsadump(c); + dumpncrregs(c, 1); + panic("bad dsa in load_state"); + } + cont = -2; + break; case A_SIR_NOTIFY_MSG_IN: IPRINT(PRINTPREFIX "%d/%d: msg_in %d\n", dsa->target, dsa->lun, n->sfbr); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1394,1400 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1519,1525 cont = -2; break; case A_SIR_NOTIFY_ISSUE: - IPRINT(PRINTPREFIX "%d/%d: issue:", dsa->target, dsa->lun); + IPRINT(PRINTPREFIX "%d/%d: issue dsa=%p end=%p:", dsa->target, dsa->lun, dsa, dsaend); dsadump: IPRINT(" tgt=%d", dsa->target); IPRINT(" time=%ld", TK2MS(m->ticks)); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1410,1420 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1535,1546 cont = -2; break; case A_SIR_NOTIFY_DUMP_NEXT_CODE: { - ulong *dsp = DMASEG_TO_KADDR(legetl(n->dsp)); + ulong *dsp = c->script + (legetl(n->dsp)-c->scriptpa)/4; int x; IPRINT(PRINTPREFIX "code at %lux", dsp - c->script); - for (x = 0; x < 6; x++) + for (x = 0; x < 6; x++) { IPRINT(" %.8lux", dsp[x]); + } IPRINT("\n"); USED(dsp); cont = -2; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1430,1444 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1556,1573 cont = -2; break; case A_SIR_NOTIFY_RESELECTED_ON_SELECT: - IPRINT(PRINTPREFIX "%d/%d: reselected during select\n", - dsa->target, dsa->lun); + if (DEBUG(2)) { + IPRINT(PRINTPREFIX "%d/%d: reselected during select\n", + dsa->target, dsa->lun); + } cont = -2; break; case A_error_reselected: /* dsa isn't valid here */ - print(PRINTPREFIX "reselection error\n"); + iprint(PRINTPREFIX "reselection error\n"); dumpncrregs(c, 1); - for (dsa = KPTR(legetl(c->dsalist.head)); dsa; dsa = KPTR(legetl(dsa->next))) + for (dsa = KPTR(legetl(c->dsalist.head)); dsa != dsaend; dsa = KPTR(legetl(dsa->next))) { IPRINT(PRINTPREFIX "dsa target %d lun %d state %d\n", dsa->target, dsa->lun, dsa->stateb); + } break; default: IPRINT(PRINTPREFIX "%d/%d: script error %ld\n", /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1448,1462 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1577,1616 } } /*else*/ if (dstat & Iid) { - ulong addr = legetl(n->dsp); - ulong dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0]; + int i, target, lun; + ulong addr, dbc, *v; + + addr = legetl(n->dsp); + if(dsa){ + target = dsa->target; + lun = dsa->lun; + }else{ + target = -1; + lun = -1; + } + dbc = (n->dbc[2]<<16)|(n->dbc[1]<<8)|n->dbc[0]; + + // if(dsa == nil) + idebug++; IPRINT(PRINTPREFIX "%d/%d: Iid pa=%.8lux sa=%.8lux dbc=%lux\n", - dsa->target, dsa->lun, + target, lun, addr, addr - c->scriptpa, dbc); - addr = (ulong)DMASEG_TO_KADDR(addr); - IPRINT("%.8lux %.8lux %.8lux\n", - *(ulong *)(addr - 12), *(ulong *)(addr - 8), *(ulong *)(addr - 4)); + addr = (ulong)c->script + addr - c->scriptpa; + addr -= 64; + addr &= ~63; + v = (ulong*)addr; + for(i=0; i<8; i++){ + IPRINT("%.8lux: %.8lux %.8lux %.8lux %.8lux\n", + addr, v[0], v[1], v[2], v[3]); + addr += 4*4; + v += 4; + } USED(addr, dbc); + if(dsa == nil){ + dsadump(c); + dumpncrregs(c, 1); + panic("bad dsa"); + } dsa->p9status = SDeio; wakeme = 1; } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1520,1527 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1674,1682 if (datalen) { KPRINT(PRINTPREFIX "write:"); - for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) + for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) { KPRINT("%.2ux", *bp); + } if (i < datalen) { KPRINT("..."); } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1541,1548 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1696,1704 if (datalen) { KPRINT(PRINTPREFIX "read:"); - for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) + for (i = 0, bp = data; i < 50 && i < datalen; i++, bp++) { KPRINT("%.2ux", *bp); + } if (i < datalen) { KPRINT("..."); } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1587,1596 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1743,1753 uchar *bp; Controller *c; uchar target_expo, my_expo; - int bc, check, status, target; + int bc, check, i, status, target; if((target = r->unit->subno) == 0x07) return r->status = SDtimeout; /* assign */ + c = r->unit->dev->ctlr; check = 0; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1659,1674 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1816,1833 setmovedata(&d->msg_out_buf, DMASEG(d->msg_out), bc); setmovedata(&d->cmd_buf, DMASEG(r->cmd), r->clen); - calcblockdma(d, DMASEG(r->data), r->dlen); + calcblockdma(d, r->data ? DMASEG(r->data) : 0, r->dlen); if (DEBUG(0)) { KPRINT(PRINTPREFIX "%d/%d: exec: ", target, r->lun); - for (bp = r->cmd; bp < &r->cmd[r->clen]; bp++) + for (bp = r->cmd; bp < &r->cmd[r->clen]; bp++) { KPRINT("%.2ux", *bp); + } KPRINT("\n"); - if (!r->write) + if (!r->write) { KPRINT(PRINTPREFIX "%d/%d: exec: limit=(%d)%ld\n", target, r->lun, d->dmablks, legetl(d->data_buf.dbc)); + } else dumpwritedata(r->data, r->dlen); } /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1677,1690 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1836,1850 d->p9status = SDnostatus; d->parityerror = 0; - + coherence(); d->stateb = A_STATE_ISSUE; /* start operation */ + coherence(); ilock(c); if (c->ssm) - c->n->dcntl |= 0x10; /* SSI */ + c->n->dcntl |= 0x10; /* single step */ if (c->running) { - c->n->istat |= Sigp; + c->n->istat = Sigp; } else { start(c, E_issue_check); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1716,1730 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1876,1896 * adjust datalen */ r->rlen = r->dlen; - if (d->dmablks > 0) + if (DEBUG(0)) { + KPRINT(PRINTPREFIX "%d/%d: exec: before rlen adjust: dmablks %d flag %d dbc %lud\n", + target, r->lun, d->dmablks, d->flag, legetl(d->data_buf.dbc)); + } + r->rlen = r->dlen; + if (d->flag != 2) { r->rlen -= d->dmablks * A_BSIZE; - else if (d->flag == 0) r->rlen -= legetl(d->data_buf.dbc); + } if(!r->write) dumpreaddata(r->data, r->rlen); - if (DEBUG(0)) + if (DEBUG(0)) { KPRINT(PRINTPREFIX "%d/%d: exec: p9status=%d status %d rlen %ld\n", target, r->lun, d->p9status, status, r->rlen); + } /* * spot the identify */ /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1751,1756 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1917,1923 * so the Dsa can be re-used. */ lesetl(&d->stateb, A_STATE_ALLOCATED); + coherence(); goto docheck; } qunlock(&c->q[target]); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1760,1770 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1927,1948 status = SDcheck; r->flags |= SDvalidsense; } - KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n", - target, r->flags, status, r->rlen); + if(DEBUG(0)) + KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n", + target, r->flags, status, r->rlen); + if(r->flags & SDvalidsense){ + if(!DEBUG(0)) + KPRINT(PRINTPREFIX "%d: r flags %8.8uX status %d rlen %ld\n", + target, r->flags, status, r->rlen); + for(i = 0; i < r->rlen; i++) + KPRINT(" %2.2uX", r->sense[i]); + KPRINT("\n"); + } return r->status = status; } + #define vpt ((ulong*)VPT) + #define VPTX(va) (((ulong)(va))>>12) static void cribbios(Controller *c) { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1796,1801 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1974,1980 #define SYM_885_DID 0x000d /* ditto */ #define SYM_875_DID 0x000f /* ditto */ #define SYM_1010_DID 0x0020 + #define SYM_1011_DID 0x0021 #define SYM_875J_DID 0x008f static Variant variant[] = { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1815,1820 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:1994,2000 { SYM_895_DID, 0xff, "SYM53C895", Burst128, 16, 24, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 }, { SYM_896_DID, 0xff, "SYM53C896", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 }, { SYM_1010_DID, 0xff, "SYM53C1010", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 }, + { SYM_1011_DID, 0xff, "SYM53C1010", Burst128, 16, 64, Prefetch|LocalRAM|BigFifo|Wide|Ultra|Ultra2 }, }; static int /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1904,1909 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2084,2090 Controller *ctlr; SDev *sdev, *head, *tail; ulong regpa, *script, scriptpa; + void *regva, *scriptva; if(cp = getconf("*maxsd53c8xx")) nctlr = strtoul(cp, 0, 0); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1921,1927 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2102,2108 print("no match\n"); continue; } - print(PRINTPREFIX "%s rev. 0x%2.2x intr=%d command=%4.4luX\n", + print(PRINTPREFIX "%s rev. 0x%2.2x intr=%d command=%4.4uX\n", v->name, p->rid, p->intl, p->pcr); regpa = p->mem[1].bar; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1931,1953 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2112,2138 continue; ba++; } - regpa = upamalloc(regpa & ~0x0F, p->mem[1].size, 0); if(regpa == 0) + print("regpa 0\n"); + regpa &= ~0xF; + regva = vmap(regpa, p->mem[1].size); + if(regva == 0) continue; script = nil; scriptpa = 0; + scriptva = nil; scriptma = nil; if((v->feature & LocalRAM) && sizeof(na_script) <= 4096){ scriptpa = p->mem[ba].bar; if((scriptpa & 0x04) && p->mem[ba+1].bar){ - upafree(regpa, p->mem[1].size); + vunmap(regva, p->mem[1].size); continue; } - scriptpa = upamalloc(scriptpa & ~0x0F, - p->mem[ba].size, 0); - if(scriptpa) - script = KADDR(scriptpa); + scriptpa &= ~0x0F; + scriptva = vmap(scriptpa, p->mem[ba].size); + if(scriptva) + script = scriptva; } if(scriptpa == 0){ /* /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1956,1962 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2141,2147 */ scriptma = malloc(sizeof(na_script)); if(scriptma == nil){ - upafree(regpa, p->mem[1].size); + vunmap(regva, p->mem[1].size); continue; } scriptpa = DMASEG(scriptma); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1973,1985 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2158,2180 free(sdev); if(scriptma) free(scriptma); - else - upafree(scriptpa, p->mem[ba].size); - upafree(regpa, p->mem[1].size); + else if(scriptva) + vunmap(scriptva, p->mem[ba].size); + if(regva) + vunmap(regva, p->mem[1].size); continue; } - ctlr->n = KADDR(regpa); + if(dsaend == nil) + dsaend = xalloc(sizeof *dsaend); + lesetl(&dsaend->stateb, A_STATE_END); + // lesetl(dsaend->next, DMASEG(dsaend)); + coherence(); + lesetl(ctlr->dsalist.head, DMASEG(dsaend)); + coherence(); + ctlr->dsalist.freechain = 0; + + ctlr->n = regva; ctlr->v = v; ctlr->script = script; memmove(ctlr->script, na_script, sizeof(na_script)); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1987,1996 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2182,2192 /* * Because we don't yet have an abstraction for the * addresses as seen from the controller side (and on - * the 386 it doesn't matter), the following two lines + * the 386 it doesn't matter), the following three lines * are different between the 386 and alpha copies of * this driver. */ + USED(scriptpa); ctlr->scriptpa = p->mem[ba].bar & ~0x0F; if(!na_fixup(ctlr, p->mem[1].bar & ~0x0F, na_patches, NA_PATCHES, xfunc)){ print("script fixup failed\n"); /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:1998,2016 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2194,2210 } swabl(ctlr->script, ctlr->script, sizeof(na_script)); - ctlr->dsalist.freechain = 0; - lesetl(ctlr->dsalist.head, 0); - ctlr->pcidev = p; sdev->ifc = &sd53c8xxifc; sdev->ctlr = ctlr; + sdev->idno = '0'; if(!(v->feature & Wide)) sdev->nunit = 8; else sdev->nunit = MAXTARGET; ctlr->sdev = sdev; - + if(head != nil) tail->next = sdev; else /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:2023,2034 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2217,2222 return head; } - static SDev* - sd53c8xxid(SDev* sdev) - { - return scsiid(sdev, &sd53c8xxifc); - } - static int sd53c8xxenable(SDev* sdev) { /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:2040,2052 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2228,2240 pcidev = ctlr->pcidev; pcisetbme(pcidev); - snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name); - intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name); ilock(ctlr); synctabinit(ctlr); cribbios(ctlr); reset(ctlr); + snprint(name, sizeof(name), "%s (%s)", sdev->name, sdev->ifc->name); + intrenable(pcidev->intl, sd53c8xxinterrupt, ctlr, pcidev->tbdf, name); iunlock(ctlr); return 1; /n/sourcesdump/2006/0113/plan9/sys/src/9/alphapc/sd53c8xx.c:2057,2063 - /n/sourcesdump/2006/0114/plan9/sys/src/9/alphapc/sd53c8xx.c:2245,2250 sd53c8xxpnp, /* pnp */ nil, /* legacy */ - sd53c8xxid, /* id */ sd53c8xxenable, /* enable */ nil, /* disable */