Module Name:    src
Committed By:   tsutsui
Date:           Sun Oct 14 00:10:11 UTC 2018

Modified Files:
        src/sys/arch/newsmips/apbus: apbus.c apbusvar.h if_sn.c if_sn_ap.c
            if_snvar.h kb_ap.c spifi.c zs_ap.c
        src/sys/arch/newsmips/conf: GENERIC files.newsmips std.newsmips
        src/sys/arch/newsmips/include: adrsmap.h apbus.h cpu.h intr.h
        src/sys/arch/newsmips/newsmips: cpu_cons.c machdep.c machid.h
            news5000.c
        src/sys/arch/newsmips/stand/boot: boot.c version
Added Files:
        src/sys/arch/newsmips/newsmips: news4000.c

Log Message:
Add NWS-4000 support.

Based on nonaka@'s porting effort back in 2002.
See announcement on port-newsmips@ for more details:
 http://mail-index.netbsd.org/port-newsmips/2018/10/13/msg000231.html


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/newsmips/apbus/apbus.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/newsmips/apbus/apbusvar.h
cvs rdiff -u -r1.42 -r1.43 src/sys/arch/newsmips/apbus/if_sn.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/newsmips/apbus/if_sn_ap.c
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/newsmips/apbus/if_snvar.h
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/newsmips/apbus/kb_ap.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/newsmips/apbus/spifi.c
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/newsmips/apbus/zs_ap.c
cvs rdiff -u -r1.135 -r1.136 src/sys/arch/newsmips/conf/GENERIC
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/newsmips/conf/files.newsmips
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/newsmips/conf/std.newsmips
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/newsmips/include/adrsmap.h
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/newsmips/include/apbus.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/newsmips/include/cpu.h
cvs rdiff -u -r1.26 -r1.27 src/sys/arch/newsmips/include/intr.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/newsmips/newsmips/cpu_cons.c
cvs rdiff -u -r1.119 -r1.120 src/sys/arch/newsmips/newsmips/machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/newsmips/newsmips/machid.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/newsmips/newsmips/news4000.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/newsmips/newsmips/news5000.c
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/newsmips/stand/boot/boot.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/newsmips/stand/boot/version

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/newsmips/apbus/apbus.c
diff -u src/sys/arch/newsmips/apbus/apbus.c:1.24 src/sys/arch/newsmips/apbus/apbus.c:1.25
--- src/sys/arch/newsmips/apbus/apbus.c:1.24	Sun Sep 30 14:09:35 2018
+++ src/sys/arch/newsmips/apbus/apbus.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: apbus.c,v 1.24 2018/09/30 14:09:35 tsutsui Exp $	*/
+/*	$NetBSD: apbus.c,v 1.25 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (C) 1999 SHIMIZU Ryo.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: apbus.c,v 1.24 2018/09/30 14:09:35 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: apbus.c,v 1.25 2018/10/14 00:10:11 tsutsui Exp $");
 
 #define __INTR_PRIVATE
 
@@ -78,6 +78,8 @@ CFATTACH_DECL_NEW(ap, 0,
 #define	NLEVEL	2
 static struct newsmips_intr apintr_tab[NLEVEL];
 
+volatile uint32_t *news_wbflush;
+
 static int
 apbusmatch(device_t parent, cfdata_t cf, void *aux)
 {
@@ -102,10 +104,17 @@ apbusattach(device_t parent, device_t se
 	apbus_map_romwork();
 	mips_set_wbflush(apbus_wbflush);
 
-	*(volatile uint32_t *)(NEWS5000_APBUS_INTST) = 0xffffffff;
-	*(volatile uint32_t *)(NEWS5000_APBUS_INTMSK) = 0xffffffff;
-	*(volatile uint32_t *)(NEWS5000_APBUS_CTRL) = 0x00000004;
-	*(volatile uint32_t *)(NEWS5000_APBUS_DMA) = 0xffffffff;
+	if (systype == NEWS5000) {
+		*(volatile uint32_t *)(NEWS5000_APBUS_INTST) = 0xffffffff;
+		*(volatile uint32_t *)(NEWS5000_APBUS_INTMSK) = 0xffffffff;
+		*(volatile uint32_t *)(NEWS5000_APBUS_CTRL) = 0x00000004;
+		*(volatile uint32_t *)(NEWS5000_APBUS_DMA) = 0xffffffff;
+	}
+	if (systype == NEWS4000) {
+		*(volatile uint32_t *)0xb60000a4 = 0x1fffffff;
+		*(volatile uint32_t *)0xb6000070 = 0xffffffff;
+		*(volatile uint32_t *)0xb6000098 = 0xffffffff;
+	}
 
 	aprint_normal("\n");
 
@@ -181,10 +190,9 @@ aptokseg0(void *va)
 void
 apbus_wbflush(void)
 {
-	volatile int32_t * const our_wbflush = (int32_t *)NEWS5000_WBFLUSH;
 
 	(*mips_locore_jumpvec.ljv_wbflush)();
-	(void)*our_wbflush;
+	(void)*news_wbflush;
 }
 
 /*
@@ -249,13 +257,19 @@ apbus_intr_establish(int level, int mask
 	LIST_INSERT_AFTER(curih, ih, ih_q);
 
  done:
+	if (systype == NEWS5000) {
+		inten0 = (uint32_t *)NEWS5000_INTEN0;
+		inten1 = (uint32_t *)NEWS5000_INTEN1;
+	}
+	if (systype == NEWS4000) {
+		inten0 = (uint32_t *)NEWS4000_INTEN0;
+		inten1 = (uint32_t *)NEWS4000_INTEN1;
+	}
 	switch (level) {
 	case 0:
-		inten0 = (volatile uint32_t *)NEWS5000_INTEN0;
 		*inten0 |= mask;
 		break;
 	case 1:
-		inten1 = (volatile uint32_t *)NEWS5000_INTEN1;
 		*inten1 |= mask;
 		break;
 	}

Index: src/sys/arch/newsmips/apbus/apbusvar.h
diff -u src/sys/arch/newsmips/apbus/apbusvar.h:1.10 src/sys/arch/newsmips/apbus/apbusvar.h:1.11
--- src/sys/arch/newsmips/apbus/apbusvar.h:1.10	Sun Sep 30 06:14:23 2018
+++ src/sys/arch/newsmips/apbus/apbusvar.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: apbusvar.h,v 1.10 2018/09/30 06:14:23 tsutsui Exp $	*/
+/*	$NetBSD: apbusvar.h,v 1.11 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (C) 1999 SHIMIZU Ryo.  All rights reserved.
@@ -50,4 +50,7 @@ void *apbus_intr_establish(int, int, int
 struct newsmips_bus_dma_tag *apbus_dmatag_init(struct apbus_attach_args *);
 void apbus_wbflush(void);
 
-#define	SLOTTOMASK(slot)	((slot) ? (0x0100 << ((slot) - 1)) : 0)
+#define	NEWS5000_SLOTTOMASK(slot)	((slot) ? (0x0100 << ((slot) - 1)) : 0)
+#define	NEWS4000_SLOTTOMASK(slot)	((slot) ? (0x0001 << ((slot) - 1)) : 0)
+#define	SLOTTOMASK(slot)		(systype == NEWS5000 ?		\
+	    NEWS5000_SLOTTOMASK(slot) : NEWS4000_SLOTTOMASK(slot))

Index: src/sys/arch/newsmips/apbus/if_sn.c
diff -u src/sys/arch/newsmips/apbus/if_sn.c:1.42 src/sys/arch/newsmips/apbus/if_sn.c:1.43
--- src/sys/arch/newsmips/apbus/if_sn.c:1.42	Mon Sep  3 16:29:26 2018
+++ src/sys/arch/newsmips/apbus/if_sn.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_sn.c,v 1.42 2018/09/03 16:29:26 riastradh Exp $	*/
+/*	$NetBSD: if_sn.c,v 1.43 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * National Semiconductor  DP8393X SONIC Driver
@@ -16,7 +16,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sn.c,v 1.42 2018/09/03 16:29:26 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sn.c,v 1.43 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include "opt_inet.h"
 
@@ -109,7 +109,7 @@ snsetup(struct sn_softc	*sc, uint8_t *ll
 	uint8_t	*pp;
 	int	i;
 
-	if (sc->space == NULL) {
+	if (sc->memory == NULL) {
 		aprint_error_dev(sc->sc_dev,
 		    "memory allocation for descriptors failed\n");
 		return 1;
@@ -133,21 +133,21 @@ snsetup(struct sn_softc	*sc, uint8_t *ll
 	 * a higher buffer address to a 16 bit offset--this will cause wrap
 	 * around problems near the end of 64k !!
 	 */
