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, Universitaetstrasse 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 const char *kernel_command_line; 39extern coreid_t my_core_id; 40 41bool arch_core_is_bsp(void); 42 43/* 44 * Utility macros. 45 * FIXME: should we move these elsewhere? 46 */ 47 48/** Macro to return the number of entries in a statically-allocated array. */ 49#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) 50 51/// Round up n to the next multiple of size 52#define ROUND_UP(n, size) ((((n) + (size) - 1)) & (~((size) - 1))) 53 54#ifndef min 55#define min(a,b) ((a) < (b) ? (a) : (b)) 56#endif 57#ifndef max 58#define max(a,b) ((a) > (b) ? (a) : (b)) 59#endif 60 61/** 62 * \brief Align block at base_addr with size n to power of two 63 * alignable at its size 64 * 65 * Compute the highest exponent x of n so that 2^x \< n _and_ 66 * the base_addr is aligned at its size. 67 * For example: n = 20, base_addr = 4 => size can be 1, 2 or 4. 68 * Biggest possible block is 4 => x = 2 69 * 70 * \param n Size of the block to split in bytes 71 * \param base_addr Base address of the block to split 72 * 73 * \return Highest exponent (bits) for the blocksize to use next 74 */ 75 76/// Computes the floor of log_2 of the given number 77static inline uint8_t log2flr(uintptr_t num) 78{ 79 uint8_t l = 0; 80 uintptr_t n; 81 for (n = num; n > 1; n >>= 1, l++); 82 return l; 83} 84 85/// Computes the ceiling of log_2 of the given number 86static inline uint8_t log2cl(uintptr_t num) 87{ 88 uint8_t l = log2flr(num); 89 if (num == ((uintptr_t)1) << l) { /* fencepost case */ 90 return l; 91 } else { 92 return l + 1; 93 } 94} 95 96static inline int bitaddralign(size_t n, lpaddr_t base_addr) 97{ 98 int exponent = sizeof(size_t) * NBBY - 1; 99 100 if(n == 0) { 101 return 0; 102 } 103 104 while ((exponent > 0) && ((base_addr % (1UL << exponent)) != 0)){ 105 exponent--; 106 } 107 return((1UL << exponent) > n ? log2flr(n) : exponent); 108} 109 110void wait_cycles(uint64_t duration); 111void kernel_startup_early(void); 112void kernel_startup(void) __attribute__ ((noreturn)); 113 114/** 115 * kernel timeslice in system ticks 116 */ 117extern systime_t kernel_timeslice; 118 119/** 120 * command-line option for kernel timeslice in milliseconds 121 */ 122extern unsigned int config_timeslice; 123 124/** 125 * variable for gating timer interrupts. 126 */ 127extern bool kernel_ticks_enabled; 128 129 130extern lvaddr_t kernel_trace_buf; 131 132extern struct capability monitor_ep; 133 134/* 135 * Variant based on Padraig Brady's implementation 136 * http://www.pixelbeat.org/programming/gcc/static_assert.html 137 */ 138#define ASSERT_CONCAT_(a, b) a##b 139#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b) 140 141/* These can't be used after statements in c89. */ 142#ifdef __COUNTER__ 143 /* Microsoft compiler. */ 144 #define STATIC_ASSERT(e,m) \ 145 enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) } 146#else 147 /* This can't be used twice on the same line so ensure if using in headers 148 * that the headers are not included twice (by wrapping in #ifndef...#endif) 149 * Note it doesn't cause an issue when used on same line of separate modules 150 * compiled with gcc -combine -fwhole-program. */ 151 #define STATIC_ASSERT(e,m) \ 152 enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) } 153#endif 154 155#define STATIC_ASSERT_SIZEOF(tname,n) \ 156 STATIC_ASSERT(sizeof(tname) == n, \ 157 ASSERT_CONCAT("Size mismatch:", tname) \ 158 ) 159 160#define sa_offsetof(x,y) ((size_t)(((void*)&(((x*)0)->y)) - (void*)(x*)0)) 161 162#define STATIC_ASSERT_OFFSETOF(tname, field, offset) \ 163 STATIC_ASSERT(sa_offsetof(tname, field) == offset, \ 164 ASSERT_CONCAT("Offset mismatch:", field) \ 165 ) 166 167#endif // __KERNEL_H 168