|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/bsp/hal/ppc/arch/context.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.1 /*- 2 * Copyright (c) 2009, 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 kernel 36 * stack. The user mode registers are always saved to the kernel 37 * 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 40 * frame at the top of the kernel stack. Before the control 41 * returns to user mode next time, these register value will be 42 * restored automatically. 43 * 44 * All thread owns its context to keep its execution state. The 45 * scheduler will switch the context to change an active thread. 46 */ 47 48 #include <kernel.h> 49 #include <kmem.h> 50 #include <cpu.h> 51 #include <context.h> 52 #include <locore.h> 53 #include <trap.h> 54 55 /* 56 * Set user mode registers into the specific context. 57 * 58 * Note: When user mode program counter is set, all register 59 * values except a stack pointer are reset to default value. 60 */ 61 void 62 context_set(context_t ctx, int type, register_t val) 63 { 64 struct kern_regs *k; 65 struct cpu_regs *u; 66 uint32_t *argp; 67 68 k = &ctx->kregs; 69 70 switch (type) { 71 case CTX_KSTACK: 72 /* Adjust stack for C code */ 73 val -= STKFRAME_LEN; 74 75 /* Set kernel mode stack pointer */ 76 ctx->uregs = (struct cpu_regs *) 77 ((uint32_t)val - sizeof(struct cpu_regs)); 78 79 k->sp = (uint32_t)ctx->uregs; 80 k->kstack = (uint32_t)val; 81 82 /* Reset minimum user mode registers */ 83 u = ctx->uregs; 84 u->gr[3] = 0x11111111; 85 u->gr[4] = 0x22222222; 86 u->gr[5] = 0x33333333; 87 u->srr1 = MSR_DFLT; 88 break; 89 90 case CTX_KENTRY: 91 /* Kernel mode program counter */ 92 k->lr = (uint32_t)val; 93 break; 94 95 case CTX_KARG: 96 /* Kernel mode argument */ 97 argp = (uint32_t *)(k->sp + sizeof(uint32_t) * 2); 98 *argp = (uint32_t)val; 99 break; 100 101 case CTX_USTACK: 102 /* User mode stack pointer */ 103 u = ctx->uregs; 104 u->gr[1] = (uint32_t)val; 105 break; 106 107 case CTX_UENTRY: 108 /* User mode program counter */ 109 u = ctx->uregs; 110 u->srr0 = (uint32_t)val; 111 u->srr1 = MSR_DFLT; 112 break; 113 114 case CTX_UARG: 115 /* User mode argument */ 116 u = ctx->uregs; 117 u->gr[3] = (uint32_t)val; 118 argp = (uint32_t *)(u->gr[1] + sizeof(uint32_t)); 119 copyout(&val, argp, sizeof(uint32_t)); 120 break; 121 122 default: 123 /* invalid */ 124 break; 125 } 126 } 127 128 /* 129 * Switch to new context 130 * 131 * Kernel mode registers and kernel stack pointer are switched to 132 * the next context. 133 * 134 * It is assumed all interrupts are disabled by caller. 135 * 136 * TODO: FPU context is not switched as of now. 137 */ 138 void 139 context_switch(context_t prev, context_t next) 140 { 141 142 cpu_switch(&prev->kregs, &next->kregs); 143 } 144 145 /* 146 * Save user mode context to handle exceptions. 147 * 148 * Copy current user mode registers in the kernel stack to the 149 * user mode stack. The user stack pointer is adjusted for this 150 * area. So that the exception handler can get the register 151 * state of the target thread. 152 * 153 * It builds arguments for the exception handler in the following 154 * format. 155 * 156 * void exception_handler(int exc, void *regs); 157 */ 158 void 159 context_save(context_t ctx) 160 { 161 struct cpu_regs *cur, *sav; 162 163 /* Copy current register context into user mode stack */ 164 cur = ctx->uregs; 165 sav = (struct cpu_regs *)(cur->gr[1] - sizeof(struct cpu_regs)); 166 copyout(cur, sav, sizeof(*sav)); 167 168 ctx->saved_regs = sav; 169 170 /* Adjust stack pointer */ 171 cur->gr[1] = (uint32_t)sav - sizeof(uint32_t); 172 } 173 174 /* 175 * Restore register context to return from the exception handler. 176 */ 177 void 178 context_restore(context_t ctx) 179 { 180 struct cpu_regs *cur; 181 182 /* Restore user mode context */ 183 cur = ctx->uregs; 184 copyin(ctx->saved_regs, cur, sizeof(*cur)); 185 186 /* Correct some registers for fail safe */ 187 cur->srr1 |= MSR_DFLT; 188 } 189 190 void 191 context_dump(context_t ctx) 192 { 193 194 #ifdef DEBUG 195 trap_dump(ctx->uregs); 196 #endif 197 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |