xref: /openbmc/linux/samples/hid/hid_mouse.bpf.c (revision 6008105b)
1*6008105bSBenjamin Tissoires // SPDX-License-Identifier: GPL-2.0
2*6008105bSBenjamin Tissoires 
3*6008105bSBenjamin Tissoires #include "vmlinux.h"
4*6008105bSBenjamin Tissoires #include <bpf/bpf_helpers.h>
5*6008105bSBenjamin Tissoires #include <bpf/bpf_tracing.h>
6*6008105bSBenjamin Tissoires #include "hid_bpf_helpers.h"
7*6008105bSBenjamin Tissoires 
8*6008105bSBenjamin Tissoires SEC("fmod_ret/hid_bpf_device_event")
BPF_PROG(hid_y_event,struct hid_bpf_ctx * hctx)9*6008105bSBenjamin Tissoires int BPF_PROG(hid_y_event, struct hid_bpf_ctx *hctx)
10*6008105bSBenjamin Tissoires {
11*6008105bSBenjamin Tissoires 	s16 y;
12*6008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
13*6008105bSBenjamin Tissoires 
14*6008105bSBenjamin Tissoires 	if (!data)
15*6008105bSBenjamin Tissoires 		return 0; /* EPERM check */
16*6008105bSBenjamin Tissoires 
17*6008105bSBenjamin Tissoires 	bpf_printk("event: size: %d", hctx->size);
18*6008105bSBenjamin Tissoires 	bpf_printk("incoming event: %02x %02x %02x",
19*6008105bSBenjamin Tissoires 		   data[0],
20*6008105bSBenjamin Tissoires 		   data[1],
21*6008105bSBenjamin Tissoires 		   data[2]);
22*6008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
23*6008105bSBenjamin Tissoires 		   data[3],
24*6008105bSBenjamin Tissoires 		   data[4],
25*6008105bSBenjamin Tissoires 		   data[5]);
26*6008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
27*6008105bSBenjamin Tissoires 		   data[6],
28*6008105bSBenjamin Tissoires 		   data[7],
29*6008105bSBenjamin Tissoires 		   data[8]);
30*6008105bSBenjamin Tissoires 
31*6008105bSBenjamin Tissoires 	y = data[3] | (data[4] << 8);
32*6008105bSBenjamin Tissoires 
33*6008105bSBenjamin Tissoires 	y = -y;
34*6008105bSBenjamin Tissoires 
35*6008105bSBenjamin Tissoires 	data[3] = y & 0xFF;
36*6008105bSBenjamin Tissoires 	data[4] = (y >> 8) & 0xFF;
37*6008105bSBenjamin Tissoires 
38*6008105bSBenjamin Tissoires 	bpf_printk("modified event: %02x %02x %02x",
39*6008105bSBenjamin Tissoires 		   data[0],
40*6008105bSBenjamin Tissoires 		   data[1],
41*6008105bSBenjamin Tissoires 		   data[2]);
42*6008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
43*6008105bSBenjamin Tissoires 		   data[3],
44*6008105bSBenjamin Tissoires 		   data[4],
45*6008105bSBenjamin Tissoires 		   data[5]);
46*6008105bSBenjamin Tissoires 	bpf_printk("                %02x %02x %02x",
47*6008105bSBenjamin Tissoires 		   data[6],
48*6008105bSBenjamin Tissoires 		   data[7],
49*6008105bSBenjamin Tissoires 		   data[8]);
50*6008105bSBenjamin Tissoires 
51*6008105bSBenjamin Tissoires 	return 0;
52*6008105bSBenjamin Tissoires }
53*6008105bSBenjamin Tissoires 
54*6008105bSBenjamin Tissoires SEC("fmod_ret/hid_bpf_device_event")
BPF_PROG(hid_x_event,struct hid_bpf_ctx * hctx)55*6008105bSBenjamin Tissoires int BPF_PROG(hid_x_event, struct hid_bpf_ctx *hctx)
56*6008105bSBenjamin Tissoires {
57*6008105bSBenjamin Tissoires 	s16 x;
58*6008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 9 /* size */);
59*6008105bSBenjamin Tissoires 
60*6008105bSBenjamin Tissoires 	if (!data)
61*6008105bSBenjamin Tissoires 		return 0; /* EPERM check */
62*6008105bSBenjamin Tissoires 
63*6008105bSBenjamin Tissoires 	x = data[1] | (data[2] << 8);
64*6008105bSBenjamin Tissoires 
65*6008105bSBenjamin Tissoires 	x = -x;
66*6008105bSBenjamin Tissoires 
67*6008105bSBenjamin Tissoires 	data[1] = x & 0xFF;
68*6008105bSBenjamin Tissoires 	data[2] = (x >> 8) & 0xFF;
69*6008105bSBenjamin Tissoires 	return 0;
70*6008105bSBenjamin Tissoires }
71*6008105bSBenjamin Tissoires 
72*6008105bSBenjamin Tissoires SEC("fmod_ret/hid_bpf_rdesc_fixup")
BPF_PROG(hid_rdesc_fixup,struct hid_bpf_ctx * hctx)73*6008105bSBenjamin Tissoires int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx)
74*6008105bSBenjamin Tissoires {
75*6008105bSBenjamin Tissoires 	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 4096 /* size */);
76*6008105bSBenjamin Tissoires 
77*6008105bSBenjamin Tissoires 	if (!data)
78*6008105bSBenjamin Tissoires 		return 0; /* EPERM check */
79*6008105bSBenjamin Tissoires 
80*6008105bSBenjamin Tissoires 	bpf_printk("rdesc: %02x %02x %02x",
81*6008105bSBenjamin Tissoires 		   data[0],
82*6008105bSBenjamin Tissoires 		   data[1],
83*6008105bSBenjamin Tissoires 		   data[2]);
84*6008105bSBenjamin Tissoires 	bpf_printk("       %02x %02x %02x",
85*6008105bSBenjamin Tissoires 		   data[3],
86*6008105bSBenjamin Tissoires 		   data[4],
87*6008105bSBenjamin Tissoires 		   data[5]);
88*6008105bSBenjamin Tissoires 	bpf_printk("       %02x %02x %02x ...",
89*6008105bSBenjamin Tissoires 		   data[6],
90*6008105bSBenjamin Tissoires 		   data[7],
91*6008105bSBenjamin Tissoires 		   data[8]);
92*6008105bSBenjamin Tissoires 
93*6008105bSBenjamin Tissoires 	/*
94*6008105bSBenjamin Tissoires 	 * The original report descriptor contains:
95*6008105bSBenjamin Tissoires 	 *
96*6008105bSBenjamin Tissoires 	 * 0x05, 0x01,                    //   Usage Page (Generic Desktop)      30
97*6008105bSBenjamin Tissoires 	 * 0x16, 0x01, 0x80,              //   Logical Minimum (-32767)          32
98*6008105bSBenjamin Tissoires 	 * 0x26, 0xff, 0x7f,              //   Logical Maximum (32767)           35
99*6008105bSBenjamin Tissoires 	 * 0x09, 0x30,                    //   Usage (X)                         38
100*6008105bSBenjamin Tissoires 	 * 0x09, 0x31,                    //   Usage (Y)                         40
101*6008105bSBenjamin Tissoires 	 *
102*6008105bSBenjamin Tissoires 	 * So byte 39 contains Usage X and byte 41 Usage Y.
103*6008105bSBenjamin Tissoires 	 *
104*6008105bSBenjamin Tissoires 	 * We simply swap the axes here.
105*6008105bSBenjamin Tissoires 	 */
106*6008105bSBenjamin Tissoires 	data[39] = 0x31;
107*6008105bSBenjamin Tissoires 	data[41] = 0x30;
108*6008105bSBenjamin Tissoires 
109*6008105bSBenjamin Tissoires 	return 0;
110*6008105bSBenjamin Tissoires }
111*6008105bSBenjamin Tissoires 
112*6008105bSBenjamin Tissoires char _license[] SEC("license") = "GPL";
113