-	p = sc->space;
+	p = sc->memory;
 	pp = (uint8_t *)roundup((int)p, PAGE_SIZE);
 	p = pp;
 
 	for (i = 0; i < NRRA; i++) {
 		sc->p_rra[i] = (void *)p;
-		sc->v_rra[i] = SONIC_GETDMA(p);
+		sc->v_rra[i] = SONIC_GETDMA(sc, p);
 		p += RXRSRC_SIZE(sc);
 	}
-	sc->v_rea = SONIC_GETDMA(p);
+	sc->v_rea = SONIC_GETDMA(sc, p);
 
 	p = (uint8_t *)SOALIGN(sc, p);
 
 	sc->p_cda = (void *)(p);
-	sc->v_cda = SONIC_GETDMA(p);
+	sc->v_cda = SONIC_GETDMA(sc, p);
 	p += CDA_SIZE(sc);
 
 	p = (uint8_t *)SOALIGN(sc, p);
@@ -155,7 +155,7 @@ snsetup(struct sn_softc	*sc, uint8_t *ll
 	for (i = 0; i < NTDA; i++) {
 		struct mtd *mtdp = &sc->mtda[i];
 		mtdp->mtd_txp = (void *)p;
-		mtdp->mtd_vtxp = SONIC_GETDMA(p);
+		mtdp->mtd_vtxp = SONIC_GETDMA(sc, p);
 		p += TXP_SIZE(sc);
 	}
 
@@ -176,12 +176,12 @@ snsetup(struct sn_softc	*sc, uint8_t *ll
 
 	sc->sc_nrda = PAGE_SIZE / RXPKT_SIZE(sc);
 	sc->p_rda = (void *)p;
-	sc->v_rda = SONIC_GETDMA(p);
+	sc->v_rda = SONIC_GETDMA(sc, p);
 
 	p = pp + PAGE_SIZE;
 
 	for (i = 0; i < NRBA; i++) {
-		sc->rbuf[i] = (void *)p;
+		sc->rbuf[i] = SONIC_BUFFER(sc, p);
 		p += PAGE_SIZE;
 	}
 
@@ -189,8 +189,8 @@ snsetup(struct sn_softc	*sc, uint8_t *ll
 	for (i = 0; i < NTDA; i++) {
 		struct mtd *mtdp = &sc->mtda[i];
 
-		mtdp->mtd_buf = p;
-		mtdp->mtd_vbuf = SONIC_GETDMA(p);
+		mtdp->mtd_buf = SONIC_BUFFER(sc, p);
+		mtdp->mtd_vbuf = SONIC_GETDMA(sc, p);
 		p += TXBSIZE;
 	}
 
@@ -738,6 +738,7 @@ initialise_tda(struct sn_softc *sc)
 
 	NIC_PUT(sc, SNR_UTDA, UPPER(sc->mtda[0].mtd_vtxp));
 	NIC_PUT(sc, SNR_CTDA, LOWER(sc->mtda[0].mtd_vtxp));
+	wbflush();
 }
 
 static void
@@ -789,7 +790,7 @@ initialise_rra(struct sn_softc *sc)
 
 	/* fill up SOME of the rra with buffers */
 	for (i = 0; i < NRBA; i++) {
-		v = SONIC_GETDMA(sc->rbuf[i]);
+		v = SONIC_GETDMA(sc, sc->rbuf[i]);
 		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRHI, UPPER(v));
 		SWO(bitmode, sc->p_rra[i], RXRSRC_PTRLO, LOWER(v));
 		SWO(bitmode, sc->p_rra[i], RXRSRC_WCHI, UPPER(PAGE_SIZE/2));

Index: src/sys/arch/newsmips/apbus/if_sn_ap.c
diff -u src/sys/arch/newsmips/apbus/if_sn_ap.c:1.12 src/sys/arch/newsmips/apbus/if_sn_ap.c:1.13
--- src/sys/arch/newsmips/apbus/if_sn_ap.c:1.12	Sun Sep 30 14:23:24 2018
+++ src/sys/arch/newsmips/apbus/if_sn_ap.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_sn_ap.c,v 1.12 2018/09/30 14:23:24 tsutsui Exp $	*/
+/*	$NetBSD: if_sn_ap.c,v 1.13 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * Copyright (C) 1997 Allen Briggs
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sn_ap.c,v 1.12 2018/09/30 14:23:24 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sn_ap.c,v 1.13 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include "opt_inet.h"
 
@@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_sn_ap.c,v
 #include <newsmips/apbus/if_snreg.h>
 #include <newsmips/apbus/if_snvar.h>
 
+#include <newsmips/newsmips/machid.h>
+
 #define SONIC_MACROM_OFFSET	0x40
 
 #define SONIC_APBUS_REG_OFFSET	0x00010000
@@ -86,18 +88,36 @@ sn_ap_attach(device_t parent, device_t s
 	struct sn_softc *sc = device_private(self);
 	struct apbus_attach_args *apa = aux;
 	uint8_t myaddr[ETHER_ADDR_LEN];
-	u_int intrmask;
+	uint32_t intrmask = 0;
 
 	sc->sc_dev = self;
-	sc->sc_hwbase = (void *)apa->apa_hwbase;
-	sc->sc_regbase = (void *)(apa->apa_hwbase + SONIC_APBUS_REG_OFFSET);
-	sc->space = (void *)(apa->apa_hwbase + SONIC_APBUS_MEM_OFFSET);
+	sc->slotno = apa->apa_slotno;
+	if (systype == NEWS4000 && sc->slotno == 0) {
+		sc->sc_flags |= F_NWS40S0;
+	}
+	if ((sc->sc_flags & F_NWS40S0) != 0) {
+		sc->sc_hwbase = (void *)apa->apa_hwbase;
+		sc->sc_regbase = (void *)apa->apa_hwbase;
+		sc->memory = (void *)NEWS4000_SONIC_MEMORY;
+		sc->buffer = (void *)NEWS4000_SONIC_BUFFER;
+	} else {
+		sc->sc_hwbase = (void *)apa->apa_hwbase;
+		sc->sc_regbase =
+		    (void *)(apa->apa_hwbase + SONIC_APBUS_REG_OFFSET);
+		sc->memory =
+		    (void *)(apa->apa_hwbase + SONIC_APBUS_MEM_OFFSET);
+	}
 
 	aprint_normal(" slot%d addr 0x%lx", apa->apa_slotno, apa->apa_hwbase);
 
-	sc->snr_dcr = DCR_WAIT0 | DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
-	sc->snr_dcr2 = 0;
-	sc->snr_dcr |= DCR_EXBUS;
+	if ((sc->sc_flags & F_NWS40S0) != 0) {
+		sc->snr_dcr = DCR_STERM | DCR_TFT28;
+		sc->snr_dcr2 = 0x0100;
+	} else {
+		sc->snr_dcr = DCR_WAIT0 | DCR_DMABLOCK | DCR_RFT16 | DCR_TFT16;
+		sc->snr_dcr2 = 0;
+		sc->snr_dcr |= DCR_EXBUS;
+	}
 	sc->bitmode = 1;
 
 	if (sn_ap_getaddr(sc, myaddr)) {
@@ -111,8 +131,14 @@ sn_ap_attach(device_t parent, device_t s
 	if (snsetup(sc, myaddr))
 		return;
 
-	intrmask = (apa->apa_slotno == 0) ?
-	    NEWS5000_INT0_SONIC : SLOTTOMASK(apa->apa_slotno);
+	if (systype == NEWS5000) {
+		intrmask = (apa->apa_slotno == 0) ?
+		    NEWS5000_INT0_SONIC : NEWS5000_SLOTTOMASK(apa->apa_slotno);
+	}
+	if (systype == NEWS4000) {
+		intrmask = (apa->apa_slotno == 0) ?
+		    NEWS4000_INT0_SONIC : NEWS4000_SLOTTOMASK(apa->apa_slotno);
+	}
 
 	apbus_intr_establish(0, /* interrupt level (0 or 1) */
 	    intrmask,
@@ -123,14 +149,21 @@ sn_ap_attach(device_t parent, device_t s
 int
 sn_ap_getaddr(struct sn_softc *sc, uint8_t *lladdr)
 {
-	uint32_t *p;
-	int i;
 
-	p = (uint32_t *)((uint8_t *)sc->sc_hwbase + SONIC_MACROM_OFFSET);
-	for (i = 0; i < ETHER_ADDR_LEN; i++) {
-		int h = *p++ & 0x0f;
-		int l = *p++ & 0x0f;
-		*lladdr++ = (h << 4) + l;
+	if ((sc->sc_flags & F_NWS40S0) != 0) {
+		extern struct idrom idrom;
+		memcpy(lladdr, idrom.id_macadrs, sizeof(idrom.id_macadrs));
+	} else {
+		uint32_t *p;
+		int i;
+
+		p = (uint32_t *)((uint8_t *)sc->sc_hwbase +
+		    SONIC_MACROM_OFFSET);
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			int h = *p++ & 0x0f;
+			int l = *p++ & 0x0f;
+			*lladdr++ = (h << 4) + l;
+		}
 	}
 
 	return 0;
@@ -142,9 +175,15 @@ sn_ap_getaddr(struct sn_softc *sc, uint8
 void
 sn_md_init(struct sn_softc *sc)
 {
-	volatile uint32_t *reg = (uint32_t *)APSONIC_INT_REG(sc->sc_hwbase);
 
-	*reg = APSONIC_INT_MASK;
+	if ((sc->sc_flags & F_NWS40S0) != 0) {
+		*(volatile uint32_t *)0xbf700000 = 1;
+	} else {
+		volatile uint32_t *reg =
+		    (uint32_t *)APSONIC_INT_REG(sc->sc_hwbase);
+
+		*reg = APSONIC_INT_MASK;
+	}
 	wbflush();
 	apbus_wbflush();
 	delay(10000);

Index: src/sys/arch/newsmips/apbus/if_snvar.h
diff -u src/sys/arch/newsmips/apbus/if_snvar.h:1.13 src/sys/arch/newsmips/apbus/if_snvar.h:1.14
--- src/sys/arch/newsmips/apbus/if_snvar.h:1.13	Sun Feb 20 07:56:31 2011
+++ src/sys/arch/newsmips/apbus/if_snvar.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_snvar.h,v 1.13 2011/02/20 07:56:31 matt Exp $	*/
+/*	$NetBSD: if_snvar.h,v 1.14 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1991   Algorithmics Ltd (http://www.algor.co.uk)
@@ -27,7 +27,11 @@
 #define	NIC_GET(sc, reg)	((sc)->sc_regbase[(reg) * 4 + 3])
 #define	NIC_PUT(sc, reg, val)	((sc)->sc_regbase[(reg) * 4 + 3] = val)
 
-#define	SONIC_GETDMA(p)	((uint32_t)(p))
+#define	SONIC_GETDMA(sc, p)	(((sc)->sc_flags & F_NWS40S0) == 0 ?	\
+	    ((uint32_t)(p)) : (((uint32_t)(p) & 0xffff) | 0xfff00000))
+#define	SONIC_BUFFER(sc, p)	(((sc)->sc_flags & F_NWS40S0) == 0 ?	\
+	    (p) :							\
+	    (void *)(((uint32_t)((sc)->buffer)) | ((uint32_t)(p) & 0xffff)))
 
 #define	SN_REGSIZE	(SN_NREGS * 4)
 
@@ -118,7 +122,10 @@ struct sn_softc {
 	void		*p_cda;
 	uint32_t	v_cda;
 
-	unsigned char	*space;
+	uint8_t		*memory;
+	uint8_t		*buffer;
+	u_int		sc_flags;
+#define	F_NWS40S0	0x0001
 };
 
 /*

Index: src/sys/arch/newsmips/apbus/kb_ap.c
diff -u src/sys/arch/newsmips/apbus/kb_ap.c:1.11 src/sys/arch/newsmips/apbus/kb_ap.c:1.12
--- src/sys/arch/newsmips/apbus/kb_ap.c:1.11	Sun Sep 30 14:23:24 2018
+++ src/sys/arch/newsmips/apbus/kb_ap.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: kb_ap.c,v 1.11 2018/09/30 14:23:24 tsutsui Exp $	*/
+/*	$NetBSD: kb_ap.c,v 1.12 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kb_ap.c,v 1.11 2018/09/30 14:23:24 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kb_ap.c,v 1.12 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: kb_ap.c,v 1.
 #include <dev/wscons/wsksymdef.h>
 
 #include <machine/adrsmap.h>
+#include <machine/cpu.h>
 #include <newsmips/apbus/apbusvar.h>
 
 struct kbreg {
@@ -128,7 +129,7 @@ kb_ap_attach(device_t parent, device_t s
 
 	sc->sc_reg = reg;
 
-	if (*dipsw & 7) {
+	if (systype == NEWS5000 && *dipsw & 7) {
 		aprint_normal(" (console)");
 		cons = 1;
 	}

Index: src/sys/arch/newsmips/apbus/spifi.c
diff -u src/sys/arch/newsmips/apbus/spifi.c:1.19 src/sys/arch/newsmips/apbus/spifi.c:1.20
--- src/sys/arch/newsmips/apbus/spifi.c:1.19	Sun Sep 30 14:23:24 2018
+++ src/sys/arch/newsmips/apbus/spifi.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: spifi.c,v 1.19 2018/09/30 14:23:24 tsutsui Exp $	*/
+/*	$NetBSD: spifi.c,v 1.20 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 2000 Tsubai Masanari.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spifi.c,v 1.19 2018/09/30 14:23:24 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spifi.c,v 1.20 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -203,7 +203,7 @@ spifi_attach(device_t parent, device_t s
 	sc->sc_channel.chan_id = sc->sc_id;
 
 	if (apa->apa_slotno == 0)
-		intr = NEWS5000_INT0_DMAC;
+		intr = NEWS5000_INT0_DMAC;	/* XXX news4000 */
 	else
 		intr = SLOTTOMASK(apa->apa_slotno);
 	apbus_intr_establish(0, intr, 0, spifi_intr, sc, device_xname(self),

Index: src/sys/arch/newsmips/apbus/zs_ap.c
diff -u src/sys/arch/newsmips/apbus/zs_ap.c:1.28 src/sys/arch/newsmips/apbus/zs_ap.c:1.29
--- src/sys/arch/newsmips/apbus/zs_ap.c:1.28	Sun Sep 30 14:23:24 2018
+++ src/sys/arch/newsmips/apbus/zs_ap.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: zs_ap.c,v 1.28 2018/09/30 14:23:24 tsutsui Exp $	*/
+/*	$NetBSD: zs_ap.c,v 1.29 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.28 2018/09/30 14:23:24 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.29 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,6 +47,9 @@ __KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.
 #include <sys/conf.h>
 #include <sys/cpu.h>
 #include <sys/intr.h>
+#ifdef NEWS4000_ZS_AP_POLLING
+#include <sys/callout.h>
+#endif
 
 #include <machine/adrsmap.h>
 #include <machine/z8530var.h>
@@ -65,29 +68,55 @@ __KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.
 #define NZS 2
 #endif
 
-#define PORTB_XPORT	0x00000000
-#define PORTB_RPORT	0x00010000
-#define PORTA_XPORT	0x00020000
-#define PORTA_RPORT	0x00030000
-#define   DMA_MODE_REG		3
-#define     DMA_ENABLE		0x01	/* DMA enable */
-#define     DMA_DIR_DM		0x00	/* device to memory */
-#define     DMA_DIR_MD		0x02	/* memory to device */
-#define     DMA_EXTRDY		0x08	/* DMA external ready */
-#define PORTB_OFFSET	0x00040000
-#define PORTA_OFFSET	0x00050000
-#define   PORT_CTL		2
-#define     PORTCTL_RI		0x01
-#define     PORTCTL_DSR		0x02
-#define     PORTCTL_DTR		0x04
-#define   PORT_SEL		3
-#define     PORTSEL_LOCALTALK	0x01
-#define     PORTSEL_RS232C	0x02
-#define ESCC_REG	0x00060000
-#define   ESCCREG_INTSTAT	0
-#define     INTSTAT_SCC		0x01
-#define   ESCCREG_INTMASK	1
-#define     INTMASK_SCC		0x01
+#define NEWS5000_PORTB_TXPORT	0x00000000
+#define NEWS5000_PORTB_RXPORT	0x00010000
+#define NEWS5000_PORTA_TXPORT	0x00020000
+#define NEWS5000_PORTA_RXPORT	0x00030000
+#define   NEWS5000_DMA_MODE_REG		3
+#define     NEWS5000_DMA_ENABLE		0x01	/* DMA enable */
+#define     NEWS5000_DMA_DIR_DM		0x00	/* device to memory */
+#define     NEWS5000_DMA_DIR_MD		0x02	/* memory to device */
+#define     NEWS5000_DMA_EXTRDY		0x08	/* DMA external ready */
+#define NEWS5000_PORTB_OFFSET	0x00040000
+#define NEWS5000_PORTA_OFFSET	0x00050000
+#define   NEWS5000_PORT_CTL		2
+#define     NEWS5000_PORTCTL_RI		0x01
+#define     NEWS5000_PORTCTL_DSR	0x02
+#define     NEWS5000_PORTCTL_DTR	0x04
+#define   NEWS5000_PORT_SEL		3
+#define     NEWS5000_PORTSEL_LOCALTALK	0x01
+#define     NEWS5000_PORTSEL_RS232C	0x02
+#define NEWS5000_ESCC_REG	0x00060000
+#define   NEWS5000_ESCCREG_INTSTAT	0
+#define     NEWS5000_INTSTAT_SCC	0x01
+#define   NEWS5000_ESCCREG_INTMASK	1
+#define     NEWS5000_INTMASK_SCC	0x01
+
+#define NEWS4000_PORTB_TXPORT	0x00000000	/* XXX: not confirmed */
+#define NEWS4000_PORTB_RXPORT	0x00010000	/* XXX: not confirmed */
+#define NEWS4000_PORTA_TXPORT	0x00040000	/* XXX: not confirmed */
+#define NEWS4000_PORTA_RXPORT	0x00050000	/* XXX: not confirmed */
+#define   NEWS4000_DMA_MODE_REG		3
+#define     NEWS4000_DMA_ENABLE		0x01	/* DMA enable */
+#define     NEWS4000_DMA_DIR_DM		0x00	/* device to memory */
+#define     NEWS4000_DMA_DIR_MD		0x02	/* memory to device */
+#define     NEWS4000_DMA_EXTRDY		0x08	/* DMA external ready */
+#define NEWS4000_PORTB_CTL	0x00020000	/* XXX: not confirmed */
+#define NEWS4000_PORTA_CTL	0x00060000	/* XXX: not confirmed */
+#define   NEWS4000_PORT_CTL		4
+#define     NEWS4000_PORTCTL_RI		0x01
+#define     NEWS4000_PORTCTL_DSR	0x02    
+#define     NEWS4000_PORTCTL_DTR	0x04
+#define   NEWS4000_PORT_SEL		5
+#define     NEWS4000_PORTSEL_LOCALTALK	0x01
+#define     NEWS4000_PORTSEL_RS232C	0x02
+#define NEWS4000_ESCC_REG	0x00060000	/* XXX:  not confirmed */
+#define   NEWS4000_ESCCREG_INTSTAT	0
+#define     NEWS4000_INTSTAT_SCC	0x01
+#define   NEWS4000_ESCCREG_INTMASK	1
+#define     NEWS4000_INTMASK_SCC	0x01
+#define NEWS4000_PORTB_OFFSET	0x00080000
+#define NEWS4000_PORTA_OFFSET	0x00080008
 
 extern int zs_def_cflag;
 extern void (*zs_delay)(void);
@@ -134,6 +163,10 @@ static uint8_t zs_init_reg[16] = {
 	ZSWR15_BREAK_IE,
 };
 
+#ifdef NEWS4000_ZS_AP_POLLING
+static struct callout zscallout;
+#endif
+
 static struct zschan * zs_get_chan_addr(int, int);
 static void zs_ap_delay(void);
 static int zshard_ap(void *);
@@ -144,17 +177,26 @@ struct zschan *
 zs_get_chan_addr(int zs_unit, int channel)
 {
 	void *addr;
-	struct zschan *zc;
+	struct zschan *zc = NULL;
 
 	if (zs_unit >= NZS)
 		return NULL;
 	addr = zsaddr[zs_unit];
 	if (addr == NULL)
 		return NULL;
-	if (channel == 0) {
-		zc = (void *)((uint8_t *)addr + PORTA_OFFSET);
-	} else {
-		zc = (void *)((uint8_t *)addr + PORTB_OFFSET);
+	if (systype == NEWS5000) {
+		if (channel == 0) {
+			zc = (void *)((uint8_t *)addr + NEWS5000_PORTA_OFFSET);
+		} else {
+			zc = (void *)((uint8_t *)addr + NEWS5000_PORTB_OFFSET);
+		}
+	}
+	if (systype == NEWS4000) {
+		if (channel == 0) {
+			zc = (void *)((uint8_t *)addr + NEWS4000_PORTA_OFFSET);
+		} else {
+			zc = (void *)((uint8_t *)addr + NEWS4000_PORTB_OFFSET);
+		}
 	}
 	return zc;
 }
@@ -185,10 +227,11 @@ zs_ap_match(device_t parent, cfdata_t cf
 {
 	struct apbus_attach_args *apa = aux;
 
-	if (strcmp("esccf", apa->apa_name) != 0)
-		return 0;
+	if (strcmp("esccf", apa->apa_name) == 0 ||
+	    strcmp("esccg", apa->apa_name) == 0)
+		return 1;
 
-	return 1;
+	return 0;
 }
 
 /*
@@ -206,13 +249,13 @@ zs_ap_attach(device_t parent, device_t s
 	volatile struct zschan *zc;
 	struct zs_chanstate *cs;
 	int s, zs_unit, channel;
-	volatile u_int *txBfifo = (void *)(apa->apa_hwbase + PORTB_XPORT);
-	volatile u_int *rxBfifo = (void *)(apa->apa_hwbase + PORTB_RPORT);
-	volatile u_int *txAfifo = (void *)(apa->apa_hwbase + PORTA_XPORT);
-	volatile u_int *rxAfifo = (void *)(apa->apa_hwbase + PORTA_RPORT);
-	volatile u_int *portBctl = (void *)(apa->apa_hwbase + PORTB_OFFSET);
-	volatile u_int *portActl = (void *)(apa->apa_hwbase + PORTA_OFFSET);
-	volatile u_int *esccregs = (void *)(apa->apa_hwbase + ESCC_REG);
+	volatile uint32_t *txBfifo;
+	volatile uint32_t *rxBfifo;
+	volatile uint32_t *txAfifo;
+	volatile uint32_t *rxAfifo;
+	volatile uint32_t *portBctl;
+	volatile uint32_t *portActl;
+	volatile uint32_t *esccregs;
 
 	zsc->zsc_dev = self;
 	zs_unit = device_unit(self);
@@ -220,17 +263,69 @@ zs_ap_attach(device_t parent, device_t s
 
 	aprint_normal(" slot%d addr 0x%lx\n", apa->apa_slotno, apa->apa_hwbase);
 
-	txAfifo[DMA_MODE_REG] = rxAfifo[DMA_MODE_REG] = DMA_EXTRDY;
-	txBfifo[DMA_MODE_REG] = rxBfifo[DMA_MODE_REG] = DMA_EXTRDY;
+	/* XXX: appease gcc -Wuninitialized */
+	txBfifo  = (void *)(apa->apa_hwbase);
+	rxBfifo  = (void *)(apa->apa_hwbase);
+	txAfifo  = (void *)(apa->apa_hwbase);
+	rxAfifo  = (void *)(apa->apa_hwbase);
+	portBctl = (void *)(apa->apa_hwbase);
+	portActl = (void *)(apa->apa_hwbase);
+	esccregs = (void *)(apa->apa_hwbase);
+
+	if (systype == NEWS5000) {
+		txBfifo  = (void *)(apa->apa_hwbase + NEWS5000_PORTB_TXPORT);
+		rxBfifo  = (void *)(apa->apa_hwbase + NEWS5000_PORTB_RXPORT);
+		txAfifo  = (void *)(apa->apa_hwbase + NEWS5000_PORTA_TXPORT);
+		rxAfifo  = (void *)(apa->apa_hwbase + NEWS5000_PORTA_RXPORT);
+		portBctl = (void *)(apa->apa_hwbase + NEWS5000_PORTB_OFFSET);
+		portActl = (void *)(apa->apa_hwbase + NEWS5000_PORTA_OFFSET);
+		esccregs = (void *)(apa->apa_hwbase + NEWS5000_ESCC_REG);
+	}
+	if (systype == NEWS4000) {
+		txBfifo  = (void *)(apa->apa_hwbase + NEWS4000_PORTB_TXPORT);
+		rxBfifo  = (void *)(apa->apa_hwbase + NEWS4000_PORTB_RXPORT);
+		txAfifo  = (void *)(apa->apa_hwbase + NEWS4000_PORTA_TXPORT);
+		rxAfifo  = (void *)(apa->apa_hwbase + NEWS4000_PORTA_RXPORT);
+		portBctl = (void *)(apa->apa_hwbase + NEWS4000_PORTB_CTL);
+		portActl = (void *)(apa->apa_hwbase + NEWS4000_PORTA_CTL);
+		esccregs = (void *)(apa->apa_hwbase + NEWS4000_ESCC_REG);
+	}
 
-	/* assert DTR */			/* XXX */
-	portBctl[PORT_CTL] = portActl[PORT_CTL] = PORTCTL_DTR;
+	if (systype == NEWS5000) {
+		txAfifo[NEWS5000_DMA_MODE_REG] = NEWS5000_DMA_EXTRDY;
+		rxAfifo[NEWS5000_DMA_MODE_REG] = NEWS5000_DMA_EXTRDY;
+		txBfifo[NEWS5000_DMA_MODE_REG] = NEWS5000_DMA_EXTRDY;
+		rxBfifo[NEWS5000_DMA_MODE_REG] = NEWS5000_DMA_EXTRDY;
+
+		/* assert DTR */			/* XXX */
+		portBctl[NEWS5000_PORT_CTL] = NEWS5000_PORTCTL_DTR;
+		portActl[NEWS5000_PORT_CTL] = NEWS5000_PORTCTL_DTR;
 
-	/* select RS-232C (ch1 only) */
-	portActl[PORT_SEL] = PORTSEL_RS232C;
+		/* select RS-232C (ch1 only) */
+		portActl[NEWS5000_PORT_SEL] = NEWS5000_PORTSEL_RS232C;
 
-	/* enable SCC interrupts */
-	esccregs[ESCCREG_INTMASK] = INTMASK_SCC;
+		/* enable SCC interrupts */
+		esccregs[NEWS5000_ESCCREG_INTMASK] = NEWS5000_INTMASK_SCC;
+	}
+
+	if (systype == NEWS4000) {
+		txAfifo[NEWS4000_DMA_MODE_REG] = NEWS4000_DMA_EXTRDY;
+		rxAfifo[NEWS4000_DMA_MODE_REG] = NEWS4000_DMA_EXTRDY;
+		txBfifo[NEWS4000_DMA_MODE_REG] = NEWS4000_DMA_EXTRDY;
+		rxBfifo[NEWS4000_DMA_MODE_REG] = NEWS4000_DMA_EXTRDY;
+
+#if 1	/* XXX: zsc on news4000 seems mangled by these ops */
+		/* assert DTR */			/* XXX */
+		portBctl[NEWS4000_PORT_CTL] = NEWS4000_PORTCTL_DTR;
+		portActl[NEWS4000_PORT_CTL] = NEWS4000_PORTCTL_DTR;
+
+		/* select RS-232C (ch1 only) */
+		portActl[NEWS4000_PORT_SEL] = NEWS4000_PORTSEL_RS232C;
+#endif
+
+		/* enable SCC interrupts */
+		esccregs[NEWS4000_ESCCREG_INTMASK] = NEWS4000_INTMASK_SCC;
+	}
 
 	zs_delay = zs_ap_delay;
 
@@ -298,9 +393,26 @@ zs_ap_attach(device_t parent, device_t s
 	 */
 	zsc->zsc_si = softint_establish(SOFTINT_SERIAL,
 	    (void (*)(void *))zsc_intr_soft, zsc);
-	apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
-	    NEWS5000_INT1_SCC, 0, /* priority */
-	    zshard_ap, zsc, device_xname(self), apa->apa_ctlnum);
+	if (systype == NEWS5000) {
+		apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
+				     NEWS5000_INT1_SCC,
+				     0, /* priority */
+				     zshard_ap, zsc,
+				     device_xname(self), apa->apa_ctlnum);
+	}
+	if (systype == NEWS4000) {
+		apbus_intr_establish(1, /* interrupt level ( 0 or 1 ) */
+				     0x0200,
+				     0, /* priority */
+				     zshard_ap, zsc,
+				     device_xname(self), apa->apa_ctlnum);
+#ifdef NEWS4000_ZS_AP_POLLING
+		/* XXX: no info how to enable zs ap interrupt for now */
+		callout_init(&zscallout, 0);
+		callout_reset(&zscallout, 1,
+		    (void (*)(void *))zshard_ap, (void *)zsc);
+#endif
+	}
 	/* XXX; evcnt_attach() ? */
 
 #if 0
@@ -335,6 +447,11 @@ zshard_ap(void *arg)
 {
 
 	zshard(arg);
+#ifdef NEWS4000_ZS_AP_POLLING
+	if (systype == NEWS4000) {
+		callout_schedule(&zscallout, 1);
+	}
+#endif
 	return 1;
 }
 
@@ -426,13 +543,25 @@ zscninit(struct consdev *cn)
 static int
 zscngetc(dev_t dev)
 {
+	void *sccport0a;
 
-	return zs_getc((void *)NEWS5000_SCCPORT0A);
+	if (systype == NEWS5000)
+		sccport0a = (void *)NEWS5000_SCCPORT0A;
+	if (systype == NEWS4000)
+		sccport0a = (void *)NEWS4000_SCCPORT0A;
+ 
+	return zs_getc(sccport0a);
 }
 
 static void
 zscnputc(dev_t dev, int c)
 {
+	void *sccport0a;
+
+	if (systype == NEWS5000)
+		sccport0a = (void *)NEWS5000_SCCPORT0A;
+	if (systype == NEWS4000)
+		sccport0a = (void *)NEWS4000_SCCPORT0A;
 
-	zs_putc((void *)NEWS5000_SCCPORT0A, c);
+	zs_putc(sccport0a, c);
 }

Index: src/sys/arch/newsmips/conf/GENERIC
diff -u src/sys/arch/newsmips/conf/GENERIC:1.135 src/sys/arch/newsmips/conf/GENERIC:1.136
--- src/sys/arch/newsmips/conf/GENERIC:1.135	Sun Sep 30 14:04:51 2018
+++ src/sys/arch/newsmips/conf/GENERIC	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.135 2018/09/30 14:04:51 tsutsui Exp $
+# $NetBSD: GENERIC,v 1.136 2018/10/14 00:10:11 tsutsui Exp $
 #
 # GENERIC machine description file
 # 
@@ -22,11 +22,12 @@ include 	"arch/newsmips/conf/std.newsmip
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.135 $"
+#ident 		"GENERIC-$Revision: 1.136 $"
 
 maxusers	16
 
 options 	news3400		# NWS-3400/3700 support
+options 	news4000		# NWS-4000 support
 options 	news5000		# NWS-5000 support
 options 	MIPS1			# R2000/R3000 support
 options 	MIPS3			# R4000 support
@@ -154,6 +155,7 @@ zsc0	at hb0 addr 0xbfec0000 level 1 flag
 zsc1	at hb0 addr 0xb8c40100 level 1 flags 0x1	# NWB-231A 4ch serial
 zsc2	at hb0 addr 0xb8c40104 level 1 flags 0x1	#
 zsc0	at ap?
+options 	NEWS4000_ZS_AP_POLLING	# XXX: can't get interrupt on news4000
 
 zstty0	at zsc0 channel 0		# tty00
 zstty1	at zsc0 channel 1		# tty01

Index: src/sys/arch/newsmips/conf/files.newsmips
diff -u src/sys/arch/newsmips/conf/files.newsmips:1.30 src/sys/arch/newsmips/conf/files.newsmips:1.31
--- src/sys/arch/newsmips/conf/files.newsmips:1.30	Sun Jul 20 10:22:54 2014
+++ src/sys/arch/newsmips/conf/files.newsmips	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: files.newsmips,v 1.30 2014/07/20 10:22:54 alnsn Exp $
+#	$NetBSD: files.newsmips,v 1.31 2018/10/14 00:10:11 tsutsui Exp $
 
 # NEWSMIPS-specific configuration info
 
@@ -90,7 +90,8 @@ file arch/newsmips/newsmips/bus.c
 file arch/newsmips/newsmips/clock.c
 file arch/newsmips/newsmips/machdep.c
 file arch/newsmips/newsmips/news3400.c		hb
-file arch/newsmips/newsmips/news5000.c		ap
+file arch/newsmips/newsmips/news4000.c		ap & news4000
+file arch/newsmips/newsmips/news5000.c		ap & news5000
 file arch/newsmips/newsmips/disksubr.c
 file arch/newsmips/newsmips/mainbus.c
 file arch/newsmips/newsmips/cpu_cons.c

Index: src/sys/arch/newsmips/conf/std.newsmips
diff -u src/sys/arch/newsmips/conf/std.newsmips:1.18 src/sys/arch/newsmips/conf/std.newsmips:1.19
--- src/sys/arch/newsmips/conf/std.newsmips:1.18	Sun Sep 30 06:14:23 2018
+++ src/sys/arch/newsmips/conf/std.newsmips	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-#	$NetBSD: std.newsmips,v 1.18 2018/09/30 06:14:23 tsutsui Exp $
+#	$NetBSD: std.newsmips,v 1.19 2018/10/14 00:10:11 tsutsui Exp $
 
 machine newsmips mips
 include		"conf/std"	# MI standard options
@@ -8,6 +8,7 @@ options 	EXEC_ELF32	# exec ELF32 binarie
 options 	EXEC_SCRIPT	# exec #! scripts
 
 options 	ENABLE_MIPS3_WIRED_MAP
+options 	ENABLE_MIPS_R4700	# NWS-4000 has NKK R4700
 
 makeoptions	DEFTEXTADDR="0x80001000"
 makeoptions	LINKFORMAT="-N"

Index: src/sys/arch/newsmips/include/adrsmap.h
diff -u src/sys/arch/newsmips/include/adrsmap.h:1.8 src/sys/arch/newsmips/include/adrsmap.h:1.9
--- src/sys/arch/newsmips/include/adrsmap.h:1.8	Sun Dec 11 12:18:24 2005
+++ src/sys/arch/newsmips/include/adrsmap.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: adrsmap.h,v 1.8 2005/12/11 12:18:24 christos Exp $	*/
+/*	$NetBSD: adrsmap.h,v 1.9 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -213,6 +213,9 @@
 
 #define	ABEINT_BADDR	0xbfdc0038
 
+/*----------------------------------------------------------------------
+ *	news5000
+ *----------------------------------------------------------------------*/
 #define	NEWS5000_DIP_SWITCH	0xbf3d0000
 #define	NEWS5000_IDROM		0xbf3c0000
 
@@ -299,4 +302,54 @@
 
 #define	NEWS5000_SCCPORT0A	0xbe950000
 
+/*----------------------------------------------------------------------
+ *	news4000
+ *----------------------------------------------------------------------*/
+#define	NEWS4000_IDROM_STATUS	0xbf880018
+#define	NEWS4000_IDROM_DATA	0xbf88001c
+
+#define	NEWS4000_TIMERCTL	0xbf90000c
+#define	NEWS4000_TIMER		0xbf900014
+
+#define	NEWS4000_NVRAM		0xbfb10000
+#define	NEWS4000_NVRAM_SIZE	0x7f8
+#define	NEWS4000_RTC_PORT	0xbfb17fe0
+
+#define	NEWS4000_INTEN0		0xb6000010
+#define	NEWS4000_INTEN1		0xb6000014
+#define	NEWS4000_INTEN2		0xb6000018
+#define	NEWS4000_INTEN3		0xb600001c
+#define	NEWS4000_INTEN4		0xb6000020
+#define	NEWS4000_INTEN5		0xb6000024
+
+#define	NEWS4000_INTST0		0xb6000030
+#define	NEWS4000_INTST1		0xb6000034
+#define	NEWS4000_INTST2		0xbf900010
+#define	NEWS4000_INTST3		0xb600003c
+#define	NEWS4000_INTST4		0xb6000040
+#define	NEWS4000_INTST5		0xb6000044
+
+/*
+ * level0 intr (INTMASK0/INTSTAT0)
+ */
+#define	NEWS4000_INT0_SONIC	0x0800
+
+/*
+ * level2 intr (INTMASK2/INTSTAT2)
+ */
+#define	NEWS4000_INT2_TIMER	0x01
+
+#define	NEWS4000_WBFLUSH	0xbf880000
+
+#define	NEWS4000_LED		0xbfb30004
+#define		NEWS4000_LED0		0x01	/* POWER LED */
+#define		NEWS4000_LED1		0x02	/* NETWORK LED */
+#define		NEWS4000_LED2		0x04	/* FLOPPY LED */
+#define		NEWS4000_LED3		0x08	/* DISK LED */
+
+#define	NEWS4000_SONIC_MEMORY	0xbf3a0000
+#define	NEWS4000_SONIC_BUFFER	0xbf380000
+
+#define	NEWS4000_SCCPORT0A	0xbfb00008
+
 #endif /* !__MACHINE_ADRSMAP__ */

Index: src/sys/arch/newsmips/include/apbus.h
diff -u src/sys/arch/newsmips/include/apbus.h:1.5 src/sys/arch/newsmips/include/apbus.h:1.6
--- src/sys/arch/newsmips/include/apbus.h:1.5	Sun Dec 11 12:18:24 2005
+++ src/sys/arch/newsmips/include/apbus.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: apbus.h,v 1.5 2005/12/11 12:18:24 christos Exp $	*/
+/*	$NetBSD: apbus.h,v 1.6 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (C) 1999 SHIMIZU Ryo.  All rights reserved.
@@ -103,6 +103,7 @@ struct apbus_sysinfo {
  */
 
 extern struct apbus_sysinfo *_sip;
+extern volatile uint32_t *news_wbflush;
 void apbus_wbflush(void);
 
 #endif /* !__MACHINE_APBUS__ */

Index: src/sys/arch/newsmips/include/cpu.h
diff -u src/sys/arch/newsmips/include/cpu.h:1.16 src/sys/arch/newsmips/include/cpu.h:1.17
--- src/sys/arch/newsmips/include/cpu.h:1.16	Fri May  9 13:36:42 2003
+++ src/sys/arch/newsmips/include/cpu.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.h,v 1.16 2003/05/09 13:36:42 tsutsui Exp $	*/
+/*	$NetBSD: cpu.h,v 1.17 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 #ifndef _NEWSMIPS_CPU_H_
 #define _NEWSMIPS_CPU_H_
@@ -11,6 +11,7 @@ extern int systype;
 
 #define NEWS3400	1
 #define NEWS5000	2
+#define NEWS4000	3
 
 /* System type dependent initializations. */
 #ifdef news3400
@@ -20,6 +21,9 @@ int news3400_badaddr(void *, u_int);
 #ifdef news5000
 void news5000_init(void);
 #endif
+#ifdef news4000
+void news4000_init(void);
+#endif
 #endif
 #endif
 

Index: src/sys/arch/newsmips/include/intr.h
diff -u src/sys/arch/newsmips/include/intr.h:1.26 src/sys/arch/newsmips/include/intr.h:1.27
--- src/sys/arch/newsmips/include/intr.h:1.26	Thu Jul 21 19:49:59 2016
+++ src/sys/arch/newsmips/include/intr.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.26 2016/07/21 19:49:59 christos Exp $	*/
+/*	$NetBSD: intr.h,v 1.27 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -77,6 +77,7 @@ extern u_int intrcnt[];
 /* handle i/o device interrupts */
 void news3400_intr(int, vaddr_t, uint32_t);
 void news5000_intr(int, vaddr_t, uint32_t);
+void news4000_intr(int, vaddr_t, uint32_t);
 extern void (*hardware_intr)(int, vaddr_t, uint32_t);
 
 extern void (*enable_intr)(void);

Index: src/sys/arch/newsmips/newsmips/cpu_cons.c
diff -u src/sys/arch/newsmips/newsmips/cpu_cons.c:1.13 src/sys/arch/newsmips/newsmips/cpu_cons.c:1.14
--- src/sys/arch/newsmips/newsmips/cpu_cons.c:1.13	Sat Jul 28 23:08:57 2012
+++ src/sys/arch/newsmips/newsmips/cpu_cons.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_cons.c,v 1.13 2012/07/28 23:08:57 matt Exp $	*/
+/*	$NetBSD: cpu_cons.c,v 1.14 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_cons.c,v 1.13 2012/07/28 23:08:57 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_cons.c,v 1.14 2018/10/14 00:10:11 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -124,5 +124,17 @@ consinit(void)
 		break;
 
 #endif /* news5000 */
+
+#ifdef news4000
+	case NEWS4000:
+		dipsw = 0;	/* XXX */
+		(void)dipsw;
+#if NZSC > 0
+		cn_tab = &consdev_zs_ap;
+		(*cn_tab->cn_init)(cn_tab);
+#endif
+		break;
+
+#endif /* news4000 */
 	}
 }

Index: src/sys/arch/newsmips/newsmips/machdep.c
diff -u src/sys/arch/newsmips/newsmips/machdep.c:1.119 src/sys/arch/newsmips/newsmips/machdep.c:1.120
--- src/sys/arch/newsmips/newsmips/machdep.c:1.119	Thu Dec 22 14:47:58 2016
+++ src/sys/arch/newsmips/newsmips/machdep.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.119 2016/12/22 14:47:58 cherry Exp $	*/
+/*	$NetBSD: machdep.c,v 1.120 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.119 2016/12/22 14:47:58 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.120 2018/10/14 00:10:11 tsutsui Exp $");
 
 /* from: Utah Hdr: machdep.c 1.63 91/04/24 */
 
@@ -194,13 +194,14 @@ mach_init(int x_boothowto, int x_bootdev
 	if (systype == 0) 
 		systype = NEWS3400;	/* XXX compatibility for old boot */
 
-#ifdef news5000
-	if (systype == NEWS5000) {
+#if defined(news5000) || defined(news4000)
+	if (systype == NEWS5000 || systype == NEWS4000) {
 		int i;
 		char *bspec = (char *)x_bootdev;
 
 		if (bi_arg == NULL)
-			panic("news5000 requires BTINFO_BOOTARG to boot");
+			panic("%s requires BTINFO_BOOTARG to boot",
+			    systype == NEWS5000 ? "news5000" : "news4000");
 
 		_sip = (void *)bi_arg->sip;
 		x_maxmem = _sip->apbsi_memsize;
@@ -225,7 +226,7 @@ mach_init(int x_boothowto, int x_bootdev
  bootspec_end:
 		consinit();
 	}
-#endif
+#endif /* news5000 || news4000 */
 
 	/*
 	 * Save parameters into kernel work area.
@@ -347,6 +348,23 @@ mach_init(int x_boothowto, int x_bootdev
 		break;
 #endif
 
+#ifdef news4000
+	case NEWS4000:
+		news4000_init();
+		cpu_setmodel("%s", idrom.id_machine);
+		model = cpu_getmodel();
+		if (strcmp(model, "news4000") == 0) {
+			/*
+			 * Set up interrupt handling and I/O addresses.
+			 */
+			hardware_intr = news4000_intr;
+			cpuspeed = 40;  /* ??? XXX */
+		} else {
+			printf("kernel not configured for machine %s\n", model);
+		}
+		break;
+#endif
+
 	default:
 		printf("kernel not configured for systype %d\n", systype);
 		break;
@@ -406,8 +424,8 @@ void
 prom_halt(int howto)
 
 {
-#ifdef news5000
-	if (systype == NEWS5000)
+#if defined(news5000) || defined(news4000)
+	if (systype == NEWS5000 || systype == NEWS4000)
 		apcall_exit(howto);
 #endif
 #ifdef news3400

Index: src/sys/arch/newsmips/newsmips/machid.h
diff -u src/sys/arch/newsmips/newsmips/machid.h:1.6 src/sys/arch/newsmips/newsmips/machid.h:1.7
--- src/sys/arch/newsmips/newsmips/machid.h:1.6	Sun Dec 11 12:18:25 2005
+++ src/sys/arch/newsmips/newsmips/machid.h	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: machid.h,v 1.6 2005/12/11 12:18:25 christos Exp $	*/
+/*	$NetBSD: machid.h,v 1.7 2018/10/14 00:10:11 tsutsui Exp $	*/
 /*
  * Copyright (c) 1992, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -158,7 +158,7 @@ struct idrom {
 };
 #endif /* news700 || news800 || news1700 || news1800 */
 
-#if defined(news1200) || defined(news3400) || defined(news3800) || defined(news5000)
+#if defined(news1200) || defined(news3400) || defined(news3800) || defined(news5000) || defined(news4000)
 struct idrom {
 /*00*/	unsigned char	id_id;          	/* always 0xff */
 /*01*/	unsigned char	id_netid[5];    	/* network ID */
@@ -180,7 +180,7 @@ struct idrom {
 /*7c*/	unsigned int	id_csum3;
 /*80*/
 };
-#endif /* news1200 || news3400 || news3800 */
+#endif /* news1200 || news3400 || news3800 || news5000 || news4000 */
 
 #endif /* !LOCORE */
 

Index: src/sys/arch/newsmips/newsmips/news5000.c
diff -u src/sys/arch/newsmips/newsmips/news5000.c:1.21 src/sys/arch/newsmips/newsmips/news5000.c:1.22
--- src/sys/arch/newsmips/newsmips/news5000.c:1.21	Thu Jul 21 19:49:59 2016
+++ src/sys/arch/newsmips/newsmips/news5000.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: news5000.c,v 1.21 2016/07/21 19:49:59 christos Exp $	*/
+/*	$NetBSD: news5000.c,v 1.22 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (C) 1999 SHIMIZU Ryo.  All rights reserved.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: news5000.c,v 1.21 2016/07/21 19:49:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: news5000.c,v 1.22 2018/10/14 00:10:11 tsutsui Exp $");
 
 #define __INTR_PRIVATE
 #include <sys/param.h>
@@ -288,6 +288,8 @@ news5000_init(void)
 	disable_intr = news5000_disable_intr;
 	enable_timer = news5000_enable_timer;
 
+	news_wbflush = (uint32_t *)NEWS5000_WBFLUSH;
+
 	news5000_readidrom((uint8_t *)&idrom);
 	hostid = idrom.id_serial;
 

Index: src/sys/arch/newsmips/stand/boot/boot.c
diff -u src/sys/arch/newsmips/stand/boot/boot.c:1.20 src/sys/arch/newsmips/stand/boot/boot.c:1.21
--- src/sys/arch/newsmips/stand/boot/boot.c:1.20	Wed Mar 26 17:43:11 2014
+++ src/sys/arch/newsmips/stand/boot/boot.c	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.20 2014/03/26 17:43:11 christos Exp $	*/
+/*	$NetBSD: boot.c,v 1.21 2018/10/14 00:10:11 tsutsui Exp $	*/
 
 /*-
  * Copyright (C) 1999 Tsubai Masanari.  All rights reserved.
@@ -195,7 +195,15 @@ boot(uint32_t a0, uint32_t a1, uint32_t 
 	strcpy(bi_bpath.bootpath, file);
 	bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
 
-	bi_sys.type = apbus ? NEWS5000 : NEWS3400;		/* XXX */
+	if (apbus) {
+		char *machine = (char *)apcall_getenv("machine");
+
+		bi_sys.type = NEWS5000;
+		if (machine != NULL && (strncmp(machine, "news4000", 8) == 0))
+			bi_sys.type = NEWS4000;
+	} else {
+		bi_sys.type = NEWS3400;
+	}
 	bi_add(&bi_sys, BTINFO_SYSTYPE, sizeof(bi_sys));
 
 	entry = (void *)marks[MARK_ENTRY];

Index: src/sys/arch/newsmips/stand/boot/version
diff -u src/sys/arch/newsmips/stand/boot/version:1.2 src/sys/arch/newsmips/stand/boot/version:1.3
--- src/sys/arch/newsmips/stand/boot/version:1.2	Sun Sep 30 14:02:06 2018
+++ src/sys/arch/newsmips/stand/boot/version	Sun Oct 14 00:10:11 2018
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.2 2018/09/30 14:02:06 tsutsui Exp $
+$NetBSD: version,v 1.3 2018/10/14 00:10:11 tsutsui Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -12,3 +12,4 @@ is taken as the current.
 1.6:	Add ustarfs support
 1.7:	Use newvers_stand.sh and print version strings
 1.8:	Switch to DHCP rather than BOOTPARAM
+1.9:	Add news4000 support

Added files:

Index: src/sys/arch/newsmips/newsmips/news4000.c
diff -u /dev/null src/sys/arch/newsmips/newsmips/news4000.c:1.1
--- /dev/null	Sun Oct 14 00:10:11 2018
+++ src/sys/arch/newsmips/newsmips/news4000.c	Sun Oct 14 00:10:11 2018
@@ -0,0 +1,242 @@
+/*	$NetBSD: news4000.c,v 1.1 2018/10/14 00:10:11 tsutsui Exp $	*/
+
+/*-
+ * Copyright (C) 2000 NONAKA Kimihiro.  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.
+ */
+
+#define __INTR_PRIVATE
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/timetc.h>
+#include <sys/intr.h>
+
+#include <machine/adrsmap.h>
+#include <machine/cpu.h>
+
+#include <mips/locore.h>
+
+#include <newsmips/apbus/apbusvar.h>
+#include <newsmips/newsmips/machid.h>
+
+static void news4000_level0_intr(void);
+static void news4000_level1_intr(void);
+
+static void news4000_enable_intr(void);
+static void news4000_disable_intr(void);
+static void news4000_enable_timer(void);
+static void news4000_readidrom(uint8_t *);
+
+/*
+ * This is a mask of bits of to clear in the SR when we go to a
+ * given interrupt priority level.
+ */
+static const struct ipl_sr_map news4000_ipl_sr_map = {
+    .sr_bits = {
+	[IPL_NONE] = 		0,
+	[IPL_SOFTCLOCK] =	MIPS_SOFT_INT_MASK_0,
+	[IPL_SOFTNET] =		MIPS_SOFT_INT_MASK,
+	[IPL_VM] =		MIPS_SOFT_INT_MASK
+				| MIPS_INT_MASK_0
+				| MIPS_INT_MASK_1,
+	[IPL_SCHED] =		MIPS_SOFT_INT_MASK
+				| MIPS_INT_MASK_0
+				| MIPS_INT_MASK_1
+				| MIPS_INT_MASK_2,
+	[IPL_DDB] =		MIPS_INT_MASK,
+	[IPL_HIGH] =		MIPS_INT_MASK,
+    },
+};
+
+/*
+ * Handle news4000 interrupts.
+ */
+void
+news4000_intr(int ppl, vaddr_t pc, uint32_t status)
+{
+	uint32_t ipending;
+	int ipl;
+
+	while (ppl < (ipl = splintr(&ipending))) {
+		if (ipending & MIPS_INT_MASK_2) {
+			uint32_t int2stat;
+
+			int2stat = *(volatile uint32_t *)NEWS4000_INTST2;
+
+			if (int2stat & NEWS4000_INT2_TIMER) {
+				struct clockframe cf = {
+					.pc = pc,
+					.sr = status,
+					.intr = (curcpu()->ci_idepth > 1),
+				};
+				*(volatile uint32_t *)NEWS4000_TIMER = 1;
+
+				hardclock(&cf);
+				intrcnt[HARDCLOCK_INTR]++;
+			}
+
+			apbus_wbflush();
+		}
+
+		if (ipending & MIPS_INT_MASK_5) {
+			uint32_t int5stat =
+			    *(volatile uint32_t *)NEWS4000_INTST5;
+			printf("level5 interrupt: status = %04x\n", int5stat);
+			apbus_wbflush();
+		}
+
+		if (ipending & MIPS_INT_MASK_4) {
+			uint32_t int4stat =
+			    *(volatile uint32_t *)NEWS4000_INTST4;
+			printf("level4 interrupt: status = %04x\n", int4stat);
+			apbus_wbflush();
+		}
+
+		if (ipending & MIPS_INT_MASK_3) {
+			printf("level3 interrupt\n");
+			apbus_wbflush();
+		}
+
+		if (ipending & MIPS_INT_MASK_1) {
+			news4000_level1_intr();
+			apbus_wbflush();
+		}
+
+		if (ipending & MIPS_INT_MASK_0) {
+			news4000_level0_intr();
+			apbus_wbflush();
+		}
+	}
+}
+
+static void
+news4000_level1_intr(void)
+{
+	uint32_t int1stat;
+
+	int1stat = *(volatile uint32_t *)NEWS4000_INTST1;
+
+#if 0
+	*(volatile uint32_t *)NEWS4000_LED = 0xe;	/* XXX */
+#endif
+
+	printf("level1_intr stat = 0x%x\n", int1stat);
+
+	if (int1stat) {
+		if (apbus_intr_dispatch(1, int1stat) == 0)
+			printf("level1_intr: no handler (mask 0x%04x)\n",
+			    int1stat);
+	} else
+		printf("level1 stray interrupt?\n");
+}
+
+static void
+news4000_level0_intr(void)
+{
+	uint32_t int0stat;
+
+	int0stat = *(volatile uint32_t *)NEWS4000_INTST0;
+
+	if (int0stat) {
+		if (apbus_intr_dispatch(0, int0stat) == 0)
+			printf("level0_intr: no handler (mask 0x%04x)\n",
+			    int0stat);
+	} else
+		printf("level0 stray interrupt?\n");
+}
+
+static void
+news4000_enable_intr(void)
+{
+
+	*(volatile uint32_t *)NEWS4000_INTEN0 = 0xffffffff;
+	*(volatile uint32_t *)NEWS4000_INTEN1 = 0xffffffff;
+	*(volatile uint32_t *)NEWS4000_INTEN2 = 1;
+	*(volatile uint32_t *)NEWS4000_INTEN3 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN4 = 0;	/* 3 */
+	*(volatile uint32_t *)NEWS4000_INTEN5 = 0;	/* 3 */
+}
+
+static void
+news4000_disable_intr(void)
+{
+
+	*(volatile uint32_t *)NEWS4000_INTEN0 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN1 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN2 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN3 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN4 = 0;
+	*(volatile uint32_t *)NEWS4000_INTEN5 = 0;
+}
+
+static void
+news4000_enable_timer(void)
+{
+
+#if 0
+	news4000_tc_init();
+#endif
+
+	/* enable timer interrpt */
+	*(volatile uint32_t *)NEWS4000_TIMERCTL = 1;
+}
+
+extern struct idrom idrom;
+
+static void
+news4000_readidrom(uint8_t *rom)
+{
+	volatile uint32_t *status_port = (uint32_t *)NEWS4000_IDROM_STATUS;
+	volatile uint32_t *data_port = (uint32_t *)NEWS4000_IDROM_DATA;
+	int offset;
+
+	while ((*status_port & 1) == 0)
+		continue;
+
+	for (offset = 0; offset < sizeof(struct idrom); offset++, rom++) {
+		*data_port = offset;
+		
+		while ((*status_port & 1) == 0)
+			continue;
+
+		*rom = (uint8_t)(*data_port & 0xff);
+	}
+}
+
+void
+news4000_init(void)
+{
+
+	ipl_sr_map = news4000_ipl_sr_map;
+
+	enable_intr = news4000_enable_intr;
+	disable_intr = news4000_disable_intr;
+	enable_timer = news4000_enable_timer;
+
+	news_wbflush = (uint32_t *)NEWS4000_WBFLUSH;
+
+	news4000_readidrom((uint8_t *)&idrom);
+	hostid = idrom.id_serial;
+}

Reply via email to