KallistiOS  2.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
Data Structures | Macros | Typedefs | Functions | Variables
mmu.h File Reference

Memory Management Unit and Translation Lookaside Buffer handling. More...

#include <sys/cdefs.h>
#include <arch/types.h>
#include <kos/iovec.h>

Go to the source code of this file.

Data Structures

struct  mmupage
 MMU TLB entry for a single page. More...
struct  mmusubcontext
 MMU sub-context type. More...
struct  mmucontext
 MMU context type. More...

Macros

#define MMU_TOP_SHIFT   21
 Top-level shift.
#define MMU_TOP_BITS   10
 Top-level bits.
#define MMU_TOP_MASK   ((1 << MMU_TOP_BITS) - 1)
 Top-level mask.
#define MMU_BOT_SHIFT   12
 Bottom shift.
#define MMU_BOT_BITS   9
 Bottom bits.
#define MMU_BOT_MASK   ((1 << MMU_BOT_BITS) - 1)
 Bottom mask.
#define MMU_IND_SHIFT   0
 Index shift.
#define MMU_IND_BITS   12
 Index bits.
#define MMU_IND_MASK   ((1 << MMU_IND_BITS) - 1)
 Index mask.
#define MMU_KERNEL_RDONLY   0
 No user access, kernel read-only.
#define MMU_KERNEL_RDWR   1
 No user access, kernel full.
#define MMU_ALL_RDONLY   2
 Read-only user and kernel.
#define MMU_ALL_RDWR   3
 Full access, user and kernel.
#define MMU_NO_CACHE   1
 Cache disabled.
#define MMU_CACHE_BACK   2
 Write-back cacheing.
#define MMU_CACHE_WT   3
 Write-through cacheing.
#define MMU_CACHEABLE   MMU_CACHE_BACK
 Default cacheing.
#define MMU_SUB_PAGES   512
 The number of pages in a sub-context.
#define MMU_PAGES   1024
 The number of sub-contexts in the main level context.

Typedefs

typedef struct mmupage mmupage_t
 MMU TLB entry for a single page.
typedef struct mmusubcontext mmusubcontext_t
 MMU sub-context type.
typedef struct mmucontext mmucontext_t
 MMU context type.
typedef mmupage_t *(* mmu_mapfunc_t )(mmucontext_t *context, int virtpage)
 MMU mapping handler.

Functions

void mmu_use_table (mmucontext_t *context)
 Set the "current" page tables for TLB handling.
mmucontext_tmmu_context_create (int asid)
 Allocate a new MMU context.
void mmu_context_destroy (mmucontext_t *context)
 Destroy an MMU context when a process is being destroyed.
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.
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.
void mmu_switch_context (mmucontext_t *context)
 Switch to the given context.
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_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 mappings.
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.
mmu_mapfunc_t mmu_map_get_callback ()
 Get the current mapping function.
mmu_mapfunc_t mmu_map_set_callback (mmu_mapfunc_t newfunc)
 Set a new MMU mapping handler.
int mmu_init ()
 Initialize MMU support.
void mmu_shutdown ()
 Shutdown MMU support.

Variables

mmucontext_tmmu_cxt_current
 "Current" page tables (for TLB exception handling).

Detailed Description

Memory Management Unit and Translation Lookaside Buffer handling.

