aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlbex.c
diff options
context:
space:
mode:
authorThiemo Seufer <ths@networkno.de>2005-04-28 04:52:57 -0400
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 14:31:11 -0400
commit63b2d2f4d2073ac3452ce977d27cc81eabaa61a3 (patch)
tree821eed26f6eef86263073e01217623bc9f25e44b /arch/mips/mm/tlbex.c
parentba5187dbb4b2eac99d6fa1d6bbece67e0066bf51 (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.c52
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];
1271u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; 1271u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
1272 1272
1273static void __init 1273static void __init
1274iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset, 1274iPTE_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
1294static void __init 1293static void __init
1295iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, 1294iPTE_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
1361build_make_valid(u32 **p, struct reloc **r, unsigned int pte, 1365build_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
1386build_make_write(u32 **p, struct reloc **r, unsigned int pte, 1391build_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