The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ia64/ia64/machdep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3acedfa7ceec7c453737a83a2b1c21e3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.