~kris/9p

9hist

ref: 0e12f635bfb37a4c9f65b33839f13d4e9d8fa22e 9hist/bitsy/mmu.c -rw-r--r-- 3.2 KiB
0e12f635 — David du Colombier Plan 9 from Bell Labs 2000-09-14 26 years ago
                                                                                
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
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"
#include	"../port/error.h"

/* real protection bits */
enum
{
	/* level 1 descriptor bits */
	L1TypeMask=	(3<<0),
	L1Invalid=	(0<<0),
	L1PageTable=	(1<<0),
	L1Section=	(2<<0),
	L1Cached=	(1<<3),
	L1Buffered=	(1<<2),
	L1Domain0=	(0<<5),
	L1KernelRW=	(0x1<<10),
	L1UserRO=	(0x2<<10),
	L1UserRW=	(0x3<<10),
	L1SectBaseMask=	(0xFFF<<20),
	L1PTBaseMask=	(0x3FFFFF<<10),
	
	/* level 2 descriptor bits */
	L2TypeMask=	(3<<0),
	L2SmallPage=	(2<<0),
	L2LargePage=	(1<<0),
	L2Cached=	(1<<3),
	L2Buffered=	(1<<2),
	L2KernelRW=	(0x55<<4),
	L2UserRO=	(0xAA<<4),
	L2UserRW=	(0xFF<<4),
	L2PageBaseMask=	(0xFFFFF<<12),
};

/*
 *  table to map fault.c bits to physical bits
 */
static ulong phystrans[16] =
{
	[PTEVALID]				L2SmallPage|L2Cached|L2Buffered|L2UserRO,
	[PTEVALID|PTEWRITE]			L2SmallPage|L2Cached|L2Buffered|L2UserRW,
	[PTEVALID|PTEUNCACHED]			L2SmallPage|L2UserRO,
	[PTEVALID|PTEUNCACHED|PTEWRITE]		L2SmallPage|L2UserRW,

	[PTEKERNEL|PTEVALID]			L2SmallPage|L2Cached|L2Buffered|L2KernelRW,
	[PTEKERNEL|PTEVALID|PTEWRITE]		L2SmallPage|L2Cached|L2Buffered|L2KernelRW,
	[PTEKERNEL|PTEVALID|PTEUNCACHED]		L2SmallPage|L2KernelRW,
	[PTEKERNEL|PTEVALID|PTEUNCACHED|PTEWRITE]	L2SmallPage|L2KernelRW,
};

ulong *l1table;

/*
 *  We map all of memory, flash, and the zeros area with sections.
 *  Special use space is mapped on the fly with regmap.
 */
void
mmuinit(void)
{
	ulong a, e;

	/* set up the domain register to cause all domains to obey pte access bits */
	putdac(0x55555555);

	/* get a prototype level 1 page */
	l1table = xspanalloc(BY2PG, 16*1024, 0);
	memset(l1table, 0, BY2PG);

	/* direct map DRAM */
	e = conf.base1 + BY2PG*conf.npage2;
	for(a = PHYSDRAM0; a < e; a += OneMeg)
		l1table[a>>20] = L1Section | L1KernelRW |
				L1Cached | L1Buffered | (a&L1SectBaseMask);

	/* direct map zeros area */
	for(a = PHYSNULL0; a < PHYSNULL0 + 128 * OneMeg; a += OneMeg)
		l1table[a>>20] = L1Section | L1KernelRW |
				L1Cached | L1Buffered | (a&L1SectBaseMask);

	/* direct map flash */
	for(a = PHYFLASH0; a < PHYFLASH0 + 128 * OneMeg; a += OneMeg)
		l1table[a>>20] = L1Section | L1KernelRW |
				L1Cached | L1Buffered | (a&L1SectBaseMask);

	/* map the uart so that we can continue using iprint */
	uart3regs = mapspecial(UART3REGS, 64);
}

/*
 *  map special use space 
 */
ulong*
mapspecial(ulong physaddr, int len)
{
	ulong *t;
	ulong virtaddr, i;

	/* first see if we've mapped it somewhere, the first hole means we're done */
	for(virtaddr = REGZERO; virtaddr < REGTOP; virtaddr += OneMeg){
		if((l1table[virtaddr>>20] & L1TypeMask) != L1PageTable){
			/* create a page table and break */
			t = xspanalloc(BY2PG, 1024, 0);
			memzero(t, BY2PG, 0);
			l1table[virtaddr>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask);
			break;
		}
		t = (ulong*)(l1table[virtaddr>>20] & L1PTBaseMask);
		for(i = 0; i < OneMeg; i += BY2PG){
			if((t[virtaddr>>20] & L2TypeMask) != L2SmallPage)
				break;
		}
		if(i < OneMeg){
			virtaddr += i;
			break;
		}
	}

	/* we get here if no entry was found mapping this physical address */
	
}

void
putmmu(ulong va, ulong pa, Page*)
{
	USED(va, pa);
}

void
mmurelease(Proc* proc)
{
	USED(proc);
}

void
mmuswitch(Proc* proc)
{
	USED(proc);
}