#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.143 2026/04/28 03:29:10 thorpej Exp $");
#include "opt_ddb.h"
#include "opt_modular.h"
#include "opt_newsconf.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/tty.h>
#include <sys/exec.h>
#include <sys/core.h>
#include <sys/kcore.h>
#include <sys/ksyms.h>
#include <sys/module.h>
#include <sys/cpu.h>
#ifdef DDB
#include <machine/db_machdep.h>
#include <ddb/db_sym.h>
#include <ddb/db_extern.h>
#endif
#ifdef __ELF__
#include <sys/exec_elf.h>
#endif
#include <m68k/cacheops.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/reg.h>
#include <machine/pcb.h>
#include <machine/pte.h>
#include <machine/intr.h>
#include <machine/kcore.h>
#include <m68k/seglist.h>
#include <dev/cons.h>
#include <dev/mm.h>
#define MAXMEM 64*1024
#include <uvm/uvm_extern.h>
#include <sys/sysctl.h>
#include <news68k/news68k/machid.h>
#include <news68k/news68k/isr.h>
#include "le.h"
#include "kb.h"
#include "ms.h"
#include "si.h"
#include "ksyms.h"
#include "romcons.h"
int maxmem;
extern paddr_t avail_start, avail_end;
extern int end, *esym;
extern u_int lowram;
#ifdef news1700
static void news1700_init(void);
static void parityenable(void);
static int parityerror(void *);
#endif
#ifdef news1200
static void news1200_init(void);
#endif
void machine_init(paddr_t);
int delay_divisor = delay_divisor_est(25);
struct pmap_bootmap machine_bootmap[] = {
{ .pmbm_vaddr = NEWS68K_IO_TT_BASE,
.pmbm_size = NEWS68K_IO_TT_SIZE,
.pmbm_flags = PMBM_F_KEEPOUT },
{ .pmbm_vaddr = NEWS68K_PROM_TT_BASE,
.pmbm_size = NEWS68K_PROM_TT_SIZE,
.pmbm_flags = PMBM_F_KEEPOUT },
{ .pmbm_vaddr = -1 },
};
void
machine_init(paddr_t nextpa)
{
PCIA();
ecacheon();
phys_seg_list[0].ps_start = lowram;
phys_seg_list[0].ps_end = m68k_ptob(maxmem);
machine_init_common(nextpa);
switch (systype) {
#ifdef news1700
case NEWS1700:
news1700_init();
break;
#endif
#ifdef news1200
case NEWS1200:
news1200_init();
break;
#endif
default:
panic("impossible system type");
}
}
void
cpu_startup(void)
{
isrinit();
#ifdef news1700
parityenable();
#endif
cpu_startup_common();
}
int news_machine_id;
void
machine_set_model(void)
{
}
void
machine_print_model(void (*pr)(const char *, ...)
__printflike(1, 2))
{
(*pr)("SONY NET WORK STATION, Model %s, Machine ID #%d\n",
cpu_getmodel(), news_machine_id);
}
SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
{
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "machdep", NULL,
NULL, 0, NULL, 0,
CTL_MACHDEP, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "console_device", NULL,
sysctl_consdev, 0, NULL, sizeof(dev_t),
CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
}
void
machine_powerdown(void)
{
extern volatile uint8_t *ctrl_power;
delay(1000000);
*ctrl_power = 0;
}
static volatile uint8_t *dip_switch, *int_status;
const uint8_t *idrom_addr;
volatile uint8_t *ctrl_ast, *ctrl_int2;
uint32_t sccport0a, lance_mem_phys;
#ifdef news1700
static volatile u_char *ctrl_parity, *ctrl_parity_clr, *parity_vector;
struct news68k_model {
const int id;
const char *name;
};
static const struct news68k_model news68k_models[] = {
{ ICK001, "ICK001" },
{ ICK00X, "ICK00X" },
{ NWS799, "NWS-799" },
{ NWS800, "NWS-800" },
{ NWS801, "NWS-801" },
{ NWS802, "NWS-802" },
{ NWS711, "NWS-711" },
{ NWS721, "NWS-721" },
{ NWS1850, "NWS-1850" },
{ NWS810, "NWS-810" },
{ NWS811, "NWS-811" },
{ NWS1830, "NWS-1830" },
{ NWS1750, "NWS-1750" },
{ NWS1720, "NWS-1720" },
{ NWS1930, "NWS-1930" },
{ NWS1960, "NWS-1960" },
{ NWS712, "NWS-712" },
{ NWS1860, "NWS-1860" },
{ PWS1630, "PWS-1630" },
{ NWS820, "NWS-820" },
{ NWS821, "NWS-821" },
{ NWS1760, "NWS-1760" },
{ NWS1710, "NWS-1710" },
{ NWS830, "NWS-830" },
{ NWS831, "NWS-831" },
{ NWS841, "NWS-841" },
{ PWS1570, "PWS-1570" },
{ PWS1590, "PWS-1590" },
{ NWS1520, "NWS-1520" },
{ PWS1550, "PWS-1550" },
{ PWS1520, "PWS-1520" },
{ PWS1560, "PWS-1560" },
{ NWS1530, "NWS-1530" },
{ NWS1580, "NWS-1580" },
{ NWS1510, "NWS-1510" },
{ NWS1410, "NWS-1410" },
{ NWS1450, "NWS-1450" },
{ NWS1460, "NWS-1460" },
{ NWS891, "NWS-891" },
{ NWS911, "NWS-911" },
{ NWS921, "NWS-921" },
{ 0, NULL }
};
static void
news1700_init(void)
{
struct oidrom idrom;
const char *t;
const uint8_t *p;
uint8_t *q;
u_int i;
dip_switch = (uint8_t *)(0xe1c00100);
int_status = (uint8_t *)(0xe1c00200);
idrom_addr = (uint8_t *)(0xe1c00000);
ctrl_ast = (uint8_t *)(0xe1280000);
ctrl_int2 = (uint8_t *)(0xe1180000);
sccport0a = (0xe0d40002);
lance_mem_phys = 0xe0e00000;
p = idrom_addr;
q = (uint8_t *)&idrom;
for (i = 0; i < sizeof(idrom); i++, p += 2)
*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
t = NULL;
for (i = 0; news68k_models[i].name != NULL; i++) {
if (news68k_models[i].id == idrom.id_model) {
t = news68k_models[i].name;
}
}
if (t == NULL)
panic("unexpected system model.");
cpu_setmodel("%s", t);
news_machine_id = (idrom.id_serial[0] << 8) + idrom.id_serial[1];
ctrl_parity = (uint8_t *)(0xe1080000);
ctrl_parity_clr = (uint8_t *)(0xe1a00000);
parity_vector = (uint8_t *)(0xe1c00200);
cpuspeed_khz = 25*1000;
delay_divisor = delay_divisor_est(25);
}
static void
parityenable(void)
{
if (systype != NEWS1700)
return;
#define PARITY_VECT 0xc0
#define PARITY_PRI 7
*parity_vector = PARITY_VECT;
isrlink_vectored(parityerror, NULL, PARITY_PRI, PARITY_VECT);
*ctrl_parity_clr = 1;
*ctrl_parity = 1;
#ifdef DEBUG
printf("enable parity check\n");
#endif
}
static int innmihand;
static int
parityerror(void *arg)
{
if (innmihand)
return 1;
innmihand = 1;
#if 0
panic("parity error");
#else
printf("parity error detected.\n");
*ctrl_parity_clr = 1;
#endif
innmihand = 0;
return 1;
}
#endif
#ifdef news1200
static void
news1200_init(void)
{
struct idrom idrom;
const uint8_t *p;
uint8_t *q;
int i;
dip_switch = (uint8_t *)0xe1680000;
int_status = (uint8_t *)0xe1200000;
idrom_addr = (uint8_t *)0xe1400000;
ctrl_ast = (uint8_t *)0xe1100000;
ctrl_int2 = (uint8_t *)0xe10c0000;
sccport0a = 0xe1780002;
lance_mem_phys = 0xe1a00000;
p = idrom_addr;
q = (uint8_t *)&idrom;
for (i = 0; i < sizeof(idrom); i++, p += 2)
*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
cpu_setmodel("%s", idrom.id_model);
news_machine_id = idrom.id_serial;
cpuspeed_khz = 25*1000;
delay_divisor = delay_divisor_est(25);
}
#endif
void intrhand_lev3(void);
void intrhand_lev4(void);
void
intrhand_lev3(void)
{
int stat;
stat = *int_status;
m68k_count_intr(3);
#if 1
printf("level 3 interrupt: INT_STATUS = 0x%02x\n", stat);
#endif
}
extern int leintr(int);
extern int si_intr(int);
void
intrhand_lev4(void)
{
int stat;
#define INTST_LANCE 0x04
#define INTST_SCSI 0x80
stat = *int_status;
m68k_count_intr(4);
#if NSI > 0
if (stat & INTST_SCSI) {
si_intr(0);
}
#endif
#if NLE > 0
if (stat & INTST_LANCE) {
leintr(0);
}
#endif
#if 0
printf("level 4 interrupt\n");
#endif
}
#define SCC_CONSOLE 0
#define SW_CONSOLE 0x07
#define SW_NWB512 0x04
#define SW_NWB225 0x01
#define SW_FBPOP 0x02
#define SW_FBPOP1 0x06
#define SW_FBPOP2 0x03
#define SW_AUTOSEL 0x07
extern struct consdev consdev_rom, consdev_zs;
int tty00_is_console = 0;
void
consinit(void)
{
uint8_t dipsw;
dipsw = *dip_switch;
dipsw = ~dipsw;
switch (dipsw & SW_CONSOLE) {
default:
#if NROMCONS > 0
cn_tab = &consdev_rom;
(*cn_tab->cn_init)(cn_tab);
break;
#endif
case 0:
tty00_is_console = 1;
cn_tab = &consdev_zs;
(*cn_tab->cn_init)(cn_tab);
break;
}
#if NKSYMS || defined(DDB) || defined(MODULAR)
ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
(void *)&end, esym);
#endif
#ifdef DDB
if (boothowto & RB_KDB)
Debugger();
#endif
}
int
mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
{
*handled = false;
if ((uint8_t *)ptr >= intiobase)
return EFAULT;
return 0;
}