KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches

Driver for the SH4's MMU (disabled by default). More...

Modules

 Address Bits
 Definitions and masks for address pages.
 
 Cacheability Settings
 SH4 MMU page cachability settings values.
 
 Protection Settings
 SH4 MMU page protection settings values.
 

Files

file  mmu.h
 Memory Management Unit and Translation Lookaside Buffer handling.
 

Data Structures

struct  mmupage_t
 MMU TLB entry for a single page. More...
 
struct  mmusubcontext_t
 MMU sub-context type. More...
 
struct  mmucontext_t
 MMU context type. More...
 

Macros

#define MMU_SUB_PAGES   512
 The number of pages in a sub-context.
 

Typedefs

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, 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, taking into account page mappings.
 
mmu_mapfunc_t mmu_map_get_callback (void)
 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 (void)
 Initialize MMU support.
 
void mmu_shutdown (void)
 Shutdown MMU support.
 
void mmu_reset_itlb (void)
 Reset ITLB.
 

Detailed Description

Driver for the SH4's MMU (disabled by default).

Since the software has to handle TLB misses on the SH-4, we have freedom to use any page table format we want (and thus save space), but we must make it quick to access. The SH-4 can address a maximum of 512M of address space per "area", but we only care about one area, so this is the total maximum addressable space. With 4K pages, that works out to 2^17 pages that must be mappable, or 17 bits. We use 18 bits just to be sure (there are a few left over).

Page tables (per-process) are a sparse two-level array. The virtual address space is actually 2^30 bytes, or 2^(30-12)=2^18 pages, so there must be a possibility of having that many page entries per process space. A full page table for a process would be 1M, so this is obviously too big!! Thus the sparse array.

The bottom layer of the page tables consists of a sub-context array for 512 pages, which translates into 2K of storage space. The process then has the possibility of using one or more of the 512 top-level slots. For a very small process (using one page for code/data and one for stack), it should be possible to achieve a page table footprint of one page. The tables can grow from there as necessary.

Virtual addresses are broken up as follows:

Macro Definition Documentation

◆ MMU_SUB_PAGES

#define MMU_SUB_PAGES   512

The number of pages in a sub-context.

Typedef Documentation

◆ mmu_mapfunc_t

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.

Function Documentation

◆ mmu_context_create()

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 or NULL on fail.

◆ mmu_context_destroy()

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.

◆ mmu_copyin()

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 (failure causes arch_panic).

◆ mmu_copyv()

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, 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.
Returns
The number of bytes copied (failure causes arch_panic).

◆ mmu_init()

int mmu_init ( void  )

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_map_get_callback()

mmu_mapfunc_t mmu_map_get_callback ( void  )

Get the current mapping function.

Returns
The current function that maps pages.

◆ mmu_map_set_callback()

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.

◆ mmu_page_map()

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 Protection Settings).
cacheCache scheme for page (see 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.

◆ mmu_phys_to_virt()

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()

◆ mmu_reset_itlb()

void mmu_reset_itlb ( void  )

Reset ITLB.

◆ mmu_shutdown()

void mmu_shutdown ( void  )

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).

◆ mmu_switch_context()

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 necessary, as well as invalidating any stale TLB entries.

Parameters
contextThe context to make current.

◆ mmu_use_table()

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.

◆ mmu_virt_to_phys()

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()