diff options
Diffstat (limited to 'sys/arch/mvme88k/dev/pcc2.c')
-rw-r--r-- | sys/arch/mvme88k/dev/pcc2.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/sys/arch/mvme88k/dev/pcc2.c b/sys/arch/mvme88k/dev/pcc2.c new file mode 100644 index 00000000000..c78cbb24a81 --- /dev/null +++ b/sys/arch/mvme88k/dev/pcc2.c @@ -0,0 +1,253 @@ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> +#include <machine/cpu.h> +#include <machine/pcc2.h> + +int m1x7pccprobe(struct device *parent, struct cfdata *self, void *aux); +void m1x7pccattach(struct device *parent, struct device *self, void *aux); + +int abort_handler(); +extern void abort_intrv(); +extern void pcc_intrv(); +extern int intrh_debug; +extern int machineid; +extern void badtrap(); +extern int submatch( struct device *parent, struct cfdata *self, void *aux); +/* static */ u_int *pcc_io_base; +static u_int *pcc_vector_base; + +static void abort_setup(); +void timer2_intr(); + +struct pcctwosoftc { + struct device sc_dev; + caddr_t sc_vaddr; + caddr_t sc_paddr; + struct pcctworeg *sc_pcc2; +}; + +void pcctwoattach __P((struct device *, struct device *, void *)); +int pcctwoprobe __P((struct device *, void *, void *)); +int pcctwoabort __P((struct frame *)); + +struct cfdriver pcctwocd = { + NULL, "pcctwo", pcctwomatch, pcctwoattach, + DV_DULL, sizeof(struct pcctwosoftc), 0 +}; + +struct pcctworeg *sys_pcc2 = NULL; + +int +pcctwomatch(struct device *parent, struct cfdata *self, void *aux) +{ +#if defined(__m88k__) + if (machineid == 0x187) { + return 1; + } +#endif + return 0; +} + +void +pcctwoattach(struct device *parent, struct device *self, void *aux) +{ + struct cfdata *cf; + volatile char *ibvr; /* Interrupt Base Vector Register */ + u_int ibv; /* Interrupt Base Vector, offset from vbr */ + u_int *iv; /* interupt vector */ + int i; + u_int vector_base; + + /* attach memory mapped io space */ + /* map 0xfffe1000 - 0xfffe102f, 0xfffe2800 */ + /* ppc_io_base = mmio(0xfffe1000, 1800, PG_RW|PG_CI); */ + pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */ + /* set PCC vector base */ + ibv = PCC_IBVR(pcc_io_base) & 0xf0; + ibvr = &PCC_IBVR(pcc_io_base); + printf("pcc:ibvr %x *ibvr %x ibv %x\n",ibvr,*ibvr, ibv); + pcc_vector_base = (u_int *)ibv; + asm volatile ("movec vbr,%0": "=d" (vector_base)); + printf("pcc:vector_base %x\n",vector_base); + /* register "standard interupt handlers */ + + abort_setup(); + iv = (u_int *)(vector_base + (ibv * 4)); +printf("iv %x\n",iv); + for (i = 0; i <= SOFT2_VECTOR; i++) { + iv[i] = (u_int)pcc_intrv; + } + /* + timer2_setup(); + */ + iv = (u_int *)(vector_base + (ibv + TICK2_VECTOR) * 4); + *iv = (u_int)&pcc_intrv; + +#ifdef DEBUG + if (intrh_debug) + pr_intrh(); +#endif + if ((cf = config_search(submatch, self, aux)) != NULL) { + return; + } + return ; +} +asm (" .text"); +asm (" .global _pcc_intrv"); +asm ("_pcc_intrv:"); +asm (" link a6,#0"); +asm (" movml a0/a1/d0/d1,sp@-"); +asm (" movel a6,a0"); +asm (" addql #4,a0"); +asm (" movel a0,sp@-"); +asm (" jbsr _pcc_handler"); +asm (" addql #4,sp"); +asm (" movml sp@+,a0/a1/d0/d1"); +asm (" unlk a6"); +asm (" jra rei"); + +asm (" .global _abort_intrv"); +asm ("_abort_intrv:"); +asm (" movml a0/a1/d0/d1,sp@-"); +asm (" jbsr _abort_handler"); +asm (" movml sp@+,a0/a1/d0/d1"); +asm (" jra rei"); +/* asm (" .previous"); */ + +void *m147le_arg; +void +pcc_handler(struct exception_frame *except) +{ + u_int vector; + int handled = 0; + +#if 0 + printf("except %x\n",except); + printf("sr %x\n",except->sr); + printf("pc %x\n",except->pc); + printf("type %x\n",except->type); +#endif + vector = except->vo; +/* printf("vector %x\n",vector); */ + vector = (vector/4 - (u_int)pcc_vector_base); +/* printf("vector %x\n",vector); */ + + switch (vector) { + case AC_FAIL_VECTOR: + printf("ac_fail vector\n"); + break; + case BERR_VECTOR: + printf("berr vector\n"); + printf("pcc_handler:invalid vector %x\n",vector); + break; + case ABORT_VECTOR: + printf("abort vector\n"); + abort_handler(); + handled = 1; + break; + case SERIAL_VECTOR: + printf("serial vector\n"); + PCC_SERIAL_ICR(0xfffe1000) = 0; + break; + case LANCE_VECTOR: + leintr(m147le_arg); + handled = 1; + break; + case SCSIPORT_VECTOR: + printf("scsiport vector\n"); + m147sc_scintr(); + break; + case SCSIDMA_VECTOR: + printf("scsidma vector\n"); + m147sc_dmaintr(); + break; + case PRINTER_VECTOR: + printf("printer vector\n"); + break; + case TICK1_VECTOR: + printf("tick1 vector\n"); + printf("pcc_handler:invalid vector %x\n",vector); + break; + case TICK2_VECTOR: + timer2_intr(except); + handled = 1; + break; + case SOFT1_VECTOR: + printf("soft1 vector\n"); + break; + case SOFT2_VECTOR: + printf("soft2 vector\n"); + break; + default: + printf("pcc_handler:invalid vector %x\n",vector); + } + + if (handled == 0) { + printf("except %x\n",except); + printf("sr %x\n",except->sr); + printf("pc %x\n",except->pc); + printf("type %x\n",except->type); + } +} + + +int +abort_handler() +{ + printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base)); + PCC_ABRT_ICR(pcc_io_base) = 0x88; + printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base)); + Debugger(); + return 0; +} +static void abort_setup() +{ + printf("PCC_ABRT_ICR %x\n",&PCC_ABRT_ICR(pcc_io_base)); + printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base)); + PCC_ABRT_ICR(pcc_io_base) = 0x88; + printf("aicr = 0x%x\n",PCC_ABRT_ICR(pcc_io_base)); +} + +/* timer2 (clock) driver */ + +/*const u_int timer_reload = 0; /* .4096 sec ? */ +/* const u_int timer_reload = 62870; 1/60 sec ? */ +const u_int timer_reload = 63936; /* 1/100 sec ? */ + +#if 0 +void +timer2_setup() +{ + u_int *io_base; + pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */ + io_base = pcc_io_base; + printf("pcc_io_base %x io_base %x\n",pcc_io_base, io_base); + printf("PCC_TIMER2_PRE %x\n",&PCC_TIMER2_PRE(io_base)); + printf("PCC_TIMER2_CTR %x\n",&PCC_TIMER2_CTR(io_base)); + printf("PCC_TIMER2_ICR %x\n",&PCC_TIMER2_ICR(io_base)); + PCC_TIMER2_PRE(io_base) = timer_reload; + PCC_TIMER2_CTR(io_base) = 0x7; + PCC_TIMER2_ICR(io_base) = 0x8e; +} +#endif +void +timer2_intr(struct exception_frame *except) +{ + u_int *io_base; + pcc_io_base = 0xfffe1000; /* should really be return of virtmem alloc */ + io_base = pcc_io_base; + + if (0x80 && PCC_TIMER2_ICR(io_base)) { + PCC_TIMER2_ICR(io_base) = 0x8e; + /* hardclock(); */ + hardclock(except); + + } else { + printf("timer2_intr: vector called without interrupt\n"); + } + /* REALLY UGLY HACK */ + bugtty_chkinput(); + + return; +} |