137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/*
237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * Copyright (C) 1998, 1999, 2002, 2003, 2005 Hewlett-Packard Co
337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang *	David Mosberger-Tang <davidm@hpl.hp.com>
437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang *
537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * Register stack engine related helper functions.  This file may be
637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * used in applications, so be careful about the name-space and give
737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * some consideration to non-GNU C compilers (though __inline__ is
837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * fine).
937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang */
1037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#ifndef RSE_H
1137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#define RSE_H
1237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
1337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include <libunwind.h>
1437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
1537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangstatic inline uint64_t
1637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangrse_slot_num (uint64_t addr)
1737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang{
1837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	return (addr >> 3) & 0x3f;
1937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang}
2037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
2137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/*
2237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * Return TRUE if ADDR is the address of an RNAT slot.
2337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang */
2437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangstatic inline uint64_t
2537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangrse_is_rnat_slot (uint64_t addr)
2637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang{
2737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	return rse_slot_num (addr) == 0x3f;
2837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang}
2937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
3037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/*
3137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * Returns the address of the RNAT slot that covers the slot at
3237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * address SLOT_ADDR.
3337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang */
3437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangstatic inline uint64_t
3537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangrse_rnat_addr (uint64_t slot_addr)
3637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang{
3737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	return slot_addr | (0x3f << 3);
3837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang}
3937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
4037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/*
4137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * Calculate the number of registers in the dirty partition starting at
4237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * BSPSTORE and ending at BSP.  This isn't simply (BSP-BSPSTORE)/8
4337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * because every 64th slot stores ar.rnat.
4437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang */
4537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangstatic inline uint64_t
4637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangrse_num_regs (uint64_t bspstore, uint64_t bsp)
4737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang{
4837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	uint64_t slots = (bsp - bspstore) >> 3;
4937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
5037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	return slots - (rse_slot_num(bspstore) + slots)/0x40;
5137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang}
5237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
5337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/*
5437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * The inverse of the above: given bspstore and the number of
5537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang * registers, calculate ar.bsp.
5637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang */
5737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangstatic inline uint64_t
5837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangrse_skip_regs (uint64_t addr, long num_regs)
5937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang{
6037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	long delta = rse_slot_num(addr) + num_regs;
6137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
6237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	if (num_regs < 0)
6337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang		delta -= 0x3e;
6437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang	return addr + ((num_regs + delta/0x3f) << 3);
6537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang}
6637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
6737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#endif /* RSE_H */
68