diff options
author | Thiemo Seufer <ths@networkno.de> | 2005-04-28 04:52:57 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:11 -0400 |
commit | 63b2d2f4d2073ac3452ce977d27cc81eabaa61a3 (patch) | |
tree | 821eed26f6eef86263073e01217623bc9f25e44b /arch/mips/mm/tlbex.c | |
parent | ba5187dbb4b2eac99d6fa1d6bbece67e0066bf51 (diff) |
Handle _PAGE_DIRTY correctly for CONFIG_64BIT_PHYS_ADDR on 32bit CPUs.
Signed-off-by: Thiemo Seufer <ths@networkno.de>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm/tlbex.c')
-rw-r--r-- | arch/mips/mm/tlbex.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 018f7527a724..cdd02d93a15c 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -1271,37 +1271,41 @@ u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE]; | |||
1271 | u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; | 1271 | u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; |
1272 | 1272 | ||
1273 | static void __init | 1273 | static void __init |
1274 | iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset, | 1274 | iPTE_LW(u32 **p, struct label **l, unsigned int pte, unsigned int ptr) |
1275 | unsigned int ptr) | ||
1276 | { | 1275 | { |
1277 | #ifdef CONFIG_SMP | 1276 | #ifdef CONFIG_SMP |
1278 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1277 | # ifdef CONFIG_64BIT_PHYS_ADDR |
1279 | if (cpu_has_64bits) | 1278 | if (cpu_has_64bits) |
1280 | i_lld(p, pte, offset, ptr); | 1279 | i_lld(p, pte, 0, ptr); |
1281 | else | 1280 | else |
1282 | # endif | 1281 | # endif |
1283 | i_LL(p, pte, offset, ptr); | 1282 | i_LL(p, pte, 0, ptr); |
1284 | #else | 1283 | #else |
1285 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1284 | # ifdef CONFIG_64BIT_PHYS_ADDR |
1286 | if (cpu_has_64bits) | 1285 | if (cpu_has_64bits) |
1287 | i_ld(p, pte, offset, ptr); | 1286 | i_ld(p, pte, 0, ptr); |
1288 | else | 1287 | else |
1289 | # endif | 1288 | # endif |
1290 | i_LW(p, pte, offset, ptr); | 1289 | i_LW(p, pte, 0, ptr); |
1291 | #endif | 1290 | #endif |
1292 | } | 1291 | } |
1293 | 1292 | ||
1294 | static void __init | 1293 | static void __init |
1295 | iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, | 1294 | iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, unsigned int ptr, |
1296 | unsigned int ptr) | 1295 | unsigned int mode) |
1297 | { | 1296 | { |
1297 | #ifdef CONFIG_64BIT_PHYS_ADDR | ||
1298 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); | ||
1299 | #endif | ||
1300 | |||
1301 | i_ori(p, pte, pte, mode); | ||
1298 | #ifdef CONFIG_SMP | 1302 | #ifdef CONFIG_SMP |
1299 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1303 | # ifdef CONFIG_64BIT_PHYS_ADDR |
1300 | if (cpu_has_64bits) | 1304 | if (cpu_has_64bits) |
1301 | i_scd(p, pte, offset, ptr); | 1305 | i_scd(p, pte, 0, ptr); |
1302 | else | 1306 | else |
1303 | # endif | 1307 | # endif |
1304 | i_SC(p, pte, offset, ptr); | 1308 | i_SC(p, pte, 0, ptr); |
1305 | 1309 | ||
1306 | if (r10000_llsc_war()) | 1310 | if (r10000_llsc_war()) |
1307 | il_beqzl(p, r, pte, label_smp_pgtable_change); | 1311 | il_beqzl(p, r, pte, label_smp_pgtable_change); |
@@ -1312,7 +1316,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, | |||
1312 | if (!cpu_has_64bits) { | 1316 | if (!cpu_has_64bits) { |
1313 | /* no i_nop needed */ | 1317 | /* no i_nop needed */ |
1314 | i_ll(p, pte, sizeof(pte_t) / 2, ptr); | 1318 | i_ll(p, pte, sizeof(pte_t) / 2, ptr); |
1315 | i_ori(p, pte, pte, _PAGE_VALID); | 1319 | i_ori(p, pte, pte, hwmode); |
1316 | i_sc(p, pte, sizeof(pte_t) / 2, ptr); | 1320 | i_sc(p, pte, sizeof(pte_t) / 2, ptr); |
1317 | il_beqz(p, r, pte, label_smp_pgtable_change); | 1321 | il_beqz(p, r, pte, label_smp_pgtable_change); |
1318 | /* no i_nop needed */ | 1322 | /* no i_nop needed */ |
@@ -1325,15 +1329,15 @@ iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, | |||
1325 | #else | 1329 | #else |
1326 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1330 | # ifdef CONFIG_64BIT_PHYS_ADDR |
1327 | if (cpu_has_64bits) | 1331 | if (cpu_has_64bits) |
1328 | i_sd(p, pte, offset, ptr); | 1332 | i_sd(p, pte, 0, ptr); |
1329 | else | 1333 | else |
1330 | # endif | 1334 | # endif |
1331 | i_SW(p, pte, offset, ptr); | 1335 | i_SW(p, pte, 0, ptr); |
1332 | 1336 | ||
1333 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1337 | # ifdef CONFIG_64BIT_PHYS_ADDR |
1334 | if (!cpu_has_64bits) { | 1338 | if (!cpu_has_64bits) { |
1335 | i_lw(p, pte, sizeof(pte_t) / 2, ptr); | 1339 | i_lw(p, pte, sizeof(pte_t) / 2, ptr); |
1336 | i_ori(p, pte, pte, _PAGE_VALID); | 1340 | i_ori(p, pte, pte, hwmode); |
1337 | i_sw(p, pte, sizeof(pte_t) / 2, ptr); | 1341 | i_sw(p, pte, sizeof(pte_t) / 2, ptr); |
1338 | i_lw(p, pte, 0, ptr); | 1342 | i_lw(p, pte, 0, ptr); |
1339 | } | 1343 | } |
@@ -1353,7 +1357,7 @@ build_pte_present(u32 **p, struct label **l, struct reloc **r, | |||
1353 | i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); | 1357 | i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); |
1354 | i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); | 1358 | i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); |
1355 | il_bnez(p, r, pte, lid); | 1359 | il_bnez(p, r, pte, lid); |
1356 | iPTE_LW(p, l, pte, 0, ptr); | 1360 | iPTE_LW(p, l, pte, ptr); |
1357 | } | 1361 | } |
1358 | 1362 | ||
1359 | /* Make PTE valid, store result in PTR. */ | 1363 | /* Make PTE valid, store result in PTR. */ |
@@ -1361,8 +1365,9 @@ static void __init | |||
1361 | build_make_valid(u32 **p, struct reloc **r, unsigned int pte, | 1365 | build_make_valid(u32 **p, struct reloc **r, unsigned int pte, |
1362 | unsigned int ptr) | 1366 | unsigned int ptr) |
1363 | { | 1367 | { |
1364 | i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED); | 1368 | unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED; |
1365 | iPTE_SW(p, r, pte, 0, ptr); | 1369 | |
1370 | iPTE_SW(p, r, pte, ptr, mode); | ||
1366 | } | 1371 | } |
1367 | 1372 | ||
1368 | /* | 1373 | /* |
@@ -1376,7 +1381,7 @@ build_pte_writable(u32 **p, struct label **l, struct reloc **r, | |||
1376 | i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); | 1381 | i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); |
1377 | i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); | 1382 | i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); |
1378 | il_bnez(p, r, pte, lid); | 1383 | il_bnez(p, r, pte, lid); |
1379 | iPTE_LW(p, l, pte, 0, ptr); | 1384 | iPTE_LW(p, l, pte, ptr); |
1380 | } | 1385 | } |
1381 | 1386 | ||
1382 | /* Make PTE writable, update software status bits as well, then store | 1387 | /* Make PTE writable, update software status bits as well, then store |
@@ -1386,9 +1391,10 @@ static void __init | |||
1386 | build_make_write(u32 **p, struct reloc **r, unsigned int pte, | 1391 | build_make_write(u32 **p, struct reloc **r, unsigned int pte, |
1387 | unsigned int ptr) | 1392 | unsigned int ptr) |
1388 | { | 1393 | { |
1389 | i_ori(p, pte, pte, | 1394 | unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID |
1390 | _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); | 1395 | | _PAGE_DIRTY); |
1391 | iPTE_SW(p, r, pte, 0, ptr); | 1396 | |
1397 | iPTE_SW(p, r, pte, ptr, mode); | ||
1392 | } | 1398 | } |
1393 | 1399 | ||
1394 | /* | 1400 | /* |
@@ -1401,7 +1407,7 @@ build_pte_modifiable(u32 **p, struct label **l, struct reloc **r, | |||
1401 | { | 1407 | { |
1402 | i_andi(p, pte, pte, _PAGE_WRITE); | 1408 | i_andi(p, pte, pte, _PAGE_WRITE); |
1403 | il_beqz(p, r, pte, lid); | 1409 | il_beqz(p, r, pte, lid); |
1404 | iPTE_LW(p, l, pte, 0, ptr); | 1410 | iPTE_LW(p, l, pte, ptr); |
1405 | } | 1411 | } |
1406 | 1412 | ||
1407 | /* | 1413 | /* |
@@ -1614,7 +1620,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct label **l, | |||
1614 | #ifdef CONFIG_SMP | 1620 | #ifdef CONFIG_SMP |
1615 | l_smp_pgtable_change(l, *p); | 1621 | l_smp_pgtable_change(l, *p); |
1616 | # endif | 1622 | # endif |
1617 | iPTE_LW(p, l, pte, 0, ptr); /* get even pte */ | 1623 | iPTE_LW(p, l, pte, ptr); /* get even pte */ |
1618 | build_tlb_probe_entry(p); | 1624 | build_tlb_probe_entry(p); |
1619 | } | 1625 | } |
1620 | 1626 | ||