1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Author: Huacai Chen <chenhuacai@loongson.cn>
4  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
5  */
6 
7 #ifndef __ASSEMBLY__
8 
9 #include <asm/asm.h>
10 #include <asm/page.h>
11 #include <asm/vdso.h>
12 
13 struct vdso_pcpu_data {
14 	u32 node;
15 } ____cacheline_aligned_in_smp;
16 
17 struct loongarch_vdso_data {
18 	struct vdso_pcpu_data pdata[NR_CPUS];
19 };
20 
21 /*
22  * The layout of vvar:
23  *
24  *                      high
25  * +---------------------+--------------------------+
26  * | loongarch vdso data | LOONGARCH_VDSO_DATA_SIZE |
27  * +---------------------+--------------------------+
28  * |  time-ns vdso data  |        PAGE_SIZE         |
29  * +---------------------+--------------------------+
30  * |  generic vdso data  |        PAGE_SIZE         |
31  * +---------------------+--------------------------+
32  *                      low
33  */
34 #define LOONGARCH_VDSO_DATA_SIZE PAGE_ALIGN(sizeof(struct loongarch_vdso_data))
35 #define LOONGARCH_VDSO_DATA_PAGES (LOONGARCH_VDSO_DATA_SIZE >> PAGE_SHIFT)
36 
37 enum vvar_pages {
38 	VVAR_GENERIC_PAGE_OFFSET,
39 	VVAR_TIMENS_PAGE_OFFSET,
40 	VVAR_LOONGARCH_PAGES_START,
41 	VVAR_LOONGARCH_PAGES_END = VVAR_LOONGARCH_PAGES_START + LOONGARCH_VDSO_DATA_PAGES - 1,
42 	VVAR_NR_PAGES,
43 };
44 
45 #define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
46 
47 static inline unsigned long get_vdso_base(void)
48 {
49 	unsigned long addr;
50 
51 	__asm__(
52 	" la.pcrel %0, _start\n"
53 	: "=r" (addr)
54 	:
55 	:);
56 
57 	return addr;
58 }
59 
60 static inline unsigned long get_vdso_data(void)
61 {
62 	return get_vdso_base() - VVAR_SIZE;
63 }
64 
65 #endif /* __ASSEMBLY__ */
66