static void segv_sigaction(int num, siginfo_t *info, void *ctx)
{
+ extern char _init, _end;
struct ucontext *context = ctx;
u32 *regs = (u32 *)&context->uc_mcontext.arm_r0;
u32 *pc = (u32 *)regs[15];
+ u32 self_start, self_end;
struct op_context *op_ctx;
int i, lp_size;
- if (((regs[15] ^ (u32)&segv_sigaction) & 0xff000000) == 0 || // PC is in our segment or
+ self_start = (u32)&_init & ~0xfff;
+ self_end = (u32)&_end;
+
+ if ((self_start <= regs[15] && regs[15] <= self_end) || // PC is in our segment or
(((regs[15] ^ (u32)g_linkpage) & ~(LINKPAGE_ALLOC - 1)) == 0) || // .. in linkpage
((long)info->si_addr & 0xffe00000) != 0x7f000000) // faulting not where expected
{
return -EINVAL;
}
+static const char wm97xx_p[] =
+ "5507 0 -831476 0 -4218 16450692 65536"; // from 4.0 fw
+
long emu_do_read(int fd, void *buf, int count)
{
- static const char wm97xx_p[] =
- "5507 0 -831476 0 -4218 16450692 65536"; // from 4.0 fw
int ret, pressed = 0, x, y;
struct {
u16 pressure, x, y;
case FAKEDEV_WM97XX:
ret = host_read_ts(&pressed, &x, &y);
if (ret == 0 && pressed) {
- wm97xx.pressure = 1;
+ wm97xx.pressure = 0x8001; // TODO: check the real thing
wm97xx.x = x * 3750 / 1024 + 200;
wm97xx.y = 3750 - y * 3750 / 1024 + 200;
}
strncpy(buf, wm97xx_p, count);
break;
default:
- err("read(%d, %d)\n", fd, count);
+ dbg("read(%d, %d)\n", fd, count);
return -EINVAL;
}
return count;
const char *w_path;
FILE *ret;
- w_path = emu_wrap_path(path);
- ret = fopen(w_path, mode);
- emu_wrap_path_free(w_path, path);
+ if (strcmp(path, "/etc/pointercal") == 0) {
+ // use local pontercal, not host's
+ ret = fopen("pointercal", mode);
+ if (ret == NULL) {
+ ret = fopen("pointercal", "w");
+ if (ret != NULL) {
+ fwrite(wm97xx_p, 1, sizeof(wm97xx_p), ret);
+ fclose(ret);
+ }
+ ret = fopen("pointercal", mode);
+ }
+ }
+ else {
+ w_path = emu_wrap_path(path);
+ ret = fopen(w_path, mode);
+ emu_wrap_path_free(w_path, path);
+ }
return ret;
}