1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/* SPDX-License-Identifier: copyleft-next-0.3.1 */
/* Copyright 2021 - 2022, Kim Kuparinen < kimi.h.kuparinen@gmail.com > */
/**
* @file asm-offsets.c
* riscv64 file used to generate offsets to register slots in stack. Used by
* _save_context.
*/
#include <kmi/utils.h>
#include <kmi/uapi.h>
#include "../kernel/regs.h"
/**
* Insert assembly comment with calculated value.
* Largely based on linux
*
* @param sym Name of symbol.
* @param val Value of symbol.
*/
#define DEFINE(sym, val) \
__asm__ volatile ("\n#-> " #sym " %0 " #val "\n" : : "i" (val))
/**
* Insert offset of member in structure.
*
* @param m Member.
* @param s Structure.
*/
#define OFFSETOF(m, s) DEFINE(offsetof_##m, offsetof(s, m))
/**
* Insert size of structure.
*
* @param n Name of structure.
* @param s Structure.
*/
#define SIZEOF(n, s) DEFINE(sizeof_##n, sizeof(s))
/**
* Generate assembly with calculated offsets and sizes.
* See arch/riscv64/gen/source.mk for how the assembly is used.
*/
void asm_offsets()
{
OFFSETOF(ra, struct riscv_regs);
OFFSETOF(sp, struct riscv_regs);
OFFSETOF(tp, struct riscv_regs);
OFFSETOF(gp, struct riscv_regs);
OFFSETOF(t0, struct riscv_regs);
OFFSETOF(t1, struct riscv_regs);
OFFSETOF(t2, struct riscv_regs);
OFFSETOF(s0, struct riscv_regs);
OFFSETOF(s1, struct riscv_regs);
OFFSETOF(a0, struct riscv_regs);
OFFSETOF(a1, struct riscv_regs);
OFFSETOF(a2, struct riscv_regs);
OFFSETOF(a3, struct riscv_regs);
OFFSETOF(a4, struct riscv_regs);
OFFSETOF(a5, struct riscv_regs);
OFFSETOF(a6, struct riscv_regs);
OFFSETOF(a7, struct riscv_regs);
OFFSETOF(s2, struct riscv_regs);
OFFSETOF(s3, struct riscv_regs);
OFFSETOF(s4, struct riscv_regs);
OFFSETOF(s5, struct riscv_regs);
OFFSETOF(s6, struct riscv_regs);
OFFSETOF(s7, struct riscv_regs);
OFFSETOF(s8, struct riscv_regs);
OFFSETOF(s9, struct riscv_regs);
OFFSETOF(s10, struct riscv_regs);
OFFSETOF(s11, struct riscv_regs);
OFFSETOF(t3, struct riscv_regs);
OFFSETOF(t4, struct riscv_regs);
OFFSETOF(t5, struct riscv_regs);
OFFSETOF(t6, struct riscv_regs);
SIZEOF(registers, struct riscv_regs);
OFFSETOF(s, struct sys_ret);
OFFSETOF(ar0, struct sys_ret);
OFFSETOF(ar1, struct sys_ret);
OFFSETOF(ar2, struct sys_ret);
OFFSETOF(ar3, struct sys_ret);
OFFSETOF(ar4, struct sys_ret);
SIZEOF(sys_ret, struct sys_ret);
OFFSETOF(exec, struct tcb);
OFFSETOF(regs, struct tcb);
/* At the moment tcbd is just a single register slot, so this works, but
* if it's expanded in the future I'll need to figure out a way to
* target specific substructure members. */
OFFSETOF(tcbd, struct tcb);
SIZEOF(tcb, struct tcb);
}
|