1/**
2 * \file
3 * \brief Standard headers for kernel code.
4 *
5 * All C source in the kernel should include this file first.
6 * This file should contain only definitions and prototypes that are
7 * required for the majority of kernel code.
8 */
9
10/*
11 * Copyright (c) 2007, 2008, 2009, 2010, 2016, ETH Zurich.
12 * All rights reserved.
13 *
14 * This file is distributed under the terms in the attached LICENSE file.
15 * If you do not find this file, copies can be found by writing to:
16 * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
17 */
18
19#ifndef __KERNEL_H
20#define __KERNEL_H
21
22#include <assert.h>
23#include <stddef.h>
24#include <stdio.h> // printf for debug
25#include <stdint.h>
26#include <inttypes.h>
27#include <stdbool.h>
28#include <barrelfish_kpi/types.h>
29#include <barrelfish_kpi/cpu.h>
30#include <barrelfish_kpi/registers_arch.h>
31#include <errors/errno.h>
32#include <bitmacros.h>
33#include <debug.h>
34#include <offsets.h> /* XXX */
35#include <schedule.h>
36#include <logging.h>
37
38extern coreid_t my_core_id;
39
40bool arch_core_is_bsp(void);
41
42/*
43 * Utility macros.
44 * FIXME: should we move these elsewhere?
45 */
46
47/** Macro to return the number of entries in a statically-allocated array. */
48#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
49
50/// Round up n to the next multiple of size
51#define ROUND_UP(n, size)           ((((n) + (size) - 1)) & (~((size) - 1)))
52
53#ifndef min
54#define min(a,b) ((a) < (b) ? (a) : (b))
55#endif
56#ifndef max
57#define max(a,b) ((a) > (b) ? (a) : (b))
58#endif
59
60/**
61 * \brief Align block at base_addr with size n to power of two
62 * alignable at its size
63 *
64 * Compute the highest exponent x of n so that 2^x \< n _and_
65 * the base_addr is aligned at its size.
66 * For example: n = 20, base_addr = 4 => size can be 1, 2 or 4.
67 * Biggest possible block is 4 => x = 2
68 *
69 * \param n         Size of the block to split in bytes
70 * \param base_addr Base address of the block to split
71 *
72 * \return Highest exponent (bits) for the blocksize to use next
73 */
74
75/// Computes the floor of log_2 of the given number
76static inline uint8_t log2flr(uintptr_t num)
77{
78    uint8_t l = 0;
79    uintptr_t n;
80    for (n = num; n > 1; n >>= 1, l++);
81    return l;
82}
83
84/// Computes the ceiling of log_2 of the given number
85static inline uint8_t log2cl(uintptr_t num)
86{
87    uint8_t l = log2flr(num);
88    if (num == ((uintptr_t)1) << l) { /* fencepost case */
89        return l;
90    } else {
91        return l + 1;
92    }
93}
94
95static inline int bitaddralign(size_t n, lpaddr_t base_addr)
96{
97    int exponent = sizeof(size_t) * NBBY - 1;
98
99    if(n == 0) {
100        return 0;
101    }
102
103    while ((exponent > 0) && ((base_addr % (1UL << exponent)) != 0)){
104        exponent--;
105    }
106    return((1UL << exponent) > n ? log2flr(n) : exponent);
107}
108
109void wait_cycles(uint64_t duration);
110void kernel_startup_early(void);
111void kernel_startup(void) __attribute__ ((noreturn));
112
113/**
114 * kernel timeslice in system ticks
115 */
116extern systime_t kernel_timeslice;
117
118/**
119 * command-line option for kernel timeslice in milliseconds
120 */
121extern unsigned int config_timeslice;
122
123/**
124 * variable for gating timer interrupts.
125 */
126extern bool kernel_ticks_enabled;
127
128
129extern lvaddr_t kernel_trace_buf;
130
131extern struct capability monitor_ep;
132
133/*
134 * Variant based on Padraig Brady's implementation
135 * http://www.pixelbeat.org/programming/gcc/static_assert.html
136 */
137#define ASSERT_CONCAT_(a, b) a##b
138#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
139
140/* These can't be used after statements in c89. */
141#ifdef __COUNTER__
142  /* Microsoft compiler. */
143  #define STATIC_ASSERT(e,m) \
144    enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
145#else
146  /* This can't be used twice on the same line so ensure if using in headers
147   * that the headers are not included twice (by wrapping in #ifndef...#endif)
148   * Note it doesn't cause an issue when used on same line of separate modules
149   * compiled with gcc -combine -fwhole-program.  */
150  #define STATIC_ASSERT(e,m) \
151    enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
152#endif
153
154#define STATIC_ASSERT_SIZEOF(tname,n)                   \
155    STATIC_ASSERT(sizeof(tname) == n,                   \
156        ASSERT_CONCAT("Size mismatch:", tname)          \
157        )
158
159#define sa_offsetof(x,y) ((size_t)(((void*)&(((x*)0)->y)) - (void*)(x*)0))
160
161#define STATIC_ASSERT_OFFSETOF(tname, field, offset)    \
162    STATIC_ASSERT(sa_offsetof(tname, field) == offset,    \
163        ASSERT_CONCAT("Offset mismatch:", field)        \
164        )
165
166#endif // __KERNEL_H
167