1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
/**************************************************************
*
* Creation Date: <1998-11-11 13:55:49 samuel>
* Time-stamp: <2001/06/28 01:03:04 samuel>
*
* <mmu.h>
*
* MMU-emulation
*
* Copyright (C) 1998, 1999, 2000, 2001 Samuel Rydh
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation;
*
**************************************************************/
#ifndef _H_MMU
#define _H_MMU
#ifndef __ASSEMBLY__
#include "kernel_vars.h"
#include "mac_registers.h"
#include "mmu_mappings.h"
#endif
#define IO_PAGE_MAGIC_1 0x10BACA57
#define IO_PAGE_MAGIC_2 0x135AB779
/* Splitmode states */
#define kSplitAlgorithmFast 1 /* Using fastest splitmode algorithm */
#define kSplitAlgorithmFastSS 2 /* Currently singlestepping */
#define kSplitAlgorithm601 4 /* Using 601-compatible algorithm */
#ifndef __ASSEMBLY__
/* this structure *must* fit into a single page (4096) bytes */
typedef struct io_page
{
ulong magic; /* identifier 1 */
ulong magic2; /* identifier 2 */
ulong me_phys; /* physical address of this block */
ulong mphys; /* mac-physical address of block */
struct io_page *next; /* next io_page */
void *usr_data[512]; /* usr data (grain=double word) */
} io_page_t;
/* Kernel exports */
extern PTE *Hash;
extern unsigned long Hash_mask;
/* from mmu */
extern int init_mmu( kernel_vars_t *kv );
extern void cleanup_mmu( kernel_vars_t *kv );
extern void clear_tlb_table( kernel_vars_t *kv );
extern void do_tlbia( kernel_vars_t *kv );
extern void do_flush( ulong vsid, ulong va, ulong *ptep );
extern void mmu_add_map( kernel_vars_t *kv, struct mmu_mapping *m );
extern void mmu_remove_map( kernel_vars_t *kv, struct mmu_mapping *m );
extern void mmu_altered( kernel_vars_t *kv );
/* from mmu_vsid */
extern int init_vsid_table( kernel_vars_t *kv );
extern void cleanup_vsid_table( kernel_vars_t *kv );
extern void vsid_lookup( kernel_vars_t *kv, ulong mac_vsid, ulong *usr_ret, ulong *sv_ret );
extern void flush_vsid_table( kernel_vars_t *kv );
extern void clear_vsids( kernel_vars_t *kv, int is_init );
/* from mmu_lvhash */
extern int init_lvhash( kernel_vars_t *kv );
extern void cleanup_lvhash( kernel_vars_t *kv );
extern void hash_lv_to_pte( kernel_vars_t *kv, ulong *ea, ulong *pte );
extern void unmap_lv_range( kernel_vars_t *kv, ulong lv, size_t size );
/* from tlbie.c */
extern int init_tlbie( kernel_vars_t *kv );
extern void cleanup_tlbie( kernel_vars_t *kv );
extern void table_tlbie( kernel_vars_t *kv, ulong ea );
extern void table_tlbia( kernel_vars_t *kv );
extern void hash_ea_to_pte( kernel_vars_t *kv, ulong ea, ulong *pte );
extern void unmap_ea_range( kernel_vars_t *kv, ulong ea, size_t size );
/* from mmu_io.c */
#define TRANSL_RO 1 /* read only memory (ROM etc) */
#define TRANSL_PHYSICAL 2 /* physical (ROM etc) */
#define TRANSL_VALID 4 /* valid bit */
#define TRANSL_IO 8 /* I/O translation */
#define TRANSL_SCRATCH 16 /* (block transl) scratch area */
#define TRANSL_FORCE_CACHE 32 /* force write-through caching */
#define TRANSL_FB_ACCEL 64 /* offscreen framebuffer, track changes */
#define TRANSL_FB 128 /* framebuffer (ea assumed to be constant) */
#define TRANSL_DBAT 256 /* allow use of a DBAT register */
#define TRANSL_MACOS_CONTROLS_CACHE 512 /* do not force WIM bits to 001 */
extern int init_mmu_io( kernel_vars_t *kv );
extern void cleanup_mmu_io( kernel_vars_t *kv );
extern int add_block_trans( kernel_vars_t *kv, ulong mbase, char *lvbase, ulong size, int flags );
extern void remove_block_trans( kernel_vars_t *kv, int id );
extern int add_io_trans( kernel_vars_t *kv, ulong mbase, int size, void *usr_data );
extern int remove_io_trans( kernel_vars_t *kv, ulong mbase, int size );
extern int mphys_to_pte( kernel_vars_t *kv, ulong mphys, PTE *pte, int is_write );
/* from mmu_fb.c */
extern int init_mmu_fb( kernel_vars_t *kv );
extern void cleanup_mmu_fb( kernel_vars_t *kv );
extern void video_pte_inserted( kernel_vars_t *kv, char *lvptr, ulong *pte_slot, ulong word1, ulong ea );
extern void setup_fb_acceleration( kernel_vars_t *kv, char *lvbase, int bytes_per_row, int height );
extern int get_dirty_fb_lines( kernel_vars_t *kv, short *retbuf, int num_bytes );
/* from mmu_tracker.c */
extern int init_mmu_tracker( kernel_vars_t *kv );
extern void cleanup_mmu_tracker( kernel_vars_t *kv );
extern int track_lvrange( kernel_vars_t *kv, char *lvbase, size_t size );
extern size_t get_track_buffer( kernel_vars_t *kv, char *retbuf );
extern void set_track_buffer( kernel_vars_t *kv, char *buf );
extern void lvpage_dirty( kernel_vars_t *kv, char *lvpage );
/* These functions should be used by the debugger only */
struct linux_page;
extern int get_PTE( kernel_vars_t *kv, int context, ulong va, PTE *ret );
extern int dbg_get_linux_page( ulong va, struct linux_page *r );
extern int dbg_translate_ea( kernel_vars_t *kv, int context, ulong va, PTE *retpte, int data_access );
/* No longer defined in the kernel header files... */
typedef struct {
unsigned long t:1; /* Normal or I/O type */
unsigned long ks:1; /* Supervisor 'key' (normally 0) */
unsigned long kp:1; /* User 'key' (normally 1) */
unsigned long n:1; /* No-execute */
unsigned long :4; /* Unused */
unsigned long vsid:24; /* Virtual Segment Identifier */
} SEGREG_MOL;
/************************************************************************/
/* Linux context allocation */
/************************************************************************/
extern int setup_mol_contexts( void );
extern void release_mol_contexts( void );
extern int flush_all_PTEs( void );
/* Number of linux-context to allocate for mol (64 is the ABSOLUTE MINIMUM) */
#define NUM_MOL_CONTEXTS 65536 /* more than we will need (ever) */
/*
* The new MM implementation uses VSID
*
* VSID = (((context * 897) << 4) + ((va>>28) * 0x111)) & 0xffffff
*
* Only context 0..32767 are used. We can use context 32768..0xfffff.
* The old MM implementation used
*
* VSID = (((context * 897) << 4) + (va>>28)) & 0xffffff
*/
#define VSID_MASK 0xffffff
#define CTX_MASK 0xfffff
#define FIRST_MOL_CONTEXT (CTX_MASK - NUM_MOL_CONTEXTS)
#define LAST_MOL_CONTEXT (FIRST_MOL_CONTEXT + NUM_MOL_CONTEXTS - 1)
#define MUNGE_ADD_NEXT 897
#define MUNGE_MUL_INVERSE 2899073 // Multiplicative inverse of 897 (modulo VSID_MASK)
#ifdef NEW_LINUX_MM
#define MUNGE_ESID_ADD 0x111
#define DETECT_LCTX_OVERFLOW()
#define MUNGE_CONTEXT(c) (((c) * 897) & CTX_MASK)
#else /* NEW_LINUX_MM */
#define LAST_LINUX_CONTEXT (LAST_MOL_CONTEXT - NUM_MOL_CONTEXTS - 16000 /* safety gap */)
#define MUNGE_ESID_ADD 1
extern void linux_context_overflow( void );
#define DETECT_LCTX_OVERFLOW() \
{ if( atomic_read(mc_next_mmu_context) > LAST_LINUX_CONTEXT ) \
linux_context_overflow(); }
#endif /* NEW_LINUX_MM */
#endif /* __ASSEMBLY__ */
#endif /* _H_MMU */
|