summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppc
diff options
context:
space:
mode:
authornsouch <nsouch@FreeBSD.org>1998-09-13 18:26:44 +0000
committernsouch <nsouch@FreeBSD.org>1998-09-13 18:26:44 +0000
commit733f1ca747c259a6da3db9ab538490f214e9f46c (patch)
treeb577f0e63ca0c9c49f494632cd4171d130246491 /sys/dev/ppc
parent5cc33ee728b656673a8728d17e20571446aa70b5 (diff)
downloadFreeBSD-src-733f1ca747c259a6da3db9ab538490f214e9f46c.zip
FreeBSD-src-733f1ca747c259a6da3db9ab538490f214e9f46c.tar.gz
ppbus enhanced to support ZIP+ : microseq improved
Diffstat (limited to 'sys/dev/ppc')
-rw-r--r--sys/dev/ppc/ppc.c92
-rw-r--r--sys/dev/ppc/ppcreg.h4
2 files changed, 69 insertions, 27 deletions
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index ae4646e..e6443ce 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppc.c,v 1.5 1998/08/24 02:28:16 bde Exp $
+ * $Id: ppc.c,v 1.6 1998/09/02 20:34:34 nsouch Exp $
*
*/
#include "ppc.h"
@@ -34,6 +34,7 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/malloc.h>
+#include <sys/kernel.h>
#include <machine/clock.h>
@@ -450,7 +451,8 @@ config:
if (bootverbose) {
outb(csr, 0x1);
- printf("SMC registers CR1=0x%x", inb(cio) & 0xff);
+ printf("SMC registers CR1=0x%x", ppc->ppc_unit,
+ inb(cio) & 0xff);
outb(csr, 0x4);
printf(" CR4=0x%x", inb(cio) & 0xff);
@@ -509,6 +511,7 @@ config:
} else {
/* mode forced */
+ ppc->ppc_avm = chipset_mode;
/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
if (type == SMC_37C666GT)
@@ -553,7 +556,7 @@ end_detect:
if (bootverbose)
printf ("\n");
- if (chipset_mode & PPB_EPP) {
+ if (ppc->ppc_avm & PPB_EPP) {
/* select CR4 */
outb(csr, 0x4);
r = inb(cio);
@@ -881,13 +884,13 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
struct ppc_data *ppc = ppcdata[unit];
struct ppb_microseq *pc;
char cc, *p;
- int i, iter, reg;
+ int i, iter, len;
int error;
- /* static to be reused after few ppc_exec_microseq()/return calls
- * XXX should be in a context variable shared with ppb level */
- static int accum;
- static char *ptr;
+ register int reg;
+ register char mask;
+ register int accum = 0;
+ register char *ptr = 0;
struct ppb_microseq *microseq_stack = 0;
struct ppb_microseq *pc_stack = 0;
@@ -907,37 +910,60 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
switch (mi->opcode) {
case MS_OP_RSET:
cc = r_reg(mi->arg[0].i, ppc);
- cc &= mi->arg[2].c; /* clear mask */
- cc |= mi->arg[1].c; /* assert mask */
+ cc &= (char)mi->arg[2].i; /* clear mask */
+ cc |= (char)mi->arg[1].i; /* assert mask */
w_reg(mi->arg[0].i, ppc, cc);
INCR_PC;
break;
case MS_OP_RASSERT_P:
- for (i=0; i<mi->arg[0].i; i++)
- w_reg(mi->arg[1].i, ppc, *ptr++);
+ reg = mi->arg[1].i;
+ ptr = ppc->ppc_ptr;
+
+ if ((len = mi->arg[0].i) == MS_ACCUM) {
+ accum = ppc->ppc_accum;
+ for (; accum; accum--)
+ w_reg(reg, ppc, *ptr++);
+ ppc->ppc_accum = accum;
+ } else
+ for (i=0; i<len; i++)
+ w_reg(reg, ppc, *ptr++);
+ ppc->ppc_ptr = ptr;
+
INCR_PC;
break;
case MS_OP_RFETCH_P:
- for (i=0; i<mi->arg[0].i; i++)
- *ptr++ = r_reg(mi->arg[1].i, ppc) &
- mi->arg[2].c;
+ reg = mi->arg[1].i;
+ mask = (char)mi->arg[2].i;
+ ptr = ppc->ppc_ptr;
+
+ if ((len = mi->arg[0].i) == MS_ACCUM) {
+ accum = ppc->ppc_accum;
+ for (; accum; accum--)
+ *ptr++ = r_reg(reg, ppc) & mask;
+ ppc->ppc_accum = accum;
+ } else
+ for (i=0; i<len; i++)
+ *ptr++ = r_reg(reg, ppc) & mask;
+ ppc->ppc_ptr = ptr;
+
INCR_PC;
break;
case MS_OP_RFETCH:
*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
- mi->arg[1].c;
+ (char)mi->arg[1].i;
INCR_PC;
break;
case MS_OP_RASSERT:
+ case MS_OP_DELAY:
/* let's suppose the next instr. is the same */
prefetch:
for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
- w_reg(mi->arg[0].i, ppc, mi->arg[1].c);
+ w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
if (mi->opcode == MS_OP_DELAY) {
DELAY(mi->arg[0].i);
@@ -946,16 +972,19 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
}
break;
- case MS_OP_DELAY:
- DELAY(mi->arg[0].i);
+ case MS_OP_ADELAY:
+ if (mi->arg[0].i)
+ tsleep(NULL, PPBPRI, "ppbdelay",
+ mi->arg[0].i * (hz/1000));
INCR_PC;
- break;
+ break;
case MS_OP_TRIG:
reg = mi->arg[0].i;
iter = mi->arg[1].i;
p = (char *)mi->arg[2].p;
+ /* XXX delay limited to 255 us */
for (i=0; i<iter; i++) {
w_reg(reg, ppc, *p++);
DELAY((unsigned char)*p++);
@@ -964,12 +993,12 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
break;
case MS_OP_SET:
- accum = mi->arg[0].i;
+ ppc->ppc_accum = mi->arg[0].i;
INCR_PC;
break;
case MS_OP_DBRA:
- if (--accum > 0)
+ if (--ppc->ppc_accum > 0)
pc += mi->arg[0].i;
else
INCR_PC;
@@ -977,7 +1006,7 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
case MS_OP_BRSET:
cc = r_str(ppc);
- if ((cc & mi->arg[0].c) == mi->arg[0].c)
+ if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
pc += mi->arg[1].i;
else
INCR_PC;
@@ -985,25 +1014,34 @@ ppc_exec_microseq(int unit, struct ppb_microseq *msq, int *ppbpc)
case MS_OP_BRCLEAR:
cc = r_str(ppc);
- if ((cc & mi->arg[0].c) == 0)
+ if ((cc & (char)mi->arg[0].i) == 0)
pc += mi->arg[1].i;
else
INCR_PC;
break;
+ case MS_OP_BRSTAT:
+ cc = r_str(ppc);
+ if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
+ (char)mi->arg[0].i)
+ pc += mi->arg[2].i;
+ else
+ INCR_PC;
+ break;
+
case MS_OP_C_CALL:
/*
* If the C call returns !0 then end the microseq.
* The current state of ptr is passed to the C function
*/
- if ((error = mi->arg[0].f(mi->arg[1].p, ptr)))
+ if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
return (error);
INCR_PC;
break;
case MS_OP_PTR:
- ptr = (char *)mi->arg[0].p;
+ ppc->ppc_ptr = (char *)mi->arg[0].p;
INCR_PC;
break;
@@ -1176,6 +1214,8 @@ ppcprobe(struct isa_device *dvp)
if((next_bios_ppc < BIOS_MAX_PPC) &&
(*(BIOS_PORTS+next_bios_ppc) != 0) ) {
dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
+ printf("ppc: parallel port found at 0x%x\n",
+ dvp->id_iobase);
} else
return (0);
}
diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h
index 27ab1a1..fe7e724 100644
--- a/sys/dev/ppc/ppcreg.h
+++ b/sys/dev/ppc/ppcreg.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ppcreg.h,v 1.2 1997/08/16 14:07:26 msmith Exp $
+ * $Id: ppcreg.h,v 1.3 1998/08/03 19:14:33 msmith Exp $
*
*/
#ifndef __PPCREG_H
@@ -58,6 +58,8 @@ struct ppc_data {
#define ppc_epp ppc_link.epp_protocol
#define ppc_irq ppc_link.id_irq
#define ppc_subm ppc_link.submicroseq
+#define ppc_ptr ppc_link.ptr
+#define ppc_accum ppc_link.accum
unsigned char ppc_flags;
OpenPOWER on IntegriCloud