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/ofw/ofwcall32.S

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) 2009-2011 Nathan Whitehorn
    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.
   17  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   18  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   21  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   23  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  */
   27 
   28 #include <sys/syscall.h>
   29 
   30 #include <machine/trap.h>
   31 #include <machine/param.h>
   32 #include <machine/spr.h>
   33 #include <machine/asm.h>
   34 
   35 #define OFWSTKSZ        4096            /* 4K Open Firmware stack */
   36 
   37 /*
   38  * Globals
   39  */
   40         .data
   41 GLOBAL(ofmsr)
   42         .long   0, 0, 0, 0, 0           /* msr/sprg0-3 used in Open Firmware */
   43 GLOBAL(rtasmsr)
   44         .long   0
   45 GLOBAL(openfirmware_entry)
   46         .long   0                       /* Open Firmware entry point */
   47 GLOBAL(rtas_entry)
   48         .long   0                       /* RTAS entry point */
   49 
   50         .align  4
   51 ofwstk:
   52         .space  OFWSTKSZ
   53 rtas_regsave:
   54         .space  4
   55 
   56 /*
   57  * Open Firmware Entry Point. May need to enter real mode.
   58  *
   59  * C prototype: int ofwcall(void *callbuffer);
   60  */
   61 
   62 ASENTRY(ofwcall)
   63         mflr    %r0
   64         stw     %r0,4(%r1)
   65 
   66         /* Record the old MSR */
   67         mfmsr   %r6
   68 
   69         /* GOT pointer in r7 */
   70         bl      1f
   71 1:
   72         mflr    %r7
   73         addis   %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
   74         addi    %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
   75 
   76         /* read client interface handler */
   77         lwz     %r4,openfirmware_entry@got(%r7)
   78         lwz     %r4,0(%r4)
   79 
   80         /*
   81          * Set the MSR to the OF value. This has the side effect of disabling
   82          * exceptions, which prevents preemption later.
   83          */
   84 
   85         lwz     %r5,ofmsr@got(%r7)
   86         lwz     %r5,0(%r5)
   87         mtmsr   %r5
   88         isync
   89 
   90         /*
   91          * Set up OF stack. This needs to be potentially accessible in real mode
   92          * The pointer to the current kernel stack is placed at the very
   93          * top of the stack along with the old MSR so we can get them back
   94          * later.
   95          */
   96         mr      %r5,%r1
   97         lwz     %r1,ofwstk@got(%r7)
   98         addi    %r1,%r1,(OFWSTKSZ-32)
   99         stw     %r5,20(%r1)     /* Save real stack pointer */
  100         stw     %r2,24(%r1)     /* Save curthread */
  101         stw     %r6,28(%r1)     /* Save old MSR */
  102         li      %r5,0
  103         stw     %r5,4(%r1)
  104         stw     %r5,0(%r1)
  105 
  106         /* Finally, branch to OF */
  107         mtctr   %r4
  108         bctrl
  109 
  110         /* Reload stack pointer and MSR from the OFW stack */
  111         lwz     %r6,28(%r1)
  112         lwz     %r2,24(%r1)
  113         lwz     %r1,20(%r1)
  114 
  115         /* Now set the real MSR */
  116         mtmsr   %r6
  117         isync
  118 
  119         /* Return */
  120         lwz     %r0,4(%r1)
  121         mtlr    %r0
  122         blr
  123 ASEND(ofwcall)
  124 
  125 /*
  126  * RTAS Entry Point. Similar to the OF one, but simpler (no separate stack)
  127  *
  128  * C prototype: int rtascall(void *callbuffer, void *rtas_privdat);
  129  */
  130 
  131 ASENTRY(rtascall)
  132         mflr    %r0
  133         stw     %r0,4(%r1)
  134 
  135         /* GOT pointer in r7 */
  136         bl      1f
  137 1:
  138         mflr    %r7
  139         addis   %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
  140         addi    %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
  141 
  142         /* Record the old MSR to real-mode-accessible area */
  143         mfmsr   %r0
  144         lwz     %r5,rtas_regsave@got(%r7)
  145         stw     %r0,0(%r5)
  146 
  147         /* read client interface handler */
  148         lwz     %r5,rtas_entry@got(%r7)
  149         lwz     %r5,0(%r5)
  150 
  151         /* Set the MSR to the RTAS value */
  152         lwz     %r6,rtasmsr@got(%r7)
  153         lwz     %r6,0(%r6)
  154         mtmsr   %r6
  155         isync
  156 
  157         /* Branch to RTAS */
  158         mtctr   %r5
  159         bctrl
  160 
  161         /* GOT pointer in r7 */
  162         bl      1f
  163 1:
  164         mflr    %r7
  165         addis   %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@ha
  166         addi    %r7,%r7,(_GLOBAL_OFFSET_TABLE_-1b)@l
  167 
  168         /* Now set the MSR back */
  169         lwz     %r6,rtas_regsave@got(%r7)
  170         lwz     %r6,0(%r6)
  171         mtmsr   %r6
  172         isync
  173 
  174         /* And return */
  175         lwz     %r0,4(%r1)
  176         mtlr    %r0
  177         blr
  178 ASEND(rtascall)

Cache object: 0c20a2ebfbf438396e8320bf141c1e45


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