Contiki 3.x
stacks.h
1 /*
2  * Copyright (C) 2015, Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef CPU_X86_MM_STACKS_H_
32 #define CPU_X86_MM_STACKS_H_
33 
34 #include "prot-domains.h"
35 
36 #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__NONE
37 #define STACKS_SIZE_INT 0
38 #else
39 /**
40  * The necessary amount of space for the interrupt and exception stacks is
41  * determined by the amount of data pushed on the stack by the CPU when
42  * delivering an interrupt or exception, and by the additional data pushed
43  * on the stack by the interrupt dispatcher. See interrupt.h for more details.
44  */
45 #define STACKS_SIZE_INT (14 * 4)
46 #endif
47 
48 #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING
49 /**
50  * The system call and return dispatchers use this stack, so its size was
51  * determined by observing their behavior. It is possible that the dispatchers
52  * could overflow the stack and overwrite data on the other stacks. An
53  * alternative design that would facilitate detection of such overflows would
54  * place the exception handler stack on a separate page surrounded by guard
55  * bands, but that would consume a substantial amount of additional memory.
56  *
57  * All stack sizes should be a multiple of 4 to accommodate a 4-byte alignment.
58  */
59 #ifdef __clang__
60 #define STACKS_SIZE_EXC 512
61 #else
62 #define STACKS_SIZE_EXC 256
63 #endif
64 #elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__SWSEG
65 #ifdef __clang__
66 #define STACKS_SIZE_EXC 512
67 #else
68 #define STACKS_SIZE_EXC 256
69 #endif
70 #elif X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__TSS
71 /**
72  * This should be large enough to execute the exception handler with the
73  * largest stack requirement: double_fault_handler:
74  * - 1 word for the return address from calling double_fault_handler
75  * - 1 word for the saved frame pointer in double_fault_handler
76  * - 2 words that GCC has been observed to skip on the stack to align it
77  * to a preferred boundary
78  * - 1 word for the return address for calling halt
79  */
80 #define STACKS_SIZE_EXC (STACKS_SIZE_INT + (6 * 4))
81 #else
82 #define STACKS_SIZE_EXC STACKS_SIZE_INT
83 #endif
84 /**
85  * The combined size of the stacks should be an even multiple of the 4K page
86  * size so that they precisely fill some number of pages when paging-based
87  * protection domains are in use. The stacks are arranged contiguously by
88  * the linker scripts. See those and README.md for more details.
89  */
90 #define STACKS_SIZE_MAIN (8192 - (STACKS_SIZE_INT + STACKS_SIZE_EXC))
91 
92 #if !__ASSEMBLER__
93 /**
94  * Stack for exception handlers. Also used for system call and return
95  * dispatchers when paging-based protection domains are enabled.
96  */
97 extern uint8_t stacks_exc[STACKS_SIZE_EXC];
98 /** Stack for interrupt handlers. */
99 extern uint8_t stacks_int[STACKS_SIZE_INT];
100 /** Main C stack. */
101 extern uint8_t stacks_main[STACKS_SIZE_MAIN];
102 
103 #define STACKS_INIT_TOP \
104  ((uintptr_t)stacks_main + STACKS_SIZE_MAIN - \
105  (PROT_DOMAINS_INIT_RET_ADDR_CNT * sizeof(uintptr_t)))
106 
107 #endif
108 
109 #endif /* CPU_X86_MM_STACKS_H_ */