xref: /OK3568_Linux_fs/kernel/arch/ia64/include/uapi/asm/rse.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2*4882a593Smuzhiyun #ifndef _ASM_IA64_RSE_H
3*4882a593Smuzhiyun #define _ASM_IA64_RSE_H
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun /*
6*4882a593Smuzhiyun  * Copyright (C) 1998, 1999 Hewlett-Packard Co
7*4882a593Smuzhiyun  * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * Register stack engine related helper functions.  This file may be
10*4882a593Smuzhiyun  * used in applications, so be careful about the name-space and give
11*4882a593Smuzhiyun  * some consideration to non-GNU C compilers (though __inline__ is
12*4882a593Smuzhiyun  * fine).
13*4882a593Smuzhiyun  */
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun static __inline__ unsigned long
ia64_rse_slot_num(unsigned long * addr)16*4882a593Smuzhiyun ia64_rse_slot_num (unsigned long *addr)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun 	return (((unsigned long) addr) >> 3) & 0x3f;
19*4882a593Smuzhiyun }
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * Return TRUE if ADDR is the address of an RNAT slot.
23*4882a593Smuzhiyun  */
24*4882a593Smuzhiyun static __inline__ unsigned long
ia64_rse_is_rnat_slot(unsigned long * addr)25*4882a593Smuzhiyun ia64_rse_is_rnat_slot (unsigned long *addr)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun 	return ia64_rse_slot_num(addr) == 0x3f;
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /*
31*4882a593Smuzhiyun  * Returns the address of the RNAT slot that covers the slot at
32*4882a593Smuzhiyun  * address SLOT_ADDR.
33*4882a593Smuzhiyun  */
34*4882a593Smuzhiyun static __inline__ unsigned long *
ia64_rse_rnat_addr(unsigned long * slot_addr)35*4882a593Smuzhiyun ia64_rse_rnat_addr (unsigned long *slot_addr)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun 	return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun  * Calculate the number of registers in the dirty partition starting at BSPSTORE and
42*4882a593Smuzhiyun  * ending at BSP.  This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores
43*4882a593Smuzhiyun  * ar.rnat.
44*4882a593Smuzhiyun  */
45*4882a593Smuzhiyun static __inline__ unsigned long
ia64_rse_num_regs(unsigned long * bspstore,unsigned long * bsp)46*4882a593Smuzhiyun ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	unsigned long slots = (bsp - bspstore);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun  * The inverse of the above: given bspstore and the number of
55*4882a593Smuzhiyun  * registers, calculate ar.bsp.
56*4882a593Smuzhiyun  */
57*4882a593Smuzhiyun static __inline__ unsigned long *
ia64_rse_skip_regs(unsigned long * addr,long num_regs)58*4882a593Smuzhiyun ia64_rse_skip_regs (unsigned long *addr, long num_regs)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	long delta = ia64_rse_slot_num(addr) + num_regs;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	if (num_regs < 0)
63*4882a593Smuzhiyun 		delta -= 0x3e;
64*4882a593Smuzhiyun 	return addr + num_regs + delta/0x3f;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #endif /* _ASM_IA64_RSE_H */
68