machdep.c revision 1.159
1/* $OpenBSD: machdep.c,v 1.159 2007/06/24 17:00:50 kettenis Exp $ */ 2 3/* 4 * Copyright (c) 1999-2003 Michael Shalayeff 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/signalvar.h> 32#include <sys/kernel.h> 33#include <sys/proc.h> 34#include <sys/buf.h> 35#include <sys/reboot.h> 36#include <sys/device.h> 37#include <sys/conf.h> 38#include <sys/file.h> 39#include <sys/timeout.h> 40#include <sys/malloc.h> 41#include <sys/mbuf.h> 42#include <sys/msgbuf.h> 43#include <sys/ioctl.h> 44#include <sys/tty.h> 45#include <sys/user.h> 46#include <sys/exec.h> 47#include <sys/sysctl.h> 48#include <sys/core.h> 49#include <sys/kcore.h> 50#include <sys/extent.h> 51#ifdef SYSVMSG 52#include <sys/msg.h> 53#endif 54 55#include <sys/mount.h> 56#include <sys/syscallargs.h> 57 58#include <uvm/uvm.h> 59#include <uvm/uvm_page.h> 60 61#include <dev/cons.h> 62 63#include <machine/pdc.h> 64#include <machine/iomod.h> 65#include <machine/psl.h> 66#include <machine/reg.h> 67#include <machine/cpufunc.h> 68#include <machine/autoconf.h> 69#include <machine/kcore.h> 70 71#ifdef COMPAT_HPUX 72#include <compat/hpux/hpux.h> 73#include <compat/hpux/hpux_sig.h> 74#include <compat/hpux/hpux_util.h> 75#include <compat/hpux/hpux_syscallargs.h> 76#include <machine/hpux_machdep.h> 77#endif 78 79#ifdef DDB 80#include <machine/db_machdep.h> 81#include <ddb/db_access.h> 82#include <ddb/db_sym.h> 83#include <ddb/db_extern.h> 84#endif 85 86#include <hppa/dev/cpudevs.h> 87 88/* 89 * Patchable buffer cache parameters 90 */ 91#ifndef BUFCACHEPERCENT 92#define BUFCACHEPERCENT 10 93#endif /* BUFCACHEPERCENT */ 94 95#ifdef BUFPAGES 96int bufpages = BUFPAGES; 97#else 98int bufpages = 0; 99#endif 100int bufcachepercent = BUFCACHEPERCENT; 101 102/* 103 * Different kinds of flags used throughout the kernel. 104 */ 105int cold = 1; /* unset when engine is up to go */ 106extern int msgbufmapped; /* set when safe to use msgbuf */ 107 108/* 109 * cache configuration, for most machines is the same 110 * numbers, so it makes sense to do defines w/ numbers depending 111 * on configured cpu types in the kernel 112 */ 113int icache_stride, icache_line_mask; 114int dcache_stride, dcache_line_mask; 115 116/* 117 * things to not kill 118 */ 119volatile u_int8_t *machine_ledaddr; 120int machine_ledword, machine_leds; 121struct cpu_info cpu_info_primary; 122 123/* 124 * CPU params (should be the same for all cpus in the system) 125 */ 126struct pdc_cache pdc_cache PDC_ALIGNMENT; 127struct pdc_btlb pdc_btlb PDC_ALIGNMENT; 128struct pdc_model pdc_model PDC_ALIGNMENT; 129 130 /* w/ a little deviation should be the same for all installed cpus */ 131u_int cpu_ticksnum, cpu_ticksdenom; 132 133 /* exported info */ 134char machine[] = MACHINE; 135char cpu_model[128]; 136enum hppa_cpu_type cpu_type; 137const char *cpu_typename; 138int cpu_hvers; 139u_int fpu_version; 140#ifdef COMPAT_HPUX 141int cpu_model_hpux; /* contains HPUX_SYSCONF_CPU* kind of value */ 142#endif 143 144/* 145 * exported methods for cpus 146 */ 147int (*cpu_desidhash)(void); 148int (*cpu_hpt_init)(vaddr_t hpt, vsize_t hptsize); 149int (*cpu_ibtlb_ins)(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 150 vsize_t sz, u_int prot); 151int (*cpu_dbtlb_ins)(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 152 vsize_t sz, u_int prot); 153 154dev_t bootdev; 155int physmem, resvmem, resvphysmem, esym; 156paddr_t avail_end; 157 158/* 159 * Things for MI glue to stick on. 160 */ 161struct user *proc0paddr; 162long mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(64) / sizeof(long)]; 163struct extent *hppa_ex; 164 165struct vm_map *exec_map = NULL; 166struct vm_map *phys_map = NULL; 167/* Virtual page frame for /dev/mem (see mem.c) */ 168vaddr_t vmmap; 169 170void delay_init(void); 171static __inline void fall(int, int, int, int, int); 172void dumpsys(void); 173void hpmc_dump(void); 174void cpuid(void); 175 176/* 177 * wide used hardware params 178 */ 179struct pdc_hwtlb pdc_hwtlb PDC_ALIGNMENT; 180struct pdc_coproc pdc_coproc PDC_ALIGNMENT; 181struct pdc_coherence pdc_coherence PDC_ALIGNMENT; 182struct pdc_spidb pdc_spidbits PDC_ALIGNMENT; 183struct pdc_model pdc_model PDC_ALIGNMENT; 184 185#ifdef DEBUG 186int sigdebug = 0; 187pid_t sigpid = 0; 188#define SDB_FOLLOW 0x01 189#endif 190 191/* 192 * Whatever CPU types we support 193 */ 194extern const u_int itlb_x[], itlbna_x[], dtlb_x[], dtlbna_x[], tlbd_x[]; 195extern const u_int itlb_s[], itlbna_s[], dtlb_s[], dtlbna_s[], tlbd_s[]; 196extern const u_int itlb_t[], itlbna_t[], dtlb_t[], dtlbna_t[], tlbd_t[]; 197extern const u_int itlb_l[], itlbna_l[], dtlb_l[], dtlbna_l[], tlbd_l[]; 198extern const u_int itlb_u[], itlbna_u[], dtlb_u[], dtlbna_u[], tlbd_u[]; 199int iibtlb_s(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 200 vsize_t sz, u_int prot); 201int idbtlb_s(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 202 vsize_t sz, u_int prot); 203int ibtlb_t(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 204 vsize_t sz, u_int prot); 205int ibtlb_l(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 206 vsize_t sz, u_int prot); 207int ibtlb_u(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 208 vsize_t sz, u_int prot); 209int ibtlb_g(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 210 vsize_t sz, u_int prot); 211int pbtlb_g(int i); 212int pbtlb_u(int i); 213int hpti_l(vaddr_t, vsize_t); 214int hpti_u(vaddr_t, vsize_t); 215int hpti_g(vaddr_t, vsize_t); 216int desidhash_x(void); 217int desidhash_s(void); 218int desidhash_t(void); 219int desidhash_l(void); 220int desidhash_u(void); 221const struct hppa_cpu_typed { 222 char name[8]; 223 enum hppa_cpu_type type; 224 int cpuid; 225 int features; 226 int patch; 227 int (*desidhash)(void); 228 int (*dbtlbins)(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 229 vsize_t sz, u_int prot); 230 int (*ibtlbins)(int i, pa_space_t sp, vaddr_t va, paddr_t pa, 231 vsize_t sz, u_int prot); 232 int (*btlbprg)(int i); 233 int (*hptinit)(vaddr_t hpt, vsize_t hptsize); 234} cpu_types[] = { 235#ifdef HP7000_CPU 236 { "PCXS", hpcxs, 0, 0, 3, desidhash_s, ibtlb_g, NULL, pbtlb_g}, 237#endif 238#ifdef HP7100_CPU 239 { "PCXT", hpcxt, 0, HPPA_FTRS_BTLBU, 240 2, desidhash_t, ibtlb_g, NULL, pbtlb_g}, 241#endif 242#ifdef HP7200_CPU 243 { "PCXT'", hpcxta,HPPA_CPU_PCXT2, HPPA_FTRS_BTLBU, 244 2, desidhash_t, ibtlb_g, NULL, pbtlb_g}, 245#endif 246#ifdef HP7100LC_CPU 247 { "PCXL", hpcxl, HPPA_CPU_PCXL, HPPA_FTRS_BTLBU|HPPA_FTRS_HVT, 248 0, desidhash_l, ibtlb_g, NULL, pbtlb_g, hpti_g}, 249#endif 250#ifdef HP7300LC_CPU 251 { "PCXL2", hpcxl2,HPPA_CPU_PCXL2, HPPA_FTRS_BTLBU|HPPA_FTRS_HVT, 252 0, desidhash_l, ibtlb_g, NULL, pbtlb_g, hpti_g}, 253#endif 254#ifdef HP8000_CPU 255 { "PCXU", hpcxu, HPPA_CPU_PCXU, HPPA_FTRS_W32B, 256 4, desidhash_u, ibtlb_u, NULL, pbtlb_u }, 257#endif 258#ifdef HP8200_CPU 259 { "PCXU+", hpcxu2,HPPA_CPU_PCXUP, HPPA_FTRS_W32B, 260 4, desidhash_u, ibtlb_u, NULL, pbtlb_u }, 261#endif 262#ifdef HP8500_CPU 263 { "PCXW", hpcxw, HPPA_CPU_PCXW, HPPA_FTRS_W32B, 264 4, desidhash_u, ibtlb_u, NULL, pbtlb_u }, 265#endif 266#ifdef HP8700_CPU 267 { "PCXW2", hpcxw, HPPA_CPU_PCXW2, HPPA_FTRS_W32B, 268 4, desidhash_u, ibtlb_u, NULL, pbtlb_u }, 269#endif 270 { "", 0 } 271}; 272 273int 274hppa_cpuspeed(int *mhz) 275{ 276 *mhz = PAGE0->mem_10msec / 10000; 277 278 return (0); 279} 280 281void 282hppa_init(start) 283 paddr_t start; 284{ 285 extern u_long cpu_hzticks; 286 extern int kernel_text; 287 vaddr_t v, v1; 288 int error; 289 290 pdc_init(); /* init PDC iface, so we can call em easy */ 291 292 cpu_hzticks = (PAGE0->mem_10msec * 100) / hz; 293 delay_init(); /* calculate cpu clock ratio */ 294 295 /* cache parameters */ 296 if ((error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT, 297 &pdc_cache)) < 0) { 298#ifdef DEBUG 299 printf("WARNING: PDC_CACHE error %d\n", error); 300#endif 301 } 302 303 dcache_line_mask = pdc_cache.dc_conf.cc_line * 16 - 1; 304 dcache_stride = pdc_cache.dc_stride; 305 icache_line_mask = pdc_cache.ic_conf.cc_line * 16 - 1; 306 icache_stride = pdc_cache.ic_stride; 307 308 /* cache coherence params (pbably available for 8k only) */ 309 error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_SETCS, 310 &pdc_coherence, 1, 1, 1, 1); 311#ifdef DEBUG 312 printf ("PDC_CACHE_SETCS: %d, %d, %d, %d (%d)\n", 313 pdc_coherence.ia_cst, pdc_coherence.da_cst, 314 pdc_coherence.ita_cst, pdc_coherence.dta_cst, error); 315#endif 316 error = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_GETSPIDB, 317 &pdc_spidbits, 0, 0, 0, 0); 318 printf("SPID bits: 0x%x, error = %d\n", pdc_spidbits.spidbits, error); 319 320 /* setup hpmc handler */ 321 { 322 extern u_int hpmc_v[]; /* from locore.s */ 323 register u_int *p = hpmc_v; 324 325 if (pdc_call((iodcio_t)pdc, 0, PDC_INSTR, PDC_INSTR_DFLT, p)) 326 *p = 0x08000240; 327 328 p[6] = (u_int)&hpmc_dump; 329 p[7] = 32; 330 p[5] = -(p[0] + p[1] + p[2] + p[3] + p[4] + p[6] + p[7]); 331 } 332 333 { 334 extern u_int hppa_toc[], hppa_toc_end[]; 335 register u_int cksum, *p; 336 337 for (cksum = 0, p = hppa_toc; p < hppa_toc_end; p++) 338 cksum += *p; 339 340 *p = cksum; 341 PAGE0->ivec_toc = (u_int)hppa_toc; 342 PAGE0->ivec_toclen = (hppa_toc_end - hppa_toc + 1) * 4; 343 } 344 345 { 346 extern u_int hppa_pfr[], hppa_pfr_end[]; 347 register u_int cksum, *p; 348 349 for (cksum = 0, p = hppa_pfr; p < hppa_pfr_end; p++) 350 cksum += *p; 351 352 *p = cksum; 353 PAGE0->ivec_mempf = (u_int)hppa_pfr; 354 PAGE0->ivec_mempflen = (hppa_pfr_end - hppa_pfr + 1) * 4; 355 } 356 357 cpuid(); 358 ptlball(); 359 ficacheall(); 360 fdcacheall(); 361 362 avail_end = trunc_page(PAGE0->imm_max_mem); 363 if (avail_end > SYSCALLGATE) 364 avail_end = SYSCALLGATE; 365 physmem = btoc(avail_end); 366 resvmem = btoc(((vaddr_t)&kernel_text)); 367 368 /* we hope this won't fail */ 369 hppa_ex = extent_create("mem", 0x0, 0xffffffff, M_DEVBUF, 370 (caddr_t)mem_ex_storage, sizeof(mem_ex_storage), 371 EX_NOCOALESCE|EX_NOWAIT); 372 if (extent_alloc_region(hppa_ex, 0, (vaddr_t)PAGE0->imm_max_mem, 373 EX_NOWAIT)) 374 panic("cannot reserve main memory"); 375 376 /* 377 * Now allocate kernel dynamic variables 378 */ 379 380 v1 = v = round_page(start); 381#define valloc(name, type, num) (name) = (type *)v; v = (vaddr_t)((name)+(num)) 382 383#ifdef SYSVMSG 384 valloc(msgpool, char, msginfo.msgmax); 385 valloc(msgmaps, struct msgmap, msginfo.msgseg); 386 valloc(msghdrs, struct msg, msginfo.msgtql); 387 valloc(msqids, struct msqid_ds, msginfo.msgmni); 388#endif 389#undef valloc 390 v = round_page(v); 391 bzero ((void *)v1, (v - v1)); 392 393 /* sets resvphysmem */ 394 pmap_bootstrap(v); 395 396 /* space has been reserved in pmap_bootstrap() */ 397 initmsgbuf((caddr_t)(ptoa(physmem) - round_page(MSGBUFSIZE)), 398 round_page(MSGBUFSIZE)); 399 400 /* they say PDC_COPROC might turn fault light on */ 401 pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP, 402 PDC_OSTAT(PDC_OSTAT_RUN) | 0xCEC0); 403 404 cpu_cpuspeed = &hppa_cpuspeed; 405#ifdef DDB 406 ddb_init(); 407#endif 408 ficacheall(); 409 fdcacheall(); 410} 411 412void 413cpuid() 414{ 415 /* 416 * Ptrs to various tlb handlers, to be filled 417 * based on cpu features. 418 * from locore.S 419 */ 420 extern u_int trap_ep_T_TLB_DIRTY[]; 421 extern u_int trap_ep_T_DTLBMISS[]; 422 extern u_int trap_ep_T_DTLBMISSNA[]; 423 extern u_int trap_ep_T_ITLBMISS[]; 424 extern u_int trap_ep_T_ITLBMISSNA[]; 425 426 extern u_int fpu_enable; 427 extern int cpu_fpuena; 428 struct pdc_cpuid pdc_cpuid PDC_ALIGNMENT; 429 const struct hppa_cpu_typed *p = NULL; 430 u_int cpu_features; 431 int error; 432 433 /* may the scientific guessing begin */ 434 cpu_features = 0; 435 cpu_type = 0; 436 437 /* identify system type */ 438 if ((error = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO, 439 &pdc_model)) < 0) { 440#ifdef DEBUG 441 printf("WARNING: PDC_MODEL error %d\n", error); 442#endif 443 pdc_model.hvers = 0; 444 } 445 446 bzero(&pdc_cpuid, sizeof(pdc_cpuid)); 447 if (pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_CPUID, 448 &pdc_cpuid, 0, 0, 0, 0) >= 0) { 449 450 /* patch for old 8200 */ 451 if (pdc_cpuid.version == HPPA_CPU_PCXU && 452 pdc_cpuid.revision > 0x0d) 453 pdc_cpuid.version = HPPA_CPU_PCXUP; 454 455 cpu_type = pdc_cpuid.version; 456 } 457 458 /* locate coprocessors and SFUs */ 459 bzero(&pdc_coproc, sizeof(pdc_coproc)); 460 if ((error = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT, 461 &pdc_coproc, 0, 0, 0, 0)) < 0) { 462 printf("WARNING: PDC_COPROC error %d\n", error); 463 cpu_fpuena = 0; 464 } else { 465 printf("pdc_coproc: 0x%x, 0x%x; model %x rev %x\n", 466 pdc_coproc.ccr_enable, pdc_coproc.ccr_present, 467 pdc_coproc.fpu_model, pdc_coproc.fpu_revision); 468 fpu_enable = pdc_coproc.ccr_enable & CCR_MASK; 469 cpu_fpuena = 1; 470 471 /* a kludge to detect PCXW */ 472 if (pdc_coproc.fpu_model == HPPA_FPU_PCXW) 473 cpu_type = HPPA_CPU_PCXW; 474 } 475 476 /* BTLB params */ 477 if (cpu_type < HPPA_CPU_PCXU && 478 (error = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, 479 PDC_BTLB_DEFAULT, &pdc_btlb)) < 0) { 480#ifdef DEBUG 481 printf("WARNING: PDC_BTLB error %d\n", error); 482#endif 483 } else { 484#ifdef BTLBDEBUG 485 printf("btlb info: minsz=%d, maxsz=%d\n", 486 pdc_btlb.min_size, pdc_btlb.max_size); 487 printf("btlb fixed: i=%d, d=%d, c=%d\n", 488 pdc_btlb.finfo.num_i, 489 pdc_btlb.finfo.num_d, 490 pdc_btlb.finfo.num_c); 491 printf("btlb varbl: i=%d, d=%d, c=%d\n", 492 pdc_btlb.vinfo.num_i, 493 pdc_btlb.vinfo.num_d, 494 pdc_btlb.vinfo.num_c); 495#endif /* BTLBDEBUG */ 496 /* purge TLBs and caches */ 497 if (pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, 498 PDC_BTLB_PURGE_ALL) < 0) 499 printf("WARNING: BTLB purge failed\n"); 500 501 if (pdc_btlb.finfo.num_c) 502 cpu_features |= HPPA_FTRS_BTLBU; 503 } 504 505 if (!pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_INFO, &pdc_hwtlb) && 506 pdc_hwtlb.min_size && pdc_hwtlb.max_size) { 507 cpu_features |= HPPA_FTRS_HVT; 508 if (pmap_hptsize > pdc_hwtlb.max_size) 509 pmap_hptsize = pdc_hwtlb.max_size; 510 else if (pmap_hptsize && pmap_hptsize < pdc_hwtlb.min_size) 511 pmap_hptsize = pdc_hwtlb.min_size; 512 } else { 513#ifdef DEBUG 514 printf("WARNING: no HPT support, fine!\n"); 515#endif 516 pmap_hptsize = 0; 517 } 518 519 if (cpu_type) 520 for (p = cpu_types; p->name[0] && p->cpuid != cpu_type; p++); 521 else 522 for (p = cpu_types; 523 p->name[0] && p->features != cpu_features; p++); 524 525 if (!p->name[0]) { 526 printf("WARNING: UNKNOWN CPU TYPE; GOOD LUCK " 527 "(type 0x%x, features 0x%x)\n", cpu_type, cpu_features); 528 p = cpu_types; 529 } else if ((p->type == hpcxl || p->type == hpcxl2) && !fpu_enable) { 530 /* we know PCXL and PCXL2 do not exist w/o FPU */ 531 fpu_enable = 0xc0; 532 cpu_fpuena = 1; 533 } 534 535 /* 536 * TODO: HPT on 7200 is not currently supported 537 */ 538 if (pmap_hptsize && p->type != hpcxl && p->type != hpcxl2) 539 pmap_hptsize = 0; 540 541 cpu_type = p->type; 542 cpu_typename = p->name; 543 cpu_ibtlb_ins = p->ibtlbins; 544 cpu_dbtlb_ins = p->dbtlbins; 545 cpu_hpt_init = p->hptinit; 546 cpu_desidhash = p->desidhash; 547 548 /* patch tlb handler branches */ 549 if (p->patch) { 550 trap_ep_T_TLB_DIRTY [0] = trap_ep_T_TLB_DIRTY [p->patch]; 551 trap_ep_T_DTLBMISS [0] = trap_ep_T_DTLBMISS [p->patch]; 552 trap_ep_T_DTLBMISSNA[0] = trap_ep_T_DTLBMISSNA[p->patch]; 553 trap_ep_T_ITLBMISS [0] = trap_ep_T_ITLBMISS [p->patch]; 554 trap_ep_T_ITLBMISSNA[0] = trap_ep_T_ITLBMISSNA[p->patch]; 555 } 556 557 /* force strong ordering for now */ 558 if (p->features & HPPA_FTRS_W32B) { 559 extern register_t kpsw; /* intr.c */ 560 561 kpsw |= PSL_O; 562 } 563 564 { 565 const char *p, *q; 566 char buf[32]; 567 int lev; 568 569 lev = 0xa + (*cpu_desidhash)(); 570 cpu_hvers = pdc_model.hvers >> 4; 571 if (!cpu_hvers) { 572 p = "(UNKNOWN)"; 573 q = lev == 0xa? "1.0" : "1.1"; 574 } else { 575 p = hppa_mod_info(HPPA_TYPE_BOARD, cpu_hvers); 576 if (!p) { 577 snprintf(buf, sizeof buf, "(UNKNOWN 0x%x)", 578 cpu_hvers); 579 p = buf; 580 } 581 582 switch (pdc_model.arch_rev) { 583 default: 584 case 0: 585 q = "1.0"; 586#ifdef COMPAT_HPUX 587 cpu_model_hpux = HPUX_SYSCONF_CPUPA10; 588#endif 589 break; 590 case 4: 591 q = "1.1"; 592#ifdef COMPAT_HPUX 593 cpu_model_hpux = HPUX_SYSCONF_CPUPA11; 594#endif 595 /* this one is just a 100MHz pcxl */ 596 if (lev == 0x10) 597 lev = 0xc; 598 /* this one is a pcxl2 */ 599 if (lev == 0x16) 600 lev = 0xe; 601 break; 602 case 8: 603 q = "2.0"; 604#ifdef COMPAT_HPUX 605 cpu_model_hpux = HPUX_SYSCONF_CPUPA20; 606#endif 607 break; 608 } 609 } 610 611 snprintf(cpu_model, sizeof cpu_model, 612 "HP 9000/%s PA-RISC %s%x", p, q, lev); 613 } 614#ifdef DEBUG 615 printf("cpu: %s\n", cpu_model); 616#endif 617} 618 619void 620cpu_startup(void) 621{ 622 vaddr_t minaddr, maxaddr; 623 624 /* 625 * i won't understand a friend of mine, 626 * who sat in a room full of artificial ice, 627 * fogging the air w/ humid cries -- 628 * WELCOME TO SUMMER! 629 */ 630 printf(version); 631 632 printf("%s\n", cpu_model); 633 printf("real mem = %u (%u reserved for PROM, %u used by OpenBSD)\n", 634 ctob(physmem), ctob(resvmem), ctob(resvphysmem - resvmem)); 635 636 /* 637 * Determine how many buffers to allocate. 638 * We allocate bufcachepercent% of memory for buffer space. 639 */ 640 if (bufpages == 0) 641 bufpages = physmem * bufcachepercent / 100; 642 643 /* Restrict to at most 25% filled kvm */ 644 if (bufpages > 645 (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / PAGE_SIZE / 4) 646 bufpages = (VM_MAX_KERNEL_ADDRESS-VM_MIN_KERNEL_ADDRESS) / 647 PAGE_SIZE / 4; 648 649 /* 650 * Allocate a submap for exec arguments. This map effectively 651 * limits the number of processes exec'ing at any time. 652 */ 653 minaddr = vm_map_min(kernel_map); 654 exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 655 16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL); 656 657 /* 658 * Allocate a submap for physio 659 */ 660 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 661 VM_PHYS_SIZE, 0, FALSE, NULL); 662 663 printf("avail mem = %lu\n", ptoa(uvmexp.free)); 664 665 /* 666 * Set up buffers, so they can be used to read disk labels. 667 */ 668 bufinit(); 669 vmmap = uvm_km_valloc_wait(kernel_map, NBPG); 670 671 /* 672 * Configure the system. 673 */ 674 if (boothowto & RB_CONFIG) { 675#ifdef BOOT_CONFIG 676 user_config(); 677#else 678 printf("kernel does not support -c; continuing..\n"); 679#endif 680 } 681} 682 683/* 684 * compute cpu clock ratio such as: 685 * cpu_ticksnum / cpu_ticksdenom = t + delta 686 * delta -> 0 687 */ 688void 689delay_init(void) 690{ 691 register u_int num, denom, delta, mdelta; 692 693 mdelta = UINT_MAX; 694 for (denom = 1; denom < 1000; denom++) { 695 num = (PAGE0->mem_10msec * denom) / 10000; 696 delta = num * 10000 / denom - PAGE0->mem_10msec; 697 if (!delta) { 698 cpu_ticksdenom = denom; 699 cpu_ticksnum = num; 700 break; 701 } else if (delta < mdelta) { 702 cpu_ticksdenom = denom; 703 cpu_ticksnum = num; 704 mdelta = delta; 705 } 706 } 707} 708 709void 710delay(us) 711 u_int us; 712{ 713 register u_int start, end, n; 714 715 mfctl(CR_ITMR, start); 716 while (us) { 717 n = min(1000, us); 718 end = start + n * cpu_ticksnum / cpu_ticksdenom; 719 720 /* N.B. Interval Timer may wrap around */ 721 if (end < start) 722 do 723 mfctl(CR_ITMR, start); 724 while (start > end); 725 726 do 727 mfctl(CR_ITMR, start); 728 while (start < end); 729 730 us -= n; 731 } 732} 733 734void 735microtime(struct timeval *tv) 736{ 737 extern u_long cpu_itmr; 738 u_long itmr, mask; 739 int s; 740 741 s = splhigh(); 742 tv->tv_sec = time.tv_sec; 743 tv->tv_usec = time.tv_usec; 744 745 rsm(PSL_I, mask); 746 mfctl(CR_ITMR, itmr); 747 itmr -= cpu_itmr; 748 ssm(PSL_I, mask); 749 splx(s); 750 751 tv->tv_usec += itmr * cpu_ticksdenom / cpu_ticksnum; 752 if (tv->tv_usec >= 1000000) { 753 tv->tv_usec -= 1000000; 754 tv->tv_sec++; 755 } 756} 757 758 759static __inline void 760fall(c_base, c_count, c_loop, c_stride, data) 761 int c_base, c_count, c_loop, c_stride, data; 762{ 763 register int loop; 764 765 for (; c_count--; c_base += c_stride) 766 for (loop = c_loop; loop--; ) 767 if (data) 768 fdce(0, c_base); 769 else 770 fice(0, c_base); 771} 772 773void 774ficacheall(void) 775{ 776 /* 777 * Flush the instruction, then data cache. 778 */ 779 fall(pdc_cache.ic_base, pdc_cache.ic_count, pdc_cache.ic_loop, 780 pdc_cache.ic_stride, 0); 781 sync_caches(); 782} 783 784void 785fdcacheall(void) 786{ 787 fall(pdc_cache.dc_base, pdc_cache.dc_count, pdc_cache.dc_loop, 788 pdc_cache.dc_stride, 1); 789 sync_caches(); 790} 791 792void 793ptlball(void) 794{ 795 register pa_space_t sp; 796 register int i, j, k; 797 798 /* instruction TLB */ 799 sp = pdc_cache.it_sp_base; 800 for (i = 0; i < pdc_cache.it_sp_count; i++) { 801 register vaddr_t off = pdc_cache.it_off_base; 802 for (j = 0; j < pdc_cache.it_off_count; j++) { 803 for (k = 0; k < pdc_cache.it_loop; k++) 804 pitlbe(sp, off); 805 off += pdc_cache.it_off_stride; 806 } 807 sp += pdc_cache.it_sp_stride; 808 } 809 810 /* data TLB */ 811 sp = pdc_cache.dt_sp_base; 812 for (i = 0; i < pdc_cache.dt_sp_count; i++) { 813 register vaddr_t off = pdc_cache.dt_off_base; 814 for (j = 0; j < pdc_cache.dt_off_count; j++) { 815 for (k = 0; k < pdc_cache.dt_loop; k++) 816 pdtlbe(sp, off); 817 off += pdc_cache.dt_off_stride; 818 } 819 sp += pdc_cache.dt_sp_stride; 820 } 821} 822 823int 824hpti_g(hpt, hptsize) 825 vaddr_t hpt; 826 vsize_t hptsize; 827{ 828 return pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_CONFIG, 829 &pdc_hwtlb, hpt, hptsize, PDC_TLB_CURRPDE); 830} 831 832int 833pbtlb_g(i) 834 int i; 835{ 836 return -1; 837} 838 839int 840ibtlb_g(i, sp, va, pa, sz, prot) 841 int i; 842 pa_space_t sp; 843 vaddr_t va; 844 paddr_t pa; 845 vsize_t sz; 846 u_int prot; 847{ 848 int error; 849 850 if ((error = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_INSERT, 851 sp, va, pa, sz, prot, i)) < 0) { 852#ifdef BTLBDEBUG 853 printf("WARNING: BTLB insert failed (%d)\n", error); 854#endif 855 } 856 return error; 857} 858 859int 860btlb_insert(space, va, pa, lenp, prot) 861 pa_space_t space; 862 vaddr_t va; 863 paddr_t pa; 864 vsize_t *lenp; 865 u_int prot; 866{ 867 static u_int32_t mask; 868 register vsize_t len; 869 register int error, i; 870 871 if (!pdc_btlb.min_size && !pdc_btlb.max_size) 872 return -(ENXIO); 873 874 /* align size */ 875 for (len = pdc_btlb.min_size << PGSHIFT; len < *lenp; len <<= 1); 876 len >>= PGSHIFT; 877 i = ffs(~mask) - 1; 878 if (len > pdc_btlb.max_size || i < 0) { 879#ifdef BTLBDEBUG 880 printf("btln_insert: too big (%u < %u < %u)\n", 881 pdc_btlb.min_size, len, pdc_btlb.max_size); 882#endif 883 return -(ENOMEM); 884 } 885 886 mask |= 1 << i; 887 pa >>= PGSHIFT; 888 va >>= PGSHIFT; 889 /* check address alignment */ 890 if (pa & (len - 1)) { 891#ifdef BTLBDEBUG 892 printf("WARNING: BTLB address misaligned pa=0x%x, len=0x%x\n", 893 pa, len); 894#endif 895 return -(ERANGE); 896 } 897 898 /* ensure IO space is uncached */ 899 if ((pa & (HPPA_IOBEGIN >> PGSHIFT)) == (HPPA_IOBEGIN >> PGSHIFT)) 900 prot |= TLB_UNCACHABLE; 901 902#ifdef BTLBDEBUG 903 printf("btlb_insert(%d): %x:%x=%x[%x,%x]\n", i, space, va, pa, len, prot); 904#endif 905 if ((error = (*cpu_dbtlb_ins)(i, space, va, pa, len, prot)) < 0) 906 return -(EINVAL); 907 *lenp = len << PGSHIFT; 908 909 return i; 910} 911 912int waittime = -1; 913 914void 915boot(howto) 916 int howto; 917{ 918 /* If system is cold, just halt. */ 919 if (cold) { 920 /* (Unless the user explicitly asked for reboot.) */ 921 if ((howto & RB_USERREQ) == 0) 922 howto |= RB_HALT; 923 } else { 924 925 boothowto = howto | (boothowto & RB_HALT); 926 927 if (!(howto & RB_NOSYNC)) { 928 waittime = 0; 929 vfs_shutdown(); 930 /* 931 * If we've been adjusting the clock, the todr 932 * will be out of synch; adjust it now unless 933 * the system was sitting in ddb. 934 */ 935 if ((howto & RB_TIMEBAD) == 0) 936 resettodr(); 937 else 938 printf("WARNING: not updating battery clock\n"); 939 } 940 941 /* XXX probably save howto into stable storage */ 942 943 splhigh(); 944 945 if (howto & RB_DUMP) 946 dumpsys(); 947 948 doshutdownhooks(); 949 } 950 951 /* in case we came on powerfail interrupt */ 952 if (cold_hook) 953 (*cold_hook)(HPPA_COLD_COLD); 954 955 if (howto & RB_HALT) { 956 if (howto & RB_POWERDOWN && cold_hook) { 957 printf("Powering off..."); 958 DELAY(2000000); 959 (*cold_hook)(HPPA_COLD_OFF); 960 DELAY(1000000); 961 } 962 963 printf("System halted!\n"); 964 DELAY(2000000); 965 __asm __volatile("stwas %0, 0(%1)" 966 :: "r" (CMD_STOP), "r" (HPPA_LBCAST + iomod_command)); 967 } else { 968 printf("rebooting..."); 969 DELAY(2000000); 970 971 /* ask firmware to reset */ 972 pdc_call((iodcio_t)pdc, 0, PDC_BROADCAST_RESET, PDC_DO_RESET); 973 974 /* forcably reset module if that fails */ 975 __asm __volatile(".export hppa_reset, entry\n\t" 976 ".label hppa_reset"); 977 __asm __volatile("stwas %0, 0(%1)" 978 :: "r" (CMD_RESET), "r" (HPPA_LBCAST + iomod_command)); 979 } 980 981 for(;;); /* loop while bus reset is comming up */ 982 /* NOTREACHED */ 983} 984 985u_long dumpmag = 0x8fca0101; /* magic number */ 986int dumpsize = 0; /* pages */ 987long dumplo = 0; /* blocks */ 988 989/* 990 * cpu_dumpsize: calculate size of machine-dependent kernel core dump headers. 991 */ 992int 993cpu_dumpsize(void) 994{ 995 int size; 996 997 size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); 998 if (roundup(size, dbtob(1)) != dbtob(1)) 999 return -1; 1000 1001 return 1; 1002} 1003 1004/* 1005 * Called from HPMC handler in locore 1006 */ 1007void 1008hpmc_dump(void) 1009{ 1010 printf("HPMC\n"); 1011 1012 cold = 0; 1013 boot(RB_NOSYNC); 1014} 1015 1016int 1017cpu_dump(void) 1018{ 1019 long buf[dbtob(1) / sizeof (long)]; 1020 kcore_seg_t *segp; 1021 cpu_kcore_hdr_t *cpuhdrp; 1022 1023 segp = (kcore_seg_t *)buf; 1024 cpuhdrp = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(*segp)) / sizeof (long)]; 1025 1026 /* 1027 * Generate a segment header. 1028 */ 1029 CORE_SETMAGIC(*segp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 1030 segp->c_size = dbtob(1) - ALIGN(sizeof(*segp)); 1031 1032 /* 1033 * Add the machine-dependent header info 1034 */ 1035 /* nothing for now */ 1036 1037 return (bdevsw[major(dumpdev)].d_dump) 1038 (dumpdev, dumplo, (caddr_t)buf, dbtob(1)); 1039} 1040 1041/* 1042 * Dump the kernel's image to the swap partition. 1043 */ 1044#define BYTES_PER_DUMP NBPG 1045 1046void 1047dumpsys(void) 1048{ 1049 int psize, bytes, i, n; 1050 caddr_t maddr; 1051 daddr64_t blkno; 1052 int (*dump)(dev_t, daddr64_t, caddr_t, size_t); 1053 int error; 1054 1055 /* Save registers 1056 savectx(&dumppcb); */ 1057 1058 if (dumpsize == 0) 1059 dumpconf(); 1060 if (dumplo <= 0) { 1061 printf("\ndump to dev %x not possible\n", dumpdev); 1062 return; 1063 } 1064 printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo); 1065 1066 psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev); 1067 printf("dump "); 1068 if (psize == -1) { 1069 printf("area unavailable\n"); 1070 return; 1071 } 1072 1073 if (!(error = cpu_dump())) { 1074 1075 bytes = ctob(physmem); 1076 maddr = NULL; 1077 blkno = dumplo + cpu_dumpsize(); 1078 dump = bdevsw[major(dumpdev)].d_dump; 1079 /* TODO block map the whole physical memory */ 1080 for (i = 0; i < bytes; i += n) { 1081 1082 /* Print out how many MBs we are to go. */ 1083 n = bytes - i; 1084 if (n && (n % (1024*1024)) == 0) 1085 printf("%d ", n / (1024 * 1024)); 1086 1087 /* Limit size for next transfer. */ 1088 1089 if (n > BYTES_PER_DUMP) 1090 n = BYTES_PER_DUMP; 1091 1092 if ((error = (*dump)(dumpdev, blkno, maddr, n))) 1093 break; 1094 maddr += n; 1095 blkno += btodb(n); 1096 } 1097 } 1098 1099 switch (error) { 1100 case ENXIO: printf("device bad\n"); break; 1101 case EFAULT: printf("device not ready\n"); break; 1102 case EINVAL: printf("area improper\n"); break; 1103 case EIO: printf("i/o error\n"); break; 1104 case EINTR: printf("aborted from console\n"); break; 1105 case 0: printf("succeeded\n"); break; 1106 default: printf("error %d\n", error); break; 1107 } 1108} 1109 1110/* bcopy(), error on fault */ 1111int 1112kcopy(from, to, size) 1113 const void *from; 1114 void *to; 1115 size_t size; 1116{ 1117 return spcopy(HPPA_SID_KERNEL, from, HPPA_SID_KERNEL, to, size); 1118} 1119 1120int 1121copystr(src, dst, size, lenp) 1122 const void *src; 1123 void *dst; 1124 size_t size; 1125 size_t *lenp; 1126{ 1127 return spstrcpy(HPPA_SID_KERNEL, src, HPPA_SID_KERNEL, dst, size, lenp); 1128} 1129 1130int 1131copyinstr(src, dst, size, lenp) 1132 const void *src; 1133 void *dst; 1134 size_t size; 1135 size_t *lenp; 1136{ 1137 return spstrcpy(curproc->p_addr->u_pcb.pcb_space, src, 1138 HPPA_SID_KERNEL, dst, size, lenp); 1139} 1140 1141 1142int 1143copyoutstr(src, dst, size, lenp) 1144 const void *src; 1145 void *dst; 1146 size_t size; 1147 size_t *lenp; 1148{ 1149 return spstrcpy(HPPA_SID_KERNEL, src, 1150 curproc->p_addr->u_pcb.pcb_space, dst, size, lenp); 1151} 1152 1153 1154int 1155copyin(src, dst, size) 1156 const void *src; 1157 void *dst; 1158 size_t size; 1159{ 1160 return spcopy(curproc->p_addr->u_pcb.pcb_space, src, 1161 HPPA_SID_KERNEL, dst, size); 1162} 1163 1164int 1165copyout(src, dst, size) 1166 const void *src; 1167 void *dst; 1168 size_t size; 1169{ 1170 return spcopy(HPPA_SID_KERNEL, src, 1171 curproc->p_addr->u_pcb.pcb_space, dst, size); 1172} 1173 1174/* 1175 * Set registers on exec. 1176 */ 1177void 1178setregs(p, pack, stack, retval) 1179 struct proc *p; 1180 struct exec_package *pack; 1181 u_long stack; 1182 register_t *retval; 1183{ 1184 extern paddr_t fpu_curpcb; /* from locore.S */ 1185 struct trapframe *tf = p->p_md.md_regs; 1186 struct pcb *pcb = &p->p_addr->u_pcb; 1187 register_t zero; 1188 1189 tf->tf_flags = TFF_SYS|TFF_LAST; 1190 tf->tf_iioq_tail = 4 + 1191 (tf->tf_iioq_head = pack->ep_entry | HPPA_PC_PRIV_USER); 1192 tf->tf_rp = 0; 1193 tf->tf_arg0 = (u_long)PS_STRINGS; 1194 tf->tf_arg1 = tf->tf_arg2 = 0; /* XXX dynload stuff */ 1195 1196 /* setup terminal stack frame */ 1197 stack = (stack + 0x1f) & ~0x1f; 1198 tf->tf_r3 = stack; 1199 tf->tf_sp = stack += HPPA_FRAME_SIZE; 1200 zero = 0; 1201 copyout(&zero, (caddr_t)(stack - HPPA_FRAME_SIZE), sizeof(register_t)); 1202 copyout(&zero, (caddr_t)(stack + HPPA_FRAME_CRP), sizeof(register_t)); 1203 1204 /* reset any of the pending FPU exceptions */ 1205 if (tf->tf_cr30 == fpu_curpcb) { 1206 fpu_exit(); 1207 fpu_curpcb = 0; 1208 } 1209 pcb->pcb_fpregs[0] = ((u_int64_t)HPPA_FPU_INIT) << 32; 1210 pcb->pcb_fpregs[1] = 0; 1211 pcb->pcb_fpregs[2] = 0; 1212 pcb->pcb_fpregs[3] = 0; 1213 fdcache(HPPA_SID_KERNEL, (vaddr_t)pcb->pcb_fpregs, 8 * 4); 1214 1215 retval[1] = 0; 1216} 1217 1218/* 1219 * Send an interrupt to process. 1220 */ 1221void 1222sendsig(catcher, sig, mask, code, type, val) 1223 sig_t catcher; 1224 int sig, mask; 1225 u_long code; 1226 int type; 1227 union sigval val; 1228{ 1229 extern paddr_t fpu_curpcb; /* from locore.S */ 1230 extern u_int fpu_enable; 1231 struct proc *p = curproc; 1232 struct trapframe *tf = p->p_md.md_regs; 1233 struct pcb *pcb = &p->p_addr->u_pcb; 1234 struct sigacts *psp = p->p_sigacts; 1235 struct sigcontext ksc; 1236 siginfo_t ksi; 1237 register_t scp, sip; 1238 int sss; 1239 1240#ifdef DEBUG 1241 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1242 printf("sendsig: %s[%d] sig %d catcher %p\n", 1243 p->p_comm, p->p_pid, sig, catcher); 1244#endif 1245 1246 /* flush the FPU ctx first */ 1247 if (tf->tf_cr30 == fpu_curpcb) { 1248 mtctl(fpu_enable, CR_CCR); 1249 fpu_save(fpu_curpcb); 1250 /* fpu_curpcb = 0; only needed if fpregs are preset */ 1251 mtctl(0, CR_CCR); 1252 } 1253 1254 ksc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 1255 1256 /* 1257 * Allocate space for the signal handler context. 1258 */ 1259 if ((psp->ps_flags & SAS_ALTSTACK) && !ksc.sc_onstack && 1260 (psp->ps_sigonstack & sigmask(sig))) { 1261 scp = (register_t)psp->ps_sigstk.ss_sp; 1262 psp->ps_sigstk.ss_flags |= SS_ONSTACK; 1263 } else 1264 scp = (tf->tf_sp + 63) & ~63; 1265 1266 sss = (sizeof(ksc) + 63) & ~63; 1267 sip = 0; 1268 if (psp->ps_siginfo & sigmask(sig)) { 1269 sip = scp + sizeof(ksc); 1270 sss += (sizeof(ksi) + 63) & ~63; 1271 } 1272 1273#ifdef DEBUG 1274 if ((tf->tf_iioq_head & ~PAGE_MASK) == SYSCALLGATE) 1275 printf("sendsig: interrupted syscall at 0x%x:0x%x flags %b\n", 1276 tf->tf_iioq_head, tf->tf_iioq_tail, tf->tf_ipsw, PSL_BITS); 1277#endif 1278 1279 ksc.sc_mask = mask; 1280 ksc.sc_fp = scp + sss; 1281 ksc.sc_ps = tf->tf_ipsw; 1282 ksc.sc_pcoqh = tf->tf_iioq_head; 1283 ksc.sc_pcoqt = tf->tf_iioq_tail; 1284 ksc.sc_regs[0] = tf->tf_t1; 1285 ksc.sc_regs[1] = tf->tf_t2; 1286 ksc.sc_regs[2] = tf->tf_sp; 1287 ksc.sc_regs[3] = tf->tf_t3; 1288 ksc.sc_regs[4] = tf->tf_sar; 1289 ksc.sc_regs[5] = tf->tf_r1; 1290 ksc.sc_regs[6] = tf->tf_rp; 1291 ksc.sc_regs[7] = tf->tf_r3; 1292 ksc.sc_regs[8] = tf->tf_r4; 1293 ksc.sc_regs[9] = tf->tf_r5; 1294 ksc.sc_regs[10] = tf->tf_r6; 1295 ksc.sc_regs[11] = tf->tf_r7; 1296 ksc.sc_regs[12] = tf->tf_r8; 1297 ksc.sc_regs[13] = tf->tf_r9; 1298 ksc.sc_regs[14] = tf->tf_r10; 1299 ksc.sc_regs[15] = tf->tf_r11; 1300 ksc.sc_regs[16] = tf->tf_r12; 1301 ksc.sc_regs[17] = tf->tf_r13; 1302 ksc.sc_regs[18] = tf->tf_r14; 1303 ksc.sc_regs[19] = tf->tf_r15; 1304 ksc.sc_regs[20] = tf->tf_r16; 1305 ksc.sc_regs[21] = tf->tf_r17; 1306 ksc.sc_regs[22] = tf->tf_r18; 1307 ksc.sc_regs[23] = tf->tf_t4; 1308 ksc.sc_regs[24] = tf->tf_arg3; 1309 ksc.sc_regs[25] = tf->tf_arg2; 1310 ksc.sc_regs[26] = tf->tf_arg1; 1311 ksc.sc_regs[27] = tf->tf_arg0; 1312 ksc.sc_regs[28] = tf->tf_dp; 1313 ksc.sc_regs[29] = tf->tf_ret0; 1314 ksc.sc_regs[30] = tf->tf_ret1; 1315 ksc.sc_regs[31] = tf->tf_r31; 1316 bcopy(p->p_addr->u_pcb.pcb_fpregs, ksc.sc_fpregs, 1317 sizeof(ksc.sc_fpregs)); 1318 1319 sss += HPPA_FRAME_SIZE; 1320 tf->tf_arg0 = sig; 1321 tf->tf_arg1 = sip; 1322 tf->tf_arg2 = tf->tf_r4 = scp; 1323 tf->tf_arg3 = (register_t)catcher; 1324 tf->tf_sp = scp + sss; 1325 tf->tf_ipsw &= ~(PSL_N|PSL_B); 1326 tf->tf_iioq_head = HPPA_PC_PRIV_USER | p->p_sigcode; 1327 tf->tf_iioq_tail = tf->tf_iioq_head + 4; 1328 tf->tf_iisq_tail = tf->tf_iisq_head = pcb->pcb_space; 1329 /* disable tracing in the trapframe */ 1330 1331#ifdef DEBUG 1332 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1333 printf("sendsig(%d): sig %d scp %p fp %p sp 0x%x\n", 1334 p->p_pid, sig, scp, ksc.sc_fp, (register_t)scp + sss); 1335#endif 1336 1337 if (copyout(&ksc, (void *)scp, sizeof(ksc))) 1338 sigexit(p, SIGILL); 1339 1340 if (sip) { 1341 initsiginfo(&ksi, sig, code, type, val); 1342 if (copyout(&ksi, (void *)sip, sizeof(ksi))) 1343 sigexit(p, SIGILL); 1344 } 1345 1346 if (copyout(&tf->tf_r3, (caddr_t)(tf->tf_sp - HPPA_FRAME_SIZE), 1347 sizeof(register_t))) 1348 sigexit(p, SIGILL); 1349 tf->tf_r3 = tf->tf_sp - HPPA_FRAME_SIZE; 1350 1351#ifdef DEBUG 1352 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1353 printf("sendsig(%d): pc 0x%x catcher 0x%x\n", p->p_pid, 1354 tf->tf_iioq_head, tf->tf_arg3); 1355#endif 1356} 1357 1358int 1359sys_sigreturn(p, v, retval) 1360 struct proc *p; 1361 void *v; 1362 register_t *retval; 1363{ 1364 extern paddr_t fpu_curpcb; /* from locore.S */ 1365 struct sys_sigreturn_args /* { 1366 syscallarg(struct sigcontext *) sigcntxp; 1367 } */ *uap = v; 1368 struct sigcontext *scp, ksc; 1369 struct trapframe *tf = p->p_md.md_regs; 1370 int error; 1371 1372 scp = SCARG(uap, sigcntxp); 1373#ifdef DEBUG 1374 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1375 printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp); 1376#endif 1377 1378 /* flush the FPU ctx first */ 1379 if (tf->tf_cr30 == fpu_curpcb) { 1380 fpu_exit(); 1381 fpu_curpcb = 0; 1382 } 1383 1384 if ((error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))) 1385 return (error); 1386 1387#define PSL_MBS (PSL_C|PSL_Q|PSL_P|PSL_D|PSL_I) 1388#define PSL_MBZ (PSL_Y|PSL_Z|PSL_S|PSL_X|PSL_M|PSL_R) 1389 if ((ksc.sc_ps & (PSL_MBS|PSL_MBZ)) != PSL_MBS) 1390 return (EINVAL); 1391 1392 if (ksc.sc_onstack) 1393 p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK; 1394 else 1395 p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK; 1396 p->p_sigmask = ksc.sc_mask &~ sigcantmask; 1397 1398 tf->tf_t1 = ksc.sc_regs[0]; /* r22 */ 1399 tf->tf_t2 = ksc.sc_regs[1]; /* r21 */ 1400 tf->tf_sp = ksc.sc_regs[2]; 1401 tf->tf_t3 = ksc.sc_regs[3]; /* r20 */ 1402 tf->tf_sar = ksc.sc_regs[4]; 1403 tf->tf_r1 = ksc.sc_regs[5]; 1404 tf->tf_rp = ksc.sc_regs[6]; 1405 tf->tf_r3 = ksc.sc_regs[7]; 1406 tf->tf_r4 = ksc.sc_regs[8]; 1407 tf->tf_r5 = ksc.sc_regs[9]; 1408 tf->tf_r6 = ksc.sc_regs[10]; 1409 tf->tf_r7 = ksc.sc_regs[11]; 1410 tf->tf_r8 = ksc.sc_regs[12]; 1411 tf->tf_r9 = ksc.sc_regs[13]; 1412 tf->tf_r10 = ksc.sc_regs[14]; 1413 tf->tf_r11 = ksc.sc_regs[15]; 1414 tf->tf_r12 = ksc.sc_regs[16]; 1415 tf->tf_r13 = ksc.sc_regs[17]; 1416 tf->tf_r14 = ksc.sc_regs[18]; 1417 tf->tf_r15 = ksc.sc_regs[19]; 1418 tf->tf_r16 = ksc.sc_regs[20]; 1419 tf->tf_r17 = ksc.sc_regs[21]; 1420 tf->tf_r18 = ksc.sc_regs[22]; 1421 tf->tf_t4 = ksc.sc_regs[23]; /* r19 */ 1422 tf->tf_arg3 = ksc.sc_regs[24]; /* r23 */ 1423 tf->tf_arg2 = ksc.sc_regs[25]; /* r24 */ 1424 tf->tf_arg1 = ksc.sc_regs[26]; /* r25 */ 1425 tf->tf_arg0 = ksc.sc_regs[27]; /* r26 */ 1426 tf->tf_dp = ksc.sc_regs[28]; 1427 tf->tf_ret0 = ksc.sc_regs[29]; 1428 tf->tf_ret1 = ksc.sc_regs[30]; 1429 tf->tf_r31 = ksc.sc_regs[31]; 1430 bcopy(ksc.sc_fpregs, p->p_addr->u_pcb.pcb_fpregs, 1431 sizeof(ksc.sc_fpregs)); 1432 fdcache(HPPA_SID_KERNEL, (vaddr_t)p->p_addr->u_pcb.pcb_fpregs, 1433 sizeof(ksc.sc_fpregs)); 1434 1435 tf->tf_iioq_head = ksc.sc_pcoqh; 1436 tf->tf_iioq_tail = ksc.sc_pcoqt; 1437 tf->tf_ipsw = ksc.sc_ps; 1438 1439#ifdef DEBUG 1440 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1441 printf("sigreturn(%d): returns\n", p->p_pid); 1442#endif 1443 return (EJUSTRETURN); 1444} 1445 1446#ifdef COMPAT_HPUX 1447void 1448hpux_sendsig(sig_t catcher, int sig, int mask, u_long code, int type, 1449 union sigval val) 1450{ 1451 extern paddr_t fpu_curpcb; /* from locore.S */ 1452 extern u_int fpu_enable; 1453 struct proc *p = curproc; 1454 struct pcb *pcb = &p->p_addr->u_pcb; 1455 struct trapframe *tf = p->p_md.md_regs; 1456 struct sigacts *psp = p->p_sigacts; 1457 struct hpux_sigcontext hsc; 1458 int sss; 1459 register_t scp; 1460 1461#ifdef DEBUG 1462 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1463 printf("hpux_sendsig: %s[%d] sig %d catcher %p\n", 1464 p->p_comm, p->p_pid, sig, catcher); 1465#endif 1466 /* flush the FPU ctx first */ 1467 if (tf->tf_cr30 == fpu_curpcb) { 1468 mtctl(fpu_enable, CR_CCR); 1469 fpu_save(fpu_curpcb); 1470 fpu_curpcb = 0; 1471 mtctl(0, CR_CCR); 1472 } 1473 1474 bzero(&hsc, sizeof hsc); 1475 hsc.sc_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; 1476 hsc.sc_omask = mask; 1477 /* sc_scact ??? */ 1478 1479 hsc.sc_ret0 = tf->tf_ret0; 1480 hsc.sc_ret1 = tf->tf_ret1; 1481 1482 hsc.sc_frame[0] = hsc.sc_args[0] = sig; 1483 hsc.sc_frame[1] = hsc.sc_args[1] = NULL; 1484 hsc.sc_frame[2] = hsc.sc_args[2] = scp; 1485 1486 /* 1487 * Allocate space for the signal handler context. 1488 */ 1489 if ((psp->ps_flags & SAS_ALTSTACK) && !hsc.sc_onstack && 1490 (psp->ps_sigonstack & sigmask(sig))) { 1491 scp = (register_t)psp->ps_sigstk.ss_sp; 1492 psp->ps_sigstk.ss_flags |= SS_ONSTACK; 1493 } else 1494 scp = (tf->tf_sp + 63) & ~63; 1495 1496 sss = (sizeof(hsc) + 63) & ~63; 1497 1498 if (tf->tf_flags & TFF_SYS) { 1499 hsc.sc_tfflags = HPUX_TFF_SYSCALL; 1500 hsc.sc_syscall = tf->tf_t1; 1501 } else if (tf->tf_flags & TFF_INTR) 1502 hsc.sc_tfflags = HPUX_TFF_INTR; 1503 else 1504 hsc.sc_tfflags = HPUX_TFF_TRAP; 1505 1506 hsc.sc_regs[0] = tf->tf_r1; 1507 hsc.sc_regs[1] = tf->tf_rp; 1508 hsc.sc_regs[2] = tf->tf_r3; 1509 hsc.sc_regs[3] = tf->tf_r4; 1510 hsc.sc_regs[4] = tf->tf_r5; 1511 hsc.sc_regs[5] = tf->tf_r6; 1512 hsc.sc_regs[6] = tf->tf_r7; 1513 hsc.sc_regs[7] = tf->tf_r8; 1514 hsc.sc_regs[8] = tf->tf_r9; 1515 hsc.sc_regs[9] = tf->tf_r10; 1516 hsc.sc_regs[10] = tf->tf_r11; 1517 hsc.sc_regs[11] = tf->tf_r12; 1518 hsc.sc_regs[12] = tf->tf_r13; 1519 hsc.sc_regs[13] = tf->tf_r14; 1520 hsc.sc_regs[14] = tf->tf_r15; 1521 hsc.sc_regs[15] = tf->tf_r16; 1522 hsc.sc_regs[16] = tf->tf_r17; 1523 hsc.sc_regs[17] = tf->tf_r18; 1524 hsc.sc_regs[18] = tf->tf_t4; 1525 hsc.sc_regs[19] = tf->tf_t3; 1526 hsc.sc_regs[20] = tf->tf_t2; 1527 hsc.sc_regs[21] = tf->tf_t1; 1528 hsc.sc_regs[22] = tf->tf_arg3; 1529 hsc.sc_regs[23] = tf->tf_arg2; 1530 hsc.sc_regs[24] = tf->tf_arg1; 1531 hsc.sc_regs[25] = tf->tf_arg0; 1532 hsc.sc_regs[26] = tf->tf_dp; 1533 hsc.sc_regs[27] = tf->tf_ret0; 1534 hsc.sc_regs[28] = tf->tf_ret1; 1535 hsc.sc_regs[29] = tf->tf_sp; 1536 hsc.sc_regs[30] = tf->tf_r31; 1537 hsc.sc_regs[31] = tf->tf_sar; 1538 hsc.sc_regs[32] = tf->tf_iioq_head; 1539 hsc.sc_regs[33] = tf->tf_iisq_head; 1540 hsc.sc_regs[34] = tf->tf_iioq_tail; 1541 hsc.sc_regs[35] = tf->tf_iisq_tail; 1542 hsc.sc_regs[35] = tf->tf_eiem; 1543 hsc.sc_regs[36] = tf->tf_iir; 1544 hsc.sc_regs[37] = tf->tf_isr; 1545 hsc.sc_regs[38] = tf->tf_ior; 1546 hsc.sc_regs[39] = tf->tf_ipsw; 1547 hsc.sc_regs[40] = 0; 1548 hsc.sc_regs[41] = tf->tf_sr4; 1549 hsc.sc_regs[42] = tf->tf_sr0; 1550 hsc.sc_regs[43] = tf->tf_sr1; 1551 hsc.sc_regs[44] = tf->tf_sr2; 1552 hsc.sc_regs[45] = tf->tf_sr3; 1553 hsc.sc_regs[46] = tf->tf_sr5; 1554 hsc.sc_regs[47] = tf->tf_sr6; 1555 hsc.sc_regs[48] = tf->tf_sr7; 1556 hsc.sc_regs[49] = tf->tf_rctr; 1557 hsc.sc_regs[50] = tf->tf_pidr1; 1558 hsc.sc_regs[51] = tf->tf_pidr2; 1559 hsc.sc_regs[52] = tf->tf_ccr; 1560 hsc.sc_regs[53] = tf->tf_pidr3; 1561 hsc.sc_regs[54] = tf->tf_pidr4; 1562 /* hsc.sc_regs[55] = tf->tf_cr24; */ 1563 hsc.sc_regs[56] = tf->tf_vtop; 1564 /* hsc.sc_regs[57] = tf->tf_cr26; */ 1565 /* hsc.sc_regs[58] = tf->tf_cr27; */ 1566 hsc.sc_regs[59] = 0; 1567 hsc.sc_regs[60] = 0; 1568 bcopy(p->p_addr->u_pcb.pcb_fpregs, hsc.sc_fpregs, 1569 sizeof(hsc.sc_fpregs)); 1570 1571 tf->tf_rp = (register_t)pcb->pcb_sigreturn; 1572 tf->tf_arg3 = (register_t)catcher; 1573 tf->tf_sp = scp + sss; 1574 tf->tf_ipsw &= ~(PSL_N|PSL_B); 1575 tf->tf_iioq_head = HPPA_PC_PRIV_USER | p->p_sigcode; 1576 tf->tf_iioq_tail = tf->tf_iioq_head + 4; 1577 1578 if (copyout(&hsc, (void *)scp, sizeof(hsc))) 1579 sigexit(p, SIGILL); 1580 1581#ifdef DEBUG 1582 if ((sigdebug & SDB_FOLLOW) && (!sigpid || p->p_pid == sigpid)) 1583 printf("sendsig(%d): pc 0x%x rp 0x%x\n", p->p_pid, 1584 tf->tf_iioq_head, tf->tf_rp); 1585#endif 1586} 1587#endif 1588 1589/* 1590 * machine dependent system variables. 1591 */ 1592int 1593cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 1594 int *name; 1595 u_int namelen; 1596 void *oldp; 1597 size_t *oldlenp; 1598 void *newp; 1599 size_t newlen; 1600 struct proc *p; 1601{ 1602 extern paddr_t fpu_curpcb; /* from locore.S */ 1603 extern u_int fpu_enable; 1604 extern int cpu_fpuena; 1605 dev_t consdev; 1606 1607 /* all sysctl names at this level are terminal */ 1608 if (namelen != 1) 1609 return (ENOTDIR); /* overloaded */ 1610 switch (name[0]) { 1611 case CPU_CONSDEV: 1612 if (cn_tab != NULL) 1613 consdev = cn_tab->cn_dev; 1614 else 1615 consdev = NODEV; 1616 return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev, 1617 sizeof consdev)); 1618 case CPU_FPU: 1619 if (fpu_curpcb) { 1620 mtctl(fpu_enable, CR_CCR); 1621 fpu_save(fpu_curpcb); 1622 fpu_curpcb = 0; 1623 mtctl(0, CR_CCR); 1624 } 1625 return (sysctl_int(oldp, oldlenp, newp, newlen, &cpu_fpuena)); 1626 default: 1627 return (EOPNOTSUPP); 1628 } 1629 /* NOTREACHED */ 1630} 1631 1632 1633/* 1634 * consinit: 1635 * initialize the system console. 1636 */ 1637void 1638consinit(void) 1639{ 1640 static int initted; 1641 1642 if (!initted) { 1643 initted++; 1644 cninit(); 1645 } 1646} 1647