| /* 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 */ |