1/**
2 * \file
3 * \brief Kernel control block declarations.
4 */
5
6/*
7 * Copyright (c) 2013, 2014, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef KCB_H
16#define KCB_H
17
18#include <kernel.h>
19#include <capabilities.h>
20#include <barrelfish_kpi/capbits.h>
21#include <irq.h>
22#include <mdb/mdb_tree.h>
23
24struct cte;
25struct dcb;
26
27enum sched_state {
28    SCHED_RR,
29    SCHED_RBED,
30};
31
32/**
33 * this is the memory layout of ObjType_KernelControlBlock
34 * this struct should contain all the persistent state that belongs to a
35 * kernel.
36 */
37struct kcb {
38    bool is_valid; ///< kcb has been initialized by a kernel before
39
40    /// kcb scheduling ring.
41    /// These fields point to the next and previous kcb that should be
42    /// scheduled when we're running multiple kcbs on the same kernel.
43    /// invariant: next == NULL --> prev == NULL
44    /// invariant: next is the next kcb in the ring and prev is the previous
45    ///            kcb in the ring
46    struct kcb *next, *prev;
47
48    /// mdb root node
49    lvaddr_t mdb_root;
50    // XXX: need memory for a rootcn here because we can't have it static in
51    // the kernel data section anymore
52    struct cte init_rootcn;
53
54    /// which scheduler state is valid
55    enum sched_state sched;
56    /// RR scheduler state
57    struct dcb *ring_current;
58    /// RBED scheduler state
59    struct dcb *queue_head, *queue_tail;
60    unsigned int u_hrt, u_srt, w_be, n_be;
61    /// current time since kernel start in timeslices. This is necessary to
62    /// make the scheduler work correctly
63    /// wakeup queue head
64    struct dcb *wakeup_queue_head;
65    /// last value of kernel_now before shutdown/migration
66    //needs to be signed because it's possible to migrate a kcb onto a cpu
67    //driver whose kernel_now > this kcb's kernel_off.
68    int64_t kernel_off;
69
70    uint8_t irq_in_use[NDISPATCH / 8]; // Bitmap of handed out caps.
71    struct cte irq_dispatch[NDISPATCH];
72    // 4 capabilitites for storing ram caps that we would drop, can be
73    // recovered by monitor doing KernelCmd_ClaimRAM.
74    uint8_t pending_ram_in_use;
75    struct RAM pending_ram[4];
76    // TODO: maybe add a shared part which can replace struct core_data?
77};
78
79STATIC_ASSERT(sizeof(struct kcb) <= OBJSIZE_KCB, "struct kcb too big");
80
81///< The kernel control block
82extern struct kcb *kcb_current;
83///< flag that indicates whether kcb scheduling should happen
84extern bool kcb_sched_suspended;
85
86static inline void print_kcb(void)
87{
88    printk(LOG_DEBUG, "kcb contents:\n");
89    printk(LOG_DEBUG, "  next = %p, prev = %p\n",
90            kcb_current->next, kcb_current->prev);
91    printk(LOG_DEBUG, "  mdb_root = 0x%"PRIxLVADDR"\n", kcb_current->mdb_root);
92    printk(LOG_DEBUG, "  queue_head = %p\n", kcb_current->queue_head);
93    printk(LOG_DEBUG, "  queue_tail = %p\n", kcb_current->queue_tail);
94    printk(LOG_DEBUG, "  wakeup_queue_head = %p\n", kcb_current->wakeup_queue_head);
95    printk(LOG_DEBUG, "  u_hrt = %u, u_srt = %u, w_be = %u, n_be = %u\n",
96            kcb_current->u_hrt, kcb_current->u_srt, kcb_current->w_be,
97            kcb_current->n_be);
98    // TODO interrupt state
99}
100
101// XXX: this is from RBED, don't know how to properly have this here -SG
102extern struct dcb *queue_tail;
103static inline void switch_kcb(struct kcb *next)
104{
105    assert (next != NULL);
106    kcb_current = next;
107    mdb_init(kcb_current);
108    // update queue tail to make associated assembly not choke
109    queue_tail = kcb_current->queue_tail;
110}
111
112void kcb_add(struct kcb* new_kcb);
113errval_t kcb_remove(struct kcb *to_remove);
114void kcb_update_core_id(struct kcb *kcb);
115
116#endif
117