File: mmu.h

package info (click to toggle)
mol 0.9.61-6
  • links: PTS
  • area: contrib
  • in suites: woody
  • size: 6,140 kB
  • ctags: 8,491
  • sloc: ansic: 50,560; asm: 2,826; sh: 458; makefile: 373; perl: 165; lex: 135; yacc: 131
file content (194 lines) | stat: -rw-r--r-- 7,082 bytes parent folder | download
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 */