First cut of news5000 support.

Mostly from SHIMIZU Ryo <dejiko@di.gi.charat.org>.
This commit is contained in:
tsubai 1999-12-22 05:53:21 +00:00
parent 2db6d32929
commit efaa549162
5 changed files with 839 additions and 347 deletions

View File

@ -0,0 +1,172 @@
/* $NetBSD: apbus.h,v 1.1 1999/12/22 05:53:21 tsubai Exp $ */
/*-
* Copyright (C) 1999 SHIMIZU Ryo. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MACHINE_APBUS__
#define __MACHINE_APBUS__
struct apbus_ctl {
int apbc_ctlno;
int apbc_mu;
int apbc_unknown2;
void *apbc_sladdr;
int apbc_unknown4;
int apbc_hwbase;
char *apbc_softc;
void *apbc_ent7;
int apbc_unknown8;
int apbc_sl;
struct apbus_ctl *apbc_slave0;
int apbc_slave0no;
int apbc_unknown12;
int apbc_unknown13;
struct apbus_ctl *apbc_slave1;
int apbc_slave1no;
int apbc_unknown16;
int apbc_unknown17;
struct apbus_ctl *apbc_slave2;
int apbc_slave2no;
int apbc_unknown20;
int apbc_unknown21;
struct apbus_ctl *apbc_parent;
int apbc_parentno;
int apbc_unknown24;
int apbc_unknown25;
struct apbus_ctl *apbc_link;
int apbc_unknown27;
int apbc_unknown28;
int apbc_unknown29;
int apbc_unknown30;
int apbc_unknown31;
};
struct apbus_device {
char *apbd_name;
char *apbd_vendor;
unsigned int apbd_atr;
#define APBD_CHAR 0x00000001
#define APBD_STDIN 0x00000002
#define APBD_STDOUT 0x00000004
unsigned int apbd_rev;
void* apbd_driver;
struct {
int (*func0)();
int (*func1)();
int (*func2)();
int (*func3)();
int (*func4)();
int (*func5)();
int (*func6)();
int (*func7)();
int (*func8)();
int (*func9)();
int (*func10)();
int (*func11)();
int (*func12)();
int (*func13)();
int (*func14)();
int (*func15)();
} apbd_call;
struct apbus_ctl *apbd_ctl;
struct apbus_device *apbd_link;
unsigned int apbd_unknwon;
};
struct apbus_bus {
unsigned int apbb_no;
void *apbb_unknown1;
void *apbb_unknown2;
void *apbb_unknown3;
struct apbus_bus *apbb_link;
unsigned int apbb_unknown5;
unsigned int apbb_unknown6;
unsigned int apbb_unknown7;
unsigned int apbb_unknown8;
};
struct apbus_vector {
unsigned short state;
unsigned short mask;
unsigned int (*handler)();
};
struct apbus_sysinfo {
int apbsi_revision;
int (*apbsi_call)();
unsigned int apbsi_error1;
void * apbsi_progstart;
void * apbsi_progend;
struct apbus_device *apbsi_dev;
struct apbus_bus *apbsi_bus;
unsigned int apbsi_error2;
unsigned int apbsi_basel;
unsigned int apbsi_baseh;
unsigned int apbsi_memsize;
unsigned int apbsi_tmpsize;
unsigned int apbsi_freesize;
unsigned char *apbsi_sram;
void *apbsi_io;
void *apbsi_alloc;
void *apbsi_cmdtable;
unsigned int apbsi_none0;
struct apbus_vector apbsi_vector[8];
void (*apbsi_trap)();
unsigned int apbsi_romversion;
unsigned char apbsi_none1[112];
};
/*
* FYI: result of 'ss -m' command on NEWS5000 rom monitor on my machine...
*
* > ss -m
* Memory use:
* diag info: bf881800
* environ: bf881000
* apinfo: bf880000
* sysinfo: 9ff03270 -> struct apbus_sysinfo
* alloc list: ffffbff8
* max mem: 04000000
* free mem: 03ff1678
* mem base: 100000000
*
*/
extern struct apbus_sysinfo *_sip;
void apbus_wbflush __P((void));
#endif /* !__MACHINE_APBUS__ */

