KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
mmu.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 arch/dreamcast/include/arch/mmu.h
4 Copyright (C) 2001 Megan Potter
5
6*/
7
8/** \file arch/mmu.h
9 \brief Memory Management Unit and Translation Lookaside Buffer handling.
10 \ingroup mmu
11
12 This file defines the interface to the Memory Management Unit (MMU) in the
13 SH4. The MMU, while not used normally by KOS, is available for virtual
14 memory use, if you so desire. While using this functionality is probably
15 overkill for most homebrew, there are a few very interesting things that
16 this functionality could be used for (like mapping large files into memory
17 that wouldn't otherwise fit).
18
19 The whole system is set up as a normal paged memory virtual->physical
20 address translation. KOS implements the page table as a sparse, two-level
21 page table. By default, pages are 4KB in size. Each top-level page table
22 entry has 512 2nd level entries (there are 1024 entries in the top-level
23 entry). This works out to about 2KB of space needed for one top-level entry.
24
25 The SH4 itself has 4 TLB entries for instruction fetches, and 64 "unified"
26 TLB entries (for combined instructions + data). Essentially, the UTLB acts
27 both as the TLB for data accesses (from mov instructions) and as a cache for
28 entries for the ITLB. If there is no entry in the ITLB for an instruction
29 access, the UTLB will automatically be searched. If no entry is found still,
30 an ITLB miss exception will be generated. Data accesses are handled
31 similarly to this (although additional complications are involved due to
32 write accesses, and of course the ITLB doesn't play into data accesses).
33
34 For more information about how the MMU works, refer to the Hitachi/Renesas
35 SH4 programming manual. It has much more detailed information than what is
36 in here, for obvious reasons.
37
38 This functionality was ported over to mainline KOS from the KOS-MMU project
39 of Megan Potter. Unfortunately, KOS-MMU never reached a real phase of maturity
40 and usefulness, but this piece can be quite useful on its own.
41
42 \author Megan Potter
43*/
44
45#ifndef __ARCH_MMU_H
46#define __ARCH_MMU_H
47
48#include <sys/cdefs.h>
49__BEGIN_DECLS
50
51#include <stdbool.h>
52
53#include <arch/types.h>
54#include <sys/uio.h>
55
56/** \defgroup mmu MMU
57 \brief Driver for the SH4's MMU (disabled by default).
58 \ingroup system
59
60 Since the software has to handle TLB misses on the SH-4, we have freedom
61 to use any page table format we want (and thus save space), but we must
62 make it quick to access. The SH-4 can address a maximum of 512M of address
63 space per "area", but we only care about one area, so this is the total
64 maximum addressable space. With 4K pages, that works out to 2^17 pages
65 that must be mappable, or 17 bits. We use 18 bits just to be sure (there
66 are a few left over).
67
68 Page tables (per-process) are a sparse two-level array. The virtual address
69 space is actually 2^30 bytes, or 2^(30-12)=2^18 pages, so there must be
70 a possibility of having that many page entries per process space. A full
71 page table for a process would be 1M, so this is obviously too big!! Thus
72 the sparse array.
73
74 The bottom layer of the page tables consists of a sub-context array for
75 512 pages, which translates into 2K of storage space. The process then
76 has the possibility of using one or more of the 512 top-level slots. For
77 a very small process (using one page for code/data and one for stack), it
78 should be possible to achieve a page table footprint of one page. The tables
79 can grow from there as necessary.
80
81 Virtual addresses are broken up as follows:
82 - Bits 31 - 22 10 bits top-level page directory
83 - Bits 21 - 13 9 bits bottom-level page entry
84 - Bits 11 - 0 Byte index into page
85
86*/
87
88/** \defgroup mmu_bit_macros Address Bits
89 \brief Definitions and masks for address pages
90 \ingroup mmu
91
92 The MMU code uses these to determine the page of a request.
93
94 @{
95*/
96#define MMU_TOP_SHIFT 21 /**< \brief Top-level shift */
97#define MMU_TOP_BITS 10 /**< \brief Top-level bits */
98#define MMU_TOP_MASK ((1 << MMU_TOP_BITS) - 1) /**< \brief Top-level mask */
99#define MMU_BOT_SHIFT 12 /**< \brief Bottom shift */
100#define MMU_BOT_BITS 9 /**< \brief Bottom bits */
101#define MMU_BOT_MASK ((1 << MMU_BOT_BITS) - 1) /**< \brief Bottom mask */
102#define MMU_IND_SHIFT 0 /**< \brief Index shift */
103#define MMU_IND_BITS 12 /**< \brief Index bits */
104#define MMU_IND_MASK ((1 << MMU_IND_BITS) - 1) /**< \brief Index mask */
105/** @} */
106
107/** \defgroup mmu_prot_values Protection Settings
108 \brief SH4 MMU page protection settings values
109 \ingroup mmu
110
111 Each page mapped via the MMU can be protected in a couple of different ways,
112 as specified here.
113
114 @{
115*/
116#define MMU_KERNEL_RDONLY 0 /**< \brief No user access, kernel read-only */
117#define MMU_KERNEL_RDWR 1 /**< \brief No user access, kernel full */
118#define MMU_ALL_RDONLY 2 /**< \brief Read-only user and kernel */
119#define MMU_ALL_RDWR 3 /**< \brief Full access, user and kernel */
120/** @} */
121
122/** \defgroup mmu_cache_values Cacheability Settings
123 \brief SH4 MMU page cachability settings values
124 \ingroup mmu
125
126 Each page mapped via the MMU can have its cacheability set individually.
127
128 @{
129*/
130#define MMU_NO_CACHE 1 /**< \brief Cache disabled */
131#define MMU_CACHE_BACK 2 /**< \brief Write-back caching */
132#define MMU_CACHE_WT 3 /**< \brief Write-through caching */
133#define MMU_CACHEABLE MMU_CACHE_BACK /**< \brief Default caching */
134/** @} */
135
136/** \brief MMU TLB entry for a single page.
137 \ingroup mmu
138
139 The TLB entries on the SH4 are a single 32-bit dword in length. We store
140 some other data here too for ease of use.
141
142 \headerfile arch/mmu.h
143*/
144typedef struct mmupage {
145 /* Explicit pieces, used for reference */
146 /*uint32 virtual; */ /* implicit */
147 uint32 physical: 18; /**< \brief Physical page ID -- 18 bits */
148 uint32 prkey: 2; /**< \brief Protection key data -- 2 bits */
149 uint32 valid: 1; /**< \brief Valid mapping -- 1 bit */
150 uint32 shared: 1; /**< \brief Shared between procs -- 1 bit */
151 uint32 cache: 1; /**< \brief Cacheable -- 1 bit */
152 uint32 dirty: 1; /**< \brief Dirty -- 1 bit */
153 uint32 wthru: 1; /**< \brief Write-thru enable -- 1 bit */
154 uint32 blank: 7; /**< \brief Reserved -- 7 bits */
155
156 /* Pre-compiled pieces. These waste a bit of ram, but they also
157 speed loading immensely at runtime. */
158 uint32 pteh; /**< \brief Pre-built PTEH value */
159 uint32 ptel; /**< \brief Pre-built PTEL value */
160} mmupage_t;
161
162/** \brief The number of pages in a sub-context.
163 \ingroup mmu
164 */
165#define MMU_SUB_PAGES 512
166
167/** \brief MMU sub-context type.
168 \ingroup mmu
169
170 We have two-level page tables on SH4, and each sub-context contains 512
171 entries.
172
173 \headerfile arch/mmu.h
174*/
175typedef struct mmusubcontext {
176 mmupage_t page[MMU_SUB_PAGES]; /**< \brief 512 page entries */
178
179/** \brief The number of sub-contexts in the main level context. */
180#define MMU_PAGES 1024
181
182/** \brief MMU context type.
183 \ingroup mmu
184
185 This type is the top-level context that makes up the page table. There is
186 one of these, with 1024 sub-contexts.
187
188 \headerfile arch/mmu.h
189*/
190typedef struct mmucontext {
191 mmusubcontext_t *sub[MMU_PAGES]; /**< \brief 1024 sub-contexts */
192 int asid; /**< \brief Address Space ID */
194
195/** \cond
196 You should not modify this directly, but rather use the functions provided
197 to do so.
198*/
199extern mmucontext_t *mmu_cxt_current;
200/** \endcond */
201
202/** \brief Set the "current" page tables for TLB handling.
203 \ingroup mmu
204
205 This function is useful if you're trying to implement a process model or
206 something of the like on top of KOS. Essentially, this allows you to
207 completely boot the MMU context in use out and replace it with another. You
208 will need to call the mmu_switch_context() function afterwards to set the
209 address space id.
210
211 \param context The context to make current.
212*/
214
215/** \brief Allocate a new MMU context.
216 \ingroup mmu
217
218 Each process should have exactly one of these, and these should not exist
219 without a process. Since KOS doesn't actually have a process model of its
220 own, that means you will only ever have one of these, if any.
221
222 \param asid The address space ID of this process.
223 \return The newly created context or NULL on fail.
224*/
226
227/** \brief Destroy an MMU context when a process is being destroyed.
228 \ingroup mmu
229
230 This function cleans up a MMU context, deallocating any memory its using.
231
232 \param context The context to clean up after.
233*/
235
236/** \brief Using the given page tables, translate the virtual page ID to a
237 physical page ID.
238 \ingroup mmu
239
240 \param context The context to look in.
241 \param virtpage The virtual page number to look for.
242 \return The physical page number, or -1 on failure.
243 \see mmu_phys_to_virt()
244*/
245int mmu_virt_to_phys(mmucontext_t *context, int virtpage);
246
247/** \brief Using the given page tables, translate the physical page ID to a
248 virtual page ID.
249 \ingroup mmu
250
251 \param context The context to look in.
252 \param physpage The physical page number to look for.
253 \return The virtual page number, or -1 on failure.
254 \see mmu_virt_to_phys()
255*/
256int mmu_phys_to_virt(mmucontext_t *context, int physpage);
257
258/** \brief Switch to the given context.
259 \ingroup mmu
260
261 This function switches to the given context's address space ID. The context
262 should have already been made current with mmu_use_table().
263 You are responsible for invalidating any caches as necessary, as well as
264 invalidating any stale TLB entries.
265
266 \param context The context to make current.
267*/
269
270/** \brief Set the given virtual page to map to the given physical page.
271 \ingroup mmu
272
273 This implies turning on the "valid" bit. Also sets the other named
274 attributes as specified.
275
276 \param context The context to modify.
277 \param virtpage The first virtual page to map.
278 \param physpage The first physical page to map.
279 \param count The number of sequential pages to map.
280 \param prot Memory protection for page (see
281 \ref mmu_prot_values).
282 \param cache Cache scheme for page (see \ref mmu_cache_values).
283 \param share Set to 1 to share between processes (meaningless),
284 otherwise set to 0.
285 \param dirty Set to 1 to mark the page as dirty, otherwise set to
286 0.
287*/
288void mmu_page_map(mmucontext_t *context, int virtpage, int physpage,
289 int count, int prot, int cache, int share, int dirty);
290
291/** \brief Copy a chunk of data from a process' address space into a kernel
292 buffer, taking into account page mappings.
293 \ingroup mmu
294
295 \param context The context to use.
296 \param srcaddr Source, in the mapped memory space.
297 \param srccnt The number of bytes to copy.
298 \param buffer The kernel buffer to copy into (should be in P1).
299 \return The number of bytes copied (failure causes arch_panic).
300*/
301int mmu_copyin(mmucontext_t *context, uint32 srcaddr, uint32 srccnt,
302 void *buffer);
303
304/** \brief Copy a chunk of data from one process' address space to another
305 process' address space, taking into account page mappings.
306 \ingroup mmu
307
308 \param context1 The source's context.
309 \param iov1 The scatter/gather array to copy from.
310 \param iovcnt1 The number of entries in iov1.
311 \param context2 The destination's context.
312 \param iov2 The scatter/gather array to copy to.
313 \param iovcnt2 The number of entries in iov2.
314 \return The number of bytes copied (failure causes arch_panic).
315*/
316int mmu_copyv(mmucontext_t *context1, struct iovec *iov1, int iovcnt1,
317 mmucontext_t *context2, struct iovec *iov2, int iovcnt2);
318
319/** \brief MMU mapping handler.
320 \ingroup mmu
321
322 This type is used for functions that will take over the mapping for the
323 kernel. In general, there shouldn't be much use for taking this over
324 yourself, unless you want to change the size of the page table entries or
325 something of the like.
326
327 \param context The context in use.
328 \param virtpage The virtual page to map.
329 \return The page table entry, or NULL if none exists.
330*/
331typedef mmupage_t * (*mmu_mapfunc_t)(mmucontext_t * context, int virtpage);
332
333/** \brief Get the current mapping function.
334 \ingroup mmu
335 \return The current function that maps pages.
336*/
338
339/** \brief Set a new MMU mapping handler.
340 \ingroup mmu
341
342 This function will allow you to set a new function to handle mapping for
343 memory pages. There's not much of a reason to do this unless you really do
344 not like the way KOS handles the page mapping internally.
345
346 \param newfunc The new function to handle mapping.
347 \return The old function that did mapping.
348*/
350
351/** \brief Initialize MMU support.
352 \ingroup mmu
353
354 Unlike most things in KOS, the MMU is not initialized by a normal startup.
355 This is because for most homebrew, its not needed.
356
357 \retval 0 On success (no error conditions defined).
358*/
359int mmu_init(void);
360
361/** \brief Shutdown MMU support.
362 \ingroup mmu
363
364 Turn off the MMU after it was initialized. You should try to make sure this
365 gets done if you initialize the MMU in your program, so as to play nice with
366 loaders and the like (that will not expect that its on, in general).
367*/
368void mmu_shutdown(void);
369
370/** \brief Reset ITLB.
371 \ingroup mmu
372 */
373void mmu_reset_itlb(void);
374
375/** \brief Check if MMU translation is enabled.
376 \ingroup mmu
377
378 \return True if MMU translation is enabled, false otherwise.
379 */
380bool mmu_enabled(void);
381
382/** \brief Reset the base target address for store queues.
383 * \ingroup mmu
384 *
385 * \param addr The base address to reset to */
386void mmu_set_sq_addr(void *addr);
387
388__END_DECLS
389
390#endif /* __ARCH_MMU_H */
void mmu_context_destroy(mmucontext_t *context)
Destroy an MMU context when a process is being destroyed.
mmu_mapfunc_t mmu_map_set_callback(mmu_mapfunc_t newfunc)
Set a new MMU mapping handler.
#define MMU_SUB_PAGES
The number of pages in a sub-context.
Definition mmu.h:165
void mmu_switch_context(mmucontext_t *context)
Switch to the given context.
int mmu_phys_to_virt(mmucontext_t *context, int physpage)
Using the given page tables, translate the physical page ID to a virtual page ID.
mmupage_t *(* mmu_mapfunc_t)(mmucontext_t *context, int virtpage)
MMU mapping handler.
Definition mmu.h:331
mmucontext_t * mmu_context_create(int asid)
Allocate a new MMU context.
int mmu_init(void)
Initialize MMU support.
void mmu_use_table(mmucontext_t *context)
Set the "current" page tables for TLB handling.
int mmu_virt_to_phys(mmucontext_t *context, int virtpage)
Using the given page tables, translate the virtual page ID to a physical page ID.
void mmu_shutdown(void)
Shutdown MMU support.
void mmu_page_map(mmucontext_t *context, int virtpage, int physpage, int count, int prot, int cache, int share, int dirty)
Set the given virtual page to map to the given physical page.
void mmu_set_sq_addr(void *addr)
Reset the base target address for store queues.
void mmu_reset_itlb(void)
Reset ITLB.
int mmu_copyv(mmucontext_t *context1, struct iovec *iov1, int iovcnt1, mmucontext_t *context2, struct iovec *iov2, int iovcnt2)
Copy a chunk of data from one process' address space to another process' address space,...
mmu_mapfunc_t mmu_map_get_callback(void)
Get the current mapping function.
int mmu_copyin(mmucontext_t *context, uint32 srcaddr, uint32 srccnt, void *buffer)
Copy a chunk of data from a process' address space into a kernel buffer, taking into account page map...
bool mmu_enabled(void)
Check if MMU translation is enabled.
unsigned long uint32
32-bit unsigned integer
Definition types.h:33
#define MMU_PAGES
The number of sub-contexts in the main level context.
Definition mmu.h:180
I/O vector structure.
Definition uio.h:34
MMU context type.
Definition mmu.h:190
int asid
Address Space ID.
Definition mmu.h:192
MMU TLB entry for a single page.
Definition mmu.h:144
uint32 shared
Shared between procs – 1 bit.
Definition mmu.h:150
uint32 dirty
Dirty – 1 bit.
Definition mmu.h:152
uint32 prkey
Protection key data – 2 bits.
Definition mmu.h:148
uint32 blank
Reserved – 7 bits.
Definition mmu.h:154
uint32 cache
Cacheable – 1 bit.
Definition mmu.h:151
uint32 pteh
Pre-built PTEH value.
Definition mmu.h:158
uint32 wthru
Write-thru enable – 1 bit.
Definition mmu.h:153
uint32 valid
Valid mapping – 1 bit.
Definition mmu.h:149
uint32 ptel
Pre-built PTEL value.
Definition mmu.h:159
uint32 physical
Physical page ID – 18 bits.
Definition mmu.h:147
MMU sub-context type.
Definition mmu.h:175
Common integer types.
Header for terminal control operations.