Home | History | Annotate | Line # | Download | only in vax
ka43.c revision 1.4
      1 /*	$NetBSD: ka43.c,v 1.4 1997/02/19 10:04:14 ragge Exp $ */
      2 /*
      3  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to Ludd by Bertram Barth.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed at Ludd, University of
     19  *	Lule}, Sweden and its contributors.
     20  * 4. The name of the author may not be used to endorse or promote products
     21  *    derived from this software without specific prior written permission
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 #include <sys/param.h>
     36 #include <sys/types.h>
     37 #include <sys/device.h>
     38 #include <sys/kernel.h>
     39 
     40 #include <vm/vm.h>
     41 #include <vm/vm_kern.h>
     42 
     43 #include <machine/pte.h>
     44 #include <machine/cpu.h>
     45 #include <machine/mtpr.h>
     46 #include <machine/sid.h>
     47 #include <machine/pmap.h>
     48 #include <machine/nexus.h>
     49 #include <machine/uvax.h>
     50 #include <machine/ka43.h>
     51 #include <machine/clock.h>
     52 #include <machine/ka650.h>	/* cache ??? */
     53 
     54 #define xtrace(x)
     55 
     56 void	ka43_conf __P((struct device*, struct device*, void*));
     57 void	ka43_steal_pages __P((void));
     58 
     59 void	ka43_memerr __P((void));
     60 int	ka43_mchk __P((caddr_t));
     61 
     62 struct	ka43_clock *ka43_clkptr;
     63 
     64 
     65 static struct uc_map ka43_map[] = {
     66 	{ KA43_CFGTST,		KA43_CFGTST,	4,		0 },
     67 	{ KA43_ROM_BASE,	KA43_ROM_END,	KA43_ROM_SIZE,	0 },
     68 	{ KA43_CPU_BASE,	KA43_CPU_END,	KA43_CPU_SIZE,	0 },
     69 	{ KA43_CT2_BASE,	KA43_CT2_END,	KA43_CT2_SIZE,	0 },
     70 	{ KA43_CH2_CREG,	KA43_CH2_CREG,	4,		0 },
     71 	{ KA43_NWA_BASE,	KA43_NWA_END,	KA43_NWA_SIZE,	0 },
     72 	{ KA43_SER_BASE,	KA43_SER_END,	KA43_SER_SIZE,	0 },
     73 	{ KA43_WAT_BASE,	KA43_WAT_END,	KA43_WAT_SIZE,	0 },
     74 	{ KA43_SCS_BASE,	KA43_SCS_END,	KA43_SCS_SIZE,	0 },
     75 	{ KA43_LAN_BASE,	KA43_LAN_END,	KA43_LAN_SIZE,	0 },
     76 	{ KA43_CUR_BASE,	KA43_CUR_END,	KA43_CUR_SIZE,	0 },
     77 	{ KA43_DMA_BASE,	KA43_DMA_END,	KA43_DMA_SIZE,	0 },
     78 	{ KA43_VME_BASE,	KA43_VME_END,	KA43_VME_SIZE,	0 },
     79 	/*
     80 	 * there's more to come, eg. framebuffers (GPX/SPX)
     81 	 */
     82 	{0, 0, 0, 0},
     83 };
     84 
     85 struct	cpu_dep ka43_calls = {
     86 	ka43_steal_pages,
     87 	no_nicr_clock,
     88 	ka43_mchk,
     89 	ka43_memerr,
     90 	ka43_conf,
     91 	ka43_clkread,
     92 	ka43_clkwrite,
     93 	4,
     94 	(void*)KA43_INTREQ,
     95 	(void*)KA43_INTCLR,
     96 	(void*)KA43_INTMSK,
     97 	ka43_map,
     98 };
     99 
    100 #define CH1_BITS \
    101 	"\020\015BCHIT\014BUSERR\013PPERR\012DPERR\011TPERR\010TRAP1" \
    102 	"\007TRAP2\006INTR\005HIT\004REFRESH\003FLUSH\002ENABLE\001FORCEHIT"
    103 
    104 #define CH2_BITS \
    105 	"\020\010TPE\007DPE\006MISS\005DIRTY\004CERR\003LERR\002SERR\001ENAB"
    106 
    107 void
    108 ka43_memerr()
    109 {
    110 	int mapen;
    111 	int *ch2reg;
    112 
    113 	printf("memory error!\n");
    114 	printf("primary cache status: %b\n", mfpr(PR_PCSTS), CH1_BITS);
    115 
    116 	mapen = mfpr(PR_MAPEN);
    117 	if (mapen)
    118 		ch2reg = (void*)uvax_phys2virt(KA43_CH2_CREG);
    119 	else
    120 		ch2reg = (void*)KA43_CH2_CREG;
    121 	printf("secondary cache status: %b\n", *ch2reg, CH2_BITS);
    122 }
    123 
    124 static char *mcc43[] = {
    125 	"no error (0)",
    126 	"FPA signalled protocoll error",
    127 	"FPA signalled illegal opcode",
    128 	"FPA detected parity error",
    129 	"FPA returned unknown status",
    130 	"FPA result has parity error",
    131 	"unused (6)",
    132 	"unused (7)",
    133 	"MMU error (TLB miss)",
    134 	"MMU error (TLB hit)",
    135 	"HW interrupt at unused IPL",
    136 	"impossible microcode state",
    137 	"undefined trap code (i-box)",
    138 	"undefined control store address",
    139 	"unused (14)",
    140 	"unused (15)",
    141 	"PC tag or data parity error",
    142 	"data bus parity error",
    143 	"data bus error (NXM)",
    144 	"undefined data bus state",
    145 };
    146 
    147 int
    148 ka43_mchk(addr)
    149 	caddr_t addr;
    150 {
    151 	struct {
    152 	  int bcount;	/* byte count (0x18) */
    153 	  int mcc;	/* "R"-flag and machine check code */
    154 	  int mrva;	/* most recent virtual address */
    155 	  int viba;	/* contents of VIBA register */
    156 	  int sisr;	/* ICCS bit 6 and SISR bits 15:0 */
    157 	  int isd;	/* internal state */
    158 	  int scr;	/* shift count register */
    159 	  int pc;	/* program counter */
    160 	  int psl;	/* processor status longword */
    161 	} *p = (void*)addr;
    162 
    163 	printf("machine check: 0x%x\n", p->mcc);
    164 	printf("reason: %s\n", mcc43[p->mcc & 0xff]);
    165 
    166 	printf("bcount:0x%x, check-code:0x%x, virtaddr:0x%x\n",
    167 	       p->bcount, p->mcc, p->mrva);
    168 	printf("pc:0x%x, psl:0x%x, viba: %x, state: %x\n",
    169 	       p->pc, p->psl, p->viba, p->isd);
    170 
    171 	return (-1);
    172 }
    173 
    174 int
    175 ka43_setup(uc,flags)
    176 	struct uvax_calls *uc;
    177 	int flags;
    178 {
    179 	uc->uc_name = "ka43";
    180 
    181 	uc->uc_physmap = ka43_map;
    182 }
    183 
    184 ka43_discache()
    185 {
    186 	int *ctag;
    187 	int *creg;
    188 	int mapen;
    189 	int i;
    190 
    191 	xtrace(("ka43_discache()\n"));
    192 	return (0);
    193 
    194 	/*
    195 	 * first disable primary cache
    196 	 */
    197 #if 0
    198 	mtpr(0, PR_PCSTS);
    199 	mtpr(0, PR_PCERR);
    200 	mtpr(0, PR_PCIDX);
    201 	mtpr(0, PR_PCTAG);
    202 #else
    203 	i = mfpr(PR_PCSTS);
    204 	mtpr((i & ~2), PR_PCSTS);
    205 	printf("pcsts: %x --> %x\n", i, mfpr(PR_PCSTS));
    206 #endif
    207 	/*
    208 	 * now secondary cache
    209 	 */
    210 	mapen = mfpr(PR_MAPEN);
    211 	if (mapen) {
    212 		ctag = (void*)uvax_phys2virt(KA43_CT2_BASE);
    213 		creg = (void*)uvax_phys2virt(KA43_CH2_CREG);
    214 	} else {
    215 		ctag = (void*)KA43_CT2_BASE;
    216 		creg = (void*)KA43_CH2_CREG;
    217 	}
    218 	i = *creg;
    219 	*creg = (i & ~1);
    220 	printf("creg: %x --> %x\n", i, *creg);
    221 
    222 	xtrace(("ka43_discache() done.\n"));
    223 }
    224 
    225 ka43_encache()
    226 {
    227 	int *ctag;
    228 	int *creg;
    229 	int mapen;
    230 	int i;
    231 
    232 	xtrace(("ka43_encache()\n"));
    233 
    234 	ka43_discache();
    235 
    236 	/*
    237 	 * first enable primary cache
    238 	 */
    239 	printf("P-0");
    240 	i = mfpr(PR_PCSTS);
    241 	mtpr((i & ~2), PR_PCSTS);
    242 	mtpr(0, PR_PCSTS);
    243 	printf("P-1");
    244 #if 1
    245 	mtpr(KA43_PCS_ENABLE | KA43_PCS_FLUSH | KA43_PCS_REFRESH, PR_PCSTS);
    246 #else
    247 	mtpr(KA43_PCS_ENABLE, PR_PCSTS);
    248 #endif
    249 	printf("P-2");
    250 
    251 	/*
    252 	 * now secondary cache
    253 	 */
    254 	mapen = mfpr(PR_MAPEN);
    255 	if (mapen) {
    256 		ctag = (void*)uvax_phys2virt(KA43_CT2_BASE);
    257 		creg = (void*)uvax_phys2virt(KA43_CH2_CREG);
    258 	} else {
    259 		ctag = (void*)KA43_CT2_BASE;
    260 		creg = (void*)KA43_CH2_CREG;
    261 	}
    262 	printf("ctag: %x, creg: %x\n", ctag, creg);
    263 	printf("S-1");
    264 	i = *creg;
    265 	printf("creg=[%x] ", *creg);
    266 #if 0
    267 	*creg = (i & ~1);
    268 	printf("creg=[%x] ", *creg);
    269 	printf("S-2");
    270 	for (i = 0; i < KA43_CT2_SIZE; i += 4)		/* Quadword entries */
    271 		ctag[i/4] = 0;				/* reset lower half */
    272 	printf("S-3");
    273 	i = *creg;
    274 	printf("creg=[%x] ", *creg);
    275 	*creg = (i & ~1);
    276 	printf("creg=[%x] ", *creg);
    277 	printf("S-4");
    278 	/* *creg = 1; */
    279 	printf("S-5");
    280 #endif
    281 	xtrace(("ka43_encache() done.\n"));
    282 
    283 	printf("primary cache status: %b\n", mfpr(PR_PCSTS), CH1_BITS);
    284 	printf("secondary cache status: %b\n", *creg, CH2_BITS);
    285 }
    286 
    287 void
    288 ka43_conf(parent, self, aux)
    289 	struct	device *parent, *self;
    290 	void	*aux;
    291 {
    292 	extern char cpu_model[];
    293 	extern int vax_siedata;
    294 
    295 	if (vax_siedata & 0x02)		/* "single-user" flag */
    296 		strcpy(cpu_model,"VAXstation 3100 model 76");
    297 	else if (vax_siedata & 0x01)	/* "multiuser" flag */
    298 		strcpy(cpu_model,"MicroVAX 3100 model 76(?)");
    299 	else
    300 		strcpy(cpu_model, "unknown KA43 board");
    301 
    302 	printf(": %s\n", cpu_model);
    303 
    304 	ka43_encache();
    305 }
    306 
    307 
    308 /*
    309  *
    310  */
    311 u_long le_iomem;		/* base addr of RAM -- CPU's view */
    312 u_long le_ioaddr;		/* base addr of RAM -- LANCE's view */
    313 
    314 void
    315 ka43_steal_pages()
    316 {
    317 	extern	vm_offset_t avail_start, virtual_avail, avail_end;
    318 	int	junk;
    319 	int	i;
    320 	struct {
    321 	  u_long     :2;
    322 	  u_long data:8;
    323 	  u_long     :22;
    324 	} *p;
    325 	int *srp;	/* Scratch Ram */
    326 	int *pctl;	/* parity control register */
    327 	char *q = (void*)&srp;
    328 	char line[20];
    329 
    330 	ka43_encache();
    331 
    332 	pctl = (void*)KA43_PARCTL;
    333 	printf("parctl: 0x%x\n", *pctl);
    334 #if 0
    335 	*pctl = KA43_PCTL_DPEN | KA43_PCTL_CPEN;
    336 #else
    337 	*pctl = KA43_PCTL_CPEN;
    338 #endif
    339 	panic("No support for ka43");
    340 #if 0
    341 	printf("new value for parctl: ");
    342 	gets(line);
    343 #endif
    344 	*pctl = *line - '0';
    345 	printf("parctl: 0x%x\n", *pctl);
    346 
    347 	srp = NULL;
    348 	p = (void*)KA43_SCR;
    349 	for (i=0; i<4; i++) {
    350 	  printf("p[%d] = %x, ", i, p[i].data);
    351 	  q[i]	= p[i].data;
    352 	}
    353 	p = (void*)KA43_SCRLEN;
    354 	printf("\nlen = %d\n", p->data);
    355 	printf("srp = 0x%x\n", srp);
    356 
    357 	for (i=0; i<0x2; i++) {
    358 	  printf("%x:0x%x ", i*4, srp[i]);
    359 	  if ((i & 0x07) == 0x07)
    360 	    printf("\n");
    361 	}
    362 	printf("\n");
    363 
    364 	printf ("ka43_steal_pages: avail_end=0x%x\n", avail_end);
    365 
    366 	/*
    367 	 * SCB is already copied/initialized at addr avail_start
    368 	 * by pmap_bootstrap(), but it's not yet mapped. Thus we use
    369 	 * the MAPPHYS() macro to reserve these two pages and to
    370 	 * perform the mapping. The mapped address is assigned to junk.
    371 	 */
    372 	MAPPHYS(junk, 2, VM_PROT_READ|VM_PROT_WRITE);
    373 
    374 	/*
    375 	 * At top of physical memory there are some console-prom and/or
    376 	 * restart-specific data. Make this area unavailable.
    377 	 */
    378 #if 1
    379 	avail_end -= 10 * NBPG;
    380 #endif
    381 
    382 	/*
    383 	 * If we need to map physical areas also, we can decrease avail_end
    384 	 * (the highest available memory-address), copy the stuff into the
    385 	 * gap between and use pmap_map to map it...
    386 	 *
    387 	 * Don't use the MAPPHYS macro here, since this uses and changes(!)
    388 	 * the value of avail_start. Use MAPVIRT even if it's name misleads.
    389 	 */
    390 	avail_end &= ~0xffff;
    391 	avail_end -= (64 * 1024);
    392 
    393 	avail_end = 0xf00000;
    394 	le_ioaddr = 0xf40000;
    395 
    396 	MAPVIRT(le_iomem, (64 * 1024)/NBPG);
    397 	pmap_map((vm_offset_t)le_iomem, le_ioaddr, le_ioaddr + 0xffff,
    398 		 VM_PROT_READ|VM_PROT_WRITE);
    399 
    400 	if (1 || le_ioaddr > 0xffffff) {
    401 		le_ioaddr &= 0xffffff;
    402 		*pctl |= KA43_PCTL_DMA;
    403 	}
    404 	printf("le_iomem: %x, le_ioaddr: %x, parctl:%x\n",
    405 	       le_iomem, le_ioaddr, *pctl);
    406 
    407 	/*
    408 	 * now map in anything listed in ka43_map...
    409 	 */
    410 	uvax_fillmap();
    411 
    412 	/*
    413 	 * Clear restart and boot in progress flags in the CPMBX.
    414 	 */
    415 	((struct ka43_clock*)ka43_clkptr)->cpmbx =
    416 	    ((struct ka43_clock*)ka43_clkptr)->cpmbx & 0xF0;
    417 
    418 	/*
    419 	 * Enable memory parity error detection and clear error bits.
    420 	 */
    421 	((struct ka43_cpu *)KA43_CPU_BASE)->ka43_mser = 0x01;
    422 	/* (UVAXIIMSER_PEN | UVAXIIMSER_MERR | UVAXIIMSER_LEB); */
    423 
    424 	/*
    425 	 * MM is not yet enabled, thus we still used the physical addresses,
    426 	 * but before leaving this routine, we need to reset them to virtual.
    427 	 */
    428 	ka43_clkptr = (void*)uvax_phys2virt(KA43_WAT_BASE);
    429 }
    430 
    431 /*
    432  * define what we need and overwrite the uVAX_??? names
    433  */
    434 
    435 #define NEED_UVAX_GENCLOCK
    436 #define NEED_UVAX_PROTOCLOCK
    437 
    438 #define uVAX_clock	ka43_clock
    439 #define uVAX_clkptr	ka43_clkptr
    440 #define uVAX_clkread	ka43_clkread
    441 #define uVAX_clkwrite	ka43_clkwrite
    442 #define uVAX_genclock	ka43_genclock
    443 
    444 #include <arch/vax/vax/uvax_proto.c>
    445