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/mips/rmi/rmi_mips_exts.h

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) 2003-2009 RMI Corporation
    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  * 3. Neither the name of RMI Corporation, nor the names of its contributors,
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * RMI_BSD
   30  * $FreeBSD: releng/9.0/sys/mips/rmi/rmi_mips_exts.h 213441 2010-10-05 05:49:38Z jchandra $
   31  */
   32 #ifndef __MIPS_EXTS_H__
   33 #define __MIPS_EXTS_H__
   34 
   35 #define CPU_BLOCKID_IFU         0
   36 #define CPU_BLOCKID_ICU         1
   37 #define CPU_BLOCKID_IEU         2
   38 #define CPU_BLOCKID_LSU         3
   39 #define CPU_BLOCKID_MMU         4
   40 #define CPU_BLOCKID_PRF         5
   41 
   42 #define LSU_CERRLOG_REGID       9
   43 
   44 #if defined(__mips_n64) || defined(__mips_n32)
   45 static __inline uint64_t
   46 read_xlr_ctrl_register(int block, int reg)
   47 { 
   48         uint64_t res;
   49 
   50         __asm__ __volatile__(
   51             ".set       push\n\t"
   52             ".set       noreorder\n\t"
   53             "move       $9, %1\n\t"
   54             ".word      0x71280018\n\t"  /* mfcr $8, $9 */
   55             "move       %0, $8\n\t"
   56             ".set       pop\n"
   57             : "=r" (res) : "r"((block << 8) | reg)
   58             : "$8", "$9"
   59         );
   60         return (res);
   61 }
   62 
   63 static __inline void
   64 write_xlr_ctrl_register(int block, int reg, uint64_t value)
   65 {
   66         __asm__ __volatile__(
   67             ".set       push\n\t"
   68             ".set       noreorder\n\t"
   69             "move       $8, %0\n"
   70             "move       $9, %1\n"
   71             ".word      0x71280019\n"    /* mtcr $8, $9  */
   72             ".set       pop\n"
   73             :
   74             : "r" (value), "r" ((block << 8) | reg)
   75             : "$8", "$9"
   76         );
   77 }
   78 
   79 #else /* !(defined(__mips_n64) || defined(__mips_n32)) */
   80 
   81 static __inline uint64_t
   82 read_xlr_ctrl_register(int block, int reg)
   83 {       
   84         uint32_t high, low;
   85 
   86         __asm__ __volatile__(
   87             ".set       push\n\t"
   88             ".set       noreorder\n\t"
   89             ".set       mips64\n\t"
   90             "move       $9, %2\n"
   91             ".word      0x71280018\n"  /* "mfcr    $8, $9\n" */
   92             "dsra32     %0, $8, 0\n\t"
   93             "sll        %1, $8, 0\n\t"
   94             ".set       pop"                                    
   95             : "=r" (high), "=r"(low)
   96             : "r" ((block << 8) | reg)
   97             : "$8", "$9");
   98 
   99         return ( (((uint64_t)high) << 32) | low);
  100 }
  101 
  102 static __inline void
  103 write_xlr_ctrl_register(int block, int reg, uint64_t value)
  104 {
  105         uint32_t low, high;
  106         high = value >> 32;
  107         low = value & 0xffffffff;
  108 
  109         __asm__ __volatile__(
  110            ".set        push\n\t"
  111            ".set        noreorder\n\t"
  112            ".set        mips64\n\t"
  113            "dsll32      $9, %0, 0\n\t"
  114            "dsll32      $8, %1, 0\n\t"
  115            "dsrl32      $8, $8, 0\n\t"
  116            "or          $8, $9, $8\n\t"
  117            "move        $9, %2\n\t"
  118            ".word       0x71280019\n\t" /* mtcr $8, $9 */
  119            ".set        pop\n"
  120            :  /* No outputs */
  121            : "r" (high), "r" (low), "r"((block << 8) | reg)
  122            : "$8", "$9");
  123 }
  124 #endif /* defined(__mips_n64) || defined(__mips_n32) */
  125 
  126 /*
  127  * 32 bit read write for c0
  128  */
  129 #define read_c0_register32(reg, sel)                            \
  130 ({                                                              \
  131          uint32_t __rv;                                         \
  132         __asm__ __volatile__(                                   \
  133             ".set       push\n\t"                               \
  134             ".set       mips32\n\t"                             \
  135             "mfc0       %0, $%1, %2\n\t"                        \
  136             ".set       pop\n"                                  \
  137             : "=r" (__rv) : "i" (reg), "i" (sel) );             \
  138         __rv;                                                   \
  139  })
  140 
  141 #define write_c0_register32(reg,  sel, value)                   \
  142         __asm__ __volatile__(                                   \
  143             ".set       push\n\t"                               \
  144             ".set       mips32\n\t"                             \
  145             "mtc0       %0, $%1, %2\n\t"                        \
  146             ".set       pop\n"                                  \
  147         : : "r" (value), "i" (reg), "i" (sel) );
  148 
  149 #define read_c2_register32(reg, sel)                            \
  150 ({                                                              \
  151         uint32_t __rv;                                          \
  152         __asm__ __volatile__(                                   \
  153             ".set       push\n\t"                               \
  154             ".set       mips32\n\t"                             \
  155             "mfc2       %0, $%1, %2\n\t"                        \
  156             ".set       pop\n"                                  \
  157             : "=r" (__rv) : "i" (reg), "i" (sel) );             \
  158         __rv;                                                   \
  159  })
  160 
  161 #define write_c2_register32(reg,  sel, value)                   \
  162         __asm__ __volatile__(                                   \
  163             ".set       push\n\t"                               \
  164             ".set       mips32\n\t"                             \
  165             "mtc2       %0, $%1, %2\n\t"                        \
  166             ".set       pop\n"                                  \
  167         : : "r" (value), "i" (reg), "i" (sel) );
  168 
  169 #if defined(__mips_n64) || defined(__mips_n32)
  170 /*
  171  * On 64 bit compilation, the operations are simple
  172  */
  173 #define read_c0_register64(reg, sel)                            \
  174 ({                                                              \
  175         uint64_t __rv;                                          \
  176         __asm__ __volatile__(                                   \
  177             ".set       push\n\t"                               \
  178             ".set       mips64\n\t"                             \
  179             "dmfc0      %0, $%1, %2\n\t"                        \
  180             ".set       pop\n"                                  \
  181             : "=r" (__rv) : "i" (reg), "i" (sel) );             \
  182         __rv;                                                   \
  183  })
  184 
  185 #define write_c0_register64(reg,  sel, value)                   \
  186         __asm__ __volatile__(                                   \
  187             ".set       push\n\t"                               \
  188             ".set       mips64\n\t"                             \
  189             "dmtc0      %0, $%1, %2\n\t"                        \
  190             ".set       pop\n"                                  \
  191         : : "r" (value), "i" (reg), "i" (sel) );
  192 
  193 #define read_c2_register64(reg, sel)                            \
  194 ({                                                              \
  195         uint64_t __rv;                                          \
  196         __asm__ __volatile__(                                   \
  197             ".set       push\n\t"                               \
  198             ".set       mips64\n\t"                             \
  199             "dmfc2      %0, $%1, %2\n\t"                        \
  200             ".set       pop\n"                                  \
  201             : "=r" (__rv) : "i" (reg), "i" (sel) );             \
  202         __rv;                                                   \
  203  })
  204 
  205 #define write_c2_register64(reg,  sel, value)                   \
  206         __asm__ __volatile__(                                   \
  207             ".set       push\n\t"                               \
  208             ".set       mips64\n\t"                             \
  209             "dmtc2      %0, $%1, %2\n\t"                        \
  210             ".set       pop\n"                                  \
  211         : : "r" (value), "i" (reg), "i" (sel) );
  212 
  213 #else /* ! (defined(__mips_n64) || defined(__mips_n32)) */
  214 
  215 /*
  216  * 32 bit compilation, 64 bit values has to split 
  217  */
  218 #define read_c0_register64(reg, sel)                            \
  219 ({                                                              \
  220         uint32_t __high, __low;                                 \
  221         __asm__ __volatile__(                                   \
  222             ".set       push\n\t"                               \
  223             ".set       noreorder\n\t"                          \
  224             ".set       mips64\n\t"                             \
  225             "dmfc0      $8, $%2, %3\n\t"                        \
  226             "dsra32     %0, $8, 0\n\t"                          \
  227             "sll        %1, $8, 0\n\t"                          \
  228             ".set       pop\n"                                  \
  229             : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel)     \
  230             : "$8");                                            \
  231         ((uint64_t)__high << 32) | __low;                       \
  232 })
  233 
  234 #define write_c0_register64(reg, sel, value)                    \
  235 do {                                                            \
  236        uint32_t __high = value >> 32;                           \
  237        uint32_t __low = value & 0xffffffff;                     \
  238         __asm__ __volatile__(                                   \
  239             ".set       push\n\t"                               \
  240             ".set       noreorder\n\t"                          \
  241             ".set       mips64\n\t"                             \
  242             "dsll32     $8, %1, 0\n\t"                          \
  243             "dsll32     $9, %0, 0\n\t"                          \
  244             "dsrl32     $8, $8, 0\n\t"                          \
  245             "or         $8, $8, $9\n\t"                         \
  246             "dmtc0      $8, $%2, %3\n\t"                        \
  247             ".set       pop"                                    \
  248             :: "r"(__high), "r"(__low),  "i"(reg), "i"(sel)     \
  249             :"$8", "$9");                                       \
  250 } while(0)
  251 
  252 #define read_c2_register64(reg, sel)                            \
  253 ({                                                              \
  254         uint32_t __high, __low;                                 \
  255         __asm__ __volatile__(                                   \
  256             ".set       push\n\t"                               \
  257             ".set       noreorder\n\t"                          \
  258             ".set       mips64\n\t"                             \
  259             "dmfc2      $8, $%2, %3\n\t"                        \
  260             "dsra32     %0, $8, 0\n\t"                          \
  261             "sll        %1, $8, 0\n\t"                          \
  262             ".set       pop\n"                                  \
  263             : "=r"(__high), "=r"(__low): "i"(reg), "i"(sel)     \
  264             : "$8");                                            \
  265         ((uint64_t)__high << 32) | __low;                       \
  266 })
  267 
  268 #define write_c2_register64(reg, sel, value)                    \
  269 do {                                                            \
  270        uint32_t __high = value >> 32;                           \
  271        uint32_t __low = value & 0xffffffff;                     \
  272         __asm__ __volatile__(                                   \
  273             ".set       push\n\t"                               \
  274             ".set       noreorder\n\t"                          \
  275             ".set       mips64\n\t"                             \
  276             "dsll32     $8, %1, 0\n\t"                          \
  277             "dsll32     $9, %0, 0\n\t"                          \
  278             "dsrl32     $8, $8, 0\n\t"                          \
  279             "or         $8, $8, $9\n\t"                         \
  280             "dmtc2      $8, $%2, %3\n\t"                        \
  281             ".set       pop"                                    \
  282             :: "r"(__high), "r"(__low),  "i"(reg), "i"(sel)     \
  283             :"$8", "$9");                                       \
  284 } while(0)
  285 
  286 #endif /* defined(__mips_n64) || defined(__mips_n32) */
  287 
  288 static __inline int
  289 xlr_cpu_id(void)
  290 {
  291 
  292         return (read_c0_register32(15, 1) & 0x1f);
  293 }
  294 
  295 static __inline int
  296 xlr_core_id(void)
  297 {
  298 
  299         return (xlr_cpu_id() / 4);
  300 }
  301 
  302 static __inline int
  303 xlr_thr_id(void)
  304 {
  305 
  306         return (read_c0_register32(15, 1) & 0x3);
  307 }
  308 
  309 /* Additional registers on the XLR */
  310 #define MIPS_COP_0_OSSCRATCH    22
  311 #define XLR_CACHELINE_SIZE      32
  312 
  313 /* functions to write to and read from the extended
  314  * cp0 registers.
  315  * EIRR : Extended Interrupt Request Register
  316  *        cp0 register 9 sel 6
  317  *        bits 0...7 are same as cause register 8...15
  318  * EIMR : Extended Interrupt Mask Register
  319  *        cp0 register 9 sel 7
  320  *        bits 0...7 are same as status register 8...15
  321  */
  322 static __inline uint64_t 
  323 read_c0_eirr64(void)
  324 {
  325 
  326         return (read_c0_register64(9, 6));
  327 }
  328 
  329 static __inline void
  330 write_c0_eirr64(uint64_t val)
  331 {
  332 
  333         write_c0_register64(9, 6, val);
  334 }
  335 
  336 static __inline uint64_t 
  337 read_c0_eimr64(void)
  338 {
  339 
  340         return (read_c0_register64(9, 7));
  341 }
  342 
  343 static __inline void
  344 write_c0_eimr64(uint64_t val)
  345 {
  346 
  347         write_c0_register64(9, 7, val);
  348 }
  349 
  350 static __inline int 
  351 xlr_test_and_set(int *lock)
  352 {
  353         int oldval = 0;
  354 
  355         __asm__ __volatile__(
  356             ".set push\n"
  357             ".set noreorder\n"
  358             "move $9, %2\n"
  359             "li $8, 1\n"
  360             //      "swapw $8, $9\n"
  361             ".word 0x71280014\n"
  362             "move %1, $8\n"
  363             ".set pop\n"
  364             : "+m"(*lock), "=r"(oldval)
  365             : "r"((unsigned long)lock)
  366             : "$8", "$9"
  367         );
  368 
  369         return (oldval == 0 ? 1 /* success */ : 0 /* failure */);
  370 }
  371 
  372 static __inline uint32_t 
  373 xlr_mfcr(uint32_t reg)
  374 {
  375         uint32_t val;
  376 
  377         __asm__ __volatile__(
  378             "move   $8, %1\n"
  379             ".word  0x71090018\n"
  380             "move   %0, $9\n"
  381             : "=r"(val)
  382             : "r"(reg):"$8", "$9");
  383 
  384         return val;
  385 }
  386 
  387 static __inline void 
  388 xlr_mtcr(uint32_t reg, uint32_t val)
  389 {
  390         __asm__ __volatile__(
  391             "move   $8, %1\n"
  392             "move   $9, %0\n"
  393             ".word  0x71090019\n"
  394             :: "r"(val), "r"(reg)
  395             : "$8", "$9");
  396 }
  397 
  398 /*
  399  * Atomic increment a unsigned  int
  400  */
  401 static __inline unsigned int
  402 xlr_ldaddwu(unsigned int value, unsigned int *addr)
  403 {
  404         __asm__  __volatile__(
  405             ".set       push\n"
  406             ".set       noreorder\n"
  407             "move       $8, %2\n"
  408             "move       $9, %3\n"
  409             ".word      0x71280011\n"  /* ldaddwu $8, $9 */
  410             "move       %0, $8\n"
  411             ".set       pop\n"
  412             : "=&r"(value), "+m"(*addr)
  413             : ""(value), "r" ((unsigned long)addr)
  414             :  "$8", "$9");
  415 
  416         return (value);
  417 }
  418 
  419 #if defined(__mips_n64)
  420 static __inline uint32_t
  421 xlr_paddr_lw(uint64_t paddr)
  422 {
  423         
  424         paddr |= 0x9800000000000000ULL;
  425         return (*(uint32_t *)(uintptr_t)paddr);
  426 }
  427 
  428 static __inline uint64_t
  429 xlr_paddr_ld(uint64_t paddr)
  430 {
  431         
  432         paddr |= 0x9800000000000000ULL;
  433         return (*(uint64_t *)(uintptr_t)paddr);
  434 }
  435 
  436 #elif defined(__mips_n32)
  437 static __inline uint32_t
  438 xlr_paddr_lw(uint64_t paddr)
  439 {
  440         uint32_t val;
  441 
  442         paddr |= 0x9800000000000000ULL;
  443         __asm__ __volatile__(
  444             ".set       push            \n\t"
  445             ".set       mips64          \n\t"
  446             "lw         %0, 0(%1)       \n\t"
  447             ".set       pop             \n"
  448             : "=r"(val)
  449             : "r"(paddr));
  450 
  451         return (val);
  452 }
  453 
  454 static __inline uint64_t
  455 xlr_paddr_ld(uint64_t paddr)
  456 {
  457         uint64_t val;
  458 
  459         paddr |= 0x9800000000000000ULL;
  460         __asm__ __volatile__(
  461             ".set       push            \n\t"
  462             ".set       mips64          \n\t"
  463             "ld         %0, 0(%1)       \n\t"
  464             ".set       pop             \n"
  465             : "=r"(val)
  466             : "r"(paddr));
  467 
  468         return (val);
  469 }
  470 
  471 #else   /* o32 compilation */
  472 static __inline uint32_t
  473 xlr_paddr_lw(uint64_t paddr)
  474 {
  475         uint32_t addrh, addrl;
  476         uint32_t val;
  477 
  478         addrh = 0x98000000 | (paddr >> 32);
  479         addrl = paddr & 0xffffffff;
  480 
  481         __asm__ __volatile__(
  482             ".set       push            \n\t"
  483             ".set       mips64          \n\t"
  484             "dsll32     $8, %1, 0       \n\t"
  485             "dsll32     $9, %2, 0       \n\t"  /* get rid of the */
  486             "dsrl32     $9, $9, 0       \n\t"  /* sign extend */
  487             "or         $9, $8, $8      \n\t"
  488             "lw         %0, 0($9)       \n\t"
  489             ".set       pop             \n"
  490             :   "=r"(val)
  491             :   "r"(addrh), "r"(addrl)
  492             :   "$8", "$9");
  493 
  494         return (val);
  495 }
  496 
  497 static __inline uint64_t
  498 xlr_paddr_ld(uint64_t paddr)
  499 {
  500         uint32_t addrh, addrl;
  501         uint32_t valh, vall;
  502 
  503         addrh = 0x98000000 | (paddr >> 32);
  504         addrl = paddr & 0xffffffff;
  505 
  506         __asm__ __volatile__(
  507             ".set       push            \n\t"
  508             ".set       mips64          \n\t"
  509             "dsll32     %0, %2, 0       \n\t"
  510             "dsll32     %1, %3, 0       \n\t"  /* get rid of the */
  511             "dsrl32     %1, %1, 0       \n\t"  /* sign extend */
  512             "or         %0, %0, %1      \n\t"
  513             "lw         %1, 4(%0)       \n\t"
  514             "lw         %0, 0(%0)       \n\t"
  515             ".set       pop             \n"
  516             :       "=&r"(valh), "=&r"(vall)
  517             :       "r"(addrh), "r"(addrl));
  518 
  519         return (((uint64_t)valh << 32) | vall);
  520 }
  521 #endif
  522 
  523 /*
  524  * XXX: Not really needed in n32 or n64, retain for now
  525  */
  526 #if defined(__mips_n64) || defined(__mips_n32)
  527 static __inline uint32_t
  528 xlr_enable_kx(void)
  529 {
  530 
  531         return (0);
  532 }
  533 
  534 static __inline void
  535 xlr_restore_kx(uint32_t sr)
  536 {
  537 }
  538 
  539 #else /* !defined(__mips_n64) && !defined(__mips_n32) */
  540 /*
  541  * o32 compilation, we will disable interrupts and enable
  542  * the KX bit so that we can use XKPHYS to access any 40bit
  543  * physical address
  544  */
  545 static __inline uint32_t 
  546 xlr_enable_kx(void)
  547 {
  548         uint32_t sr = mips_rd_status();
  549 
  550         mips_wr_status((sr & ~MIPS_SR_INT_IE) | MIPS_SR_KX);
  551         return (sr);
  552 }
  553 
  554 static __inline void
  555 xlr_restore_kx(uint32_t sr)
  556 {
  557 
  558         mips_wr_status(sr);
  559 }
  560 #endif /* defined(__mips_n64) || defined(__mips_n32) */
  561 
  562 /*
  563  * XLR/XLS processors have maximum 8 cores, and maximum 4 threads
  564  * per core
  565  */
  566 #define XLR_MAX_CORES           8
  567 #define XLR_NTHREADS            4
  568 
  569 /*
  570  * FreeBSD can be started with few threads and cores turned off,
  571  * so have a hardware thread id to FreeBSD cpuid mapping.
  572  */
  573 extern int xlr_ncores;
  574 extern int xlr_threads_per_core;
  575 extern uint32_t xlr_hw_thread_mask;
  576 extern int xlr_cpuid_to_hwtid[];
  577 extern int xlr_hwtid_to_cpuid[];
  578 
  579 #endif

Cache object: ea1c32cd8fc069b4828529f9821ea955


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