Subversion Repositories HelenOS

Rev

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

  1. /*
  2.  * Copyright (c) 2005 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. #ifndef KERN_sparc64_ASM_H_
  36. #define KERN_sparc64_ASM_H_
  37.  
  38. #include <arch/arch.h>
  39. #include <arch/types.h>
  40. #include <typedefs.h>
  41. #include <align.h>
  42. #include <arch/register.h>
  43. #include <config.h>
  44. #include <arch/stack.h>
  45.  
  46. typedef uint64_t ioport_t;
  47.  
  48.  
  49. static inline void  outb(ioport_t port,uint8_t v)
  50. {
  51.     *((uint8_t *)(port)) = v;
  52. }
  53.  
  54. static inline void  outw(ioport_t port,uint16_t v)
  55. {
  56.     *((uint16_t *)(port)) = v;
  57. }
  58.  
  59. static inline void  outl(ioport_t port,uint32_t v)
  60. {
  61.     *((uint32_t *)(port)) = v;
  62. }
  63.  
  64.  
  65.  
  66. static inline uint8_t inb(ioport_t port)
  67. {
  68.     return *((uint8_t *)(port));
  69. }
  70.  
  71. static inline uint16_t inw(ioport_t port)
  72. {
  73.     return *((uint16_t *)(port));
  74. }
  75.  
  76. static inline uint32_t inl(ioport_t port)
  77. {
  78.     return *((uint32_t *)(port));
  79. }
  80.  
  81.  
  82.  
  83.  
  84.  
  85. /** Read Processor State register.
  86.  *
  87.  * @return Value of PSTATE register.
  88.  */
  89. static inline uint64_t pstate_read(void)
  90. {
  91.     uint64_t v;
  92.    
  93.     asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
  94.    
  95.     return v;
  96. }
  97.  
  98. /** Write Processor State register.
  99.  *
  100.  * @param v New value of PSTATE register.
  101.  */
  102. static inline void pstate_write(uint64_t v)
  103. {
  104.     asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
  105. }
  106.  
  107. /** Read TICK_compare Register.
  108.  *
  109.  * @return Value of TICK_comapre register.
  110.  */
  111. static inline uint64_t tick_compare_read(void)
  112. {
  113.     uint64_t v;
  114.    
  115.     asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
  116.    
  117.     return v;
  118. }
  119.  
  120. /** Write TICK_compare Register.
  121.  *
  122.  * @param v New value of TICK_comapre register.
  123.  */
  124. static inline void tick_compare_write(uint64_t v)
  125. {
  126.     asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
  127. }
  128.  
  129. /** Read TICK Register.
  130.  *
  131.  * @return Value of TICK register.
  132.  */
  133. static inline uint64_t tick_read(void)
  134. {
  135.     uint64_t v;
  136.    
  137.     asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
  138.    
  139.     return v;
  140. }
  141.  
  142. /** Write TICK Register.
  143.  *
  144.  * @param v New value of TICK register.
  145.  */
  146. static inline void tick_write(uint64_t v)
  147. {
  148.     asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
  149. }
  150.  
  151. /** Read FPRS Register.
  152.  *
  153.  * @return Value of FPRS register.
  154.  */
  155. static inline uint64_t fprs_read(void)
  156. {
  157.     uint64_t v;
  158.    
  159.     asm volatile ("rd %%fprs, %0\n" : "=r" (v));
  160.    
  161.     return v;
  162. }
  163.  
  164. /** Write FPRS Register.
  165.  *
  166.  * @param v New value of FPRS register.
  167.  */
  168. static inline void fprs_write(uint64_t v)
  169. {
  170.     asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
  171. }
  172.  
  173. /** Read SOFTINT Register.
  174.  *
  175.  * @return Value of SOFTINT register.
  176.  */
  177. static inline uint64_t softint_read(void)
  178. {
  179.     uint64_t v;
  180.  
  181.     asm volatile ("rd %%softint, %0\n" : "=r" (v));
  182.  
  183.     return v;
  184. }
  185.  
  186. /** Write SOFTINT Register.
  187.  *
  188.  * @param v New value of SOFTINT register.
  189.  */
  190. static inline void softint_write(uint64_t v)
  191. {
  192.     asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
  193. }
  194.  
  195. /** Write CLEAR_SOFTINT Register.
  196.  *
  197.  * Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
  198.  *
  199.  * @param v New value of CLEAR_SOFTINT register.
  200.  */
  201. static inline void clear_softint_write(uint64_t v)
  202. {
  203.     asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
  204. }
  205.  
  206. /** Write SET_SOFTINT Register.
  207.  *
  208.  * Bits set in SET_SOFTINT register will be set in SOFTINT register.
  209.  *
  210.  * @param v New value of SET_SOFTINT register.
  211.  */
  212. static inline void set_softint_write(uint64_t v)
  213. {
  214.     asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
  215. }
  216.  
  217. /** Enable interrupts.
  218.  *
  219.  * Enable interrupts and return previous
  220.  * value of IPL.
  221.  *
  222.  * @return Old interrupt priority level.
  223.  */
  224. static inline ipl_t interrupts_enable(void) {
  225.     pstate_reg_t pstate;
  226.     uint64_t value;
  227.    
  228.     value = pstate_read();
  229.     pstate.value = value;
  230.     pstate.ie = true;
  231.     pstate_write(pstate.value);
  232.    
  233.     return (ipl_t) value;
  234. }
  235.  
  236. /** Disable interrupts.
  237.  *
  238.  * Disable interrupts and return previous
  239.  * value of IPL.
  240.  *
  241.  * @return Old interrupt priority level.
  242.  */
  243. static inline ipl_t interrupts_disable(void) {
  244.     pstate_reg_t pstate;
  245.     uint64_t value;
  246.    
  247.     value = pstate_read();
  248.     pstate.value = value;
  249.     pstate.ie = false;
  250.     pstate_write(pstate.value);
  251.    
  252.     return (ipl_t) value;
  253. }
  254.  
  255. /** Restore interrupt priority level.
  256.  *
  257.  * Restore IPL.
  258.  *
  259.  * @param ipl Saved interrupt priority level.
  260.  */
  261. static inline void interrupts_restore(ipl_t ipl) {
  262.     pstate_reg_t pstate;
  263.    
  264.     pstate.value = pstate_read();
  265.     pstate.ie = ((pstate_reg_t) ipl).ie;
  266.     pstate_write(pstate.value);
  267. }
  268.  
  269. /** Return interrupt priority level.
  270.  *
  271.  * Return IPL.
  272.  *
  273.  * @return Current interrupt priority level.
  274.  */
  275. static inline ipl_t interrupts_read(void) {
  276.     return (ipl_t) pstate_read();
  277. }
  278.  
  279. /** Return base address of current stack.
  280.  *
  281.  * Return the base address of the current stack.
  282.  * The stack is assumed to be STACK_SIZE bytes long.
  283.  * The stack must start on page boundary.
  284.  */
  285. static inline uintptr_t get_stack_base(void)
  286. {
  287.     uintptr_t unbiased_sp;
  288.    
  289.     asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
  290.    
  291.     return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
  292. }
  293.  
  294. /** Read Version Register.
  295.  *
  296.  * @return Value of VER register.
  297.  */
  298. static inline uint64_t ver_read(void)
  299. {
  300.     uint64_t v;
  301.    
  302.     asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
  303.    
  304.     return v;
  305. }
  306.  
  307. /** Read Trap Program Counter register.
  308.  *
  309.  * @return Current value in TPC.
  310.  */
  311. static inline uint64_t tpc_read(void)
  312. {
  313.     uint64_t v;
  314.    
  315.     asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
  316.    
  317.     return v;
  318. }
  319.  
  320. /** Read Trap Level register.
  321.  *
  322.  * @return Current value in TL.
  323.  */
  324. static inline uint64_t tl_read(void)
  325. {
  326.     uint64_t v;
  327.    
  328.     asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
  329.    
  330.     return v;
  331. }
  332.  
  333. /** Read Trap Base Address register.
  334.  *
  335.  * @return Current value in TBA.
  336.  */
  337. static inline uint64_t tba_read(void)
  338. {
  339.     uint64_t v;
  340.    
  341.     asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
  342.    
  343.     return v;
  344. }
  345.  
  346. /** Write Trap Base Address register.
  347.  *
  348.  * @param v New value of TBA.
  349.  */
  350. static inline void tba_write(uint64_t v)
  351. {
  352.     asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
  353. }
  354.  
  355. /** Load uint64_t from alternate space.
  356.  *
  357.  * @param asi ASI determining the alternate space.
  358.  * @param va Virtual address within the ASI.
  359.  *
  360.  * @return Value read from the virtual address in the specified address space.
  361.  */
  362. static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
  363. {
  364.     uint64_t v;
  365.    
  366.     asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
  367.    
  368.     return v;
  369. }
  370.  
  371. /** Store uint64_t to alternate space.
  372.  *
  373.  * @param asi ASI determining the alternate space.
  374.  * @param va Virtual address within the ASI.
  375.  * @param v Value to be written.
  376.  */
  377. static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
  378. {
  379.     asm volatile ("stxa %0, [%1] %2\n" : :  "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
  380. }
  381.  
  382. /** Flush all valid register windows to memory. */
  383. static inline void flushw(void)
  384. {
  385.     asm volatile ("flushw\n");
  386. }
  387.  
  388. /** Switch to nucleus by setting TL to 1. */
  389. static inline void nucleus_enter(void)
  390. {
  391.     asm volatile ("wrpr %g0, 1, %tl\n");
  392. }
  393.  
  394. /** Switch from nucleus by setting TL to 0. */
  395. static inline void nucleus_leave(void)
  396. {
  397.     asm volatile ("wrpr %g0, %g0, %tl\n");
  398. }
  399.  
  400. /** Read UPA_CONFIG register.
  401.  *
  402.  * @return Value of the UPA_CONFIG register.
  403.  */
  404. static inline uint64_t upa_config_read(void)
  405. {
  406.     return asi_u64_read(ASI_UPA_CONFIG, 0);
  407. }
  408.  
  409. extern void cpu_halt(void);
  410. extern void cpu_sleep(void);
  411. extern void asm_delay_loop(const uint32_t usec);
  412.  
  413. extern uint64_t read_from_ag_g7(void);
  414. extern void write_to_ag_g6(uint64_t val);
  415. extern void write_to_ag_g7(uint64_t val);
  416. extern void write_to_ig_g6(uint64_t val);
  417.  
  418. extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
  419.  
  420. #endif
  421.  
  422. /** @}
  423.  */
  424.