Annotation of prex-old/sys/arch/arm/arm/context.c, Revision 1.1.1.1
1.1 nbrk 1: /*-
2: * Copyright (c) 2005, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * context.c - context management routines
32: */
33:
34: /*
35: * The context consists of kernel/user mode registers, and
36: * kernel stack. The user mode registers are always saved to the
37: * kernel stack when processor enters kernel mode by H/W or S/W events.
38: *
39: * The user mode registers are located in the interrupt/trap frame
40: * at the top of the kernel stack. Before the control returns to user
41: * mode next time, these register value will be restored automatically.
42: *
43: * All thread owns its context to keep its execution state. The
44: * scheduler will switch the context to change an active thread.
45: */
46:
47: #include <kernel.h>
48: #include <cpu.h>
49: #include <locore.h>
50:
51: /*
52: * Initialize specified context.
53: * @ctx: context id (pointer)
54: * @kstack: kernel stack for the context
55: *
56: * All thread will start at the trap return routine - syscall_ret().
57: * In this time, the interrupt flag is enabled and I/O access
58: * is disabled.
59: */
60: void
61: context_init(context_t ctx, u_long kstack)
62: {
63: struct kern_regs *k;
64: struct cpu_regs *u;
65:
66: ctx->uregs = (struct cpu_regs *)(kstack - sizeof(struct cpu_regs));
67:
68: /* Initialize kernel mode registers */
69: k = &ctx->kregs;
70: k->lr = (u_long)syscall_ret;
71: k->sp = (u_long)ctx->uregs;
72:
73: /* Reset minimum user mode registers */
74: u = ctx->uregs;
75: u->r0 = 0;
76: u->r1 = 0x11111111;
77: u->r2 = 0x22222222;
78: u->r3 = 0x33333333;
79: u->svc_sp = kstack;
80: u->cpsr = PSR_APP_MODE; /* FIQ/IRQ is enabled */
81: }
82:
83: /*
84: * Set data to the specific register stored in context.
85: * @type: register type to be set
86: * @val: register value to be set
87: *
88: * Note: When user mode program counter is set, all register
89: * values except stack pointer are reset to default value.
90: */
91: void
92: context_set(context_t ctx, int type, u_long val)
93: {
94: struct kern_regs *k;
95: struct cpu_regs *u;
96:
97: switch (type) {
98: case CTX_UENTRY: /* User mode program counter */
99: u = ctx->uregs;
100: u->cpsr = PSR_APP_MODE; /* FIQ/IRQ is enabled */
101: u->pc = u->lr = val;
102: break;
103: case CTX_USTACK: /* User mode stack pointer */
104: u = ctx->uregs;
105: u->sp = val;
106: break;
107: case CTX_KENTRY: /* Kernel mode program counter */
108: k = &ctx->kregs;
109: k->lr = (u_long)kernel_thread_entry;
110: k->r4 = val; /* Entry point */
111: break;
112: case CTX_KARG: /* Kernel mode argument */
113: k = &ctx->kregs;
114: k->r5 = val;
115: break;
116: }
117: }
118:
119: /*
120: * Switch to new context
121: *
122: * Kernel mode registers and kernel stack pointer are switched to the
123: * next context.
124: *
125: * We don't use x86 task switch mechanism to minimize the context space.
126: * The system has only one TSS(task state segment), and the context
127: * switching is done by changing the register value in this TSS. Processor
128: * will reload them automatically when it enters to the kernel mode in
129: * next time.
130: *
131: * It is assumed all interrupts are disabled by caller.
132: *
133: * TODO: FPU context is not switched as of now.
134: */
135: void
136: context_switch(context_t prev, context_t next)
137: {
138: cpu_switch(&prev->kregs, &next->kregs);
139: }
140:
141: /*
142: * Save user mode context to handle exceptions.
143: * @exc: exception code passed to the exception handler
144: *
145: * Copy current user mode registers in the kernel stack to the user
146: * mode stack. The user stack pointer is adjusted for this area.
147: * So that the exception handler can get the register state of
148: * the target thread.
149: *
150: * It builds arguments for the exception handler in the following
151: * format.
152: *
153: * void exception_handler(int exc, void *regs);
154: */
155: void
156: context_save(context_t ctx, int exc)
157: {
158: struct cpu_regs *cur, *sav;
159:
160: /* Copy current register context into user mode stack */
161: cur = ctx->uregs;
162: sav = (struct cpu_regs *)(cur->sp - sizeof(struct cpu_regs));
163: memcpy(sav, cur, sizeof(struct cpu_regs));
164:
165: /* Setup arguments for exception handler */
166: cur->sp = (u_long)sav;
167: cur->r0 = exc; /* Argument 1 */
168: cur->r1 = (u_long)sav; /* Argument 2 */
169: cur->r2 = 0xdeadbeef; /* Tag */
170: }
171:
172: /*
173: * Restore register context to return from the exception handler.
174: * @regs: pointer to user mode register context.
175: */
176: void
177: context_restore(context_t ctx, void *regs)
178: {
179: struct cpu_regs *cur;
180:
181: /* Restore user mode context */
182: cur = ctx->uregs;
183: memcpy(cur, regs, sizeof(struct cpu_regs));
184:
185: /* Correct some registers for fail safe */
186: cur->cpsr = PSR_APP_MODE;
187: }
CVSweb