|
@@ -3,7 +3,7 @@
|
|
*
|
|
*
|
|
* Blackfin BF533/2.6 support : LG Soft India
|
|
* Blackfin BF533/2.6 support : LG Soft India
|
|
* Modification: Dec 07 2004
|
|
* Modification: Dec 07 2004
|
|
- * 1. Correction in icheck_lock. Valid lock entries were
|
|
|
|
|
|
+ * 1. Correction in icheck_lock. Valid lock entries were
|
|
* geting victimized, for instruction cplb replacement.
|
|
* geting victimized, for instruction cplb replacement.
|
|
* 2. Setup loop's are modified as now toolchain support's P Indexed
|
|
* 2. Setup loop's are modified as now toolchain support's P Indexed
|
|
* addressing
|
|
* addressing
|
|
@@ -18,15 +18,15 @@
|
|
*
|
|
*
|
|
* Returns:
|
|
* Returns:
|
|
* CPLB_RELOADED => Successfully updated CPLB table.
|
|
* CPLB_RELOADED => Successfully updated CPLB table.
|
|
- * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates
|
|
|
|
- * that the CPLBs in the configuration tablei are badly
|
|
|
|
|
|
+ * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted.This indicates
|
|
|
|
+ * that the CPLBs in the configuration tablei are badly
|
|
* configured, as this should never occur.
|
|
* configured, as this should never occur.
|
|
- * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception,
|
|
|
|
- * is not covered by any of the CPLBs in the configuration
|
|
|
|
|
|
+ * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the exception,
|
|
|
|
+ * is not covered by any of the CPLBs in the configuration
|
|
* table. The application isi presumably misbehaving.
|
|
* table. The application isi presumably misbehaving.
|
|
- * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception,
|
|
|
|
- * was not a first-write to a clean Write Back Data page,
|
|
|
|
- * and so presumably is a genuine violation of the page's
|
|
|
|
|
|
+ * CPLB_PROT_VIOL => The address being accessed, that triggered thei exception,
|
|
|
|
+ * was not a first-write to a clean Write Back Data page,
|
|
|
|
+ * and so presumably is a genuine violation of the page's
|
|
* protection attributes. The application is misbehaving.
|
|
* protection attributes. The application is misbehaving.
|
|
*/
|
|
*/
|
|
#define ASSEMBLY
|
|
#define ASSEMBLY
|
|
@@ -35,9 +35,9 @@
|
|
#include <asm-blackfin/blackfin.h>
|
|
#include <asm-blackfin/blackfin.h>
|
|
#include <asm-blackfin/cplbtab.h>
|
|
#include <asm-blackfin/cplbtab.h>
|
|
#include <asm-blackfin/cplb.h>
|
|
#include <asm-blackfin/cplb.h>
|
|
-
|
|
|
|
|
|
+
|
|
.text
|
|
.text
|
|
-
|
|
|
|
|
|
+
|
|
.align 2;
|
|
.align 2;
|
|
ENTRY(_cplb_mgr)
|
|
ENTRY(_cplb_mgr)
|
|
|
|
|
|
@@ -51,8 +51,8 @@ ENTRY(_cplb_mgr)
|
|
|
|
|
|
/* ICPLB Miss Exception. We need to choose one of the
|
|
/* ICPLB Miss Exception. We need to choose one of the
|
|
* currently-installed CPLBs, and replace it with one
|
|
* currently-installed CPLBs, and replace it with one
|
|
- * from the configuration table.
|
|
|
|
- */
|
|
|
|
|
|
+ * from the configuration table.
|
|
|
|
+ */
|
|
|
|
|
|
P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
|
|
P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
|
|
P4.H = (ICPLB_FAULT_ADDR >> 16);
|
|
P4.H = (ICPLB_FAULT_ADDR >> 16);
|
|
@@ -72,7 +72,7 @@ ENTRY(_cplb_mgr)
|
|
isearch:
|
|
isearch:
|
|
|
|
|
|
R1 = [P0-0x100]; /* Address for this CPLB */
|
|
R1 = [P0-0x100]; /* Address for this CPLB */
|
|
-
|
|
|
|
|
|
+
|
|
R0 = [P0++]; /* Info for this CPLB*/
|
|
R0 = [P0++]; /* Info for this CPLB*/
|
|
CC = BITTST(R0,0); /* Is the CPLB valid?*/
|
|
CC = BITTST(R0,0); /* Is the CPLB valid?*/
|
|
IF !CC JUMP nomatch; /* Skip it, if not.*/
|
|
IF !CC JUMP nomatch; /* Skip it, if not.*/
|
|
@@ -94,7 +94,7 @@ nomatch:
|
|
|
|
|
|
isearch_done:
|
|
isearch_done:
|
|
I0 = R4; /* Fault address we'll search for*/
|
|
I0 = R4; /* Fault address we'll search for*/
|
|
-
|
|
|
|
|
|
+
|
|
/* set up pointers */
|
|
/* set up pointers */
|
|
P0.L = (ICPLB_DATA0 & 0xFFFF);
|
|
P0.L = (ICPLB_DATA0 & 0xFFFF);
|
|
P0.H = (ICPLB_DATA0 >> 16);
|
|
P0.H = (ICPLB_DATA0 >> 16);
|
|
@@ -138,7 +138,7 @@ ifound_victim:
|
|
P3.H = ipdt_swapcount_table;
|
|
P3.H = ipdt_swapcount_table;
|
|
P3 += -4;
|
|
P3 += -4;
|
|
icount:
|
|
icount:
|
|
- R2 = [P2]; /* address from config table */
|
|
|
|
|
|
+ R2 = [P2]; /* address from config table */
|
|
P2 += 8;
|
|
P2 += 8;
|
|
P3 += 8;
|
|
P3 += 8;
|
|
CC = R2==-1;
|
|
CC = R2==-1;
|
|
@@ -153,13 +153,13 @@ icount_done:
|
|
#endif
|
|
#endif
|
|
LC0=R3;
|
|
LC0=R3;
|
|
LSETUP(is_move,ie_move) LC0;
|
|
LSETUP(is_move,ie_move) LC0;
|
|
-is_move:
|
|
|
|
|
|
+is_move:
|
|
R0 = [P0];
|
|
R0 = [P0];
|
|
[P0 - 4] = R0;
|
|
[P0 - 4] = R0;
|
|
R0 = [P0 - 0x100];
|
|
R0 = [P0 - 0x100];
|
|
- [P0-0x104] = R0;
|
|
|
|
|
|
+ [P0-0x104] = R0;
|
|
ie_move:P0+=4;
|
|
ie_move:P0+=4;
|
|
-
|
|
|
|
|
|
+
|
|
/* We've made space in the ICPLB table, so that ICPLB15
|
|
/* We've made space in the ICPLB table, so that ICPLB15
|
|
* is now free to be overwritten. Next, we have to determine
|
|
* is now free to be overwritten. Next, we have to determine
|
|
* which CPLB we need to install, from the configuration
|
|
* which CPLB we need to install, from the configuration
|
|
@@ -167,8 +167,8 @@ ie_move:P0+=4;
|
|
* addresses and page-lengths from the config table, and
|
|
* addresses and page-lengths from the config table, and
|
|
* determining whether the fault address falls within that
|
|
* determining whether the fault address falls within that
|
|
* range.
|
|
* range.
|
|
- */
|
|
|
|
-
|
|
|
|
|
|
+ */
|
|
|
|
+
|
|
P2.L = ipdt_table;
|
|
P2.L = ipdt_table;
|
|
P2.H = ipdt_table;
|
|
P2.H = ipdt_table;
|
|
#ifdef CONFIG_CPLB_INFO
|
|
#ifdef CONFIG_CPLB_INFO
|
|
@@ -190,7 +190,7 @@ ie_move:P0+=4;
|
|
*/
|
|
*/
|
|
|
|
|
|
R1 = ((16<<8)|2);
|
|
R1 = ((16<<8)|2);
|
|
-inext: R4 = [P2++]; /* address from config table */
|
|
|
|
|
|
+inext: R4 = [P2++]; /* address from config table */
|
|
R2 = [P2++]; /* data from config table */
|
|
R2 = [P2++]; /* data from config table */
|
|
#ifdef CONFIG_CPLB_INFO
|
|
#ifdef CONFIG_CPLB_INFO
|
|
P3 += 8;
|
|
P3 += 8;
|
|
@@ -201,7 +201,7 @@ inext: R4 = [P2++]; /* address from config table */
|
|
|
|
|
|
/* See if failed address > start address */
|
|
/* See if failed address > start address */
|
|
CC = R4 <= R0(IU);
|
|
CC = R4 <= R0(IU);
|
|
- IF !CC JUMP inext;
|
|
|
|
|
|
+ IF !CC JUMP inext;
|
|
|
|
|
|
/* extract page size (17:16)*/
|
|
/* extract page size (17:16)*/
|
|
R3 = EXTRACT(R2, R1.L) (Z);
|
|
R3 = EXTRACT(R2, R1.L) (Z);
|
|
@@ -250,17 +250,17 @@ inext: R4 = [P2++]; /* address from config table */
|
|
|
|
|
|
/* FAILED CASES*/
|
|
/* FAILED CASES*/
|
|
no_page_in_table:
|
|
no_page_in_table:
|
|
- ( R7:0,P5:0 ) = [SP++];
|
|
|
|
- R0 = CPLB_NO_ADDR_MATCH;
|
|
|
|
- RTS;
|
|
|
|
|
|
+ ( R7:0,P5:0 ) = [SP++];
|
|
|
|
+ R0 = CPLB_NO_ADDR_MATCH;
|
|
|
|
+ RTS;
|
|
all_locked:
|
|
all_locked:
|
|
- ( R7:0,P5:0 ) = [SP++];
|
|
|
|
- R0 = CPLB_NO_UNLOCKED;
|
|
|
|
- RTS;
|
|
|
|
|
|
+ ( R7:0,P5:0 ) = [SP++];
|
|
|
|
+ R0 = CPLB_NO_UNLOCKED;
|
|
|
|
+ RTS;
|
|
prot_violation:
|
|
prot_violation:
|
|
- ( R7:0,P5:0 ) = [SP++];
|
|
|
|
- R0 = CPLB_PROT_VIOL;
|
|
|
|
- RTS;
|
|
|
|
|
|
+ ( R7:0,P5:0 ) = [SP++];
|
|
|
|
+ R0 = CPLB_PROT_VIOL;
|
|
|
|
+ RTS;
|
|
|
|
|
|
dcplb_write:
|
|
dcplb_write:
|
|
|
|
|
|
@@ -275,7 +275,7 @@ dcplb_write:
|
|
P4.H = (DCPLB_STATUS >> 16);
|
|
P4.H = (DCPLB_STATUS >> 16);
|
|
P3.L = (DCPLB_DATA0 & 0xFFFF);
|
|
P3.L = (DCPLB_DATA0 & 0xFFFF);
|
|
P3.H = (DCPLB_DATA0 >> 16);
|
|
P3.H = (DCPLB_DATA0 >> 16);
|
|
- R5 = [P4];
|
|
|
|
|
|
+ R5 = [P4];
|
|
|
|
|
|
/* A protection violation can be caused by more than just writes
|
|
/* A protection violation can be caused by more than just writes
|
|
* to a clean WB page, so we have to ensure that:
|
|
* to a clean WB page, so we have to ensure that:
|
|
@@ -315,7 +315,7 @@ dcplb_write:
|
|
R2 <<= R5; /* if was super, check write in super mode*/
|
|
R2 <<= R5; /* if was super, check write in super mode*/
|
|
R2 = R3 & R2;
|
|
R2 = R3 & R2;
|
|
CC = R2 == 0;
|
|
CC = R2 == 0;
|
|
- IF CC JUMP prot_violation;
|
|
|
|
|
|
+ IF CC JUMP prot_violation;
|
|
|
|
|
|
/* It's a genuine write-to-clean-page.*/
|
|
/* It's a genuine write-to-clean-page.*/
|
|
|
|
|
|
@@ -333,7 +333,7 @@ dcplb_miss_compare:
|
|
* config table, that covers the faulting address.
|
|
* config table, that covers the faulting address.
|
|
*/
|
|
*/
|
|
|
|
|
|
- P1.L = (DCPLB_DATA15 & 0xFFFF);
|
|
|
|
|
|
+ P1.L = (DCPLB_DATA15 & 0xFFFF);
|
|
P1.H = (DCPLB_DATA15 >> 16);
|
|
P1.H = (DCPLB_DATA15 >> 16);
|
|
|
|
|
|
P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
|
|
P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
|
|
@@ -379,7 +379,7 @@ sdsearch2:
|
|
CC = R2 == 0; /* If none are set, it'll do.*/
|
|
CC = R2 == 0; /* If none are set, it'll do.*/
|
|
IF !CC JUMP skip_stack_check;
|
|
IF !CC JUMP skip_stack_check;
|
|
|
|
|
|
- R2 = [P0 - 0x104]; /* R2 - PageStart */
|
|
|
|
|
|
+ R2 = [P0 - 0x104]; /* R2 - PageStart */
|
|
P3.L = page_size_table; /* retrive end address */
|
|
P3.L = page_size_table; /* retrive end address */
|
|
P3.H = page_size_table; /* retrive end address */
|
|
P3.H = page_size_table; /* retrive end address */
|
|
R3 = 0x2; /* 0th - position, 2 bits -length */
|
|
R3 = 0x2; /* 0th - position, 2 bits -length */
|
|
@@ -392,13 +392,13 @@ sdsearch2:
|
|
|
|
|
|
R7 = R7 << 0xA; /* in bytes * 1024*/
|
|
R7 = R7 << 0xA; /* in bytes * 1024*/
|
|
R7 = R2 + R7; /* R7 - PageEnd */
|
|
R7 = R2 + R7; /* R7 - PageEnd */
|
|
- R4 = SP; /* Test SP is in range */
|
|
|
|
|
|
+ R4 = SP; /* Test SP is in range */
|
|
|
|
|
|
CC = R7 < R4; /* if PageEnd < SP */
|
|
CC = R7 < R4; /* if PageEnd < SP */
|
|
IF CC JUMP dfound_victim;
|
|
IF CC JUMP dfound_victim;
|
|
R3 = 0x284; /* stack length from start of trap till the point */
|
|
R3 = 0x284; /* stack length from start of trap till the point */
|
|
/* 20 stack locations for future modifications */
|
|
/* 20 stack locations for future modifications */
|
|
- R4 = R4 + R3;
|
|
|
|
|
|
+ R4 = R4 + R3;
|
|
CC = R4 < R2; /* if SP + stacklen < PageStart */
|
|
CC = R4 < R2; /* if SP + stacklen < PageStart */
|
|
IF CC JUMP dfound_victim;
|
|
IF CC JUMP dfound_victim;
|
|
skip_stack_check:
|
|
skip_stack_check:
|
|
@@ -409,7 +409,7 @@ edsearch1: NOP;
|
|
/* If we got here, we didn't find a DCPLB we considered
|
|
/* If we got here, we didn't find a DCPLB we considered
|
|
* replacable, which means all of them were locked.
|
|
* replacable, which means all of them were locked.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
|
|
+
|
|
JUMP all_locked;
|
|
JUMP all_locked;
|
|
dfound_victim:
|
|
dfound_victim:
|
|
|
|
|
|
@@ -450,14 +450,14 @@ dicount_done:
|
|
CC = BITTST(R1, 7); /* Is it dirty?*/
|
|
CC = BITTST(R1, 7); /* Is it dirty?*/
|
|
IF !CC JUMP Ddoverwrite (BP); /* Nope.*/
|
|
IF !CC JUMP Ddoverwrite (BP); /* Nope.*/
|
|
CC = BITTST(R1, 14); /* Is it Write-Through?*/
|
|
CC = BITTST(R1, 14); /* Is it Write-Through?*/
|
|
- IF CC JUMP Ddoverwrite; /* Yep*/
|
|
|
|
|
|
+ IF CC JUMP Ddoverwrite; /* Yep*/
|
|
|
|
|
|
/* This is a dirty page, so we need to flush all writes
|
|
/* This is a dirty page, so we need to flush all writes
|
|
* that are pending on the page.
|
|
* that are pending on the page.
|
|
*/
|
|
*/
|
|
|
|
|
|
/* Retrieve the page start address*/
|
|
/* Retrieve the page start address*/
|
|
- R0 = [P0 - 0x104];
|
|
|
|
|
|
+ R0 = [P0 - 0x104];
|
|
[--sp] = rets;
|
|
[--sp] = rets;
|
|
CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/
|
|
CALL dcplb_flush; /* R0==CPLB addr, R1==CPLB data*/
|
|
rets = [sp++];
|
|
rets = [sp++];
|
|
@@ -467,7 +467,7 @@ Ddoverwrite:
|
|
* overwrite it by moving all the following CPLBs
|
|
* overwrite it by moving all the following CPLBs
|
|
* one space closer to the start.
|
|
* one space closer to the start.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
|
|
+
|
|
R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/
|
|
R1.L = ((DCPLB_DATA15+4) & 0xFFFF); /*DCPLB_DATA15+4*/
|
|
R1.H = ((DCPLB_DATA15+4) >> 16);
|
|
R1.H = ((DCPLB_DATA15+4) >> 16);
|
|
R0 = P0;
|
|
R0 = P0;
|
|
@@ -485,7 +485,7 @@ Ddoverwrite:
|
|
ds_move:
|
|
ds_move:
|
|
R0 = [P0++]; /* move data */
|
|
R0 = [P0++]; /* move data */
|
|
[P0 - 8] = R0;
|
|
[P0 - 8] = R0;
|
|
- R0 = [P0-0x104] /* move address */
|
|
|
|
|
|
+ R0 = [P0-0x104] /* move address */
|
|
de_move: [P0-0x108] = R0;
|
|
de_move: [P0-0x108] = R0;
|
|
|
|
|
|
/* We've now made space in DCPLB15 for the new CPLB to be
|
|
/* We've now made space in DCPLB15 for the new CPLB to be
|
|
@@ -510,7 +510,7 @@ de_moved:NOP;
|
|
/* An extraction pattern, to retrieve bits 17:16.*/
|
|
/* An extraction pattern, to retrieve bits 17:16.*/
|
|
|
|
|
|
R1 = (16<<8)|2;
|
|
R1 = (16<<8)|2;
|
|
-dnext: R4 = [P2++]; /* address */
|
|
|
|
|
|
+dnext: R4 = [P2++]; /* address */
|
|
R2 = [P2++]; /* data */
|
|
R2 = [P2++]; /* data */
|
|
#ifdef CONFIG_CPLB_INFO
|
|
#ifdef CONFIG_CPLB_INFO
|
|
P3 += 8;
|
|
P3 += 8;
|
|
@@ -521,7 +521,7 @@ dnext: R4 = [P2++]; /* address */
|
|
|
|
|
|
/* See if failed address > start address */
|
|
/* See if failed address > start address */
|
|
CC = R4 <= R0(IU);
|
|
CC = R4 <= R0(IU);
|
|
- IF !CC JUMP dnext;
|
|
|
|
|
|
+ IF !CC JUMP dnext;
|
|
|
|
|
|
/* extract page size (17:16)*/
|
|
/* extract page size (17:16)*/
|
|
R3 = EXTRACT(R2, R1.L) (Z);
|
|
R3 = EXTRACT(R2, R1.L) (Z);
|