linux/arch/powerpc/platforms/pseries/plpar_wrappers.h
<<
>>
Prefs
   1#ifndef _PSERIES_PLPAR_WRAPPERS_H
   2#define _PSERIES_PLPAR_WRAPPERS_H
   3
   4#include <linux/string.h>
   5
   6#include <asm/hvcall.h>
   7#include <asm/paca.h>
   8#include <asm/page.h>
   9
  10/* Get state of physical CPU from query_cpu_stopped */
  11int smp_query_cpu_stopped(unsigned int pcpu);
  12#define QCSS_STOPPED 0
  13#define QCSS_STOPPING 1
  14#define QCSS_NOT_STOPPED 2
  15#define QCSS_HARDWARE_ERROR -1
  16#define QCSS_HARDWARE_BUSY -2
  17
  18static inline long poll_pending(void)
  19{
  20        return plpar_hcall_norets(H_POLL_PENDING);
  21}
  22
  23static inline u8 get_cede_latency_hint(void)
  24{
  25        return get_lppaca()->gpr5_dword.fields.cede_latency_hint;
  26}
  27
  28static inline void set_cede_latency_hint(u8 latency_hint)
  29{
  30        get_lppaca()->gpr5_dword.fields.cede_latency_hint = latency_hint;
  31}
  32
  33static inline long cede_processor(void)
  34{
  35        return plpar_hcall_norets(H_CEDE);
  36}
  37
  38static inline long extended_cede_processor(unsigned long latency_hint)
  39{
  40        long rc;
  41        u8 old_latency_hint = get_cede_latency_hint();
  42
  43        set_cede_latency_hint(latency_hint);
  44        rc = cede_processor();
  45        set_cede_latency_hint(old_latency_hint);
  46
  47        return rc;
  48}
  49
  50static inline long vpa_call(unsigned long flags, unsigned long cpu,
  51                unsigned long vpa)
  52{
  53        /* flags are in bits 16-18 (counting from most significant bit) */
  54        flags = flags << (63 - 18);
  55
  56        return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa);
  57}
  58
  59static inline long unregister_vpa(unsigned long cpu)
  60{
  61        return vpa_call(0x5, cpu, 0);
  62}
  63
  64static inline long register_vpa(unsigned long cpu, unsigned long vpa)
  65{
  66        return vpa_call(0x1, cpu, vpa);
  67}
  68
  69static inline long unregister_slb_shadow(unsigned long cpu)
  70{
  71        return vpa_call(0x7, cpu, 0);
  72}
  73
  74static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
  75{
  76        return vpa_call(0x3, cpu, vpa);
  77}
  78
  79static inline long unregister_dtl(unsigned long cpu)
  80{
  81        return vpa_call(0x6, cpu, 0);
  82}
  83
  84static inline long register_dtl(unsigned long cpu, unsigned long vpa)
  85{
  86        return vpa_call(0x2, cpu, vpa);
  87}
  88
  89static inline long plpar_page_set_loaned(unsigned long vpa)
  90{
  91        unsigned long cmo_page_sz = cmo_get_page_size();
  92        long rc = 0;
  93        int i;
  94
  95        for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
  96                rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED, vpa + i, 0);
  97
  98        for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
  99                plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE,
 100                                   vpa + i - cmo_page_sz, 0);
 101
 102        return rc;
 103}
 104
 105static inline long plpar_page_set_active(unsigned long vpa)
 106{
 107        unsigned long cmo_page_sz = cmo_get_page_size();
 108        long rc = 0;
 109        int i;
 110
 111        for (i = 0; !rc && i < PAGE_SIZE; i += cmo_page_sz)
 112                rc = plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_ACTIVE, vpa + i, 0);
 113
 114        for (i -= cmo_page_sz; rc && i != 0; i -= cmo_page_sz)
 115                plpar_hcall_norets(H_PAGE_INIT, H_PAGE_SET_LOANED,
 116                                   vpa + i - cmo_page_sz, 0);
 117
 118        return rc;
 119}
 120
 121extern void vpa_init(int cpu);
 122
 123static inline long plpar_pte_enter(unsigned long flags,
 124                unsigned long hpte_group, unsigned long hpte_v,
 125                unsigned long hpte_r, unsigned long *slot)
 126{
 127        long rc;
 128        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 129
 130        rc = plpar_hcall(H_ENTER, retbuf, flags, hpte_group, hpte_v, hpte_r);
 131
 132        *slot = retbuf[0];
 133
 134        return rc;
 135}
 136
 137static inline long plpar_pte_remove(unsigned long flags, unsigned long ptex,
 138                unsigned long avpn, unsigned long *old_pteh_ret,
 139                unsigned long *old_ptel_ret)
 140{
 141        long rc;
 142        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 143
 144        rc = plpar_hcall(H_REMOVE, retbuf, flags, ptex, avpn);
 145
 146        *old_pteh_ret = retbuf[0];
 147        *old_ptel_ret = retbuf[1];
 148
 149        return rc;
 150}
 151
 152/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */
 153static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex,
 154                unsigned long avpn, unsigned long *old_pteh_ret,
 155                unsigned long *old_ptel_ret)
 156{
 157        long rc;
 158        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 159
 160        rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn);
 161
 162        *old_pteh_ret = retbuf[0];
 163        *old_ptel_ret = retbuf[1];
 164
 165        return rc;
 166}
 167
 168static inline long plpar_pte_read(unsigned long flags, unsigned long ptex,
 169                unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
 170{
 171        long rc;
 172        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 173
 174        rc = plpar_hcall(H_READ, retbuf, flags, ptex);
 175
 176        *old_pteh_ret = retbuf[0];
 177        *old_ptel_ret = retbuf[1];
 178
 179        return rc;
 180}
 181
 182/* plpar_pte_read_raw can be called in real mode. It calls plpar_hcall_raw */
 183static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
 184                unsigned long *old_pteh_ret, unsigned long *old_ptel_ret)
 185{
 186        long rc;
 187        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 188
 189        rc = plpar_hcall_raw(H_READ, retbuf, flags, ptex);
 190
 191        *old_pteh_ret = retbuf[0];
 192        *old_ptel_ret = retbuf[1];
 193
 194        return rc;
 195}
 196
 197/*
 198 * plpar_pte_read_4_raw can be called in real mode.
 199 * ptes must be 8*sizeof(unsigned long)
 200 */
 201static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
 202                                        unsigned long *ptes)
 203
 204{
 205        long rc;
 206        unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
 207
 208        rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
 209
 210        memcpy(ptes, retbuf, 8*sizeof(unsigned long));
 211
 212        return rc;
 213}
 214
 215static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
 216                unsigned long avpn)
 217{
 218        return plpar_hcall_norets(H_PROTECT, flags, ptex, avpn);
 219}
 220
 221static inline long plpar_tce_get(unsigned long liobn, unsigned long ioba,
 222                unsigned long *tce_ret)
 223{
 224        long rc;
 225        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 226
 227        rc = plpar_hcall(H_GET_TCE, retbuf, liobn, ioba);
 228
 229        *tce_ret = retbuf[0];
 230
 231        return rc;
 232}
 233
 234static inline long plpar_tce_put(unsigned long liobn, unsigned long ioba,
 235                unsigned long tceval)
 236{
 237        return plpar_hcall_norets(H_PUT_TCE, liobn, ioba, tceval);
 238}
 239
 240static inline long plpar_tce_put_indirect(unsigned long liobn,
 241                unsigned long ioba, unsigned long page, unsigned long count)
 242{
 243        return plpar_hcall_norets(H_PUT_TCE_INDIRECT, liobn, ioba, page, count);
 244}
 245
 246static inline long plpar_tce_stuff(unsigned long liobn, unsigned long ioba,
 247                unsigned long tceval, unsigned long count)
 248{
 249        return plpar_hcall_norets(H_STUFF_TCE, liobn, ioba, tceval, count);
 250}
 251
 252static inline long plpar_get_term_char(unsigned long termno,
 253                unsigned long *len_ret, char *buf_ret)
 254{
 255        long rc;
 256        unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
 257        unsigned long *lbuf = (unsigned long *)buf_ret; /* TODO: alignment? */
 258
 259        rc = plpar_hcall(H_GET_TERM_CHAR, retbuf, termno);
 260
 261        *len_ret = retbuf[0];
 262        lbuf[0] = retbuf[1];
 263        lbuf[1] = retbuf[2];
 264
 265        return rc;
 266}
 267
 268static inline long plpar_put_term_char(unsigned long termno, unsigned long len,
 269                const char *buffer)
 270{
 271        unsigned long *lbuf = (unsigned long *)buffer;  /* TODO: alignment? */
 272        return plpar_hcall_norets(H_PUT_TERM_CHAR, termno, len, lbuf[0],
 273                        lbuf[1]);
 274}
 275
 276#endif /* _PSERIES_PLPAR_WRAPPERS_H */
 277