* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include "qemu.h"
+#include "qemu-common.h"
#define DEBUG_LOGFILE "/tmp/qemu.log"
#include <mach/mach_init.h>
#include <mach/vm_map.h>
+int singlestep;
+
const char *interp_prefix = "";
asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
va_end(ap);
}
-void cpu_outb(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
-}
-
-void cpu_outw(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
-}
-
-void cpu_outl(CPUState *env, int addr, int val)
-{
- fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
-}
-
-int cpu_inb(CPUState *env, int addr)
-{
- fprintf(stderr, "inb: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inw(CPUState *env, int addr)
-{
- fprintf(stderr, "inw: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_inl(CPUState *env, int addr)
-{
- fprintf(stderr, "inl: port=0x%04x\n", addr);
- return 0;
-}
-
-int cpu_get_pic_interrupt(CPUState *env)
+int cpu_get_pic_interrupt(CPUArchState *env)
{
return -1;
}
#ifdef TARGET_PPC
-static inline uint64_t cpu_ppc_get_tb (CPUState *env)
+static inline uint64_t cpu_ppc_get_tb(CPUPPCState *env)
{
/* TO FIX */
return 0;
}
-uint32_t cpu_ppc_load_tbl (CPUState *env)
+uint64_t cpu_ppc_load_tbl(CPUPPCState *env)
{
- return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
+ return cpu_ppc_get_tb(env);
}
-uint32_t cpu_ppc_load_tbu (CPUState *env)
+uint32_t cpu_ppc_load_tbu(CPUPPCState *env)
{
return cpu_ppc_get_tb(env) >> 32;
}
-uint32_t cpu_ppc_load_atbl (CPUState *env)
+uint64_t cpu_ppc_load_atbl(CPUPPCState *env)
{
- return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
+ return cpu_ppc_get_tb(env);
}
-uint32_t cpu_ppc_load_atbu (CPUState *env)
+uint32_t cpu_ppc_load_atbu(CPUPPCState *env)
{
return cpu_ppc_get_tb(env) >> 32;
}
-uint32_t cpu_ppc601_load_rtcu (CPUState *env)
+uint32_t cpu_ppc601_load_rtcu(CPUPPCState *env)
{
cpu_ppc_load_tbu(env);
}
-uint32_t cpu_ppc601_load_rtcl (CPUState *env)
+uint32_t cpu_ppc601_load_rtcl(CPUPPCState *env)
{
return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
}
/* XXX: to be fixed */
-int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
+int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp)
{
return -1;
}
-int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
+int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
{
return -1;
}
-#define EXCP_DUMP(env, fmt, args...) \
-do { \
- fprintf(stderr, fmt , ##args); \
- cpu_dump_state(env, stderr, fprintf, 0); \
- if (loglevel != 0) { \
- fprintf(logfile, fmt , ##args); \
- cpu_dump_state(env, logfile, fprintf, 0); \
- } \
+#define EXCP_DUMP(env, fmt, ...) \
+do { \
+ fprintf(stderr, fmt , ## __VA_ARGS__); \
+ cpu_dump_state(env, stderr, fprintf, 0); \
+ qemu_log(fmt, ## __VA_ARGS__); \
+ log_cpu_state(env, 0); \
} while (0)
void cpu_loop(CPUPPCState *env)
/* To deal with multiple qemu header version as host for the darwin-user code */
# define DAR SPR_DAR
#endif
- EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
+ EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
env->spr[SPR_DAR]);
/* Handle this via the gdb */
gdb_handlesig (env, SIGSEGV);
queue_signal(info.si_signo, &info);
break;
case POWERPC_EXCP_ISI: /* Instruction storage exception */
- EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
+ EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx "\n",
env->spr[SPR_DAR]);
/* Handle this via the gdb */
gdb_handlesig (env, SIGSEGV);
cpu_abort(env, "Reset interrupt while in user mode. "
"Aborting\n");
break;
-#if defined(TARGET_PPC64) /* PowerPC 64 */
case POWERPC_EXCP_DSEG: /* Data segment exception */
cpu_abort(env, "Data segment exception while in user mode. "
"Aborting\n");
cpu_abort(env, "Instruction segment exception "
"while in user mode. Aborting\n");
break;
-#endif /* defined(TARGET_PPC64) */
-#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
cpu_abort(env, "Hypervisor decrementer interrupt "
"while in user mode. Aborting\n");
break;
-#endif /* defined(TARGET_PPC64H) */
case POWERPC_EXCP_TRACE: /* Trace exception */
/* Nothing to do:
* we use this exception to emulate step-by-step execution mode.
*/
break;
-#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
cpu_abort(env, "Hypervisor data storage exception "
"while in user mode. Aborting\n");
cpu_abort(env, "Hypervisor instruction segment exception "
"while in user mode. Aborting\n");
break;
-#endif /* defined(TARGET_PPC64H) */
case POWERPC_EXCP_VPU: /* Vector unavailable exception */
EXCP_DUMP(env, "No Altivec instructions allowed\n");
info.si_signo = SIGILL;
queue_signal(info.si_signo, &info);
break;
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
- cpu_abort(env, "Programable interval timer interrupt "
+ cpu_abort(env, "Programmable interval timer interrupt "
"while in user mode. Aborting\n");
break;
case POWERPC_EXCP_IO: /* IO error exception */
}
#endif
-void usage(void)
+static void usage(void)
{
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
"usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n"
"-d options activate log (logfile='%s')\n"
"-g wait for gdb on port 1234\n"
"-p pagesize set the host page size to 'pagesize'\n",
+ "-singlestep always run in singlestep mode\n"
TARGET_ARCH,
TARGET_ARCH,
interp_prefix,
stack_size,
DEBUG_LOGFILE);
- _exit(1);
+ exit(1);
}
/* XXX: currently only used for async signals (see signal.c) */
-CPUState *global_env;
-/* used only if single thread */
-CPUState *cpu_single_env = NULL;
+CPUArchState *global_env;
/* used to free thread contexts */
TaskState *first_task_state;
int main(int argc, char **argv)
{
const char *filename;
+ const char *log_file = DEBUG_LOGFILE;
+ const char *log_mask = NULL;
struct target_pt_regs regs1, *regs = ®s1;
TaskState ts1, *ts = &ts1;
- CPUState *env;
+ CPUArchState *env;
int optind;
short use_gdbstub = 0;
const char *r;
if (argc <= 1)
usage();
- /* init debug */
- cpu_set_log_filename(DEBUG_LOGFILE);
+ module_call_init(MODULE_INIT_QOM);
optind = 1;
for(;;) {
if (!strcmp(r, "-")) {
break;
} else if (!strcmp(r, "d")) {
- int mask;
- CPULogItem *item;
-
- if (optind >= argc)
- break;
-
- r = argv[optind++];
- mask = cpu_str_to_log_mask(r);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
+ if (optind >= argc) {
+ break;
+ }
+ log_mask = argv[optind++];
+ } else if (!strcmp(r, "D")) {
+ if (optind >= argc) {
+ break;
}
- cpu_set_log(mask);
+ log_file = argv[optind++];
} else if (!strcmp(r, "s")) {
r = argv[optind++];
stack_size = strtol(r, (char **)&r, 0);
} else
if (!strcmp(r, "g")) {
use_gdbstub = 1;
+ } else if (!strcmp(r, "cpu")) {
+ cpu_model = argv[optind++];
+ if (strcmp(cpu_model, "?") == 0) {
+/* XXX: implement xxx_cpu_list for targets that still miss it */
+#if defined(cpu_list)
+ cpu_list(stdout, &fprintf);
+#endif
+ exit(1);
+ }
+ } else if (!strcmp(r, "singlestep")) {
+ singlestep = 1;
} else
{
usage();
}
}
- if (optind >= argc)
+
+ /* init debug */
+ cpu_set_log_filename(log_file);
+ if (log_mask) {
+ int mask;
+ CPULogItem *item;
+
+ mask = cpu_str_to_log_mask(log_mask);
+ if (!mask) {
+ printf("Log items (comma separated):\n");
+ for (item = cpu_log_items; item->mask != 0; item++) {
+ printf("%-10s %s\n", item->name, item->help);
+ }
+ exit(1);
+ }
+ cpu_set_log(mask);
+ }
+
+ if (optind >= argc) {
usage();
+ }
filename = argv[optind];
/* Zero out regs */
memset(regs, 0, sizeof(struct target_pt_regs));
- /* NOTE: we need to init the CPU at this stage to get
- qemu_host_page_size */
+ if (cpu_model == NULL) {
#if defined(TARGET_I386)
- cpu_model = "qemu32";
+#ifdef TARGET_X86_64
+ cpu_model = "qemu64";
+#else
+ cpu_model = "qemu32";
+#endif
#elif defined(TARGET_PPC)
- cpu_model = "750";
+#ifdef TARGET_PPC64
+ cpu_model = "970";
+#else
+ cpu_model = "750";
+#endif
#else
#error unsupported CPU
#endif
-
+ }
+ tcg_exec_init(0);
+ cpu_exec_init_all();
+ /* NOTE: we need to init the CPU at this stage to get
+ qemu_host_page_size */
env = cpu_init(cpu_model);
+ cpu_state_reset(env);
printf("Starting %s with qemu\n----------------\n", filename);
memset(ts, 0, sizeof(TaskState));
env->opaque = ts;
ts->used = 1;
- env->user_mode_only = 1;
#if defined(TARGET_I386)
cpu_x86_set_cpl(env, 3);
#elif defined(TARGET_PPC)
{
int i;
+
+#if defined(TARGET_PPC64)
+#if defined(TARGET_ABI32)
+ env->msr &= ~((target_ulong)1 << MSR_SF);
+#else
+ env->msr |= (target_ulong)1 << MSR_SF;
+#endif
+#endif
env->nip = regs->nip;
for(i = 0; i < 32; i++) {
env->gpr[i] = regs->gpr[i];