summaryrefslogtreecommitdiffstats
path: root/src/arch/riscv/include/bits/virt_offset.h
blob: 83ac175514def7d5fb41210dc509d4308bf4b54d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef _BITS_VIRT_OFFSET_H
#define _BITS_VIRT_OFFSET_H

/** @file
 *
 * RISCV-specific virtual address offset
 *
 * We use the thread pointer register (tp) to hold the virtual address
 * offset, so that virtual-to-physical address translations work as
 * expected even while we are executing directly from read-only memory
 * (and so cannot store a value in a global virt_offset variable).
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/**
 * Read virtual address offset held in thread pointer register
 *
 * @ret virt_offset	Virtual address offset
 */
static inline __attribute__ (( const, always_inline )) unsigned long
tp_virt_offset ( void ) {
	register unsigned long tp asm ( "tp" );

	__asm__ ( "" : "=r" ( tp ) );
	return tp;
}

/** Always read thread pointer register to get virtual address offset */
#define virt_offset tp_virt_offset()

#endif /* _BITS_VIRT_OFFSET_H */