18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_IA64_RSE_H 38c2ecf20Sopenharmony_ci#define _ASM_IA64_RSE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * Copyright (C) 1998, 1999 Hewlett-Packard Co 78c2ecf20Sopenharmony_ci * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Register stack engine related helper functions. This file may be 108c2ecf20Sopenharmony_ci * used in applications, so be careful about the name-space and give 118c2ecf20Sopenharmony_ci * some consideration to non-GNU C compilers (though __inline__ is 128c2ecf20Sopenharmony_ci * fine). 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic __inline__ unsigned long 168c2ecf20Sopenharmony_ciia64_rse_slot_num (unsigned long *addr) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci return (((unsigned long) addr) >> 3) & 0x3f; 198c2ecf20Sopenharmony_ci} 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* 228c2ecf20Sopenharmony_ci * Return TRUE if ADDR is the address of an RNAT slot. 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_cistatic __inline__ unsigned long 258c2ecf20Sopenharmony_ciia64_rse_is_rnat_slot (unsigned long *addr) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci return ia64_rse_slot_num(addr) == 0x3f; 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Returns the address of the RNAT slot that covers the slot at 328c2ecf20Sopenharmony_ci * address SLOT_ADDR. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_cistatic __inline__ unsigned long * 358c2ecf20Sopenharmony_ciia64_rse_rnat_addr (unsigned long *slot_addr) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3)); 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Calculate the number of registers in the dirty partition starting at BSPSTORE and 428c2ecf20Sopenharmony_ci * ending at BSP. This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores 438c2ecf20Sopenharmony_ci * ar.rnat. 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_cistatic __inline__ unsigned long 468c2ecf20Sopenharmony_ciia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci unsigned long slots = (bsp - bspstore); 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* 548c2ecf20Sopenharmony_ci * The inverse of the above: given bspstore and the number of 558c2ecf20Sopenharmony_ci * registers, calculate ar.bsp. 568c2ecf20Sopenharmony_ci */ 578c2ecf20Sopenharmony_cistatic __inline__ unsigned long * 588c2ecf20Sopenharmony_ciia64_rse_skip_regs (unsigned long *addr, long num_regs) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci long delta = ia64_rse_slot_num(addr) + num_regs; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (num_regs < 0) 638c2ecf20Sopenharmony_ci delta -= 0x3e; 648c2ecf20Sopenharmony_ci return addr + num_regs + delta/0x3f; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#endif /* _ASM_IA64_RSE_H */ 68