View File

@ -0,0 +1,129 @@
/* $NetBSD: apcall.h,v 1.1 1999/12/22 05:53:21 tsubai Exp $ */
/*-
* Copyright (C) 1999 SHIMIZU Ryo. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MACHINE_APCALL_H__
#define __MACHINE_APCALL_H__
#include <machine/apbus.h>
#define APCALL (*(_sip->apbsi_call))
#define APCALL_EXIT 1
#define APCALL_READ 3
#define APCALL_WRITE 4
#define APCALL_OPEN 5
#define APCALL_CLOSE 6
#define APCALL_LSEEK 19
#define APCALL_IOCTL 54
#define APCALL_GETBASE 1001
#define APCALL_BOOT 1002
#define APCALL_BADADDR 1003
#define APCALL_GETENV 1004
#define APCALL_SETENV 1005
#define APCALL_FLCACHE 1006
#define APCALL_SLEEP 1007
#define APCALL_USLEEP 1008
#define APCALL_PHYSADDR 1009
#define APCALL_MALLOC 1010
#define APCALL_FREE 1011
#define APCALL_NSECTIME 1012
#define APCALL_IOMAP 1013
#define APCALL_DMAMAP 1014
#define APCALL_OPENBFS 1015
#define APCALL_READBFS 1016
#define APCALL_CLOSEBFS 1017
#define APCALL_PRINTF 1101
#define APCALL_FPRINTF 1103
#define APCALL_SPRINTF 1104
#define APCALL_BCOPY 1105
#define APCALL_BCMP 1106
#define APCALL_BZERO 1107
#define APCALL_PANIC 2001
#define APCALL_READDIPSW 2002
#define APCALL_STRCPY 2003
#define APCALL_STRCAT 2004
#define APCALL_STRCMP 2005
#define APCALL_STRLEN 2006
#define APCALL_STRNCPY 2007
#define APCALL_STRNCAT 2008
#define APCALL_STRNCMP 2009
#define APCALL_STRTOL 2010
#define APCALL_LTOSTR 2011
#define APCALL_EPRINTF 2012
#define APCALL_FONTADDR 2013
#define APIOCGIFHWADDR 9200 /* get hardware address */
#define apcall_exit(a) APCALL(APCALL_EXIT,(a))
#define apcall_read(a,b,c) APCALL(APCALL_READ,(a),(b),(c))
#define apcall_write(a,b,c) APCALL(APCALL_WRITE,(a),(b),(c))
#define apcall_open(a,b) APCALL(APCALL_OPEN,(a),(b))
#define apcall_close(a) APCALL(APCALL_CLOSE,(a))
#define apcall_lseek(a,b,c) APCALL(APCALL_LSEEK,(a),(b),(c))
#define apcall_ioctl(a,b,c) APCALL(APCALL_IOCTL,(a),(b),(c))
#define apcall_getbase(a,b,c) APCALL(APCALL_GETBASE,(a),(b),(c))
#define apcall_boot(a) APCALL(APCALL_BOOT,(a))
#define apcall_badaddr(a,b) APCALL(APCALL_BADADDR,(a),(b))
#define apcall_getenv(a) APCALL(APCALL_GETENV,(a))
#define apcall_setenv(a,b) APCALL(APCALL_SETENV,(a),(b))
#define apcall_flush_cache() APCALL(APCALL_FLCACHE)
#define apcall_sleep(a) APCALL(APCALL_SLEEP,(a))
#define apcall_usleep(a) APCALL(APCALL_USLEEP,(a))
#define apcall_physaddr(a,b,c) APCALL(APCALL_PHYSADDR,(a),(b),(c))
#define apcall_malloc(a) APCALL(APCALL_MALLOC,(a))
#define apcall_free(a) APCALL(APCALL_FREE,(a))
#define apcall_nsectime(a) APCALL(APCALL_NSECTIME,(a))
#define apcall_iomap(a,b) APCALL(APCALL_IOMAP,(a),(b))
#define apcall_dmamap(a,b) APCALL(APCALL_DMAMAP,(a),(b))
#define apcall_openbfs(a,b) APCALL(APCALL_OPENBFS,(a),(b))
#define apcall_readbfs(a,b) APCALL(APCALL_READBFS,(a),(b))
#define apcall_closebfs() APCALL(APCALL_CLOSEBFS)
#define apcall_bcopy(a,b,c) APCALL(APCALL_BCOPY,(a),(b),(c))
#define apcall_bcmp(a,b,c) APCALL(APCALL_BCMP,(a),(b),(c))
#define apcall_bzero(a,b) APCALL(APCALL_BZERO,(a),(b))
#define apcall_panic(a,b) APCALL(APCALL_PANIC,(a),(b))
#define apcall_readdipsw() APCALL(APCALL_READDIPSW)
#define apcall_strcpy(a,b) APCALL(APCALL_STRCPY,(a),(b))
#define apcall_strcat(a,b) APCALL(APCALL_STRCAT,(a),(b))
#define apcall_strcmp(a,b) APCALL(APCALL_STRCMP,(a),(b))
#define apcall_strlen(a) APCALL(APCALL_STRLEN,(a))
#define apcall_strncpy(a,b,c) APCALL(APCALL_STRNCPY,(a),(b),(c))
#define apcall_strncat(a,b,c) APCALL(APCALL_STRNCAT,(a),(b),(c))
#define apcall_strncmp(a,b,c) APCALL(APCALL_STRNCMP,(a),(b),(c))
#define apcall_getsx(a,b) APCALL(APCALL_GETSX,(a),(b))
#define apcall_strtol(a,b,c) APCALL(APCALL_STRTOL,(a),(b),(c))
#define apcall_ltostr(a,b,c) APCALL(APCALL_LTOSTR,(a),(b),(c))
#define apcall_fontaddr(a,b) APCALL(APCALL_FONTADDR,(a),(b))
#endif /* !__MACHINE_APCALL_H__ */

