diff options
author | Richard Kuo <rkuo@codeaurora.org> | 2012-03-27 18:38:09 -0400 |
---|---|---|
committer | Richard Kuo <rkuo@codeaurora.org> | 2013-04-30 20:40:23 -0400 |
commit | 60c4ba99e015afe879c2682967c8ca8d233f6d3c (patch) | |
tree | ddf41e569dd852c627ad8008b756d224694861c5 /arch/hexagon | |
parent | 444dd742d3b0353c55c92f77e6732d932120c829 (diff) |
Hexagon: add support for new v4+ registers
Add support for a couple new v4+ registers, along with
newer save/restore pt_regs.
Signed-off-by: Richard Kuo <rkuo@codeaurora.org>
Diffstat (limited to 'arch/hexagon')
-rw-r--r-- | arch/hexagon/include/uapi/asm/registers.h | 11 | ||||
-rw-r--r-- | arch/hexagon/include/uapi/asm/user.h | 6 | ||||
-rw-r--r-- | arch/hexagon/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/hexagon/kernel/kgdb.c | 2 | ||||
-rw-r--r-- | arch/hexagon/kernel/ptrace.c | 9 | ||||
-rw-r--r-- | arch/hexagon/kernel/signal.c | 10 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_entry.S | 211 | ||||
-rw-r--r-- | arch/hexagon/kernel/vm_events.c | 2 |
8 files changed, 206 insertions, 48 deletions
diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index c20406f63b5c..80504155ca3a 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h | |||
@@ -57,10 +57,17 @@ struct pt_regs { | |||
57 | }; | 57 | }; |
58 | union { | 58 | union { |
59 | struct { | 59 | struct { |
60 | unsigned long gp; | ||
61 | unsigned long ugp; | 60 | unsigned long ugp; |
61 | unsigned long gp; | ||
62 | }; | ||
63 | long long int gpugp; | ||
64 | }; | ||
65 | union { | ||
66 | struct { | ||
67 | unsigned long cs0; | ||
68 | unsigned long cs1; | ||
62 | }; | 69 | }; |
63 | long long int ugpgp; | 70 | long long int cs1cs0; |
64 | }; | 71 | }; |
65 | /* | 72 | /* |
66 | * Be extremely careful with rearranging these, if at all. Some code | 73 | * Be extremely careful with rearranging these, if at all. Some code |
diff --git a/arch/hexagon/include/uapi/asm/user.h b/arch/hexagon/include/uapi/asm/user.h index cef13ee1413f..3dae94d9ced7 100644 --- a/arch/hexagon/include/uapi/asm/user.h +++ b/arch/hexagon/include/uapi/asm/user.h | |||
@@ -55,9 +55,15 @@ struct user_regs_struct { | |||
55 | unsigned long pc; | 55 | unsigned long pc; |
56 | unsigned long cause; | 56 | unsigned long cause; |
57 | unsigned long badva; | 57 | unsigned long badva; |
58 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
58 | unsigned long pad1; /* pad out to 48 words total */ | 59 | unsigned long pad1; /* pad out to 48 words total */ |
59 | unsigned long pad2; /* pad out to 48 words total */ | 60 | unsigned long pad2; /* pad out to 48 words total */ |
60 | unsigned long pad3; /* pad out to 48 words total */ | 61 | unsigned long pad3; /* pad out to 48 words total */ |
62 | #else | ||
63 | unsigned long cs0; | ||
64 | unsigned long cs1; | ||
65 | unsigned long pad1; /* pad out to 48 words total */ | ||
66 | #endif | ||
61 | }; | 67 | }; |
62 | 68 | ||
63 | #endif | 69 | #endif |
diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c index 2d5e84d3b00d..181515ba825d 100644 --- a/arch/hexagon/kernel/asm-offsets.c +++ b/arch/hexagon/kernel/asm-offsets.c | |||
@@ -44,7 +44,8 @@ int main(void) | |||
44 | 44 | ||
45 | COMMENT("Hexagon pt_regs definitions"); | 45 | COMMENT("Hexagon pt_regs definitions"); |
46 | OFFSET(_PT_SYSCALL_NR, pt_regs, syscall_nr); | 46 | OFFSET(_PT_SYSCALL_NR, pt_regs, syscall_nr); |
47 | OFFSET(_PT_UGPGP, pt_regs, ugpgp); | 47 | OFFSET(_PT_GPUGP, pt_regs, gpugp); |
48 | OFFSET(_PT_CS1CS0, pt_regs, cs1cs0); | ||
48 | OFFSET(_PT_R3130, pt_regs, r3130); | 49 | OFFSET(_PT_R3130, pt_regs, r3130); |
49 | OFFSET(_PT_R2928, pt_regs, r2928); | 50 | OFFSET(_PT_R2928, pt_regs, r2928); |
50 | OFFSET(_PT_R2726, pt_regs, r2726); | 51 | OFFSET(_PT_R2726, pt_regs, r2726); |
diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c index 344645370646..19f9e6ca5e33 100644 --- a/arch/hexagon/kernel/kgdb.c +++ b/arch/hexagon/kernel/kgdb.c | |||
@@ -70,6 +70,8 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { | |||
70 | { "lc1", GDB_SIZEOF_REG, offsetof(struct pt_regs, lc1)}, | 70 | { "lc1", GDB_SIZEOF_REG, offsetof(struct pt_regs, lc1)}, |
71 | { " gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp)}, | 71 | { " gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp)}, |
72 | { "ugp", GDB_SIZEOF_REG, offsetof(struct pt_regs, ugp)}, | 72 | { "ugp", GDB_SIZEOF_REG, offsetof(struct pt_regs, ugp)}, |
73 | { "cs0", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs0)}, | ||
74 | { "cs1", GDB_SIZEOF_REG, offsetof(struct pt_regs, cs1)}, | ||
73 | { "psp", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmpsp)}, | 75 | { "psp", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmpsp)}, |
74 | { "elr", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmel)}, | 76 | { "elr", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmel)}, |
75 | { "est", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmest)}, | 77 | { "est", GDB_SIZEOF_REG, offsetof(struct pt_regs, hvmer.vmest)}, |
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index 670b1b0bee63..3982d9c9ec2b 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c | |||
@@ -76,6 +76,10 @@ static int genregs_get(struct task_struct *target, | |||
76 | dummy = pt_cause(regs); | 76 | dummy = pt_cause(regs); |
77 | ONEXT(&dummy, cause); | 77 | ONEXT(&dummy, cause); |
78 | ONEXT(&pt_badva(regs), badva); | 78 | ONEXT(&pt_badva(regs), badva); |
79 | #if CONFIG_HEXAGON_ARCH_VERSION >=4 | ||
80 | ONEXT(®s->cs0, cs0); | ||
81 | ONEXT(®s->cs1, cs1); | ||
82 | #endif | ||
79 | 83 | ||
80 | /* Pad the rest with zeros, if needed */ | 84 | /* Pad the rest with zeros, if needed */ |
81 | if (!ret) | 85 | if (!ret) |
@@ -123,6 +127,11 @@ static int genregs_set(struct task_struct *target, | |||
123 | INEXT(&bucket, cause); | 127 | INEXT(&bucket, cause); |
124 | INEXT(&bucket, badva); | 128 | INEXT(&bucket, badva); |
125 | 129 | ||
130 | #if CONFIG_HEXAGON_ARCH_VERSION >=4 | ||
131 | INEXT(®s->cs0, cs0); | ||
132 | INEXT(®s->cs1, cs1); | ||
133 | #endif | ||
134 | |||
126 | /* Ignore the rest, if needed */ | 135 | /* Ignore the rest, if needed */ |
127 | if (!ret) | 136 | if (!ret) |
128 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | 137 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, |
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index 60fa2ca3202b..a1492a69752b 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c | |||
@@ -66,7 +66,10 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
66 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); | 66 | err |= __put_user(regs->preds, &sc->sc_regs.p3_0); |
67 | err |= __put_user(regs->gp, &sc->sc_regs.gp); | 67 | err |= __put_user(regs->gp, &sc->sc_regs.gp); |
68 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); | 68 | err |= __put_user(regs->ugp, &sc->sc_regs.ugp); |
69 | 69 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
70 | err |= __put_user(regs->cs0, &sc->sc_regs.cs0); | ||
71 | err |= __put_user(regs->cs1, &sc->sc_regs.cs1); | ||
72 | #endif | ||
70 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); | 73 | tmp = pt_elr(regs); err |= __put_user(tmp, &sc->sc_regs.pc); |
71 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); | 74 | tmp = pt_cause(regs); err |= __put_user(tmp, &sc->sc_regs.cause); |
72 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); | 75 | tmp = pt_badva(regs); err |= __put_user(tmp, &sc->sc_regs.badva); |
@@ -93,7 +96,10 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
93 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); | 96 | err |= __get_user(regs->preds, &sc->sc_regs.p3_0); |
94 | err |= __get_user(regs->gp, &sc->sc_regs.gp); | 97 | err |= __get_user(regs->gp, &sc->sc_regs.gp); |
95 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); | 98 | err |= __get_user(regs->ugp, &sc->sc_regs.ugp); |
96 | 99 | #if CONFIG_HEXAGON_ARCH_VERSION >= 4 | |
100 | err |= __get_user(regs->cs0, &sc->sc_regs.cs0); | ||
101 | err |= __get_user(regs->cs1, &sc->sc_regs.cs1); | ||
102 | #endif | ||
97 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); | 103 | err |= __get_user(tmp, &sc->sc_regs.pc); pt_set_elr(regs, tmp); |
98 | 104 | ||
99 | return err; | 105 | return err; |
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 425e50c694f7..ffe4a424b706 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S | |||
@@ -45,48 +45,88 @@ | |||
45 | * number in the case where we decode a system call (trap0(#1)). | 45 | * number in the case where we decode a system call (trap0(#1)). |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
48 | #define save_pt_regs()\ | 49 | #define save_pt_regs()\ |
49 | memd(R0 + #_PT_R3130) = R31:30; \ | 50 | memd(R0 + #_PT_R3130) = R31:30; \ |
51 | { memw(R0 + #_PT_R2928) = R28; \ | ||
52 | R31 = memw(R0 + #_PT_ER_VMPSP); }\ | ||
53 | { memw(R0 + #(_PT_R2928 + 4)) = R31; \ | ||
54 | R31 = ugp; } \ | ||
55 | { memd(R0 + #_PT_R2726) = R27:26; \ | ||
56 | R30 = gp ; } \ | ||
57 | memd(R0 + #_PT_R2524) = R25:24; \ | ||
58 | memd(R0 + #_PT_R2322) = R23:22; \ | ||
59 | memd(R0 + #_PT_R2120) = R21:20; \ | ||
60 | memd(R0 + #_PT_R1918) = R19:18; \ | ||
61 | memd(R0 + #_PT_R1716) = R17:16; \ | ||
62 | memd(R0 + #_PT_R1514) = R15:14; \ | ||
63 | memd(R0 + #_PT_R1312) = R13:12; \ | ||
64 | { memd(R0 + #_PT_R1110) = R11:10; \ | ||
65 | R15 = lc0; } \ | ||
66 | { memd(R0 + #_PT_R0908) = R9:8; \ | ||
67 | R14 = sa0; } \ | ||
68 | { memd(R0 + #_PT_R0706) = R7:6; \ | ||
69 | R13 = lc1; } \ | ||
70 | { memd(R0 + #_PT_R0504) = R5:4; \ | ||
71 | R12 = sa1; } \ | ||
72 | { memd(R0 + #_PT_GPUGP) = R31:30; \ | ||
73 | R11 = m1; \ | ||
74 | R2.H = #HI(_THREAD_SIZE); } \ | ||
75 | { memd(R0 + #_PT_LC0SA0) = R15:14; \ | ||
76 | R10 = m0; \ | ||
77 | R2.L = #LO(_THREAD_SIZE); } \ | ||
78 | { memd(R0 + #_PT_LC1SA1) = R13:12; \ | ||
79 | R15 = p3:0; \ | ||
80 | R2 = neg(R2); } \ | ||
81 | { memd(R0 + #_PT_M1M0) = R11:10; \ | ||
82 | R14 = usr; \ | ||
83 | R2 = and(R0,R2); } \ | ||
84 | { memd(R0 + #_PT_PREDSUSR) = R15:14; \ | ||
85 | THREADINFO_REG = R2; } \ | ||
86 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ | ||
87 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ | ||
88 | R2 = #-1; } \ | ||
89 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ | ||
90 | R30 = #0; } | ||
91 | #else | ||
92 | /* V4+ */ | ||
93 | /* the # ## # syntax inserts a literal ## */ | ||
94 | #define save_pt_regs()\ | ||
95 | { memd(R0 + #_PT_R3130) = R31:30; \ | ||
96 | R30 = memw(R0 + #_PT_ER_VMPSP); }\ | ||
50 | { memw(R0 + #_PT_R2928) = R28; \ | 97 | { memw(R0 + #_PT_R2928) = R28; \ |
51 | R31 = memw(R0 + #_PT_ER_VMPSP); }\ | 98 | memw(R0 + #(_PT_R2928 + 4)) = R30; }\ |
52 | { memw(R0 + #(_PT_R2928 + 4)) = R31; \ | 99 | { R31:30 = C11:10; \ |
53 | R31 = ugp; } \ | 100 | memd(R0 + #_PT_R2726) = R27:26; \ |
54 | { memd(R0 + #_PT_R2726) = R27:26; \ | 101 | memd(R0 + #_PT_R2524) = R25:24; }\ |
55 | R30 = gp ; } \ | 102 | { memd(R0 + #_PT_R2322) = R23:22; \ |
56 | memd(R0 + #_PT_R2524) = R25:24; \ | 103 | memd(R0 + #_PT_R2120) = R21:20; }\ |
57 | memd(R0 + #_PT_R2322) = R23:22; \ | 104 | { memd(R0 + #_PT_R1918) = R19:18; \ |
58 | memd(R0 + #_PT_R2120) = R21:20; \ | 105 | memd(R0 + #_PT_R1716) = R17:16; }\ |
59 | memd(R0 + #_PT_R1918) = R19:18; \ | 106 | { memd(R0 + #_PT_R1514) = R15:14; \ |
60 | memd(R0 + #_PT_R1716) = R17:16; \ | 107 | memd(R0 + #_PT_R1312) = R13:12; \ |
61 | memd(R0 + #_PT_R1514) = R15:14; \ | 108 | R17:16 = C13:12; }\ |
62 | memd(R0 + #_PT_R1312) = R13:12; \ | ||
63 | { memd(R0 + #_PT_R1110) = R11:10; \ | 109 | { memd(R0 + #_PT_R1110) = R11:10; \ |
64 | R15 = lc0; } \ | 110 | memd(R0 + #_PT_R0908) = R9:8; \ |
65 | { memd(R0 + #_PT_R0908) = R9:8; \ | 111 | R15:14 = C1:0; } \ |
66 | R14 = sa0; } \ | ||
67 | { memd(R0 + #_PT_R0706) = R7:6; \ | 112 | { memd(R0 + #_PT_R0706) = R7:6; \ |
68 | R13 = lc1; } \ | 113 | memd(R0 + #_PT_R0504) = R5:4; \ |
69 | { memd(R0 + #_PT_R0504) = R5:4; \ | 114 | R13:12 = C3:2; } \ |
70 | R12 = sa1; } \ | 115 | { memd(R0 + #_PT_GPUGP) = R31:30; \ |
71 | { memd(R0 + #_PT_UGPGP) = R31:30; \ | 116 | memd(R0 + #_PT_LC0SA0) = R15:14; \ |
72 | R11 = m1; \ | 117 | R11:10 = C7:6; }\ |
73 | R2.H = #HI(_THREAD_SIZE); } \ | 118 | { THREADINFO_REG = and(R0, # ## #-_THREAD_SIZE); \ |
74 | { memd(R0 + #_PT_LC0SA0) = R15:14; \ | 119 | memd(R0 + #_PT_LC1SA1) = R13:12; \ |
75 | R10 = m0; \ | 120 | R15 = p3:0; }\ |
76 | R2.L = #LO(_THREAD_SIZE); } \ | ||
77 | { memd(R0 + #_PT_LC1SA1) = R13:12; \ | ||
78 | R15 = p3:0; \ | ||
79 | R2 = neg(R2); } \ | ||
80 | { memd(R0 + #_PT_M1M0) = R11:10; \ | 121 | { memd(R0 + #_PT_M1M0) = R11:10; \ |
81 | R14 = usr; \ | 122 | memw(R0 + #_PT_PREDSUSR + 4) = R15; }\ |
82 | R2 = and(R0,R2); } \ | ||
83 | { memd(R0 + #_PT_PREDSUSR) = R15:14; \ | ||
84 | THREADINFO_REG = R2; } \ | ||
85 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ | 123 | { r24 = memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS); \ |
86 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ | 124 | memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R0; \ |
87 | R2 = #-1; } \ | 125 | R2 = #-1; } \ |
88 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ | 126 | { memw(R0 + #_PT_SYSCALL_NR) = R2; \ |
127 | memd(R0 + #_PT_CS1CS0) = R17:16; \ | ||
89 | R30 = #0; } | 128 | R30 = #0; } |
129 | #endif | ||
90 | 130 | ||
91 | /* | 131 | /* |
92 | * Restore registers and thread_info.regs state. THREADINFO_REG | 132 | * Restore registers and thread_info.regs state. THREADINFO_REG |
@@ -94,6 +134,7 @@ | |||
94 | * preserved. Don't restore R29 (SP) until later. | 134 | * preserved. Don't restore R29 (SP) until later. |
95 | */ | 135 | */ |
96 | 136 | ||
137 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
97 | #define restore_pt_regs() \ | 138 | #define restore_pt_regs() \ |
98 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ | 139 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ |
99 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ | 140 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ |
@@ -121,11 +162,44 @@ | |||
121 | R23:22 = memd(R0 + #_PT_R2322); } \ | 162 | R23:22 = memd(R0 + #_PT_R2322); } \ |
122 | { R25:24 = memd(R0 + #_PT_R2524); \ | 163 | { R25:24 = memd(R0 + #_PT_R2524); \ |
123 | R27:26 = memd(R0 + #_PT_R2726); } \ | 164 | R27:26 = memd(R0 + #_PT_R2726); } \ |
124 | R31:30 = memd(R0 + #_PT_UGPGP); \ | 165 | R31:30 = memd(R0 + #_PT_GPUGP); \ |
125 | { R28 = memw(R0 + #_PT_R2928); \ | 166 | { R28 = memw(R0 + #_PT_R2928); \ |
126 | ugp = R31; } \ | 167 | ugp = R31; } \ |
127 | { R31:30 = memd(R0 + #_PT_R3130); \ | 168 | { R31:30 = memd(R0 + #_PT_R3130); \ |
128 | gp = R30; } | 169 | gp = R30; } |
170 | #else | ||
171 | /* V4+ */ | ||
172 | #define restore_pt_regs() \ | ||
173 | { memw(THREADINFO_REG + #_THREAD_INFO_PT_REGS) = R24; \ | ||
174 | R15:14 = memd(R0 + #_PT_PREDSUSR); } \ | ||
175 | { R11:10 = memd(R0 + #_PT_M1M0); \ | ||
176 | R13:12 = memd(R0 + #_PT_LC1SA1); \ | ||
177 | p3:0 = R15; } \ | ||
178 | { R15:14 = memd(R0 + #_PT_LC0SA0); \ | ||
179 | R3:2 = memd(R0 + #_PT_R0302); \ | ||
180 | usr = R14; } \ | ||
181 | { R5:4 = memd(R0 + #_PT_R0504); \ | ||
182 | R7:6 = memd(R0 + #_PT_R0706); \ | ||
183 | C7:6 = R11:10; }\ | ||
184 | { R9:8 = memd(R0 + #_PT_R0908); \ | ||
185 | R11:10 = memd(R0 + #_PT_R1110); \ | ||
186 | C3:2 = R13:12; }\ | ||
187 | { R13:12 = memd(R0 + #_PT_R1312); \ | ||
188 | R15:14 = memd(R0 + #_PT_R1514); \ | ||
189 | C1:0 = R15:14; }\ | ||
190 | { R17:16 = memd(R0 + #_PT_R1716); \ | ||
191 | R19:18 = memd(R0 + #_PT_R1918); } \ | ||
192 | { R21:20 = memd(R0 + #_PT_R2120); \ | ||
193 | R23:22 = memd(R0 + #_PT_R2322); } \ | ||
194 | { R25:24 = memd(R0 + #_PT_R2524); \ | ||
195 | R27:26 = memd(R0 + #_PT_R2726); } \ | ||
196 | R31:30 = memd(R0 + #_PT_CS1CS0); \ | ||
197 | { C13:12 = R31:30; \ | ||
198 | R31:30 = memd(R0 + #_PT_GPUGP) ; \ | ||
199 | R28 = memw(R0 + #_PT_R2928); }\ | ||
200 | { C11:10 = R31:30; \ | ||
201 | R31:30 = memd(R0 + #_PT_R3130); } | ||
202 | #endif | ||
129 | 203 | ||
130 | /* | 204 | /* |
131 | * Clears off enough space for the rest of pt_regs; evrec is a part | 205 | * Clears off enough space for the rest of pt_regs; evrec is a part |
@@ -139,6 +213,7 @@ | |||
139 | * Need to save off R0, R1, R2, R3 immediately. | 213 | * Need to save off R0, R1, R2, R3 immediately. |
140 | */ | 214 | */ |
141 | 215 | ||
216 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
142 | #define vm_event_entry(CHandler) \ | 217 | #define vm_event_entry(CHandler) \ |
143 | { \ | 218 | { \ |
144 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ | 219 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ |
@@ -158,6 +233,34 @@ | |||
158 | R1.H = #HI(CHandler); \ | 233 | R1.H = #HI(CHandler); \ |
159 | jump event_dispatch; \ | 234 | jump event_dispatch; \ |
160 | } | 235 | } |
236 | #else | ||
237 | /* V4+ */ | ||
238 | /* turn on I$ prefetch early */ | ||
239 | /* the # ## # syntax inserts a literal ## */ | ||
240 | #define vm_event_entry(CHandler) \ | ||
241 | { \ | ||
242 | R29 = add(R29, #-(_PT_REGS_SIZE)); \ | ||
243 | memd(R29 + #(_PT_R0100 + -_PT_REGS_SIZE)) = R1:0; \ | ||
244 | memd(R29 + #(_PT_R0302 + -_PT_REGS_SIZE)) = R3:2; \ | ||
245 | R0 = usr; \ | ||
246 | } \ | ||
247 | { \ | ||
248 | memw(R29 + #_PT_PREDSUSR) = R0; \ | ||
249 | R0 = setbit(R0, #16); \ | ||
250 | } \ | ||
251 | usr = R0; \ | ||
252 | R1:0 = G1:0; \ | ||
253 | { \ | ||
254 | memd(R29 + #_PT_ER_VMEL) = R1:0; \ | ||
255 | R1 = # ## #(CHandler); \ | ||
256 | R3:2 = G3:2; \ | ||
257 | } \ | ||
258 | { \ | ||
259 | R0 = R29; \ | ||
260 | memd(R29 + #_PT_ER_VMPSP) = R3:2; \ | ||
261 | jump event_dispatch; \ | ||
262 | } | ||
263 | #endif | ||
161 | 264 | ||
162 | .text | 265 | .text |
163 | /* | 266 | /* |
@@ -184,8 +287,10 @@ event_dispatch: | |||
184 | 287 | ||
185 | /* "Nested control path" -- if the previous mode was kernel */ | 288 | /* "Nested control path" -- if the previous mode was kernel */ |
186 | R0 = memw(R29 + #_PT_ER_VMEST); | 289 | R0 = memw(R29 + #_PT_ER_VMEST); |
187 | P0 = tstbit(R0, #HVM_VMEST_UM_SFT); | 290 | { |
188 | if !P0 jump restore_all; | 291 | P0 = tstbit(R0, #HVM_VMEST_UM_SFT); |
292 | if (!P0.new) jump:nt restore_all; | ||
293 | } | ||
189 | /* | 294 | /* |
190 | * Returning from system call, normally coming back from user mode | 295 | * Returning from system call, normally coming back from user mode |
191 | */ | 296 | */ |
@@ -198,11 +303,18 @@ return_from_syscall: | |||
198 | * Coming back from the C-world, our thread info pointer | 303 | * Coming back from the C-world, our thread info pointer |
199 | * should be in the designated register (usually R19) | 304 | * should be in the designated register (usually R19) |
200 | */ | 305 | */ |
306 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
201 | R1.L = #LO(_TIF_ALLWORK_MASK) | 307 | R1.L = #LO(_TIF_ALLWORK_MASK) |
202 | { | 308 | { |
203 | R1.H = #HI(_TIF_ALLWORK_MASK); | 309 | R1.H = #HI(_TIF_ALLWORK_MASK); |
204 | R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); | 310 | R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); |
205 | } | 311 | } |
312 | #else | ||
313 | { | ||
314 | R1 = ##_TIF_ALLWORK_MASK; | ||
315 | R0 = memw(THREADINFO_REG + #_THREAD_INFO_FLAGS); | ||
316 | } | ||
317 | #endif | ||
206 | 318 | ||
207 | /* | 319 | /* |
208 | * Compare against the "return to userspace" _TIF_WORK_MASK | 320 | * Compare against the "return to userspace" _TIF_WORK_MASK |
@@ -222,10 +334,14 @@ work_pending: | |||
222 | work_notifysig: | 334 | work_notifysig: |
223 | /* this is the part that's kind of fuzzy. */ | 335 | /* this is the part that's kind of fuzzy. */ |
224 | R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)); | 336 | R1 = and(R0, #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME)); |
225 | P0 = cmp.eq(R1, #0); | 337 | { |
226 | if P0 jump restore_all | 338 | P0 = cmp.eq(R1, #0); |
227 | R1 = R0; /* unsigned long thread_info_flags */ | 339 | if P0.new jump:t restore_all; |
228 | R0 = R29; /* regs should still be at top of stack */ | 340 | } |
341 | { | ||
342 | R1 = R0; /* unsigned long thread_info_flags */ | ||
343 | R0 = R29; /* regs should still be at top of stack */ | ||
344 | } | ||
229 | call do_notify_resume | 345 | call do_notify_resume |
230 | 346 | ||
231 | restore_all: | 347 | restore_all: |
@@ -235,14 +351,23 @@ restore_all: | |||
235 | 351 | ||
236 | /* do the setregs here for VM 0.5 */ | 352 | /* do the setregs here for VM 0.5 */ |
237 | /* R29 here should already be pointing at pt_regs */ | 353 | /* R29 here should already be pointing at pt_regs */ |
238 | R1:0 = memd(R29 + #_PT_ER_VMEL); | 354 | { |
239 | R3:2 = memd(R29 + #_PT_ER_VMPSP); | 355 | R1:0 = memd(R29 + #_PT_ER_VMEL); |
356 | R3:2 = memd(R29 + #_PT_ER_VMPSP); | ||
357 | } | ||
358 | #if CONFIG_HEXAGON_ARCH_VERSION < 4 | ||
240 | trap1(#HVM_TRAP1_VMSETREGS); | 359 | trap1(#HVM_TRAP1_VMSETREGS); |
360 | #else | ||
361 | G1:0 = R1:0; | ||
362 | G3:2 = R3:2; | ||
363 | #endif | ||
241 | 364 | ||
242 | R0 = R29 | 365 | R0 = R29 |
243 | restore_pt_regs() | 366 | restore_pt_regs() |
244 | R1:0 = memd(R29 + #_PT_R0100); | 367 | { |
245 | R29 = add(R29, #_PT_REGS_SIZE); | 368 | R1:0 = memd(R29 + #_PT_R0100); |
369 | R29 = add(R29, #_PT_REGS_SIZE); | ||
370 | } | ||
246 | trap1(#HVM_TRAP1_VMRTE) | 371 | trap1(#HVM_TRAP1_VMRTE) |
247 | /* Notreached */ | 372 | /* Notreached */ |
248 | 373 | ||
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c index 9b5a4a295a68..5b81bacf7125 100644 --- a/arch/hexagon/kernel/vm_events.c +++ b/arch/hexagon/kernel/vm_events.c | |||
@@ -42,6 +42,8 @@ void show_regs(struct pt_regs *regs) | |||
42 | regs->lc1, regs->sa1, regs->m1); | 42 | regs->lc1, regs->sa1, regs->m1); |
43 | printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n", | 43 | printk(KERN_EMERG "gp: \t0x%08lx ugp: 0x%08lx usr: 0x%08lx\n", |
44 | regs->gp, regs->ugp, regs->usr); | 44 | regs->gp, regs->ugp, regs->usr); |
45 | printk(KERN_EMERG "cs0: \t0x%08lx cs1: 0x%08lx\n", | ||
46 | regs->cs0, regs->cs1); | ||
45 | printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00, | 47 | printk(KERN_EMERG "r0: \t0x%08lx %08lx %08lx %08lx\n", regs->r00, |
46 | regs->r01, | 48 | regs->r01, |
47 | regs->r02, | 49 | regs->r02, |