This file defines the interface to the Memory Management Unit (MMU) in the SH4. The MMU, while not used normally by KOS, is available for virtual memory use, if you so desire. While using this functionality is probably overkill for most homebrew, there are a few very interesting things that this functionality could be used for (like mapping large files into memory that wouldn't otherwise fit).

The whole system is set up as a normal paged memory virtual->physical address translation. KOS implements the page table as a sparse, two-level page table. By default, pages are 4KB in size. Each top-level page table entry has 512 2nd level entries (there are 1024 entries in the top-level entry). This works out to about 2KB of space needed for one top-level entry.

The SH4 itself has 4 TLB entries for instruction fetches, and 64 "unified" TLB entries (for combined instructions + data). Essentially, the UTLB acts both as the TLB for data accesses (from mov instructions) and as a cache for entries for the ITLB. If there is no entry in the ITLB for an instruction access, the UTLB will automatically be searched. If no entry is found still, an ITLB miss exception will be generated. Data accesses are handled similarly to this (although additional complications are involved due to write accesses, and of course the ITLB doesn't play into data accesses).

For more information about how the MMU works, refer to the Hitachi/Renesas SH4 programming manual. It has much more detailed information than what is in here, for obvious reasons.

This functionality was ported over to mainline KOS from the KOS-MMU project of Dan Potter. Unfortunately, KOS-MMU never reached a real phase of maturity and usefulness, but this piece can be quite useful on its own.

Author:
Dan Potter

Macro Definition Documentation

#define MMU_PAGES   1024

The number of sub-contexts in the main level context.

#define MMU_SUB_PAGES   512

The number of pages in a sub-context.


Typedef Documentation

typedef mmupage_t*(* mmu_mapfunc_t)(mmucontext_t *context, int virtpage)

MMU mapping handler.

This type is used for functions that will take over the mapping for the kernel. In general, there shouldn't be much use for taking this over yourself, unless you want to change the size of the page table entries or something of the like.

Parameters:
contextThe context in use.
virtpageThe virtual page to map.
Returns:
The page table entry, or NULL if none exists.
typedef struct mmucontext mmucontext_t

MMU context type.

This type is the top-level context that makes up the page table. There is one of these, with 1024 sub-contexts.

typedef struct mmupage mmupage_t

MMU TLB entry for a single page.

The TLB entries on the SH4 are a single 32-bit dword in length. We store some other data here too for ease of use.

MMU sub-context type.

We have two-level page tables on SH4, and each sub-context contains 512 entries.


Function Documentation

mmucontext_t* mmu_context_create ( int  asid)

Allocate a new MMU context.

Each process should have exactly one of these, and these should not exist without a process. Since KOS doesn't actually have a process model of its own, that means you will only ever have one of these, if any.

Parameters:
asidThe address space ID of this process.
Returns:
The newly created context.
void mmu_context_destroy ( mmucontext_t context)

Destroy an MMU context when a process is being destroyed.

This function cleans up a MMU context, deallocating any memory its using.

Parameters:
contextThe context to clean up after.
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 mappings.

Parameters:
contextThe context to use.
srcaddrSource, in the mapped memory space.
srccntThe number of bytes to copy.
bufferThe kernel buffer to copy into (should be in P1).
Returns:
The number of bytes copied.
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.

Parameters:
context1The source's context.
iov1The scatter/gather array to copy from.
iovcnt1The number of entries in iov1.
context2The destination's context.
iov2The scatter/gather array to copy to.
iovcnt2The number of entries in iov2.
int mmu_init ( )

Initialize MMU support.

Unlike most things in KOS, the MMU is not initialized by a normal startup. This is because for most homebrew, its not needed.

Return values:
0On success (no error conditions defined).
mmu_mapfunc_t mmu_map_get_callback ( )

Get the current mapping function.

Returns:
The current function that maps pages.
mmu_mapfunc_t mmu_map_set_callback ( mmu_mapfunc_t  newfunc)

Set a new MMU mapping handler.

This function will allow you to set a new function to handle mapping for memory pages. There's not much of a reason to do this unless you really do not like the way KOS handles the page mapping internally.

Parameters:
newfuncThe new function to handle mapping.
Returns:
The old function that did mapping.
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.

This implies turning on the "valid" bit. Also sets the other named attributes as specified.

Parameters:
contextThe context to modify.
virtpageThe first virtual page to map.
physpageThe first physical page to map.
countThe number of sequential pages to map.
protMemory protection for page (see MMU protection settings).
cacheCache scheme for page (see MMU cacheability settings).
shareSet to 1 to share between processes (meaningless), otherwise set to 0.
dirtySet to 1 to mark the page as dirty, otherwise set to 0.
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.

Parameters:
contextThe context to look in.
physpageThe physical page number to look for.
Returns:
The virtual page number, or -1 on failure.
See also:
mmu_virt_to_phys()
void mmu_shutdown ( )

Shutdown MMU support.

Turn off the MMU after it was initialized. You should try to make sure this gets done if you initialize the MMU in your program, so as to play nice with loaders and the like (that will not expect that its on, in general).

void mmu_switch_context ( mmucontext_t context)

Switch to the given context.

This function switches to the given context's address space ID. The context should have already been made current with mmu_use_table(). You are responsible for invalidating any caches as neccessary, as well as invalidating any stale TLB entries.

Parameters:
contextThe context to make current.
void mmu_use_table ( mmucontext_t context)

Set the "current" page tables for TLB handling.

This function is useful if you're trying to implement a process model or something of the like on top of KOS. Essentially, this allows you to completely boot the MMU context in use out and replace it with another. You will need to call the mmu_switch_context() function afterwards to set the address space id.

Parameters:
contextThe context to make current.
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.

Parameters:
contextThe context to look in.
virtpageThe virtual page number to look for.
Returns:
The physical page number, or -1 on failure.
See also:
mmu_phys_to_virt()

Variable Documentation

mmucontext_t* mmu_cxt_current

"Current" page tables (for TLB exception handling).

You should not modify this directly, but rather use the functions provided to do so.