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

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

Topics

 Cacheability Settings
 SH4 MMU page cachability settings values
 
 Page size settings
 SH4 MMU page sizes
 
 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, page_prot_t prot, page_cache_t cache, bool share, bool dirty)
 Set the given virtual page to map to the given physical page.
 
int mmu_copyin (mmucontext_t *context, uint32_t srcaddr, uint32_t 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_page_map_static (uintptr_t virt, uintptr_t phys, page_size_t page_size, page_prot_t page_prot, bool cached)
 Create a static virtual memory maping.
 
void mmu_init (void)
 Initialize MMU support.
 
void mmu_init_basic (void)
 Initialize basic MMU support.
 
void mmu_shutdown (void)
 Shutdown MMU support.
 
void mmu_shutdown_basic (void)
 Shutdown basic MMU support.
 
void mmu_reset_itlb (void)
 Reset ITLB.
 
bool mmu_enabled (void)
 Check if MMU translation is enabled.
 
void mmu_set_sq_addr (void *addr)
 Reset the base target address for store queues.
 

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_t srcaddr,
uint32_t 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_enabled()

bool mmu_enabled ( void )

Check if MMU translation is enabled.

Returns
True if MMU translation is enabled, false otherwise.

◆ mmu_init()

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

This implies mmu_init_basic().

◆ mmu_init_basic()

void mmu_init_basic ( void )

Initialize basic MMU support.

This function can be used to initialize the very minimum for MMU to work with static mappings. Dynamic mapping (and mmu_page_map()) will not work. If you need dynamic mapping, use mmu_init() instead.

◆ 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,
page_prot_t prot,
page_cache_t cache,
bool share,
bool 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 share between processes (meaningless).
dirtySet to mark the page as dirty.

◆ mmu_page_map_static()

int mmu_page_map_static ( uintptr_t virt,
uintptr_t phys,
page_size_t page_size,
page_prot_t page_prot,
bool cached )

Create a static virtual memory maping.

This function reserves one TLB entry to create a static mapping from a virtual memory address to a physical memory address. Static mappings are never flushed out of the TLB, and are sometimes useful when the whole MMU function is not necesary. Static memory mappings can also use different page sizes.

Note that the only way to undo static mappings is to call mmu_shutdown_basic().

Parameters
virtThe virtual address for the memory mapping.
physThe physical address for the memory mapping.
page_sizeThe size of the memory page used.
page_protThe memory protection usef for that mapping.
cachedTrue if the mapped memory area is cached, false otherwise.
Return values
0On success.
-1When the virtual or physical addresses are not aligned to the page size.

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

void mmu_set_sq_addr ( void * addr)

Reset the base target address for store queues.

Parameters
addrThe base address to reset to

◆ mmu_shutdown()

void mmu_shutdown ( void )

Shutdown MMU support.

Turn off MMU support after it was initialized with mmu_init(). 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_shutdown_basic()

void mmu_shutdown_basic ( void )

Shutdown basic MMU support.

Turn off basic MMU support after it was initialized with mmu_init_basic(). 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()