162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 262306a36Sopenharmony_ci#ifndef _ASM_IA64_RSE_H 362306a36Sopenharmony_ci#define _ASM_IA64_RSE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci/* 662306a36Sopenharmony_ci * Copyright (C) 1998, 1999 Hewlett-Packard Co 762306a36Sopenharmony_ci * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Register stack engine related helper functions. This file may be 1062306a36Sopenharmony_ci * used in applications, so be careful about the name-space and give 1162306a36Sopenharmony_ci * some consideration to non-GNU C compilers (though __inline__ is 1262306a36Sopenharmony_ci * fine). 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic __inline__ unsigned long 1662306a36Sopenharmony_ciia64_rse_slot_num (unsigned long *addr) 1762306a36Sopenharmony_ci{ 1862306a36Sopenharmony_ci return (((unsigned long) addr) >> 3) & 0x3f; 1962306a36Sopenharmony_ci} 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * Return TRUE if ADDR is the address of an RNAT slot. 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_cistatic __inline__ unsigned long 2562306a36Sopenharmony_ciia64_rse_is_rnat_slot (unsigned long *addr) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci return ia64_rse_slot_num(addr) == 0x3f; 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * Returns the address of the RNAT slot that covers the slot at 3262306a36Sopenharmony_ci * address SLOT_ADDR. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic __inline__ unsigned long * 3562306a36Sopenharmony_ciia64_rse_rnat_addr (unsigned long *slot_addr) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3)); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* 4162306a36Sopenharmony_ci * Calculate the number of registers in the dirty partition starting at BSPSTORE and 4262306a36Sopenharmony_ci * ending at BSP. This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores 4362306a36Sopenharmony_ci * ar.rnat. 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_cistatic __inline__ unsigned long 4662306a36Sopenharmony_ciia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci unsigned long slots = (bsp - bspstore); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * The inverse of the above: given bspstore and the number of 5562306a36Sopenharmony_ci * registers, calculate ar.bsp. 5662306a36Sopenharmony_ci */ 5762306a36Sopenharmony_cistatic __inline__ unsigned long * 5862306a36Sopenharmony_ciia64_rse_skip_regs (unsigned long *addr, long num_regs) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci long delta = ia64_rse_slot_num(addr) + num_regs; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci if (num_regs < 0) 6362306a36Sopenharmony_ci delta -= 0x3e; 6462306a36Sopenharmony_ci return addr + num_regs + delta/0x3f; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#endif /* _ASM_IA64_RSE_H */ 68