diff options
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r-- | arch/parisc/kernel/entry.S | 217 |
1 files changed, 126 insertions, 91 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 6337adef30f6..e5477092a5d4 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -225,22 +225,13 @@ | |||
225 | #ifndef CONFIG_64BIT | 225 | #ifndef CONFIG_64BIT |
226 | /* | 226 | /* |
227 | * naitlb miss interruption handler (parisc 1.1 - 32 bit) | 227 | * naitlb miss interruption handler (parisc 1.1 - 32 bit) |
228 | * | ||
229 | * Note: naitlb misses will be treated | ||
230 | * as an ordinary itlb miss for now. | ||
231 | * However, note that naitlb misses | ||
232 | * have the faulting address in the | ||
233 | * IOR/ISR. | ||
234 | */ | 228 | */ |
235 | 229 | ||
236 | .macro naitlb_11 code | 230 | .macro naitlb_11 code |
237 | 231 | ||
238 | mfctl %isr,spc | 232 | mfctl %isr,spc |
239 | b itlb_miss_11 | 233 | b naitlb_miss_11 |
240 | mfctl %ior,va | 234 | mfctl %ior,va |
241 | /* FIXME: If user causes a naitlb miss, the priv level may not be in | ||
242 | * lower bits of va, where the itlb miss handler is expecting them | ||
243 | */ | ||
244 | 235 | ||
245 | .align 32 | 236 | .align 32 |
246 | .endm | 237 | .endm |
@@ -248,26 +239,17 @@ | |||
248 | 239 | ||
249 | /* | 240 | /* |
250 | * naitlb miss interruption handler (parisc 2.0) | 241 | * naitlb miss interruption handler (parisc 2.0) |
251 | * | ||
252 | * Note: naitlb misses will be treated | ||
253 | * as an ordinary itlb miss for now. | ||
254 | * However, note that naitlb misses | ||
255 | * have the faulting address in the | ||
256 | * IOR/ISR. | ||
257 | */ | 242 | */ |
258 | 243 | ||
259 | .macro naitlb_20 code | 244 | .macro naitlb_20 code |
260 | 245 | ||
261 | mfctl %isr,spc | 246 | mfctl %isr,spc |
262 | #ifdef CONFIG_64BIT | 247 | #ifdef CONFIG_64BIT |
263 | b itlb_miss_20w | 248 | b naitlb_miss_20w |
264 | #else | 249 | #else |
265 | b itlb_miss_20 | 250 | b naitlb_miss_20 |
266 | #endif | 251 | #endif |
267 | mfctl %ior,va | 252 | mfctl %ior,va |
268 | /* FIXME: If user causes a naitlb miss, the priv level may not be in | ||
269 | * lower bits of va, where the itlb miss handler is expecting them | ||
270 | */ | ||
271 | 253 | ||
272 | .align 32 | 254 | .align 32 |
273 | .endm | 255 | .endm |
@@ -581,7 +563,24 @@ | |||
581 | copy \va,\tmp1 | 563 | copy \va,\tmp1 |
582 | depi 0,31,23,\tmp1 | 564 | depi 0,31,23,\tmp1 |
583 | cmpb,COND(<>),n \tmp,\tmp1,\fault | 565 | cmpb,COND(<>),n \tmp,\tmp1,\fault |
584 | ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot | 566 | mfctl %cr19,\tmp /* iir */ |
567 | /* get the opcode (first six bits) into \tmp */ | ||
568 | extrw,u \tmp,5,6,\tmp | ||
569 | /* | ||
570 | * Only setting the T bit prevents data cache movein | ||
571 | * Setting access rights to zero prevents instruction cache movein | ||
572 | * | ||
573 | * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go | ||
574 | * to type field and _PAGE_READ goes to top bit of PL1 | ||
575 | */ | ||
576 | ldi (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot | ||
577 | /* | ||
578 | * so if the opcode is one (i.e. this is a memory management | ||
579 | * instruction) nullify the next load so \prot is only T. | ||
580 | * Otherwise this is a normal data operation | ||
581 | */ | ||
582 | cmpiclr,= 0x01,\tmp,%r0 | ||
583 | ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot | ||
585 | depd,z \prot,8,7,\prot | 584 | depd,z \prot,8,7,\prot |
586 | /* | 585 | /* |
587 | * OK, it is in the temp alias region, check whether "from" or "to". | 586 | * OK, it is in the temp alias region, check whether "from" or "to". |
@@ -631,11 +630,7 @@ ENTRY(fault_vector_20) | |||
631 | def 13 | 630 | def 13 |
632 | def 14 | 631 | def 14 |
633 | dtlb_20 15 | 632 | dtlb_20 15 |
634 | #if 0 | ||
635 | naitlb_20 16 | 633 | naitlb_20 16 |
636 | #else | ||
637 | def 16 | ||
638 | #endif | ||
639 | nadtlb_20 17 | 634 | nadtlb_20 17 |
640 | def 18 | 635 | def 18 |
641 | def 19 | 636 | def 19 |
@@ -678,11 +673,7 @@ ENTRY(fault_vector_11) | |||
678 | def 13 | 673 | def 13 |
679 | def 14 | 674 | def 14 |
680 | dtlb_11 15 | 675 | dtlb_11 15 |
681 | #if 0 | ||
682 | naitlb_11 16 | 676 | naitlb_11 16 |
683 | #else | ||
684 | def 16 | ||
685 | #endif | ||
686 | nadtlb_11 17 | 677 | nadtlb_11 17 |
687 | def 18 | 678 | def 18 |
688 | def 19 | 679 | def 19 |
@@ -1203,7 +1194,7 @@ nadtlb_miss_20w: | |||
1203 | get_pgd spc,ptp | 1194 | get_pgd spc,ptp |
1204 | space_check spc,t0,nadtlb_fault | 1195 | space_check spc,t0,nadtlb_fault |
1205 | 1196 | ||
1206 | L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w | 1197 | L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w |
1207 | 1198 | ||
1208 | update_ptep ptp,pte,t0,t1 | 1199 | update_ptep ptp,pte,t0,t1 |
1209 | 1200 | ||
@@ -1214,16 +1205,8 @@ nadtlb_miss_20w: | |||
1214 | rfir | 1205 | rfir |
1215 | nop | 1206 | nop |
1216 | 1207 | ||
1217 | nadtlb_check_flush_20w: | 1208 | nadtlb_check_alias_20w: |
1218 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1209 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1219 | |||
1220 | /* Insert a "flush only" translation */ | ||
1221 | |||
1222 | depdi,z 7,7,3,prot | ||
1223 | depdi 1,10,1,prot | ||
1224 | |||
1225 | /* Drop prot bits from pte and convert to page addr for idtlbt */ | ||
1226 | convert_for_tlb_insert20 pte | ||
1227 | 1210 | ||
1228 | idtlbt pte,prot | 1211 | idtlbt pte,prot |
1229 | 1212 | ||
@@ -1255,25 +1238,7 @@ dtlb_miss_11: | |||
1255 | nop | 1238 | nop |
1256 | 1239 | ||
1257 | dtlb_check_alias_11: | 1240 | dtlb_check_alias_11: |
1258 | 1241 | do_alias spc,t0,t1,va,pte,prot,dtlb_fault | |
1259 | /* Check to see if fault is in the temporary alias region */ | ||
1260 | |||
1261 | cmpib,<>,n 0,spc,dtlb_fault /* forward */ | ||
1262 | ldil L%(TMPALIAS_MAP_START),t0 | ||
1263 | copy va,t1 | ||
1264 | depwi 0,31,23,t1 | ||
1265 | cmpb,<>,n t0,t1,dtlb_fault /* forward */ | ||
1266 | ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot | ||
1267 | depw,z prot,8,7,prot | ||
1268 | |||
1269 | /* | ||
1270 | * OK, it is in the temp alias region, check whether "from" or "to". | ||
1271 | * Check "subtle" note in pacache.S re: r23/r26. | ||
1272 | */ | ||
1273 | |||
1274 | extrw,u,= va,9,1,r0 | ||
1275 | or,tr %r23,%r0,pte /* If "from" use "from" page */ | ||
1276 | or %r26,%r0,pte /* else "to", use "to" page */ | ||
1277 | 1242 | ||
1278 | idtlba pte,(va) | 1243 | idtlba pte,(va) |
1279 | idtlbp prot,(va) | 1244 | idtlbp prot,(va) |
@@ -1286,7 +1251,7 @@ nadtlb_miss_11: | |||
1286 | 1251 | ||
1287 | space_check spc,t0,nadtlb_fault | 1252 | space_check spc,t0,nadtlb_fault |
1288 | 1253 | ||
1289 | L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 | 1254 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 |
1290 | 1255 | ||
1291 | update_ptep ptp,pte,t0,t1 | 1256 | update_ptep ptp,pte,t0,t1 |
1292 | 1257 | ||
@@ -1304,26 +1269,11 @@ nadtlb_miss_11: | |||
1304 | rfir | 1269 | rfir |
1305 | nop | 1270 | nop |
1306 | 1271 | ||
1307 | nadtlb_check_flush_11: | 1272 | nadtlb_check_alias_11: |
1308 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1273 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1309 | |||
1310 | /* Insert a "flush only" translation */ | ||
1311 | |||
1312 | zdepi 7,7,3,prot | ||
1313 | depi 1,10,1,prot | ||
1314 | 1274 | ||
1315 | /* Get rid of prot bits and convert to page addr for idtlba */ | 1275 | idtlba pte,(va) |
1316 | 1276 | idtlbp prot,(va) | |
1317 | depi 0,31,ASM_PFN_PTE_SHIFT,pte | ||
1318 | SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte | ||
1319 | |||
1320 | mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ | ||
1321 | mtsp spc,%sr1 | ||
1322 | |||
1323 | idtlba pte,(%sr1,va) | ||
1324 | idtlbp prot,(%sr1,va) | ||
1325 | |||
1326 | mtsp t0, %sr1 /* Restore sr1 */ | ||
1327 | 1277 | ||
1328 | rfir | 1278 | rfir |
1329 | nop | 1279 | nop |
@@ -1359,7 +1309,7 @@ nadtlb_miss_20: | |||
1359 | 1309 | ||
1360 | space_check spc,t0,nadtlb_fault | 1310 | space_check spc,t0,nadtlb_fault |
1361 | 1311 | ||
1362 | L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 | 1312 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 |
1363 | 1313 | ||
1364 | update_ptep ptp,pte,t0,t1 | 1314 | update_ptep ptp,pte,t0,t1 |
1365 | 1315 | ||
@@ -1372,21 +1322,14 @@ nadtlb_miss_20: | |||
1372 | rfir | 1322 | rfir |
1373 | nop | 1323 | nop |
1374 | 1324 | ||
1375 | nadtlb_check_flush_20: | 1325 | nadtlb_check_alias_20: |
1376 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1326 | do_alias spc,t0,t1,va,pte,prot,nadtlb_emulate |
1377 | |||
1378 | /* Insert a "flush only" translation */ | ||
1379 | |||
1380 | depdi,z 7,7,3,prot | ||
1381 | depdi 1,10,1,prot | ||
1382 | |||
1383 | /* Drop prot bits from pte and convert to page addr for idtlbt */ | ||
1384 | convert_for_tlb_insert20 pte | ||
1385 | 1327 | ||
1386 | idtlbt pte,prot | 1328 | idtlbt pte,prot |
1387 | 1329 | ||
1388 | rfir | 1330 | rfir |
1389 | nop | 1331 | nop |
1332 | |||
1390 | #endif | 1333 | #endif |
1391 | 1334 | ||
1392 | nadtlb_emulate: | 1335 | nadtlb_emulate: |
@@ -1484,6 +1427,36 @@ itlb_miss_20w: | |||
1484 | rfir | 1427 | rfir |
1485 | nop | 1428 | nop |
1486 | 1429 | ||
1430 | naitlb_miss_20w: | ||
1431 | |||
1432 | /* | ||
1433 | * I miss is a little different, since we allow users to fault | ||
1434 | * on the gateway page which is in the kernel address space. | ||
1435 | */ | ||
1436 | |||
1437 | space_adjust spc,va,t0 | ||
1438 | get_pgd spc,ptp | ||
1439 | space_check spc,t0,naitlb_fault | ||
1440 | |||
1441 | L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w | ||
1442 | |||
1443 | update_ptep ptp,pte,t0,t1 | ||
1444 | |||
1445 | make_insert_tlb spc,pte,prot | ||
1446 | |||
1447 | iitlbt pte,prot | ||
1448 | |||
1449 | rfir | ||
1450 | nop | ||
1451 | |||
1452 | naitlb_check_alias_20w: | ||
1453 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault | ||
1454 | |||
1455 | iitlbt pte,prot | ||
1456 | |||
1457 | rfir | ||
1458 | nop | ||
1459 | |||
1487 | #else | 1460 | #else |
1488 | 1461 | ||
1489 | itlb_miss_11: | 1462 | itlb_miss_11: |
@@ -1508,6 +1481,38 @@ itlb_miss_11: | |||
1508 | rfir | 1481 | rfir |
1509 | nop | 1482 | nop |
1510 | 1483 | ||
1484 | naitlb_miss_11: | ||
1485 | get_pgd spc,ptp | ||
1486 | |||
1487 | space_check spc,t0,naitlb_fault | ||
1488 | |||
1489 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 | ||
1490 | |||
1491 | update_ptep ptp,pte,t0,t1 | ||
1492 | |||
1493 | make_insert_tlb_11 spc,pte,prot | ||
1494 | |||
1495 | mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ | ||
1496 | mtsp spc,%sr1 | ||
1497 | |||
1498 | iitlba pte,(%sr1,va) | ||
1499 | iitlbp prot,(%sr1,va) | ||
1500 | |||
1501 | mtsp t0, %sr1 /* Restore sr1 */ | ||
1502 | |||
1503 | rfir | ||
1504 | nop | ||
1505 | |||
1506 | naitlb_check_alias_11: | ||
1507 | do_alias spc,t0,t1,va,pte,prot,itlb_fault | ||
1508 | |||
1509 | iitlba pte,(%sr0, va) | ||
1510 | iitlbp prot,(%sr0, va) | ||
1511 | |||
1512 | rfir | ||
1513 | nop | ||
1514 | |||
1515 | |||
1511 | itlb_miss_20: | 1516 | itlb_miss_20: |
1512 | get_pgd spc,ptp | 1517 | get_pgd spc,ptp |
1513 | 1518 | ||
@@ -1526,6 +1531,32 @@ itlb_miss_20: | |||
1526 | rfir | 1531 | rfir |
1527 | nop | 1532 | nop |
1528 | 1533 | ||
1534 | naitlb_miss_20: | ||
1535 | get_pgd spc,ptp | ||
1536 | |||
1537 | space_check spc,t0,naitlb_fault | ||
1538 | |||
1539 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 | ||
1540 | |||
1541 | update_ptep ptp,pte,t0,t1 | ||
1542 | |||
1543 | make_insert_tlb spc,pte,prot | ||
1544 | |||
1545 | f_extend pte,t0 | ||
1546 | |||
1547 | iitlbt pte,prot | ||
1548 | |||
1549 | rfir | ||
1550 | nop | ||
1551 | |||
1552 | naitlb_check_alias_20: | ||
1553 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault | ||
1554 | |||
1555 | iitlbt pte,prot | ||
1556 | |||
1557 | rfir | ||
1558 | nop | ||
1559 | |||
1529 | #endif | 1560 | #endif |
1530 | 1561 | ||
1531 | #ifdef CONFIG_64BIT | 1562 | #ifdef CONFIG_64BIT |
@@ -1662,6 +1693,10 @@ nadtlb_fault: | |||
1662 | b intr_save | 1693 | b intr_save |
1663 | ldi 17,%r8 | 1694 | ldi 17,%r8 |
1664 | 1695 | ||
1696 | naitlb_fault: | ||
1697 | b intr_save | ||
1698 | ldi 16,%r8 | ||
1699 | |||
1665 | dtlb_fault: | 1700 | dtlb_fault: |
1666 | b intr_save | 1701 | b intr_save |
1667 | ldi 15,%r8 | 1702 | ldi 15,%r8 |