summaryrefslogtreecommitdiff
path: root/sys/arch/riscv/include/pmap.h
blob: 4d2ee5bb01e2f000c2b7d69b8bfce6748df1579a (plain)
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
/* $NetBSD: pmap.h,v 1.18 2023/06/12 19:04:14 skrll Exp $ */

/*
 * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Matt Thomas (of 3am Software Foundry), Maxime Villard, and
 * Nick Hudson.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _RISCV_PMAP_H_
#define	_RISCV_PMAP_H_

#ifdef _KERNEL_OPT
#include "opt_modular.h"
#endif

#if !defined(_MODULE)

#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/pool.h>
#include <sys/evcnt.h>

#include <uvm/uvm_physseg.h>
#include <uvm/pmap/vmpagemd.h>

#include <riscv/pte.h>
#include <riscv/sysreg.h>

#define	PMAP_SEGTABSIZE	NPTEPG
#define	PMAP_PDETABSIZE	NPTEPG

#ifdef _LP64
#define	PTPSHIFT	3
/* This is SV57. */
//#define	XSEGSHIFT	(SEGSHIFT + SEGLENGTH + SEGLENGTH + SEGLENGTH)

/* This is SV48. */
//#define	XSEGSHIFT	(SEGSHIFT + SEGLENGTH + SEGLENGTH)

/* This is SV39. */
#define	XSEGSHIFT	(SEGSHIFT + SEGLENGTH)
#define	NBXSEG		(1ULL << XSEGSHIFT)
#define	XSEGOFSET	(NBXSEG - 1)		/* byte offset into xsegment */
#define	XSEGLENGTH	(PGSHIFT - 3)
#define	NXSEGPG		(1 << XSEGLENGTH)
#else
#define	PTPSHIFT	2
#define	XSEGSHIFT	SEGSHIFT
#endif

#define	SEGLENGTH	(PGSHIFT - PTPSHIFT)
#define	SEGSHIFT	(SEGLENGTH + PGSHIFT)
#define	NBSEG		(1 << SEGSHIFT)		/* bytes/segment */
#define	SEGOFSET	(NBSEG - 1)		/* byte offset into segment */

#define	KERNEL_PID	0

#define	PMAP_HWPAGEWALKER		1
#define	PMAP_TLB_MAX			MAXCPUS
#ifdef _LP64
#define	PMAP_INVALID_PDETAB_ADDRESS	((pmap_pdetab_t *)(VM_MIN_KERNEL_ADDRESS - PAGE_SIZE))
#define	PMAP_INVALID_SEGTAB_ADDRESS	((pmap_segtab_t *)(VM_MIN_KERNEL_ADDRESS - PAGE_SIZE))
#else
#define	PMAP_INVALID_PDETAB_ADDRESS	((pmap_pdetab_t *)0xdeadbeef)
#define	PMAP_INVALID_SEGTAB_ADDRESS	((pmap_segtab_t *)0xdeadbeef)
#endif
#define	PMAP_TLB_NUM_PIDS		(__SHIFTOUT_MASK(SATP_ASID) + 1)
#define	PMAP_TLB_BITMAP_LENGTH          PMAP_TLB_NUM_PIDS
// Should use SBI TLB ops
#define	PMAP_TLB_NEED_SHOOTDOWN		1
#define	PMAP_TLB_FLUSH_ASID_ON_RESET	false

#define	pmap_phys_address(x)		(x)

#ifndef __BSD_PTENTRY_T__
#define	__BSD_PTENTRY_T__
#ifdef _LP64
#define	PRIxPTE         PRIx64
#else
#define	PRIxPTE         PRIx32
#endif
#endif /* __BSD_PTENTRY_T__ */

#define	PMAP_NEED_PROCWR
static inline void
pmap_procwr(struct proc *p, vaddr_t va, vsize_t len)
{
	__asm __volatile("fence\trw,rw; fence.i" ::: "memory");
}

#include <uvm/pmap/tlb.h>
#include <uvm/pmap/pmap_devmap.h>
#include <uvm/pmap/pmap_tlb.h>
#include <uvm/pmap/pmap_synci.h>

#define	PMAP_GROWKERNEL
#define	PMAP_STEAL_MEMORY

#ifdef _KERNEL

#define	__HAVE_PMAP_MD
struct pmap_md {
	paddr_t md_ppn;
};

static inline void
pmap_md_icache_sync_all(void)
{
}

static inline void
pmap_md_icache_sync_range_index(vaddr_t va, vsize_t size)
{
}

struct vm_page *
	pmap_md_alloc_poolpage(int);
