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