2026-01-21 18:59:54 +08:00

206 lines
5.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_SW64_HMC_H
#define _ASM_SW64_HMC_H
/*
* Common HMC-code
*/
/* 0x0 - 0x3F : Kernel Level HMC routine */
#define HMC_halt 0x00
#define HMC_rdio64 0x01
#define HMC_rdio32 0x02
#define HMC_cpuid 0x03
#define HMC_sleepen 0x05
#define HMC_rdksp 0x06
#define HMC_rdptbr 0x0B
#define HMC_wrptbr 0x0C
#define HMC_wrksp 0x0E
#define HMC_mtinten 0x0F
#define HMC_load_mm 0x11
#define HMC_rdpcbb 0x12
#define HMC_wrpcbb 0x13
#define HMC_tbisasn 0x14
#define HMC_tbivpn 0x19
#define HMC_ret 0x1A
#define HMC_wrvpcr 0x29
#define HMC_wrfen 0x2B
#define HMC_kvcpucb 0x2C
#define HMC_sflush 0x2F
#define HMC_swpctx 0x30
#define HMC_entervm 0x31
#define HMC_hcall 0x32
#define HMC_tbi 0x33
#define HMC_wrent 0x34
#define HMC_swpipl 0x35
#define HMC_rdps 0x36
#define HMC_wrkgp 0x37
#define HMC_wrusp 0x38
#define HMC_rvpcr 0x39
#define HMC_rdusp 0x3A
#define HMC_wrtimer 0x3B
#define HMC_whami 0x3C
#define HMC_retsys 0x3D
#define HMC_sendii 0x3E
#define HMC_rti 0x3F
/* 0x80 - 0xBF : User Level HMC routine */
#define HMC_bpt 0x80
#define HMC_callsys 0x83
#define HMC_imb 0x86
#define HMC_rwreg 0x87
#define HMC_rdunique 0x9E
#define HMC_wrunique 0x9F
#define HMC_sz_uflush 0xA8
#define HMC_gentrap 0xAA
#define HMC_wrperfmon 0xB0
#define HMC_longtime 0xB1
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
extern void halt(void) __attribute__((noreturn));
#define __halt() __asm__ __volatile__ ("sys_call %0 #halt" : : "i" (HMC_halt))
#define imb() \
__asm__ __volatile__ ("sys_call %0 #imb" : : "i" (HMC_imb) : "memory")
#define __CALL_HMC_R0(NAME, TYPE) \
static inline TYPE NAME(void) \
{ \
register TYPE __r0 __asm__("$0"); \
__asm__ __volatile__( \
"sys_call %1 # " #NAME \
: "=r" (__r0) \
: "i" (HMC_ ## NAME) \
: "$1", "$16", "$22", "$23", "$24", "$25"); \
return __r0; \
}
#define __CALL_HMC_W1(NAME, TYPE0) \
static inline void NAME(TYPE0 arg0) \
{ \
register TYPE0 __r16 __asm__("$16") = arg0; \
__asm__ __volatile__( \
"sys_call %1 # "#NAME \
: "=r"(__r16) \
: "i"(HMC_ ## NAME), "0"(__r16) \
: "$1", "$22", "$23", "$24", "$25"); \
}
#define __CALL_HMC_W2(NAME, TYPE0, TYPE1) \
static inline void NAME(TYPE0 arg0, TYPE1 arg1) \
{ \
register TYPE0 __r16 __asm__("$16") = arg0; \
register TYPE1 __r17 __asm__("$17") = arg1; \
__asm__ __volatile__( \
"sys_call %2 # "#NAME \
: "=r"(__r16), "=r"(__r17) \
: "i"(HMC_ ## NAME), "0"(__r16), "1"(__r17) \
: "$1", "$22", "$23", "$24", "$25"); \
}
#define __CALL_HMC_RW1(NAME, RTYPE, TYPE0) \
static inline RTYPE NAME(TYPE0 arg0) \
{ \
register RTYPE __r0 __asm__("$0"); \
register TYPE0 __r16 __asm__("$16") = arg0; \
__asm__ __volatile__( \
"sys_call %2 # "#NAME \
: "=r"(__r16), "=r"(__r0) \
: "i"(HMC_ ## NAME), "0"(__r16) \
: "$1", "$22", "$23", "$24", "$25"); \
return __r0; \
}
#define __CALL_HMC_RW2(NAME, RTYPE, TYPE0, TYPE1) \
static inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1) \
{ \
register RTYPE __r0 __asm__("$0"); \
register TYPE0 __r16 __asm__("$16") = arg0; \
register TYPE1 __r17 __asm__("$17") = arg1; \
__asm__ __volatile__( \
"sys_call %3 # "#NAME \
: "=r"(__r16), "=r"(__r17), "=r"(__r0) \
: "i"(HMC_ ## NAME), "0"(__r16), "1"(__r17) \
: "$1", "$22", "$23", "$24", "$25"); \
return __r0; \
}
#define __CALL_HMC_RW3(NAME, RTYPE, TYPE0, TYPE1, TYPE2) \
static inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1, TYPE2 arg2) \
{ \
register RTYPE __r0 __asm__("$0"); \
register TYPE0 __r16 __asm__("$16") = arg0; \
register TYPE1 __r17 __asm__("$17") = arg1; \
register TYPE2 __r18 __asm__("$18") = arg2; \
__asm__ __volatile__( \
"sys_call %4 # "#NAME \
: "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0) \
: "i"(HMC_ ## NAME), "0"(__r16), "1"(__r17), "2"(__r18) \
: "$1", "$22", "$23", "$24", "$25"); \
return __r0; \
}
#define sflush() \
{ \
__asm__ __volatile__("sys_call 0x2f"); \
}
__CALL_HMC_R0(rdps, unsigned long);
__CALL_HMC_R0(rdusp, unsigned long);
__CALL_HMC_W1(wrusp, unsigned long);
__CALL_HMC_R0(rdksp, unsigned long);
__CALL_HMC_W1(wrksp, unsigned long);
__CALL_HMC_W2(load_mm, unsigned long, unsigned long);
__CALL_HMC_R0(rdpcbb, unsigned long);
__CALL_HMC_W1(wrpcbb, unsigned long);
__CALL_HMC_R0(rdptbr, unsigned long);
__CALL_HMC_W1(wrptbr, unsigned long);
__CALL_HMC_RW1(swpipl, unsigned long, unsigned long);
__CALL_HMC_R0(whami, unsigned long);
__CALL_HMC_RW1(rdio64, unsigned long, unsigned long);
__CALL_HMC_RW1(rdio32, unsigned int, unsigned long);
__CALL_HMC_R0(kvcpucb, unsigned long);
__CALL_HMC_R0(sleepen, unsigned long);
__CALL_HMC_R0(mtinten, unsigned long);
__CALL_HMC_W2(wrent, void*, unsigned long);
__CALL_HMC_W2(tbisasn, unsigned long, unsigned long);
__CALL_HMC_W1(wrkgp, unsigned long);
__CALL_HMC_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
__CALL_HMC_RW3(sendii, unsigned long, unsigned long, unsigned long, unsigned long);
__CALL_HMC_W1(wrtimer, unsigned long);
__CALL_HMC_RW3(tbivpn, unsigned long, unsigned long, unsigned long, unsigned long);
__CALL_HMC_RW2(cpuid, unsigned long, unsigned long, unsigned long);
/*
* TB routines..
*/
#define __tbi(nr, arg, arg1...) \
({ \
register unsigned long __r16 __asm__("$16") = (nr); \
register unsigned long __r17 __asm__("$17"); arg; \
__asm__ __volatile__( \
"sys_call %3 #__tbi" \
: "=r" (__r16), "=r" (__r17) \
: "0" (__r16), "i" (HMC_tbi), ##arg1 \
: "$0", "$1", "$22", "$23", "$24", "$25"); \
})
#define tbi(x, y) __tbi(x, __r17 = (y), "1" (__r17))
#define tbisi(x) __tbi(1, __r17 = (x), "1" (__r17))
#define tbisd(x) __tbi(2, __r17 = (x), "1" (__r17))
#define tbis(x) __tbi(3, __r17 = (x), "1" (__r17))
#define tbiap() __tbi(-1, /* no second argument */)
#define tbia() __tbi(-2, /* no second argument */)
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_SW64_HMC_H */