blob: 7a0b048629f1740a58add1689fdb4fb9427f15b4 [file] [log] [blame]
Wolfgang Denk6cb142f2006-03-12 02:12:27 +01001/*This file is subject to the terms and conditions of the GNU General Public
2 * License.
3 *
4 * Blackfin BF533/2.6 support : LG Soft India
5 * Modification: Dec 07 2004
Wolfgang Denk8e7b7032006-03-12 02:55:22 +01006 * 1. Correction in icheck_lock. Valid lock entries were
Wolfgang Denk6cb142f2006-03-12 02:12:27 +01007 * geting victimized, for instruction cplb replacement.
8 * 2. Setup loop's are modified as now toolchain support's P Indexed
9 * addressing
10 * :LG Soft India
11 *
12 */
13
14/* Usage: int _cplb_mgr(is_data_miss,int enable_cache)
15 * is_data_miss==2 => Mark as Dirty, write to the clean data page
16 * is_data_miss==1 => Replace a data CPLB.
17 * is_data_miss==0 => Replace an instruction CPLB.
18 *
19 * Returns:
20 * CPLB_RELOADED => Successfully updated CPLB table.
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010021 * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates
22 * that the CPLBs in the configuration tablei are badly
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010023 * configured, as this should never occur.
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010024 * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception,
25 * is not covered by any of the CPLBs in the configuration
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010026 * table. The application isi presumably misbehaving.
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010027 * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception,
28 * was not a first-write to a clean Write Back Data page,
29 * and so presumably is a genuine violation of the page's
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010030 * protection attributes. The application is misbehaving.
31 */
32#define ASSEMBLY
33
34#include <asm-blackfin/linkage.h>
35#include <asm-blackfin/blackfin.h>
36#include <asm-blackfin/cplbtab.h>
37#include <asm-blackfin/cplb.h>
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010038
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010039.text
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010040
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010041.align 2;
42ENTRY(_cplb_mgr)
43
44 [--SP]=( R7:0,P5:0 );
45
46 CC = R0 == 2;
47 IF CC JUMP dcplb_write;
48
49 CC = R0 == 0;
50 IF !CC JUMP dcplb_miss_compare;
51
52 /* ICPLB Miss Exception. We need to choose one of the
53 * currently-installed CPLBs, and replace it with one
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010054 * from the configuration table.
55 */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010056
57 P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
58 P4.H = (ICPLB_FAULT_ADDR >> 16);
59
60 P1 = 16;
61 P5.L = page_size_table;
62 P5.H = page_size_table;
63
64 P0.L = (ICPLB_DATA0 & 0xFFFF);
65 P0.H = (ICPLB_DATA0 >> 16);
66 R4 = [P4]; /* Get faulting address*/
67 R6 = 64; /* Advance past the fault address, which*/
68 R6 = R6 + R4; /* we'll use if we find a match*/
69 R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/
70
71 R5 = 0;
72isearch:
73
74 R1 = [P0-0x100]; /* Address for this CPLB */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010075
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010076 R0 = [P0++]; /* Info for this CPLB*/
77 CC = BITTST(R0,0); /* Is the CPLB valid?*/
78 IF !CC JUMP nomatch; /* Skip it, if not.*/
79 CC = R4 < R1(IU); /* If fault address less than page start*/
80 IF CC JUMP nomatch; /* then skip this one.*/
81 R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/
82 P1 = R2;
83 P1 = P5 + (P1<<2); /* index into page-size table*/
84 R2 = [P1]; /* Get the page size*/
85 R1 = R1 + R2; /* and add to page start, to get page end*/
86 CC = R4 < R1(IU); /* and see whether fault addr is in page.*/
87 IF !CC R4 = R6; /* If so, advance the address and finish loop.*/
88 IF !CC JUMP isearch_done;
89nomatch:
90 /* Go around again*/
91 R5 += 1;
92 CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/
93 IF !CC JUMP isearch;
94
95isearch_done:
96 I0 = R4; /* Fault address we'll search for*/
Wolfgang Denk8e7b7032006-03-12 02:55:22 +010097
Wolfgang Denk6cb142f2006-03-12 02:12:27 +010098 /* set up pointers */
99 P0.L = (ICPLB_DATA0 & 0xFFFF);
100 P0.H = (ICPLB_DATA0 >> 16);
101
102 /* The replacement procedure for ICPLBs */
103
104 P4.L = (IMEM_CONTROL & 0xFFFF);
105 P4.H = (IMEM_CONTROL >> 16);
106
107 /* disable cplbs */
108 R5 = [P4]; /* Control Register*/
109 BITCLR(R5,ENICPLB_P);
110 CLI R1;
111 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
112 .align 8;
113 [P4] = R5;
114 SSYNC;
115 STI R1;
116
117 R1 = -1; /* end point comparison */
118 R3 = 16; /* counter */
119
120 /* Search through CPLBs for first non-locked entry */
121 /* Overwrite it by moving everyone else up by 1 */
122icheck_lock:
123 R0 = [P0++];
124 R3 = R3 + R1;
125 CC = R3 == R1;
126 IF CC JUMP all_locked;
127 CC = BITTST(R0, 0); /* an invalid entry is good */
128 IF !CC JUMP ifound_victim;
129 CC = BITTST(R0,1); /* but a locked entry isn't */
130 IF CC JUMP icheck_lock;
131
132ifound_victim:
133#ifdef CONFIG_CPLB_INFO
134 R7 = [P0 - 0x104];
135 P2.L = ipdt_table;
136 P2.H = ipdt_table;
137 P3.L = ipdt_swapcount_table;
138 P3.H = ipdt_swapcount_table;
139 P3 += -4;
140icount:
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100141 R2 = [P2]; /* address from config table */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100142 P2 += 8;
143 P3 += 8;
144 CC = R2==-1;
145 IF CC JUMP icount_done;
146 CC = R7==R2;
147 IF !CC JUMP icount;
148 R7 = [P3];
149 R7 += 1;
150 [P3] = R7;
151 CSYNC;
152icount_done:
153#endif
154 LC0=R3;
155 LSETUP(is_move,ie_move) LC0;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100156is_move:
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100157 R0 = [P0];
158 [P0 - 4] = R0;
159 R0 = [P0 - 0x100];
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100160 [P0-0x104] = R0;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100161ie_move:P0+=4;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100162
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100163 /* We've made space in the ICPLB table, so that ICPLB15
164 * is now free to be overwritten. Next, we have to determine
165 * which CPLB we need to install, from the configuration
166 * table. This is a matter of getting the start-of-page
167 * addresses and page-lengths from the config table, and
168 * determining whether the fault address falls within that
169 * range.
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100170 */
171
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100172 P2.L = ipdt_table;
173 P2.H = ipdt_table;
174#ifdef CONFIG_CPLB_INFO
175 P3.L = ipdt_swapcount_table;
176 P3.H = ipdt_swapcount_table;
177 P3 += -8;
178#endif
179 P0.L = page_size_table;
180 P0.H = page_size_table;
181
182 /* Retrieve our fault address (which may have been advanced
183 * because the faulting instruction crossed a page boundary).
184 */
185
186 R0 = I0;
187
188 /* An extraction pattern, to get the page-size bits from
189 * the CPLB data entry. Bits 16-17, so two bits at posn 16.
190 */
191
192 R1 = ((16<<8)|2);
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100193inext: R4 = [P2++]; /* address from config table */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100194 R2 = [P2++]; /* data from config table */
195#ifdef CONFIG_CPLB_INFO
196 P3 += 8;
197#endif
198
199 CC = R4 == -1; /* End of config table*/
200 IF CC JUMP no_page_in_table;
201
202 /* See if failed address > start address */
203 CC = R4 <= R0(IU);
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100204 IF !CC JUMP inext;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100205
206 /* extract page size (17:16)*/
207 R3 = EXTRACT(R2, R1.L) (Z);
208
209 /* add page size to addr to get range */
210
211 P5 = R3;
212 P5 = P0 + (P5 << 2); /* scaled, for int access*/
213 R3 = [P5];
214 R3 = R3 + R4;
215
216 /* See if failed address < (start address + page size) */
217 CC = R0 < R3(IU);
218 IF !CC JUMP inext;
219
220 /* We've found a CPLB in the config table that covers
221 * the faulting address, so install this CPLB into the
222 * last entry of the table.
223 */
224
225 P1.L = (ICPLB_DATA15 & 0xFFFF); /*ICPLB_DATA15*/
226 P1.H = (ICPLB_DATA15 >> 16);
227 [P1] = R2;
228 [P1-0x100] = R4;
229#ifdef CONFIG_CPLB_INFO
230 R3 = [P3];
231 R3 += 1;
232 [P3] = R3;
233#endif
234
235 /* P4 points to IMEM_CONTROL, and R5 contains its old
236 * value, after we disabled ICPLBS. Re-enable them.
237 */
238
239 BITSET(R5,ENICPLB_P);
240 CLI R2;
241 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
242 .align 8;
243 [P4] = R5;
244 SSYNC;
245 STI R2;
246
247 ( R7:0,P5:0 ) = [SP++];
248 R0 = CPLB_RELOADED;
249 RTS;
250
251/* FAILED CASES*/
252no_page_in_table:
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100253 ( R7:0,P5:0 ) = [SP++];
254 R0 = CPLB_NO_ADDR_MATCH;
255 RTS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100256all_locked:
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100257 ( R7:0,P5:0 ) = [SP++];
258 R0 = CPLB_NO_UNLOCKED;
259 RTS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100260prot_violation:
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100261 ( R7:0,P5:0 ) = [SP++];
262 R0 = CPLB_PROT_VIOL;
263 RTS;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100264
265dcplb_write:
266
267 /* if a DCPLB is marked as write-back (CPLB_WT==0), and
268 * it is clean (CPLB_DIRTY==0), then a write to the
269 * CPLB's page triggers a protection violation. We have to
270 * mark the CPLB as dirty, to indicate that there are
271 * pending writes associated with the CPLB.
272 */
273
274 P4.L = (DCPLB_STATUS & 0xFFFF);
275 P4.H = (DCPLB_STATUS >> 16);
276 P3.L = (DCPLB_DATA0 & 0xFFFF);
277 P3.H = (DCPLB_DATA0 >> 16);
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100278 R5 = [P4];
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100279
280 /* A protection violation can be caused by more than just writes
281 * to a clean WB page, so we have to ensure that:
282 * - It's a write
283 * - to a clean WB page
284 * - and is allowed in the mode the access occurred.
285 */
286
287 CC = BITTST(R5, 16); /* ensure it was a write*/
288 IF !CC JUMP prot_violation;
289
290 /* to check the rest, we have to retrieve the DCPLB.*/
291
292 /* The low half of DCPLB_STATUS is a bit mask*/
293
294 R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/
295 R3 = 30; /* so we can use this to determine the offset*/
296 R2.L = SIGNBITS R2;
297 R2 = R2.L (Z); /* into the DCPLB table.*/
298 R3 = R3 - R2;
299 P4 = R3;
300 P3 = P3 + (P4<<2);
301 R3 = [P3]; /* Retrieve the CPLB*/
302
303 /* Now we can check whether it's a clean WB page*/
304
305 CC = BITTST(R3, 14); /* 0==WB, 1==WT*/
306 IF CC JUMP prot_violation;
307 CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/
308 IF CC JUMP prot_violation;
309
310 /* Check whether the write is allowed in the mode that was active.*/
311
312 R2 = 1<<3; /* checking write in user mode*/
313 CC = BITTST(R5, 17); /* 0==was user, 1==was super*/
314 R5 = CC;
315 R2 <<= R5; /* if was super, check write in super mode*/
316 R2 = R3 & R2;
317 CC = R2 == 0;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100318 IF CC JUMP prot_violation;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100319
320 /* It's a genuine write-to-clean-page.*/
321
322 BITSET(R3, 7); /* mark as dirty*/
323 [P3] = R3; /* and write back.*/
324 CSYNC;
325 ( R7:0,P5:0 ) = [SP++];
326 R0 = CPLB_RELOADED;
327 RTS;
328
329dcplb_miss_compare:
330
331 /* Data CPLB Miss event. We need to choose a CPLB to
332 * evict, and then locate a new CPLB to install from the
333 * config table, that covers the faulting address.
334 */
335
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100336 P1.L = (DCPLB_DATA15 & 0xFFFF);
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100337 P1.H = (DCPLB_DATA15 >> 16);
338
339 P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
340 P4.H = (DCPLB_FAULT_ADDR >> 16);
341 R4 = [P4];
342 I0 = R4;
343
344 /* The replacement procedure for DCPLBs*/
345
346 R6 = R1; /* Save for later*/
347
348 /* Turn off CPLBs while we work.*/
349 P4.L = (DMEM_CONTROL & 0xFFFF);
350 P4.H = (DMEM_CONTROL >> 16);
351 R5 = [P4];
352 BITCLR(R5,ENDCPLB_P);
353 CLI R0;
354 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */
355 .align 8;
356 [P4] = R5;
357 SSYNC;
358 STI R0;
359
360 /* Start looking for a CPLB to evict. Our order of preference
361 * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs
362 * are no good.
363 */
364
365 I1.L = (DCPLB_DATA0 & 0xFFFF);
366 I1.H = (DCPLB_DATA0 >> 16);
367 P1 = 3;
368 P2 = 16;
369 I2.L = dcplb_preference;
370 I2.H = dcplb_preference;
371 LSETUP(sdsearch1, edsearch1) LC0 = P1;
372sdsearch1:
373 R0 = [I2++]; /* Get the bits we're interested in*/
374 P0 = I1; /* Go back to start of table*/
375 LSETUP (sdsearch2, edsearch2) LC1 = P2;
376sdsearch2:
377 R1 = [P0++]; /* Fetch each installed CPLB in turn*/
378 R2 = R1 & R0; /* and test for interesting bits.*/
379 CC = R2 == 0; /* If none are set, it'll do.*/
380 IF !CC JUMP skip_stack_check;
381
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100382 R2 = [P0 - 0x104]; /* R2 - PageStart */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100383 P3.L = page_size_table; /* retrive end address */
384 P3.H = page_size_table; /* retrive end address */
385 R3 = 0x2; /* 0th - position, 2 bits -length */
386 nop; /*Anamoly 05000209*/
387 R7 = EXTRACT(R1,R3.l);
388 R7 = R7 << 2; /* Page size index offset */
389 P5 = R7;
390 P3 = P3 + P5;
391 R7 = [P3]; /* page size in 1K bytes */
392
393 R7 = R7 << 0xA; /* in bytes * 1024*/
394 R7 = R2 + R7; /* R7 - PageEnd */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100395 R4 = SP; /* Test SP is in range */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100396
397 CC = R7 < R4; /* if PageEnd < SP */
398 IF CC JUMP dfound_victim;
399 R3 = 0x284; /* stack length from start of trap till the point */
400 /* 20 stack locations for future modifications */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100401 R4 = R4 + R3;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100402 CC = R4 < R2; /* if SP + stacklen < PageStart */
403 IF CC JUMP dfound_victim;
404skip_stack_check:
405
406edsearch2: NOP;
407edsearch1: NOP;
408
409 /* If we got here, we didn't find a DCPLB we considered
410 * replacable, which means all of them were locked.
411 */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100412
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100413 JUMP all_locked;
414dfound_victim:
415
416#ifdef CONFIG_CPLB_INFO
417 R1 = [P0 - 0x104];
418 P2.L = dpdt_table;
419 P2.H = dpdt_table;
420 P3.L = dpdt_swapcount_table;
421 P3.H = dpdt_swapcount_table;
422 P3 += -4;
423dicount:
424 R2 = [P2];
425 P2 += 8;
426 P3 += 8;
427 CC = R2==-1;
428 IF CC JUMP dicount_done;
429 CC = R1==R2;
430 IF !CC JUMP dicount;
431 R1 = [P3];
432 R1 += 1;
433 [P3] = R1;
434 CSYNC;
435dicount_done:
436#endif
437
438 /* Clean down the hardware loops*/
439 R2 = 0;
440 LC1 = R2;
441 LC0 = R2;
442
443 /* There's a suitable victim in [P0-4] (because we've
444 * advanced already). If it's a valid dirty write-back
445 * CPLB, we need to flush the pending writes first.
446 */
447
448 CC = BITTST(R1, 0); /* Is it valid?*/
449 IF !CC JUMP Ddoverwrite;/* nope.*/
450 CC = BITTST(R1, 7); /* Is it dirty?*/
451 IF !CC JUMP Ddoverwrite (BP); /* Nope.*/
452 CC = BITTST(R1, 14); /* Is it Write-Through?*/
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100453 IF CC JUMP Ddoverwrite; /* Yep*/
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100454
455 /* This is a dirty page, so we need to flush all writes
456 * that are pending on the page.
457 */
458
459 /* Retrieve the page start address*/
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100460 R0 = [P0 - 0x104];
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100461 [--sp] = rets;
462 CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/
463 rets = [sp++];
464Ddoverwrite:
465
466 /* [P0-4] is a suitable victim CPLB, so we want to
467 * overwrite it by moving all the following CPLBs
468 * one space closer to the start.
469 */
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100470
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100471 R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/
472 R1.H = ((DCPLB_DATA15+4) >> 16);
473 R0 = P0;
474
475 /* If the victim happens to be in DCPLB15,
476 * we don't need to move anything.
477 */
478
479 CC = R1 == R0;
480 IF CC JUMP de_moved;
481 R1 = R1 - R0;
482 R1 >>= 2;
483 P1 = R1;
484 LSETUP(ds_move, de_move) LC0=P1;
485ds_move:
486 R0 = [P0++]; /* move data */
487 [P0 - 8] = R0;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100488 R0 = [P0-0x104] /* move address */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100489de_move: [P0-0x108] = R0;
490
491 /* We've now made space in DCPLB15 for the new CPLB to be
492 * installed. The next stage is to locate a CPLB in the
493 * config table that covers the faulting address.
494 */
495
496de_moved:NOP;
497 R0 = I0; /* Our faulting address */
498
499 P2.L = dpdt_table;
500 P2.H = dpdt_table;
501#ifdef CONFIG_CPLB_INFO
502 P3.L = dpdt_swapcount_table;
503 P3.H = dpdt_swapcount_table;
504 P3 += -8;
505#endif
506
507 P1.L = page_size_table;
508 P1.H = page_size_table;
509
510 /* An extraction pattern, to retrieve bits 17:16.*/
511
512 R1 = (16<<8)|2;
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100513dnext: R4 = [P2++]; /* address */
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100514 R2 = [P2++]; /* data */
515#ifdef CONFIG_CPLB_INFO
516 P3 += 8;
517#endif
518
519 CC = R4 == -1;
520 IF CC JUMP no_page_in_table;
521
522 /* See if failed address > start address */
523 CC = R4 <= R0(IU);
Wolfgang Denk8e7b7032006-03-12 02:55:22 +0100524 IF !CC JUMP dnext;
Wolfgang Denk6cb142f2006-03-12 02:12:27 +0100525
526 /* extract page size (17:16)*/
527 R3 = EXTRACT(R2, R1.L) (Z);
528
529 /* add page size to addr to get range */
530
531 P5 = R3;
532 P5 = P1 + (P5 << 2);
533 R3 = [P5];
534 R3 = R3 + R4;
535
536 /* See if failed address < (start address + page size) */
537 CC = R0 < R3(IU);
538 IF !CC JUMP dnext;
539
540 /* We've found the CPLB that should be installed, so
541 * write it into CPLB15, masking off any caching bits
542 * if necessary.
543 */
544
545 P1.L = (DCPLB_DATA15 & 0xFFFF);
546 P1.H = (DCPLB_DATA15 >> 16);
547
548 /* If the DCPLB has cache bits set, but caching hasn't
549 * been enabled, then we want to mask off the cache-in-L1
550 * bit before installing. Moreover, if caching is off, we
551 * also want to ensure that the DCPLB has WT mode set, rather
552 * than WB, since WB pages still trigger first-write exceptions
553 * even when not caching is off, and the page isn't marked as
554 * cachable. Finally, we could mark the page as clean, not dirty,
555 * but we choose to leave that decision to the user; if the user
556 * chooses to have a CPLB pre-defined as dirty, then they always
557 * pay the cost of flushing during eviction, but don't pay the
558 * cost of first-write exceptions to mark the page as dirty.
559 */
560
561#ifdef CONFIG_BLKFIN_WT
562 BITSET(R6, 14); /* Set WT*/
563#endif
564
565 [P1] = R2;
566 [P1-0x100] = R4;
567#ifdef CONFIG_CPLB_INFO
568 R3 = [P3];
569 R3 += 1;
570 [P3] = R3;
571#endif
572
573 /* We've installed the CPLB, so re-enable CPLBs. P4
574 * points to DMEM_CONTROL, and R5 is the value we
575 * last wrote to it, when we were disabling CPLBs.
576 */
577
578 BITSET(R5,ENDCPLB_P);
579 CLI R2;
580 .align 8;
581 [P4] = R5;
582 SSYNC;
583 STI R2;
584
585 ( R7:0,P5:0 ) = [SP++];
586 R0 = CPLB_RELOADED;
587 RTS;
588
589.data
590.align 4;
591page_size_table:
592.byte4 0x00000400; /* 1K */
593.byte4 0x00001000; /* 4K */
594.byte4 0x00100000; /* 1M */
595.byte4 0x00400000; /* 4M */
596
597.align 4;
598dcplb_preference:
599.byte4 0x00000001; /* valid bit */
600.byte4 0x00000082; /* dirty+lock bits */
601.byte4 0x00000002; /* lock bit */