View File

@ -0,0 +1,239 @@
/* $NetBSD: news3400.c,v 1.1 1999/12/22 05:53:21 tsubai Exp $ */
/*-
* Copyright (C) 1999 Tsubai Masanari. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <machine/adrsmap.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <newsmips/newsmips/machid.h>
void level0_intr __P((void));
void level1_intr __P((void));
void hb_intr_dispatch __P((int));
static int badaddr_flag;
/*
* Handle news3400 interrupts.
*/
int
news3400_intr(mask, pc, status, cause)
u_int mask;
u_int pc; /* program counter where to continue */
u_int status; /* status register at time of the exception */
u_int cause; /* cause register at time of exception */
{
struct clockframe cf;
/* handle clock interrupts ASAP */
if (mask & MIPS_INT_MASK_2) {
register int stat;
stat = *(volatile u_char *)INTST0;
stat &= INTST0_TIMINT|INTST0_KBDINT|INTST0_MSINT;
*(volatile u_char *)INTCLR0 = stat;
if (stat & INTST0_TIMINT) {
cf.pc = pc;
cf.sr = status;
hardclock(&cf);
intrcnt[HARDCLOCK_INTR]++;
stat &= ~INTST0_TIMINT;
}
if (stat)
hb_intr_dispatch(2);
cause &= ~MIPS_INT_MASK_2;
}
/* If clock interrupts were enabled, re-enable them ASAP. */
splx(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_2));
if (mask & MIPS_INT_MASK_5) {
*(volatile char *)INTCLR0 = INTCLR0_PERR;
printf("Memory error interrupt(?) at 0x%x\n", pc);
cause &= ~MIPS_INT_MASK_5;
}
/* asynchronous bus error */
if (mask & MIPS_INT_MASK_4) {
*(volatile char *)INTCLR0 = INTCLR0_BERR;
cause &= ~MIPS_INT_MASK_4;
badaddr_flag = 1;
}
if (mask & MIPS_INT_MASK_1) {
level1_intr();
cause &= ~MIPS_INT_MASK_1;
}
if (mask & MIPS_INT_MASK_0) {
level0_intr();
cause &= ~MIPS_INT_MASK_0;
}
return (status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE;
}
#define LEVEL0_MASK \
(INTST1_DMA|INTST1_SLOT1|INTST1_SLOT3|INTST1_EXT1|INTST1_EXT3)
void
level0_intr()
{
volatile u_char *istat1 = (void *)INTST1;
volatile u_char *iclr1 = (void *)INTCLR1;
int stat;
stat = *istat1 & LEVEL0_MASK;
*iclr1 = stat;
hb_intr_dispatch(0);
if (stat & INTST1_SLOT1)
intrcnt[SLOT1_INTR]++;
if (stat & INTST1_SLOT3)
intrcnt[SLOT3_INTR]++;
}
#define LEVEL1_MASK0 (INTST0_CFLT|INTST0_CBSY)
#define LEVEL1_MASK1 (INTST1_BEEP|INTST1_SCC|INTST1_LANCE)
void
level1_intr()
{
volatile u_char *ien1 = (void *)INTEN1;
volatile u_char *istat1 = (void *)INTST1;
volatile u_char *iclr1 = (void *)INTCLR1;
int stat1, saved_ie1;
saved_ie1 = *ien1;
*ien1 = 0; /* disable BEEP, LANCE, and SCC */
stat1 = *istat1 & LEVEL1_MASK1;
*iclr1 = stat1;
stat1 &= saved_ie1;
hb_intr_dispatch(1);
*ien1 = saved_ie1;
if (stat1 & INTST1_SCC)
intrcnt[SERIAL0_INTR]++;
if (stat1 & INTST1_LANCE)
intrcnt[LANCE_INTR]++;
}
int
news3400_badaddr(addr, size)
void *addr;
u_int size;
{
volatile int x;
badaddr_flag = 0;
switch (size) {
case 1:
x = *(volatile int8_t *)addr;
break;
case 2:
x = *(volatile int16_t *)addr;
break;
case 4:
x = *(volatile int32_t *)addr;
break;
}
return badaddr_flag;
}
void
enable_intr_3400()
{
volatile u_int8_t *inten0 = (void *)INTEN0;
volatile u_int8_t *inten1 = (void *)INTEN1;
volatile u_int8_t *intclr0 = (void *)INTCLR0;
volatile u_int8_t *intclr1 = (void *)INTCLR1;
/* clear all interrupts */
*intclr0 = 0xff;
*intclr1 = 0xff;
/*
* It's not a time to enable timer yet.
*
* INTEN0: PERR ABORT BERR TIMER KBD MS CFLT CBSY
* o o o x o o x x
* INTEN1: BEEP SCC LANCE DMA SLOT1 SLOT3 EXT1 EXT3
* x o o o o o x x
*/
*inten0 = INTEN0_PERR | INTEN0_ABORT | INTEN0_BERR |
INTEN0_KBDINT | INTEN0_MSINT;
*inten1 = INTEN1_SCC | INTEN1_LANCE | INTEN1_DMA |
INTEN1_SLOT1 | INTEN1_SLOT3;
}
void
disable_intr_3400()
{
volatile u_int8_t *inten0 = (void *)INTEN0;
volatile u_int8_t *inten1 = (void *)INTEN1;
*inten0 = 0;
*inten1 = 0;
}
void
readidrom_3400(rom)
register u_char *rom;
{
register u_char *p = (u_char *)IDROM;
register int i;
for (i = 0; i < sizeof (struct idrom); i++, p += 2)
*rom++ = ((*p & 0x0f) << 4) + (*(p + 1) & 0x0f);
}
extern struct idrom idrom;
void
news3400_init()
{
enable_intr = enable_intr_3400;
disable_intr = disable_intr_3400;
readidrom_3400((u_char *)&idrom);
}

