1 /*
2  * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #pragma once
8 
9 #include <config.h>
10 
11 #ifdef ENABLE_SMP_SUPPORT
12 
13 typedef struct nodeInfo {
14     void *stackTop;
15     void *irqStack;
16     /* This is the address (+8 bytes) of the 'Error' register of the user
17      * context of the current thread. This address is designed so that the
18      * 'syscall' trap code can do
19      * movq %gs:16, %rsp
20      * pushq $-1
21      * pushq %rcx (rcx holds NextIP)
22      * pushq %r11 (r11 holds RFLAGS)
23      * etc etc
24      * This value needs to be updated every time we switch to the user
25      */
26     word_t currentThreadUserContext;
27     cpu_id_t index;
28     PAD_TO_NEXT_CACHE_LN(sizeof(void *) + sizeof(void *) + sizeof(word_t) + sizeof(cpu_id_t));
29 } nodeInfo_t;
30 compile_assert(nodeInfoIsCacheSized, (sizeof(nodeInfo_t) % L1_CACHE_LINE_SIZE) == 0)
31 
32 extern nodeInfo_t node_info[CONFIG_MAX_NUM_NODES] ALIGN(L1_CACHE_LINE_SIZE);
33 
34 #ifdef CONFIG_KERNEL_SKIM_WINDOW
35 /* we only need 1 word of scratch space, which we know we will at least get by the size
36  8 of the nodeInfo_t struct so we define this array as char to ensure it is sized correctly.
37  We need each element of the array to be precisely the same size as each element of node_info
38  so that the offset between the element of each array is a constant */
39 extern char nodeSkimScratch[CONFIG_MAX_NUM_NODES][sizeof(nodeInfo_t)] ALIGN(L1_CACHE_LINE_SIZE) VISIBLE SKIM_BSS;
40 compile_assert(nodeInfoAndScratchSameSize, sizeof(node_info) == sizeof(nodeSkimScratch))
41 /* this will be declared in the linker script as the offset between node_info and
42  * nodeSkimScratch */
43 extern char nodeSkimScratchOffset[];
44 #endif
45 
getCurrentCPUIndex(void)46 static inline CONST cpu_id_t getCurrentCPUIndex(void)
47 {
48     cpu_id_t index;
49     asm("movq %%gs:%c[offset], %[result]"
50         : [result] "=r"(index)
51         : [offset] "i"(OFFSETOF(nodeInfo_t, index)));
52     return index;
53 }
54 
55 BOOT_CODE void
56 mode_init_tls(cpu_id_t cpu_index);
57 
58 #endif /* ENABLE_SMP_SUPPORT */
59