1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#pragma once
8
9#include <config.h>
10#include <stdint.h>
11#include <util.h>
12#include <sel4/shared_types_gen.h>
13#include <arch/api/types.h>
14#include <arch/types.h>
15#include <sel4/macros.h>
16#include <sel4/constants.h>
17#include <sel4/shared_types.h>
18#include <machine/io.h>
19
20/* seL4_CapRights_t defined in mode/api/shared_types.bf */
21
22typedef word_t prio_t;
23typedef uint64_t ticks_t;
24typedef uint64_t time_t;
25
26enum domainConstants {
27    minDom = 0,
28    maxDom = CONFIG_NUM_DOMAINS - 1
29};
30
31struct cap_transfer {
32    cptr_t ctReceiveRoot;
33    cptr_t ctReceiveIndex;
34    word_t ctReceiveDepth;
35};
36typedef struct cap_transfer cap_transfer_t;
37
38enum ctLimits {
39    capTransferDataSize = 3
40};
41
42static inline seL4_CapRights_t CONST rightsFromWord(word_t w)
43{
44    seL4_CapRights_t seL4_CapRights;
45
46    seL4_CapRights.words[0] = w;
47    return seL4_CapRights;
48}
49
50static inline word_t CONST wordFromRights(seL4_CapRights_t seL4_CapRights)
51{
52    return seL4_CapRights.words[0] & MASK(seL4_CapRightsBits);
53}
54
55static inline cap_transfer_t PURE capTransferFromWords(word_t *wptr)
56{
57    cap_transfer_t transfer;
58
59    transfer.ctReceiveRoot  = (cptr_t)wptr[0];
60    transfer.ctReceiveIndex = (cptr_t)wptr[1];
61    transfer.ctReceiveDepth = wptr[2];
62    return transfer;
63}
64
65static inline seL4_MessageInfo_t CONST messageInfoFromWord_raw(word_t w)
66{
67    seL4_MessageInfo_t mi;
68
69    mi.words[0] = w;
70    return mi;
71}
72
73static inline seL4_MessageInfo_t CONST messageInfoFromWord(word_t w)
74{
75    seL4_MessageInfo_t mi;
76    word_t len;
77
78    mi.words[0] = w;
79
80    len = seL4_MessageInfo_get_length(mi);
81    if (len > seL4_MsgMaxLength) {
82        mi = seL4_MessageInfo_set_length(mi, seL4_MsgMaxLength);
83    }
84
85    return mi;
86}
87
88static inline word_t CONST wordFromMessageInfo(seL4_MessageInfo_t mi)
89{
90    return mi.words[0];
91}
92
93#ifdef CONFIG_PRINTING
94#ifdef CONFIG_COLOUR_PRINTING
95#define ANSI_RESET "\033[0m"
96#define ANSI_GREEN ANSI_RESET "\033[32m"
97#define ANSI_DARK  ANSI_RESET "\033[30;1m"
98#else
99#define ANSI_RESET ""
100#define ANSI_GREEN ANSI_RESET ""
101#define ANSI_DARK  ANSI_RESET ""
102#endif
103
104/*
105 * thread name is only available if the kernel is built in debug mode.
106 */
107#ifdef CONFIG_DEBUG_BUILD
108#define THREAD_NAME TCB_PTR_DEBUG_PTR(NODE_STATE(ksCurThread))->tcbName
109#else
110#define THREAD_NAME ""
111#endif
112
113#ifdef CONFIG_KERNEL_INVOCATION_REPORT_ERROR_IPC
114extern struct debug_syscall_error current_debug_error;
115
116#define out_error(...) \
117    snprintf((char *)current_debug_error.errorMessage, \
118            DEBUG_MESSAGE_MAXLEN * sizeof(word_t), __VA_ARGS__);
119#else
120#define out_error printf
121#endif
122
123/*
124 * Print to serial a message helping userspace programmers to determine why the
125 * kernel is not performing their requested operation.
126 */
127#define userError(M, ...) \
128    do {                                                                     \
129        out_error(ANSI_DARK "<<" ANSI_GREEN "seL4(CPU %lu)" ANSI_DARK        \
130                " [%s/%d T%p \"%s\" @%lx]: " M ">>" ANSI_RESET "\n",         \
131                SMP_TERNARY(getCurrentCPUIndex(), 0lu),                      \
132                __func__, __LINE__, NODE_STATE(ksCurThread),                 \
133                THREAD_NAME,                                                 \
134                (word_t)getRestartPC(NODE_STATE(ksCurThread)),               \
135                ## __VA_ARGS__);                                             \
136    } while (0)
137#else /* !CONFIG_PRINTING */
138#define userError(...)
139#endif
140
141