Home | History | Annotate | Line # | Download | only in news68k
      1 /*	$NetBSD: machdep.c,v 1.144 2026/09/20 10:29:12 tsutsui Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988 University of Utah.
      5  * Copyright (c) 1982, 1986, 1990, 1993
      6  *	The Regents of the University of California.  All rights reserved.
      7  *
      8  * This code is derived from software contributed to Berkeley by
      9  * the Systems Programming Group of the University of Utah Computer
     10  * Science Department.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. Neither the name of the University nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  *
     36  * from: Utah $Hdr: machdep.c 1.74 92/12/20$
     37  *
     38  *	@(#)machdep.c	8.10 (Berkeley) 4/20/94
     39  */
     40 
     41 #include <sys/cdefs.h>
     42 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.144 2026/09/20 10:29:12 tsutsui Exp $");
     43 
     44 #include "opt_ddb.h"
     45 #include "opt_modular.h"
     46 #include "opt_newsconf.h"
     47 
     48 #include <sys/param.h>
     49 #include <sys/systm.h>
     50 #include <sys/buf.h>
     51 #include <sys/conf.h>
     52 #include <sys/kernel.h>
     53 #include <sys/device.h>
     54 #include <sys/mbuf.h>
     55 #include <sys/mount.h>
     56 #include <sys/msgbuf.h>
     57 #include <sys/proc.h>
     58 #include <sys/reboot.h>
     59 #include <sys/tty.h>
     60 #include <sys/exec.h>
     61 #include <sys/core.h>
     62 #include <sys/kcore.h>
     63 #include <sys/ksyms.h>
     64 #include <sys/module.h>
     65 #include <sys/cpu.h>
     66 
     67 #ifdef DDB
     68 #include <machine/db_machdep.h>
     69 #include <ddb/db_sym.h>
     70 #include <ddb/db_extern.h>
     71 #endif
     72 #ifdef __ELF__
     73 #include <sys/exec_elf.h>
     74 #endif
     75 
     76 #include <m68k/cacheops.h>
     77 
     78 #include <machine/autoconf.h>
     79 #include <machine/cpu.h>
     80 #include <machine/reg.h>
     81 #include <machine/pcb.h>
     82 #include <machine/pte.h>
     83 #include <machine/intr.h>
     84 
     85 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
     86 
     87 #include <m68k/seglist.h>
     88 
     89 #include <dev/cons.h>
     90 #include <dev/mm.h>
     91 
     92 #define MAXMEM	64*1024		/* XXX - from cmap.h */
     93 #include <uvm/uvm_extern.h>
     94 
     95 #include <sys/sysctl.h>
     96 
     97 #include <news68k/news68k/machid.h>
     98 #include <news68k/news68k/isr.h>
     99 
    100 #include "le.h"
    101 #include "fbbm.h"
    102 #include "kb.h"
    103 #include "kb_kbc.h"
    104 #include "ms.h"
    105 #include "si.h"
    106 #include "ksyms.h"
    107 #include "romcons.h"
    108 /* XXX etc. etc. */
    109 
    110 int	maxmem;			/* max memory per process */
    111 
    112 extern paddr_t avail_start, avail_end;
    113 extern int end, *esym;
    114 extern u_int lowram;
    115 
    116 #ifdef news1700
    117 static void news1700_init(void);
    118 static void parityenable(void);
    119 static int parityerror(void *);
    120 #endif
    121 #ifdef news1200
    122 static void news1200_init(void);
    123 #endif
    124 
    125 /* functions called from locore.s */
    126 void machine_init(paddr_t);
    127 
    128 int	delay_divisor = delay_divisor_est(25);
    129 
    130 /*
    131  * Clamp the kernel virtual address space to keep it out of the
    132  * TT ranges we use for devices.
    133  */
    134 struct pmap_bootmap machine_bootmap[] = {
    135 	{ .pmbm_vaddr = NEWS68K_IO_TT_BASE,
    136 	  .pmbm_size  = NEWS68K_IO_TT_SIZE,
    137 	  .pmbm_flags = PMBM_F_KEEPOUT },
    138 
    139 	{ .pmbm_vaddr = NEWS68K_PROM_TT_BASE,
    140 	  .pmbm_size  = NEWS68K_PROM_TT_SIZE,
    141 	  .pmbm_flags = PMBM_F_KEEPOUT },
    142 
    143 	{ .pmbm_vaddr = -1 },
    144 };
    145 
    146 /*
    147  * Early initialization, before main() is called.
    148  */
    149 void
    150 machine_init(paddr_t nextpa)
    151 {
    152 	/* Clear and enable the external cache, if any. */
    153 	PCIA();
    154 	ecacheon();
    155 
    156 	phys_seg_list[0].ps_start = lowram;
    157 	phys_seg_list[0].ps_end = m68k_ptob(maxmem);
    158 
    159 	machine_init_common(nextpa);
    160 
    161 	/* Initialize system variables. */
    162 	switch (systype) {
    163 #ifdef news1700
    164 	case NEWS1700:
    165 		news1700_init();
    166 		break;
    167 #endif
    168 #ifdef news1200
    169 	case NEWS1200:
    170 		news1200_init();
    171 		break;
    172 #endif
    173 	default:
    174 		panic("impossible system type");
    175 	}
    176 }
    177 
    178 /*
    179  * cpu_startup: allocate memory for variable-sized tables,
    180  * initialize CPU, and do autoconfiguration.
    181  */
    182 void
    183 cpu_startup(void)
    184 {
    185 	/* Initialize the interrupt handlers. */
    186 	isrinit();
    187 
    188 #ifdef news1700
    189 	parityenable();
    190 #endif
    191 
    192 	cpu_startup_common();
    193 }
    194 
    195 int news_machine_id;
    196 
    197 void
    198 machine_set_model(void)
    199 {
    200 	/* This has already been done in newsXXXX_init() */
    201 }
    202 
    203 void
    204 machine_print_model(void (*pr)(const char *, ...)
    205 		    __printflike(1, 2))
    206 {
    207 	(*pr)("SONY NET WORK STATION, Model %s, Machine ID #%d\n",
    208 	    cpu_getmodel(), news_machine_id);
    209 }
    210 
    211 /*
    212  * machine dependent system variables.
    213  */
    214 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
    215 {
    216 
    217 	sysctl_createv(clog, 0, NULL, NULL,
    218 	    CTLFLAG_PERMANENT,
    219 	    CTLTYPE_NODE, "machdep", NULL,
    220 	    NULL, 0, NULL, 0,
    221 	    CTL_MACHDEP, CTL_EOL);
    222 
    223 	sysctl_createv(clog, 0, NULL, NULL,
    224 	    CTLFLAG_PERMANENT,
    225 	    CTLTYPE_STRUCT, "console_device", NULL,
    226 	    sysctl_consdev, 0, NULL, sizeof(dev_t),
    227 	    CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
    228 }
    229 
    230 void
    231 machine_powerdown(void)
    232 {
    233 	extern volatile uint8_t *ctrl_power;
    234 
    235 	delay(1000000);
    236 	*ctrl_power = 0;	/* *poof* */
    237 }
    238 
    239 /*
    240  *  System dependent initialization
    241  */
    242 
    243 static volatile uint8_t *dip_switch, *int_status;
    244 
    245 const uint8_t *idrom_addr;
    246 volatile uint8_t *ctrl_ast, *ctrl_int2;
    247 uint32_t sccport0a, lance_mem_phys;
    248 
    249 #ifdef news1700
    250 static volatile u_char *ctrl_parity, *ctrl_parity_clr, *parity_vector;
    251 
    252 struct news68k_model {
    253 	const int id;
    254 	const char *name;
    255 };
    256 
    257 static const struct news68k_model news68k_models[] = {
    258 	{ ICK001,	"ICK001"	},	/*  1 */
    259 	{ ICK00X,	"ICK00X"	},	/*  2 */
    260 	{ NWS799,	"NWS-799"	},	/*  3 */
    261 	{ NWS800,	"NWS-800"	},	/*  4 */
    262 	{ NWS801,	"NWS-801"	},	/*  5 */
    263 	{ NWS802,	"NWS-802"	},	/*  6 */
    264 	{ NWS711,	"NWS-711"	},	/*  7 */
    265 	{ NWS721,	"NWS-721"	},	/*  8 */
    266 	{ NWS1850,	"NWS-1850"	},	/*  9 */
    267 	{ NWS810,	"NWS-810"	},	/* 10 */
    268 	{ NWS811,	"NWS-811"	},	/* 11 */
    269 	{ NWS1830,	"NWS-1830"	},	/* 12 */
    270 	{ NWS1750,	"NWS-1750"	},	/* 13 */
    271 	{ NWS1720,	"NWS-1720"	},	/* 14 */
    272 	{ NWS1930,	"NWS-1930"	},	/* 15 */
    273 	{ NWS1960,	"NWS-1960"	},	/* 16 */
    274 	{ NWS712,	"NWS-712"	},	/* 17 */
    275 	{ NWS1860,	"NWS-1860"	},	/* 18 */
    276 	{ PWS1630,	"PWS-1630"	},	/* 19 */
    277 	{ NWS820,	"NWS-820"	},	/* 20 */
    278 	{ NWS821,	"NWS-821"	},	/* 21 */
    279 	{ NWS1760,	"NWS-1760"	},	/* 22 */
    280 	{ NWS1710,	"NWS-1710"	},	/* 23 */
    281 	{ NWS830,	"NWS-830"	},	/* 30 */
    282 	{ NWS831,	"NWS-831"	},	/* 31 */
    283 	{ NWS841,	"NWS-841"	},	/* 41 */
    284 	{ PWS1570,	"PWS-1570"	},	/* 52 */
    285 	{ PWS1590,	"PWS-1590"	},	/* 54 */
    286 	{ NWS1520,	"NWS-1520"	},	/* 56 */
    287 	{ PWS1550,	"PWS-1550"	},	/* 73 */
    288 	{ PWS1520,	"PWS-1520"	},	/* 74 */
    289 	{ PWS1560,	"PWS-1560"	},	/* 75 */
    290 	{ NWS1530,	"NWS-1530"	},	/* 76 */
    291 	{ NWS1580,	"NWS-1580"	},	/* 77 */
    292 	{ NWS1510,	"NWS-1510"	},	/* 78 */
    293 	{ NWS1410,	"NWS-1410"	},	/* 81 */
    294 	{ NWS1450,	"NWS-1450"	},	/* 85 */
    295 	{ NWS1460,	"NWS-1460"	},	/* 86 */
    296 	{ NWS891,	"NWS-891"	},	/* 91 */
    297 	{ NWS911,	"NWS-911"	},	/* 111 */
    298 	{ NWS921,	"NWS-921"	},	/* 121 */
    299 	{ 0,		NULL		}
    300 };
    301 
    302 static void
    303 news1700_init(void)
    304 {
    305 	struct oidrom idrom;
    306 	const char *t;
    307 	const uint8_t *p;
    308 	uint8_t *q;
    309 	u_int i;
    310 
    311 	dip_switch	= (uint8_t *)(0xe1c00100);
    312 	int_status	= (uint8_t *)(0xe1c00200);
    313 
    314 	idrom_addr	= (uint8_t *)(0xe1c00000);
    315 	ctrl_ast	= (uint8_t *)(0xe1280000);
    316 	ctrl_int2	= (uint8_t *)(0xe1180000);
    317 
    318 	sccport0a	= (0xe0d40002);
    319 	lance_mem_phys	= 0xe0e00000;
    320 
    321 	p = idrom_addr;
    322 	q = (uint8_t *)&idrom;
    323 
    324 	for (i = 0; i < sizeof(idrom); i++, p += 2)
    325 		*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
    326 
    327 	t = NULL;
    328 	for (i = 0; news68k_models[i].name != NULL; i++) {
    329 		if (news68k_models[i].id == idrom.id_model) {
    330 			t = news68k_models[i].name;
    331 		}
    332 	}
    333 	if (t == NULL)
    334 		panic("unexpected system model.");
    335 
    336 	cpu_setmodel("%s", t);
    337 	news_machine_id = (idrom.id_serial[0] << 8) + idrom.id_serial[1];
    338 
    339 	ctrl_parity	= (uint8_t *)(0xe1080000);
    340 	ctrl_parity_clr	= (uint8_t *)(0xe1a00000);
    341 	parity_vector	= (uint8_t *)(0xe1c00200);
    342 
    343 	cpuspeed_khz = 25*1000;
    344 	delay_divisor = delay_divisor_est(25);
    345 }
    346 
    347 /*
    348  * parity error handling (vectored NMI?)
    349  */
    350 
    351 static void
    352 parityenable(void)
    353 {
    354 
    355 	if (systype != NEWS1700)
    356 		return;
    357 
    358 #define PARITY_VECT 0xc0
    359 #define PARITY_PRI 7
    360 
    361 	*parity_vector = PARITY_VECT;
    362 
    363 	isrlink_vectored(parityerror, NULL, PARITY_PRI, PARITY_VECT);
    364 
    365 	*ctrl_parity_clr = 1;
    366 	*ctrl_parity = 1;
    367 
    368 #ifdef DEBUG
    369 	printf("enable parity check\n");
    370 #endif
    371 }
    372 
    373 static int innmihand;	/* simple mutex */
    374 
    375 static int
    376 parityerror(void *arg)
    377 {
    378 
    379 	/* Prevent unwanted recursion. */
    380 	if (innmihand)
    381 		return 1;
    382 	innmihand = 1;
    383 
    384 #if 0 /* XXX need to implement XXX */
    385 	panic("parity error");
    386 #else
    387 	printf("parity error detected.\n");
    388 	*ctrl_parity_clr = 1;
    389 #endif
    390 	innmihand = 0;
    391 
    392 	return 1;
    393 }
    394 #endif /* news1700 */
    395 
    396 #ifdef news1200
    397 static void
    398 news1200_init(void)
    399 {
    400 	struct idrom idrom;
    401 	const uint8_t *p;
    402 	uint8_t *q;
    403 	int i;
    404 
    405 	dip_switch	= (uint8_t *)0xe1680000;
    406 	int_status	= (uint8_t *)0xe1200000;
    407 
    408 	idrom_addr	= (uint8_t *)0xe1400000;
    409 	ctrl_ast	= (uint8_t *)0xe1100000;
    410 	ctrl_int2	= (uint8_t *)0xe10c0000;
    411 
    412 	sccport0a	= 0xe1780002;
    413 	lance_mem_phys	= 0xe1a00000;
    414 
    415 	p = idrom_addr;
    416 	q = (uint8_t *)&idrom;
    417 	for (i = 0; i < sizeof(idrom); i++, p += 2)
    418 		*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
    419 
    420 	cpu_setmodel("%s", idrom.id_model);
    421 	news_machine_id = idrom.id_serial;
    422 
    423 	cpuspeed_khz = 25*1000;
    424 	delay_divisor = delay_divisor_est(25);
    425 }
    426 #endif /* news1200 */
    427 
    428 /*
    429  * interrupt handlers
    430  * XXX should do better handling XXX
    431  */
    432 
    433 void intrhand_lev3(void);
    434 void intrhand_lev4(void);
    435 
    436 void
    437 intrhand_lev3(void)
    438 {
    439 	int stat;
    440 
    441 	stat = *int_status;
    442 	m68k_count_intr(3);
    443 #if 1
    444 	printf("level 3 interrupt: INT_STATUS = 0x%02x\n", stat);
    445 #endif
    446 }
    447 
    448 extern int leintr(int);
    449 extern int si_intr(int);
    450 
    451 void
    452 intrhand_lev4(void)
    453 {
    454 	int stat;
    455 
    456 #define INTST_LANCE	0x04
    457 #define INTST_SCSI	0x80
    458 
    459 	stat = *int_status;
    460 	m68k_count_intr(4);
    461 
    462 #if NSI > 0
    463 	if (stat & INTST_SCSI) {
    464 		si_intr(0);
    465 	}
    466 #endif
    467 #if NLE > 0
    468 	if (stat & INTST_LANCE) {
    469 		leintr(0);
    470 	}
    471 #endif
    472 #if 0
    473 	printf("level 4 interrupt\n");
    474 #endif
    475 }
    476 
    477 /*
    478  * consinit() routines - from newsmips/cpu_cons.c
    479  */
    480 
    481 /*
    482  * Console initialization: called early on from main,
    483  * before vm init or startup.  Do enough configuration
    484  * to choose and initialize a console.
    485  * XXX need something better here.
    486  */
    487 #define SCC_CONSOLE	0
    488 #define SW_CONSOLE	0x07
    489 #define SW_NWB512	0x04
    490 #define SW_NWB225	0x01
    491 #define SW_FBPOP	0x02
    492 #define SW_FBPOP1	0x06
    493 #define SW_FBPOP2	0x03
    494 #define SW_AUTOSEL	0x07
    495 
    496 extern struct consdev consdev_rom, consdev_zs;
    497 
    498 #if NFBBM > 0
    499 int fbbm_cnattach(void);
    500 #endif
    501 #if NKB_KBC > 0
    502 int kb_kbc_cnattach(void);
    503 #endif
    504 
    505 int tty00_is_console = 0;
    506 
    507 void
    508 consinit(void)
    509 {
    510 	uint8_t dipsw;
    511 
    512 	dipsw = *dip_switch;
    513 
    514 	dipsw = ~dipsw;
    515 
    516 	switch (dipsw & SW_CONSOLE) {
    517 	case SW_NWB225:
    518 #if NFBBM > 0 && NKB_KBC > 0
    519 		if (systype == NEWS1700) {
    520 			if (fbbm_cnattach() == 0) {
    521 				(void)kb_kbc_cnattach();
    522 				break;
    523 			}
    524 
    525 			/*
    526 			 * Fixed framebuffer initialization is destructive.
    527 			 * If takeover fails, do not assume the PROM
    528 			 * framebuffer console remains usable.
    529 			 */
    530 			tty00_is_console = 1;
    531 			cn_tab = &consdev_zs;
    532 			(*cn_tab->cn_init)(cn_tab);
    533 			printf("fbbm console attach failed;"
    534 			    " using serial console\n");
    535 			break;
    536 		}
    537 #endif
    538 		/* FALLTHROUGH */
    539 	default:
    540 #if NROMCONS > 0
    541 		cn_tab = &consdev_rom;
    542 		(*cn_tab->cn_init)(cn_tab);
    543 		break;
    544 #endif
    545 	case 0:
    546 		tty00_is_console = 1;
    547 		cn_tab = &consdev_zs;
    548 		(*cn_tab->cn_init)(cn_tab);
    549 		break;
    550 	}
    551 #if NKSYMS || defined(DDB) || defined(MODULAR)
    552 	ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
    553 	    (void *)&end, esym);
    554 #endif
    555 #ifdef DDB
    556 	if (boothowto & RB_KDB)
    557 		Debugger();
    558 #endif
    559 }
    560 
    561 int
    562 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
    563 {
    564 
    565 	*handled = false;
    566 	if ((uint8_t *)ptr >= intiobase)
    567 		return EFAULT;
    568 	return 0;
    569 }
    570