Port-newsmips archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
NWS-4000 (news4000) support
I'm working on pulling NWS-4000 support into -current.
The NWS-4000 porting effort was done by nonaka@ back in 2002
(around 1.5ZA and 1.6):
http://www.asahi-net.or.jp/~aw9k-nnk/n/#news4000
You can see NEWS machine (including NWS-4000) specifications in this page:
http://katsu.watanabe.name/doc/sonynews/model.html
(NWS-4000 has NKK R4700 133 or 175MHz)
I'll commit changes (attached below) in this weekend,
if there is no particular objection.
Current status:
- on-board (and APbus) sn(4) SONIC Ethernet work
- on-board zs(4) serial partially work (no interrupt, polling only)
- no SCSI (spifi + lr4710) support
- no framebuffer (xg; aka PowerVR 9100) support
- keyboard and mouse may work (but untested)
- GENERIC kernel boot both NWS-4000 and NWS-5000
dmesg:
---
Real memory size 0x06000000 (98304KB)
Free memory size 0x05fe8d78 (98211KB)
slot 0: base=0xbfc70000, size=0x00010000, Sony/NWS-4000
slot 1: base=0xb8000000, size=0x00400000, Sony/NWB-5851
Testing main memory from 0x00000000 through 0x05dfffff: done
Clearing kernel message buffer: done
SONY NET WORK STATION, Model NWS-4000, Machine ID #12200
APbus System Monitor Release 3.530
Copyright (c) 1992, 1993, 1994, 1995, 1996 Sony Corporation
All Rights Reserved
fd0: 2DD/2HD drive
scsi0 on spifi0
sonic0: hardware address 08:00:46:01:1a:59
sonic1: hardware address 08:00:46:01:1a:f2
xg0: Power9100/4MB-VRAM/170MHz-DAC
xg0: VESA(1024x768,60Hz)
Uninitialized system clock, set date & time.
> bo tftp
NetBSD/newsmips Secondary Boot, Revision 1.7
(tsutsui@mirage, Sat Sep 29 01:47:37 JST 2018)
Booting sonic()
Using IP address: 192.168.20.27
myip: (192.168.20.27), gateip: 192.168.20.1, netmask: 255.255.255.0
root addr=192.168.20.1 path=/r/export/NetBSD/newsmips/root
3837520+128624 [221424+210089]=0x431f40
[ 1.0000000] SONY NET WORK STATION, Model NWS-4000, Machine ID #12200
[ 1.0000000] Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
[ 1.0000000] 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
[ 1.0000000] 2018 The NetBSD Foundation, Inc. All rights reserved.
[ 1.0000000] Copyright (c) 1982, 1986, 1989, 1991, 1993
[ 1.0000000] The Regents of the University of California. All rights reserved.
[ 1.0000000] NetBSD 8.99.25 (GENERIC) #224: Sat Oct 13 08:20:19 JST 2018
[ 1.0000000] tsutsui@mirage:/usr/src/sys/arch/newsmips/compile/GENERIC
[ 1.0000000] news4000
[ 1.0000000] total memory = 97280 KB
[ 1.0000000] avail memory = 90992 KB
[ 1.0000000] mainbus0 (root)
[ 1.0000000] cpu0 at mainbus0: QED R4700 Orion CPU (0x2110) Rev. 1.0 with built-in FPU Rev. 1.0
[ 1.0000000] cpu0: 48 TLB entries, 16MB max page size
[ 1.0000000] cpu0: 16KB/32B 2-way set-associative L1 instruction cache
[ 1.0000000] cpu0: 16KB/32B 2-way set-associative write-back L1 data cache
[ 1.0000000] ap0 at mainbus0
[ 1.0000000] audio at ap0 slot0 addr 0xbe230000 not configured
[ 1.0000000] mkclock0 at ap0 slot0 addr 0xbfb17fe0: mk48t02
[ 1.0000000] zsc0 at ap0 slot0 addr 0xbfa80000
[ 1.0000000] zstty0 at zsc0 channel 0 (console i/o)
[ 1.0000000] zstty1 at zsc0 channel 1
[ 1.0000000] fd at ap0 slot0 addr 0xbe220000 not configured
[ 1.0000000] kb0 at ap0 slot0 addr 0xbf980000
[ 1.0000000] wskbd0 at kb0 (mux ignored)
[ 1.0000000] lp at ap0 slot0 addr 0xbfa00000 not configured
[ 1.0000000] lr4710 at ap0 slot0 addr 0xbe200000 not configured
[ 1.0000000] ms0 at ap0 slot0 addr 0xbf980014
[ 1.0000000] wsmouse0 at ms0 (mux ignored)
[ 1.0000000] sn0 at ap0 slot0 addr 0xbf600000
[ 1.0000000] sn0: Ethernet address 08:00:46:01:1a:59
[ 1.0000000] sn1 at ap0 slot1 addr 0xb8200000
[ 1.0000000] sn1: Ethernet address 08:00:46:01:1a:f2
[ 1.0000000] spifi0 at ap0: cannot find slave dmac
[ 1.0000000] xg at ap0 slot0 addr 0xb0000000 not configured
[ 1.1500030] WARNING: 1 error while detecting hardware; check system log.
[ 1.1600030] boot device: <unknown>
[ 1.1700030] root device: sn0
[ 1.2200030] dump device:
[ 1.2400030] file system (default generic):
[ 1.2600030] root on sn0
[ 1.2700030] nfs_boot: trying DHCP/BOOTP
[ 4.3100030] nfs_boot: DHCP next-server: 192.168.20.1
[ 4.3200030] nfs_boot: my_domain=ceres.dti.ne.jp
[ 4.3300030] nfs_boot: my_addr=192.168.20.27
[ 4.3400030] nfs_boot: my_mask=255.255.255.0
[ 4.3500030] nfs_boot: gateway=192.168.20.1
[ 10.4300030] root on mirage:/r/export/NetBSD/newsmips/root
[ 10.4400030] root file system type: nfs
[ 10.4500030] kern.module.path=/stand/newsmips/8.99.25/modules
[ 10.4600030] WARNING: preposterous TOD clock time
[ 10.4700030] WARNING: using filesystem time
[ 10.4800030] WARNING: CHECK AND RESET THE DATE!
[ 10.5100030] init path (default /sbin/init):
[ 10.5400030] init: trying /sbin/init
/etc/rc.conf is not configured. Multiuser boot aborted.
Enter pathname of shell or RETURN for /bin/sh:
We recommend that you create a non-root account and use su(1) for root access.
#
---
diffs:
- apbus/apbus.c, apbus/apbusvar.h
news4000 specific apbus stuff
- apbus/if_sn.c, apbus/if_sn_ap.c, apbus/if_snvar.h
news4000 on-board sonic quirk support
- apbus/kb_ap.c
disable console on news4000 for now
- apbus/zs_ap.c
news4000 on-board zs support
- include/adrsmap.h
add news4000 specific addresses
- newsmips/cpu_cons.c, newsmips/machdep.c, newsmips/news4000.c
news4000 specific stuff
- newsmips/news5000.c, include/apbus.h
change MD wbflush() glue to support both news4000 and news5000
- stand/boot/boot.c
check news4000 machine type
diff --git a/apbus/apbus.c b/apbus/apbus.c
index 3f8b687..3928231 100644
--- a/apbus/apbus.c
+++ b/apbus/apbus.c
@@ -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 self, void *aux)
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, int priority, int (*func)(void *),
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;
}
diff --git a/apbus/apbusvar.h b/apbus/apbusvar.h
index 74f60a6..5ae33e1 100644
--- a/apbus/apbusvar.h
+++ b/apbus/apbusvar.h
@@ -50,4 +50,7 @@ void *apbus_intr_establish(int, int, int, int (*)(void *), void *,
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))
diff --git a/apbus/if_sn.c b/apbus/if_sn.c
index 5e361dd..4711284 100644
--- a/apbus/if_sn.c
+++ b/apbus/if_sn.c
@@ -109,7 +109,7 @@ snsetup(struct sn_softc *sc, uint8_t *lladdr)
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 *lladdr)
* 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 *lladdr)
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 *lladdr)
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 *lladdr)
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));
diff --git a/apbus/if_sn_ap.c b/apbus/if_sn_ap.c
index 798eacd..608a323 100644
--- a/apbus/if_sn_ap.c
+++ b/apbus/if_sn_ap.c
@@ -53,6 +53,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_sn_ap.c,v 1.12 2018/09/30 14:23:24 tsutsui Exp $"
#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 self, void *aux)
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 self, void *aux)
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 self, void *aux)
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_t *lladdr)
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);
diff --git a/apbus/if_snvar.h b/apbus/if_snvar.h
index 5baf2d9..05de2b8 100644
--- a/apbus/if_snvar.h
+++ b/apbus/if_snvar.h
@@ -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
};
/*
diff --git a/apbus/kb_ap.c b/apbus/kb_ap.c
index 74b8ab7..b9b64f9 100644
--- a/apbus/kb_ap.c
+++ b/apbus/kb_ap.c
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: kb_ap.c,v 1.11 2018/09/30 14:23:24 tsutsui Exp $");
#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 self, void *aux)
sc->sc_reg = reg;
- if (*dipsw & 7) {
+ if (systype == NEWS5000 && *dipsw & 7) {
aprint_normal(" (console)");
cons = 1;
}
diff --git a/apbus/spifi.c b/apbus/spifi.c
index 75fcb80..955b17c 100644
--- a/apbus/spifi.c
+++ b/apbus/spifi.c
@@ -203,7 +203,7 @@ spifi_attach(device_t parent, device_t self, void *aux)
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),
diff --git a/apbus/zs_ap.c b/apbus/zs_ap.c
index 354edac..8cff645 100644
--- a/apbus/zs_ap.c
+++ b/apbus/zs_ap.c
@@ -47,6 +47,9 @@ __KERNEL_RCSID(0, "$NetBSD: zs_ap.c,v 1.28 2018/09/30 14:23:24 tsutsui Exp $");
#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.28 2018/09/30 14:23:24 tsutsui Exp $");
#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, void *aux)
{
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 self, void *aux)
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 self, void *aux)
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);
+ }
+
+ 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;
- /* assert DTR */ /* XXX */
- portBctl[PORT_CTL] = portActl[PORT_CTL] = PORTCTL_DTR;
+ /* select RS-232C (ch1 only) */
+ portActl[NEWS5000_PORT_SEL] = NEWS5000_PORTSEL_RS232C;
- /* select RS-232C (ch1 only) */
- portActl[PORT_SEL] = PORTSEL_RS232C;
+ /* 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;
- /* enable SCC interrupts */
- esccregs[ESCCREG_INTMASK] = INTMASK_SCC;
+#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 self, void *aux)
*/
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)
{
-
- return zs_getc((void *)NEWS5000_SCCPORT0A);
+ void *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);
}
diff --git a/conf/GENERIC b/conf/GENERIC
index 5db9088..5148109 100644
--- a/conf/GENERIC
+++ b/conf/GENERIC
@@ -27,6 +27,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary
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 flags 0x0 # on-board serial
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
diff --git a/conf/files.newsmips b/conf/files.newsmips
index ed5cd36..1fe7e19 100644
--- a/conf/files.newsmips
+++ b/conf/files.newsmips
@@ -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
diff --git a/conf/std.newsmips b/conf/std.newsmips
index 147a1d9..6ad955a 100644
--- a/conf/std.newsmips
+++ b/conf/std.newsmips
@@ -8,6 +8,7 @@ options EXEC_ELF32 # exec ELF32 binaries
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"
diff --git a/include/adrsmap.h b/include/adrsmap.h
index b448814..9f59a79 100644
--- a/include/adrsmap.h
+++ b/include/adrsmap.h
@@ -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__ */
diff --git a/include/apbus.h b/include/apbus.h
index d7a94d5..28e1704 100644
--- a/include/apbus.h
+++ b/include/apbus.h
@@ -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__ */
diff --git a/include/cpu.h b/include/cpu.h
index eb0158e..a682df5 100644
--- a/include/cpu.h
+++ b/include/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
diff --git a/include/intr.h b/include/intr.h
index f92503c..ae136f1 100644
--- a/include/intr.h
+++ b/include/intr.h
@@ -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);
diff --git a/newsmips/cpu_cons.c b/newsmips/cpu_cons.c
index 7ef6ab9..b8cdfd1 100644
--- a/newsmips/cpu_cons.c
+++ b/newsmips/cpu_cons.c
@@ -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 */
}
}
diff --git a/newsmips/machdep.c b/newsmips/machdep.c
index 18b8233..b820f15 100644
--- a/newsmips/machdep.c
+++ b/newsmips/machdep.c
@@ -194,13 +194,14 @@ mach_init(int x_boothowto, int x_bootdev, int x_bootname, int x_maxmem)
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, int x_bootname, int x_maxmem)
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, int x_bootname, int x_maxmem)
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
diff --git a/newsmips/machid.h b/newsmips/machid.h
index e71ba47..ff71609 100644
--- a/newsmips/machid.h
+++ b/newsmips/machid.h
@@ -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 */
diff --git a/newsmips/news4000.c b/newsmips/news4000.c
new file mode 100644
index 0000000..69b92d3
--- /dev/null
+++ b/newsmips/news4000.c
@@ -0,0 +1,242 @@
+/* $NetBSD$ */
+
+/*-
+ * 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;
+}
diff --git a/newsmips/news5000.c b/newsmips/news5000.c
index 6a4f602..042c10d 100644
--- a/newsmips/news5000.c
+++ b/newsmips/news5000.c
@@ -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;
diff --git a/stand/boot/boot.c b/stand/boot/boot.c
index e00e1ae..8bf0b72 100644
--- a/stand/boot/boot.c
+++ b/stand/boot/boot.c
@@ -195,7 +195,15 @@ boot(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
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];
diff --git a/stand/boot/version b/stand/boot/version
index d220ce1..362ecac 100644
--- a/stand/boot/version
+++ b/stand/boot/version
@@ -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
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index