machdep.c revision 86291
1/*- 2 * Copyright (c) 2000,2001 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/ia64/ia64/machdep.c 86291 2001-11-12 07:18:16Z marcel $ 27 */ 28 29#include "opt_compat.h" 30#include "opt_ddb.h" 31#include "opt_ski.h" 32#include "opt_msgbuf.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/eventhandler.h> 37#include <sys/sysproto.h> 38#include <sys/signalvar.h> 39#include <sys/kernel.h> 40#include <sys/proc.h> 41#include <sys/lock.h> 42#include <sys/pcpu.h> 43#include <sys/malloc.h> 44#include <sys/reboot.h> 45#include <sys/bio.h> 46#include <sys/buf.h> 47#include <sys/mbuf.h> 48#include <sys/vmmeter.h> 49#include <sys/msgbuf.h> 50#include <sys/exec.h> 51#include <sys/sysctl.h> 52#include <sys/uio.h> 53#include <sys/linker.h> 54#include <sys/random.h> 55#include <sys/cons.h> 56#include <net/netisr.h> 57#include <vm/vm.h> 58#include <vm/vm_kern.h> 59#include <vm/vm_page.h> 60#include <vm/vm_map.h> 61#include <vm/vm_extern.h> 62#include <vm/vm_object.h> 63#include <vm/vm_pager.h> 64#include <sys/user.h> 65#include <sys/ptrace.h> 66#include <machine/clock.h> 67#include <machine/md_var.h> 68#include <machine/reg.h> 69#include <machine/fpu.h> 70#include <machine/pal.h> 71#include <machine/sal.h> 72#include <machine/bootinfo.h> 73#include <machine/mutex.h> 74#include <machine/vmparam.h> 75#include <machine/elf.h> 76#include <ddb/ddb.h> 77#include <sys/vnode.h> 78#include <machine/sigframe.h> 79#include <machine/efi.h> 80#include <machine/inst.h> 81#include <machine/rse.h> 82#include <machine/unwind.h> 83 84void ia64_probe_sapics(void); 85 86#ifdef SKI 87extern void ia64_ski_init(void); 88#endif 89 90u_int64_t processor_frequency; 91u_int64_t bus_frequency; 92u_int64_t itc_frequency; 93int cold = 1; 94struct bootinfo bootinfo; 95 96struct mtx sched_lock; 97struct mtx Giant; 98 99extern char kstack[]; 100struct user *proc0uarea; 101vm_offset_t proc0kstack; 102 103extern u_int64_t kernel_text[], _end[]; 104extern u_int64_t _ia64_unwind_start[]; 105extern u_int64_t _ia64_unwind_end[]; 106 107u_int64_t ia64_port_base; 108 109char machine[] = "ia64"; 110SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 111 112static char cpu_model[128]; 113SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, ""); 114 115#ifdef DDB 116/* start and end of kernel symbol table */ 117void *ksym_start, *ksym_end; 118#endif 119 120int ia64_unaligned_print = 1; /* warn about unaligned accesses */ 121int ia64_unaligned_fix = 1; /* fix up unaligned accesses */ 122int ia64_unaligned_sigbus = 0; /* don't SIGBUS on fixed-up accesses */ 123 124SYSCTL_INT(_machdep, CPU_UNALIGNED_PRINT, unaligned_print, 125 CTLFLAG_RW, &ia64_unaligned_print, 0, ""); 126 127SYSCTL_INT(_machdep, CPU_UNALIGNED_FIX, unaligned_fix, 128 CTLFLAG_RW, &ia64_unaligned_fix, 0, ""); 129 130SYSCTL_INT(_machdep, CPU_UNALIGNED_SIGBUS, unaligned_sigbus, 131 CTLFLAG_RW, &ia64_unaligned_sigbus, 0, ""); 132 133static void cpu_startup __P((void *)); 134SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 135 136struct msgbuf *msgbufp=0; 137 138int bootverbose = 0, Maxmem = 0; 139long dumplo; 140 141int totalphysmem; /* total amount of physical memory in system */ 142int physmem; /* physical memory used by NetBSD + some rsvd */ 143int resvmem; /* amount of memory reserved for PROM */ 144int unusedmem; /* amount of memory for OS that we don't use */ 145int unknownmem; /* amount of memory with an unknown use */ 146int ncpus; /* number of cpus */ 147 148vm_offset_t phys_avail[20]; 149 150static int 151sysctl_hw_physmem(SYSCTL_HANDLER_ARGS) 152{ 153 int error = sysctl_handle_int(oidp, 0, ia64_ptob(physmem), req); 154 return (error); 155} 156 157SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, 158 0, 0, sysctl_hw_physmem, "I", ""); 159 160static int 161sysctl_hw_usermem(SYSCTL_HANDLER_ARGS) 162{ 163 int error = sysctl_handle_int(oidp, 0, 164 ia64_ptob(physmem - cnt.v_wire_count), req); 165 return (error); 166} 167 168SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD, 169 0, 0, sysctl_hw_usermem, "I", ""); 170 171SYSCTL_INT(_hw, OID_AUTO, availpages, CTLFLAG_RD, &physmem, 0, ""); 172 173/* must be 2 less so 0 0 can signal end of chunks */ 174#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2) 175 176static void identifycpu __P((void)); 177 178struct kva_md_info kmi; 179 180static void 181cpu_startup(dummy) 182 void *dummy; 183{ 184 185 /* 186 * Good {morning,afternoon,evening,night}. 187 */ 188 identifycpu(); 189 190 /* startrtclock(); */ 191#ifdef PERFMON 192 perfmon_init(); 193#endif 194 printf("real memory = %ld (%ldK bytes)\n", ia64_ptob(Maxmem), ia64_ptob(Maxmem) / 1024); 195 196 /* 197 * Display any holes after the first chunk of extended memory. 198 */ 199 if (bootverbose) { 200 int indx; 201 202 printf("Physical memory chunk(s):\n"); 203 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 204 int size1 = phys_avail[indx + 1] - phys_avail[indx]; 205 206 printf("0x%08lx - 0x%08lx, %d bytes (%d pages)\n", phys_avail[indx], 207 phys_avail[indx + 1] - 1, size1, size1 / PAGE_SIZE); 208 } 209 } 210 211 vm_ksubmap_init(&kmi); 212 213#if defined(USERCONFIG) 214#if defined(USERCONFIG_BOOT) 215 if (1) 216#else 217 if (boothowto & RB_CONFIG) 218#endif 219 { 220 userconfig(); 221 cninit(); /* the preferred console may have changed */ 222 } 223#endif 224 225 printf("avail memory = %ld (%ldK bytes)\n", ptoa(cnt.v_free_count), 226 ptoa(cnt.v_free_count) / 1024); 227 228 /* 229 * Set up buffers, so they can be used to read disk labels. 230 */ 231 bufinit(); 232 vm_pager_bufferinit(); 233 234 /* 235 * Traverse the MADT to discover IOSAPIC and Local SAPIC 236 * information. 237 */ 238 ia64_probe_sapics(); 239} 240 241static void 242identifycpu(void) 243{ 244 char vendor[17]; 245 u_int64_t t; 246 int number, revision, model, family, archrev; 247 u_int64_t features; 248 249 /* 250 * Assumes little-endian. 251 */ 252 *(u_int64_t *) &vendor[0] = ia64_get_cpuid(0); 253 *(u_int64_t *) &vendor[8] = ia64_get_cpuid(1); 254 vendor[16] = '\0'; 255 256 t = ia64_get_cpuid(3); 257 number = (t >> 0) & 0xff; 258 revision = (t >> 8) & 0xff; 259 model = (t >> 16) & 0xff; 260 family = (t >> 24) & 0xff; 261 archrev = (t >> 32) & 0xff; 262 263 if (family == 0x7) 264 strcpy(cpu_model, "Itanium"); 265 else if (family == 0x1f) 266 strcpy(cpu_model, "McKinley"); 267 else 268 snprintf(cpu_model, sizeof(cpu_model), "Family=%d", family); 269 270 features = ia64_get_cpuid(4); 271 272 printf("CPU: %s", cpu_model); 273 if (processor_frequency) 274 printf(" (%ld.%02ld-Mhz)\n", 275 (processor_frequency + 4999) / 1000000, 276 ((processor_frequency + 4999) / 10000) % 100); 277 else 278 printf("\n"); 279 printf(" Origin = \"%s\" Model = %d Revision = %d\n", 280 vendor, model, revision); 281 printf(" Features = 0x%b\n", (u_int32_t) features, 282 "\020" 283 "\001LB"); 284} 285 286static void 287add_kernel_unwind_tables(void *arg) 288{ 289 /* 290 * Register the kernel's unwind table. 291 */ 292 ia64_add_unwind_table(kernel_text, 293 _ia64_unwind_start, 294 _ia64_unwind_end); 295} 296SYSINIT(unwind, SI_SUB_KMEM, SI_ORDER_ANY, add_kernel_unwind_tables, 0); 297 298static void 299map_pal_code(void) 300{ 301 EFI_MEMORY_DESCRIPTOR *md, *mdp; 302 int mdcount, i; 303 u_int64_t psr; 304 struct ia64_pte pte; 305 vm_offset_t addr; 306 307 if (!bootinfo.bi_systab) 308 return; 309 310 mdcount = bootinfo.bi_memmap_size / bootinfo.bi_memdesc_size; 311 md = (EFI_MEMORY_DESCRIPTOR *) IA64_PHYS_TO_RR7(bootinfo.bi_memmap); 312 313 for (i = 0, mdp = md; i < mdcount; i++, 314 mdp = NextMemoryDescriptor(mdp, bootinfo.bi_memdesc_size)) { 315 if (mdp->Type == EfiPalCode) 316 break; 317 } 318 319 if (i == mdcount) { 320 printf("Can't find PAL Code\n"); 321 return; 322 } 323 324 /* 325 * We use a TR to map the first 256M of memory - this might 326 * cover the palcode too. 327 */ 328 if ((mdp->PhysicalStart & ~((1 << 28) - 1)) == 0) { 329 printf("PAL Code is mapped by the kernel's TR\n"); 330 return; 331 } 332 333 addr = mdp->PhysicalStart & ~((1 << 28) - 1); 334 335 bzero(&pte, sizeof(pte)); 336 pte.pte_p = 1; 337 pte.pte_ma = PTE_MA_WB; 338 pte.pte_a = 1; 339 pte.pte_d = 1; 340 pte.pte_pl = PTE_PL_KERN; 341 pte.pte_ar = PTE_AR_RWX; 342 pte.pte_ppn = addr >> 12; 343 344 __asm __volatile("mov %0=psr;;" : "=r" (psr)); 345 __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;"); 346 __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_PHYS_TO_RR7(addr))); 347 __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2)); 348 __asm __volatile("srlz.i;;"); 349 __asm __volatile("itr.i itr[%0]=%1;;" 350 :: "r"(2), "r"(*(u_int64_t*)&pte)); 351 __asm __volatile("srlz.i;;"); 352 __asm __volatile("mov psr.l=%0;; srlz.i;;" :: "r" (psr)); 353} 354 355static void 356calculate_frequencies(void) 357{ 358 struct ia64_sal_result sal; 359 struct ia64_pal_result pal; 360 361 sal = ia64_sal_entry(SAL_FREQ_BASE, 0, 0, 0, 0, 0, 0, 0); 362 pal = ia64_call_pal_static(PAL_FREQ_RATIOS, 0, 0, 0); 363 364 if (sal.sal_status == 0 && pal.pal_status == 0) { 365 if (bootverbose) { 366 printf("Platform clock frequency %ld Hz\n", 367 sal.sal_result[0]); 368 printf("Processor ratio %ld/%ld, Bus ratio %ld/%ld, " 369 "ITC ratio %ld/%ld\n", 370 pal.pal_result[0] >> 32, 371 pal.pal_result[0] & ((1L << 32) - 1), 372 pal.pal_result[1] >> 32, 373 pal.pal_result[1] & ((1L << 32) - 1), 374 pal.pal_result[2] >> 32, 375 pal.pal_result[2] & ((1L << 32) - 1)); 376 } 377 processor_frequency = 378 sal.sal_result[0] * (pal.pal_result[0] >> 32) 379 / (pal.pal_result[0] & ((1L << 32) - 1)); 380 bus_frequency = 381 sal.sal_result[0] * (pal.pal_result[1] >> 32) 382 / (pal.pal_result[1] & ((1L << 32) - 1)); 383 itc_frequency = 384 sal.sal_result[0] * (pal.pal_result[2] >> 32) 385 / (pal.pal_result[2] & ((1L << 32) - 1)); 386 } 387} 388 389void 390ia64_init(u_int64_t arg1, u_int64_t arg2) 391{ 392 int phys_avail_cnt; 393 vm_offset_t kernstart, kernend; 394 vm_offset_t kernstartpfn, kernendpfn, pfn0, pfn1; 395 char *p; 396 EFI_MEMORY_DESCRIPTOR *md, *mdp; 397 int mdcount, i; 398 399 /* NO OUTPUT ALLOWED UNTIL FURTHER NOTICE */ 400 401 /* 402 * TODO: Disable interrupts, floating point etc. 403 * Maybe flush cache and tlb 404 */ 405 ia64_set_fpsr(IA64_FPSR_DEFAULT); 406 407 /* 408 * TODO: Get critical system information (if possible, from the 409 * information provided by the boot program). 410 */ 411 412 /* 413 * Gross and disgusting hack. The bootinfo is written into 414 * memory at a fixed address. 415 */ 416 bootinfo = *(struct bootinfo *) 0xe000000000508000; 417 if (bootinfo.bi_magic != BOOTINFO_MAGIC 418 || bootinfo.bi_version != 1) { 419 bzero(&bootinfo, sizeof(bootinfo)); 420 bootinfo.bi_kernend = (vm_offset_t) round_page(_end); 421 } 422 423 /* 424 * Look for the I/O ports first - we need them for console 425 * probing. 426 */ 427 mdcount = bootinfo.bi_memmap_size / bootinfo.bi_memdesc_size; 428 md = (EFI_MEMORY_DESCRIPTOR *) IA64_PHYS_TO_RR7(bootinfo.bi_memmap); 429 if (md == NULL || mdcount == 0) { 430#ifdef SKI 431 static EFI_MEMORY_DESCRIPTOR ski_md[2]; 432 /* 433 * XXX hack for ski. In reality, the loader will probably ask 434 * EFI and pass the results to us. Possibly, we will call EFI 435 * directly. 436 */ 437 ski_md[0].Type = EfiConventionalMemory; 438 ski_md[0].PhysicalStart = 2L*1024*1024; 439 ski_md[0].VirtualStart = 0; 440 ski_md[0].NumberOfPages = (64L*1024*1024)>>12; 441 ski_md[0].Attribute = EFI_MEMORY_WB; 442 443 ski_md[1].Type = EfiMemoryMappedIOPortSpace; 444 ski_md[1].PhysicalStart = 0xffffc000000; 445 ski_md[1].VirtualStart = 0; 446 ski_md[1].NumberOfPages = (64L*1024*1024)>>12; 447 ski_md[1].Attribute = EFI_MEMORY_UC; 448 449 md = ski_md; 450 mdcount = 2; 451#endif 452 } 453 454 for (i = 0, mdp = md; i < mdcount; i++, 455 mdp = NextMemoryDescriptor(mdp, bootinfo.bi_memdesc_size)) { 456 if (mdp->Type == EfiMemoryMappedIOPortSpace) { 457 ia64_port_base = IA64_PHYS_TO_RR6(mdp->PhysicalStart); 458 } 459 } 460 461 /* 462 * Look at arguments passed to us and compute boothowto. 463 */ 464 boothowto = bootinfo.bi_boothowto; 465#ifdef KADB 466 boothowto |= RB_KDB; 467#endif 468 469 /* 470 * Catch case of boot_verbose set in environment. 471 */ 472 if ((p = getenv("boot_verbose")) != NULL) { 473 if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) { 474 boothowto |= RB_VERBOSE; 475 } 476 } 477 478 if (boothowto & RB_VERBOSE) 479 bootverbose = 1; 480 481 /* 482 * Initialize the console before we print anything out. 483 */ 484 cninit(); 485 486 /* OUTPUT NOW ALLOWED */ 487 488 /* 489 * Wire things up so we can call the firmware. 490 */ 491 map_pal_code(); 492 ia64_efi_init(); 493#ifdef SKI 494 ia64_ski_init(); 495#endif 496 calculate_frequencies(); 497 498 /* 499 * Find the beginning and end of the kernel. 500 */ 501 kernstart = trunc_page(kernel_text); 502 ksym_start = (void *)bootinfo.bi_symtab; 503 ksym_end = (void *)bootinfo.bi_esymtab; 504 kernend = (vm_offset_t)round_page(ksym_end); 505 /* But if the bootstrap tells us otherwise, believe it! */ 506 if (bootinfo.bi_kernend) 507 kernend = round_page(bootinfo.bi_kernend); 508 preload_metadata = (caddr_t)bootinfo.bi_modulep; 509 if (envmode == 1) 510 kern_envp = static_env; 511 else 512 kern_envp = (caddr_t)bootinfo.bi_envp; 513 514 /* Init basic tunables, including hz */ 515 init_param(); 516 517 p = getenv("kernelname"); 518 if (p) 519 strncpy(kernelname, p, sizeof(kernelname) - 1); 520 521 kernstartpfn = atop(IA64_RR_MASK(kernstart)); 522 kernendpfn = atop(IA64_RR_MASK(kernend)); 523 524 /* 525 * Size the memory regions and load phys_avail[] with the results. 526 */ 527 528 /* 529 * Find out how much memory is available, by looking at 530 * the memory descriptors. 531 */ 532 533#ifdef DEBUG_MD 534 printf("Memory descriptor count: %d\n", mdcount); 535#endif 536 537 phys_avail_cnt = 0; 538 for (i = 0, mdp = md; i < mdcount; i++, 539 mdp = NextMemoryDescriptor(mdp, bootinfo.bi_memdesc_size)) { 540#ifdef DEBUG_MD 541 printf("MD %d: type %d pa 0x%lx cnt 0x%lx\n", i, 542 mdp->Type, 543 mdp->PhysicalStart, 544 mdp->NumberOfPages); 545#endif 546 547 pfn0 = ia64_btop(round_page(mdp->PhysicalStart)); 548 pfn1 = ia64_btop(trunc_page(mdp->PhysicalStart 549 + mdp->NumberOfPages * 4096)); 550 if (pfn1 <= pfn0) 551 continue; 552 553 if (mdp->Type != EfiConventionalMemory) { 554 resvmem += (pfn1 - pfn0); 555 continue; 556 } 557 558 totalphysmem += (pfn1 - pfn0); 559 560 /* 561 * We have a memory descriptors available for system 562 * software use. We must determine if this cluster 563 * holds the kernel. 564 */ 565 physmem += (pfn1 - pfn0); 566 if (pfn0 <= kernendpfn && kernstartpfn <= pfn1) { 567 /* 568 * Must compute the location of the kernel 569 * within the segment. 570 */ 571#ifdef DEBUG_MD 572 printf("Descriptor %d contains kernel\n", i); 573#endif 574 if (pfn0 < kernstartpfn) { 575 /* 576 * There is a chunk before the kernel. 577 */ 578#ifdef DEBUG_MD 579 printf("Loading chunk before kernel: " 580 "0x%lx / 0x%lx\n", pfn0, kernstartpfn); 581#endif 582 phys_avail[phys_avail_cnt] = ia64_ptob(pfn0); 583 phys_avail[phys_avail_cnt+1] = ia64_ptob(kernstartpfn); 584 phys_avail_cnt += 2; 585 } 586 if (kernendpfn < pfn1) { 587 /* 588 * There is a chunk after the kernel. 589 */ 590#ifdef DEBUG_MD 591 printf("Loading chunk after kernel: " 592 "0x%lx / 0x%lx\n", kernendpfn, pfn1); 593#endif 594 phys_avail[phys_avail_cnt] = ia64_ptob(kernendpfn); 595 phys_avail[phys_avail_cnt+1] = ia64_ptob(pfn1); 596 phys_avail_cnt += 2; 597 } 598 } else { 599 /* 600 * Just load this cluster as one chunk. 601 */ 602#ifdef DEBUG_MD 603 printf("Loading descriptor %d: 0x%lx / 0x%lx\n", i, 604 pfn0, pfn1); 605#endif 606 phys_avail[phys_avail_cnt] = ia64_ptob(pfn0); 607 phys_avail[phys_avail_cnt+1] = ia64_ptob(pfn1); 608 phys_avail_cnt += 2; 609 610 } 611 } 612 phys_avail[phys_avail_cnt] = 0; 613 614 Maxmem = physmem; 615 616 /* 617 * Initialize error message buffer (at end of core). 618 */ 619 { 620 size_t sz = round_page(MSGBUF_SIZE); 621 int i = phys_avail_cnt - 2; 622 623 /* shrink so that it'll fit in the last segment */ 624 if (phys_avail[i+1] - phys_avail[i] < sz) 625 sz = phys_avail[i+1] - phys_avail[i]; 626 627 phys_avail[i+1] -= sz; 628 msgbufp = (struct msgbuf*) IA64_PHYS_TO_RR7(phys_avail[i+1]); 629 630 msgbufinit(msgbufp, sz); 631 632 /* Remove the last segment if it now has no pages. */ 633 if (phys_avail[i] == phys_avail[i+1]) { 634 phys_avail[i] = 0; 635 phys_avail[i+1] = 0; 636 } 637 638 /* warn if the message buffer had to be shrunk */ 639 if (sz != round_page(MSGBUF_SIZE)) 640 printf("WARNING: %ld bytes not available for msgbuf in last cluster (%ld used)\n", 641 round_page(MSGBUF_SIZE), sz); 642 643 } 644 645 proc_linkup(&proc0); 646 /* 647 * Init mapping for u page(s) for proc 0 648 */ 649 proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE); 650 proc0kstack = (vm_offset_t)kstack; 651 proc0.p_uarea = proc0uarea; 652 thread0 = &proc0.p_thread; 653 thread0->td_kstack = proc0kstack; 654 thread0->td_pcb = (struct pcb *) 655 (thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 656 /* 657 * Setup the global data for the bootstrap cpu. 658 */ 659 { 660 /* This is not a 'struct user' */ 661 size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE); 662 globalp = (struct globaldata *) pmap_steal_memory(sz); 663 globaldata_init(globalp, 0, sz); 664 ia64_set_k4((u_int64_t) globalp); 665 PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ 666 } 667 668 /* 669 * Initialize the virtual memory system. 670 */ 671 pmap_bootstrap(); 672 673 /* 674 * Initialize the rest of proc 0's PCB. 675 * 676 * Set the kernel sp, reserving space for an (empty) trapframe, 677 * and make proc0's trapframe pointer point to it for sanity. 678 * Initialise proc0's backing store to start after u area. 679 * 680 * XXX what is all this +/- 16 stuff? 681 */ 682 thread0->td_frame = (struct trapframe *)thread0->td_pcb - 1; 683 thread0->td_pcb->pcb_sp = (u_int64_t)thread0->td_frame - 16; 684 thread0->td_pcb->pcb_bspstore = (u_int64_t)proc0kstack; 685 686 /* Setup curproc so that mutexes work */ 687 PCPU_SET(curthread, thread0); 688 PCPU_SET(spinlocks, NULL); 689 690 LIST_INIT(&thread0->td_contested); 691 692 /* 693 * Initialise mutexes. 694 */ 695 mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE); 696 mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); 697 mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); 698 mtx_lock(&Giant); 699 700 /* 701 * Initialize debuggers, and break into them if appropriate. 702 */ 703#ifdef DDB 704 kdb_init(); 705 if (boothowto & RB_KDB) { 706 printf("Boot flags requested debugger\n"); 707 breakpoint(); 708 } 709#endif 710} 711 712int 713ia64_running_in_simulator() 714{ 715 return bootinfo.bi_systab == 0; 716} 717 718void 719bzero(void *buf, size_t len) 720{ 721 caddr_t p = buf; 722 723 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 724 *p++ = 0; 725 len--; 726 } 727 while (len >= sizeof(u_long) * 8) { 728 *(u_long*) p = 0; 729 *((u_long*) p + 1) = 0; 730 *((u_long*) p + 2) = 0; 731 *((u_long*) p + 3) = 0; 732 len -= sizeof(u_long) * 8; 733 *((u_long*) p + 4) = 0; 734 *((u_long*) p + 5) = 0; 735 *((u_long*) p + 6) = 0; 736 *((u_long*) p + 7) = 0; 737 p += sizeof(u_long) * 8; 738 } 739 while (len >= sizeof(u_long)) { 740 *(u_long*) p = 0; 741 len -= sizeof(u_long); 742 p += sizeof(u_long); 743 } 744 while (len) { 745 *p++ = 0; 746 len--; 747 } 748} 749 750void 751DELAY(int n) 752{ 753 u_int64_t start, end, now; 754 755 start = ia64_get_itc(); 756 end = start + (itc_frequency * n) / 1000000; 757 /* printf("DELAY from 0x%lx to 0x%lx\n", start, end); */ 758 do { 759 now = ia64_get_itc(); 760 } while (now < end || (now > start && end < start)); 761} 762 763/* 764 * Send an interrupt to process. 765 * 766 * Stack is set up to allow sigcode stored 767 * at top to call routine, followed by kcall 768 * to sigreturn routine below. After sigreturn 769 * resets the signal mask, the stack, and the 770 * frame pointer, it returns to the user 771 * specified pc, psl. 772 */ 773void 774sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) 775{ 776 struct proc *p; 777 struct thread *td; 778 struct trapframe *frame; 779 struct sigacts *psp; 780 struct sigframe sf, *sfp; 781 u_int64_t sbs = 0; 782 int oonstack, rndfsize; 783 784 td = curthread; 785 p = td->td_proc; 786 PROC_LOCK_ASSERT(p, MA_OWNED); 787 psp = p->p_sigacts; 788 frame = td->td_frame; 789 oonstack = sigonstack(frame->tf_r[FRAME_SP]); 790 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 791 792 /* 793 * Make sure that we restore the entire trapframe after a 794 * signal. 795 */ 796 frame->tf_flags &= ~FRAME_SYSCALL; 797 798 /* save user context */ 799 bzero(&sf, sizeof(struct sigframe)); 800 sf.sf_uc.uc_sigmask = *mask; 801 sf.sf_uc.uc_stack = p->p_sigstk; 802 sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK) 803 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 804 sf.sf_uc.uc_mcontext.mc_flags = IA64_MC_FLAG_ONSTACK; 805 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 806 807 sf.sf_uc.uc_mcontext.mc_nat = 0; /* XXX */ 808 sf.sf_uc.uc_mcontext.mc_sp = frame->tf_r[FRAME_SP]; 809 sf.sf_uc.uc_mcontext.mc_ip = (frame->tf_cr_iip 810 | ((frame->tf_cr_ipsr >> 41) & 3)); 811 sf.sf_uc.uc_mcontext.mc_cfm = frame->tf_cr_ifs & ~(1<<31); 812 sf.sf_uc.uc_mcontext.mc_um = frame->tf_cr_ipsr & 0x1fff; 813 sf.sf_uc.uc_mcontext.mc_ar_rsc = frame->tf_ar_rsc; 814 sf.sf_uc.uc_mcontext.mc_ar_bsp = frame->tf_ar_bspstore; 815 sf.sf_uc.uc_mcontext.mc_ar_rnat = frame->tf_ar_rnat; 816 sf.sf_uc.uc_mcontext.mc_ar_ccv = frame->tf_ar_ccv; 817 sf.sf_uc.uc_mcontext.mc_ar_unat = frame->tf_ar_unat; 818 sf.sf_uc.uc_mcontext.mc_ar_fpsr = frame->tf_ar_fpsr; 819 sf.sf_uc.uc_mcontext.mc_ar_pfs = frame->tf_ar_pfs; 820 sf.sf_uc.uc_mcontext.mc_pr = frame->tf_pr; 821 822 bcopy(&frame->tf_b[0], 823 &sf.sf_uc.uc_mcontext.mc_br[0], 824 8 * sizeof(unsigned long)); 825 sf.sf_uc.uc_mcontext.mc_gr[0] = 0; 826 bcopy(&frame->tf_r[0], 827 &sf.sf_uc.uc_mcontext.mc_gr[1], 828 31 * sizeof(unsigned long)); 829 830 /* XXX mc_fr[] */ 831 832 /* 833 * Allocate and validate space for the signal handler 834 * context. Note that if the stack is in P0 space, the 835 * call to grow() is a nop, and the useracc() check 836 * will fail if the process has not already allocated 837 * the space with a `brk'. 838 */ 839 if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack && 840 SIGISMEMBER(psp->ps_sigonstack, sig)) { 841 sbs = (u_int64_t) p->p_sigstk.ss_sp; 842 sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp + 843 p->p_sigstk.ss_size - rndfsize); 844 /* 845 * Align sp and bsp. 846 */ 847 sbs = (sbs + 15) & ~15; 848 sfp = (struct sigframe *)((u_int64_t)sfp & ~15); 849#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 850 p->p_sigstk.ss_flags |= SS_ONSTACK; 851#endif 852 } else 853 sfp = (struct sigframe *)(frame->tf_r[FRAME_SP] - rndfsize); 854 PROC_UNLOCK(p); 855 856 (void)grow_stack(p, (u_long)sfp); 857#ifdef DEBUG 858 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 859 printf("sendsig(%d): sig %d ssp %p usp %p\n", p->p_pid, 860 sig, &sf, sfp); 861#endif 862 if (!useracc((caddr_t)sfp, sizeof(sf), VM_PROT_WRITE)) { 863#ifdef DEBUG 864 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 865 printf("sendsig(%d): useracc failed on sig %d\n", 866 p->p_pid, sig); 867#endif 868 /* 869 * Process has trashed its stack; give it an illegal 870 * instruction to halt it in its tracks. 871 */ 872 PROC_LOCK(p); 873 SIGACTION(p, SIGILL) = SIG_DFL; 874 SIGDELSET(p->p_sigignore, SIGILL); 875 SIGDELSET(p->p_sigcatch, SIGILL); 876 SIGDELSET(p->p_sigmask, SIGILL); 877 psignal(p, SIGILL); 878 return; 879 } 880 881#if 0 882 /* save the floating-point state, if necessary, then copy it. */ 883 ia64_fpstate_save(td, 1); 884 sf.sf_uc.uc_mcontext.mc_ownedfp = td->td_md.md_flags & MDP_FPUSED; 885 bcopy(&td->td_pcb->pcb_fp, 886 (struct fpreg *)sf.sf_uc.uc_mcontext.mc_fpregs, 887 sizeof(struct fpreg)); 888 sf.sf_uc.uc_mcontext.mc_fp_control = td->td_pcb.pcb_fp_control; 889#endif 890 891 /* 892 * copy the frame out to userland. 893 */ 894 (void) copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)); 895#ifdef DEBUG 896 if (sigdebug & SDB_FOLLOW) 897 printf("sendsig(%d): sig %d sfp %p code %lx\n", p->p_pid, sig, 898 sfp, code); 899#endif 900 901 /* 902 * Set up the registers to return to sigcode. 903 */ 904 frame->tf_cr_ipsr &= ~IA64_PSR_RI; 905 frame->tf_cr_iip = PS_STRINGS - (esigcode - sigcode); 906 frame->tf_r[FRAME_R1] = sig; 907 PROC_LOCK(p); 908 if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) { 909 frame->tf_r[FRAME_R15] = (u_int64_t)&(sfp->sf_si); 910 911 /* Fill in POSIX parts */ 912 sf.sf_si.si_signo = sig; 913 sf.sf_si.si_code = code; 914 sf.sf_si.si_addr = (void*)frame->tf_cr_ifa; 915 } 916 else 917 frame->tf_r[FRAME_R15] = code; 918 919 frame->tf_r[FRAME_SP] = (u_int64_t)sfp - 16; 920 frame->tf_r[FRAME_R14] = sig; 921 frame->tf_r[FRAME_R15] = (u_int64_t) &sfp->sf_si; 922 frame->tf_r[FRAME_R16] = (u_int64_t) &sfp->sf_uc; 923 frame->tf_r[FRAME_R17] = (u_int64_t)catcher; 924 frame->tf_r[FRAME_R18] = sbs; 925 926#ifdef DEBUG 927 if (sigdebug & SDB_FOLLOW) 928 printf("sendsig(%d): pc %lx, catcher %lx\n", p->p_pid, 929 frame->tf_cr_iip, frame->tf_regs[FRAME_R4]); 930 if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid) 931 printf("sendsig(%d): sig %d returns\n", 932 p->p_pid, sig); 933#endif 934} 935 936/* 937 * System call to cleanup state after a signal 938 * has been taken. Reset signal mask and 939 * stack state from context left by sendsig (above). 940 * Return to previous pc and psl as specified by 941 * context left by sendsig. Check carefully to 942 * make sure that the user has not modified the 943 * state to gain improper privileges. 944 */ 945#ifdef COMPAT_43 946int 947osigreturn(struct thread *td, 948 struct osigreturn_args /* { 949 struct osigcontext *sigcntxp; 950 } */ *uap) 951{ 952 return EOPNOTSUPP; 953} 954#endif 955 956/* 957 * System call to cleanup state after a signal 958 * has been taken. Reset signal mask and 959 * stack state from context left by sendsig (above). 960 * Return to previous pc and psl as specified by 961 * context left by sendsig. Check carefully to 962 * make sure that the user has not modified the 963 * state to gain improper privileges. 964 */ 965 966int 967sigreturn(struct thread *td, 968 struct sigreturn_args /* { 969 ucontext_t *sigcntxp; 970 } */ *uap) 971{ 972 ucontext_t uc, *ucp; 973 struct pcb *pcb; 974 struct trapframe *frame = td->td_frame; 975 struct __mcontext *mcp; 976 struct proc *p; 977 978 ucp = uap->sigcntxp; 979 pcb = td->td_pcb; 980 p = td->td_proc; 981 982#ifdef DEBUG 983 if (sigdebug & SDB_FOLLOW) 984 printf("sigreturn: pid %d, scp %p\n", p->p_pid, ucp); 985#endif 986 987 /* 988 * Fetch the entire context structure at once for speed. 989 * We don't use a normal argument to simplify RSE handling. 990 */ 991 if (copyin((caddr_t)frame->tf_r[FRAME_R4], 992 (caddr_t)&uc, sizeof(ucontext_t))) 993 return (EFAULT); 994 995 if (frame->tf_ndirty != 0) { 996 printf("sigreturn: dirty user stacked registers\n"); 997 } 998 999 /* 1000 * Restore the user-supplied information 1001 */ 1002 mcp = &uc.uc_mcontext; 1003 bcopy(&mcp->mc_br[0], &frame->tf_b[0], 8*sizeof(u_int64_t)); 1004 bcopy(&mcp->mc_gr[1], &frame->tf_r[0], 31*sizeof(u_int64_t)); 1005 /* XXX mc_fr */ 1006 1007 frame->tf_flags &= ~FRAME_SYSCALL; 1008 frame->tf_cr_iip = mcp->mc_ip & ~15; 1009 frame->tf_cr_ipsr &= ~IA64_PSR_RI; 1010 switch (mcp->mc_ip & 15) { 1011 case 1: 1012 frame->tf_cr_ipsr |= IA64_PSR_RI_1; 1013 break; 1014 case 2: 1015 frame->tf_cr_ipsr |= IA64_PSR_RI_2; 1016 break; 1017 } 1018 frame->tf_cr_ipsr = ((frame->tf_cr_ipsr & ~0x1fff) 1019 | (mcp->mc_um & 0x1fff)); 1020 frame->tf_pr = mcp->mc_pr; 1021 frame->tf_ar_rsc = (mcp->mc_ar_rsc & 3) | 12; /* user, loadrs=0 */ 1022 frame->tf_ar_pfs = mcp->mc_ar_pfs; 1023 frame->tf_cr_ifs = mcp->mc_cfm | (1UL<<63); 1024 frame->tf_ar_bspstore = mcp->mc_ar_bsp; 1025 frame->tf_ar_rnat = mcp->mc_ar_rnat; 1026 frame->tf_ndirty = 0; /* assumes flushrs in sigcode */ 1027 frame->tf_ar_unat = mcp->mc_ar_unat; 1028 frame->tf_ar_ccv = mcp->mc_ar_ccv; 1029 frame->tf_ar_fpsr = mcp->mc_ar_fpsr; 1030 1031 frame->tf_r[FRAME_SP] = mcp->mc_sp; 1032 1033 PROC_LOCK(p); 1034#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 1035 if (uc.uc_mcontext.mc_onstack & 1) 1036 p->p_sigstk.ss_flags |= SS_ONSTACK; 1037 else 1038 p->p_sigstk.ss_flags &= ~SS_ONSTACK; 1039#endif 1040 1041 p->p_sigmask = uc.uc_sigmask; 1042 SIG_CANTMASK(p->p_sigmask); 1043 PROC_UNLOCK(p); 1044 1045 /* XXX ksc.sc_ownedfp ? */ 1046 ia64_fpstate_drop(td); 1047#if 0 1048 bcopy((struct fpreg *)uc.uc_mcontext.mc_fpregs, 1049 &td->td_pcb->pcb_fp, sizeof(struct fpreg)); 1050 td->td_pcb->pcb_fp_control = uc.uc_mcontext.mc_fp_control; 1051#endif 1052 1053#ifdef DEBUG 1054 if (sigdebug & SDB_FOLLOW) 1055 printf("sigreturn(%d): returns\n", p->p_pid); 1056#endif 1057 return (EJUSTRETURN); 1058} 1059 1060/* 1061 * Machine dependent boot() routine 1062 */ 1063void 1064cpu_boot(int howto) 1065{ 1066 1067 ia64_efi_runtime->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, 0); 1068} 1069 1070/* 1071 * Shutdown the CPU as much as possible 1072 */ 1073void 1074cpu_halt(void) 1075{ 1076 1077 ia64_efi_runtime->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, 0); 1078} 1079 1080/* 1081 * Clear registers on exec 1082 */ 1083void 1084setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 1085{ 1086 struct trapframe *frame; 1087 1088 frame = td->td_frame; 1089 1090 /* 1091 * Make sure that we restore the entire trapframe after an 1092 * execve. 1093 */ 1094 frame->tf_flags &= ~FRAME_SYSCALL; 1095 1096 bzero(frame->tf_r, sizeof(frame->tf_r)); 1097 bzero(frame->tf_f, sizeof(frame->tf_f)); 1098 frame->tf_cr_iip = entry; 1099 frame->tf_cr_ipsr = (IA64_PSR_IC 1100 | IA64_PSR_I 1101 | IA64_PSR_IT 1102 | IA64_PSR_DT 1103 | IA64_PSR_RT 1104 | IA64_PSR_DFH 1105 | IA64_PSR_BN 1106 | IA64_PSR_CPL_USER); 1107 /* 1108 * Make sure that sp is aligned to a 16 byte boundary and 1109 * reserve 16 bytes of scratch space for _start. 1110 */ 1111 frame->tf_r[FRAME_SP] = (stack & ~15) - 16; 1112 1113 /* 1114 * Write values for out0, out1 and out2 to the user's backing 1115 * store and arrange for them to be restored into the user's 1116 * initial register frame. Assumes that (bspstore & 0x1f8) < 1117 * 0x1e0. 1118 */ 1119 frame->tf_ar_bspstore = td->td_md.md_bspstore + 24; 1120 suword((caddr_t) frame->tf_ar_bspstore - 24, stack); 1121 suword((caddr_t) frame->tf_ar_bspstore - 16, ps_strings); 1122 suword((caddr_t) frame->tf_ar_bspstore - 8, 0); 1123 frame->tf_ndirty = 0; 1124 frame->tf_cr_ifs = (1L<<63) | 3; /* sof=3, v=1 */ 1125 1126 frame->tf_ar_rsc = 0xf; /* user mode rsc */ 1127 frame->tf_ar_fpsr = IA64_FPSR_DEFAULT; 1128 1129 td->td_md.md_flags &= ~MDP_FPUSED; 1130 ia64_fpstate_drop(td); 1131} 1132 1133int 1134ptrace_set_pc(struct thread *td, unsigned long addr) 1135{ 1136 /* TODO set pc in trapframe */ 1137 return 0; 1138} 1139 1140int 1141ptrace_single_step(struct thread *td) 1142{ 1143 /* TODO arrange for user process to single step */ 1144 return 0; 1145} 1146 1147int 1148ia64_pa_access(vm_offset_t pa) 1149{ 1150 return VM_PROT_READ|VM_PROT_WRITE; 1151} 1152 1153int 1154fill_regs(td, regs) 1155 struct thread *td; 1156 struct reg *regs; 1157{ 1158 /* TODO copy trapframe to regs */ 1159 return (0); 1160} 1161 1162int 1163set_regs(td, regs) 1164 struct thread *td; 1165 struct reg *regs; 1166{ 1167 /* TODO copy regs to trapframe */ 1168 return (0); 1169} 1170 1171int 1172fill_dbregs(struct thread *td, struct dbreg *dbregs) 1173{ 1174 1175 return (ENOSYS); 1176} 1177 1178int 1179set_dbregs(struct thread *td, struct dbreg *dbregs) 1180{ 1181 1182 return (ENOSYS); 1183} 1184 1185int 1186fill_fpregs(td, fpregs) 1187 struct thread *td; 1188 struct fpreg *fpregs; 1189{ 1190 /* TODO copy fpu state to fpregs */ 1191 ia64_fpstate_save(td, 0); 1192 1193#if 0 1194 bcopy(&td->td_pcb->pcb_fp, fpregs, sizeof *fpregs); 1195#endif 1196 return (0); 1197} 1198 1199int 1200set_fpregs(td, fpregs) 1201 struct thread *td; 1202 struct fpreg *fpregs; 1203{ 1204 /* TODO copy fpregs fpu state */ 1205 ia64_fpstate_drop(td); 1206 1207#if 0 1208 bcopy(fpregs, &td->td_pcb->pcb_fp, sizeof *fpregs); 1209#endif 1210 return (0); 1211} 1212 1213#ifndef DDB 1214void 1215Debugger(const char *msg) 1216{ 1217 printf("Debugger(\"%s\") called.\n", msg); 1218} 1219#endif /* no DDB */ 1220 1221#include <sys/disklabel.h> 1222 1223/* 1224 * Determine the size of the transfer, and make sure it is 1225 * within the boundaries of the partition. Adjust transfer 1226 * if needed, and signal errors or early completion. 1227 */ 1228int 1229bounds_check_with_label(struct bio *bp, struct disklabel *lp, int wlabel) 1230{ 1231#if 0 1232 struct partition *p = lp->d_partitions + dkpart(bp->bio_dev); 1233 int labelsect = lp->d_partitions[0].p_offset; 1234 int maxsz = p->p_size, 1235 sz = (bp->bio_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; 1236 1237 /* overwriting disk label ? */ 1238 /* XXX should also protect bootstrap in first 8K */ 1239 if (bp->bio_blkno + p->p_offset <= LABELSECTOR + labelsect && 1240#if LABELSECTOR != 0 1241 bp->bio_blkno + p->p_offset + sz > LABELSECTOR + labelsect && 1242#endif 1243 (bp->bio_cmd == BIO_WRITE) && wlabel == 0) { 1244 bp->bio_error = EROFS; 1245 goto bad; 1246 } 1247 1248#if defined(DOSBBSECTOR) && defined(notyet) 1249 /* overwriting master boot record? */ 1250 if (bp->bio_blkno + p->p_offset <= DOSBBSECTOR && 1251 (bp->bio_cmd == BIO_WRITE) && wlabel == 0) { 1252 bp->bio_error = EROFS; 1253 goto bad; 1254 } 1255#endif 1256 1257 /* beyond partition? */ 1258 if (bp->bio_blkno < 0 || bp->bio_blkno + sz > maxsz) { 1259 /* if exactly at end of disk, return an EOF */ 1260 if (bp->bio_blkno == maxsz) { 1261 bp->bio_resid = bp->bio_bcount; 1262 return(0); 1263 } 1264 /* or truncate if part of it fits */ 1265 sz = maxsz - bp->bio_blkno; 1266 if (sz <= 0) { 1267 bp->bio_error = EINVAL; 1268 goto bad; 1269 } 1270 bp->bio_bcount = sz << DEV_BSHIFT; 1271 } 1272 1273 bp->bio_pblkno = bp->bio_blkno + p->p_offset; 1274 return(1); 1275 1276bad: 1277#endif 1278 bp->bio_flags |= BIO_ERROR; 1279 return(-1); 1280 1281} 1282 1283static int 1284sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) 1285{ 1286 int error; 1287 error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, 1288 req); 1289 if (!error && req->newptr) 1290 resettodr(); 1291 return (error); 1292} 1293 1294SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, 1295 &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", ""); 1296 1297SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set, 1298 CTLFLAG_RW, &disable_rtc_set, 0, ""); 1299 1300SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock, 1301 CTLFLAG_RW, &wall_cmos_clock, 0, ""); 1302 1303void 1304ia64_fpstate_check(struct thread *td) 1305{ 1306 if ((td->td_frame->tf_cr_ipsr & IA64_PSR_DFH) == 0) 1307 if (td != PCPU_GET(fpcurthread)) 1308 panic("ia64_check_fpcurthread: bogus"); 1309} 1310 1311/* 1312 * Save the high floating point state in the pcb. Use this to get 1313 * read-only access to the floating point state. If write is true, the 1314 * current fp process is cleared so that fp state can safely be 1315 * modified. The process will automatically reload the changed state 1316 * by generating a disabled fp trap. 1317 */ 1318void 1319ia64_fpstate_save(struct thread *td, int write) 1320{ 1321 if (td == PCPU_GET(fpcurthread)) { 1322 /* 1323 * Save the state in the pcb. 1324 */ 1325 savehighfp(td->td_pcb->pcb_highfp); 1326 1327 if (write) { 1328 td->td_frame->tf_cr_ipsr |= IA64_PSR_DFH; 1329 PCPU_SET(fpcurthread, NULL); 1330 } 1331 } 1332} 1333 1334/* 1335 * Relinquish ownership of the FP state. This is called instead of 1336 * ia64_save_fpstate() if the entire FP state is being changed 1337 * (e.g. on sigreturn). 1338 */ 1339void 1340ia64_fpstate_drop(struct thread *td) 1341{ 1342 if (td == PCPU_GET(fpcurthread)) { 1343 td->td_frame->tf_cr_ipsr |= IA64_PSR_DFH; 1344 PCPU_SET(fpcurthread, NULL); 1345 } 1346} 1347 1348/* 1349 * Switch the current owner of the fp state to p, reloading the state 1350 * from the pcb. 1351 */ 1352void 1353ia64_fpstate_switch(struct thread *td) 1354{ 1355 if (PCPU_GET(fpcurthread)) { 1356 /* 1357 * Dump the old fp state if its valid. 1358 */ 1359 savehighfp(PCPU_GET(fpcurthread)->td_pcb->pcb_highfp); 1360 PCPU_GET(fpcurthread)->td_frame->tf_cr_ipsr |= IA64_PSR_DFH; 1361 } 1362 1363 /* 1364 * Remember the new FP owner and reload its state. 1365 */ 1366 PCPU_SET(fpcurthread, td); 1367 restorehighfp(td->td_pcb->pcb_highfp); 1368 td->td_frame->tf_cr_ipsr &= ~IA64_PSR_DFH; 1369 1370 td->td_md.md_flags |= MDP_FPUSED; 1371} 1372 1373/* 1374 * Initialise a struct globaldata. 1375 */ 1376void 1377globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz) 1378{ 1379 bzero(globaldata, sz); 1380 globaldata->gd_cpuid = cpuid; 1381 globaldata_register(globaldata); 1382} 1383 1384/* 1385 * Utility functions for manipulating instruction bundles. 1386 */ 1387void 1388ia64_unpack_bundle(u_int64_t low, u_int64_t high, struct ia64_bundle *bp) 1389{ 1390 bp->template = low & 0x1f; 1391 bp->slot[0] = (low >> 5) & ((1L<<41) - 1); 1392 bp->slot[1] = (low >> 46) | ((high & ((1L<<23) - 1)) << 18); 1393 bp->slot[2] = (high >> 23); 1394} 1395 1396void 1397ia64_pack_bundle(u_int64_t *lowp, u_int64_t *highp, 1398 const struct ia64_bundle *bp) 1399{ 1400 u_int64_t low, high; 1401 1402 low = bp->template | (bp->slot[0] << 5) | (bp->slot[1] << 46); 1403 high = (bp->slot[1] >> 18) | (bp->slot[2] << 23); 1404 *lowp = low; 1405 *highp = high; 1406} 1407 1408static int 1409rse_slot(u_int64_t *bsp) 1410{ 1411 return ((u_int64_t) bsp >> 3) & 0x3f; 1412} 1413 1414/* 1415 * Return the address of register regno (regno >= 32) given that bsp 1416 * points at the base of the register stack frame. 1417 */ 1418u_int64_t * 1419ia64_rse_register_address(u_int64_t *bsp, int regno) 1420{ 1421 int off = regno - 32; 1422 u_int64_t rnats = (rse_slot(bsp) + off) / 63; 1423 return bsp + off + rnats; 1424} 1425 1426/* 1427 * Calculate the base address of the previous frame given that the 1428 * current frame's locals area is 'size'. 1429 */ 1430u_int64_t * 1431ia64_rse_previous_frame(u_int64_t *bsp, int size) 1432{ 1433 int slot = rse_slot(bsp); 1434 int rnats = 0; 1435 int count = size; 1436 1437 while (count > slot) { 1438 count -= 63; 1439 rnats++; 1440 slot = 63; 1441 } 1442 return bsp - size - rnats; 1443} 1444 1445