View File

@ -0,0 +1,299 @@
/* $NetBSD: news5000.c,v 1.1 1999/12/22 05:53:21 tsubai Exp $ */
/*-
* Copyright (C) 1999 SHIMIZU Ryo. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <machine/adrsmap.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <newsmips/apbus/apbusvar.h>
#include <newsmips/newsmips/machid.h>
static void level5_interrupt __P((void));
static void level4_interrupt __P((void));
static void level3_interrupt __P((void));
static void level2_interrupt __P((unsigned int, unsigned int));
static void level1_interrupt __P((void));
static void level0_interrupt __P((void));
static void abif_error4 __P((void));
/*
* Handle news5000 interrupts.
*/
int
news5000_intr(mask, pc, statusReg, causeReg)
u_int mask;
u_int pc; /* program counter where to continue */
u_int statusReg; /* status register at time of the exception */
u_int causeReg; /* cause register at time of exception */
{
if (mask & MIPS_INT_MASK_2) {
level2_interrupt(pc,statusReg);
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_2;
}
/* If clock interrupts were enabled, re-enable them ASAP. */
splx(MIPS_SR_INT_IE | (statusReg & MIPS_INT_MASK_2));
if (mask & MIPS_INT_MASK_5) {
level5_interrupt();
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_5;
}
if (mask & MIPS_INT_MASK_4) {
level4_interrupt();
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_4;
}
if (mask & MIPS_INT_MASK_3) {
level3_interrupt();
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_3;
}
if (mask & MIPS_INT_MASK_1) {
level1_interrupt();
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_1;
}
if (mask & MIPS_INT_MASK_0) {
level0_interrupt();
apbus_wbflush();
causeReg &= ~MIPS_INT_MASK_0;
}
return ((statusReg & ~causeReg & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
}
void
level5_interrupt()
{
printf("level5 interrupt\n");
}
void
level4_interrupt()
{
volatile int *intenp = (volatile int *)NEWS5000_INTMASK4;
int int4stat, saved_inten;
int4stat = *(volatile int *)NEWS5000_INTSTAT4;
saved_inten = *intenp;
*intenp = 0;
if (int4stat & NEWS5000_INT4_SBIF) {
printf("SBIF ERROR\n");
/* sbif_error4(); */
} else if (int4stat & NEWS5000_INT4_MFBIF) {
printf("MBIF ERROR\n");
/*
mbif_error4();
if (fxif_error4)
fxif_error4();
*/
} else if (int4stat & NEWS5000_INT4_ABIF) {
/* printf("ABIF ERROR\n"); */
abif_error4();
}
*intenp = saved_inten;
}
static void
abif_error4()
{
#define AB_BERRADR 0xb4c00018
#define AB_BERRDATA 0xb4c00020
#define AB_BERRPARITY 0xb4c00028
int stat;
printf("abif_error4\n");
stat = *(volatile u_int *)NEWS5000_APBUS_INTSTAT &
*(volatile u_int *)NEWS5000_APBUS_INTMASK;
if (stat & NEWS5000_INTAPBUS_DMAADDRESS) {
printf("AB I/F: DMA address error\n");
}
if (stat & (NEWS5000_INTAPBUS_RDTIMEO|NEWS5000_INTAPBUS_WRTIMEO)) {
if (stat & NEWS5000_INTAPBUS_RDTIMEO)
printf("AB I/F: read timeout\n");
if (stat & NEWS5000_INTAPBUS_WRTIMEO)
printf("AB I/F: write timeout\n");
printf(" address = %x:%x\n",
*(volatile u_int *)AB_BERRADR, *(volatile u_int *)(AB_BERRADR + 4));
}
*(volatile u_int *)NEWS5000_APBUS_INTSTAT = stat;
}
void
level3_interrupt()
{
printf("level3 interrupt\n");
}
void
level2_interrupt(pc, statusReg)
unsigned int pc;
unsigned int statusReg;
{
#ifdef DEBUG
static int l2cnt = 0;
#endif
unsigned int int2stat;
struct clockframe cf;
int2stat = *(volatile unsigned int *)NEWS5000_INTSTAT2;
#ifdef DEBUG
l2cnt++;
if (l2cnt == 50) {
*(volatile unsigned int *)NEWS5000_LED3 = 1;
}
if (l2cnt == 100) {
*(volatile unsigned int *)NEWS5000_LED3 = 0;
l2cnt = 0;
}
#endif
if (int2stat & NEWS5000_INT2_TIMER0) {
*(volatile unsigned int *)NEWS5000_TIMER0 = 1;
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[HARDCLOCK_INTR]++;
}
if (int2stat & NEWS5000_INT2_TIMER1) {
*(volatile unsigned int *)NEWS5000_TIMER1 = 1;
}
}
void
level1_interrupt()
{
unsigned int int1stat;
int nintcall;
int1stat = *(volatile unsigned int *)NEWS5000_INTSTAT1;
if (int1stat) {
/* printf("level1 interrupt (%08x)\n", int1stat); */
nintcall = apbus_intr_call(1,int1stat);
if (!nintcall) {
printf("level1_interrupt: no match interrupt mask! %04x\n",int1stat);
}
} else {
printf("level1 stray interrupt?\n");
}
}
void
level0_interrupt()
{
unsigned int int0stat;
int nintcall;
int0stat = *(volatile unsigned int *)NEWS5000_INTSTAT0;
if (int0stat) {
/* printf("level0 interrupt (%08x)\n", int0stat); */
nintcall = apbus_intr_call(0, int0stat);
if (!nintcall) {
printf("level0_interrupt: no match interrupt mask! %04x\n",int0stat);
}
} else {
printf("level0 stray interrupt?\n");
}
}
void
enable_intr_5000()
{
/* APbus Interrupt (DMAC, SONIC, FIFO*, FDC) */
*(volatile unsigned int *)NEWS5000_INTMASK0 =
NEWS5000_INTSLOT_ALL|NEWS5000_INT0_ALL;
/* APbus Interrupt (KBD, SERIAL, AUDIO*, PARALLEL, FB */
*(volatile unsigned int *)NEWS5000_INTMASK1 =
NEWS5000_INTSLOT_ALL|NEWS5000_INT1_ALL;
*(volatile unsigned int *)NEWS5000_INTMASK4 =
NEWS5000_INT4_ALL;
*(volatile unsigned int *)NEWS5000_INTCLR5 = 0xffffffff;
*(volatile unsigned int *)NEWS5000_INTMASK5 =
NEWS5000_INT5_ABIF|NEWS5000_INT5_MBIF|NEWS5000_INT5_SBIF;
}
void
disable_intr_5000()
{
*(volatile unsigned int *)NEWS5000_INTMASK0 = 0;
*(volatile unsigned int *)NEWS5000_INTMASK1 = 0;
*(volatile unsigned int *)NEWS5000_INTMASK2 = 0;
*(volatile unsigned int *)NEWS5000_INTMASK3 = 0;
*(volatile unsigned int *)NEWS5000_INTMASK4 = 0;
*(volatile unsigned int *)NEWS5000_INTMASK5 = 0;
}
void
readidrom_5000(rom)
u_char *rom;
{
u_int32_t *p = (void *)NEWS5000_IDROM;
int i;
for (i = 0; i < sizeof (struct idrom); i++, p += 2)
*rom++ = ((*p & 0x0f) << 4) + (*(p + 1) & 0x0f);
}
extern struct idrom idrom;
void
news5000_init()
{
enable_intr = enable_intr_5000;
disable_intr = disable_intr_5000;
readidrom_5000((u_char *)&idrom);
}

View File

@ -1,347 +0,0 @@
/* $NetBSD: newsmips_trap.c,v 1.8 1999/12/18 06:54:05 tsubai Exp $ */
/*
* Copyright (c) 1988 University of Utah.
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
* Science Department and Ralph Campbell.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: Utah Hdr: trap.c 1.32 91/04/06
*
* @(#)trap.c 8.5 (Berkeley) 1/11/94
*/
#include "opt_ktrace.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <machine/trap.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/adrsmap.h>
#include <newsmips/dev/scc.h>
#include "sc.h"
/*#include "lp.h"*/
/*#include "fd.h"*/
/*#include "sb.h"*/
/* XXX hokanimo ippai */
void level0_intr __P((void));
void level1_intr __P((void));
void dma_intr __P((void));
void print_int_stat __P((char *));
void news3400_errintr __P((u_int));
int sc_intr __P((void));
void hb_intr_dispatch __P((int));
static int badaddr_flag;
/*
* Handle news3400 interrupts.
*/
int
news3400_intr(mask, pc, statusReg, causeReg)
unsigned mask;
unsigned pc; /* program counter where to continue */
unsigned statusReg; /* status register at time of the exception */
unsigned causeReg; /* cause register at time of exception */
{
struct clockframe cf;
/* handle clock interrupts ASAP */
if (mask & MIPS_INT_MASK_2) { /* level 2 interrupt */
register int stat;
stat = *(volatile u_char *)INTST0;
stat &= INTST0_TIMINT|INTST0_KBDINT|INTST0_MSINT;
*(volatile u_char *)INTCLR0 = stat;
if (stat & INTST0_TIMINT) { /* timer */
static int led_count = 0;
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[HARDCLOCK_INTR]++;
if (++led_count > hz) {
led_count = 0;
*(volatile u_char *)DEBUG_PORT ^= DP_LED1;
}
stat &= ~INTST0_TIMINT;
}
if (stat)
hb_intr_dispatch(2);
/* keep clock interrupts enabled when we return */
causeReg &= ~MIPS_INT_MASK_2;
}
/* If clock interrupts were enabled, re-enable them ASAP. */
splx(MIPS_SR_INT_ENA_CUR | (statusReg & MIPS_INT_MASK_2));
if (mask & MIPS_INT_MASK_5) { /* level 5 interrupt */
*(char *)INTCLR0 = INTCLR0_PERR;
news3400_errintr(pc);
causeReg &= ~MIPS_INT_MASK_5;
}
if (mask & MIPS_INT_MASK_4) { /* level 4 interrupt */
/*
* asynchronous bus error
*/
*(char *)INTCLR0 = INTCLR0_BERR;
causeReg &= ~MIPS_INT_MASK_4;
badaddr_flag = 1;
}
if (mask & MIPS_INT_MASK_1) { /* level 1 interrupt */
level1_intr();
causeReg &= ~MIPS_INT_MASK_1;
}
if (mask & MIPS_INT_MASK_0) { /* level 0 interrupt */
level0_intr();
causeReg &= ~MIPS_INT_MASK_0;
}
return ((statusReg & ~causeReg & MIPS_HARD_INT_MASK) |
MIPS_SR_INT_ENA_CUR);
}
void
news3400_errintr(pc)
u_int pc;
{
printf("Memory error interrupt(?) at 0x%x\n", pc);
}
#include <newsmips/dev/dmac_0448.h>
/*
* news3400 - INT0 service routine.
*
* INTST0 bit 4: dma
* 3: slot #1
* 2: slot #3
* 1: external #1
* 0: external #3
*/
#define LEVEL0_MASK \
(INTST1_DMA|INTST1_SLOT1|INTST1_SLOT3|INTST1_EXT1|INTST1_EXT3)
void
level0_intr()
{
register int stat;
stat = *(volatile u_char *)INTST1 & LEVEL0_MASK;
*(u_char *)INTCLR1 = stat;
hb_intr_dispatch(0);
if (stat & INTST1_SLOT1)
intrcnt[SLOT1_INTR]++;
if (stat & INTST1_SLOT3)
intrcnt[SLOT3_INTR]++;
if (stat & INTST1_EXT1)
print_int_stat("EXT #1");
if (stat & INTST1_EXT3)
print_int_stat("EXT #3");
}
/*
* news3400 - INT1 service routine.
*
* INTST0 bit 1: centro fault
* 0: centro busy
* INTST1 bit 7: beep
* 6: scc
* 5: lance
*/
#define LEVEL1_MASK2 (INTST0_CFLT|INTST0_CBSY)
#define LEVEL1_MASK1 (INTST1_BEEP|INTST1_SCC|INTST1_LANCE)
void
level1_intr()
{
register int stat;
register u_int saved_inten1 = *(u_char *)INTEN1;
*(u_char *)INTEN1 = 0; /* disable intr: beep, lance, scc */
stat = *(volatile u_char *)INTST1 & LEVEL1_MASK1;
*(u_char *)INTCLR1 = stat;
stat &= saved_inten1;
if (stat & INTST1_BEEP) {
*(volatile u_char *)INTCLR1 = INTCLR1_BEEP;
print_int_stat("BEEP");
}
if (stat & INTST1_SCC)
intrcnt[SERIAL0_INTR]++;
if (stat & INTST1_LANCE)
intrcnt[LANCE_INTR]++;
hb_intr_dispatch(1);
*(u_char *)INTEN1 = saved_inten1;
#if NLP > 0
/*
* The PARK2 cannot find centro interrupt correctly.
* We must check it by reading the cause register of cpu
* while other interrupts are disabled.
*/
{
register int causereg;
int s = splhigh();
causereg = get_causereg();
(void) splx(s);
if ((causereg & CAUSE_IP4) == 0)
return;
}
#endif
stat = (int)(*(u_char *)INTST0) & LEVEL1_MASK2;
*(u_char *)INTCLR0 = stat;
if (stat & INTST0_CBSY) /* centro busy */
#if NLP > 0
lpxint(0);
#else
printf("stray intr: CBSY\n");
#endif
}
/*
* DMA interrupt service routine.
* XXX only SCSI works now.
*/
void
dma_intr()
{
register volatile u_char *gsp = (u_char *)DMAC_GSTAT;
register u_int gstat = *gsp;
register int mrqb, i;
/*
* when DMA intrrupt occurs there remain some untransferred data.
* wait data transfer completion.
*/
mrqb = (gstat & (CH0_INT|CH1_INT|CH2_INT|CH3_INT)) << 1;
if (gstat & mrqb) {
/*
* SHOULD USE DELAY()
*/
for (i = 0; i < 50; i++)
;
if (*gsp & mrqb)
printf("dma_intr: MRQ\n");
}
#if NSC > 0
/* SCSI Dispatch */
if (gstat & CH_INT(CH_SCSI))
sc_intr();
#endif
#if NFD > 0
/* FDC Interrupt Dispatch */
if (gstat & CH_INT(CH_FDC))
fdc_intr(0);
#endif /* NFD > 0 */
#if NSB > 0
/* Audio Interface Dispatch */
sbintr(0);
#endif /* NSB > 0 */
/* Video I/F Dispatch */
if (gstat & CH_INT(CH_VIDEO))
;
}
void
print_int_stat(msg)
char *msg;
{
int s0 = *(volatile u_char *)INTST0;
int s1 = *(volatile u_char *)INTST1;
if (msg)
printf("%s: ", msg);
else
printf("intr: ");
printf("INTST0=0x%x, INTST1=0x%x.\n", s0, s1);
}
int
news3400_badaddr(addr, size)
void *addr;
u_int size;
{
volatile int x;
badaddr_flag = 0;
switch (size) {
case 1:
x = *(volatile int8_t *)addr;
break;
case 2:
x = *(volatile int16_t *)addr;
break;
case 4:
x = *(volatile int32_t *)addr;
break;
}
return badaddr_flag;
}