diff options
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r-- | arch/parisc/kernel/entry.S | 230 |
1 files changed, 134 insertions, 96 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 6337adef30f6..6f0594439143 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -187,8 +187,8 @@ | |||
187 | 187 | ||
188 | /* Register definitions for tlb miss handler macros */ | 188 | /* Register definitions for tlb miss handler macros */ |
189 | 189 | ||
190 | va = r8 /* virtual address for which the trap occured */ | 190 | va = r8 /* virtual address for which the trap occurred */ |
191 | spc = r24 /* space for which the trap occured */ | 191 | spc = r24 /* space for which the trap occurred */ |
192 | 192 | ||
193 | #ifndef CONFIG_64BIT | 193 | #ifndef CONFIG_64BIT |
194 | 194 | ||
@@ -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 |
@@ -701,6 +692,9 @@ ENTRY(fault_vector_11) | |||
701 | END(fault_vector_11) | 692 | END(fault_vector_11) |
702 | 693 | ||
703 | #endif | 694 | #endif |
695 | /* Fault vector is separately protected and *must* be on its own page */ | ||
696 | .align PAGE_SIZE | ||
697 | ENTRY(end_fault_vector) | ||
704 | 698 | ||
705 | .import handle_interruption,code | 699 | .import handle_interruption,code |
706 | .import do_cpu_irq_mask,code | 700 | .import do_cpu_irq_mask,code |
@@ -891,7 +885,7 @@ ENTRY(syscall_exit_rfi) | |||
891 | * (we don't store them in the sigcontext), so set them | 885 | * (we don't store them in the sigcontext), so set them |
892 | * to "proper" values now (otherwise we'll wind up restoring | 886 | * to "proper" values now (otherwise we'll wind up restoring |
893 | * whatever was last stored in the task structure, which might | 887 | * whatever was last stored in the task structure, which might |
894 | * be inconsistent if an interrupt occured while on the gateway | 888 | * be inconsistent if an interrupt occurred while on the gateway |
895 | * page). Note that we may be "trashing" values the user put in | 889 | * page). Note that we may be "trashing" values the user put in |
896 | * them, but we don't support the user changing them. | 890 | * them, but we don't support the user changing them. |
897 | */ | 891 | */ |
@@ -1165,11 +1159,11 @@ ENDPROC(intr_save) | |||
1165 | */ | 1159 | */ |
1166 | 1160 | ||
1167 | t0 = r1 /* temporary register 0 */ | 1161 | t0 = r1 /* temporary register 0 */ |
1168 | va = r8 /* virtual address for which the trap occured */ | 1162 | va = r8 /* virtual address for which the trap occurred */ |
1169 | t1 = r9 /* temporary register 1 */ | 1163 | t1 = r9 /* temporary register 1 */ |
1170 | pte = r16 /* pte/phys page # */ | 1164 | pte = r16 /* pte/phys page # */ |
1171 | prot = r17 /* prot bits */ | 1165 | prot = r17 /* prot bits */ |
1172 | spc = r24 /* space for which the trap occured */ | 1166 | spc = r24 /* space for which the trap occurred */ |
1173 | ptp = r25 /* page directory/page table pointer */ | 1167 | ptp = r25 /* page directory/page table pointer */ |
1174 | 1168 | ||
1175 | #ifdef CONFIG_64BIT | 1169 | #ifdef CONFIG_64BIT |
@@ -1203,7 +1197,7 @@ nadtlb_miss_20w: | |||
1203 | get_pgd spc,ptp | 1197 | get_pgd spc,ptp |
1204 | space_check spc,t0,nadtlb_fault | 1198 | space_check spc,t0,nadtlb_fault |
1205 | 1199 | ||
1206 | L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w | 1200 | L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w |
1207 | 1201 | ||
1208 | update_ptep ptp,pte,t0,t1 | 1202 | update_ptep ptp,pte,t0,t1 |
1209 | 1203 | ||
@@ -1214,16 +1208,8 @@ nadtlb_miss_20w: | |||
1214 | rfir | 1208 | rfir |
1215 | nop | 1209 | nop |
1216 | 1210 | ||
1217 | nadtlb_check_flush_20w: | 1211 | nadtlb_check_alias_20w: |
1218 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1212 | 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 | 1213 | ||
1228 | idtlbt pte,prot | 1214 | idtlbt pte,prot |
1229 | 1215 | ||
@@ -1255,25 +1241,7 @@ dtlb_miss_11: | |||
1255 | nop | 1241 | nop |
1256 | 1242 | ||
1257 | dtlb_check_alias_11: | 1243 | dtlb_check_alias_11: |
1258 | 1244 | 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 | 1245 | ||
1278 | idtlba pte,(va) | 1246 | idtlba pte,(va) |
1279 | idtlbp prot,(va) | 1247 | idtlbp prot,(va) |
@@ -1286,7 +1254,7 @@ nadtlb_miss_11: | |||
1286 | 1254 | ||
1287 | space_check spc,t0,nadtlb_fault | 1255 | space_check spc,t0,nadtlb_fault |
1288 | 1256 | ||
1289 | L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 | 1257 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 |
1290 | 1258 | ||
1291 | update_ptep ptp,pte,t0,t1 | 1259 | update_ptep ptp,pte,t0,t1 |
1292 | 1260 | ||
@@ -1304,26 +1272,11 @@ nadtlb_miss_11: | |||
1304 | rfir | 1272 | rfir |
1305 | nop | 1273 | nop |
1306 | 1274 | ||
1307 | nadtlb_check_flush_11: | 1275 | nadtlb_check_alias_11: |
1308 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1276 | 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 | 1277 | ||
1315 | /* Get rid of prot bits and convert to page addr for idtlba */ | 1278 | idtlba pte,(va) |
1316 | 1279 | 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 | 1280 | ||
1328 | rfir | 1281 | rfir |
1329 | nop | 1282 | nop |
@@ -1359,7 +1312,7 @@ nadtlb_miss_20: | |||
1359 | 1312 | ||
1360 | space_check spc,t0,nadtlb_fault | 1313 | space_check spc,t0,nadtlb_fault |
1361 | 1314 | ||
1362 | L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 | 1315 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 |
1363 | 1316 | ||
1364 | update_ptep ptp,pte,t0,t1 | 1317 | update_ptep ptp,pte,t0,t1 |
1365 | 1318 | ||
@@ -1372,21 +1325,14 @@ nadtlb_miss_20: | |||
1372 | rfir | 1325 | rfir |
1373 | nop | 1326 | nop |
1374 | 1327 | ||
1375 | nadtlb_check_flush_20: | 1328 | nadtlb_check_alias_20: |
1376 | bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate | 1329 | 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 | 1330 | ||
1386 | idtlbt pte,prot | 1331 | idtlbt pte,prot |
1387 | 1332 | ||
1388 | rfir | 1333 | rfir |
1389 | nop | 1334 | nop |
1335 | |||
1390 | #endif | 1336 | #endif |
1391 | 1337 | ||
1392 | nadtlb_emulate: | 1338 | nadtlb_emulate: |
@@ -1484,6 +1430,36 @@ itlb_miss_20w: | |||
1484 | rfir | 1430 | rfir |
1485 | nop | 1431 | nop |
1486 | 1432 | ||
1433 | naitlb_miss_20w: | ||
1434 | |||
1435 | /* | ||
1436 | * I miss is a little different, since we allow users to fault | ||
1437 | * on the gateway page which is in the kernel address space. | ||
1438 | */ | ||
1439 | |||
1440 | space_adjust spc,va,t0 | ||
1441 | get_pgd spc,ptp | ||
1442 | space_check spc,t0,naitlb_fault | ||
1443 | |||
1444 | L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w | ||
1445 | |||
1446 | update_ptep ptp,pte,t0,t1 | ||
1447 | |||
1448 | make_insert_tlb spc,pte,prot | ||
1449 | |||
1450 | iitlbt pte,prot | ||
1451 | |||
1452 | rfir | ||
1453 | nop | ||
1454 | |||
1455 | naitlb_check_alias_20w: | ||
1456 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault | ||
1457 | |||
1458 | iitlbt pte,prot | ||
1459 | |||
1460 | rfir | ||
1461 | nop | ||
1462 | |||
1487 | #else | 1463 | #else |
1488 | 1464 | ||
1489 | itlb_miss_11: | 1465 | itlb_miss_11: |
@@ -1508,6 +1484,38 @@ itlb_miss_11: | |||
1508 | rfir | 1484 | rfir |
1509 | nop | 1485 | nop |
1510 | 1486 | ||
1487 | naitlb_miss_11: | ||
1488 | get_pgd spc,ptp | ||
1489 | |||
1490 | space_check spc,t0,naitlb_fault | ||
1491 | |||
1492 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 | ||
1493 | |||
1494 | update_ptep ptp,pte,t0,t1 | ||
1495 | |||
1496 | make_insert_tlb_11 spc,pte,prot | ||
1497 | |||
1498 | mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ | ||
1499 | mtsp spc,%sr1 | ||
1500 | |||
1501 | iitlba pte,(%sr1,va) | ||
1502 | iitlbp prot,(%sr1,va) | ||
1503 | |||
1504 | mtsp t0, %sr1 /* Restore sr1 */ | ||
1505 | |||
1506 | rfir | ||
1507 | nop | ||
1508 | |||
1509 | naitlb_check_alias_11: | ||
1510 | do_alias spc,t0,t1,va,pte,prot,itlb_fault | ||
1511 | |||
1512 | iitlba pte,(%sr0, va) | ||
1513 | iitlbp prot,(%sr0, va) | ||
1514 | |||
1515 | rfir | ||
1516 | nop | ||
1517 | |||
1518 | |||
1511 | itlb_miss_20: | 1519 | itlb_miss_20: |
1512 | get_pgd spc,ptp | 1520 | get_pgd spc,ptp |
1513 | 1521 | ||
@@ -1526,6 +1534,32 @@ itlb_miss_20: | |||
1526 | rfir | 1534 | rfir |
1527 | nop | 1535 | nop |
1528 | 1536 | ||
1537 | naitlb_miss_20: | ||
1538 | get_pgd spc,ptp | ||
1539 | |||
1540 | space_check spc,t0,naitlb_fault | ||
1541 | |||
1542 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 | ||
1543 | |||
1544 | update_ptep ptp,pte,t0,t1 | ||
1545 | |||
1546 | make_insert_tlb spc,pte,prot | ||
1547 | |||
1548 | f_extend pte,t0 | ||
1549 | |||
1550 | iitlbt pte,prot | ||
1551 | |||
1552 | rfir | ||
1553 | nop | ||
1554 | |||
1555 | naitlb_check_alias_20: | ||
1556 | do_alias spc,t0,t1,va,pte,prot,naitlb_fault | ||
1557 | |||
1558 | iitlbt pte,prot | ||
1559 | |||
1560 | rfir | ||
1561 | nop | ||
1562 | |||
1529 | #endif | 1563 | #endif |
1530 | 1564 | ||
1531 | #ifdef CONFIG_64BIT | 1565 | #ifdef CONFIG_64BIT |
@@ -1662,6 +1696,10 @@ nadtlb_fault: | |||
1662 | b intr_save | 1696 | b intr_save |
1663 | ldi 17,%r8 | 1697 | ldi 17,%r8 |
1664 | 1698 | ||
1699 | naitlb_fault: | ||
1700 | b intr_save | ||
1701 | ldi 16,%r8 | ||
1702 | |||
1665 | dtlb_fault: | 1703 | dtlb_fault: |
1666 | b intr_save | 1704 | b intr_save |
1667 | ldi 15,%r8 | 1705 | ldi 15,%r8 |