1/* $NetBSD$ */ 2 3/*- 4 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center and by Chris G. Demetriou. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/* 34 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60#include "opt_ddb.h" 61#include "opt_kgdb.h" 62#include "opt_modular.h" 63#include "opt_multiprocessor.h" 64#include "opt_dec_3000_300.h" 65#include "opt_dec_3000_500.h" 66#include "opt_compat_osf1.h" 67#include "opt_execfmt.h" 68 69#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 70 71__KERNEL_RCSID(0, "$NetBSD$"); 72 73#include <sys/param.h> 74#include <sys/systm.h> 75#include <sys/signalvar.h> 76#include <sys/kernel.h> 77#include <sys/cpu.h> 78#include <sys/proc.h> 79#include <sys/ras.h> 80#include <sys/sa.h> 81#include <sys/savar.h> 82#include <sys/sched.h> 83#include <sys/reboot.h> 84#include <sys/device.h> 85#include <sys/malloc.h> 86#include <sys/mman.h> 87#include <sys/msgbuf.h> 88#include <sys/ioctl.h> 89#include <sys/tty.h> 90#include <sys/exec.h> 91#include <sys/exec_aout.h> /* for MID_* */ 92#include <sys/exec_ecoff.h> 93#include <sys/core.h> 94#include <sys/kcore.h> 95#include <sys/ucontext.h> 96#include <sys/conf.h> 97#include <sys/ksyms.h> 98#include <sys/kauth.h> 99#include <sys/atomic.h> 100#include <sys/cpu.h> 101 102#include <machine/kcore.h> 103#include <machine/fpu.h> 104 105#include <sys/mount.h> 106#include <sys/syscallargs.h> 107 108#include <uvm/uvm.h> 109#include <sys/sysctl.h> 110 111#include <dev/cons.h> 112#include <dev/mm.h> 113 114#include <machine/autoconf.h> 115#include <machine/reg.h> 116#include <machine/rpb.h> 117#include <machine/prom.h> 118#include <machine/cpuconf.h> 119#include <machine/ieeefp.h> 120 121#ifdef DDB 122#include <machine/db_machdep.h> 123#include <ddb/db_access.h> 124#include <ddb/db_sym.h> 125#include <ddb/db_extern.h> 126#include <ddb/db_interface.h> 127#endif 128 129#ifdef KGDB 130#include <sys/kgdb.h> 131#endif 132 133#ifdef DEBUG 134#include <machine/sigdebug.h> 135#endif 136 137#include <machine/alpha.h> 138 139#include "ksyms.h" 140 141struct vm_map *phys_map = NULL; 142 143void *msgbufaddr; 144 145int maxmem; /* max memory per process */ 146 147int totalphysmem; /* total amount of physical memory in system */ 148int physmem; /* physical memory used by NetBSD + some rsvd */ 149int resvmem; /* amount of memory reserved for PROM */ 150int unusedmem; /* amount of memory for OS that we don't use */ 151int unknownmem; /* amount of memory with an unknown use */ 152 153int cputype; /* system type, from the RPB */ 154 155int bootdev_debug = 0; /* patchable, or from DDB */ 156 157/* 158 * XXX We need an address to which we can assign things so that they 159 * won't be optimized away because we didn't use the value. 160 */ 161uint32_t no_optimize; 162 163/* the following is used externally (sysctl_hw) */ 164char machine[] = MACHINE; /* from <machine/param.h> */ 165char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */ 166char cpu_model[128]; 167 168/* Number of machine cycles per microsecond */ 169uint64_t cycles_per_usec; 170 171/* number of CPUs in the box. really! */ 172int ncpus; 173 174struct bootinfo_kernel bootinfo; 175 176/* For built-in TCDS */ 177#if defined(DEC_3000_300) || defined(DEC_3000_500) 178uint8_t dec_3000_scsiid[2], dec_3000_scsifast[2]; 179#endif 180 181struct platform platform; 182 183#if NKSYMS || defined(DDB) || defined(MODULAR) 184/* start and end of kernel symbol table */ 185void *ksym_start, *ksym_end; 186#endif 187 188/* for cpu_sysctl() */ 189int alpha_unaligned_print = 1; /* warn about unaligned accesses */ 190int alpha_unaligned_fix = 1; /* fix up unaligned accesses */ 191int alpha_unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */ 192int alpha_fp_sync_complete = 0; /* fp fixup if sync even without /s */ 193 194/* 195 * XXX This should be dynamically sized, but we have the chicken-egg problem! 196 * XXX it should also be larger than it is, because not all of the mddt 197 * XXX clusters end up being used for VM. 198 */ 199phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; /* low size bits overloaded */ 200int mem_cluster_cnt; 201 202int cpu_dump(void); 203int cpu_dumpsize(void); 204u_long cpu_dump_mempagecnt(void); 205void dumpsys(void); 206void identifycpu(void); 207void printregs(struct reg *); 208 209const pcu_ops_t fpu_ops = { 210 .pcu_id = PCU_FPU, 211 .pcu_state_load = fpu_state_load, 212 .pcu_state_save = fpu_state_save, 213 .pcu_state_release = fpu_state_release, 214}; 215 216const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = { 217 [PCU_FPU] = &fpu_ops, 218}; 219 220void 221alpha_init(u_long pfn, u_long ptb, u_long bim, u_long bip, u_long biv) 222 /* pfn: first free PFN number */ 223 /* ptb: PFN of current level 1 page table */ 224 /* bim: bootinfo magic */ 225 /* bip: bootinfo pointer */ 226 /* biv: bootinfo version */ 227{ 228 extern char kernel_text[], _end[]; 229 struct mddt *mddtp; 230 struct mddt_cluster *memc; 231 int i, mddtweird; 232 struct vm_physseg *vps; 233 struct pcb *pcb0; 234 vaddr_t kernstart, kernend, v; 235 paddr_t kernstartpfn, kernendpfn, pfn0, pfn1; 236 cpuid_t cpu_id; 237 struct cpu_info *ci; 238 char *p; 239 const char *bootinfo_msg; 240 const struct cpuinit *c; 241 242 /* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */ 243 244 /* 245 * Turn off interrupts (not mchecks) and floating point. 246 * Make sure the instruction and data streams are consistent. 247 */ 248 (void)alpha_pal_swpipl(ALPHA_PSL_IPL_HIGH); 249 alpha_pal_wrfen(0); 250 ALPHA_TBIA(); 251 alpha_pal_imb(); 252 253 /* Initialize the SCB. */ 254 scb_init(); 255 256 cpu_id = cpu_number(); 257 258#if defined(MULTIPROCESSOR) 259 /* 260 * Set our SysValue to the address of our cpu_info structure. 261 * Secondary processors do this in their spinup trampoline. 262 */ 263 alpha_pal_wrval((u_long)&cpu_info_primary); 264 cpu_info[cpu_id] = &cpu_info_primary; 265#endif 266 267 ci = curcpu(); 268 ci->ci_cpuid = cpu_id; 269 270 /* 271 * Get critical system information (if possible, from the 272 * information provided by the boot program). 273 */ 274 bootinfo_msg = NULL; 275 if (bim == BOOTINFO_MAGIC) { 276 if (biv == 0) { /* backward compat */ 277 biv = *(u_long *)bip; 278 bip += 8; 279 } 280 switch (biv) { 281 case 1: { 282 struct bootinfo_v1 *v1p = (struct bootinfo_v1 *)bip; 283 284 bootinfo.ssym = v1p->ssym; 285 bootinfo.esym = v1p->esym; 286 /* hwrpb may not be provided by boot block in v1 */ 287 if (v1p->hwrpb != NULL) { 288 bootinfo.hwrpb_phys = 289 ((struct rpb *)v1p->hwrpb)->rpb_phys; 290 bootinfo.hwrpb_size = v1p->hwrpbsize; 291 } else { 292 bootinfo.hwrpb_phys = 293 ((struct rpb *)HWRPB_ADDR)->rpb_phys; 294 bootinfo.hwrpb_size = 295 ((struct rpb *)HWRPB_ADDR)->rpb_size; 296 } 297 memcpy(bootinfo.boot_flags, v1p->boot_flags, 298 min(sizeof v1p->boot_flags, 299 sizeof bootinfo.boot_flags)); 300 memcpy(bootinfo.booted_kernel, v1p->booted_kernel, 301 min(sizeof v1p->booted_kernel, 302 sizeof bootinfo.booted_kernel)); 303 /* booted dev not provided in bootinfo */ 304 init_prom_interface((struct rpb *) 305 ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys)); 306 prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, 307 sizeof bootinfo.booted_dev); 308 break; 309 } 310 default: 311 bootinfo_msg = "unknown bootinfo version"; 312 goto nobootinfo; 313 } 314 } else { 315 bootinfo_msg = "boot program did not pass bootinfo"; 316nobootinfo: 317 bootinfo.ssym = (u_long)_end; 318 bootinfo.esym = (u_long)_end; 319 bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys; 320 bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size; 321 init_prom_interface((struct rpb *)HWRPB_ADDR); 322 prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags, 323 sizeof bootinfo.boot_flags); 324 prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel, 325 sizeof bootinfo.booted_kernel); 326 prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev, 327 sizeof bootinfo.booted_dev); 328 } 329 330 /* 331 * Initialize the kernel's mapping of the RPB. It's needed for 332 * lots of things. 333 */ 334 hwrpb = (struct rpb *)ALPHA_PHYS_TO_K0SEG(bootinfo.hwrpb_phys); 335 336#if defined(DEC_3000_300) || defined(DEC_3000_500) 337 if (hwrpb->rpb_type == ST_DEC_3000_300 || 338 hwrpb->rpb_type == ST_DEC_3000_500) { 339 prom_getenv(PROM_E_SCSIID, dec_3000_scsiid, 340 sizeof(dec_3000_scsiid)); 341 prom_getenv(PROM_E_SCSIFAST, dec_3000_scsifast, 342 sizeof(dec_3000_scsifast)); 343 } 344#endif 345 346 /* 347 * Remember how many cycles there are per microsecond, 348 * so that we can use delay(). Round up, for safety. 349 */ 350 cycles_per_usec = (hwrpb->rpb_cc_freq + 999999) / 1000000; 351 352 /* 353 * Initialize the (temporary) bootstrap console interface, so 354 * we can use printf until the VM system starts being setup. 355 * The real console is initialized before then. 356 */ 357 init_bootstrap_console(); 358 359 /* OUTPUT NOW ALLOWED */ 360 361 /* delayed from above */ 362 if (bootinfo_msg) 363 printf("WARNING: %s (0x%lx, 0x%lx, 0x%lx)\n", 364 bootinfo_msg, bim, bip, biv); 365 366 /* Initialize the trap vectors on the primary processor. */ 367 trap_init(); 368 369 /* 370 * Find out this system's page size, and initialize 371 * PAGE_SIZE-dependent variables. 372 */ 373 if (hwrpb->rpb_page_size != ALPHA_PGBYTES) 374 panic("page size %lu != %d?!", hwrpb->rpb_page_size, 375 ALPHA_PGBYTES); 376 uvmexp.pagesize = hwrpb->rpb_page_size; 377 uvm_setpagesize(); 378 379 /* 380 * Find out what hardware we're on, and do basic initialization. 381 */ 382 cputype = hwrpb->rpb_type; 383 if (cputype < 0) { 384 /* 385 * At least some white-box systems have SRM which 386 * reports a systype that's the negative of their 387 * blue-box counterpart. 388 */ 389 cputype = -cputype; 390 } 391 c = platform_lookup(cputype); 392 if (c == NULL) { 393 platform_not_supported(); 394 /* NOTREACHED */ 395 } 396 (*c->init)(); 397 strcpy(cpu_model, platform.model); 398 399 /* 400 * Initialize the real console, so that the bootstrap console is 401 * no longer necessary. 402 */ 403 (*platform.cons_init)(); 404 405#ifdef DIAGNOSTIC 406 /* Paranoid sanity checking */ 407 408 /* We should always be running on the primary. */ 409 assert(hwrpb->rpb_primary_cpu_id == cpu_id); 410 411 /* 412 * On single-CPU systypes, the primary should always be CPU 0, 413 * except on Alpha 8200 systems where the CPU id is related 414 * to the VID, which is related to the Turbo Laser node id. 415 */ 416 if (cputype != ST_DEC_21000) 417 assert(hwrpb->rpb_primary_cpu_id == 0); 418#endif 419 420 /* NO MORE FIRMWARE ACCESS ALLOWED */ 421#ifdef _PMAP_MAY_USE_PROM_CONSOLE 422 /* 423 * XXX (unless _PMAP_MAY_USE_PROM_CONSOLE is defined and 424 * XXX pmap_uses_prom_console() evaluates to non-zero.) 425 */ 426#endif 427 428 /* 429 * Find the beginning and end of the kernel (and leave a 430 * bit of space before the beginning for the bootstrap 431 * stack). 432 */ 433 kernstart = trunc_page((vaddr_t)kernel_text) - 2 * PAGE_SIZE; 434#if NKSYMS || defined(DDB) || defined(MODULAR) 435 ksym_start = (void *)bootinfo.ssym; 436 ksym_end = (void *)bootinfo.esym; 437 kernend = (vaddr_t)round_page((vaddr_t)ksym_end); 438#else 439 kernend = (vaddr_t)round_page((vaddr_t)_end); 440#endif 441 442 kernstartpfn = atop(ALPHA_K0SEG_TO_PHYS(kernstart)); 443 kernendpfn = atop(ALPHA_K0SEG_TO_PHYS(kernend)); 444 445 /* 446 * Find out how much memory is available, by looking at 447 * the memory cluster descriptors. This also tries to do 448 * its best to detect things things that have never been seen 449 * before... 450 */ 451 mddtp = (struct mddt *)(((char *)hwrpb) + hwrpb->rpb_memdat_off); 452 453 /* MDDT SANITY CHECKING */ 454 mddtweird = 0; 455 if (mddtp->mddt_cluster_cnt < 2) { 456 mddtweird = 1; 457 printf("WARNING: weird number of mem clusters: %lu\n", 458 mddtp->mddt_cluster_cnt); 459 } 460 461#if 0 462 printf("Memory cluster count: %d\n", mddtp->mddt_cluster_cnt); 463#endif 464 465 for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 466 memc = &mddtp->mddt_clusters[i]; 467#if 0 468 printf("MEMC %d: pfn 0x%lx cnt 0x%lx usage 0x%lx\n", i, 469 memc->mddt_pfn, memc->mddt_pg_cnt, memc->mddt_usage); 470#endif 471 totalphysmem += memc->mddt_pg_cnt; 472 if (mem_cluster_cnt < VM_PHYSSEG_MAX) { /* XXX */ 473 mem_clusters[mem_cluster_cnt].start = 474 ptoa(memc->mddt_pfn); 475 mem_clusters[mem_cluster_cnt].size = 476 ptoa(memc->mddt_pg_cnt); 477 if (memc->mddt_usage & MDDT_mbz || 478 memc->mddt_usage & MDDT_NONVOLATILE || /* XXX */ 479 memc->mddt_usage & MDDT_PALCODE) 480 mem_clusters[mem_cluster_cnt].size |= 481 PROT_READ; 482 else 483 mem_clusters[mem_cluster_cnt].size |= 484 PROT_READ | PROT_WRITE | PROT_EXEC; 485 mem_cluster_cnt++; 486 } 487 488 if (memc->mddt_usage & MDDT_mbz) { 489 mddtweird = 1; 490 printf("WARNING: mem cluster %d has weird " 491 "usage 0x%lx\n", i, memc->mddt_usage); 492 unknownmem += memc->mddt_pg_cnt; 493 continue; 494 } 495 if (memc->mddt_usage & MDDT_NONVOLATILE) { 496 /* XXX should handle these... */ 497 printf("WARNING: skipping non-volatile mem " 498 "cluster %d\n", i); 499 unusedmem += memc->mddt_pg_cnt; 500 continue; 501 } 502 if (memc->mddt_usage & MDDT_PALCODE) { 503 resvmem += memc->mddt_pg_cnt; 504 continue; 505 } 506 507 /* 508 * We have a memory cluster available for system 509 * software use. We must determine if this cluster 510 * holds the kernel. 511 */ 512#ifdef _PMAP_MAY_USE_PROM_CONSOLE 513 /* 514 * XXX If the kernel uses the PROM console, we only use the 515 * XXX memory after the kernel in the first system segment, 516 * XXX to avoid clobbering prom mapping, data, etc. 517 */ 518 if (!pmap_uses_prom_console() || physmem == 0) { 519#endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 520 physmem += memc->mddt_pg_cnt; 521 pfn0 = memc->mddt_pfn; 522 pfn1 = memc->mddt_pfn + memc->mddt_pg_cnt; 523 if (pfn0 <= kernstartpfn && kernendpfn <= pfn1) { 524 /* 525 * Must compute the location of the kernel 526 * within the segment. 527 */ 528#if 0 529 printf("Cluster %d contains kernel\n", i); 530#endif 531#ifdef _PMAP_MAY_USE_PROM_CONSOLE 532 if (!pmap_uses_prom_console()) { 533#endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 534 if (pfn0 < kernstartpfn) { 535 /* 536 * There is a chunk before the kernel. 537 */ 538#if 0 539 printf("Loading chunk before kernel: " 540 "0x%lx / 0x%lx\n", pfn0, kernstartpfn); 541#endif 542 uvm_page_physload(pfn0, kernstartpfn, 543 pfn0, kernstartpfn, VM_FREELIST_DEFAULT); 544 } 545#ifdef _PMAP_MAY_USE_PROM_CONSOLE 546 } 547#endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 548 if (kernendpfn < pfn1) { 549 /* 550 * There is a chunk after the kernel. 551 */ 552#if 0 553 printf("Loading chunk after kernel: " 554 "0x%lx / 0x%lx\n", kernendpfn, pfn1); 555#endif 556 uvm_page_physload(kernendpfn, pfn1, 557 kernendpfn, pfn1, VM_FREELIST_DEFAULT); 558 } 559 } else { 560 /* 561 * Just load this cluster as one chunk. 562 */ 563#if 0 564 printf("Loading cluster %d: 0x%lx / 0x%lx\n", i, 565 pfn0, pfn1); 566#endif 567 uvm_page_physload(pfn0, pfn1, pfn0, pfn1, 568 VM_FREELIST_DEFAULT); 569 } 570#ifdef _PMAP_MAY_USE_PROM_CONSOLE 571 } 572#endif /* _PMAP_MAY_USE_PROM_CONSOLE */ 573 } 574 575 /* 576 * Dump out the MDDT if it looks odd... 577 */ 578 if (mddtweird) { 579 printf("\n"); 580 printf("complete memory cluster information:\n"); 581 for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 582 printf("mddt %d:\n", i); 583 printf("\tpfn %lx\n", 584 mddtp->mddt_clusters[i].mddt_pfn); 585 printf("\tcnt %lx\n", 586 mddtp->mddt_clusters[i].mddt_pg_cnt); 587 printf("\ttest %lx\n", 588 mddtp->mddt_clusters[i].mddt_pg_test); 589 printf("\tbva %lx\n", 590 mddtp->mddt_clusters[i].mddt_v_bitaddr); 591 printf("\tbpa %lx\n", 592 mddtp->mddt_clusters[i].mddt_p_bitaddr); 593 printf("\tbcksum %lx\n", 594 mddtp->mddt_clusters[i].mddt_bit_cksum); 595 printf("\tusage %lx\n", 596 mddtp->mddt_clusters[i].mddt_usage); 597 } 598 printf("\n"); 599 } 600 601 if (totalphysmem == 0) 602 panic("can't happen: system seems to have no memory!"); 603 maxmem = physmem; 604#if 0 605 printf("totalphysmem = %d\n", totalphysmem); 606 printf("physmem = %d\n", physmem); 607 printf("resvmem = %d\n", resvmem); 608 printf("unusedmem = %d\n", unusedmem); 609 printf("unknownmem = %d\n", unknownmem); 610#endif 611 612 /* 613 * Initialize error message buffer (at end of core). 614 */ 615 { 616 vsize_t sz = (vsize_t)round_page(MSGBUFSIZE); 617 vsize_t reqsz = sz; 618 619 vps = VM_PHYSMEM_PTR(vm_nphysseg - 1); 620 621 /* shrink so that it'll fit in the last segment */ 622 if ((vps->avail_end - vps->avail_start) < atop(sz)) 623 sz = ptoa(vps->avail_end - vps->avail_start); 624 625 vps->end -= atop(sz); 626 vps->avail_end -= atop(sz); 627 msgbufaddr = (void *) ALPHA_PHYS_TO_K0SEG(ptoa(vps->end)); 628 initmsgbuf(msgbufaddr, sz); 629 630 /* Remove the last segment if it now has no pages. */ 631 if (vps->start == vps->end) 632 vm_nphysseg--; 633 634 /* warn if the message buffer had to be shrunk */ 635 if (sz != reqsz) 636 printf("WARNING: %ld bytes not available for msgbuf " 637 "in last cluster (%ld used)\n", reqsz, sz); 638 639 } 640 641 /* 642 * NOTE: It is safe to use uvm_pageboot_alloc() before 643 * pmap_bootstrap() because our pmap_virtual_space() 644 * returns compile-time constants. 645 */ 646 647 /* 648 * Allocate uarea page for lwp0 and set it. 649 */ 650 v = uvm_pageboot_alloc(UPAGES * PAGE_SIZE); 651 uvm_lwp_setuarea(&lwp0, v); 652 653 /* 654 * Initialize the virtual memory system, and set the 655 * page table base register in proc 0's PCB. 656 */ 657 pmap_bootstrap(ALPHA_PHYS_TO_K0SEG(ptb << PGSHIFT), 658 hwrpb->rpb_max_asn, hwrpb->rpb_pcs_cnt); 659 660 /* 661 * Initialize the rest of lwp0's PCB and cache its physical address. 662 */ 663 pcb0 = lwp_getpcb(&lwp0); 664 lwp0.l_md.md_pcbpaddr = (void *)ALPHA_K0SEG_TO_PHYS((vaddr_t)pcb0); 665 666 /* 667 * Set the kernel sp, reserving space for an (empty) trapframe, 668 * and make lwp0's trapframe pointer point to it for sanity. 669 */ 670 pcb0->pcb_hw.apcb_ksp = v + USPACE - sizeof(struct trapframe); 671 lwp0.l_md.md_tf = (struct trapframe *)pcb0->pcb_hw.apcb_ksp; 672 673 /* Indicate that lwp0 has a CPU. */ 674 lwp0.l_cpu = ci; 675 676 /* 677 * Look at arguments passed to us and compute boothowto. 678 */ 679 680 boothowto = RB_SINGLE; 681#ifdef KADB 682 boothowto |= RB_KDB; 683#endif 684 for (p = bootinfo.boot_flags; p && *p != '\0'; p++) { 685 /* 686 * Note that we'd really like to differentiate case here, 687 * but the Alpha AXP Architecture Reference Manual 688 * says that we shouldn't. 689 */ 690 switch (*p) { 691 case 'a': /* autoboot */ 692 case 'A': 693 boothowto &= ~RB_SINGLE; 694 break; 695 696#ifdef DEBUG 697 case 'c': /* crash dump immediately after autoconfig */ 698 case 'C': 699 boothowto |= RB_DUMP; 700 break; 701#endif 702 703#if defined(KGDB) || defined(DDB) 704 case 'd': /* break into the kernel debugger ASAP */ 705 case 'D': 706 boothowto |= RB_KDB; 707 break; 708#endif 709 710 case 'h': /* always halt, never reboot */ 711 case 'H': 712 boothowto |= RB_HALT; 713 break; 714 715#if 0 716 case 'm': /* mini root present in memory */ 717 case 'M': 718 boothowto |= RB_MINIROOT; 719 break; 720#endif 721 722 case 'n': /* askname */ 723 case 'N': 724 boothowto |= RB_ASKNAME; 725 break; 726 727 case 's': /* single-user (default, supported for sanity) */ 728 case 'S': 729 boothowto |= RB_SINGLE; 730 break; 731 732 case 'q': /* quiet boot */ 733 case 'Q': 734 boothowto |= AB_QUIET; 735 break; 736 737 case 'v': /* verbose boot */ 738 case 'V': 739 boothowto |= AB_VERBOSE; 740 break; 741 742 case '-': 743 /* 744 * Just ignore this. It's not required, but it's 745 * common for it to be passed regardless. 746 */ 747 break; 748 749 default: 750 printf("Unrecognized boot flag '%c'.\n", *p); 751 break; 752 } 753 } 754 755 /* 756 * Perform any initial kernel patches based on the running system. 757 * We may perform more later if we attach additional CPUs. 758 */ 759 alpha_patch(false); 760 761 /* 762 * Figure out the number of CPUs in the box, from RPB fields. 763 * Really. We mean it. 764 */ 765 for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { 766 struct pcs *pcsp; 767 768 pcsp = LOCATE_PCS(hwrpb, i); 769 if ((pcsp->pcs_flags & PCS_PP) != 0) 770 ncpus++; 771 } 772 773 /* 774 * Initialize debuggers, and break into them if appropriate. 775 */ 776#if NKSYMS || defined(DDB) || defined(MODULAR) 777 ksyms_addsyms_elf((int)((uint64_t)ksym_end - (uint64_t)ksym_start), 778 ksym_start, ksym_end); 779#endif 780 781 if (boothowto & RB_KDB) { 782#if defined(KGDB) 783 kgdb_debug_init = 1; 784 kgdb_connect(1); 785#elif defined(DDB) 786 Debugger(); 787#endif 788 } 789 790#ifdef DIAGNOSTIC 791 /* 792 * Check our clock frequency, from RPB fields. 793 */ 794 if ((hwrpb->rpb_intr_freq >> 12) != 1024) 795 printf("WARNING: unbelievable rpb_intr_freq: %ld (%d hz)\n", 796 hwrpb->rpb_intr_freq, hz); 797#endif 798} 799 800void 801consinit(void) 802{ 803 804 /* 805 * Everything related to console initialization is done 806 * in alpha_init(). 807 */ 808#if defined(DIAGNOSTIC) && defined(_PMAP_MAY_USE_PROM_CONSOLE) 809 printf("consinit: %susing prom console\n", 810 pmap_uses_prom_console() ? "" : "not "); 811#endif 812} 813 814void 815cpu_startup(void) 816{ 817 extern struct evcnt fpevent_use, fpevent_reuse; 818 vaddr_t minaddr, maxaddr; 819 char pbuf[9]; 820#if defined(DEBUG) 821 extern int pmapdebug; 822 int opmapdebug = pmapdebug; 823 824 pmapdebug = 0; 825#endif 826 827 /* 828 * Good {morning,afternoon,evening,night}. 829 */ 830 printf("%s%s", copyright, version); 831 identifycpu(); 832 format_bytes(pbuf, sizeof(pbuf), ptoa(totalphysmem)); 833 printf("total memory = %s\n", pbuf); 834 format_bytes(pbuf, sizeof(pbuf), ptoa(resvmem)); 835 printf("(%s reserved for PROM, ", pbuf); 836 format_bytes(pbuf, sizeof(pbuf), ptoa(physmem)); 837 printf("%s used by NetBSD)\n", pbuf); 838 if (unusedmem) { 839 format_bytes(pbuf, sizeof(pbuf), ptoa(unusedmem)); 840 printf("WARNING: unused memory = %s\n", pbuf); 841 } 842 if (unknownmem) { 843 format_bytes(pbuf, sizeof(pbuf), ptoa(unknownmem)); 844 printf("WARNING: %s of memory with unknown purpose\n", pbuf); 845 } 846 847 minaddr = 0; 848 849 /* 850 * Allocate a submap for physio 851 */ 852 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 853 VM_PHYS_SIZE, 0, false, NULL); 854 855 /* 856 * No need to allocate an mbuf cluster submap. Mbuf clusters 857 * are allocated via the pool allocator, and we use K0SEG to 858 * map those pages. 859 */ 860 861#if defined(DEBUG) 862 pmapdebug = opmapdebug; 863#endif 864 format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); 865 printf("avail memory = %s\n", pbuf); 866#if 0 867 { 868 extern u_long pmap_pages_stolen; 869 870 format_bytes(pbuf, sizeof(pbuf), pmap_pages_stolen * PAGE_SIZE); 871 printf("stolen memory for VM structures = %s\n", pbuf); 872 } 873#endif 874 875 /* 876 * Set up the HWPCB so that it's safe to configure secondary 877 * CPUs. 878 */ 879 hwrpb_primary_init(); 880 881 /* 882 * Initialize some trap event counters. 883 */ 884 evcnt_attach_dynamic_nozero(&fpevent_use, EVCNT_TYPE_MISC, NULL, 885 "FP", "proc use"); 886 evcnt_attach_dynamic_nozero(&fpevent_reuse, EVCNT_TYPE_MISC, NULL, 887 "FP", "proc re-use"); 888} 889 890/* 891 * Retrieve the platform name from the DSR. 892 */ 893const char * 894alpha_dsr_sysname(void) 895{ 896 struct dsrdb *dsr; 897 const char *sysname; 898 899 /* 900 * DSR does not exist on early HWRPB versions. 901 */ 902 if (hwrpb->rpb_version < HWRPB_DSRDB_MINVERS) 903 return (NULL); 904 905 dsr = (struct dsrdb *)(((char *)hwrpb) + hwrpb->rpb_dsrdb_off); 906 sysname = (const char *)((char *)dsr + (dsr->dsr_sysname_off + 907 sizeof(uint64_t))); 908 return (sysname); 909} 910 911/* 912 * Lookup the system specified system variation in the provided table, 913 * returning the model string on match. 914 */ 915const char * 916alpha_variation_name(uint64_t variation, const struct alpha_variation_table *avtp) 917{ 918 int i; 919 920 for (i = 0; avtp[i].avt_model != NULL; i++) 921 if (avtp[i].avt_variation == variation) 922 return (avtp[i].avt_model); 923 return (NULL); 924} 925 926/* 927 * Generate a default platform name based for unknown system variations. 928 */ 929const char * 930alpha_unknown_sysname(void) 931{ 932 static char s[128]; /* safe size */ 933 934 sprintf(s, "%s family, unknown model variation 0x%lx", 935 platform.family, hwrpb->rpb_variation & SV_ST_MASK); 936 return ((const char *)s); 937} 938 939void 940identifycpu(void) 941{ 942 char *s; 943 int i; 944 945 /* 946 * print out CPU identification information. 947 */ 948 printf("%s", cpu_model); 949 for(s = cpu_model; *s; ++s) 950 if(strncasecmp(s, "MHz", 3) == 0) 951 goto skipMHz; 952 printf(", %ldMHz", hwrpb->rpb_cc_freq / 1000000); 953skipMHz: 954 printf(", s/n "); 955 for (i = 0; i < 10; i++) 956 printf("%c", hwrpb->rpb_ssn[i]); 957 printf("\n"); 958 printf("%ld byte page size, %d processor%s.\n", 959 hwrpb->rpb_page_size, ncpus, ncpus == 1 ? "" : "s"); 960#if 0 961 /* this isn't defined for any systems that we run on? */ 962 printf("serial number 0x%lx 0x%lx\n", 963 ((long *)hwrpb->rpb_ssn)[0], ((long *)hwrpb->rpb_ssn)[1]); 964 965 /* and these aren't particularly useful! */ 966 printf("variation: 0x%lx, revision 0x%lx\n", 967 hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision); 968#endif 969} 970 971int waittime = -1; 972struct pcb dumppcb; 973 974void 975cpu_reboot(int howto, char *bootstr) 976{ 977#if defined(MULTIPROCESSOR) 978 u_long cpu_id = cpu_number(); 979 u_long wait_mask; 980 int i; 981#endif 982 983 /* If "always halt" was specified as a boot flag, obey. */ 984 if ((boothowto & RB_HALT) != 0) 985 howto |= RB_HALT; 986 987 boothowto = howto; 988 989 /* If system is cold, just halt. */ 990 if (cold) { 991 boothowto |= RB_HALT; 992 goto haltsys; 993 } 994 995 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 996 waittime = 0; 997 vfs_shutdown(); 998 /* 999 * If we've been adjusting the clock, the todr 1000 * will be out of synch; adjust it now. 1001 */ 1002 resettodr(); 1003 } 1004 1005 /* Disable interrupts. */ 1006 splhigh(); 1007 1008#if defined(MULTIPROCESSOR) 1009 /* 1010 * Halt all other CPUs. If we're not the primary, the 1011 * primary will spin, waiting for us to halt. 1012 */ 1013 cpu_id = cpu_number(); /* may have changed cpu */ 1014 wait_mask = (1UL << cpu_id) | (1UL << hwrpb->rpb_primary_cpu_id); 1015 1016 alpha_broadcast_ipi(ALPHA_IPI_HALT); 1017 1018 /* Ensure any CPUs paused by DDB resume execution so they can halt */ 1019 cpus_paused = 0; 1020 1021 for (i = 0; i < 10000; i++) { 1022 alpha_mb(); 1023 if (cpus_running == wait_mask) 1024 break; 1025 delay(1000); 1026 } 1027 alpha_mb(); 1028 if (cpus_running != wait_mask) 1029 printf("WARNING: Unable to halt secondary CPUs (0x%lx)\n", 1030 cpus_running); 1031#endif /* MULTIPROCESSOR */ 1032 1033 /* If rebooting and a dump is requested do it. */ 1034#if 0 1035 if ((boothowto & (RB_DUMP | RB_HALT)) == RB_DUMP) 1036#else 1037 if (boothowto & RB_DUMP) 1038#endif 1039 dumpsys(); 1040 1041haltsys: 1042 1043 /* run any shutdown hooks */ 1044 doshutdownhooks(); 1045 1046 pmf_system_shutdown(boothowto); 1047 1048#ifdef BOOTKEY 1049 printf("hit any key to %s...\n", howto & RB_HALT ? "halt" : "reboot"); 1050 cnpollc(1); /* for proper keyboard command handling */ 1051 cngetc(); 1052 cnpollc(0); 1053 printf("\n"); 1054#endif 1055 1056 /* Finally, powerdown/halt/reboot the system. */ 1057 if ((boothowto & RB_POWERDOWN) == RB_POWERDOWN && 1058 platform.powerdown != NULL) { 1059 (*platform.powerdown)(); 1060 printf("WARNING: powerdown failed!\n"); 1061 } 1062 printf("%s\n\n", (boothowto & RB_HALT) ? "halted." : "rebooting..."); 1063#if defined(MULTIPROCESSOR) 1064 if (cpu_id != hwrpb->rpb_primary_cpu_id) 1065 cpu_halt(); 1066 else 1067#endif 1068 prom_halt(boothowto & RB_HALT); 1069 /*NOTREACHED*/ 1070} 1071 1072/* 1073 * These variables are needed by /sbin/savecore 1074 */ 1075uint32_t dumpmag = 0x8fca0101; /* magic number */ 1076int dumpsize = 0; /* pages */ 1077long dumplo = 0; /* blocks */ 1078 1079/* 1080 * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers. 1081 */ 1082int 1083cpu_dumpsize(void) 1084{ 1085 int size; 1086 1087 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)) + 1088 ALIGN(mem_cluster_cnt * sizeof(phys_ram_seg_t)); 1089 if (roundup(size, dbtob(1)) != dbtob(1)) 1090 return -1; 1091 1092 return (1); 1093} 1094 1095/* 1096 * cpu_dump_mempagecnt: calculate size of RAM (in pages) to be dumped. 1097 */ 1098u_long 1099cpu_dump_mempagecnt(void) 1100{ 1101 u_long i, n; 1102 1103 n = 0; 1104 for (i = 0; i < mem_cluster_cnt; i++) 1105 n += atop(mem_clusters[i].size); 1106 return (n); 1107} 1108 1109/* 1110 * cpu_dump: dump machine-dependent kernel core dump headers. 1111 */ 1112int 1113cpu_dump(void) 1114{ 1115 int (*dump)(dev_t, daddr_t, void *, size_t); 1116 char buf[dbtob(1)]; 1117 kcore_seg_t *segp; 1118 cpu_kcore_hdr_t *cpuhdrp; 1119 phys_ram_seg_t *memsegp; 1120 const struct bdevsw *bdev; 1121 int i; 1122 1123 bdev = bdevsw_lookup(dumpdev); 1124 if (bdev == NULL) 1125 return (ENXIO); 1126 dump = bdev->d_dump; 1127 1128 memset(buf, 0, sizeof buf); 1129 segp = (kcore_seg_t *)buf; 1130 cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp))]; 1131 memsegp = (phys_ram_seg_t *)&buf[ ALIGN(sizeof(*segp)) + 1132 ALIGN(sizeof(*cpuhdrp))]; 1133 1134 /* 1135 * Generate a segment header. 1136 */ 1137 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 1138 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); 1139 1140 /* 1141 * Add the machine-dependent header info. 1142 */ 1143 cpuhdrp->lev1map_pa = ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map); 1144 cpuhdrp->page_size = PAGE_SIZE; 1145 cpuhdrp->nmemsegs = mem_cluster_cnt; 1146 1147 /* 1148 * Fill in the memory segment descriptors. 1149 */ 1150 for (i = 0; i < mem_cluster_cnt; i++) { 1151 memsegp[i].start = mem_clusters[i].start; 1152 memsegp[i].size = mem_clusters[i].size & ~PAGE_MASK; 1153 } 1154 1155 return (dump(dumpdev, dumplo, (void *)buf, dbtob(1))); 1156} 1157 1158/* 1159 * This is called by main to set dumplo and dumpsize. 1160 * Dumps always skip the first PAGE_SIZE of disk space 1161 * in case there might be a disk label stored there. 1162 * If there is extra space, put dump at the end to 1163 * reduce the chance that swapping trashes it. 1164 */ 1165void 1166cpu_dumpconf(void) 1167{ 1168 int nblks, dumpblks; /* size of dump area */ 1169 1170 if (dumpdev == NODEV) 1171 goto bad; 1172 nblks = bdev_size(dumpdev); 1173 if (nblks <= ctod(1)) 1174 goto bad; 1175 1176 dumpblks = cpu_dumpsize(); 1177 if (dumpblks < 0) 1178 goto bad; 1179 dumpblks += ctod(cpu_dump_mempagecnt()); 1180 1181 /* If dump won't fit (incl. room for possible label), punt. */ 1182 if (dumpblks > (nblks - ctod(1))) 1183 goto bad; 1184 1185 /* Put dump at end of partition */ 1186 dumplo = nblks - dumpblks; 1187 1188 /* dumpsize is in page units, and doesn't include headers. */ 1189 dumpsize = cpu_dump_mempagecnt(); 1190 return; 1191 1192bad: 1193 dumpsize = 0; 1194 return; 1195} 1196 1197/* 1198 * Dump the kernel's image to the swap partition. 1199 */ 1200#define BYTES_PER_DUMP PAGE_SIZE 1201 1202void 1203dumpsys(void) 1204{ 1205 const struct bdevsw *bdev; 1206 u_long totalbytesleft, bytes, i, n, memcl; 1207 u_long maddr; 1208 int psize; 1209 daddr_t blkno; 1210 int (*dump)(dev_t, daddr_t, void *, size_t); 1211 int error; 1212 1213 /* Save registers. */ 1214 savectx(&dumppcb); 1215 1216 if (dumpdev == NODEV) 1217 return; 1218 bdev = bdevsw_lookup(dumpdev); 1219 if (bdev == NULL || bdev->d_psize == NULL) 1220 return; 1221 1222 /* 1223 * For dumps during autoconfiguration, 1224 * if dump device has already configured... 1225 */ 1226 if (dumpsize == 0) 1227 cpu_dumpconf(); 1228 if (dumplo <= 0) { 1229 printf("\ndump to dev %u,%u not possible\n", 1230 major(dumpdev), minor(dumpdev)); 1231 return; 1232 } 1233 printf("\ndumping to dev %u,%u offset %ld\n", 1234 major(dumpdev), minor(dumpdev), dumplo); 1235 1236 psize = bdev_size(dumpdev); 1237 printf("dump "); 1238 if (psize == -1) { 1239 printf("area unavailable\n"); 1240 return; 1241 } 1242 1243 /* XXX should purge all outstanding keystrokes. */ 1244 1245 if ((error = cpu_dump()) != 0) 1246 goto err; 1247 1248 totalbytesleft = ptoa(cpu_dump_mempagecnt()); 1249 blkno = dumplo + cpu_dumpsize(); 1250 dump = bdev->d_dump; 1251 error = 0; 1252 1253 for (memcl = 0; memcl < mem_cluster_cnt; memcl++) { 1254 maddr = mem_clusters[memcl].start; 1255 bytes = mem_clusters[memcl].size & ~PAGE_MASK; 1256 1257 for (i = 0; i < bytes; i += n, totalbytesleft -= n) { 1258 1259 /* Print out how many MBs we to go. */ 1260 if ((totalbytesleft % (1024*1024)) == 0) 1261 printf_nolog("%ld ", 1262 totalbytesleft / (1024 * 1024)); 1263 1264 /* Limit size for next transfer. */ 1265 n = bytes - i; 1266 if (n > BYTES_PER_DUMP) 1267 n = BYTES_PER_DUMP; 1268 1269 error = (*dump)(dumpdev, blkno, 1270 (void *)ALPHA_PHYS_TO_K0SEG(maddr), n); 1271 if (error) 1272 goto err; 1273 maddr += n; 1274 blkno += btodb(n); /* XXX? */ 1275 1276 /* XXX should look for keystrokes, to cancel. */ 1277 } 1278 } 1279 1280err: 1281 switch (error) { 1282 1283 case ENXIO: 1284 printf("device bad\n"); 1285 break; 1286 1287 case EFAULT: 1288 printf("device not ready\n"); 1289 break; 1290 1291 case EINVAL: 1292 printf("area improper\n"); 1293 break; 1294 1295 case EIO: 1296 printf("i/o error\n"); 1297 break; 1298 1299 case EINTR: 1300 printf("aborted from console\n"); 1301 break; 1302 1303 case 0: 1304 printf("succeeded\n"); 1305 break; 1306 1307 default: 1308 printf("error %d\n", error); 1309 break; 1310 } 1311 printf("\n\n"); 1312 delay(1000); 1313} 1314 1315void 1316frametoreg(const struct trapframe *framep, struct reg *regp) 1317{ 1318 1319 regp->r_regs[R_V0] = framep->tf_regs[FRAME_V0]; 1320 regp->r_regs[R_T0] = framep->tf_regs[FRAME_T0]; 1321 regp->r_regs[R_T1] = framep->tf_regs[FRAME_T1]; 1322 regp->r_regs[R_T2] = framep->tf_regs[FRAME_T2]; 1323 regp->r_regs[R_T3] = framep->tf_regs[FRAME_T3]; 1324 regp->r_regs[R_T4] = framep->tf_regs[FRAME_T4]; 1325 regp->r_regs[R_T5] = framep->tf_regs[FRAME_T5]; 1326 regp->r_regs[R_T6] = framep->tf_regs[FRAME_T6]; 1327 regp->r_regs[R_T7] = framep->tf_regs[FRAME_T7]; 1328 regp->r_regs[R_S0] = framep->tf_regs[FRAME_S0]; 1329 regp->r_regs[R_S1] = framep->tf_regs[FRAME_S1]; 1330 regp->r_regs[R_S2] = framep->tf_regs[FRAME_S2]; 1331 regp->r_regs[R_S3] = framep->tf_regs[FRAME_S3]; 1332 regp->r_regs[R_S4] = framep->tf_regs[FRAME_S4]; 1333 regp->r_regs[R_S5] = framep->tf_regs[FRAME_S5]; 1334 regp->r_regs[R_S6] = framep->tf_regs[FRAME_S6]; 1335 regp->r_regs[R_A0] = framep->tf_regs[FRAME_A0]; 1336 regp->r_regs[R_A1] = framep->tf_regs[FRAME_A1]; 1337 regp->r_regs[R_A2] = framep->tf_regs[FRAME_A2]; 1338 regp->r_regs[R_A3] = framep->tf_regs[FRAME_A3]; 1339 regp->r_regs[R_A4] = framep->tf_regs[FRAME_A4]; 1340 regp->r_regs[R_A5] = framep->tf_regs[FRAME_A5]; 1341 regp->r_regs[R_T8] = framep->tf_regs[FRAME_T8]; 1342 regp->r_regs[R_T9] = framep->tf_regs[FRAME_T9]; 1343 regp->r_regs[R_T10] = framep->tf_regs[FRAME_T10]; 1344 regp->r_regs[R_T11] = framep->tf_regs[FRAME_T11]; 1345 regp->r_regs[R_RA] = framep->tf_regs[FRAME_RA]; 1346 regp->r_regs[R_T12] = framep->tf_regs[FRAME_T12]; 1347 regp->r_regs[R_AT] = framep->tf_regs[FRAME_AT]; 1348 regp->r_regs[R_GP] = framep->tf_regs[FRAME_GP]; 1349 /* regp->r_regs[R_SP] = framep->tf_regs[FRAME_SP]; XXX */ 1350 regp->r_regs[R_ZERO] = 0; 1351} 1352 1353void 1354regtoframe(const struct reg *regp, struct trapframe *framep) 1355{ 1356 1357 framep->tf_regs[FRAME_V0] = regp->r_regs[R_V0]; 1358 framep->tf_regs[FRAME_T0] = regp->r_regs[R_T0]; 1359 framep->tf_regs[FRAME_T1] = regp->r_regs[R_T1]; 1360 framep->tf_regs[FRAME_T2] = regp->r_regs[R_T2]; 1361 framep->tf_regs[FRAME_T3] = regp->r_regs[R_T3]; 1362 framep->tf_regs[FRAME_T4] = regp->r_regs[R_T4]; 1363 framep->tf_regs[FRAME_T5] = regp->r_regs[R_T5]; 1364 framep->tf_regs[FRAME_T6] = regp->r_regs[R_T6]; 1365 framep->tf_regs[FRAME_T7] = regp->r_regs[R_T7]; 1366 framep->tf_regs[FRAME_S0] = regp->r_regs[R_S0]; 1367 framep->tf_regs[FRAME_S1] = regp->r_regs[R_S1]; 1368 framep->tf_regs[FRAME_S2] = regp->r_regs[R_S2]; 1369 framep->tf_regs[FRAME_S3] = regp->r_regs[R_S3]; 1370 framep->tf_regs[FRAME_S4] = regp->r_regs[R_S4]; 1371 framep->tf_regs[FRAME_S5] = regp->r_regs[R_S5]; 1372 framep->tf_regs[FRAME_S6] = regp->r_regs[R_S6]; 1373 framep->tf_regs[FRAME_A0] = regp->r_regs[R_A0]; 1374 framep->tf_regs[FRAME_A1] = regp->r_regs[R_A1]; 1375 framep->tf_regs[FRAME_A2] = regp->r_regs[R_A2]; 1376 framep->tf_regs[FRAME_A3] = regp->r_regs[R_A3]; 1377 framep->tf_regs[FRAME_A4] = regp->r_regs[R_A4]; 1378 framep->tf_regs[FRAME_A5] = regp->r_regs[R_A5]; 1379 framep->tf_regs[FRAME_T8] = regp->r_regs[R_T8]; 1380 framep->tf_regs[FRAME_T9] = regp->r_regs[R_T9]; 1381 framep->tf_regs[FRAME_T10] = regp->r_regs[R_T10]; 1382 framep->tf_regs[FRAME_T11] = regp->r_regs[R_T11]; 1383 framep->tf_regs[FRAME_RA] = regp->r_regs[R_RA]; 1384 framep->tf_regs[FRAME_T12] = regp->r_regs[R_T12]; 1385 framep->tf_regs[FRAME_AT] = regp->r_regs[R_AT]; 1386 framep->tf_regs[FRAME_GP] = regp->r_regs[R_GP]; 1387 /* framep->tf_regs[FRAME_SP] = regp->r_regs[R_SP]; XXX */ 1388 /* ??? = regp->r_regs[R_ZERO]; */ 1389} 1390 1391void 1392printregs(struct reg *regp) 1393{ 1394 int i; 1395 1396 for (i = 0; i < 32; i++) 1397 printf("R%d:\t0x%016lx%s", i, regp->r_regs[i], 1398 i & 1 ? "\n" : "\t"); 1399} 1400 1401void 1402regdump(struct trapframe *framep) 1403{ 1404 struct reg reg; 1405 1406 frametoreg(framep, ®); 1407 reg.r_regs[R_SP] = alpha_pal_rdusp(); 1408 1409 printf("REGISTERS:\n"); 1410 printregs(®); 1411} 1412 1413 1414 1415void * 1416getframe(const struct lwp *l, int sig, int *onstack) 1417{ 1418 void *frame; 1419 1420 /* Do we need to jump onto the signal stack? */ 1421 *onstack = 1422 (l->l_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 && 1423 (SIGACTION(l->l_proc, sig).sa_flags & SA_ONSTACK) != 0; 1424 1425 if (*onstack) 1426 frame = (void *)((char *)l->l_sigstk.ss_sp + 1427 l->l_sigstk.ss_size); 1428 else 1429 frame = (void *)(alpha_pal_rdusp()); 1430 return (frame); 1431} 1432 1433void 1434buildcontext(struct lwp *l, const void *catcher, const void *tramp, const void *fp) 1435{ 1436 struct trapframe *tf = l->l_md.md_tf; 1437 1438 tf->tf_regs[FRAME_RA] = (uint64_t)tramp; 1439 tf->tf_regs[FRAME_PC] = (uint64_t)catcher; 1440 tf->tf_regs[FRAME_T12] = (uint64_t)catcher; 1441 alpha_pal_wrusp((unsigned long)fp); 1442} 1443 1444 1445/* 1446 * Send an interrupt to process, new style 1447 */ 1448void 1449sendsig_siginfo(const ksiginfo_t *ksi, const sigset_t *mask) 1450{ 1451 struct lwp *l = curlwp; 1452 struct proc *p = l->l_proc; 1453 struct sigacts *ps = p->p_sigacts; 1454 int onstack, sig = ksi->ksi_signo, error; 1455 struct sigframe_siginfo *fp, frame; 1456 struct trapframe *tf; 1457 sig_t catcher = SIGACTION(p, ksi->ksi_signo).sa_handler; 1458 1459 fp = (struct sigframe_siginfo *)getframe(l,ksi->ksi_signo,&onstack); 1460 tf = l->l_md.md_tf; 1461 1462 /* Allocate space for the signal handler context. */ 1463 fp--; 1464 1465#ifdef DEBUG 1466 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1467 printf("sendsig_siginfo(%d): sig %d ssp %p usp %p\n", p->p_pid, 1468 sig, &onstack, fp); 1469#endif 1470 1471 /* Build stack frame for signal trampoline. */ 1472 1473 frame.sf_si._info = ksi->ksi_info; 1474 frame.sf_uc.uc_flags = _UC_SIGMASK; 1475 frame.sf_uc.uc_sigmask = *mask; 1476 frame.sf_uc.uc_link = l->l_ctxlink; 1477 memset(&frame.sf_uc.uc_stack, 0, sizeof(frame.sf_uc.uc_stack)); 1478 sendsig_reset(l, sig); 1479 mutex_exit(p->p_lock); 1480 cpu_getmcontext(l, &frame.sf_uc.uc_mcontext, &frame.sf_uc.uc_flags); 1481 error = copyout(&frame, fp, sizeof(frame)); 1482 mutex_enter(p->p_lock); 1483 1484 if (error != 0) { 1485 /* 1486 * Process has trashed its stack; give it an illegal 1487 * instruction to halt it in its tracks. 1488 */ 1489#ifdef DEBUG 1490 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1491 printf("sendsig_siginfo(%d): copyout failed on sig %d\n", 1492 p->p_pid, sig); 1493#endif 1494 sigexit(l, SIGILL); 1495 /* NOTREACHED */ 1496 } 1497 1498#ifdef DEBUG 1499 if (sigdebug & SDB_FOLLOW) 1500 printf("sendsig_siginfo(%d): sig %d usp %p code %x\n", 1501 p->p_pid, sig, fp, ksi->ksi_code); 1502#endif 1503 1504 /* 1505 * Set up the registers to directly invoke the signal handler. The 1506 * signal trampoline is then used to return from the signal. Note 1507 * the trampoline version numbers are coordinated with machine- 1508 * dependent code in libc. 1509 */ 1510 1511 tf->tf_regs[FRAME_A0] = sig; 1512 tf->tf_regs[FRAME_A1] = (uint64_t)&fp->sf_si; 1513 tf->tf_regs[FRAME_A2] = (uint64_t)&fp->sf_uc; 1514 1515 buildcontext(l,catcher,ps->sa_sigdesc[sig].sd_tramp,fp); 1516 1517 /* Remember that we're now on the signal stack. */ 1518 if (onstack) 1519 l->l_sigstk.ss_flags |= SS_ONSTACK; 1520 1521#ifdef DEBUG 1522 if (sigdebug & SDB_FOLLOW) 1523 printf("sendsig_siginfo(%d): pc %lx, catcher %lx\n", p->p_pid, 1524 tf->tf_regs[FRAME_PC], tf->tf_regs[FRAME_A3]); 1525 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 1526 printf("sendsig_siginfo(%d): sig %d returns\n", 1527 p->p_pid, sig); 1528#endif 1529} 1530 1531 1532void 1533cpu_upcall(struct lwp *l, int type, int nevents, int ninterrupted, void *sas, void *ap, void *sp, sa_upcall_t upcall) 1534{ 1535 struct trapframe *tf; 1536 1537 tf = l->l_md.md_tf; 1538 1539 tf->tf_regs[FRAME_PC] = (uint64_t)upcall; 1540 tf->tf_regs[FRAME_RA] = 0; 1541 tf->tf_regs[FRAME_A0] = type; 1542 tf->tf_regs[FRAME_A1] = (uint64_t)sas; 1543 tf->tf_regs[FRAME_A2] = nevents; 1544 tf->tf_regs[FRAME_A3] = ninterrupted; 1545 tf->tf_regs[FRAME_A4] = (uint64_t)ap; 1546 tf->tf_regs[FRAME_T12] = (uint64_t)upcall; /* t12 is pv */ 1547 alpha_pal_wrusp((unsigned long)sp); 1548} 1549 1550/* 1551 * machine dependent system variables. 1552 */ 1553SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 1554{ 1555 1556 sysctl_createv(clog, 0, NULL, NULL, 1557 CTLFLAG_PERMANENT, 1558 CTLTYPE_NODE, "machdep", NULL, 1559 NULL, 0, NULL, 0, 1560 CTL_MACHDEP, CTL_EOL); 1561 1562 sysctl_createv(clog, 0, NULL, NULL, 1563 CTLFLAG_PERMANENT, 1564 CTLTYPE_STRUCT, "console_device", NULL, 1565 sysctl_consdev, 0, NULL, sizeof(dev_t), 1566 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 1567 sysctl_createv(clog, 0, NULL, NULL, 1568 CTLFLAG_PERMANENT, 1569 CTLTYPE_STRING, "root_device", NULL, 1570 sysctl_root_device, 0, NULL, 0, 1571 CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); 1572 sysctl_createv(clog, 0, NULL, NULL, 1573 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1574 CTLTYPE_INT, "unaligned_print", NULL, 1575 NULL, 0, &alpha_unaligned_print, 0, 1576 CTL_MACHDEP, CPU_UNALIGNED_PRINT, CTL_EOL); 1577 sysctl_createv(clog, 0, NULL, NULL, 1578 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1579 CTLTYPE_INT, "unaligned_fix", NULL, 1580 NULL, 0, &alpha_unaligned_fix, 0, 1581 CTL_MACHDEP, CPU_UNALIGNED_FIX, CTL_EOL); 1582 sysctl_createv(clog, 0, NULL, NULL, 1583 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1584 CTLTYPE_INT, "unaligned_sigbus", NULL, 1585 NULL, 0, &alpha_unaligned_sigbus, 0, 1586 CTL_MACHDEP, CPU_UNALIGNED_SIGBUS, CTL_EOL); 1587 sysctl_createv(clog, 0, NULL, NULL, 1588 CTLFLAG_PERMANENT, 1589 CTLTYPE_STRING, "booted_kernel", NULL, 1590 NULL, 0, bootinfo.booted_kernel, 0, 1591 CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); 1592 sysctl_createv(clog, 0, NULL, NULL, 1593 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 1594 CTLTYPE_INT, "fp_sync_complete", NULL, 1595 NULL, 0, &alpha_fp_sync_complete, 0, 1596 CTL_MACHDEP, CPU_FP_SYNC_COMPLETE, CTL_EOL); 1597} 1598 1599/* 1600 * Set registers on exec. 1601 */ 1602void 1603setregs(register struct lwp *l, struct exec_package *pack, vaddr_t stack) 1604{ 1605 struct trapframe *tfp = l->l_md.md_tf; 1606 struct pcb *pcb; 1607#ifdef DEBUG 1608 int i; 1609#endif 1610 1611#ifdef DEBUG 1612 /* 1613 * Crash and dump, if the user requested it. 1614 */ 1615 if (boothowto & RB_DUMP) 1616 panic("crash requested by boot flags"); 1617#endif 1618 1619#ifdef DEBUG 1620 for (i = 0; i < FRAME_SIZE; i++) 1621 tfp->tf_regs[i] = 0xbabefacedeadbeef; 1622#else 1623 memset(tfp->tf_regs, 0, FRAME_SIZE * sizeof tfp->tf_regs[0]); 1624#endif 1625 pcb = lwp_getpcb(l); 1626 memset(&pcb->pcb_fp, 0, sizeof(pcb->pcb_fp)); 1627 alpha_pal_wrusp(stack); 1628 tfp->tf_regs[FRAME_PS] = ALPHA_PSL_USERSET; 1629 tfp->tf_regs[FRAME_PC] = pack->ep_entry & ~3; 1630 1631 tfp->tf_regs[FRAME_A0] = stack; /* a0 = sp */ 1632 tfp->tf_regs[FRAME_A1] = 0; /* a1 = rtld cleanup */ 1633 tfp->tf_regs[FRAME_A2] = 0; /* a2 = rtld object */ 1634 tfp->tf_regs[FRAME_A3] = l->l_proc->p_psstrp; /* a3 = ps_strings */ 1635 tfp->tf_regs[FRAME_T12] = tfp->tf_regs[FRAME_PC]; /* a.k.a. PV */ 1636 1637 l->l_md.md_flags &= ~MDLWP_FPUSED; 1638 if (__predict_true((l->l_md.md_flags & IEEE_INHERIT) == 0)) { 1639 l->l_md.md_flags &= ~MDLWP_FP_C; 1640 pcb->pcb_fp.fpr_cr = FPCR_DYN(FP_RN); 1641 } 1642 fpu_discard(); 1643} 1644 1645/* 1646 * Wait "n" microseconds. 1647 */ 1648void 1649delay(unsigned long n) 1650{ 1651 unsigned long pcc0, pcc1, curcycle, cycles, usec; 1652 1653 if (n == 0) 1654 return; 1655 1656 pcc0 = alpha_rpcc() & 0xffffffffUL; 1657 cycles = 0; 1658 usec = 0; 1659 1660 while (usec <= n) { 1661 /* 1662 * Get the next CPU cycle count- assumes that we cannot 1663 * have had more than one 32 bit overflow. 1664 */ 1665 pcc1 = alpha_rpcc() & 0xffffffffUL; 1666 if (pcc1 < pcc0) 1667 curcycle = (pcc1 + 0x100000000UL) - pcc0; 1668 else 1669 curcycle = pcc1 - pcc0; 1670 1671 /* 1672 * We now have the number of processor cycles since we 1673 * last checked. Add the current cycle count to the 1674 * running total. If it's over cycles_per_usec, increment 1675 * the usec counter. 1676 */ 1677 cycles += curcycle; 1678 while (cycles > cycles_per_usec) { 1679 usec++; 1680 cycles -= cycles_per_usec; 1681 } 1682 pcc0 = pcc1; 1683 } 1684} 1685 1686#ifdef EXEC_ECOFF 1687void 1688cpu_exec_ecoff_setregs(struct lwp *l, struct exec_package *epp, vaddr_t stack) 1689{ 1690 struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1691 1692 l->l_md.md_tf->tf_regs[FRAME_GP] = execp->a.gp_value; 1693} 1694 1695/* 1696 * cpu_exec_ecoff_hook(): 1697 * cpu-dependent ECOFF format hook for execve(). 1698 * 1699 * Do any machine-dependent diddling of the exec package when doing ECOFF. 1700 * 1701 */ 1702int 1703cpu_exec_ecoff_probe(struct lwp *l, struct exec_package *epp) 1704{ 1705 struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr; 1706 int error; 1707 1708 if (execp->f.f_magic == ECOFF_MAGIC_NETBSD_ALPHA) 1709 error = 0; 1710 else 1711 error = ENOEXEC; 1712 1713 return (error); 1714} 1715#endif /* EXEC_ECOFF */ 1716 1717int 1718mm_md_physacc(paddr_t pa, vm_prot_t prot) 1719{ 1720 u_quad_t size; 1721 int i; 1722 1723 for (i = 0; i < mem_cluster_cnt; i++) { 1724 if (pa < mem_clusters[i].start) 1725 continue; 1726 size = mem_clusters[i].size & ~PAGE_MASK; 1727 if (pa >= (mem_clusters[i].start + size)) 1728 continue; 1729 if ((prot & mem_clusters[i].size & PAGE_MASK) == prot) 1730 return 0; 1731 } 1732 return EFAULT; 1733} 1734 1735bool 1736mm_md_direct_mapped_io(void *addr, paddr_t *paddr) 1737{ 1738 vaddr_t va = (vaddr_t)addr; 1739 1740 if (va >= ALPHA_K0SEG_BASE && va <= ALPHA_K0SEG_END) { 1741 *paddr = ALPHA_K0SEG_TO_PHYS(va); 1742 return true; 1743 } 1744 return false; 1745} 1746 1747bool 1748mm_md_direct_mapped_phys(paddr_t paddr, vaddr_t *vaddr) 1749{ 1750 1751 *vaddr = ALPHA_PHYS_TO_K0SEG(paddr); 1752 return true; 1753} 1754 1755/* XXX XXX BEGIN XXX XXX */ 1756paddr_t alpha_XXX_dmamap_or; /* XXX */ 1757 /* XXX */ 1758paddr_t /* XXX */ 1759alpha_XXX_dmamap(vaddr_t v) /* XXX */ 1760{ /* XXX */ 1761 /* XXX */ 1762 return (vtophys(v) | alpha_XXX_dmamap_or); /* XXX */ 1763} /* XXX */ 1764/* XXX XXX END XXX XXX */ 1765 1766char * 1767dot_conv(unsigned long x) 1768{ 1769 int i; 1770 char *xc; 1771 static int next; 1772 static char space[2][20]; 1773 1774 xc = space[next ^= 1] + sizeof space[0]; 1775 *--xc = '\0'; 1776 for (i = 0;; ++i) { 1777 if (i && (i & 3) == 0) 1778 *--xc = '.'; 1779 *--xc = hexdigits[x & 0xf]; 1780 x >>= 4; 1781 if (x == 0) 1782 break; 1783 } 1784 return xc; 1785} 1786 1787void 1788cpu_getmcontext(struct lwp *l, mcontext_t *mcp, unsigned int *flags) 1789{ 1790 struct trapframe *frame = l->l_md.md_tf; 1791 struct pcb *pcb = lwp_getpcb(l); 1792 __greg_t *gr = mcp->__gregs; 1793 __greg_t ras_pc; 1794 1795 /* Save register context. */ 1796 frametoreg(frame, (struct reg *)gr); 1797 /* XXX if there's a better, general way to get the USP of 1798 * an LWP that might or might not be curlwp, I'd like to know 1799 * about it. 1800 */ 1801 if (l == curlwp) { 1802 gr[_REG_SP] = alpha_pal_rdusp(); 1803 gr[_REG_UNIQUE] = alpha_pal_rdunique(); 1804 } else { 1805 gr[_REG_SP] = pcb->pcb_hw.apcb_usp; 1806 gr[_REG_UNIQUE] = pcb->pcb_hw.apcb_unique; 1807 } 1808 gr[_REG_PC] = frame->tf_regs[FRAME_PC]; 1809 gr[_REG_PS] = frame->tf_regs[FRAME_PS]; 1810 1811 if ((ras_pc = (__greg_t)ras_lookup(l->l_proc, 1812 (void *) gr[_REG_PC])) != -1) 1813 gr[_REG_PC] = ras_pc; 1814 1815 *flags |= _UC_CPU | _UC_UNIQUE; 1816 1817 /* Save floating point register context, if any, and copy it. */ 1818 if (fpu_used_p(l)) { 1819 fpu_save(); 1820 (void)memcpy(&mcp->__fpregs, &pcb->pcb_fp, 1821 sizeof (mcp->__fpregs)); 1822 mcp->__fpregs.__fp_fpcr = alpha_read_fp_c(l); 1823 *flags |= _UC_FPU; 1824 } 1825} 1826 1827int 1828cpu_mcontext_validate(struct lwp *l, const mcontext_t *mcp) 1829{ 1830 const __greg_t *gr = mcp->__gregs; 1831 1832 if ((gr[_REG_PS] & ALPHA_PSL_USERSET) != ALPHA_PSL_USERSET || 1833 (gr[_REG_PS] & ALPHA_PSL_USERCLR) != 0) 1834 return EINVAL; 1835 1836 return 0; 1837} 1838 1839int 1840cpu_setmcontext(struct lwp *l, const mcontext_t *mcp, unsigned int flags) 1841{ 1842 struct trapframe *frame = l->l_md.md_tf; 1843 struct pcb *pcb = lwp_getpcb(l); 1844 const __greg_t *gr = mcp->__gregs; 1845 int error; 1846 1847 /* Restore register context, if any. */ 1848 if (flags & _UC_CPU) { 1849 /* Check for security violations first. */ 1850 error = cpu_mcontext_validate(l, mcp); 1851 if (error) 1852 return error; 1853 1854 regtoframe((const struct reg *)gr, l->l_md.md_tf); 1855 if (l == curlwp) 1856 alpha_pal_wrusp(gr[_REG_SP]); 1857 else 1858 pcb->pcb_hw.apcb_usp = gr[_REG_SP]; 1859 frame->tf_regs[FRAME_PC] = gr[_REG_PC]; 1860 frame->tf_regs[FRAME_PS] = gr[_REG_PS]; 1861 } 1862 if (flags & _UC_UNIQUE) 1863 lwp_setprivate(l, (void *)(uintptr_t)gr[_REG_UNIQUE]); 1864 /* Restore floating point register context, if any. */ 1865 if (flags & _UC_FPU) { 1866 /* If we have an FP register context, get rid of it. */ 1867 fpu_discard(); 1868 (void)memcpy(&pcb->pcb_fp, &mcp->__fpregs, 1869 sizeof (pcb->pcb_fp)); 1870 l->l_md.md_flags = mcp->__fpregs.__fp_fpcr & MDLWP_FP_C; 1871 fpu_mark_used(l); 1872 } 1873 1874 return (0); 1875} 1876 1877/* 1878 * Preempt the current process if in interrupt from user mode, 1879 * or after the current trap/syscall if in system mode. 1880 */ 1881void 1882cpu_need_resched(struct cpu_info *ci, int flags) 1883{ 1884#if defined(MULTIPROCESSOR) 1885 bool immed = (flags & RESCHED_IMMED) != 0; 1886#endif /* defined(MULTIPROCESSOR) */ 1887 1888 aston(ci->ci_data.cpu_onproc); 1889 ci->ci_want_resched = 1; 1890 if (ci->ci_data.cpu_onproc != ci->ci_data.cpu_idlelwp) { 1891#if defined(MULTIPROCESSOR) 1892 if (immed && ci != curcpu()) { 1893 alpha_send_ipi(ci->ci_cpuid, 0); 1894 } 1895#endif /* defined(MULTIPROCESSOR) */ 1896 } 1897} 1898