vaddr_t	pmap_md_map_poolpage(paddr_t, vsize_t);
void	pmap_md_unmap_poolpage(vaddr_t, vsize_t);

bool	pmap_md_direct_mapped_vaddr_p(vaddr_t);
paddr_t	pmap_md_direct_mapped_vaddr_to_paddr(vaddr_t);
vaddr_t	pmap_md_direct_map_paddr(paddr_t);
void	pmap_md_init(void);
bool	pmap_md_io_vaddr_p(vaddr_t);
bool	pmap_md_ok_to_steal_p(const uvm_physseg_t, size_t);
void	pmap_md_pdetab_init(struct pmap *);
void	pmap_md_pdetab_fini(struct pmap *);
void	pmap_md_tlb_info_attach(struct pmap_tlb_info *, struct cpu_info *);
void	pmap_md_xtab_activate(struct pmap *, struct lwp *);
void	pmap_md_xtab_deactivate(struct pmap *);

void	pmap_bootstrap(vaddr_t, vaddr_t);

vsize_t	pmap_kenter_range(vaddr_t, paddr_t, vsize_t, vm_prot_t, u_int);

#ifdef _LP64
extern vaddr_t pmap_direct_base;
extern vaddr_t pmap_direct_end;
#define	PMAP_DIRECT_MAP(pa)	RISCV_PA_TO_KVA(pa)
#define	PMAP_DIRECT_UNMAP(va)	RISCV_KVA_TO_PA(va)

/*
 * Other hooks for the pool allocator.
 */
#define	POOL_PHYSTOV(pa)	RISCV_PA_TO_KVA((paddr_t)(pa))
#define	POOL_VTOPHYS(va)	RISCV_KVA_TO_PA((vaddr_t)(va))

#endif	/* _LP64 */

#define	MEGAPAGE_TRUNC(x)	((x) & ~SEGOFSET)
#define	MEGAPAGE_ROUND(x)	MEGAPAGE_TRUNC((x) + SEGOFSET)

#define	PMAP_DEV		__BIT(29)	/* 0x2000_0000 */

#define	DEVMAP_ALIGN(x)		MEGAPAGE_TRUNC((x))
#define	DEVMAP_SIZE(x)		MEGAPAGE_ROUND((x))
#define	DEVMAP_FLAGS		PMAP_DEV

#ifdef __PMAP_PRIVATE

static inline bool
pmap_md_tlb_check_entry(void *ctx, vaddr_t va, tlb_asid_t asid, pt_entry_t pte)
{
        // TLB not walked and so not called.
        return false;
}

static inline void
pmap_md_page_syncicache(struct vm_page_md *mdpg, const kcpuset_t *kc)
{
	__asm __volatile("fence\trw,rw; fence.i" ::: "memory");
}

/*
 * Virtual Cache Alias helper routines.  Not a problem for RISCV CPUs.
 */
static inline bool
pmap_md_vca_add(struct vm_page_md *mdpg, vaddr_t va, pt_entry_t *nptep)
{
	return false;
}

static inline void
pmap_md_vca_remove(struct vm_page_md *mdpg, vaddr_t va)
{
}

static inline void
pmap_md_vca_clean(struct vm_page_md *mdpg, vaddr_t va, int op)
{
}

static inline size_t
pmap_md_tlb_asid_max(void)
{
	return PMAP_TLB_NUM_PIDS - 1;
}

static inline pt_entry_t *
pmap_md_nptep(pt_entry_t *ptep)
{
	return ptep + 1;
}

static inline bool
pmap_md_kernel_vaddr_p(vaddr_t va)
{
	return false;
}

static inline paddr_t
pmap_md_kernel_vaddr_to_paddr(vaddr_t vax)
{
	/* Not used due to false from pmap_md_kernel_vaddr_p */

	return 0;
}

#endif /* __PMAP_PRIVATE */
#endif /* _KERNEL */

#include <uvm/pmap/pmap.h>

#endif /* !_MODULE */

#if defined(MODULAR) || defined(_MODULE)
/*
 * Define a compatible vm_page_md so that struct vm_page is the same size
 * whether we are using modules or not.
 */
#ifndef __HAVE_VM_PAGE_MD
#define	__HAVE_VM_PAGE_MD

struct vm_page_md {
	uintptr_t mdpg_dummy[3];
};
__CTASSERT(sizeof(struct vm_page_md) == sizeof(uintptr_t)*3);

#endif /* !__HAVE_VM_PAGE_MD */

#endif /* MODULAR || _MODULE */

#endif /* !_RISCV_PMAP_H_ */