source: mainline/kernel/generic/include/context.h@ 2cf8f994

Last change on this file since 2cf8f994 was ed7e057, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 18 months ago

Add functions context_create(), context_replace() and context_swap()

and use them where appropriate, removing context_save() in the process.
Much like in userspace, context_swap() maintains natural control flow
as opposed to context_save()'s return-twice mechanic.

Beyond that, in the future, context_replace() and context_swap()
can be implemented more efficiently than the context_save()/
context_restore() pair. As of now, the original implementation is
retained.

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Jakub Jermar
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 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_generic
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_CONTEXT_H_
36#define KERN_CONTEXT_H_
37
38#include <panic.h>
39#include <trace.h>
40#include <arch/context.h>
41#include <arch/faddr.h>
42
43#define context_set_generic(ctx, _pc, stack, size) \
44 do { \
45 (ctx)->pc = (uintptr_t) (_pc); \
46 (ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
47 } while (0)
48
49extern int context_save_arch(context_t *ctx) __attribute__((returns_twice));
50extern void context_restore_arch(context_t *ctx) __attribute__((noreturn));
51
52/** Restore register context.
53 *
54 * Restore a previously saved register context (including stack pointer) from
55 * a context structure.
56 *
57 * Note that this function does not normally return. Instead, it returns to the
58 * same address as the corresponding call to context_save(), the only difference
59 * being return value.
60 *
61 * @param ctx Context structure.
62 *
63 */
64_NO_TRACE __attribute__((noreturn))
65 static inline void context_restore(context_t *ctx)
66{
67 context_restore_arch(ctx);
68}
69
70/**
71 * Saves current context to the variable pointed to by `self`,
72 * and restores the context denoted by `other`.
73 *
74 * When the `self` context is later restored by another call to
75 * `context_swap()`, the control flow behaves as if the earlier call to
76 * `context_swap()` just returned.
77 */
78_NO_TRACE static inline void context_swap(context_t *self, context_t *other)
79{
80 if (context_save_arch(self))
81 context_restore_arch(other);
82}
83
84_NO_TRACE static inline void context_create(context_t *context,
85 void (*fn)(void), void *stack_base, size_t stack_size)
86{
87 *context = (context_t) { 0 };
88 context_set(context, FADDR(fn), stack_base, stack_size);
89}
90
91__attribute__((noreturn)) static inline void context_replace(void (*fn)(void),
92 void *stack_base, size_t stack_size)
93{
94 context_t ctx;
95 context_create(&ctx, fn, stack_base, stack_size);
96 context_restore(&ctx);
97}
98
99#endif
100
101/** @}
102 */
Note: See TracBrowser for help on using the repository browser.