1/**
2 * \file
3 * \brief Kernel management of dispatchers
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, 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 KERNEL_DISPATCH_H
16#define KERNEL_DISPATCH_H
17
18#include <barrelfish_kpi/cpu.h>
19#include <barrelfish_kpi/dispatcher_shared_arch.h>
20#include <capabilities.h>
21#include <misc.h>
22
23extern uint64_t context_switch_counter;
24
25/**
26 * \brief Structure to hold information regarding AMD SVM
27 */
28struct guest {
29    struct cte          monitor_ep;     ///< The endpoint to the monitor
30    struct cte          ctrl;           ///< The VMKit guest shared data structure
31    struct cte          vmcb;           ///< The physical address of the AMD VMCB
32    lpaddr_t            vspace;         ///< Addresss of Guest VSPACE root
33};
34
35/**
36 * \brief The dispatcher control block.
37 *
38 * This block holds necessary kernel data to control a user-space dispatcher
39 */
40struct dcb {
41    dispatcher_handle_t disp;           ///< User-mode dispatcher frame pointer
42    bool                disabled;       ///< Was dispatcher disabled when last saved?
43    struct cte          cspace;         ///< Cap slot for CSpace
44    lpaddr_t            vspace;         ///< Address of VSpace root
45    struct cte          disp_cte;
46    unsigned int        faults_taken;   ///< # of disabled faults or traps taken
47    /// Indicates whether this domain shall be executed in VM guest mode
48    bool                is_vm_guest;
49    struct guest        guest_desc;     ///< Descriptor of the VM Guest
50    uint64_t            domain_id;      ///< ID of dispatcher's domain
51    systime_t           wakeup_time;    ///< Time to wakeup this dispatcher
52    struct dcb          *wakeup_prev, *wakeup_next; ///< Next/prev in timeout queue
53
54    struct dcb          *next;          ///< Next DCB in schedule
55    struct dcb          *prev;          ///< Previous DCB in schedule
56                                        /// (only valid iff CONFIG_SCHEDULER_RR)
57#if defined(CONFIG_SCHEDULER_RBED)
58    systime_t          release_time, etime, last_dispatch;
59    systime_t          wcet, period, deadline;
60    unsigned short      weight;
61    enum task_type      type;
62#endif
63};
64
65static inline const char *get_disp_name(struct dcb *dcb)
66{
67    struct dispatcher_shared_generic *dst =
68        get_dispatcher_shared_generic(dcb->disp);
69    return dst->name;
70}
71
72void context_switch(struct dcb *dcb);
73
74/// The currently running dispatcher
75extern struct dcb *dcb_current;
76
77void dispatch(struct dcb *dcb) __attribute__ ((noreturn));
78errval_t lmp_can_deliver_payload(struct capability *ep,
79                                 size_t payload_len);
80errval_t lmp_deliver_payload(struct capability *ep, struct dcb *send,
81                             uintptr_t *payload, size_t payload_len,
82                             bool captransfer, bool now);
83errval_t lmp_deliver(struct capability *ep, struct dcb *send,
84                     uintptr_t *payload, size_t payload_len,
85                     capaddr_t send_cptr, uint8_t send_bits, bool give_away);
86
87/// Deliver an empty LMP as a notification
88static inline errval_t lmp_deliver_notification(struct capability *ep)
89{
90    return lmp_deliver_payload(ep, NULL, NULL, 0, false, true);
91}
92
93/// Reset csc
94static inline void dispatch_csc_reset(void)
95{
96    context_switch_counter = 0;
97}
98
99/// Returns csc
100static inline uint64_t dispatch_get_csc(void)
101{
102    return context_switch_counter;
103}
104
105#endif
106