Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/sparc/mm/sun4c.c
10817 views
1
/* sun4c.c: Doing in software what should be done in hardware.
2
*
3
* Copyright (C) 1996 David S. Miller ([email protected])
4
* Copyright (C) 1996 Eddie C. Dost ([email protected])
5
* Copyright (C) 1996 Andrew Tridgell ([email protected])
6
* Copyright (C) 1997-2000 Anton Blanchard ([email protected])
7
* Copyright (C) 1998 Jakub Jelinek ([email protected])
8
*/
9
10
#define NR_TASK_BUCKETS 512
11
12
#include <linux/kernel.h>
13
#include <linux/mm.h>
14
#include <linux/init.h>
15
#include <linux/slab.h>
16
#include <linux/bootmem.h>
17
#include <linux/highmem.h>
18
#include <linux/fs.h>
19
#include <linux/seq_file.h>
20
#include <linux/scatterlist.h>
21
#include <linux/bitmap.h>
22
23
#include <asm/sections.h>
24
#include <asm/page.h>
25
#include <asm/pgalloc.h>
26
#include <asm/pgtable.h>
27
#include <asm/vaddrs.h>
28
#include <asm/idprom.h>
29
#include <asm/machines.h>
30
#include <asm/memreg.h>
31
#include <asm/processor.h>
32
#include <asm/auxio.h>
33
#include <asm/io.h>
34
#include <asm/oplib.h>
35
#include <asm/openprom.h>
36
#include <asm/mmu_context.h>
37
#include <asm/highmem.h>
38
#include <asm/btfixup.h>
39
#include <asm/cacheflush.h>
40
#include <asm/tlbflush.h>
41
42
/* Because of our dynamic kernel TLB miss strategy, and how
43
* our DVMA mapping allocation works, you _MUST_:
44
*
45
* 1) Disable interrupts _and_ not touch any dynamic kernel
46
* memory while messing with kernel MMU state. By
47
* dynamic memory I mean any object which is not in
48
* the kernel image itself or a thread_union (both of
49
* which are locked into the MMU).
50
* 2) Disable interrupts while messing with user MMU state.
51
*/
52
53
extern int num_segmaps, num_contexts;
54
55
extern unsigned long page_kernel;
56
57
/* That's it, we prom_halt() on sun4c if the cache size is something other than 65536.
58
* So let's save some cycles and just use that everywhere except for that bootup
59
* sanity check.
60
*/
61
#define SUN4C_VAC_SIZE 65536
62
63
#define SUN4C_KERNEL_BUCKETS 32
64
65
/* Flushing the cache. */
66
struct sun4c_vac_props sun4c_vacinfo;
67
unsigned long sun4c_kernel_faults;
68
69
/* Invalidate every sun4c cache line tag. */
70
static void __init sun4c_flush_all(void)
71
{
72
unsigned long begin, end;
73
74
if (sun4c_vacinfo.on)
75
panic("SUN4C: AIEEE, trying to invalidate vac while it is on.");
76
77
/* Clear 'valid' bit in all cache line tags */
78
begin = AC_CACHETAGS;
79
end = (AC_CACHETAGS + SUN4C_VAC_SIZE);
80
while (begin < end) {
81
__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
82
"r" (begin), "i" (ASI_CONTROL));
83
begin += sun4c_vacinfo.linesize;
84
}
85
}
86
87
static void sun4c_flush_context_hw(void)
88
{
89
unsigned long end = SUN4C_VAC_SIZE;
90
91
__asm__ __volatile__(
92
"1: addcc %0, -4096, %0\n\t"
93
" bne 1b\n\t"
94
" sta %%g0, [%0] %2"
95
: "=&r" (end)
96
: "0" (end), "i" (ASI_HWFLUSHCONTEXT)
97
: "cc");
98
}
99
100
/* Must be called minimally with IRQs disabled. */
101
static void sun4c_flush_segment_hw(unsigned long addr)
102
{
103
if (sun4c_get_segmap(addr) != invalid_segment) {
104
unsigned long vac_size = SUN4C_VAC_SIZE;
105
106
__asm__ __volatile__(
107
"1: addcc %0, -4096, %0\n\t"
108
" bne 1b\n\t"
109
" sta %%g0, [%2 + %0] %3"
110
: "=&r" (vac_size)
111
: "0" (vac_size), "r" (addr), "i" (ASI_HWFLUSHSEG)
112
: "cc");
113
}
114
}
115
116
/* File local boot time fixups. */
117
BTFIXUPDEF_CALL(void, sun4c_flush_page, unsigned long)
118
BTFIXUPDEF_CALL(void, sun4c_flush_segment, unsigned long)
119
BTFIXUPDEF_CALL(void, sun4c_flush_context, void)
120
121
#define sun4c_flush_page(addr) BTFIXUP_CALL(sun4c_flush_page)(addr)
122
#define sun4c_flush_segment(addr) BTFIXUP_CALL(sun4c_flush_segment)(addr)
123
#define sun4c_flush_context() BTFIXUP_CALL(sun4c_flush_context)()
124
125
/* Must be called minimally with interrupts disabled. */
126
static void sun4c_flush_page_hw(unsigned long addr)
127
{
128
addr &= PAGE_MASK;
129
if ((int)sun4c_get_pte(addr) < 0)
130
__asm__ __volatile__("sta %%g0, [%0] %1"
131
: : "r" (addr), "i" (ASI_HWFLUSHPAGE));
132
}
133
134
/* Don't inline the software version as it eats too many cache lines if expanded. */
135
static void sun4c_flush_context_sw(void)
136
{
137
unsigned long nbytes = SUN4C_VAC_SIZE;
138
unsigned long lsize = sun4c_vacinfo.linesize;
139
140
__asm__ __volatile__(
141
"add %2, %2, %%g1\n\t"
142
"add %2, %%g1, %%g2\n\t"
143
"add %2, %%g2, %%g3\n\t"
144
"add %2, %%g3, %%g4\n\t"
145
"add %2, %%g4, %%g5\n\t"
146
"add %2, %%g5, %%o4\n\t"
147
"add %2, %%o4, %%o5\n"
148
"1:\n\t"
149
"subcc %0, %%o5, %0\n\t"
150
"sta %%g0, [%0] %3\n\t"
151
"sta %%g0, [%0 + %2] %3\n\t"
152
"sta %%g0, [%0 + %%g1] %3\n\t"
153
"sta %%g0, [%0 + %%g2] %3\n\t"
154
"sta %%g0, [%0 + %%g3] %3\n\t"
155
"sta %%g0, [%0 + %%g4] %3\n\t"
156
"sta %%g0, [%0 + %%g5] %3\n\t"
157
"bg 1b\n\t"
158
" sta %%g0, [%1 + %%o4] %3\n"
159
: "=&r" (nbytes)
160
: "0" (nbytes), "r" (lsize), "i" (ASI_FLUSHCTX)
161
: "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
162
}
163
164
/* Don't inline the software version as it eats too many cache lines if expanded. */
165
static void sun4c_flush_segment_sw(unsigned long addr)
166
{
167
if (sun4c_get_segmap(addr) != invalid_segment) {
168
unsigned long nbytes = SUN4C_VAC_SIZE;
169
unsigned long lsize = sun4c_vacinfo.linesize;
170
171
__asm__ __volatile__(
172
"add %2, %2, %%g1\n\t"
173
"add %2, %%g1, %%g2\n\t"
174
"add %2, %%g2, %%g3\n\t"
175
"add %2, %%g3, %%g4\n\t"
176
"add %2, %%g4, %%g5\n\t"
177
"add %2, %%g5, %%o4\n\t"
178
"add %2, %%o4, %%o5\n"
179
"1:\n\t"
180
"subcc %1, %%o5, %1\n\t"
181
"sta %%g0, [%0] %6\n\t"
182
"sta %%g0, [%0 + %2] %6\n\t"
183
"sta %%g0, [%0 + %%g1] %6\n\t"
184
"sta %%g0, [%0 + %%g2] %6\n\t"
185
"sta %%g0, [%0 + %%g3] %6\n\t"
186
"sta %%g0, [%0 + %%g4] %6\n\t"
187
"sta %%g0, [%0 + %%g5] %6\n\t"
188
"sta %%g0, [%0 + %%o4] %6\n\t"
189
"bg 1b\n\t"
190
" add %0, %%o5, %0\n"
191
: "=&r" (addr), "=&r" (nbytes), "=&r" (lsize)
192
: "0" (addr), "1" (nbytes), "2" (lsize),
193
"i" (ASI_FLUSHSEG)
194
: "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
195
}
196
}
197
198
/* Don't inline the software version as it eats too many cache lines if expanded. */
199
static void sun4c_flush_page_sw(unsigned long addr)
200
{
201
addr &= PAGE_MASK;
202
if ((sun4c_get_pte(addr) & (_SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_VALID)) ==
203
_SUN4C_PAGE_VALID) {
204
unsigned long left = PAGE_SIZE;
205
unsigned long lsize = sun4c_vacinfo.linesize;
206
207
__asm__ __volatile__(
208
"add %2, %2, %%g1\n\t"
209
"add %2, %%g1, %%g2\n\t"
210
"add %2, %%g2, %%g3\n\t"
211
"add %2, %%g3, %%g4\n\t"
212
"add %2, %%g4, %%g5\n\t"
213
"add %2, %%g5, %%o4\n\t"
214
"add %2, %%o4, %%o5\n"
215
"1:\n\t"
216
"subcc %1, %%o5, %1\n\t"
217
"sta %%g0, [%0] %6\n\t"
218
"sta %%g0, [%0 + %2] %6\n\t"
219
"sta %%g0, [%0 + %%g1] %6\n\t"
220
"sta %%g0, [%0 + %%g2] %6\n\t"
221
"sta %%g0, [%0 + %%g3] %6\n\t"
222
"sta %%g0, [%0 + %%g4] %6\n\t"
223
"sta %%g0, [%0 + %%g5] %6\n\t"
224
"sta %%g0, [%0 + %%o4] %6\n\t"
225
"bg 1b\n\t"
226
" add %0, %%o5, %0\n"
227
: "=&r" (addr), "=&r" (left), "=&r" (lsize)
228
: "0" (addr), "1" (left), "2" (lsize),
229
"i" (ASI_FLUSHPG)
230
: "g1", "g2", "g3", "g4", "g5", "o4", "o5", "cc");
231
}
232
}
233
234
/* The sun4c's do have an on chip store buffer. And the way you
235
* clear them out isn't so obvious. The only way I can think of
236
* to accomplish this is to read the current context register,
237
* store the same value there, then read an external hardware
238
* register.
239
*/
240
void sun4c_complete_all_stores(void)
241
{
242
volatile int _unused;
243
244
_unused = sun4c_get_context();
245
sun4c_set_context(_unused);
246
_unused = get_auxio();
247
}
248
249
/* Bootup utility functions. */
250
static inline void sun4c_init_clean_segmap(unsigned char pseg)
251
{
252
unsigned long vaddr;
253
254
sun4c_put_segmap(0, pseg);
255
for (vaddr = 0; vaddr < SUN4C_REAL_PGDIR_SIZE; vaddr += PAGE_SIZE)
256
sun4c_put_pte(vaddr, 0);
257
sun4c_put_segmap(0, invalid_segment);
258
}
259
260
static inline void sun4c_init_clean_mmu(unsigned long kernel_end)
261
{
262
unsigned long vaddr;
263
unsigned char savectx, ctx;
264
265
savectx = sun4c_get_context();
266
for (ctx = 0; ctx < num_contexts; ctx++) {
267
sun4c_set_context(ctx);
268
for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE)
269
sun4c_put_segmap(vaddr, invalid_segment);
270
for (vaddr = 0xe0000000; vaddr < KERNBASE; vaddr += SUN4C_REAL_PGDIR_SIZE)
271
sun4c_put_segmap(vaddr, invalid_segment);
272
for (vaddr = kernel_end; vaddr < KADB_DEBUGGER_BEGVM; vaddr += SUN4C_REAL_PGDIR_SIZE)
273
sun4c_put_segmap(vaddr, invalid_segment);
274
for (vaddr = LINUX_OPPROM_ENDVM; vaddr; vaddr += SUN4C_REAL_PGDIR_SIZE)
275
sun4c_put_segmap(vaddr, invalid_segment);
276
}
277
sun4c_set_context(savectx);
278
}
279
280
void __init sun4c_probe_vac(void)
281
{
282
sun4c_disable_vac();
283
284
if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
285
(idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
286
/* PROM on SS1 lacks this info, to be super safe we
287
* hard code it here since this arch is cast in stone.
288
*/
289
sun4c_vacinfo.num_bytes = 65536;
290
sun4c_vacinfo.linesize = 16;
291
} else {
292
sun4c_vacinfo.num_bytes =
293
prom_getintdefault(prom_root_node, "vac-size", 65536);
294
sun4c_vacinfo.linesize =
295
prom_getintdefault(prom_root_node, "vac-linesize", 16);
296
}
297
sun4c_vacinfo.do_hwflushes =
298
prom_getintdefault(prom_root_node, "vac-hwflush", 0);
299
300
if (sun4c_vacinfo.do_hwflushes == 0)
301
sun4c_vacinfo.do_hwflushes =
302
prom_getintdefault(prom_root_node, "vac_hwflush", 0);
303
304
if (sun4c_vacinfo.num_bytes != 65536) {
305
prom_printf("WEIRD Sun4C VAC cache size, "
306
"tell [email protected]");
307
prom_halt();
308
}
309
310
switch (sun4c_vacinfo.linesize) {
311
case 16:
312
sun4c_vacinfo.log2lsize = 4;
313
break;
314
case 32:
315
sun4c_vacinfo.log2lsize = 5;
316
break;
317
default:
318
prom_printf("probe_vac: Didn't expect vac-linesize of %d, halting\n",
319
sun4c_vacinfo.linesize);
320
prom_halt();
321
}
322
323
sun4c_flush_all();
324
sun4c_enable_vac();
325
}
326
327
/* Patch instructions for the low level kernel fault handler. */
328
extern unsigned long invalid_segment_patch1, invalid_segment_patch1_ff;
329
extern unsigned long invalid_segment_patch2, invalid_segment_patch2_ff;
330
extern unsigned long invalid_segment_patch1_1ff, invalid_segment_patch2_1ff;
331
extern unsigned long num_context_patch1, num_context_patch1_16;
332
extern unsigned long num_context_patch2_16;
333
extern unsigned long vac_linesize_patch, vac_linesize_patch_32;
334
extern unsigned long vac_hwflush_patch1, vac_hwflush_patch1_on;
335
extern unsigned long vac_hwflush_patch2, vac_hwflush_patch2_on;
336
337
#define PATCH_INSN(src, dst) do { \
338
daddr = &(dst); \
339
iaddr = &(src); \
340
*daddr = *iaddr; \
341
} while (0)
342
343
static void __init patch_kernel_fault_handler(void)
344
{
345
unsigned long *iaddr, *daddr;
346
347
switch (num_segmaps) {
348
case 128:
349
/* Default, nothing to do. */
350
break;
351
case 256:
352
PATCH_INSN(invalid_segment_patch1_ff,
353
invalid_segment_patch1);
354
PATCH_INSN(invalid_segment_patch2_ff,
355
invalid_segment_patch2);
356
break;
357
case 512:
358
PATCH_INSN(invalid_segment_patch1_1ff,
359
invalid_segment_patch1);
360
PATCH_INSN(invalid_segment_patch2_1ff,
361
invalid_segment_patch2);
362
break;
363
default:
364
prom_printf("Unhandled number of segmaps: %d\n",
365
num_segmaps);
366
prom_halt();
367
}
368
switch (num_contexts) {
369
case 8:
370
/* Default, nothing to do. */
371
break;
372
case 16:
373
PATCH_INSN(num_context_patch1_16,
374
num_context_patch1);
375
break;
376
default:
377
prom_printf("Unhandled number of contexts: %d\n",
378
num_contexts);
379
prom_halt();
380
}
381
382
if (sun4c_vacinfo.do_hwflushes != 0) {
383
PATCH_INSN(vac_hwflush_patch1_on, vac_hwflush_patch1);
384
PATCH_INSN(vac_hwflush_patch2_on, vac_hwflush_patch2);
385
} else {
386
switch (sun4c_vacinfo.linesize) {
387
case 16:
388
/* Default, nothing to do. */
389
break;
390
case 32:
391
PATCH_INSN(vac_linesize_patch_32, vac_linesize_patch);
392
break;
393
default:
394
prom_printf("Impossible VAC linesize %d, halting...\n",
395
sun4c_vacinfo.linesize);
396
prom_halt();
397
}
398
}
399
}
400
401
static void __init sun4c_probe_mmu(void)
402
{
403
if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
404
(idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
405
/* Hardcode these just to be safe, PROM on SS1 does
406
* not have this info available in the root node.
407
*/
408
num_segmaps = 128;
409
num_contexts = 8;
410
} else {
411
num_segmaps =
412
prom_getintdefault(prom_root_node, "mmu-npmg", 128);
413
num_contexts =
414
prom_getintdefault(prom_root_node, "mmu-nctx", 0x8);
415
}
416
patch_kernel_fault_handler();
417
}
418
419
volatile unsigned long __iomem *sun4c_memerr_reg = NULL;
420
421
void __init sun4c_probe_memerr_reg(void)
422
{
423
phandle node;
424
struct linux_prom_registers regs[1];
425
426
node = prom_getchild(prom_root_node);
427
node = prom_searchsiblings(prom_root_node, "memory-error");
428
if (!node)
429
return;
430
if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0)
431
return;
432
/* hmm I think regs[0].which_io is zero here anyways */
433
sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);
434
}
435
436
static inline void sun4c_init_ss2_cache_bug(void)
437
{
438
if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) ||
439
(idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) ||
440
(idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) {
441
/* Whee.. */
442
printk("SS2 cache bug detected, uncaching trap table page\n");
443
sun4c_flush_page((unsigned int) &_start);
444
sun4c_put_pte(((unsigned long) &_start),
445
(sun4c_get_pte((unsigned long) &_start) | _SUN4C_PAGE_NOCACHE));
446
}
447
}
448
449
/* Addr is always aligned on a page boundary for us already. */
450
static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va,
451
unsigned long addr, int len)
452
{
453
unsigned long page, end;
454
455
*pba = addr;
456
457
end = PAGE_ALIGN((addr + len));
458
while (addr < end) {
459
page = va;
460
sun4c_flush_page(page);
461
page -= PAGE_OFFSET;
462
page >>= PAGE_SHIFT;
463
page |= (_SUN4C_PAGE_VALID | _SUN4C_PAGE_DIRTY |
464
_SUN4C_PAGE_NOCACHE | _SUN4C_PAGE_PRIV);
465
sun4c_put_pte(addr, page);
466
addr += PAGE_SIZE;
467
va += PAGE_SIZE;
468
}
469
470
return 0;
471
}
472
473
static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len)
474
{
475
/* Fortunately for us, bus_addr == uncached_virt in sun4c. */
476
/* XXX Implement this */
477
}
478
479
/* TLB management. */
480
481
/* Don't change this struct without changing entry.S. This is used
482
* in the in-window kernel fault handler, and you don't want to mess
483
* with that. (See sun4c_fault in entry.S).
484
*/
485
struct sun4c_mmu_entry {
486
struct sun4c_mmu_entry *next;
487
struct sun4c_mmu_entry *prev;
488
unsigned long vaddr;
489
unsigned char pseg;
490
unsigned char locked;
491
492
/* For user mappings only, and completely hidden from kernel
493
* TLB miss code.
494
*/
495
unsigned char ctx;
496
struct sun4c_mmu_entry *lru_next;
497
struct sun4c_mmu_entry *lru_prev;
498
};
499
500
static struct sun4c_mmu_entry mmu_entry_pool[SUN4C_MAX_SEGMAPS];
501
502
static void __init sun4c_init_mmu_entry_pool(void)
503
{
504
int i;
505
506
for (i=0; i < SUN4C_MAX_SEGMAPS; i++) {
507
mmu_entry_pool[i].pseg = i;
508
mmu_entry_pool[i].next = NULL;
509
mmu_entry_pool[i].prev = NULL;
510
mmu_entry_pool[i].vaddr = 0;
511
mmu_entry_pool[i].locked = 0;
512
mmu_entry_pool[i].ctx = 0;
513
mmu_entry_pool[i].lru_next = NULL;
514
mmu_entry_pool[i].lru_prev = NULL;
515
}
516
mmu_entry_pool[invalid_segment].locked = 1;
517
}
518
519
static inline void fix_permissions(unsigned long vaddr, unsigned long bits_on,
520
unsigned long bits_off)
521
{
522
unsigned long start, end;
523
524
end = vaddr + SUN4C_REAL_PGDIR_SIZE;
525
for (start = vaddr; start < end; start += PAGE_SIZE)
526
if (sun4c_get_pte(start) & _SUN4C_PAGE_VALID)
527
sun4c_put_pte(start, (sun4c_get_pte(start) | bits_on) &
528
~bits_off);
529
}
530
531
static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
532
{
533
unsigned long vaddr;
534
unsigned char pseg, ctx;
535
536
for (vaddr = KADB_DEBUGGER_BEGVM;
537
vaddr < LINUX_OPPROM_ENDVM;
538
vaddr += SUN4C_REAL_PGDIR_SIZE) {
539
pseg = sun4c_get_segmap(vaddr);
540
if (pseg != invalid_segment) {
541
mmu_entry_pool[pseg].locked = 1;
542
for (ctx = 0; ctx < num_contexts; ctx++)
543
prom_putsegment(ctx, vaddr, pseg);
544
fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);
545
}
546
}
547
548
for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {
549
pseg = sun4c_get_segmap(vaddr);
550
mmu_entry_pool[pseg].locked = 1;
551
for (ctx = 0; ctx < num_contexts; ctx++)
552
prom_putsegment(ctx, vaddr, pseg);
553
fix_permissions(vaddr, _SUN4C_PAGE_PRIV, _SUN4C_PAGE_NOCACHE);
554
}
555
}
556
557
static void __init sun4c_init_lock_area(unsigned long start, unsigned long end)
558
{
559
int i, ctx;
560
561
while (start < end) {
562
for (i = 0; i < invalid_segment; i++)
563
if (!mmu_entry_pool[i].locked)
564
break;
565
mmu_entry_pool[i].locked = 1;
566
sun4c_init_clean_segmap(i);
567
for (ctx = 0; ctx < num_contexts; ctx++)
568
prom_putsegment(ctx, start, mmu_entry_pool[i].pseg);
569
start += SUN4C_REAL_PGDIR_SIZE;
570
}
571
}
572
573
/* Don't change this struct without changing entry.S. This is used
574
* in the in-window kernel fault handler, and you don't want to mess
575
* with that. (See sun4c_fault in entry.S).
576
*/
577
struct sun4c_mmu_ring {
578
struct sun4c_mmu_entry ringhd;
579
int num_entries;
580
};
581
582
static struct sun4c_mmu_ring sun4c_context_ring[SUN4C_MAX_CONTEXTS]; /* used user entries */
583
static struct sun4c_mmu_ring sun4c_ufree_ring; /* free user entries */
584
static struct sun4c_mmu_ring sun4c_ulru_ring; /* LRU user entries */
585
struct sun4c_mmu_ring sun4c_kernel_ring; /* used kernel entries */
586
struct sun4c_mmu_ring sun4c_kfree_ring; /* free kernel entries */
587
588
static inline void sun4c_init_rings(void)
589
{
590
int i;
591
592
for (i = 0; i < SUN4C_MAX_CONTEXTS; i++) {
593
sun4c_context_ring[i].ringhd.next =
594
sun4c_context_ring[i].ringhd.prev =
595
&sun4c_context_ring[i].ringhd;
596
sun4c_context_ring[i].num_entries = 0;
597
}
598
sun4c_ufree_ring.ringhd.next = sun4c_ufree_ring.ringhd.prev =
599
&sun4c_ufree_ring.ringhd;
600
sun4c_ufree_ring.num_entries = 0;
601
sun4c_ulru_ring.ringhd.lru_next = sun4c_ulru_ring.ringhd.lru_prev =
602
&sun4c_ulru_ring.ringhd;
603
sun4c_ulru_ring.num_entries = 0;
604
sun4c_kernel_ring.ringhd.next = sun4c_kernel_ring.ringhd.prev =
605
&sun4c_kernel_ring.ringhd;
606
sun4c_kernel_ring.num_entries = 0;
607
sun4c_kfree_ring.ringhd.next = sun4c_kfree_ring.ringhd.prev =
608
&sun4c_kfree_ring.ringhd;
609
sun4c_kfree_ring.num_entries = 0;
610
}
611
612
static void add_ring(struct sun4c_mmu_ring *ring,
613
struct sun4c_mmu_entry *entry)
614
{
615
struct sun4c_mmu_entry *head = &ring->ringhd;
616
617
entry->prev = head;
618
(entry->next = head->next)->prev = entry;
619
head->next = entry;
620
ring->num_entries++;
621
}
622
623
static inline void add_lru(struct sun4c_mmu_entry *entry)
624
{
625
struct sun4c_mmu_ring *ring = &sun4c_ulru_ring;
626
struct sun4c_mmu_entry *head = &ring->ringhd;
627
628
entry->lru_next = head;
629
(entry->lru_prev = head->lru_prev)->lru_next = entry;
630
head->lru_prev = entry;
631
}
632
633
static void add_ring_ordered(struct sun4c_mmu_ring *ring,
634
struct sun4c_mmu_entry *entry)
635
{
636
struct sun4c_mmu_entry *head = &ring->ringhd;
637
unsigned long addr = entry->vaddr;
638
639
while ((head->next != &ring->ringhd) && (head->next->vaddr < addr))
640
head = head->next;
641
642
entry->prev = head;
643
(entry->next = head->next)->prev = entry;
644
head->next = entry;
645
ring->num_entries++;
646
647
add_lru(entry);
648
}
649
650
static inline void remove_ring(struct sun4c_mmu_ring *ring,
651
struct sun4c_mmu_entry *entry)
652
{
653
struct sun4c_mmu_entry *next = entry->next;
654
655
(next->prev = entry->prev)->next = next;
656
ring->num_entries--;
657
}
658
659
static void remove_lru(struct sun4c_mmu_entry *entry)
660
{
661
struct sun4c_mmu_entry *next = entry->lru_next;
662
663
(next->lru_prev = entry->lru_prev)->lru_next = next;
664
}
665
666
static void free_user_entry(int ctx, struct sun4c_mmu_entry *entry)
667
{
668
remove_ring(sun4c_context_ring+ctx, entry);
669
remove_lru(entry);
670
add_ring(&sun4c_ufree_ring, entry);
671
}
672
673
static void free_kernel_entry(struct sun4c_mmu_entry *entry,
674
struct sun4c_mmu_ring *ring)
675
{
676
remove_ring(ring, entry);
677
add_ring(&sun4c_kfree_ring, entry);
678
}
679
680
static void __init sun4c_init_fill_kernel_ring(int howmany)
681
{
682
int i;
683
684
while (howmany) {
685
for (i = 0; i < invalid_segment; i++)
686
if (!mmu_entry_pool[i].locked)
687
break;
688
mmu_entry_pool[i].locked = 1;
689
sun4c_init_clean_segmap(i);
690
add_ring(&sun4c_kfree_ring, &mmu_entry_pool[i]);
691
howmany--;
692
}
693
}
694
695
static void __init sun4c_init_fill_user_ring(void)
696
{
697
int i;
698
699
for (i = 0; i < invalid_segment; i++) {
700
if (mmu_entry_pool[i].locked)
701
continue;
702
sun4c_init_clean_segmap(i);
703
add_ring(&sun4c_ufree_ring, &mmu_entry_pool[i]);
704
}
705
}
706
707
static void sun4c_kernel_unmap(struct sun4c_mmu_entry *kentry)
708
{
709
int savectx, ctx;
710
711
savectx = sun4c_get_context();
712
for (ctx = 0; ctx < num_contexts; ctx++) {
713
sun4c_set_context(ctx);
714
sun4c_put_segmap(kentry->vaddr, invalid_segment);
715
}
716
sun4c_set_context(savectx);
717
}
718
719
static void sun4c_kernel_map(struct sun4c_mmu_entry *kentry)
720
{
721
int savectx, ctx;
722
723
savectx = sun4c_get_context();
724
for (ctx = 0; ctx < num_contexts; ctx++) {
725
sun4c_set_context(ctx);
726
sun4c_put_segmap(kentry->vaddr, kentry->pseg);
727
}
728
sun4c_set_context(savectx);
729
}
730
731
#define sun4c_user_unmap(__entry) \
732
sun4c_put_segmap((__entry)->vaddr, invalid_segment)
733
734
static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx)
735
{
736
struct sun4c_mmu_entry *head = &crp->ringhd;
737
unsigned long flags;
738
739
local_irq_save(flags);
740
if (head->next != head) {
741
struct sun4c_mmu_entry *entry = head->next;
742
int savectx = sun4c_get_context();
743
744
flush_user_windows();
745
sun4c_set_context(ctx);
746
sun4c_flush_context();
747
do {
748
struct sun4c_mmu_entry *next = entry->next;
749
750
sun4c_user_unmap(entry);
751
free_user_entry(ctx, entry);
752
753
entry = next;
754
} while (entry != head);
755
sun4c_set_context(savectx);
756
}
757
local_irq_restore(flags);
758
}
759
760
static int sun4c_user_taken_entries; /* This is how much we have. */
761
static int max_user_taken_entries; /* This limits us and prevents deadlock. */
762
763
static struct sun4c_mmu_entry *sun4c_kernel_strategy(void)
764
{
765
struct sun4c_mmu_entry *this_entry;
766
767
/* If some are free, return first one. */
768
if (sun4c_kfree_ring.num_entries) {
769
this_entry = sun4c_kfree_ring.ringhd.next;
770
return this_entry;
771
}
772
773
/* Else free one up. */
774
this_entry = sun4c_kernel_ring.ringhd.prev;
775
sun4c_flush_segment(this_entry->vaddr);
776
sun4c_kernel_unmap(this_entry);
777
free_kernel_entry(this_entry, &sun4c_kernel_ring);
778
this_entry = sun4c_kfree_ring.ringhd.next;
779
780
return this_entry;
781
}
782
783
/* Using this method to free up mmu entries eliminates a lot of
784
* potential races since we have a kernel that incurs tlb
785
* replacement faults. There may be performance penalties.
786
*
787
* NOTE: Must be called with interrupts disabled.
788
*/
789
static struct sun4c_mmu_entry *sun4c_user_strategy(void)
790
{
791
struct sun4c_mmu_entry *entry;
792
unsigned char ctx;
793
int savectx;
794
795
/* If some are free, return first one. */
796
if (sun4c_ufree_ring.num_entries) {
797
entry = sun4c_ufree_ring.ringhd.next;
798
goto unlink_out;
799
}
800
801
if (sun4c_user_taken_entries) {
802
entry = sun4c_kernel_strategy();
803
sun4c_user_taken_entries--;
804
goto kunlink_out;
805
}
806
807
/* Grab from the beginning of the LRU list. */
808
entry = sun4c_ulru_ring.ringhd.lru_next;
809
ctx = entry->ctx;
810
811
savectx = sun4c_get_context();
812
flush_user_windows();
813
sun4c_set_context(ctx);
814
sun4c_flush_segment(entry->vaddr);
815
sun4c_user_unmap(entry);
816
remove_ring(sun4c_context_ring + ctx, entry);
817
remove_lru(entry);
818
sun4c_set_context(savectx);
819
820
return entry;
821
822
unlink_out:
823
remove_ring(&sun4c_ufree_ring, entry);
824
return entry;
825
kunlink_out:
826
remove_ring(&sun4c_kfree_ring, entry);
827
return entry;
828
}
829
830
/* NOTE: Must be called with interrupts disabled. */
831
void sun4c_grow_kernel_ring(void)
832
{
833
struct sun4c_mmu_entry *entry;
834
835
/* Prevent deadlock condition. */
836
if (sun4c_user_taken_entries >= max_user_taken_entries)
837
return;
838
839
if (sun4c_ufree_ring.num_entries) {
840
entry = sun4c_ufree_ring.ringhd.next;
841
remove_ring(&sun4c_ufree_ring, entry);
842
add_ring(&sun4c_kfree_ring, entry);
843
sun4c_user_taken_entries++;
844
}
845
}
846
847
/* 2 page buckets for task struct and kernel stack allocation.
848
*
849
* TASK_STACK_BEGIN
850
* bucket[0]
851
* bucket[1]
852
* [ ... ]
853
* bucket[NR_TASK_BUCKETS-1]
854
* TASK_STACK_BEGIN + (sizeof(struct task_bucket) * NR_TASK_BUCKETS)
855
*
856
* Each slot looks like:
857
*
858
* page 1 -- task struct + beginning of kernel stack
859
* page 2 -- rest of kernel stack
860
*/
861
862
union task_union *sun4c_bucket[NR_TASK_BUCKETS];
863
864
static int sun4c_lowbucket_avail;
865
866
#define BUCKET_EMPTY ((union task_union *) 0)
867
#define BUCKET_SHIFT (PAGE_SHIFT + 1) /* log2(sizeof(struct task_bucket)) */
868
#define BUCKET_SIZE (1 << BUCKET_SHIFT)
869
#define BUCKET_NUM(addr) ((((addr) - SUN4C_LOCK_VADDR) >> BUCKET_SHIFT))
870
#define BUCKET_ADDR(num) (((num) << BUCKET_SHIFT) + SUN4C_LOCK_VADDR)
871
#define BUCKET_PTE(page) \
872
((((page) - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(SUN4C_PAGE_KERNEL))
873
#define BUCKET_PTE_PAGE(pte) \
874
(PAGE_OFFSET + (((pte) & SUN4C_PFN_MASK) << PAGE_SHIFT))
875
876
static void get_locked_segment(unsigned long addr)
877
{
878
struct sun4c_mmu_entry *stolen;
879
unsigned long flags;
880
881
local_irq_save(flags);
882
addr &= SUN4C_REAL_PGDIR_MASK;
883
stolen = sun4c_user_strategy();
884
max_user_taken_entries--;
885
stolen->vaddr = addr;
886
flush_user_windows();
887
sun4c_kernel_map(stolen);
888
local_irq_restore(flags);
889
}
890
891
static void free_locked_segment(unsigned long addr)
892
{
893
struct sun4c_mmu_entry *entry;
894
unsigned long flags;
895
unsigned char pseg;
896
897
local_irq_save(flags);
898
addr &= SUN4C_REAL_PGDIR_MASK;
899
pseg = sun4c_get_segmap(addr);
900
entry = &mmu_entry_pool[pseg];
901
902
flush_user_windows();
903
sun4c_flush_segment(addr);
904
sun4c_kernel_unmap(entry);
905
add_ring(&sun4c_ufree_ring, entry);
906
max_user_taken_entries++;
907
local_irq_restore(flags);
908
}
909
910
static inline void garbage_collect(int entry)
911
{
912
int start, end;
913
914
/* 32 buckets per segment... */
915
entry &= ~31;
916
start = entry;
917
for (end = (start + 32); start < end; start++)
918
if (sun4c_bucket[start] != BUCKET_EMPTY)
919
return;
920
921
/* Entire segment empty, release it. */
922
free_locked_segment(BUCKET_ADDR(entry));
923
}
924
925
static struct thread_info *sun4c_alloc_thread_info_node(int node)
926
{
927
unsigned long addr, pages;
928
int entry;
929
930
pages = __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER);
931
if (!pages)
932
return NULL;
933
934
for (entry = sun4c_lowbucket_avail; entry < NR_TASK_BUCKETS; entry++)
935
if (sun4c_bucket[entry] == BUCKET_EMPTY)
936
break;
937
if (entry == NR_TASK_BUCKETS) {
938
free_pages(pages, THREAD_INFO_ORDER);
939
return NULL;
940
}
941
if (entry >= sun4c_lowbucket_avail)
942
sun4c_lowbucket_avail = entry + 1;
943
944
addr = BUCKET_ADDR(entry);
945
sun4c_bucket[entry] = (union task_union *) addr;
946
if(sun4c_get_segmap(addr) == invalid_segment)
947
get_locked_segment(addr);
948
949
/* We are changing the virtual color of the page(s)
950
* so we must flush the cache to guarantee consistency.
951
*/
952
sun4c_flush_page(pages);
953
sun4c_flush_page(pages + PAGE_SIZE);
954
955
sun4c_put_pte(addr, BUCKET_PTE(pages));
956
sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE));
957
958
#ifdef CONFIG_DEBUG_STACK_USAGE
959
memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER);
960
#endif /* DEBUG_STACK_USAGE */
961
962
return (struct thread_info *) addr;
963
}
964
965
static void sun4c_free_thread_info(struct thread_info *ti)
966
{
967
unsigned long tiaddr = (unsigned long) ti;
968
unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr));
969
int entry = BUCKET_NUM(tiaddr);
970
971
/* We are deleting a mapping, so the flush here is mandatory. */
972
sun4c_flush_page(tiaddr);
973
sun4c_flush_page(tiaddr + PAGE_SIZE);
974
975
sun4c_put_pte(tiaddr, 0);
976
sun4c_put_pte(tiaddr + PAGE_SIZE, 0);
977
978
sun4c_bucket[entry] = BUCKET_EMPTY;
979
if (entry < sun4c_lowbucket_avail)
980
sun4c_lowbucket_avail = entry;
981
982
free_pages(pages, THREAD_INFO_ORDER);
983
garbage_collect(entry);
984
}
985
986
static void __init sun4c_init_buckets(void)
987
{
988
int entry;
989
990
if (sizeof(union thread_union) != (PAGE_SIZE << THREAD_INFO_ORDER)) {
991
extern void thread_info_size_is_bolixed_pete(void);
992
thread_info_size_is_bolixed_pete();
993
}
994
995
for (entry = 0; entry < NR_TASK_BUCKETS; entry++)
996
sun4c_bucket[entry] = BUCKET_EMPTY;
997
sun4c_lowbucket_avail = 0;
998
}
999
1000
static unsigned long sun4c_iobuffer_start;
1001
static unsigned long sun4c_iobuffer_end;
1002
static unsigned long sun4c_iobuffer_high;
1003
static unsigned long *sun4c_iobuffer_map;
1004
static int iobuffer_map_size;
1005
1006
/*
1007
* Alias our pages so they do not cause a trap.
1008
* Also one page may be aliased into several I/O areas and we may
1009
* finish these I/O separately.
1010
*/
1011
static char *sun4c_lockarea(char *vaddr, unsigned long size)
1012
{
1013
unsigned long base, scan;
1014
unsigned long npages;
1015
unsigned long vpage;
1016
unsigned long pte;
1017
unsigned long apage;
1018
unsigned long high;
1019
unsigned long flags;
1020
1021
npages = (((unsigned long)vaddr & ~PAGE_MASK) +
1022
size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
1023
1024
local_irq_save(flags);
1025
base = bitmap_find_next_zero_area(sun4c_iobuffer_map, iobuffer_map_size,
1026
0, npages, 0);
1027
if (base >= iobuffer_map_size)
1028
goto abend;
1029
1030
high = ((base + npages) << PAGE_SHIFT) + sun4c_iobuffer_start;
1031
high = SUN4C_REAL_PGDIR_ALIGN(high);
1032
while (high > sun4c_iobuffer_high) {
1033
get_locked_segment(sun4c_iobuffer_high);
1034
sun4c_iobuffer_high += SUN4C_REAL_PGDIR_SIZE;
1035
}
1036
1037
vpage = ((unsigned long) vaddr) & PAGE_MASK;
1038
for (scan = base; scan < base+npages; scan++) {
1039
pte = ((vpage-PAGE_OFFSET) >> PAGE_SHIFT);
1040
pte |= pgprot_val(SUN4C_PAGE_KERNEL);
1041
pte |= _SUN4C_PAGE_NOCACHE;
1042
set_bit(scan, sun4c_iobuffer_map);
1043
apage = (scan << PAGE_SHIFT) + sun4c_iobuffer_start;
1044
1045
/* Flush original mapping so we see the right things later. */
1046
sun4c_flush_page(vpage);
1047
1048
sun4c_put_pte(apage, pte);
1049
vpage += PAGE_SIZE;
1050
}
1051
local_irq_restore(flags);
1052
return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start +
1053
(((unsigned long) vaddr) & ~PAGE_MASK));
1054
1055
abend:
1056
local_irq_restore(flags);
1057
printk("DMA vaddr=0x%p size=%08lx\n", vaddr, size);
1058
panic("Out of iobuffer table");
1059
return NULL;
1060
}
1061
1062
static void sun4c_unlockarea(char *vaddr, unsigned long size)
1063
{
1064
unsigned long vpage, npages;
1065
unsigned long flags;
1066
int scan, high;
1067
1068
vpage = (unsigned long)vaddr & PAGE_MASK;
1069
npages = (((unsigned long)vaddr & ~PAGE_MASK) +
1070
size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
1071
1072
local_irq_save(flags);
1073
while (npages != 0) {
1074
--npages;
1075
1076
/* This mapping is marked non-cachable, no flush necessary. */
1077
sun4c_put_pte(vpage, 0);
1078
clear_bit((vpage - sun4c_iobuffer_start) >> PAGE_SHIFT,
1079
sun4c_iobuffer_map);
1080
vpage += PAGE_SIZE;
1081
}
1082
1083
/* garbage collect */
1084
scan = (sun4c_iobuffer_high - sun4c_iobuffer_start) >> PAGE_SHIFT;
1085
while (scan >= 0 && !sun4c_iobuffer_map[scan >> 5])
1086
scan -= 32;
1087
scan += 32;
1088
high = sun4c_iobuffer_start + (scan << PAGE_SHIFT);
1089
high = SUN4C_REAL_PGDIR_ALIGN(high) + SUN4C_REAL_PGDIR_SIZE;
1090
while (high < sun4c_iobuffer_high) {
1091
sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE;
1092
free_locked_segment(sun4c_iobuffer_high);
1093
}
1094
local_irq_restore(flags);
1095
}
1096
1097
/* Note the scsi code at init time passes to here buffers
1098
* which sit on the kernel stack, those are already locked
1099
* by implication and fool the page locking code above
1100
* if passed to by mistake.
1101
*/
1102
static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len)
1103
{
1104
unsigned long page;
1105
1106
page = ((unsigned long)bufptr) & PAGE_MASK;
1107
if (!virt_addr_valid(page)) {
1108
sun4c_flush_page(page);
1109
return (__u32)bufptr; /* already locked */
1110
}
1111
return (__u32)sun4c_lockarea(bufptr, len);
1112
}
1113
1114
static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
1115
{
1116
while (sz != 0) {
1117
--sz;
1118
sg->dma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length);
1119
sg->dma_length = sg->length;
1120
sg = sg_next(sg);
1121
}
1122
}
1123
1124
static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len)
1125
{
1126
if (bufptr < sun4c_iobuffer_start)
1127
return; /* On kernel stack or similar, see above */
1128
sun4c_unlockarea((char *)bufptr, len);
1129
}
1130
1131
static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
1132
{
1133
while (sz != 0) {
1134
--sz;
1135
sun4c_unlockarea((char *)sg->dma_address, sg->length);
1136
sg = sg_next(sg);
1137
}
1138
}
1139
1140
#define TASK_ENTRY_SIZE BUCKET_SIZE /* see above */
1141
#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
1142
1143
struct vm_area_struct sun4c_kstack_vma;
1144
1145
static void __init sun4c_init_lock_areas(void)
1146
{
1147
unsigned long sun4c_taskstack_start;
1148
unsigned long sun4c_taskstack_end;
1149
int bitmap_size;
1150
1151
sun4c_init_buckets();
1152
sun4c_taskstack_start = SUN4C_LOCK_VADDR;
1153
sun4c_taskstack_end = (sun4c_taskstack_start +
1154
(TASK_ENTRY_SIZE * NR_TASK_BUCKETS));
1155
if (sun4c_taskstack_end >= SUN4C_LOCK_END) {
1156
prom_printf("Too many tasks, decrease NR_TASK_BUCKETS please.\n");
1157
prom_halt();
1158
}
1159
1160
sun4c_iobuffer_start = sun4c_iobuffer_high =
1161
SUN4C_REAL_PGDIR_ALIGN(sun4c_taskstack_end);
1162
sun4c_iobuffer_end = SUN4C_LOCK_END;
1163
bitmap_size = (sun4c_iobuffer_end - sun4c_iobuffer_start) >> PAGE_SHIFT;
1164
bitmap_size = (bitmap_size + 7) >> 3;
1165
bitmap_size = LONG_ALIGN(bitmap_size);
1166
iobuffer_map_size = bitmap_size << 3;
1167
sun4c_iobuffer_map = __alloc_bootmem(bitmap_size, SMP_CACHE_BYTES, 0UL);
1168
memset((void *) sun4c_iobuffer_map, 0, bitmap_size);
1169
1170
sun4c_kstack_vma.vm_mm = &init_mm;
1171
sun4c_kstack_vma.vm_start = sun4c_taskstack_start;
1172
sun4c_kstack_vma.vm_end = sun4c_taskstack_end;
1173
sun4c_kstack_vma.vm_page_prot = PAGE_SHARED;
1174
sun4c_kstack_vma.vm_flags = VM_READ | VM_WRITE | VM_EXEC;
1175
insert_vm_struct(&init_mm, &sun4c_kstack_vma);
1176
}
1177
1178
/* Cache flushing on the sun4c. */
1179
static void sun4c_flush_cache_all(void)
1180
{
1181
unsigned long begin, end;
1182
1183
flush_user_windows();
1184
begin = (KERNBASE + SUN4C_REAL_PGDIR_SIZE);
1185
end = (begin + SUN4C_VAC_SIZE);
1186
1187
if (sun4c_vacinfo.linesize == 32) {
1188
while (begin < end) {
1189
__asm__ __volatile__(
1190
"ld [%0 + 0x00], %%g0\n\t"
1191
"ld [%0 + 0x20], %%g0\n\t"
1192
"ld [%0 + 0x40], %%g0\n\t"
1193
"ld [%0 + 0x60], %%g0\n\t"
1194
"ld [%0 + 0x80], %%g0\n\t"
1195
"ld [%0 + 0xa0], %%g0\n\t"
1196
"ld [%0 + 0xc0], %%g0\n\t"
1197
"ld [%0 + 0xe0], %%g0\n\t"
1198
"ld [%0 + 0x100], %%g0\n\t"
1199
"ld [%0 + 0x120], %%g0\n\t"
1200
"ld [%0 + 0x140], %%g0\n\t"
1201
"ld [%0 + 0x160], %%g0\n\t"
1202
"ld [%0 + 0x180], %%g0\n\t"
1203
"ld [%0 + 0x1a0], %%g0\n\t"
1204
"ld [%0 + 0x1c0], %%g0\n\t"
1205
"ld [%0 + 0x1e0], %%g0\n"
1206
: : "r" (begin));
1207
begin += 512;
1208
}
1209
} else {
1210
while (begin < end) {
1211
__asm__ __volatile__(
1212
"ld [%0 + 0x00], %%g0\n\t"
1213
"ld [%0 + 0x10], %%g0\n\t"
1214
"ld [%0 + 0x20], %%g0\n\t"
1215
"ld [%0 + 0x30], %%g0\n\t"
1216
"ld [%0 + 0x40], %%g0\n\t"
1217
"ld [%0 + 0x50], %%g0\n\t"
1218
"ld [%0 + 0x60], %%g0\n\t"
1219
"ld [%0 + 0x70], %%g0\n\t"
1220
"ld [%0 + 0x80], %%g0\n\t"
1221
"ld [%0 + 0x90], %%g0\n\t"
1222
"ld [%0 + 0xa0], %%g0\n\t"
1223
"ld [%0 + 0xb0], %%g0\n\t"
1224
"ld [%0 + 0xc0], %%g0\n\t"
1225
"ld [%0 + 0xd0], %%g0\n\t"
1226
"ld [%0 + 0xe0], %%g0\n\t"
1227
"ld [%0 + 0xf0], %%g0\n"
1228
: : "r" (begin));
1229
begin += 256;
1230
}
1231
}
1232
}
1233
1234
static void sun4c_flush_cache_mm(struct mm_struct *mm)
1235
{
1236
int new_ctx = mm->context;
1237
1238
if (new_ctx != NO_CONTEXT) {
1239
flush_user_windows();
1240
1241
if (sun4c_context_ring[new_ctx].num_entries) {
1242
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
1243
unsigned long flags;
1244
1245
local_irq_save(flags);
1246
if (head->next != head) {
1247
struct sun4c_mmu_entry *entry = head->next;
1248
int savectx = sun4c_get_context();
1249
1250
sun4c_set_context(new_ctx);
1251
sun4c_flush_context();
1252
do {
1253
struct sun4c_mmu_entry *next = entry->next;
1254
1255
sun4c_user_unmap(entry);
1256
free_user_entry(new_ctx, entry);
1257
1258
entry = next;
1259
} while (entry != head);
1260
sun4c_set_context(savectx);
1261
}
1262
local_irq_restore(flags);
1263
}
1264
}
1265
}
1266
1267
static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
1268
{
1269
struct mm_struct *mm = vma->vm_mm;
1270
int new_ctx = mm->context;
1271
1272
if (new_ctx != NO_CONTEXT) {
1273
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
1274
struct sun4c_mmu_entry *entry;
1275
unsigned long flags;
1276
1277
flush_user_windows();
1278
1279
local_irq_save(flags);
1280
/* All user segmap chains are ordered on entry->vaddr. */
1281
for (entry = head->next;
1282
(entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
1283
entry = entry->next)
1284
;
1285
1286
/* Tracing various job mixtures showed that this conditional
1287
* only passes ~35% of the time for most worse case situations,
1288
* therefore we avoid all of this gross overhead ~65% of the time.
1289
*/
1290
if ((entry != head) && (entry->vaddr < end)) {
1291
int octx = sun4c_get_context();
1292
sun4c_set_context(new_ctx);
1293
1294
/* At this point, always, (start >= entry->vaddr) and
1295
* (entry->vaddr < end), once the latter condition
1296
* ceases to hold, or we hit the end of the list, we
1297
* exit the loop. The ordering of all user allocated
1298
* segmaps makes this all work out so beautifully.
1299
*/
1300
do {
1301
struct sun4c_mmu_entry *next = entry->next;
1302
unsigned long realend;
1303
1304
/* "realstart" is always >= entry->vaddr */
1305
realend = entry->vaddr + SUN4C_REAL_PGDIR_SIZE;
1306
if (end < realend)
1307
realend = end;
1308
if ((realend - entry->vaddr) <= (PAGE_SIZE << 3)) {
1309
unsigned long page = entry->vaddr;
1310
while (page < realend) {
1311
sun4c_flush_page(page);
1312
page += PAGE_SIZE;
1313
}
1314
} else {
1315
sun4c_flush_segment(entry->vaddr);
1316
sun4c_user_unmap(entry);
1317
free_user_entry(new_ctx, entry);
1318
}
1319
entry = next;
1320
} while ((entry != head) && (entry->vaddr < end));
1321
sun4c_set_context(octx);
1322
}
1323
local_irq_restore(flags);
1324
}
1325
}
1326
1327
static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
1328
{
1329
struct mm_struct *mm = vma->vm_mm;
1330
int new_ctx = mm->context;
1331
1332
/* Sun4c has no separate I/D caches so cannot optimize for non
1333
* text page flushes.
1334
*/
1335
if (new_ctx != NO_CONTEXT) {
1336
int octx = sun4c_get_context();
1337
unsigned long flags;
1338
1339
flush_user_windows();
1340
local_irq_save(flags);
1341
sun4c_set_context(new_ctx);
1342
sun4c_flush_page(page);
1343
sun4c_set_context(octx);
1344
local_irq_restore(flags);
1345
}
1346
}
1347
1348
static void sun4c_flush_page_to_ram(unsigned long page)
1349
{
1350
unsigned long flags;
1351
1352
local_irq_save(flags);
1353
sun4c_flush_page(page);
1354
local_irq_restore(flags);
1355
}
1356
1357
/* Sun4c cache is unified, both instructions and data live there, so
1358
* no need to flush the on-stack instructions for new signal handlers.
1359
*/
1360
static void sun4c_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
1361
{
1362
}
1363
1364
/* TLB flushing on the sun4c. These routines count on the cache
1365
* flushing code to flush the user register windows so that we need
1366
* not do so when we get here.
1367
*/
1368
1369
static void sun4c_flush_tlb_all(void)
1370
{
1371
struct sun4c_mmu_entry *this_entry, *next_entry;
1372
unsigned long flags;
1373
int savectx, ctx;
1374
1375
local_irq_save(flags);
1376
this_entry = sun4c_kernel_ring.ringhd.next;
1377
savectx = sun4c_get_context();
1378
flush_user_windows();
1379
while (sun4c_kernel_ring.num_entries) {
1380
next_entry = this_entry->next;
1381
sun4c_flush_segment(this_entry->vaddr);
1382
for (ctx = 0; ctx < num_contexts; ctx++) {
1383
sun4c_set_context(ctx);
1384
sun4c_put_segmap(this_entry->vaddr, invalid_segment);
1385
}
1386
free_kernel_entry(this_entry, &sun4c_kernel_ring);
1387
this_entry = next_entry;
1388
}
1389
sun4c_set_context(savectx);
1390
local_irq_restore(flags);
1391
}
1392
1393
static void sun4c_flush_tlb_mm(struct mm_struct *mm)
1394
{
1395
int new_ctx = mm->context;
1396
1397
if (new_ctx != NO_CONTEXT) {
1398
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
1399
unsigned long flags;
1400
1401
local_irq_save(flags);
1402
if (head->next != head) {
1403
struct sun4c_mmu_entry *entry = head->next;
1404
int savectx = sun4c_get_context();
1405
1406
sun4c_set_context(new_ctx);
1407
sun4c_flush_context();
1408
do {
1409
struct sun4c_mmu_entry *next = entry->next;
1410
1411
sun4c_user_unmap(entry);
1412
free_user_entry(new_ctx, entry);
1413
1414
entry = next;
1415
} while (entry != head);
1416
sun4c_set_context(savectx);
1417
}
1418
local_irq_restore(flags);
1419
}
1420
}
1421
1422
static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
1423
{
1424
struct mm_struct *mm = vma->vm_mm;
1425
int new_ctx = mm->context;
1426
1427
if (new_ctx != NO_CONTEXT) {
1428
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
1429
struct sun4c_mmu_entry *entry;
1430
unsigned long flags;
1431
1432
local_irq_save(flags);
1433
/* See commentary in sun4c_flush_cache_range(). */
1434
for (entry = head->next;
1435
(entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
1436
entry = entry->next)
1437
;
1438
1439
if ((entry != head) && (entry->vaddr < end)) {
1440
int octx = sun4c_get_context();
1441
1442
sun4c_set_context(new_ctx);
1443
do {
1444
struct sun4c_mmu_entry *next = entry->next;
1445
1446
sun4c_flush_segment(entry->vaddr);
1447
sun4c_user_unmap(entry);
1448
free_user_entry(new_ctx, entry);
1449
1450
entry = next;
1451
} while ((entry != head) && (entry->vaddr < end));
1452
sun4c_set_context(octx);
1453
}
1454
local_irq_restore(flags);
1455
}
1456
}
1457
1458
static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
1459
{
1460
struct mm_struct *mm = vma->vm_mm;
1461
int new_ctx = mm->context;
1462
1463
if (new_ctx != NO_CONTEXT) {
1464
int savectx = sun4c_get_context();
1465
unsigned long flags;
1466
1467
local_irq_save(flags);
1468
sun4c_set_context(new_ctx);
1469
page &= PAGE_MASK;
1470
sun4c_flush_page(page);
1471
sun4c_put_pte(page, 0);
1472
sun4c_set_context(savectx);
1473
local_irq_restore(flags);
1474
}
1475
}
1476
1477
static inline void sun4c_mapioaddr(unsigned long physaddr, unsigned long virt_addr)
1478
{
1479
unsigned long page_entry, pg_iobits;
1480
1481
pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE |
1482
_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE;
1483
1484
page_entry = ((physaddr >> PAGE_SHIFT) & SUN4C_PFN_MASK);
1485
page_entry |= ((pg_iobits | _SUN4C_PAGE_PRIV) & ~(_SUN4C_PAGE_PRESENT));
1486
sun4c_put_pte(virt_addr, page_entry);
1487
}
1488
1489
static void sun4c_mapiorange(unsigned int bus, unsigned long xpa,
1490
unsigned long xva, unsigned int len)
1491
{
1492
while (len != 0) {
1493
len -= PAGE_SIZE;
1494
sun4c_mapioaddr(xpa, xva);
1495
xva += PAGE_SIZE;
1496
xpa += PAGE_SIZE;
1497
}
1498
}
1499
1500
static void sun4c_unmapiorange(unsigned long virt_addr, unsigned int len)
1501
{
1502
while (len != 0) {
1503
len -= PAGE_SIZE;
1504
sun4c_put_pte(virt_addr, 0);
1505
virt_addr += PAGE_SIZE;
1506
}
1507
}
1508
1509
static void sun4c_alloc_context(struct mm_struct *old_mm, struct mm_struct *mm)
1510
{
1511
struct ctx_list *ctxp;
1512
1513
ctxp = ctx_free.next;
1514
if (ctxp != &ctx_free) {
1515
remove_from_ctx_list(ctxp);
1516
add_to_used_ctxlist(ctxp);
1517
mm->context = ctxp->ctx_number;
1518
ctxp->ctx_mm = mm;
1519
return;
1520
}
1521
ctxp = ctx_used.next;
1522
if (ctxp->ctx_mm == old_mm)
1523
ctxp = ctxp->next;
1524
remove_from_ctx_list(ctxp);
1525
add_to_used_ctxlist(ctxp);
1526
ctxp->ctx_mm->context = NO_CONTEXT;
1527
ctxp->ctx_mm = mm;
1528
mm->context = ctxp->ctx_number;
1529
sun4c_demap_context(&sun4c_context_ring[ctxp->ctx_number],
1530
ctxp->ctx_number);
1531
}
1532
1533
/* Switch the current MM context. */
1534
static void sun4c_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk, int cpu)
1535
{
1536
struct ctx_list *ctx;
1537
int dirty = 0;
1538
1539
if (mm->context == NO_CONTEXT) {
1540
dirty = 1;
1541
sun4c_alloc_context(old_mm, mm);
1542
} else {
1543
/* Update the LRU ring of contexts. */
1544
ctx = ctx_list_pool + mm->context;
1545
remove_from_ctx_list(ctx);
1546
add_to_used_ctxlist(ctx);
1547
}
1548
if (dirty || old_mm != mm)
1549
sun4c_set_context(mm->context);
1550
}
1551
1552
static void sun4c_destroy_context(struct mm_struct *mm)
1553
{
1554
struct ctx_list *ctx_old;
1555
1556
if (mm->context != NO_CONTEXT) {
1557
sun4c_demap_context(&sun4c_context_ring[mm->context], mm->context);
1558
ctx_old = ctx_list_pool + mm->context;
1559
remove_from_ctx_list(ctx_old);
1560
add_to_free_ctxlist(ctx_old);
1561
mm->context = NO_CONTEXT;
1562
}
1563
}
1564
1565
static void sun4c_mmu_info(struct seq_file *m)
1566
{
1567
int used_user_entries, i;
1568
1569
used_user_entries = 0;
1570
for (i = 0; i < num_contexts; i++)
1571
used_user_entries += sun4c_context_ring[i].num_entries;
1572
1573
seq_printf(m,
1574
"vacsize\t\t: %d bytes\n"
1575
"vachwflush\t: %s\n"
1576
"vaclinesize\t: %d bytes\n"
1577
"mmuctxs\t\t: %d\n"
1578
"mmupsegs\t: %d\n"
1579
"kernelpsegs\t: %d\n"
1580
"kfreepsegs\t: %d\n"
1581
"usedpsegs\t: %d\n"
1582
"ufreepsegs\t: %d\n"
1583
"user_taken\t: %d\n"
1584
"max_taken\t: %d\n",
1585
sun4c_vacinfo.num_bytes,
1586
(sun4c_vacinfo.do_hwflushes ? "yes" : "no"),
1587
sun4c_vacinfo.linesize,
1588
num_contexts,
1589
(invalid_segment + 1),
1590
sun4c_kernel_ring.num_entries,
1591
sun4c_kfree_ring.num_entries,
1592
used_user_entries,
1593
sun4c_ufree_ring.num_entries,
1594
sun4c_user_taken_entries,
1595
max_user_taken_entries);
1596
}
1597
1598
/* Nothing below here should touch the mmu hardware nor the mmu_entry
1599
* data structures.
1600
*/
1601
1602
/* First the functions which the mid-level code uses to directly
1603
* manipulate the software page tables. Some defines since we are
1604
* emulating the i386 page directory layout.
1605
*/
1606
#define PGD_PRESENT 0x001
1607
#define PGD_RW 0x002
1608
#define PGD_USER 0x004
1609
#define PGD_ACCESSED 0x020
1610
#define PGD_DIRTY 0x040
1611
#define PGD_TABLE (PGD_PRESENT | PGD_RW | PGD_USER | PGD_ACCESSED | PGD_DIRTY)
1612
1613
static void sun4c_set_pte(pte_t *ptep, pte_t pte)
1614
{
1615
*ptep = pte;
1616
}
1617
1618
static void sun4c_pgd_set(pgd_t * pgdp, pmd_t * pmdp)
1619
{
1620
}
1621
1622
static void sun4c_pmd_set(pmd_t * pmdp, pte_t * ptep)
1623
{
1624
pmdp->pmdv[0] = PGD_TABLE | (unsigned long) ptep;
1625
}
1626
1627
static void sun4c_pmd_populate(pmd_t * pmdp, struct page * ptep)
1628
{
1629
if (page_address(ptep) == NULL) BUG(); /* No highmem on sun4c */
1630
pmdp->pmdv[0] = PGD_TABLE | (unsigned long) page_address(ptep);
1631
}
1632
1633
static int sun4c_pte_present(pte_t pte)
1634
{
1635
return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0);
1636
}
1637
static void sun4c_pte_clear(pte_t *ptep) { *ptep = __pte(0); }
1638
1639
static int sun4c_pmd_bad(pmd_t pmd)
1640
{
1641
return (((pmd_val(pmd) & ~PAGE_MASK) != PGD_TABLE) ||
1642
(!virt_addr_valid(pmd_val(pmd))));
1643
}
1644
1645
static int sun4c_pmd_present(pmd_t pmd)
1646
{
1647
return ((pmd_val(pmd) & PGD_PRESENT) != 0);
1648
}
1649
1650
#if 0 /* if PMD takes one word */
1651
static void sun4c_pmd_clear(pmd_t *pmdp) { *pmdp = __pmd(0); }
1652
#else /* if pmd_t is a longish aggregate */
1653
static void sun4c_pmd_clear(pmd_t *pmdp) {
1654
memset((void *)pmdp, 0, sizeof(pmd_t));
1655
}
1656
#endif
1657
1658
static int sun4c_pgd_none(pgd_t pgd) { return 0; }
1659
static int sun4c_pgd_bad(pgd_t pgd) { return 0; }
1660
static int sun4c_pgd_present(pgd_t pgd) { return 1; }
1661
static void sun4c_pgd_clear(pgd_t * pgdp) { }
1662
1663
/*
1664
* The following only work if pte_present() is true.
1665
* Undefined behaviour if not..
1666
*/
1667
static pte_t sun4c_pte_mkwrite(pte_t pte)
1668
{
1669
pte = __pte(pte_val(pte) | _SUN4C_PAGE_WRITE);
1670
if (pte_val(pte) & _SUN4C_PAGE_MODIFIED)
1671
pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE);
1672
return pte;
1673
}
1674
1675
static pte_t sun4c_pte_mkdirty(pte_t pte)
1676
{
1677
pte = __pte(pte_val(pte) | _SUN4C_PAGE_MODIFIED);
1678
if (pte_val(pte) & _SUN4C_PAGE_WRITE)
1679
pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_WRITE);
1680
return pte;
1681
}
1682
1683
static pte_t sun4c_pte_mkyoung(pte_t pte)
1684
{
1685
pte = __pte(pte_val(pte) | _SUN4C_PAGE_ACCESSED);
1686
if (pte_val(pte) & _SUN4C_PAGE_READ)
1687
pte = __pte(pte_val(pte) | _SUN4C_PAGE_SILENT_READ);
1688
return pte;
1689
}
1690
1691
/*
1692
* Conversion functions: convert a page and protection to a page entry,
1693
* and a page entry and page directory to the page they refer to.
1694
*/
1695
static pte_t sun4c_mk_pte(struct page *page, pgprot_t pgprot)
1696
{
1697
return __pte(page_to_pfn(page) | pgprot_val(pgprot));
1698
}
1699
1700
static pte_t sun4c_mk_pte_phys(unsigned long phys_page, pgprot_t pgprot)
1701
{
1702
return __pte((phys_page >> PAGE_SHIFT) | pgprot_val(pgprot));
1703
}
1704
1705
static pte_t sun4c_mk_pte_io(unsigned long page, pgprot_t pgprot, int space)
1706
{
1707
return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot));
1708
}
1709
1710
static unsigned long sun4c_pte_pfn(pte_t pte)
1711
{
1712
return pte_val(pte) & SUN4C_PFN_MASK;
1713
}
1714
1715
static pte_t sun4c_pgoff_to_pte(unsigned long pgoff)
1716
{
1717
return __pte(pgoff | _SUN4C_PAGE_FILE);
1718
}
1719
1720
static unsigned long sun4c_pte_to_pgoff(pte_t pte)
1721
{
1722
return pte_val(pte) & ((1UL << PTE_FILE_MAX_BITS) - 1);
1723
}
1724
1725
1726
static inline unsigned long sun4c_pmd_page_v(pmd_t pmd)
1727
{
1728
return (pmd_val(pmd) & PAGE_MASK);
1729
}
1730
1731
static struct page *sun4c_pmd_page(pmd_t pmd)
1732
{
1733
return virt_to_page(sun4c_pmd_page_v(pmd));
1734
}
1735
1736
static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; }
1737
1738
/* to find an entry in a page-table-directory */
1739
static inline pgd_t *sun4c_pgd_offset(struct mm_struct * mm, unsigned long address)
1740
{
1741
return mm->pgd + (address >> SUN4C_PGDIR_SHIFT);
1742
}
1743
1744
/* Find an entry in the second-level page table.. */
1745
static pmd_t *sun4c_pmd_offset(pgd_t * dir, unsigned long address)
1746
{
1747
return (pmd_t *) dir;
1748
}
1749
1750
/* Find an entry in the third-level page table.. */
1751
pte_t *sun4c_pte_offset_kernel(pmd_t * dir, unsigned long address)
1752
{
1753
return (pte_t *) sun4c_pmd_page_v(*dir) +
1754
((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1));
1755
}
1756
1757
static unsigned long sun4c_swp_type(swp_entry_t entry)
1758
{
1759
return (entry.val & SUN4C_SWP_TYPE_MASK);
1760
}
1761
1762
static unsigned long sun4c_swp_offset(swp_entry_t entry)
1763
{
1764
return (entry.val >> SUN4C_SWP_OFF_SHIFT) & SUN4C_SWP_OFF_MASK;
1765
}
1766
1767
static swp_entry_t sun4c_swp_entry(unsigned long type, unsigned long offset)
1768
{
1769
return (swp_entry_t) {
1770
(offset & SUN4C_SWP_OFF_MASK) << SUN4C_SWP_OFF_SHIFT
1771
| (type & SUN4C_SWP_TYPE_MASK) };
1772
}
1773
1774
static void sun4c_free_pte_slow(pte_t *pte)
1775
{
1776
free_page((unsigned long)pte);
1777
}
1778
1779
static void sun4c_free_pgd_slow(pgd_t *pgd)
1780
{
1781
free_page((unsigned long)pgd);
1782
}
1783
1784
static pgd_t *sun4c_get_pgd_fast(void)
1785
{
1786
unsigned long *ret;
1787
1788
if ((ret = pgd_quicklist) != NULL) {
1789
pgd_quicklist = (unsigned long *)(*ret);
1790
ret[0] = ret[1];
1791
pgtable_cache_size--;
1792
} else {
1793
pgd_t *init;
1794
1795
ret = (unsigned long *)__get_free_page(GFP_KERNEL);
1796
memset (ret, 0, (KERNBASE / SUN4C_PGDIR_SIZE) * sizeof(pgd_t));
1797
init = sun4c_pgd_offset(&init_mm, 0);
1798
memcpy (((pgd_t *)ret) + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
1799
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
1800
}
1801
return (pgd_t *)ret;
1802
}
1803
1804
static void sun4c_free_pgd_fast(pgd_t *pgd)
1805
{
1806
*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
1807
pgd_quicklist = (unsigned long *) pgd;
1808
pgtable_cache_size++;
1809
}
1810
1811
1812
static inline pte_t *
1813
sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
1814
{
1815
unsigned long *ret;
1816
1817
if ((ret = (unsigned long *)pte_quicklist) != NULL) {
1818
pte_quicklist = (unsigned long *)(*ret);
1819
ret[0] = ret[1];
1820
pgtable_cache_size--;
1821
}
1822
return (pte_t *)ret;
1823
}
1824
1825
static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
1826
{
1827
pte_t *pte;
1828
1829
if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL)
1830
return pte;
1831
1832
pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
1833
return pte;
1834
}
1835
1836
static pgtable_t sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address)
1837
{
1838
pte_t *pte;
1839
struct page *page;
1840
1841
pte = sun4c_pte_alloc_one_kernel(mm, address);
1842
if (pte == NULL)
1843
return NULL;
1844
page = virt_to_page(pte);
1845
pgtable_page_ctor(page);
1846
return page;
1847
}
1848
1849
static inline void sun4c_free_pte_fast(pte_t *pte)
1850
{
1851
*(unsigned long *)pte = (unsigned long) pte_quicklist;
1852
pte_quicklist = (unsigned long *) pte;
1853
pgtable_cache_size++;
1854
}
1855
1856
static void sun4c_pte_free(pgtable_t pte)
1857
{
1858
pgtable_page_dtor(pte);
1859
sun4c_free_pte_fast(page_address(pte));
1860
}
1861
1862
/*
1863
* allocating and freeing a pmd is trivial: the 1-entry pmd is
1864
* inside the pgd, so has no extra memory associated with it.
1865
*/
1866
static pmd_t *sun4c_pmd_alloc_one(struct mm_struct *mm, unsigned long address)
1867
{
1868
BUG();
1869
return NULL;
1870
}
1871
1872
static void sun4c_free_pmd_fast(pmd_t * pmd) { }
1873
1874
static void sun4c_check_pgt_cache(int low, int high)
1875
{
1876
if (pgtable_cache_size > high) {
1877
do {
1878
if (pgd_quicklist)
1879
sun4c_free_pgd_slow(sun4c_get_pgd_fast());
1880
if (pte_quicklist)
1881
sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0));
1882
} while (pgtable_cache_size > low);
1883
}
1884
}
1885
1886
/* An experiment, turn off by default for now... -DaveM */
1887
#define SUN4C_PRELOAD_PSEG
1888
1889
void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
1890
{
1891
unsigned long flags;
1892
int pseg;
1893
1894
if (vma->vm_mm->context == NO_CONTEXT)
1895
return;
1896
1897
local_irq_save(flags);
1898
address &= PAGE_MASK;
1899
if ((pseg = sun4c_get_segmap(address)) == invalid_segment) {
1900
struct sun4c_mmu_entry *entry = sun4c_user_strategy();
1901
struct mm_struct *mm = vma->vm_mm;
1902
unsigned long start, end;
1903
1904
entry->vaddr = start = (address & SUN4C_REAL_PGDIR_MASK);
1905
entry->ctx = mm->context;
1906
add_ring_ordered(sun4c_context_ring + mm->context, entry);
1907
sun4c_put_segmap(entry->vaddr, entry->pseg);
1908
end = start + SUN4C_REAL_PGDIR_SIZE;
1909
while (start < end) {
1910
#ifdef SUN4C_PRELOAD_PSEG
1911
pgd_t *pgdp = sun4c_pgd_offset(mm, start);
1912
pte_t *ptep;
1913
1914
if (!pgdp)
1915
goto no_mapping;
1916
ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, start);
1917
if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT))
1918
goto no_mapping;
1919
sun4c_put_pte(start, pte_val(*ptep));
1920
goto next;
1921
1922
no_mapping:
1923
#endif
1924
sun4c_put_pte(start, 0);
1925
#ifdef SUN4C_PRELOAD_PSEG
1926
next:
1927
#endif
1928
start += PAGE_SIZE;
1929
}
1930
#ifndef SUN4C_PRELOAD_PSEG
1931
sun4c_put_pte(address, pte_val(*ptep));
1932
#endif
1933
local_irq_restore(flags);
1934
return;
1935
} else {
1936
struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg];
1937
1938
remove_lru(entry);
1939
add_lru(entry);
1940
}
1941
1942
sun4c_put_pte(address, pte_val(*ptep));
1943
local_irq_restore(flags);
1944
}
1945
1946
extern void sparc_context_init(int);
1947
extern unsigned long bootmem_init(unsigned long *pages_avail);
1948
extern unsigned long last_valid_pfn;
1949
1950
void __init sun4c_paging_init(void)
1951
{
1952
int i, cnt;
1953
unsigned long kernel_end, vaddr;
1954
extern struct resource sparc_iomap;
1955
unsigned long end_pfn, pages_avail;
1956
1957
kernel_end = (unsigned long) &_end;
1958
kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
1959
1960
pages_avail = 0;
1961
last_valid_pfn = bootmem_init(&pages_avail);
1962
end_pfn = last_valid_pfn;
1963
1964
sun4c_probe_mmu();
1965
invalid_segment = (num_segmaps - 1);
1966
sun4c_init_mmu_entry_pool();
1967
sun4c_init_rings();
1968
sun4c_init_map_kernelprom(kernel_end);
1969
sun4c_init_clean_mmu(kernel_end);
1970
sun4c_init_fill_kernel_ring(SUN4C_KERNEL_BUCKETS);
1971
sun4c_init_lock_area(sparc_iomap.start, IOBASE_END);
1972
sun4c_init_lock_area(DVMA_VADDR, DVMA_END);
1973
sun4c_init_lock_areas();
1974
sun4c_init_fill_user_ring();
1975
1976
sun4c_set_context(0);
1977
memset(swapper_pg_dir, 0, PAGE_SIZE);
1978
memset(pg0, 0, PAGE_SIZE);
1979
memset(pg1, 0, PAGE_SIZE);
1980
memset(pg2, 0, PAGE_SIZE);
1981
memset(pg3, 0, PAGE_SIZE);
1982
1983
/* Save work later. */
1984
vaddr = VMALLOC_START;
1985
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg0);
1986
vaddr += SUN4C_PGDIR_SIZE;
1987
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg1);
1988
vaddr += SUN4C_PGDIR_SIZE;
1989
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg2);
1990
vaddr += SUN4C_PGDIR_SIZE;
1991
swapper_pg_dir[vaddr>>SUN4C_PGDIR_SHIFT] = __pgd(PGD_TABLE | (unsigned long) pg3);
1992
sun4c_init_ss2_cache_bug();
1993
sparc_context_init(num_contexts);
1994
1995
{
1996
unsigned long zones_size[MAX_NR_ZONES];
1997
unsigned long zholes_size[MAX_NR_ZONES];
1998
unsigned long npages;
1999
int znum;
2000
2001
for (znum = 0; znum < MAX_NR_ZONES; znum++)
2002
zones_size[znum] = zholes_size[znum] = 0;
2003
2004
npages = max_low_pfn - pfn_base;
2005
2006
zones_size[ZONE_DMA] = npages;
2007
zholes_size[ZONE_DMA] = npages - pages_avail;
2008
2009
npages = highend_pfn - max_low_pfn;
2010
zones_size[ZONE_HIGHMEM] = npages;
2011
zholes_size[ZONE_HIGHMEM] = npages - calc_highpages();
2012
2013
free_area_init_node(0, zones_size, pfn_base, zholes_size);
2014
}
2015
2016
cnt = 0;
2017
for (i = 0; i < num_segmaps; i++)
2018
if (mmu_entry_pool[i].locked)
2019
cnt++;
2020
2021
max_user_taken_entries = num_segmaps - cnt - 40 - 1;
2022
2023
printk("SUN4C: %d mmu entries for the kernel\n", cnt);
2024
}
2025
2026
static pgprot_t sun4c_pgprot_noncached(pgprot_t prot)
2027
{
2028
prot |= __pgprot(_SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE);
2029
2030
return prot;
2031
}
2032
2033
/* Load up routines and constants for sun4c mmu */
2034
void __init ld_mmu_sun4c(void)
2035
{
2036
extern void ___xchg32_sun4c(void);
2037
2038
printk("Loading sun4c MMU routines\n");
2039
2040
/* First the constants */
2041
BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT);
2042
BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE);
2043
BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK);
2044
2045
BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD);
2046
BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD);
2047
BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);
2048
2049
BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE));
2050
PAGE_SHARED = pgprot_val(SUN4C_PAGE_SHARED);
2051
BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY));
2052
BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY));
2053
BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL));
2054
page_kernel = pgprot_val(SUN4C_PAGE_KERNEL);
2055
2056
/* Functions */
2057
BTFIXUPSET_CALL(pgprot_noncached, sun4c_pgprot_noncached, BTFIXUPCALL_NORM);
2058
BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4c, BTFIXUPCALL_NORM);
2059
BTFIXUPSET_CALL(do_check_pgt_cache, sun4c_check_pgt_cache, BTFIXUPCALL_NORM);
2060
2061
BTFIXUPSET_CALL(flush_cache_all, sun4c_flush_cache_all, BTFIXUPCALL_NORM);
2062
2063
if (sun4c_vacinfo.do_hwflushes) {
2064
BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_hw, BTFIXUPCALL_NORM);
2065
BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_hw, BTFIXUPCALL_NORM);
2066
BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_hw, BTFIXUPCALL_NORM);
2067
} else {
2068
BTFIXUPSET_CALL(sun4c_flush_page, sun4c_flush_page_sw, BTFIXUPCALL_NORM);
2069
BTFIXUPSET_CALL(sun4c_flush_segment, sun4c_flush_segment_sw, BTFIXUPCALL_NORM);
2070
BTFIXUPSET_CALL(sun4c_flush_context, sun4c_flush_context_sw, BTFIXUPCALL_NORM);
2071
}
2072
2073
BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm, BTFIXUPCALL_NORM);
2074
BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm, BTFIXUPCALL_NORM);
2075
BTFIXUPSET_CALL(destroy_context, sun4c_destroy_context, BTFIXUPCALL_NORM);
2076
BTFIXUPSET_CALL(switch_mm, sun4c_switch_mm, BTFIXUPCALL_NORM);
2077
BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page, BTFIXUPCALL_NORM);
2078
BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM);
2079
BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM);
2080
BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM);
2081
BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM);
2082
BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM);
2083
2084
BTFIXUPSET_CALL(flush_sig_insns, sun4c_flush_sig_insns, BTFIXUPCALL_NOP);
2085
2086
BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
2087
2088
BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM);
2089
#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
2090
BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
2091
#else
2092
BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM);
2093
#endif
2094
BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM);
2095
BTFIXUPSET_CALL(pmd_populate, sun4c_pmd_populate, BTFIXUPCALL_NORM);
2096
2097
BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM);
2098
BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0);
2099
2100
BTFIXUPSET_CALL(pmd_bad, sun4c_pmd_bad, BTFIXUPCALL_NORM);
2101
BTFIXUPSET_CALL(pmd_present, sun4c_pmd_present, BTFIXUPCALL_NORM);
2102
BTFIXUPSET_CALL(pmd_clear, sun4c_pmd_clear, BTFIXUPCALL_STG0O0);
2103
2104
BTFIXUPSET_CALL(pgd_none, sun4c_pgd_none, BTFIXUPCALL_RETINT(0));
2105
BTFIXUPSET_CALL(pgd_bad, sun4c_pgd_bad, BTFIXUPCALL_RETINT(0));
2106
BTFIXUPSET_CALL(pgd_present, sun4c_pgd_present, BTFIXUPCALL_RETINT(1));
2107
BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP);
2108
2109
BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM);
2110
BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM);
2111
BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM);
2112
2113
BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK);
2114
BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM);
2115
BTFIXUPSET_CALL(pte_offset_kernel, sun4c_pte_offset_kernel, BTFIXUPCALL_NORM);
2116
BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM);
2117
BTFIXUPSET_CALL(pte_free, sun4c_pte_free, BTFIXUPCALL_NORM);
2118
BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM);
2119
BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM);
2120
BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP);
2121
BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0);
2122
BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);
2123
BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM);
2124
2125
BTFIXUPSET_HALF(pte_writei, _SUN4C_PAGE_WRITE);
2126
BTFIXUPSET_HALF(pte_dirtyi, _SUN4C_PAGE_MODIFIED);
2127
BTFIXUPSET_HALF(pte_youngi, _SUN4C_PAGE_ACCESSED);
2128
BTFIXUPSET_HALF(pte_filei, _SUN4C_PAGE_FILE);
2129
BTFIXUPSET_HALF(pte_wrprotecti, _SUN4C_PAGE_WRITE|_SUN4C_PAGE_SILENT_WRITE);
2130
BTFIXUPSET_HALF(pte_mkcleani, _SUN4C_PAGE_MODIFIED|_SUN4C_PAGE_SILENT_WRITE);
2131
BTFIXUPSET_HALF(pte_mkoldi, _SUN4C_PAGE_ACCESSED|_SUN4C_PAGE_SILENT_READ);
2132
BTFIXUPSET_CALL(pte_mkwrite, sun4c_pte_mkwrite, BTFIXUPCALL_NORM);
2133
BTFIXUPSET_CALL(pte_mkdirty, sun4c_pte_mkdirty, BTFIXUPCALL_NORM);
2134
BTFIXUPSET_CALL(pte_mkyoung, sun4c_pte_mkyoung, BTFIXUPCALL_NORM);
2135
BTFIXUPSET_CALL(update_mmu_cache, sun4c_update_mmu_cache, BTFIXUPCALL_NORM);
2136
2137
BTFIXUPSET_CALL(pte_to_pgoff, sun4c_pte_to_pgoff, BTFIXUPCALL_NORM);
2138
BTFIXUPSET_CALL(pgoff_to_pte, sun4c_pgoff_to_pte, BTFIXUPCALL_NORM);
2139
2140
BTFIXUPSET_CALL(mmu_lockarea, sun4c_lockarea, BTFIXUPCALL_NORM);
2141
BTFIXUPSET_CALL(mmu_unlockarea, sun4c_unlockarea, BTFIXUPCALL_NORM);
2142
2143
BTFIXUPSET_CALL(mmu_get_scsi_one, sun4c_get_scsi_one, BTFIXUPCALL_NORM);
2144
BTFIXUPSET_CALL(mmu_get_scsi_sgl, sun4c_get_scsi_sgl, BTFIXUPCALL_NORM);
2145
BTFIXUPSET_CALL(mmu_release_scsi_one, sun4c_release_scsi_one, BTFIXUPCALL_NORM);
2146
BTFIXUPSET_CALL(mmu_release_scsi_sgl, sun4c_release_scsi_sgl, BTFIXUPCALL_NORM);
2147
2148
BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);
2149
BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);
2150
2151
BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM);
2152
BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM);
2153
2154
BTFIXUPSET_CALL(__swp_type, sun4c_swp_type, BTFIXUPCALL_NORM);
2155
BTFIXUPSET_CALL(__swp_offset, sun4c_swp_offset, BTFIXUPCALL_NORM);
2156
BTFIXUPSET_CALL(__swp_entry, sun4c_swp_entry, BTFIXUPCALL_NORM);
2157
2158
BTFIXUPSET_CALL(alloc_thread_info_node, sun4c_alloc_thread_info_node, BTFIXUPCALL_NORM);
2159
BTFIXUPSET_CALL(free_thread_info, sun4c_free_thread_info, BTFIXUPCALL_NORM);
2160
2161
BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);
2162
2163
/* These should _never_ get called with two level tables. */
2164
BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);
2165
BTFIXUPSET_CALL(pgd_page_vaddr, sun4c_pgd_page, BTFIXUPCALL_RETO0);
2166
}
2167
2168