18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Virtual hardware for bridging the FUSE kernel module
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the emulated OS and outside file system
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1628a09b6fe8d8f3e92ffee9263609a6da881b8818David 'Digit' Turner#include "migration/qemu-file.h"
17f5bc01c356e1fa924ed07aadf589b3663873593eDavid 'Digit' Turner#include "hw/android/goldfish/trace.h"
18f5bc01c356e1fa924ed07aadf589b3663873593eDavid 'Digit' Turner#include "hw/android/goldfish/vmem.h"
1934c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h"
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner/* Set to 1 to debug tracing */
22335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#define DEBUG   0
23335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner
24335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG
25335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#  define D(...)  printf(__VA_ARGS__), fflush(stdout)
26335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#else
27335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#  define D(...)  ((void)0)
28335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#endif
29335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner
30335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner/* Set to 1 to debug PID tracking */
31335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#define  DEBUG_PID  0
32335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner
33335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG_PID
34335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#  define  DPID(...)  printf(__VA_ARGS__), fflush(stdout)
35335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#else
36335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#  define  DPID(...)  ((void)0)
37335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#endif
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner// TODO(digit): Re-enable tracing some day?
40171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner#define tracing 0
41171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner
4285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerextern void cpu_loop_exit(CPUArchState* env);
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineextern const char *trace_filename;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for execve */
47b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_path[CLIENT_PAGE_SIZE];
48b91980562344f6a3b719bfe4be007fa9406e585fDavid Turnerstatic char exec_arg[CLIENT_PAGE_SIZE];
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vstart;    // VM start
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long vend;      // VM end
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long eoff;      // offset in EXE file
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned cmdlen;         // cmdline length
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned pid;            // PID (really thread id)
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned tgid;           // thread group id (really process id)
55335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turnerstatic unsigned tid;            // current thread id (same as pid, most of the time)
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long dsaddr;    // dynamic symbol address
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned long unmap_start; // start address to unmap
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for context switch */
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//static unsigned long cs_pid;    // context switch PID
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O write */
63bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic void trace_dev_write(void *opaque, hwaddr offset, uint32_t value)
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_dev_state *s = (trace_dev_state *)opaque;
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
674e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    (void)s;
684e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (offset >> 2) {
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_SWITCH:  // context switch, switch to pid
71335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: context switch tid=%u\n", value);
725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
73335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, context switch %u\n", value);
745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
75335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        tid = (unsigned) value;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_TGID:    // save the tgid for the following fork/clone
78335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: tgid=%u\n", value);
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tgid = value;
805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
81335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, tgid %u\n", value);
825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_FORK:    // fork, fork new pid
85335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: fork (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
87335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, fork %u\n", value);
885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_CLONE:    // fork, clone new pid (i.e. thread)
91335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: clone (pid=%d tgid=%d value=%d)\n", pid, tgid, value);
925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
93335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, clone %u\n", value);
945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_EXECVE_VMSTART:  // execve, vstart
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vstart = value;
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_EXECVE_VMEND:    // execve, vend
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vend = value;
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_EXECVE_OFFSET:   // execve, offset in EXE
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        eoff = value;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_EXECVE_EXEPATH:  // init exec, path of EXE
106b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
1075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
108335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, init exec [%lx,%lx]@%lx [%s]\n",
109335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner              vstart, vend, eoff, exec_path);
1105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
111b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        exec_path[0] = 0;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_CMDLINE_LEN:     // execve, process cmdline length
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cmdlen = value;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_CMDLINE:         // execve, process cmdline
117aaef275467ba13162d52ef6f690fd97f9733eb58David 'Digit' Turner        safe_memory_rw_debug(current_cpu, value, (uint8_t*)exec_arg, cmdlen, 0);
1185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
119171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner            D("QEMU.trace: kernel, execve [%.*s]\n", cmdlen, exec_arg);
1205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
121335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner#if DEBUG || DEBUG_PID
1225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int i;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < cmdlen; i ++)
125b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner                if (i != cmdlen - 1 && exec_arg[i] == 0)
126b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner                    exec_arg[i] = ' ';
127b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner            printf("QEMU.trace: kernel, execve %s[%d]\n", exec_arg, cmdlen);
128b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner            exec_arg[0] = 0;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_EXIT:            // exit, exit current process with exit code
133335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: exit tid=%u\n", value);
1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
135335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, exit %x\n", value);
1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_NAME:            // record thread name
139b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
140335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: thread name=%s\n", exec_path);
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        // Remove the trailing newline if it exists
143b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        int len = strlen(exec_path);
144b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        if (exec_path[len - 1] == '\n') {
145b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner            exec_path[len - 1] = 0;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
148335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, name %s\n", exec_path);
1495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_MMAP_EXEPATH:    // mmap, path of EXE, the others are same as execve
152b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
153335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: mmap exe=%s\n", exec_path);
1545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
155335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, mmap [%lx,%lx]@%lx [%s]\n", vstart, vend, eoff, exec_path);
1565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
157b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        exec_path[0] = 0;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_INIT_PID:        // init, name the pid that starts before device registered
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pid = value;
161335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: pid=%d\n", value);
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_INIT_NAME:       // init, the comm of the init pid
164b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_path, CLIENT_PAGE_SIZE);
165335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        DPID("QEMU.trace: tgid=%d pid=%d name=%s\n", tgid, pid, exec_path);
1665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
167335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: kernel, init name %u [%s]\n", pid, exec_path);
1685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
169b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        exec_path[0] = 0;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_DYN_SYM_ADDR:    // dynamic symbol address
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dsaddr = value;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_DYN_SYM:         // add dynamic symbol
176b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
178335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: dynamic symbol %lx:%s\n", dsaddr, exec_arg);
1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
180b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        exec_arg[0] = 0;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_REMOVE_ADDR:         // remove dynamic symbol addr
1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
184335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("QEMU.trace: dynamic symbol remove %lx\n", dsaddr);
1855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_PRINT_STR:       // print string
189b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        vstrcpy(value, exec_arg, CLIENT_PAGE_SIZE);
190b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        printf("%s", exec_arg);
191b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner        exec_arg[0] = 0;
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_PRINT_NUM_DEC:   // print number in decimal
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("%d", value);
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_PRINT_NUM_HEX:   // print number in hexical
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("%x", value);
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_STOP_EMU:        // stop the VM execution
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_single_env->exception_index = EXCP_HLT;
2026657678c3d86395084f6a699e73614195f06c445David 'Digit' Turner        current_cpu->halted = 1;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        qemu_system_shutdown_request();
20485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner        cpu_loop_exit(cpu_single_env);
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_ENABLE:          // tracing enable: 0 = stop, 1 = start
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_UNMAP_START:
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        unmap_start = value;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_UNMAP_END:
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2169980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    case TRACE_DEV_REG_METHOD_ENTRY:
2179980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    case TRACE_DEV_REG_METHOD_EXIT:
2189980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    case TRACE_DEV_REG_METHOD_EXCEPTION:
219e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra    case TRACE_DEV_REG_NATIVE_ENTRY:
220e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra    case TRACE_DEV_REG_NATIVE_EXIT:
221e3ea32ffa04468eddaf9c6ce2d36090f7bf43e49Jack Veenstra    case TRACE_DEV_REG_NATIVE_EXCEPTION:
2225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_filename != NULL) {
2235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (tracing) {
224171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner                int __attribute__((unused)) call_type = (offset - 4096) >> 2;
225171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner                //trace_interpreted_method(value, call_type);
2265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            }
2275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        break;
2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
2319980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra        if (offset < 4096) {
2329980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra            cpu_abort(cpu_single_env, "trace_dev_write: Bad offset %x\n", offset);
233335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        } else {
234335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("%s: offset=%d (0x%x) value=%d (0x%x)\n", __FUNCTION__, offset,
235335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner              offset, value, value);
2369980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra        }
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* I/O read */
242bcde1092aca184dbd7860078af020de7d1e4e22fDavid 'Digit' Turnerstatic uint32_t trace_dev_read(void *opaque, hwaddr offset)
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_dev_state *s = (trace_dev_state *)opaque;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2464e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    (void)s;
2474e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (offset >> 2) {
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case TRACE_DEV_REG_ENABLE:          // tracing enable
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return tracing;
251335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
2539980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra        if (offset < 4096) {
2549980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra            cpu_abort(cpu_single_env, "trace_dev_read: Bad offset %x\n", offset);
255335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner        } else {
256335d2c1342bb887ac67f1f60cff795f0c06beacaDavid 'Digit' Turner            D("%s: offset=%d (0x%x)\n", __FUNCTION__, offset, offset);
2579980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra        }
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUReadMemoryFunc *trace_dev_readfn[] = {
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_read,
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_read,
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_read
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic CPUWriteMemoryFunc *trace_dev_writefn[] = {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_write,
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_write,
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   trace_dev_write
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* initialize the trace device */
2769980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstravoid trace_dev_init()
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trace_dev_state *s;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
280aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    s = (trace_dev_state *)g_malloc0(sizeof(trace_dev_state));
2819980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.name = "qemu_trace";
2829980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.id = -1;
2839980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.base = 0;       // will be allocated dynamically
2849980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.size = 0x2000;
2859980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.irq = 0;
2869980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    s->dev.irq_count = 0;
2879980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra
2889980bbb9965ee2df42f94aafa817e91835dad406Jack Veenstra    goldfish_device_add(&s->dev, trace_dev_readfn, trace_dev_writefn, s);
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
290b91980562344f6a3b719bfe4be007fa9406e585fDavid Turner    exec_path[0] = exec_arg[0] = '\0';
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
292