aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/vpe.c
diff options
context:
space:
mode:
authorNigel Stephens <nigel@mips.com>2007-11-08 08:25:51 -0500
committerRalf Baechle <ralf@linux-mips.org>2007-11-15 18:21:50 -0500
commit7c3a622d9c8e88117a8d647756827852dd8c8432 (patch)
treee30d2274855e61cab96cc4abebcab7e69263c641 /arch/mips/kernel/vpe.c
parent8dfa741f146b39eb59ef2094e03f47079ca99eb0 (diff)
[MIPS] vpe: handle halting TCs in an errata safe way.
Adds a JR.HB after halting a TC, to ensure that the TC has really halted. only modifies the TCSTATUS register when the TC is safely halted. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/vpe.c')
-rw-r--r--arch/mips/kernel/vpe.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 436a64ff3989..38bd33fa2a23 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -1003,6 +1003,7 @@ static void cleanup_tc(struct tc *tc)
1003 write_tc_c0_tcstatus(tmp); 1003 write_tc_c0_tcstatus(tmp);
1004 1004
1005 write_tc_c0_tchalt(TCHALT_H); 1005 write_tc_c0_tchalt(TCHALT_H);
1006 mips_ihb();
1006 1007
1007 /* bind it to anything other than VPE1 */ 1008 /* bind it to anything other than VPE1 */
1008// write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE 1009// write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE
@@ -1235,9 +1236,12 @@ int vpe_free(vpe_handle vpe)
1235 settc(t->index); 1236 settc(t->index);
1236 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA); 1237 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
1237 1238
1238 /* mark the TC unallocated and halt'ed */ 1239 /* halt the TC */
1239 write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
1240 write_tc_c0_tchalt(TCHALT_H); 1240 write_tc_c0_tchalt(TCHALT_H);
1241 mips_ihb();
1242
1243 /* mark the TC unallocated */
1244 write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
1241 1245
1242 v->state = VPE_STATE_UNUSED; 1246 v->state = VPE_STATE_UNUSED;
1243 1247
@@ -1533,14 +1537,16 @@ static int __init vpe_module_init(void)
1533 t->pvpe = get_vpe(0); /* set the parent vpe */ 1537 t->pvpe = get_vpe(0); /* set the parent vpe */
1534 } 1538 }
1535 1539
1540 /* halt the TC */
1541 write_tc_c0_tchalt(TCHALT_H);
1542 mips_ihb();
1543
1536 tmp = read_tc_c0_tcstatus(); 1544 tmp = read_tc_c0_tcstatus();
1537 1545
1538 /* mark not activated and not dynamically allocatable */ 1546 /* mark not activated and not dynamically allocatable */
1539 tmp &= ~(TCSTATUS_A | TCSTATUS_DA); 1547 tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
1540 tmp |= TCSTATUS_IXMT; /* interrupt exempt */ 1548 tmp |= TCSTATUS_IXMT; /* interrupt exempt */
1541 write_tc_c0_tcstatus(tmp); 1549 write_tc_c0_tcstatus(tmp);
1542
1543 write_tc_c0_tchalt(TCHALT_H);
1544 } 1550 }
1545 } 1551 }
1546 1552