LCOV - code coverage report
Current view: top level - include - processor.h (source / functions) Hit Total Coverage
Test: skiboot.info Lines: 4 12 33.3 %
Date: 2024-01-02 21:04:04 Functions: 1 2 50.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       2                 :            : /* Copyright 2013-2019 IBM Corp. */
       3                 :            : 
       4                 :            : #ifndef __PROCESSOR_H
       5                 :            : #define __PROCESSOR_H
       6                 :            : 
       7                 :            : #include <bitutils.h>
       8                 :            : 
       9                 :            : /* MSR bits */
      10                 :            : #define MSR_SF          PPC_BIT(0)      /* 64-bit mode */
      11                 :            : #define MSR_HV          PPC_BIT(3)      /* Hypervisor mode */
      12                 :            : #define MSR_VEC         PPC_BIT(38)     /* VMX enable */
      13                 :            : #define MSR_VSX         PPC_BIT(40)     /* VSX enable */
      14                 :            : #define MSR_S           PPC_BIT(41)     /* Secure mode */
      15                 :            : #define MSR_EE          PPC_BIT(48)     /* External Int. Enable */
      16                 :            : #define MSR_PR          PPC_BIT(49)             /* Problem state */
      17                 :            : #define MSR_FP          PPC_BIT(50)     /* Floating Point Enable */
      18                 :            : #define MSR_ME          PPC_BIT(51)     /* Machine Check Enable */
      19                 :            : #define MSR_FE0         PPC_BIT(52)     /* FP Exception 0 */
      20                 :            : #define MSR_SE          PPC_BIT(53)     /* Step enable */
      21                 :            : #define MSR_BE          PPC_BIT(54)     /* Branch trace enable */
      22                 :            : #define MSR_FE1         PPC_BIT(55)     /* FP Exception 1 */
      23                 :            : #define MSR_IR          PPC_BIT(58)     /* Instructions reloc */
      24                 :            : #define MSR_DR          PPC_BIT(59)     /* Data reloc */
      25                 :            : #define MSR_PMM         PPC_BIT(61)     /* Perf Monitor */
      26                 :            : #define MSR_RI          PPC_BIT(62)     /* Recoverable Interrupt */
      27                 :            : #define MSR_LE          PPC_BIT(63)     /* Little Endian */
      28                 :            : 
      29                 :            : /* PIR */
      30                 :            : #define SPR_PIR_P10_MASK        0x7fff  /* Mask of implemented bits */
      31                 :            : #define SPR_PIR_P9_MASK         0x7fff  /* Mask of implemented bits */
      32                 :            : #define SPR_PIR_P8_MASK         0x1fff  /* Mask of implemented bits */
      33                 :            : 
      34                 :            : /* SPR register definitions */
      35                 :            : #define SPR_DSCR        0x011   /* RW: Data stream control reg */
      36                 :            : #define SPR_DSISR       0x012   /* RW: Data storage interrupt status reg */
      37                 :            : #define SPR_DAR         0x013   /* RW: Data address reg */
      38                 :            : #define SPR_DEC         0x016   /* RW: Decrement Register */
      39                 :            : #define SPR_SDR1        0x019
      40                 :            : #define SPR_SRR0        0x01a   /* RW: Exception save/restore reg 0 */
      41                 :            : #define SPR_SRR1        0x01b   /* RW: Exception save/restore reg 1 */
      42                 :            : #define SPR_CFAR        0x01c   /* RW: Come From Address Register */
      43                 :            : #define SPR_AMR         0x01d   /* RW: Authority Mask Register */
      44                 :            : #define SPR_IAMR        0x03d   /* RW: Instruction Authority Mask Register */
      45                 :            : #define SPR_RPR         0x0ba   /* RW: Relative Priority Register */
      46                 :            : #define SPR_TBRL        0x10c   /* RO: Timebase low */
      47                 :            : #define SPR_TBRU        0x10d   /* RO: Timebase high */
      48                 :            : #define SPR_SPRC        0x114   /* RW: Access to uArch SPRs (ex SCOMC) */
      49                 :            : #define SPR_SPRD        0x115   /* RW: Access to uArch SPRs (ex SCOMD) */
      50                 :            : #define SPR_SCOMC       0x114   /* RW: SCOM Control - old name of SPRC */
      51                 :            : #define SPR_SCOMD       0x115   /* RW: SCOM Data    - old name of SPRD */
      52                 :            : #define SPR_TBWL        0x11c   /* RW: Timebase low */
      53                 :            : #define SPR_TBWU        0x11d   /* RW: Timebase high */
      54                 :            : #define SPR_TBU40       0x11e   /* RW: Timebase Upper 40 bit */
      55                 :            : #define SPR_PVR         0x11f   /* RO: Processor version register */
      56                 :            : #define SPR_HSPRG0      0x130   /* RW: Hypervisor scratch 0 */
      57                 :            : #define SPR_HSPRG1      0x131   /* RW: Hypervisor scratch 1 */
      58                 :            : #define SPR_SPURR       0x134   /* RW: Scaled Processor Utilization Resource */
      59                 :            : #define SPR_PURR        0x135   /* RW: Processor Utilization Resource reg */
      60                 :            : #define SPR_HDEC        0x136   /* RW: Hypervisor Decrementer */
      61                 :            : #define SPR_HRMOR       0x139   /* RW: Hypervisor Real Mode Offset reg */
      62                 :            : #define SPR_HSRR0       0x13a   /* RW: HV Exception save/restore reg 0 */
      63                 :            : #define SPR_HSRR1       0x13b   /* RW: HV Exception save/restore reg 1 */
      64                 :            : #define SPR_TFMR        0x13d
      65                 :            : #define SPR_LPCR        0x13e
      66                 :            : #define SPR_HMER        0x150   /* Hypervisor Maintenance Exception */
      67                 :            : #define SPR_HMEER       0x151   /* HMER interrupt enable mask */
      68                 :            : #define SPR_PCR         0x152
      69                 :            : #define SPR_AMOR        0x15d
      70                 :            : #define SPR_USRR0       0x1fa   /* RW: Ultravisor Save/Restore Register 0 */
      71                 :            : #define SPR_USRR1       0x1fb   /* RW: Ultravisor Save/Restore Register 1 */
      72                 :            : #define SPR_SMFCTRL     0x1ff   /* RW: Secure Memory Facility Control */
      73                 :            : #define SPR_PSSCR       0x357   /* RW: Stop status and control (ISA 3) */
      74                 :            : #define SPR_PPR32       0x382
      75                 :            : #define SPR_TSCR        0x399
      76                 :            : #define SPR_HID0        0x3f0
      77                 :            : #define SPR_HID1        0x3f1
      78                 :            : #define SPR_HID2        0x3f8
      79                 :            : #define SPR_HID4        0x3f4
      80                 :            : #define SPR_HID5        0x3f6
      81                 :            : #define SPR_PIR         0x3ff   /* RO: Processor Identification */
      82                 :            : 
      83                 :            : /* Bits in SRR1 */
      84                 :            : 
      85                 :            : #define SPR_SRR1_PM_WAKE_MASK   0x3c0000        /* PM wake reason for P8/9 */
      86                 :            : #define SPR_SRR1_PM_WAKE_SRESET 0x100000
      87                 :            : #define SPR_SRR1_PM_WAKE_MCE    0x3c0000        /* Use reserved value for MCE */
      88                 :            : 
      89                 :            : /* Bits in LPCR */
      90                 :            : 
      91                 :            : /* Powersave Exit Cause Enable is different on each generation */
      92                 :            : #define SPR_LPCR_P8_PECE        PPC_BITMASK(47,51)
      93                 :            : #define SPR_LPCR_P8_PECE0       PPC_BIT(47)   /* Wake on priv doorbell */
      94                 :            : #define SPR_LPCR_P8_PECE1       PPC_BIT(48)   /* Wake on hv doorbell */
      95                 :            : #define SPR_LPCR_P8_PECE2       PPC_BIT(49)   /* Wake on external interrupts */
      96                 :            : #define SPR_LPCR_P8_PECE3       PPC_BIT(50)   /* Wake on decrementer */
      97                 :            : #define SPR_LPCR_P8_PECE4       PPC_BIT(51)   /* Wake on MCs, HMIs, etc... */
      98                 :            : 
      99                 :            : #define SPR_LPCR_P9_PECE        (PPC_BITMASK(47,51) | PPC_BITMASK(17,17))
     100                 :            : #define SPR_LPCR_P9_PECEU0      PPC_BIT(17)   /* Wake on HVI */
     101                 :            : #define SPR_LPCR_P9_PECEL0      PPC_BIT(47)   /* Wake on priv doorbell */
     102                 :            : #define SPR_LPCR_P9_PECEL1      PPC_BIT(48)   /* Wake on hv doorbell */
     103                 :            : #define SPR_LPCR_P9_PECEL2      PPC_BIT(49)   /* Wake on external interrupts */
     104                 :            : #define SPR_LPCR_P9_PECEL3      PPC_BIT(50)   /* Wake on decrementer */
     105                 :            : #define SPR_LPCR_P9_PECEL4      PPC_BIT(51)   /* Wake on MCs, HMIs, etc... */
     106                 :            : #define SPR_LPCR_P9_LD          PPC_BIT(46)   /* Large decrementer mode bit */
     107                 :            : 
     108                 :            : 
     109                 :            : /* Bits in TFMR - control bits */
     110                 :            : #define SPR_TFMR_MAX_CYC_BET_STEPS      PPC_BITMASK(0,7)
     111                 :            : #define SPR_TFMR_N_CLKS_PER_STEP        PPC_BITMASK(8,9)
     112                 :            : #define SPR_TFMR_MASK_HMI               PPC_BIT(10)
     113                 :            : #define SPR_TFMR_SYNC_BIT_SEL           PPC_BITMASK(11,13)
     114                 :            : #define SPR_TFMR_TB_ECLIPZ              PPC_BIT(14)
     115                 :            : #define SPR_TFMR_LOAD_TOD_MOD           PPC_BIT(16)
     116                 :            : #define SPR_TFMR_MOVE_CHIP_TOD_TO_TB    PPC_BIT(18)
     117                 :            : #define SPR_TFMR_CLEAR_TB_ERRORS        PPC_BIT(24)
     118                 :            : /* Bits in TFMR - thread indep. status bits */
     119                 :            : #define SPR_TFMR_TFAC_XFER_ERROR        PPC_BIT(25)
     120                 :            : #define SPR_TFMR_HDEC_PARITY_ERROR      PPC_BIT(26)
     121                 :            : #define SPR_TFMR_TBST_CORRUPT           PPC_BIT(27)
     122                 :            : #define SPR_TFMR_TBST_ENCODED           PPC_BITMASK(28,31)
     123                 :            : #define SPR_TFMR_TBST_LAST              PPC_BITMASK(32,35)
     124                 :            : #define SPR_TFMR_TB_ENABLED             PPC_BIT(40)
     125                 :            : #define SPR_TFMR_TB_VALID               PPC_BIT(41)
     126                 :            : #define SPR_TFMR_TB_SYNC_OCCURED        PPC_BIT(42)
     127                 :            : #define SPR_TFMR_TB_MISSING_SYNC        PPC_BIT(43)
     128                 :            : #define SPR_TFMR_TB_MISSING_STEP        PPC_BIT(44)
     129                 :            : #define SPR_TFMR_TB_RESIDUE_ERR         PPC_BIT(45)
     130                 :            : #define SPR_TFMR_FW_CONTROL_ERR         PPC_BIT(46)
     131                 :            : #define SPR_TFMR_CHIP_TOD_STATUS        PPC_BITMASK(47,50)
     132                 :            : #define SPR_TFMR_CHIP_TOD_INTERRUPT     PPC_BIT(51)
     133                 :            : #define SPR_TFMR_CHIP_TOD_TIMEOUT       PPC_BIT(54)
     134                 :            : #define SPR_TFMR_CHIP_TOD_PARITY_ERR    PPC_BIT(56)
     135                 :            : /* Bits in TFMR - thread specific. status bits */
     136                 :            : #define SPR_TFMR_PURR_PARITY_ERR        PPC_BIT(57)
     137                 :            : #define SPR_TFMR_SPURR_PARITY_ERR       PPC_BIT(58)
     138                 :            : #define SPR_TFMR_DEC_PARITY_ERR         PPC_BIT(59)
     139                 :            : #define SPR_TFMR_TFMR_CORRUPT           PPC_BIT(60)
     140                 :            : #define SPR_TFMR_PURR_OVERFLOW          PPC_BIT(61)
     141                 :            : #define SPR_TFMR_SPURR_OVERFLOW         PPC_BIT(62)
     142                 :            : 
     143                 :            : /* Bits in HMER/HMEER */
     144                 :            : #define SPR_HMER_MALFUNCTION_ALERT      PPC_BIT(0)
     145                 :            : #define SPR_HMER_PROC_RECV_DONE         PPC_BIT(2)
     146                 :            : #define SPR_HMER_PROC_RECV_ERROR_MASKED PPC_BIT(3) /* Not P10 */
     147                 :            : #define SPR_HMER_TFAC_ERROR             PPC_BIT(4)
     148                 :            : #define SPR_HMER_TFMR_PARITY_ERROR      PPC_BIT(5) /* P9 */
     149                 :            : #define SPR_HMER_TFAC_SHADOW_XFER_ERROR PPC_BIT(5) /* P10 */
     150                 :            : #define SPR_HMER_SPURR_SCALE_LIMIT      PPC_BIT(6) /* P10 */
     151                 :            : #define SPR_HMER_XSCOM_FAIL             PPC_BIT(8)
     152                 :            : #define SPR_HMER_XSCOM_DONE             PPC_BIT(9)
     153                 :            : #define SPR_HMER_PROC_RECV_AGAIN        PPC_BIT(11)
     154                 :            : #define SPR_HMER_WARN_RISE              PPC_BIT(14) /* Not P10 */
     155                 :            : #define SPR_HMER_WARN_FALL              PPC_BIT(15) /* Not P10 */
     156                 :            : #define SPR_HMER_SCOM_FIR_HMI           PPC_BIT(16)
     157                 :            : #define SPR_HMER_TRIG_FIR_HMI           PPC_BIT(17) /* Not P10 */
     158                 :            : #define SPR_HMER_THD_WAKE_BLOCKED_TM_SUSPEND    PPC_BIT(17) /* Not P10 */
     159                 :            : #define SPR_HMER_P10_TRIG_FIR_HMI       PPC_BIT(18)
     160                 :            : #define SPR_HMER_HYP_RESOURCE_ERR       PPC_BIT(20) /* Not P10 */
     161                 :            : #define SPR_HMER_XSCOM_STATUS           PPC_BITMASK(21,23)
     162                 :            : 
     163                 :            : /*
     164                 :            :  * HMEER: initial bits for HMI interrupt enable mask.
     165                 :            :  * Per Dave Larson, never enable 8,9,21-23
     166                 :            :  */
     167                 :            : #define SPR_HMEER_HMI_ENABLE_MASK       (SPR_HMER_MALFUNCTION_ALERT |\
     168                 :            :                                          SPR_HMER_HYP_RESOURCE_ERR |\
     169                 :            :                                          SPR_HMER_PROC_RECV_DONE |\
     170                 :            :                                          SPR_HMER_PROC_RECV_ERROR_MASKED |\
     171                 :            :                                          SPR_HMER_TFAC_ERROR |\
     172                 :            :                                          SPR_HMER_TFMR_PARITY_ERROR |\
     173                 :            :                                          SPR_HMER_PROC_RECV_AGAIN)
     174                 :            : 
     175                 :            : #define SPR_HMEER_P10_HMI_ENABLE_MASK   (SPR_HMER_MALFUNCTION_ALERT |\
     176                 :            :                                          SPR_HMER_PROC_RECV_DONE |\
     177                 :            :                                          SPR_HMER_TFAC_ERROR |\
     178                 :            :                                          SPR_HMER_TFAC_SHADOW_XFER_ERROR |\
     179                 :            :                                          SPR_HMER_SPURR_SCALE_LIMIT |\
     180                 :            :                                          SPR_HMER_PROC_RECV_AGAIN)
     181                 :            : 
     182                 :            : /* Bits in HID0 */
     183                 :            : #define SPR_HID0_POWER8_4LPARMODE       PPC_BIT(2)
     184                 :            : #define SPR_HID0_POWER8_2LPARMODE       PPC_BIT(6)
     185                 :            : #define SPR_HID0_POWER8_DYNLPARDIS      PPC_BIT(15)
     186                 :            : #define SPR_HID0_POWER8_HILE            PPC_BIT(19)
     187                 :            : #define SPR_HID0_POWER9_HILE            PPC_BIT(4)
     188                 :            : #define SPR_HID0_POWER10_HILE           PPC_BIT(4)
     189                 :            : #define SPR_HID0_POWER8_ENABLE_ATTN     PPC_BIT(31)
     190                 :            : #define SPR_HID0_POWER9_ENABLE_ATTN     PPC_BIT(3)
     191                 :            : #define SPR_HID0_POWER10_ENABLE_ATTN    PPC_BIT(3)
     192                 :            : #define SPR_HID0_POWER9_FLUSH_ICACHE    PPC_BIT(2)
     193                 :            : #define SPR_HID0_POWER10_FLUSH_ICACHE   PPC_BIT(2)
     194                 :            : #define SPR_HID0_POWER9_RADIX           PPC_BIT(8)
     195                 :            : 
     196                 :            : /* PVR bits */
     197                 :            : #define SPR_PVR_TYPE                    0xffff0000
     198                 :            : #define SPR_PVR_CHIP_TYPE               0x0000f000
     199                 :            : #define SPR_PVR_VERS_MAJ                0x00000f00
     200                 :            : #define SPR_PVR_VERS_MIN                0x000000ff
     201                 :            : 
     202                 :            : #define PVR_TYPE(_pvr)          GETFIELD(SPR_PVR_TYPE, _pvr)
     203                 :            : #define PVR_CHIP_TYPE(_pvr)     GETFIELD(SPR_PVR_CHIP_TYPE, _pvr)
     204                 :            : #define PVR_VERS_MAJ(_pvr)      GETFIELD(SPR_PVR_VERS_MAJ, _pvr)
     205                 :            : #define PVR_VERS_MIN(_pvr)      GETFIELD(SPR_PVR_VERS_MIN, _pvr)
     206                 :            : 
     207                 :            : /* PVR definitions */
     208                 :            : #define PVR_TYPE_P8E    0x004b /* Murano */
     209                 :            : #define PVR_TYPE_P8     0x004d /* Venice */
     210                 :            : #define PVR_TYPE_P8NVL  0x004c /* Naples */
     211                 :            : #define PVR_TYPE_P9     0x004e
     212                 :            : #define PVR_TYPE_P9P    0x004f /* Axone */
     213                 :            : #define PVR_TYPE_P10    0x0080
     214                 :            : 
     215                 :            : #ifdef __ASSEMBLY__
     216                 :            : 
     217                 :            : /* Thread priority control opcodes */
     218                 :            : #define smt_low         or 1,1,1
     219                 :            : #define smt_medium      or 2,2,2
     220                 :            : #define smt_high        or 3,3,3
     221                 :            : #define smt_medium_high or 5,5,5
     222                 :            : #define smt_medium_low  or 6,6,6
     223                 :            : #define smt_extra_high  or 7,7,7
     224                 :            : #define smt_very_low    or 31,31,31
     225                 :            : #define smt_lowest      smt_low ; smt_very_low
     226                 :            : 
     227                 :            : #else /* __ASSEMBLY__ */
     228                 :            : 
     229                 :            : #include <ccan/str/str.h>
     230                 :            : #include <compiler.h>
     231                 :            : #include <stdbool.h>
     232                 :            : #include <stdint.h>
     233                 :            : 
     234                 :            : #define PPC_INST_NOP    0x60000000UL
     235                 :            : #define PPC_INST_TRAP   0x7fe00008UL
     236                 :            : 
     237                 :            : #define RB(b)           (((b) & 0x1f) << 11)
     238                 :            : #define MSGSND(b)       stringify(.long 0x7c00019c | RB(b))
     239                 :            : #define MSGCLR(b)       stringify(.long 0x7c0001dc | RB(b))
     240                 :            : #define MSGSYNC         stringify(.long 0x7c0006ec)
     241                 :            : 
     242                 :          4 : static inline bool is_power9n(uint32_t version)
     243                 :            : {
     244                 :          4 :         if (PVR_TYPE(version) != PVR_TYPE_P9)
     245                 :          0 :                 return false;
     246                 :            :         /*
     247                 :            :          * Bit 13 tells us:
     248                 :            :          *   0 = Scale out (aka Nimbus)
     249                 :            :          *   1 = Scale up  (aka Cumulus)
     250                 :            :          */
     251                 :          4 :         if ((version >> 13) & 1)
     252                 :          0 :                 return false;
     253                 :          4 :         return true;
     254                 :            : }
     255                 :            : 
     256                 :            : static inline bool is_fused_core(uint32_t version)
     257                 :            : {
     258                 :            :         if (PVR_TYPE(version) == PVR_TYPE_P9) {
     259                 :            :                 switch(PVR_CHIP_TYPE(version)) {
     260                 :            :                         case 0:
     261                 :            :                         case 2:
     262                 :            :                                 return true;
     263                 :            :                         default:
     264                 :            :                                 return false;
     265                 :            :                 }
     266                 :            : 
     267                 :            :         } else if(PVR_TYPE(version) == PVR_TYPE_P10) {
     268                 :            :                 if(PVR_CHIP_TYPE(version) & 0x01)
     269                 :            :                         return false;
     270                 :            :                 else
     271                 :            :                         return true;
     272                 :            :         } else
     273                 :            :                 return false;
     274                 :            : }
     275                 :            : 
     276                 :          0 : static inline bool is_power9c(uint32_t version) 
     277                 :            : {
     278                 :            : 
     279                 :          0 :         if (PVR_TYPE(version) != PVR_TYPE_P9)
     280                 :          0 :                 return false;
     281                 :            :         /*
     282                 :            :          * Bit 13 tells us:
     283                 :            :          *   0 = Scale out (aka Nimbus)
     284                 :            :          *   1 = Scale up  (aka Cumulus)
     285                 :            :          */
     286                 :          0 :         if (!((version >> 13) & 1))
     287                 :          0 :                 return false;
     288                 :          0 :         return true;
     289                 :            : }
     290                 :            : 
     291                 :            : #ifndef __TEST__
     292                 :            : 
     293                 :            : /* POWER9 and above only */
     294                 :            : static inline void flush_erat(void)
     295                 :            : {
     296                 :            :         asm volatile("slbia        7");
     297                 :            : }
     298                 :            : 
     299                 :            : /*
     300                 :            :  * SMT priority
     301                 :            :  */
     302                 :            : 
     303                 :            : static inline void smt_low(void)        { asm volatile("or 1,1,1");   }
     304                 :            : static inline void smt_medium(void)     { asm volatile("or 2,2,2");   }
     305                 :            : static inline void smt_high(void)       { asm volatile("or 3,3,3");   }
     306                 :            : static inline void smt_medium_high(void){ asm volatile("or 5,5,5");   }
     307                 :            : static inline void smt_medium_low(void) { asm volatile("or 6,6,6");   }
     308                 :            : static inline void smt_extra_high(void) { asm volatile("or 7,7,7");   }
     309                 :            : static inline void smt_very_low(void)   { asm volatile("or 31,31,31");        }
     310                 :            : static inline void smt_lowest(void)     { smt_low(); smt_very_low();    }
     311                 :            : 
     312                 :            : /*
     313                 :            :  * SPR access functions
     314                 :            :  */
     315                 :            : 
     316                 :            : static inline unsigned long mfmsr(void)
     317                 :            : {
     318                 :            :         unsigned long val;
     319                 :            :         
     320                 :            :         asm volatile("mfmsr %0" : "=r"(val) : : "memory");
     321                 :            :         return val;
     322                 :            : }
     323                 :            : 
     324                 :            : static inline void mtmsr(unsigned long val)
     325                 :            : {
     326                 :            :         asm volatile("mtmsr %0" : : "r"(val) : "memory");
     327                 :            : }
     328                 :            : 
     329                 :            : static inline void mtmsrd(unsigned long val, int l)
     330                 :            : {
     331                 :            :         asm volatile("mtmsrd %0,%1" : : "r"(val), "i"(l) : "memory");
     332                 :            : }
     333                 :            : 
     334                 :            : static inline __attribute__((always_inline))
     335                 :            : unsigned long mfspr(const unsigned int spr)
     336                 :            : {
     337                 :            :         unsigned long val;
     338                 :            : 
     339                 :            :         asm volatile("mfspr %0,%1" : "=r"(val) : "i"(spr) : "memory");
     340                 :            :         return val;
     341                 :            : }
     342                 :            : 
     343                 :            : static inline __attribute__((always_inline))
     344                 :            : void mtspr(const unsigned int spr, unsigned long val)
     345                 :            : {
     346                 :            :         asm volatile("mtspr %0,%1" : : "i"(spr), "r"(val) : "memory");
     347                 :            : }
     348                 :            : 
     349                 :            : /* Helpers for special sequences needed by some registers */
     350                 :            : extern void set_hid0(unsigned long hid0);
     351                 :            : extern void trigger_attn(void);
     352                 :            : 
     353                 :            : /*
     354                 :            :  * Barriers
     355                 :            :  */
     356                 :            : 
     357                 :            : static inline void eieio(void)
     358                 :            : {
     359                 :            :         asm volatile("eieio" : : : "memory");
     360                 :            : }
     361                 :            : 
     362                 :            : static inline void sync(void)
     363                 :            : {
     364                 :            :         asm volatile("sync" : : : "memory");
     365                 :            : }
     366                 :            : 
     367                 :            : static inline void lwsync(void)
     368                 :            : {
     369                 :            :         asm volatile("lwsync" : : : "memory");
     370                 :            : }
     371                 :            : 
     372                 :            : static inline void isync(void)
     373                 :            : {
     374                 :            :         asm volatile("isync" : : : "memory");
     375                 :            : }
     376                 :            : 
     377                 :            : 
     378                 :            : /*
     379                 :            :  * Cache sync
     380                 :            :  */
     381                 :            : static inline void sync_icache(void)
     382                 :            : {
     383                 :            :         asm volatile("sync; icbi 0,%0; sync; isync" : : "r" (0) : "memory");
     384                 :            : }
     385                 :            : 
     386                 :            : /*
     387                 :            :  * Doorbells
     388                 :            :  */
     389                 :            : static inline void msgclr(void)
     390                 :            : {
     391                 :            :         uint64_t rb = (0x05 << (63-36));
     392                 :            :         asm volatile(MSGCLR(%0) : : "r"(rb));
     393                 :            : }
     394                 :            : 
     395                 :            : static inline void p9_dbell_receive(void)
     396                 :            : {
     397                 :            :         uint64_t rb = (0x05 << (63-36));
     398                 :            :         asm volatile(MSGCLR(%0) ";"
     399                 :            :                      MSGSYNC    ";"
     400                 :            :                      "lwsync"
     401                 :            :                      : : "r"(rb));
     402                 :            : }
     403                 :            : 
     404                 :            : static inline void p9_dbell_send(uint32_t pir)
     405                 :            : {
     406                 :            :         uint64_t rb = (0x05 << (63-36)) | pir;
     407                 :            :         asm volatile("sync ;"
     408                 :            :                      MSGSND(%0)
     409                 :            :                      : : "r"(rb));
     410                 :            : }
     411                 :            : 
     412                 :            : /*
     413                 :            :  * Byteswap load/stores
     414                 :            :  */
     415                 :            : 
     416                 :            : static inline uint16_t ld_le16(const uint16_t *addr)
     417                 :            : {
     418                 :            :         uint16_t val;
     419                 :            :         asm volatile("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
     420                 :            :         return val;
     421                 :            : }
     422                 :            : 
     423                 :            : static inline uint32_t ld_le32(const uint32_t *addr)
     424                 :            : {
     425                 :            :         uint32_t val;
     426                 :            :         asm volatile("lwbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
     427                 :            :         return val;
     428                 :            : }
     429                 :            : 
     430                 :            : static inline void st_le16(uint16_t *addr, uint16_t val)
     431                 :            : {
     432                 :            :         asm volatile("sthbrx %0,0,%1" : : "r"(val), "r"(addr), "m"(*addr));
     433                 :            : }
     434                 :            : 
     435                 :            : static inline void st_le32(uint32_t *addr, uint32_t val)
     436                 :            : {
     437                 :            :         asm volatile("stwbrx %0,0,%1" : : "r"(val), "r"(addr), "m"(*addr));
     438                 :            : }
     439                 :            : 
     440                 :            : #endif /* __TEST__ */
     441                 :            : 
     442                 :            : #endif /* __ASSEMBLY__ */
     443                 :            : 
     444                 :            : #endif /* __PROCESSOR_H */

Generated by: LCOV version 1.14