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/powerpc/booke/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) 2006-2012 Semihalf
    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 ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
   17  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
   19  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  */
   25 /*-
   26  * Copyright (C) 2001 Benno Rice
   27  * All rights reserved.
   28  *
   29  * Redistribution and use in source and binary forms, with or without
   30  * modification, are permitted provided that the following conditions
   31  * are met:
   32  * 1. Redistributions of source code must retain the above copyright
   33  *    notice, this list of conditions and the following disclaimer.
   34  * 2. Redistributions in binary form must reproduce the above copyright
   35  *    notice, this list of conditions and the following disclaimer in the
   36  *    documentation and/or other materials provided with the distribution.
   37  *
   38  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
   39  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   40  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   41  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   44  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   45  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   46  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   47  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   48  * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $
   49  */
   50 /*-
   51  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
   52  * Copyright (C) 1995, 1996 TooLs GmbH.
   53  * All rights reserved.
   54  *
   55  * Redistribution and use in source and binary forms, with or without
   56  * modification, are permitted provided that the following conditions
   57  * are met:
   58  * 1. Redistributions of source code must retain the above copyright
   59  *    notice, this list of conditions and the following disclaimer.
   60  * 2. Redistributions in binary form must reproduce the above copyright
   61  *    notice, this list of conditions and the following disclaimer in the
   62  *    documentation and/or other materials provided with the distribution.
   63  * 3. All advertising materials mentioning features or use of this software
   64  *    must display the following acknowledgement:
   65  *      This product includes software developed by TooLs GmbH.
   66  * 4. The name of TooLs GmbH may not be used to endorse or promote products
   67  *    derived from this software without specific prior written permission.
   68  *
   69  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
   70  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   71  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   72  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   73  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   74  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   75  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   76  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   77  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   78  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   79  */
   80 
   81 #include <sys/cdefs.h>
   82 __FBSDID("$FreeBSD: releng/10.1/sys/powerpc/booke/machdep.c 266003 2014-05-14 04:14:58Z ian $");
   83 
   84 #include "opt_compat.h"
   85 #include "opt_ddb.h"
   86 #include "opt_kstack_pages.h"
   87 #include "opt_platform.h"
   88 
   89 #include <sys/cdefs.h>
   90 #include <sys/types.h>
   91 #include <sys/param.h>
   92 #include <sys/proc.h>
   93 #include <sys/systm.h>
   94 #include <sys/time.h>
   95 #include <sys/bio.h>
   96 #include <sys/buf.h>
   97 #include <sys/bus.h>
   98 #include <sys/cons.h>
   99 #include <sys/cpu.h>
  100 #include <sys/kdb.h>
  101 #include <sys/kernel.h>
  102 #include <sys/lock.h>
  103 #include <sys/mutex.h>
  104 #include <sys/rwlock.h>
  105 #include <sys/sysctl.h>
  106 #include <sys/exec.h>
  107 #include <sys/ktr.h>
  108 #include <sys/syscallsubr.h>
  109 #include <sys/sysproto.h>
  110 #include <sys/signalvar.h>
  111 #include <sys/sysent.h>
  112 #include <sys/imgact.h>
  113 #include <sys/msgbuf.h>
  114 #include <sys/ptrace.h>
  115 
  116 #include <vm/vm.h>
  117 #include <vm/pmap.h>
  118 #include <vm/vm_page.h>
  119 #include <vm/vm_object.h>
  120 #include <vm/vm_pager.h>
  121 
  122 #include <machine/cpu.h>
  123 #include <machine/kdb.h>
  124 #include <machine/reg.h>
  125 #include <machine/vmparam.h>
  126 #include <machine/spr.h>
  127 #include <machine/hid.h>
  128 #include <machine/psl.h>
  129 #include <machine/trap.h>
  130 #include <machine/md_var.h>
  131 #include <machine/mmuvar.h>
  132 #include <machine/sigframe.h>
  133 #include <machine/machdep.h>
  134 #include <machine/metadata.h>
  135 #include <machine/platform.h>
  136 
  137 #include <sys/linker.h>
  138 #include <sys/reboot.h>
  139 
  140 #include <contrib/libfdt/libfdt.h>
  141 #include <dev/fdt/fdt_common.h>
  142 #include <dev/ofw/openfirm.h>
  143 
  144 #ifdef DDB
  145 extern vm_offset_t ksym_start, ksym_end;
  146 #endif
  147 
  148 #ifdef  DEBUG
  149 #define debugf(fmt, args...) printf(fmt, ##args)
  150 #else
  151 #define debugf(fmt, args...)
  152 #endif
  153 
  154 extern unsigned char kernel_text[];
  155 extern unsigned char _etext[];
  156 extern unsigned char _edata[];
  157 extern unsigned char __bss_start[];
  158 extern unsigned char __sbss_start[];
  159 extern unsigned char __sbss_end[];
  160 extern unsigned char _end[];
  161 
  162 /*
  163  * Bootinfo is passed to us by legacy loaders. Save the address of the
  164  * structure to handle backward compatibility.
  165  */
  166 uint32_t *bootinfo;
  167 
  168 struct kva_md_info kmi;
  169 struct pcpu __pcpu[MAXCPU];
  170 struct trapframe frame0;
  171 int cold = 1;
  172 long realmem = 0;
  173 long Maxmem = 0;
  174 char machine[] = "powerpc";
  175 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
  176 
  177 int cacheline_size = 32;
  178 
  179 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
  180            CTLFLAG_RD, &cacheline_size, 0, "");
  181 
  182 int hw_direct_map = 0;
  183 
  184 static void cpu_booke_startup(void *);
  185 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_booke_startup, NULL);
  186 
  187 void print_kernel_section_addr(void);
  188 void print_kenv(void);
  189 u_int booke_init(uint32_t, uint32_t);
  190 
  191 extern int elf32_nxstack;
  192 
  193 static void
  194 cpu_booke_startup(void *dummy)
  195 {
  196         int indx;
  197         unsigned long size;
  198 
  199         /* Initialise the decrementer-based clock. */
  200         decr_init();
  201 
  202         /* Good {morning,afternoon,evening,night}. */
  203         cpu_setup(PCPU_GET(cpuid));
  204 
  205         printf("real memory  = %lu (%ld MB)\n", ptoa(physmem),
  206             ptoa(physmem) / 1048576);
  207         realmem = physmem;
  208 
  209         /* Display any holes after the first chunk of extended memory. */
  210         if (bootverbose) {
  211                 printf("Physical memory chunk(s):\n");
  212                 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
  213                         size = phys_avail[indx + 1] - phys_avail[indx];
  214 
  215                         printf("0x%08x - 0x%08x, %lu bytes (%lu pages)\n",
  216                             phys_avail[indx], phys_avail[indx + 1] - 1,
  217                             size, size / PAGE_SIZE);
  218                 }
  219         }
  220 
  221         vm_ksubmap_init(&kmi);
  222 
  223         printf("avail memory = %lu (%ld MB)\n", ptoa(cnt.v_free_count),
  224             ptoa(cnt.v_free_count) / 1048576);
  225 
  226         /* Set up buffers, so they can be used to read disk labels. */
  227         bufinit();
  228         vm_pager_bufferinit();
  229 
  230         /* Cpu supports execution permissions on the pages. */
  231         elf32_nxstack = 1;
  232 }
  233 
  234 static char *
  235 kenv_next(char *cp)
  236 {
  237 
  238         if (cp != NULL) {
  239                 while (*cp != 0)
  240                         cp++;
  241                 cp++;
  242                 if (*cp == 0)
  243                         cp = NULL;
  244         }
  245         return (cp);
  246 }
  247 
  248 void
  249 print_kenv(void)
  250 {
  251         int len;
  252         char *cp;
  253 
  254         debugf("loader passed (static) kenv:\n");
  255         if (kern_envp == NULL) {
  256                 debugf(" no env, null ptr\n");
  257                 return;
  258         }
  259         debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp);
  260 
  261         len = 0;
  262         for (cp = kern_envp; cp != NULL; cp = kenv_next(cp))
  263                 debugf(" %x %s\n", (u_int32_t)cp, cp);
  264 }
  265 
  266 void
  267 print_kernel_section_addr(void)
  268 {
  269 
  270         debugf("kernel image addresses:\n");
  271         debugf(" kernel_text    = 0x%08x\n", (uint32_t)kernel_text);
  272         debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext);
  273         debugf(" _edata         = 0x%08x\n", (uint32_t)_edata);
  274         debugf(" __sbss_start   = 0x%08x\n", (uint32_t)__sbss_start);
  275         debugf(" __sbss_end     = 0x%08x\n", (uint32_t)__sbss_end);
  276         debugf(" __sbss_start   = 0x%08x\n", (uint32_t)__bss_start);
  277         debugf(" _end           = 0x%08x\n", (uint32_t)_end);
  278 }
  279 
  280 static int
  281 booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp)
  282 {
  283         void *ptr;
  284 
  285         if (arg1 % 8 != 0)
  286                 return (-1);
  287 
  288         ptr = (void *)pmap_early_io_map(arg1, PAGE_SIZE);
  289         if (fdt_check_header(ptr) != 0)
  290                 return (-1);
  291 
  292         *dtbp = (vm_offset_t)ptr;
  293 
  294         return (0);
  295 }
  296 
  297 u_int
  298 booke_init(uint32_t arg1, uint32_t arg2)
  299 {
  300         struct pcpu *pc;
  301         void *kmdp, *mdp;
  302         vm_offset_t dtbp, end;
  303 
  304         kmdp = NULL;
  305 
  306         end = (uintptr_t)_end;
  307         dtbp = (vm_offset_t)NULL;
  308 
  309         /* Set up TLB initially */
  310         bootinfo = NULL;
  311         tlb1_init();
  312 
  313         /*
  314          * Handle the various ways we can get loaded and started:
  315          *  -   FreeBSD's loader passes the pointer to the metadata
  316          *      in arg1, with arg2 undefined. arg1 has a value that's
  317          *      relative to the kernel's link address (i.e. larger
  318          *      than 0xc0000000).
  319          *  -   Juniper's loader passes the metadata pointer in arg2
  320          *      and sets arg1 to zero. This is to signal that the
  321          *      loader maps the kernel and starts it at its link
  322          *      address (unlike the FreeBSD loader).
  323          *  -   U-Boot passes the standard argc and argv parameters
  324          *      in arg1 and arg2 (resp). arg1 is between 1 and some
  325          *      relatively small number, such as 64K. arg2 is the
  326          *      physical address of the argv vector.
  327          *  -   ePAPR loaders pass an FDT blob in r3 (arg1) and the magic hex
  328          *      string 0x45504150 ('ePAP') in r6 (which has been lost by now).
  329          *      r4 (arg2) is supposed to be set to zero, but is not always.
  330          */
  331         
  332         if (arg1 == 0)                          /* Juniper loader */
  333                 mdp = (void *)arg2;
  334         else if (booke_check_for_fdt(arg1, &dtbp) == 0) { /* ePAPR */
  335                 end = roundup(end, 8);
  336                 memmove((void *)end, (void *)dtbp, fdt_totalsize((void *)dtbp));
  337                 dtbp = end;
  338                 end += fdt_totalsize((void *)dtbp);
  339                 mdp = NULL;
  340         } else if (arg1 > (uintptr_t)kernel_text)       /* FreeBSD loader */
  341                 mdp = (void *)arg1;
  342         else                                    /* U-Boot */
  343                 mdp = NULL;
  344 
  345         /*
  346          * Parse metadata and fetch parameters.
  347          */
  348         if (mdp != NULL) {
  349                 preload_metadata = mdp;
  350                 kmdp = preload_search_by_type("elf kernel");
  351                 if (kmdp != NULL) {
  352                         boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
  353                         kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
  354                         dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t);
  355                         end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
  356 
  357                         bootinfo = (uint32_t *)preload_search_info(kmdp,
  358                             MODINFO_METADATA | MODINFOMD_BOOTINFO);
  359 
  360 #ifdef DDB
  361                         ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
  362                         ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
  363 #endif
  364                 }
  365         } else {
  366                 bzero(__sbss_start, __sbss_end - __sbss_start);
  367                 bzero(__bss_start, _end - __bss_start);
  368         }
  369 
  370 #if defined(FDT_DTB_STATIC)
  371         /*
  372          * In case the device tree blob was not retrieved (from metadata) try
  373          * to use the statically embedded one.
  374          */
  375         if (dtbp == (vm_offset_t)NULL)
  376                 dtbp = (vm_offset_t)&fdt_static_dtb;
  377 #endif
  378 
  379         if (OF_install(OFW_FDT, 0) == FALSE)
  380                 while (1);
  381 
  382         if (OF_init((void *)dtbp) != 0)
  383                 while (1);
  384 
  385         OF_interpret("perform-fixup", 0);
  386         
  387         /* Reset TLB1 to get rid of temporary mappings */
  388         tlb1_init();
  389 
  390         /* Reset Time Base */
  391         mttb(0);
  392 
  393         /* Init params/tunables that can be overridden by the loader. */
  394         init_param1();
  395 
  396         /* Start initializing proc0 and thread0. */
  397         proc_linkup0(&proc0, &thread0);
  398         thread0.td_frame = &frame0;
  399 
  400         /* Set up per-cpu data and store the pointer in SPR general 0. */
  401         pc = &__pcpu[0];
  402         pcpu_init(pc, 0, sizeof(struct pcpu));
  403         pc->pc_curthread = &thread0;
  404 #ifdef __powerpc64__
  405         __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread));
  406 #else
  407         __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread));
  408 #endif
  409         __asm __volatile("mtsprg 0, %0" :: "r"(pc));
  410 
  411         /* Initialize system mutexes. */
  412         mutex_init();
  413 
  414         /* Initialize the console before printing anything. */
  415         cninit();
  416 
  417         /* Print out some debug info... */
  418         debugf("%s: console initialized\n", __func__);
  419         debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp);
  420         debugf(" end = 0x%08x\n", (u_int32_t)end);
  421         debugf(" boothowto = 0x%08x\n", boothowto);
  422         debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA);
  423         debugf(" MSR = 0x%08x\n", mfmsr());
  424 #if defined(BOOKE_E500)
  425         debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0));
  426         debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1));
  427         debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR));
  428 #endif
  429 
  430         debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp);
  431 
  432         print_kernel_section_addr();
  433         print_kenv();
  434 #if defined(BOOKE_E500)
  435         //tlb1_print_entries();
  436         //tlb1_print_tlbentries();
  437 #endif
  438 
  439         kdb_init();
  440 
  441 #ifdef KDB
  442         if (boothowto & RB_KDB)
  443                 kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
  444 #endif
  445 
  446         /* Initialise platform module */
  447         platform_probe_and_attach();
  448 
  449         /* Initialise virtual memory. */
  450         pmap_mmu_install(MMU_TYPE_BOOKE, 0);
  451         pmap_bootstrap((uintptr_t)kernel_text, end);
  452         pmap_bootstrapped = 1;
  453         debugf("MSR = 0x%08x\n", mfmsr());
  454 #if defined(BOOKE_E500)
  455         //tlb1_print_entries();
  456         //tlb1_print_tlbentries();
  457 #endif
  458 
  459         /* Initialize params/tunables that are derived from memsize. */
  460         init_param2(physmem);
  461 
  462         /* Finish setting up thread0. */
  463         thread0.td_pcb = (struct pcb *)
  464             ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
  465             sizeof(struct pcb)) & ~15);
  466         bzero((void *)thread0.td_pcb, sizeof(struct pcb));
  467         pc->pc_curpcb = thread0.td_pcb;
  468 
  469         /* Initialise the message buffer. */
  470         msgbufinit(msgbufp, msgbufsize);
  471 
  472         /* Enable Machine Check interrupt. */
  473         mtmsr(mfmsr() | PSL_ME);
  474         isync();
  475 
  476         /* Enable L1 caches */
  477         booke_enable_l1_cache();
  478 
  479         debugf("%s: SP = 0x%08x\n", __func__,
  480             ((uintptr_t)thread0.td_pcb - 16) & ~15);
  481 
  482         return (((uintptr_t)thread0.td_pcb - 16) & ~15);
  483 }
  484 
  485 #define RES_GRANULE 32
  486 extern uint32_t tlb0_miss_locks[];
  487 
  488 /* Initialise a struct pcpu. */
  489 void
  490 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
  491 {
  492 
  493         pcpu->pc_tid_next = TID_MIN;
  494 
  495 #ifdef SMP
  496         uint32_t *ptr;
  497         int words_per_gran = RES_GRANULE / sizeof(uint32_t);
  498 
  499         ptr = &tlb0_miss_locks[cpuid * words_per_gran];
  500         pcpu->pc_booke_tlb_lock = ptr;
  501         *ptr = TLB_UNLOCKED;
  502         *(ptr + 1) = 0;         /* recurse counter */
  503 #endif
  504 }
  505 
  506 /*
  507  * Flush the D-cache for non-DMA I/O so that the I-cache can
  508  * be made coherent later.
  509  */
  510 void
  511 cpu_flush_dcache(void *ptr, size_t len)
  512 {
  513         register_t addr, off;
  514 
  515         /*
  516          * Align the address to a cacheline and adjust the length
  517          * accordingly. Then round the length to a multiple of the
  518          * cacheline for easy looping.
  519          */
  520         addr = (uintptr_t)ptr;
  521         off = addr & (cacheline_size - 1);
  522         addr -= off;
  523         len = (len + off + cacheline_size - 1) & ~(cacheline_size - 1);
  524 
  525         while (len > 0) {
  526                 __asm __volatile ("dcbf 0,%0" :: "r"(addr));
  527                 __asm __volatile ("sync");
  528                 addr += cacheline_size;
  529                 len -= cacheline_size;
  530         }
  531 }
  532 
  533 void
  534 spinlock_enter(void)
  535 {
  536         struct thread *td;
  537         register_t msr;
  538 
  539         td = curthread;
  540         if (td->td_md.md_spinlock_count == 0) {
  541                 msr = intr_disable();
  542                 td->td_md.md_spinlock_count = 1;
  543                 td->td_md.md_saved_msr = msr;
  544         } else
  545                 td->td_md.md_spinlock_count++;
  546         critical_enter();
  547 }
  548 
  549 void
  550 spinlock_exit(void)
  551 {
  552         struct thread *td;
  553         register_t msr;
  554 
  555         td = curthread;
  556         critical_exit();
  557         msr = td->td_md.md_saved_msr;
  558         td->td_md.md_spinlock_count--;
  559         if (td->td_md.md_spinlock_count == 0)
  560                 intr_restore(msr);
  561 }
  562 
  563 /* Shutdown the CPU as much as possible. */
  564 void
  565 cpu_halt(void)
  566 {
  567 
  568         mtmsr(mfmsr() & ~(PSL_CE | PSL_EE | PSL_ME | PSL_DE));
  569         while (1)
  570                 ;
  571 }
  572 
  573 int
  574 ptrace_set_pc(struct thread *td, unsigned long addr)
  575 {
  576         struct trapframe *tf;
  577 
  578         tf = td->td_frame;
  579         tf->srr0 = (register_t)addr;
  580 
  581         return (0);
  582 }
  583 
  584 int
  585 ptrace_single_step(struct thread *td)
  586 {
  587         struct trapframe *tf;
  588 
  589         tf = td->td_frame;
  590         tf->srr1 |= PSL_DE;
  591         tf->cpu.booke.dbcr0 |= (DBCR0_IDM | DBCR0_IC);
  592         return (0);
  593 }
  594 
  595 int
  596 ptrace_clear_single_step(struct thread *td)
  597 {
  598         struct trapframe *tf;
  599 
  600         tf = td->td_frame;
  601         tf->srr1 &= ~PSL_DE;
  602         tf->cpu.booke.dbcr0 &= ~(DBCR0_IDM | DBCR0_IC);
  603         return (0);
  604 }
  605 
  606 void
  607 kdb_cpu_clear_singlestep(void)
  608 {
  609         register_t r;
  610 
  611         r = mfspr(SPR_DBCR0);
  612         mtspr(SPR_DBCR0, r & ~DBCR0_IC);
  613         kdb_frame->srr1 &= ~PSL_DE;
  614 }
  615 
  616 void
  617 kdb_cpu_set_singlestep(void)
  618 {
  619         register_t r;
  620 
  621         r = mfspr(SPR_DBCR0);
  622         mtspr(SPR_DBCR0, r | DBCR0_IC | DBCR0_IDM);
  623         kdb_frame->srr1 |= PSL_DE;
  624 }
  625 
  626 void
  627 bzero(void *buf, size_t len)
  628 {
  629         caddr_t p;
  630 
  631         p = buf;
  632 
  633         while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
  634                 *p++ = 0;
  635                 len--;
  636         }
  637 
  638         while (len >= sizeof(u_long) * 8) {
  639                 *(u_long*) p = 0;
  640                 *((u_long*) p + 1) = 0;
  641                 *((u_long*) p + 2) = 0;
  642                 *((u_long*) p + 3) = 0;
  643                 len -= sizeof(u_long) * 8;
  644                 *((u_long*) p + 4) = 0;
  645                 *((u_long*) p + 5) = 0;
  646                 *((u_long*) p + 6) = 0;
  647                 *((u_long*) p + 7) = 0;
  648                 p += sizeof(u_long) * 8;
  649         }
  650 
  651         while (len >= sizeof(u_long)) {
  652                 *(u_long*) p = 0;
  653                 len -= sizeof(u_long);
  654                 p += sizeof(u_long);
  655         }
  656 
  657         while (len) {
  658                 *p++ = 0;
  659                 len--;
  660         }
  661 }
  662 

Cache object: 54a99e9415e08e7b5c35d023c9ff4e35


[ 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.