X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=ginge.git;a=blobdiff_plain;f=loader%2Femu.c;h=8234a1462def19c9061be3705b1cd2b93d63febf;hp=38fea460a56c68a312a48e812b0266d743d60edb;hb=6c888740e36d8ec83c68f35c5f14b8f698db7a2b;hpb=7868435641e4209e956a591ff0844afc14f83f16 diff --git a/loader/emu.c b/loader/emu.c index 38fea46..8234a14 100644 --- a/loader/emu.c +++ b/loader/emu.c @@ -916,13 +916,18 @@ static void init_linkpage(void) 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 { @@ -1059,20 +1064,6 @@ void emu_init(void *map_bottom) sigaction(SIGSEGV, &segv_action, NULL); } -long emu_read_gpiodev(void *buf, int count) -{ - if (count <= 0) { - err("gpiodev read %d?\n", count); - return -EINVAL; - } - if (count > 4) - count = 4; - - mmsp2.btn_state = host_read_btns(); - memcpy(buf, &mmsp2.btn_state, count); - return count; -} - static long emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int offset) { u8 *umem, *umem_end; @@ -1273,6 +1264,57 @@ fail: 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) +{ + int ret, pressed = 0, x, y; + struct { + u16 pressure, x, y; + } wm97xx; + + if (count < 0) { + err("read(%d, %d)\n", fd, count); + return -EINVAL; + } + + switch (fd) { + case FAKEDEV_GPIO: + mmsp2.btn_state = host_read_btns(); + + if (count > 4) + count = 4; + memcpy(buf, &mmsp2.btn_state, count); + break; + case FAKEDEV_WM97XX: + ret = host_read_ts(&pressed, &x, &y); + if (ret == 0 && pressed) { + wm97xx.pressure = 0x8001; // TODO: check the real thing + wm97xx.x = x * 3750 / 1024 + 200; + wm97xx.y = 3750 - y * 3750 / 1024 + 200; + } + else { + wm97xx.pressure = 0; + wm97xx.x = wm97xx.y = 200; + } + + if (count > sizeof(wm97xx)) + count = sizeof(wm97xx); + memcpy(buf, &wm97xx, count); + break; + case FAKEDEV_WM97XX_P: + if (count < sizeof(wm97xx_p)) + err("incomplete pointercal read\n"); + strncpy(buf, wm97xx_p, count); + break; + default: + dbg("read(%d, %d)\n", fd, count); + return -EINVAL; + } + return count; +} + struct dev_fd_t emu_interesting_fds[] = { [IFD_SOUND] = { "/dev/dsp", -1, emu_sound_open }, { NULL, 0, NULL }, @@ -1283,13 +1325,15 @@ static const struct { const char *to; } path_map[] = { { "/mnt/tmp", "./tmp" }, + { "/mnt/sd", "./mntsd" }, }; -static const char *wrap_path(const char *path) +const char *emu_wrap_path(const char *path) { char *buff, *p; size_t size; int i, len; + long ret; // do only path mapping for now for (i = 0; i < ARRAY_SIZE(path_map); i++) { @@ -1304,6 +1348,11 @@ static const char *wrap_path(const char *path) snprintf(buff + len, size - len, "%s%s", path_map[i].to, path + len + strlen(path_map[i].from)); dbg("mapped path \"%s\" -> \"%s\"\n", path, buff); + + ret = g_mkdir_raw(path_map[i].to, 0666); + if (ret != 0 && ret != -EEXIST) + err("mkdir(%s): %ld\n", path_map[i].to, ret); + return buff; } } @@ -1311,7 +1360,7 @@ static const char *wrap_path(const char *path) return path; } -static void wrap_path_free(const char *w_path, const char *old_path) +void emu_wrap_path_free(const char *w_path, const char *old_path) { if (w_path != old_path) free((void *)w_path); @@ -1322,9 +1371,23 @@ void *emu_do_fopen(const char *path, const char *mode) const char *w_path; FILE *ret; - w_path = wrap_path(path); - ret = fopen(w_path, mode); - 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; } @@ -1351,7 +1414,7 @@ int emu_do_system(const char *command) // absolute path, but not a system command need_ginge = 1; - p2 = wrap_path(command); + p2 = emu_wrap_path(command); if (need_ginge) { make_local_path(tmp_path, sizeof(tmp_path), "ginge_prep"); p = tmp_path + strlen(tmp_path); @@ -1360,7 +1423,7 @@ int emu_do_system(const char *command) } else snprintf(tmp_path, sizeof(tmp_path), "%s", p2); - wrap_path_free(p2, command); + emu_wrap_path_free(p2, command); dbg("system: \"%s\"\n", tmp_path); @@ -1400,7 +1463,7 @@ long emu_do_execve(const char *filename, char * const argv[], make_local_path(prep_path, 512, "ginge_prep"); new_argv[0] = prep_path; new_argv[1] = "--nomenu"; - new_argv[2] = wrap_path(filename); + new_argv[2] = emu_wrap_path(filename); if (argv[0] != NULL) for (i = 1; argv[i] != NULL; i++)