blob: 44327af3a7a58173edec288c0da457864f1154ed [file] [log] [blame] [edit]
/* Copyright (c) 2010-2011 The Regents of the University of California
* Barret Rhoden <brho@cs.berkeley.edu>
* See LICENSE for details.
*
* Kernel interface for event/notification delivery and preemption. */
#ifndef ROS_INC_EVENT_H
#define ROS_INC_EVENT_H
#include <ros/common.h>
#include <ros/atomic.h>
#include <ros/trapframe.h>
/* #include <ros/ucq.h> included below */
/* Event Delivery Flags from the process to the kernel */
#define EVENT_IPI 0x001 /* IPI the vcore (usually with INDIR) */
#define EVENT_NOMSG 0x002 /* just send the bit, not the msg */
#define EVENT_SPAM_PUBLIC 0x004 /* spam the msg to public vcpd mboxes */
#define EVENT_INDIR 0x008 /* send an indirection event to vcore */
#define EVENT_VCORE_PRIVATE 0x010 /* Will go to the private VCPD mbox */
/* Delivery style flags */
#define EVENT_FALLBACK 0x020 /* spam INDIRs if the vcore's offline */
#define EVENT_VCORE_MUST_RUN 0x040 /* Alerts go to a vcore that will run */
#define EVENT_NOTHROTTLE 0x080 /* send all INDIRs (no throttling) */
/* Not seriously used flags */
#define EVENT_ROUNDROBIN 0x100 /* pick a vcore, RR style */
#define EVENT_VCORE_APPRO 0x200 /* send to where the kernel wants */
/* Flags from the program to the 2LS */
#define EVENT_JUSTHANDLEIT 0x400 /* 2LS should handle the ev_q */
#define EVENT_THREAD 0x800 /* spawn thread to handle ev_q */
/* Certain event flags apply to spam/fallback messages */
#define EVENT_SPAM_FLAGS (EVENT_IPI | EVENT_VCORE_MUST_RUN)
/* Event Message Types */
#define EV_NONE 0
#define EV_PREEMPT_PENDING 1
#define EV_GANG_PREMPT_PENDING 2
#define EV_VCORE_PREEMPT 3
#define EV_GANG_RETURN 4
#define EV_USER_IPI 5
#define EV_PAGE_FAULT 6
#define EV_ALARM 7
#define EV_EVENT 8
#define EV_FREE_APPLE_PIE 9
#define EV_SYSCALL 10
#define EV_CHECK_MSGS 11
#define EV_POSIX_SIGNAL 12
#define NR_EVENT_TYPES 25 /* keep me last (and 1 > the last one) */
/* Will probably have dynamic notifications later */
#define MAX_NR_DYN_EVENT 25
#define MAX_NR_EVENT (NR_EVENT_TYPES + MAX_NR_DYN_EVENT)
/* Want to keep this small and generic, but add items as you need them. One
* item some will need is an expiration time, which ought to be put in the 64
* bit arg. Will need tweaking / thought as we come up with events. These are
* what get put on the per-core queue in procdata. */
struct event_msg {
uint16_t ev_type;
uint16_t ev_arg1;
uint32_t ev_arg2;
void *ev_arg3;
uint64_t ev_arg4;
};
/* Including here since ucq.h needs to know about struct event_msg */
#include <ros/ucq.h>
/* Structure for storing / receiving event messages. An overflow causes the
* bit of the event to get set in the bitmap. You can also have just the bit
* sent (and no message). */
struct event_mbox {
struct ucq ev_msgs;
bool ev_check_bits;
uint8_t ev_bitmap[(MAX_NR_EVENT - 1) / 8 + 1];
};
/* The kernel sends messages to this structure, which describes how and where
* to receive messages, including optional IPIs. */
struct event_queue {
struct event_mbox *ev_mbox;
int ev_flags;
bool ev_alert_pending;
uint32_t ev_vcore;
void (*ev_handler)(struct event_queue *);
};
/* Big version, contains storage space for the ev_mbox. Never access the
* internal mbox directly. */
struct event_queue_big {
struct event_mbox *ev_mbox;
int ev_flags;
bool ev_alert_pending;
uint32_t ev_vcore;
void (*ev_handler)(struct event_queue *);
struct event_mbox ev_imbox;
};
/* Vcore state flags. K_LOCK means the kernel is writing */
#define VC_K_LOCK 0x001 /* CASing with the kernel */
#define VC_PREEMPTED 0x002 /* VC is preempted */
#define VC_CAN_RCV_MSG 0x004 /* can receive FALLBACK */
#define VC_UTHREAD_STEALING 0x008 /* Uthread being stolen */
#define VC_SCP_NOVCCTX 0x010 /* can't go into vc ctx */
/* Racy flags, where we don't need the atomics */
#define VC_FPU_SAVED 0x1000 /* valid FPU state in anc */
/* Per-core data about preemptions and notifications */
struct preempt_data {
struct user_context vcore_ctx; /* for preemptions */
struct ancillary_state preempt_anc;
struct user_context uthread_ctx; /* for preempts or notifs */
uintptr_t transition_stack; /* advertised by the user */
uintptr_t vcore_tls_desc; /* advertised by the user */
atomic_t flags;
int rflags; /* racy flags */
bool notif_disabled; /* vcore unwilling to recv*/
bool notif_pending; /* notif k_msg on the way */
struct event_mbox ev_mbox_public; /* can be read remotely */
struct event_mbox ev_mbox_private; /* for this vcore only */
};
#endif /* ROS_INC_EVENT_H */