File indexing completed on 2025-05-11 08:23:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 #ifndef _EPAPR_HCALLS_H
0051 #define _EPAPR_HCALLS_H
0052
0053 #include <uapi/asm/epapr_hcalls.h>
0054
0055 #ifndef __ASSEMBLY__
0056 #include <sys/endian.h>
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 #define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory"
0093
0094 #define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS
0095 #define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10"
0096 #define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9"
0097 #define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8"
0098 #define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7"
0099 #define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6"
0100 #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5"
0101 #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4"
0102
0103 extern bool epapr_paravirt_enabled;
0104 extern uint32_t epapr_hypercall_start[];
0105
0106 #ifdef CONFIG_EPAPR_PARAVIRT
0107 int __init epapr_paravirt_early_init(void);
0108 #else
0109 static inline int epapr_paravirt_early_init(void) { return 0; }
0110 #endif
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 static inline unsigned int ev_int_set_config(unsigned int interrupt,
0135 uint32_t config, unsigned int priority, uint32_t destination)
0136 {
0137 register uintptr_t r11 __asm__("r11");
0138 register uintptr_t r3 __asm__("r3");
0139 register uintptr_t r4 __asm__("r4");
0140 register uintptr_t r5 __asm__("r5");
0141 register uintptr_t r6 __asm__("r6");
0142
0143 r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG);
0144 r3 = interrupt;
0145 r4 = config;
0146 r5 = priority;
0147 r6 = destination;
0148
0149 asm volatile("bl epapr_hypercall_start"
0150 : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6)
0151 : : EV_HCALL_CLOBBERS4
0152 );
0153
0154 return r3;
0155 }
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 static inline unsigned int ev_int_get_config(unsigned int interrupt,
0167 uint32_t *config, unsigned int *priority, uint32_t *destination)
0168 {
0169 register uintptr_t r11 __asm__("r11");
0170 register uintptr_t r3 __asm__("r3");
0171 register uintptr_t r4 __asm__("r4");
0172 register uintptr_t r5 __asm__("r5");
0173 register uintptr_t r6 __asm__("r6");
0174
0175 r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG);
0176 r3 = interrupt;
0177
0178 asm volatile("bl epapr_hypercall_start"
0179 : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6)
0180 : : EV_HCALL_CLOBBERS4
0181 );
0182
0183 *config = r4;
0184 *priority = r5;
0185 *destination = r6;
0186
0187 return r3;
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197 static inline unsigned int ev_int_set_mask(unsigned int interrupt,
0198 unsigned int mask)
0199 {
0200 register uintptr_t r11 __asm__("r11");
0201 register uintptr_t r3 __asm__("r3");
0202 register uintptr_t r4 __asm__("r4");
0203
0204 r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK);
0205 r3 = interrupt;
0206 r4 = mask;
0207
0208 asm volatile("bl epapr_hypercall_start"
0209 : "+r" (r11), "+r" (r3), "+r" (r4)
0210 : : EV_HCALL_CLOBBERS2
0211 );
0212
0213 return r3;
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223 static inline unsigned int ev_int_get_mask(unsigned int interrupt,
0224 unsigned int *mask)
0225 {
0226 register uintptr_t r11 __asm__("r11");
0227 register uintptr_t r3 __asm__("r3");
0228 register uintptr_t r4 __asm__("r4");
0229
0230 r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK);
0231 r3 = interrupt;
0232
0233 asm volatile("bl epapr_hypercall_start"
0234 : "+r" (r11), "+r" (r3), "=r" (r4)
0235 : : EV_HCALL_CLOBBERS2
0236 );
0237
0238 *mask = r4;
0239
0240 return r3;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 static inline unsigned int ev_int_eoi(unsigned int interrupt)
0254 {
0255 register uintptr_t r11 __asm__("r11");
0256 register uintptr_t r3 __asm__("r3");
0257
0258 r11 = EV_HCALL_TOKEN(EV_INT_EOI);
0259 r3 = interrupt;
0260
0261 asm volatile("bl epapr_hypercall_start"
0262 : "+r" (r11), "+r" (r3)
0263 : : EV_HCALL_CLOBBERS1
0264 );
0265
0266 return r3;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 static inline unsigned int ev_byte_channel_send(unsigned int handle,
0281 unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
0282 {
0283 register uintptr_t r11 __asm__("r11");
0284 register uintptr_t r3 __asm__("r3");
0285 register uintptr_t r4 __asm__("r4");
0286 register uintptr_t r5 __asm__("r5");
0287 register uintptr_t r6 __asm__("r6");
0288 register uintptr_t r7 __asm__("r7");
0289 register uintptr_t r8 __asm__("r8");
0290 const uint32_t *p = (const uint32_t *) buffer;
0291
0292 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND);
0293 r3 = handle;
0294 r4 = *count;
0295 r5 = be32toh(p[0]);
0296 r6 = be32toh(p[1]);
0297 r7 = be32toh(p[2]);
0298 r8 = be32toh(p[3]);
0299
0300 asm volatile("bl epapr_hypercall_start"
0301 : "+r" (r11), "+r" (r3),
0302 "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8)
0303 : : EV_HCALL_CLOBBERS6
0304 );
0305
0306 *count = r4;
0307
0308 return r3;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 static inline unsigned int ev_byte_channel_receive(unsigned int handle,
0324 unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES])
0325 {
0326 register uintptr_t r11 __asm__("r11");
0327 register uintptr_t r3 __asm__("r3");
0328 register uintptr_t r4 __asm__("r4");
0329 register uintptr_t r5 __asm__("r5");
0330 register uintptr_t r6 __asm__("r6");
0331 register uintptr_t r7 __asm__("r7");
0332 register uintptr_t r8 __asm__("r8");
0333 uint32_t *p = (uint32_t *) buffer;
0334
0335 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE);
0336 r3 = handle;
0337 r4 = *count;
0338
0339 asm volatile("bl epapr_hypercall_start"
0340 : "+r" (r11), "+r" (r3), "+r" (r4),
0341 "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8)
0342 : : EV_HCALL_CLOBBERS6
0343 );
0344
0345 *count = r4;
0346 p[0] = htobe32(r5);
0347 p[1] = htobe32(r6);
0348 p[2] = htobe32(r7);
0349 p[3] = htobe32(r8);
0350
0351 return r3;
0352 }
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 static inline unsigned int ev_byte_channel_poll(unsigned int handle,
0367 unsigned int *rx_count, unsigned int *tx_count)
0368 {
0369 register uintptr_t r11 __asm__("r11");
0370 register uintptr_t r3 __asm__("r3");
0371 register uintptr_t r4 __asm__("r4");
0372 register uintptr_t r5 __asm__("r5");
0373
0374 r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL);
0375 r3 = handle;
0376
0377 asm volatile("bl epapr_hypercall_start"
0378 : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5)
0379 : : EV_HCALL_CLOBBERS3
0380 );
0381
0382 *rx_count = r4;
0383 *tx_count = r5;
0384
0385 return r3;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 static inline unsigned int ev_int_iack(unsigned int handle,
0401 unsigned int *vector)
0402 {
0403 register uintptr_t r11 __asm__("r11");
0404 register uintptr_t r3 __asm__("r3");
0405 register uintptr_t r4 __asm__("r4");
0406
0407 r11 = EV_HCALL_TOKEN(EV_INT_IACK);
0408 r3 = handle;
0409
0410 asm volatile("bl epapr_hypercall_start"
0411 : "+r" (r11), "+r" (r3), "=r" (r4)
0412 : : EV_HCALL_CLOBBERS2
0413 );
0414
0415 *vector = r4;
0416
0417 return r3;
0418 }
0419
0420
0421
0422
0423
0424
0425
0426 static inline unsigned int ev_doorbell_send(unsigned int handle)
0427 {
0428 register uintptr_t r11 __asm__("r11");
0429 register uintptr_t r3 __asm__("r3");
0430
0431 r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND);
0432 r3 = handle;
0433
0434 asm volatile("bl epapr_hypercall_start"
0435 : "+r" (r11), "+r" (r3)
0436 : : EV_HCALL_CLOBBERS1
0437 );
0438
0439 return r3;
0440 }
0441
0442
0443
0444
0445
0446
0447 static inline unsigned int ev_idle(void)
0448 {
0449 register uintptr_t r11 __asm__("r11");
0450 register uintptr_t r3 __asm__("r3");
0451
0452 r11 = EV_HCALL_TOKEN(EV_IDLE);
0453
0454 asm volatile("bl epapr_hypercall_start"
0455 : "+r" (r11), "=r" (r3)
0456 : : EV_HCALL_CLOBBERS1
0457 );
0458
0459 return r3;
0460 }
0461
0462 #ifdef CONFIG_EPAPR_PARAVIRT
0463 static inline unsigned long epapr_hypercall(unsigned long *in,
0464 unsigned long *out,
0465 unsigned long nr)
0466 {
0467 unsigned long register r0 asm("r0");
0468 unsigned long register r3 asm("r3") = in[0];
0469 unsigned long register r4 asm("r4") = in[1];
0470 unsigned long register r5 asm("r5") = in[2];
0471 unsigned long register r6 asm("r6") = in[3];
0472 unsigned long register r7 asm("r7") = in[4];
0473 unsigned long register r8 asm("r8") = in[5];
0474 unsigned long register r9 asm("r9") = in[6];
0475 unsigned long register r10 asm("r10") = in[7];
0476 unsigned long register r11 asm("r11") = nr;
0477 unsigned long register r12 asm("r12");
0478
0479 asm volatile("bl epapr_hypercall_start"
0480 : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6),
0481 "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11),
0482 "=r"(r12)
0483 : "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "r"(r8),
0484 "r"(r9), "r"(r10), "r"(r11)
0485 : "memory", "cc", "xer", "ctr", "lr");
0486
0487 out[0] = r4;
0488 out[1] = r5;
0489 out[2] = r6;
0490 out[3] = r7;
0491 out[4] = r8;
0492 out[5] = r9;
0493 out[6] = r10;
0494 out[7] = r11;
0495
0496 return r3;
0497 }
0498 #else
0499 static unsigned long epapr_hypercall(unsigned long *in,
0500 unsigned long *out,
0501 unsigned long nr)
0502 {
0503 return EV_UNIMPLEMENTED;
0504 }
0505 #endif
0506
0507 static inline long epapr_hypercall0_1(unsigned int nr, unsigned long *r2)
0508 {
0509 unsigned long in[8];
0510 unsigned long out[8];
0511 unsigned long r;
0512
0513 r = epapr_hypercall(in, out, nr);
0514 *r2 = out[0];
0515
0516 return r;
0517 }
0518
0519 static inline long epapr_hypercall0(unsigned int nr)
0520 {
0521 unsigned long in[8];
0522 unsigned long out[8];
0523
0524 return epapr_hypercall(in, out, nr);
0525 }
0526
0527 static inline long epapr_hypercall1(unsigned int nr, unsigned long p1)
0528 {
0529 unsigned long in[8];
0530 unsigned long out[8];
0531
0532 in[0] = p1;
0533 return epapr_hypercall(in, out, nr);
0534 }
0535
0536 static inline long epapr_hypercall2(unsigned int nr, unsigned long p1,
0537 unsigned long p2)
0538 {
0539 unsigned long in[8];
0540 unsigned long out[8];
0541
0542 in[0] = p1;
0543 in[1] = p2;
0544 return epapr_hypercall(in, out, nr);
0545 }
0546
0547 static inline long epapr_hypercall3(unsigned int nr, unsigned long p1,
0548 unsigned long p2, unsigned long p3)
0549 {
0550 unsigned long in[8];
0551 unsigned long out[8];
0552
0553 in[0] = p1;
0554 in[1] = p2;
0555 in[2] = p3;
0556 return epapr_hypercall(in, out, nr);
0557 }
0558
0559 static inline long epapr_hypercall4(unsigned int nr, unsigned long p1,
0560 unsigned long p2, unsigned long p3,
0561 unsigned long p4)
0562 {
0563 unsigned long in[8];
0564 unsigned long out[8];
0565
0566 in[0] = p1;
0567 in[1] = p2;
0568 in[2] = p3;
0569 in[3] = p4;
0570 return epapr_hypercall(in, out, nr);
0571 }
0572 #endif
0573 #endif