Subversion Repositories HelenOS

Rev

Rev 1884 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2006 Jakub Jermar
  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.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup sparc64
  30.  * @{
  31.  */
  32. /** @file
  33.  *
  34.  */
  35.  
  36. #include <fpu_context.h>
  37. #include <arch/register.h>
  38. #include <arch/asm.h>
  39.  
  40. void fpu_context_save(fpu_context_t *fctx)
  41. {
  42.     fprs_reg_t fprs;
  43.    
  44.     fprs.value = fprs_read();
  45.  
  46.     if (fprs.dl) {
  47.         /*
  48.          * The lower half of floating-point registers is dirty.
  49.          * Spill it to memory.
  50.          */
  51.         __asm__ volatile (
  52.             "std %%f0, %0\n"
  53.             "std %%f2, %1\n"
  54.             "std %%f4, %2\n"
  55.             "std %%f6, %3\n"
  56.             "std %%f8, %4\n"
  57.             "std %%f10, %5\n"
  58.             "std %%f12, %6\n"
  59.             "std %%f14, %7\n"
  60.             "std %%f16, %8\n"
  61.             "std %%f18, %9\n"
  62.             "std %%f20, %10\n"
  63.             "std %%f22, %11\n"
  64.             "std %%f24, %12\n"
  65.             "std %%f26, %13\n"
  66.             "std %%f28, %14\n"
  67.             "std %%f30, %15\n"
  68.             : "=m" (fctx->d[0]), "=m" (fctx->d[1]), "=m" (fctx->d[2]), "=m" (fctx->d[3]),
  69.               "=m" (fctx->d[4]), "=m" (fctx->d[5]), "=m" (fctx->d[6]), "=m" (fctx->d[7]),
  70.               "=m" (fctx->d[8]), "=m" (fctx->d[9]), "=m" (fctx->d[10]), "=m" (fctx->d[11]),
  71.               "=m" (fctx->d[12]), "=m" (fctx->d[13]), "=m" (fctx->d[14]), "=m" (fctx->d[15])
  72.         );
  73.         fprs.dl = false;
  74.     }
  75.    
  76.     if (fprs.du) { 
  77.         /*
  78.          * The upper half of floating-point registers is dirty.
  79.          * Spill it to memory.
  80.          */
  81.         __asm__ volatile (
  82.             "std %%f32, %0\n"
  83.             "std %%f34, %1\n"
  84.             "std %%f36, %2\n"
  85.             "std %%f38, %3\n"
  86.             "std %%f40, %4\n"
  87.             "std %%f42, %5\n"
  88.             "std %%f44, %6\n"
  89.             "std %%f46, %7\n"
  90.             "std %%f48, %8\n"
  91.             "std %%f50, %9\n"
  92.             "std %%f52, %10\n"
  93.             "std %%f54, %11\n"
  94.             "std %%f56, %12\n"
  95.             "std %%f58, %13\n"
  96.             "std %%f60, %14\n"
  97.             "std %%f62, %15\n"
  98.             : "=m" (fctx->d[16]), "=m" (fctx->d[17]), "=m" (fctx->d[18]), "=m" (fctx->d[19]),
  99.               "=m" (fctx->d[20]), "=m" (fctx->d[21]), "=m" (fctx->d[22]), "=m" (fctx->d[23]),
  100.               "=m" (fctx->d[24]), "=m" (fctx->d[25]), "=m" (fctx->d[26]), "=m" (fctx->d[27]),
  101.               "=m" (fctx->d[28]), "=m" (fctx->d[29]), "=m" (fctx->d[30]), "=m" (fctx->d[31])
  102.         );
  103.         fprs.du = false;
  104.     }
  105.    
  106.     fprs_write(fprs.value);
  107.    
  108.     __asm__ volatile ("stx %%fsr, %0\n" : "=m" (fctx->fsr));
  109. }
  110.  
  111. void fpu_context_restore(fpu_context_t *fctx)
  112. {
  113.     fprs_reg_t fprs;
  114.    
  115.     fprs.value = fprs_read();
  116.    
  117.     __asm__ volatile (
  118.         "ldd %0, %%f0\n"
  119.         "ldd %1, %%f2\n"
  120.         "ldd %2, %%f4\n"
  121.         "ldd %3, %%f6\n"
  122.         "ldd %4, %%f8\n"
  123.         "ldd %5, %%f10\n"
  124.         "ldd %6, %%f12\n"
  125.         "ldd %7, %%f14\n"
  126.         "ldd %8, %%f16\n"
  127.         "ldd %9, %%f18\n"
  128.         "ldd %10, %%f20\n"
  129.         "ldd %11, %%f22\n"
  130.         "ldd %12, %%f24\n"
  131.         "ldd %13, %%f26\n"
  132.         "ldd %14, %%f28\n"
  133.         "ldd %15, %%f30\n"
  134.         :
  135.         : "m" (fctx->d[0]), "m" (fctx->d[1]), "m" (fctx->d[2]), "m" (fctx->d[3]),
  136.           "m" (fctx->d[4]), "m" (fctx->d[5]), "m" (fctx->d[6]), "m" (fctx->d[7]),
  137.           "m" (fctx->d[8]), "m" (fctx->d[9]), "m" (fctx->d[10]), "m" (fctx->d[11]),
  138.           "m" (fctx->d[12]), "m" (fctx->d[13]), "m" (fctx->d[14]), "m" (fctx->d[15])
  139.     );
  140.    
  141.     /*
  142.      * We need to split loading of the floating-point registers because
  143.      * GCC (4.1.1) can't handle more than 30 operands in one asm statement.
  144.      */
  145.    
  146.     __asm__ volatile (
  147.         "ldd %0, %%f32\n"
  148.         "ldd %1, %%f34\n"
  149.         "ldd %2, %%f36\n"
  150.         "ldd %3, %%f38\n"
  151.         "ldd %4, %%f40\n"
  152.         "ldd %5, %%f42\n"
  153.         "ldd %6, %%f44\n"
  154.         "ldd %7, %%f46\n"
  155.         "ldd %8, %%f48\n"
  156.         "ldd %9, %%f50\n"
  157.         "ldd %10, %%f52\n"
  158.         "ldd %11, %%f54\n"
  159.         "ldd %12, %%f56\n"
  160.         "ldd %13, %%f58\n"
  161.         "ldd %14, %%f60\n"
  162.         "ldd %15, %%f62\n"
  163.         :
  164.         : "m" (fctx->d[16]), "m" (fctx->d[17]), "m" (fctx->d[18]), "m" (fctx->d[19]),
  165.           "m" (fctx->d[20]), "m" (fctx->d[21]), "m" (fctx->d[22]), "m" (fctx->d[23]),
  166.           "m" (fctx->d[24]), "m" (fctx->d[25]), "m" (fctx->d[26]), "m" (fctx->d[27]),
  167.           "m" (fctx->d[28]), "m" (fctx->d[29]), "m" (fctx->d[30]), "m" (fctx->d[31])
  168.     );
  169.    
  170.     fprs.dl = fprs.du = false;
  171.     fprs_write(fprs.value);
  172.    
  173.     __asm__ volatile ("ldx %0, %%fsr\n" : : "m" (fctx->fsr));
  174. }
  175.  
  176. void fpu_enable(void)
  177. {
  178.     pstate_reg_t pstate;
  179.    
  180.     pstate.value = pstate_read();
  181.     pstate.pef = true;
  182.     pstate_write(pstate.value);
  183. }
  184.  
  185. void fpu_disable(void)
  186. {
  187.     pstate_reg_t pstate;
  188.    
  189.     pstate.value = pstate_read();
  190.     pstate.pef = false;
  191.     pstate_write(pstate.value);
  192. }
  193.  
  194. void fpu_init(void)
  195. {
  196.     fpu_enable();
  197. }
  198.  
  199. /** @}
  200.  */
  201.