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