156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/* -----------------------------------------------------------------------------
256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Copyright (c) 2011 Ozmo Inc
356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Released under the GNU General Public License Version 2 (GPLv2).
456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * -----------------------------------------------------------------------------
556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#include "ozconfig.h"
756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#ifdef WANT_EVENT_TRACE
856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#include <linux/jiffies.h>
956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#include <linux/uaccess.h>
1056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#include "oztrace.h"
1156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#include "ozevent.h"
1256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
1356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
1456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyunsigned long g_evt_mask = 0xffffffff;
1556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
1656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
1756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#define OZ_MAX_EVTS	2048	/* Must be power of 2 */
1856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris KellyDEFINE_SPINLOCK(g_eventlock);
1956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellystatic int g_evt_in;
2056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellystatic int g_evt_out;
2156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellystatic int g_missed_events;
2256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellystatic struct oz_event g_events[OZ_MAX_EVTS];
2356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
2456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Context: process
2556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
2656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyvoid oz_event_init(void)
2756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly{
2856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	oz_trace("Event tracing initialized\n");
2956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_evt_in = g_evt_out = 0;
3056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_missed_events = 0;
3156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly}
3256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
3356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Context: process
3456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
3556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyvoid oz_event_term(void)
3656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly{
3756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	oz_trace("Event tracing terminated\n");
3856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly}
3956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
4056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Context: any
4156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
4256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyvoid oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4)
4356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly{
4456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	unsigned long irqstate;
4556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	int ix;
4656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	spin_lock_irqsave(&g_eventlock, irqstate);
4756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	ix = (g_evt_in + 1) & (OZ_MAX_EVTS - 1);
4856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (ix != g_evt_out) {
4956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		struct oz_event *e = &g_events[g_evt_in];
5056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->jiffies = jiffies;
5156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->evt = evt;
5256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->ctx1 = ctx1;
5356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->ctx2 = ctx2;
5456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->ctx3 = ctx3;
5556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		e->ctx4 = ctx4;
5656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		g_evt_in = ix;
5756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	} else {
5856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		g_missed_events++;
5956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	}
6056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	spin_unlock_irqrestore(&g_eventlock, irqstate);
6156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly}
6256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
6356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Context: process
6456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
6556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyint oz_events_copy(struct oz_evtlist __user *lst)
6656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly{
6756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	int first;
6856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	int ix;
6956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	struct hdr {
7056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		int count;
7156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		int missed;
7256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	} hdr;
7356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	ix = g_evt_out;
7456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	hdr.count = g_evt_in - ix;
7556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (hdr.count < 0)
7656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		hdr.count += OZ_MAX_EVTS;
7756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (hdr.count > OZ_EVT_LIST_SZ)
7856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		hdr.count = OZ_EVT_LIST_SZ;
7956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	hdr.missed = g_missed_events;
8056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_missed_events = 0;
8156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (copy_to_user((void __user *)lst, &hdr, sizeof(hdr)))
8256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		return -EFAULT;
8356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	first = OZ_MAX_EVTS - ix;
8456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (first > hdr.count)
8556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		first = hdr.count;
8656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (first) {
8756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		int sz = first*sizeof(struct oz_event);
8856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		void __user *p = (void __user *)lst->evts;
8956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		if (copy_to_user(p, &g_events[ix], sz))
9056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly			return -EFAULT;
9156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		if (hdr.count > first) {
9256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly			p = (void __user *)&lst->evts[first];
9356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly			sz = (hdr.count-first)*sizeof(struct oz_event);
9456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly			if (copy_to_user(p, g_events, sz))
9556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly				return -EFAULT;
9656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		}
9756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	}
9856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	ix += hdr.count;
9956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	if (ix >= OZ_MAX_EVTS)
10056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly		ix -= OZ_MAX_EVTS;
10156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_evt_out = ix;
10256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	return 0;
10356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly}
10456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly/*------------------------------------------------------------------------------
10556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly * Context: process
10656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly */
10756ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kellyvoid oz_events_clear(void)
10856ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly{
10956ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	unsigned long irqstate;
11056ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	spin_lock_irqsave(&g_eventlock, irqstate);
11156ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_evt_in = g_evt_out = 0;
11256ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	g_missed_events = 0;
11356ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly	spin_unlock_irqrestore(&g_eventlock, irqstate);
11456ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly}
11556ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly#endif /* WANT_EVENT_TRACE */
11656ff32fe1cf24d624ca4a68a409753fb3fd593f6Chris Kelly
117