~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/tile/kernel/regs_64.S

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2011 Tilera Corporation. All Rights Reserved.
 
3
 *
 
4
 *   This program is free software; you can redistribute it and/or
 
5
 *   modify it under the terms of the GNU General Public License
 
6
 *   as published by the Free Software Foundation, version 2.
 
7
 *
 
8
 *   This program is distributed in the hope that it will be useful, but
 
9
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 
11
 *   NON INFRINGEMENT.  See the GNU General Public License for
 
12
 *   more details.
 
13
 */
 
14
 
 
15
#include <linux/linkage.h>
 
16
#include <asm/system.h>
 
17
#include <asm/ptrace.h>
 
18
#include <asm/asm-offsets.h>
 
19
#include <arch/spr_def.h>
 
20
#include <asm/processor.h>
 
21
 
 
22
/*
 
23
 * See <asm/system.h>; called with prev and next task_struct pointers.
 
24
 * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
 
25
 *
 
26
 * We want to save pc/sp in "prev", and get the new pc/sp from "next".
 
27
 * We also need to save all the callee-saved registers on the stack.
 
28
 *
 
29
 * Intel enables/disables access to the hardware cycle counter in
 
30
 * seccomp (secure computing) environments if necessary, based on
 
31
 * has_secure_computing().  We might want to do this at some point,
 
32
 * though it would require virtualizing the other SPRs under WORLD_ACCESS.
 
33
 *
 
34
 * Since we're saving to the stack, we omit sp from this list.
 
35
 * And for parallels with other architectures, we save lr separately,
 
36
 * in the thread_struct itself (as the "pc" field).
 
37
 *
 
38
 * This code also needs to be aligned with process.c copy_thread()
 
39
 */
 
40
 
 
41
#if CALLEE_SAVED_REGS_COUNT != 24
 
42
# error Mismatch between <asm/system.h> and kernel/entry.S
 
43
#endif
 
44
#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8)
 
45
 
 
46
#define SAVE_REG(r) { st r12, r; addi r12, r12, 8 }
 
47
#define LOAD_REG(r) { ld r, r12; addi r12, r12, 8 }
 
48
#define FOR_EACH_CALLEE_SAVED_REG(f)                                    \
 
49
                                                        f(r30); f(r31); \
 
50
        f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
 
51
        f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
 
52
        f(r48); f(r49); f(r50); f(r51); f(r52);
 
53
 
 
54
STD_ENTRY_SECTION(__switch_to, .sched.text)
 
55
        {
 
56
          move r10, sp
 
57
          st sp, lr
 
58
        }
 
59
        {
 
60
          addli r11, sp, -FRAME_SIZE + 8
 
61
          addli sp, sp, -FRAME_SIZE
 
62
        }
 
63
        {
 
64
          st r11, r10
 
65
          addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
 
66
        }
 
67
        {
 
68
          ld r13, r4   /* Load new sp to a temp register early. */
 
69
          addi r12, sp, 16
 
70
        }
 
71
        FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
 
72
        addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
 
73
        {
 
74
          st r3, sp
 
75
          addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
 
76
        }
 
77
        {
 
78
          st r3, lr
 
79
          addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
 
80
        }
 
81
        {
 
82
          ld lr, r4
 
83
          addi r12, r13, 16
 
84
        }
 
85
        {
 
86
          /* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
 
87
          move sp, r13
 
88
          mtspr SPR_SYSTEM_SAVE_K_0, r2
 
89
        }
 
90
        FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
 
91
.L__switch_to_pc:
 
92
        {
 
93
          addli sp, sp, FRAME_SIZE
 
94
          jrp lr   /* r0 is still valid here, so return it */
 
95
        }
 
96
        STD_ENDPROC(__switch_to)
 
97
 
 
98
/* Return a suitable address for the backtracer for suspended threads */
 
99
STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
 
100
        lnk r0
 
101
        {
 
102
          addli r0, r0, .L__switch_to_pc - .
 
103
          jrp lr
 
104
        }
 
105
        STD_ENDPROC(get_switch_to_pc)
 
106
 
 
107
STD_ENTRY(get_pt_regs)
 
108
        .irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
 
109
                 r8, r9, r10, r11, r12, r13, r14, r15, \
 
110
                 r16, r17, r18, r19, r20, r21, r22, r23, \
 
111
                 r24, r25, r26, r27, r28, r29, r30, r31, \
 
112
                 r32, r33, r34, r35, r36, r37, r38, r39, \
 
113
                 r40, r41, r42, r43, r44, r45, r46, r47, \
 
114
                 r48, r49, r50, r51, r52, tp, sp
 
115
        {
 
116
         st r0, \reg
 
117
         addi r0, r0, 8
 
118
        }
 
119
        .endr
 
120
        {
 
121
         st r0, lr
 
122
         addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
 
123
        }
 
124
        lnk r1
 
125
        {
 
126
         st r0, r1
 
127
         addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
 
128
        }
 
129
        mfspr r1, INTERRUPT_CRITICAL_SECTION
 
130
        shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
 
131
        ori r1, r1, KERNEL_PL
 
132
        {
 
133
         st r0, r1
 
134
         addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
 
135
        }
 
136
        {
 
137
         st r0, zero       /* clear faultnum */
 
138
         addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
 
139
        }
 
140
        {
 
141
         st r0, zero       /* clear orig_r0 */
 
142
         addli r0, r0, -PTREGS_OFFSET_ORIG_R0    /* restore r0 to base */
 
143
        }
 
144
        jrp lr
 
145
        STD_ENDPROC(get_pt_regs)