[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Patch: Sparc system support (3/3)
From: |
Blue Swirl |
Subject: |
[Qemu-devel] Patch: Sparc system support (3/3) |
Date: |
Sat, 18 Sep 2004 09:44:34 +0200 |
Hi,
Contents: GDB support for Sparc target, signal support for Sparc usermode
(incomplete), interrupt support (incomplete), wait4 fix for return value,
monitor support for Sparc registers, fix for DHCP to support older BOOTP
clients.
diff -ruN qemu-0.6.0.orig/cpu-exec.c qemu-0.6.0/cpu-exec.c
--- qemu-0.6.0.orig/cpu-exec.c 2004-07-10 20:20:09.000000000 +0200
+++ qemu-0.6.0/cpu-exec.c 2004-09-15 19:17:11.000000000 +0200
@@ -208,6 +208,11 @@
env->exception_next_eip, 0);
#elif defined(TARGET_PPC)
do_interrupt(env);
+#elif defined(TARGET_SPARC)
+ do_interrupt(env->exception_index,
+ 1,
+ env->error_code,
+ env->exception_next_pc, 0);
#endif
}
env->exception_index = -1;
@@ -261,6 +266,14 @@
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
}
}
+#elif defined(TARGET_SPARC)
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
+ do_interrupt(0, 0, 0, 0, 0);
+ env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
+ //do_interrupt(0, 0, 0, 0, 0);
+ env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
+ }
#endif
if (interrupt_request & CPU_INTERRUPT_EXITTB) {
env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
diff -ruN qemu-0.6.0.orig/gdbstub.c qemu-0.6.0/gdbstub.c
--- qemu-0.6.0.orig/gdbstub.c 2004-07-10 20:20:09.000000000 +0200
+++ qemu-0.6.0/gdbstub.c 2004-09-11 21:21:35.000000000 +0200
@@ -289,6 +289,90 @@
env->ctr = from_le32(®isters[100]);
_store_xer(env, from_le32(®isters[101]));
}
+#elif defined (TARGET_SPARC)
+static void to_le32(uint32_t *buf, uint32_t v)
+{
+ uint8_t *p = (uint8_t *)buf;
+ p[3] = v;
+ p[2] = v >> 8;
+ p[1] = v >> 16;
+ p[0] = v >> 24;
+}
+
+static uint32_t from_le32 (uint32_t *buf)
+{
+ uint8_t *p = (uint8_t *)buf;
+
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ uint32_t *registers = (uint32_t *)mem_buf, tmp;
+ int i;
+
+ /* fill in g0..g7 */
+ for(i = 0; i < 7; i++) {
+ to_le32(®isters[i], env->gregs[i]);
+ }
+ /* fill in register window */
+ for(i = 0; i < 24; i++) {
+ to_le32(®isters[i + 8], env->regwptr[i]);
+ }
+ /* fill in fprs */
+ for (i = 0; i < 32; i++) {
+ to_le32(®isters[i + 32], *((uint32_t *)&env->fpr[i]));
+ }
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ to_le32(®isters[64], (uint32_t)env->y);
+ tmp = (0<<28) | (4<<24) | env->psr \
+ | (env->psrs? PSR_S : 0) \
+ | (env->psrs? PSR_PS : 0) \
+ | (env->psret? PSR_ET : 0) \
+ | env->cwp;
+ to_le32(®isters[65], tmp);
+ to_le32(®isters[66], (uint32_t)env->wim);
+ to_le32(®isters[67], (uint32_t)env->tbr);
+ to_le32(®isters[68], (uint32_t)env->pc);
+ to_le32(®isters[69], (uint32_t)env->npc);
+ to_le32(®isters[70], (uint32_t)env->fsr);
+ to_le32(®isters[71], 0); /* csr */
+ to_le32(®isters[72], 0);
+
+ return 73 * 4;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int
size)
+{
+ uint32_t *registers = (uint32_t *)mem_buf, tmp;
+ int i;
+
+ /* fill in g0..g7 */
+ for(i = 0; i < 7; i++) {
+ env->gregs[i] = from_le32(®isters[i]);
+ }
+ /* fill in register window */
+ for(i = 0; i < 24; i++) {
+ env->regwptr[i] = from_le32(®isters[i]);
+ }
+ /* fill in fprs */
+ for (i = 0; i < 32; i++) {
+ *((uint32_t *)&env->fpr[i]) = from_le32(®isters[i + 32]);
+ }
+ /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ env->y = from_le32(®isters[64]);
+ tmp = from_le32(®isters[65]);
+ env->psr = tmp & ~PSR_ICC;
+ env->psrs = (tmp & PSR_S)? 1 : 0;
+ env->psrps = (tmp & PSR_PS)? 1 : 0;
+ env->psret = (tmp & PSR_ET)? 1 : 0;
+ env->cwp = (tmp & PSR_CWP);
+ env->wim = from_le32(®isters[66]);
+ env->tbr = from_le32(®isters[67]);
+ env->pc = from_le32(®isters[68]);
+ env->npc = from_le32(®isters[69]);
+ env->fsr = from_le32(®isters[70]);
+}
#else
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
diff -ruN qemu-0.6.0.orig/linux-user/signal.c qemu-0.6.0/linux-user/signal.c
--- qemu-0.6.0.orig/linux-user/signal.c 2004-07-10 20:20:09.000000000 +0200
+++ qemu-0.6.0/linux-user/signal.c 2004-09-15 19:22:02.000000000 +0200
@@ -1271,6 +1271,346 @@
return 0;
}
+#elif defined(TARGET_SPARC)
+#define __SUNOS_MAXWIN 31
+
+/* This is what SunOS does, so shall I. */
+struct target_sigcontext {
+ target_ulong sigc_onstack; /* state to restore */
+
+ target_ulong sigc_mask; /* sigmask to restore */
+ target_ulong sigc_sp; /* stack pointer */
+ target_ulong sigc_pc; /* program counter */
+ target_ulong sigc_npc; /* next program counter */
+ target_ulong sigc_psr; /* for condition codes etc */
+ target_ulong sigc_g1; /* User uses these two registers */
+ target_ulong sigc_o0; /* within the trampoline code. */
+
+ /* Now comes information regarding the users window set
+ * at the time of the signal.
+ */
+ target_ulong sigc_oswins; /* outstanding windows */
+
+ /* stack ptrs for each regwin buf */
+ char *sigc_spbuf[__SUNOS_MAXWIN];
+
+ /* Windows to restore after signal */
+ struct {
+ target_ulong locals[8];
+ target_ulong ins[8];
+ } sigc_wbuf[__SUNOS_MAXWIN];
+};
+/* A Sparc stack frame */
+struct sparc_stackf {
+ target_ulong locals[8];
+ target_ulong ins[6];
+ struct sparc_stackf *fp;
+ target_ulong callers_pc;
+ char *structptr;
+ target_ulong xargs[6];
+ target_ulong xxargs[1];
+};
+
+typedef struct {
+ struct {
+ target_ulong psr;
+ target_ulong pc;
+ target_ulong npc;
+ target_ulong y;
+ target_ulong u_regs[16]; /* globals and ins */
+ } si_regs;
+ int si_mask;
+} __siginfo_t;
+
+typedef struct {
+ unsigned long si_float_regs [32];
+ unsigned long si_fsr;
+ unsigned long si_fpqdepth;
+ struct {
+ unsigned long *insn_addr;
+ unsigned long insn;
+ } si_fpqueue [16];
+} __siginfo_fpu_t;
+
+
+struct target_signal_frame {
+ struct sparc_stackf ss;
+ __siginfo_t info;
+ __siginfo_fpu_t __user *fpu_save;
+ target_ulong insns[2] __attribute__ ((aligned (8)));
+ target_ulong extramask[TARGET_NSIG_WORDS - 1];
+ target_ulong extra_size; /* Should be 0 */
+ __siginfo_fpu_t fpu_state;
+};
+struct target_rt_signal_frame {
+ struct sparc_stackf ss;
+ siginfo_t info;
+ target_ulong regs[20];
+ sigset_t mask;
+ __siginfo_fpu_t __user *fpu_save;
+ unsigned int insns[2];
+ stack_t stack;
+ unsigned int extra_size; /* Should be 0 */
+ __siginfo_fpu_t fpu_state;
+};
+
+#define UREG_O0 0
+#define UREG_O6 6
+#define UREG_I0 16
+#define UREG_I1 17
+#define UREG_I2 18
+#define UREG_I6 22
+#define UREG_I7 23
+#define UREG_FP UREG_I6
+#define UREG_SP UREG_O6
+
+static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState
*env, unsigned long framesize)
+{
+ unsigned long sp;
+
+ sp = env->regwptr[UREG_FP];
+#if 0
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (sa->sa_flags & TARGET_SA_ONSTACK) {
+ if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) &
7))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+ }
+#endif
+ return (void *)(sp - framesize);
+}
+
+static int
+setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
+{
+ int err = 0, i;
+
+ fprintf(stderr, "2.a %lx psr: %lx regs: %lx\n", si, env->psr,
si->si_regs.psr);
+ err |= __put_user(env->psr, &si->si_regs.psr);
+ fprintf(stderr, "2.a1 pc:%lx\n", si->si_regs.pc);
+ err |= __put_user(env->pc, &si->si_regs.pc);
+ err |= __put_user(env->npc, &si->si_regs.npc);
+ err |= __put_user(env->y, &si->si_regs.y);
+ fprintf(stderr, "2.b\n");
+ for (i=0; i < 7; i++) {
+ err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
+ }
+ for (i=0; i < 7; i++) {
+ err |= __put_user(env->regwptr[i+16], &si->si_regs.u_regs[i+8]);
+ }
+ fprintf(stderr, "2.c\n");
+ err |= __put_user(mask, &si->si_mask);
+ return err;
+}
+static int
+setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate
*fpstate,*/
+ CPUState *env, unsigned long mask)
+{
+ int err = 0;
+
+ err |= __put_user(mask, &sc->sigc_mask);
+ err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);
+ err |= __put_user(env->pc, &sc->sigc_pc);
+ err |= __put_user(env->npc, &sc->sigc_npc);
+ err |= __put_user(env->psr, &sc->sigc_psr);
+ err |= __put_user(env->gregs[1], &sc->sigc_g1);
+ err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);
+
+ return err;
+}
+#define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
+
+static void setup_frame(int sig, struct emulated_sigaction *ka,
+ target_sigset_t *set, CPUState *env)
+{
+ struct target_signal_frame *sf;
+ int sigframe_size, err, i;
+
+ /* 1. Make sure everything is clean */
+ //synchronize_user_stack();
+
+ sigframe_size = NF_ALIGNEDSZ;
+
+ sf = (struct target_signal_frame *)
+ get_sigframe(ka, env, sigframe_size);
+
+#if 0
+ if (invalid_frame_pointer(sf, sigframe_size))
+ goto sigill_and_return;
+#endif
+ /* 2. Save the current process state */
+ err = setup___siginfo(&sf->info, env, set->sig[0]);
+ err |= __put_user(0, &sf->extra_size);
+
+ //err |= save_fpu_state(regs, &sf->fpu_state);
+ //err |= __put_user(&sf->fpu_state, &sf->fpu_save);
+
+ err |= __put_user(set->sig[0], &sf->info.si_mask);
+ for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
+ err |= __put_user(set->sig[i + 1], &sf->extramask[i]);
+ }
+
+ for (i = 0; i < 7; i++) {
+ err |= __put_user(env->regwptr[i + 8], &sf->ss.locals[i]);
+ }
+ for (i = 0; i < 7; i++) {
+ err |= __put_user(env->regwptr[i + 16], &sf->ss.ins[i]);
+ }
+ //err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
+ // sizeof(struct reg_window));
+ if (err)
+ goto sigsegv;
+
+ /* 3. signal handler back-trampoline and parameters */
+ env->regwptr[UREG_FP] = (target_ulong) sf;
+ env->regwptr[UREG_I0] = sig;
+ env->regwptr[UREG_I1] = (target_ulong) &sf->info;
+ env->regwptr[UREG_I2] = (target_ulong) &sf->info;
+
+ /* 4. signal handler */
+ env->pc = (unsigned long) ka->sa._sa_handler;
+ env->npc = (env->pc + 4);
+ /* 5. return to kernel instructions */
+ if (ka->sa.sa_restorer)
+ env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
+ else {
+ env->regwptr[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
+
+ /* mov __NR_sigreturn, %g1 */
+ err |= __put_user(0x821020d8, &sf->insns[0]);
+
+ /* t 0x10 */
+ err |= __put_user(0x91d02010, &sf->insns[1]);
+ if (err)
+ goto sigsegv;
+
+ /* Flush instruction space. */
+ //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
+ //tb_flush(env);
+ }
+ return;
+
+sigill_and_return:
+ force_sig(TARGET_SIGILL);
+sigsegv:
+ force_sig(TARGET_SIGSEGV);
+}
+static inline int
+restore_fpu_state(CPUState *env, __siginfo_fpu_t *fpu)
+{
+ int err;
+#if 0
+#ifdef CONFIG_SMP
+ if (current->flags & PF_USEDFPU)
+ regs->psr &= ~PSR_EF;
+#else
+ if (current == last_task_used_math) {
+ last_task_used_math = 0;
+ regs->psr &= ~PSR_EF;
+ }
+#endif
+ current->used_math = 1;
+ current->flags &= ~PF_USEDFPU;
+#endif
+#if 0
+ if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
+ return -EFAULT;
+#endif
+
+ err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],
+ (sizeof(unsigned long) * 32));
+ err |= __get_user(env->fsr, &fpu->si_fsr);
+#if 0
+ err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
+ if (current->thread.fpqdepth != 0)
+ err |= __copy_from_user(¤t->thread.fpqueue[0],
+ &fpu->si_fpqueue[0],
+ ((sizeof(unsigned long) +
+ (sizeof(unsigned long *)))*16));
+#endif
+ return err;
+}
+
+
+static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPUState *env)
+{
+ fprintf(stderr, "setup_rt_frame: not implemented\n");
+}
+
+long do_sigreturn(CPUState *env)
+{
+ struct target_signal_frame *sf;
+ unsigned long up_psr, pc, npc;
+ target_sigset_t set;
+ __siginfo_fpu_t *fpu_save;
+ int err;
+
+ sf = (struct new_signal_frame *) env->regwptr[UREG_FP];
+ fprintf(stderr, "sigreturn sf: %lx\n", &sf);
+
+ /* 1. Make sure we are not getting garbage from the user */
+#if 0
+ if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
+ goto segv_and_exit;
+#endif
+
+ if (((uint) sf) & 3)
+ goto segv_and_exit;
+
+ err = __get_user(pc, &sf->info.si_regs.pc);
+ err |= __get_user(npc, &sf->info.si_regs.npc);
+
+ fprintf(stderr, "pc: %lx npc %lx\n", pc, npc);
+ if ((pc | npc) & 3)
+ goto segv_and_exit;
+
+ /* 2. Restore the state */
+ up_psr = env->psr;
+ //err |= __copy_from_user(regs, &sf->info.si_regs, sizeof (struct
pt_regs)
+ //);
+ /* User can only change condition codes and FPU enabling in %psr.
*/
+ env->psr = (up_psr & ~(PSR_ICC /* | PSR_EF */))
+ | (env->psr & (PSR_ICC /* | PSR_EF */));
+ fprintf(stderr, "psr: %lx\n", env->psr);
+
+ err |= __get_user(fpu_save, &sf->fpu_save);
+
+ if (fpu_save)
+ err |= restore_fpu_state(env, fpu_save);
+
+ /* This is pretty much atomic, no amount locking would prevent
+ * the races which exist anyways.
+ */
+ err |= __get_user(set.sig[0], &sf->info.si_mask);
+ //err |= __copy_from_user(&set.sig[1], &sf->extramask,
+ // (_NSIG_WORDS-1) * sizeof(unsigned int));
+
+ if (err)
+ goto segv_and_exit;
+
+#if 0
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(¤t->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+#endif
+ fprintf(stderr, "returning %lx\n", env->regwptr[0]);
+ return env->regwptr[0];
+
+segv_and_exit:
+ force_sig(TARGET_SIGSEGV);
+}
+
+long do_rt_sigreturn(CPUState *env)
+{
+ fprintf(stderr, "do_rt_sigreturn: not implemented\n");
+ return -ENOSYS;
+}
+
+
#else
static void setup_frame(int sig, struct emulated_sigaction *ka,
diff -ruN qemu-0.6.0.orig/linux-user/syscall.c
qemu-0.6.0/linux-user/syscall.c
--- qemu-0.6.0.orig/linux-user/syscall.c 2004-07-10 20:20:09.000000000
+0200
+++ qemu-0.6.0/linux-user/syscall.c 2004-07-14 19:57:40.000000000 +0200
@@ -2336,7 +2336,7 @@
else
rusage_ptr = NULL;
ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
- if (!is_error(ret)) {
+ if (ret == 0 || ret == -1) {
if (status_ptr)
*status_ptr = tswap32(status);
if (target_rusage) {
diff -ruN qemu-0.6.0.orig/linux-user/syscall_defs.h
qemu-0.6.0/linux-user/syscall_defs.h
--- qemu-0.6.0.orig/linux-user/syscall_defs.h 2004-07-10 20:20:09.000000000
+0200
+++ qemu-0.6.0/linux-user/syscall_defs.h 2004-07-15 21:46:08.000000000
+0200
@@ -294,6 +294,7 @@
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) ||
defined(TARGET_PPC)
+#if !defined(TARGET_SPARC)
#define TARGET_SA_NOCLDSTOP 0x00000001
#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
#define TARGET_SA_SIGINFO 0x00000004
@@ -302,6 +303,15 @@
#define TARGET_SA_NODEFER 0x40000000
#define TARGET_SA_RESETHAND 0x80000000
#define TARGET_SA_RESTORER 0x04000000
+#else /* TARGET_SPARC */
+#define TARGET_SA_NOCLDSTOP 8u
+#define TARGET_SA_NOCLDWAIT 0x100u
+#define TARGET_SA_SIGINFO 0x200u
+#define TARGET_SA_ONSTACK 1u
+#define TARGET_SA_RESTART 2u
+#define TARGET_SA_NODEFER 0x20u
+#define TARGET_SA_RESETHAND 4u
+#endif
#define TARGET_SIGHUP 1
#define TARGET_SIGINT 2
@@ -310,36 +320,72 @@
#define TARGET_SIGTRAP 5
#define TARGET_SIGABRT 6
#define TARGET_SIGIOT 6
+#if !defined(TARGET_SPARC)
#define TARGET_SIGBUS 7
+#else /* TARGET_SPARC */
+#define TARGET_SIGSTKFLT 7 /* actually EMT */
+#endif
#define TARGET_SIGFPE 8
#define TARGET_SIGKILL 9
+#if !defined(TARGET_SPARC)
#define TARGET_SIGUSR1 10
+#else /* TARGET_SPARC */
+#define TARGET_SIGBUS 10
+#endif
#define TARGET_SIGSEGV 11
+#if !defined(TARGET_SPARC)
#define TARGET_SIGUSR2 12
+#else /* TARGET_SPARC */
+#define TARGET_SIGSYS 12
+#endif
#define TARGET_SIGPIPE 13
#define TARGET_SIGALRM 14
#define TARGET_SIGTERM 15
+#if !defined(TARGET_SPARC)
#define TARGET_SIGSTKFLT 16
#define TARGET_SIGCHLD 17
#define TARGET_SIGCONT 18
#define TARGET_SIGSTOP 19
#define TARGET_SIGTSTP 20
+#else /* TARGET_SPARC */
+#define TARGET_SIGURG 16
+#define TARGET_SIGSTOP 17
+#define TARGET_SIGTSTP 18
+#define TARGET_SIGCONT 19
+#define TARGET_SIGCHLD 20
+#endif
#define TARGET_SIGTTIN 21
#define TARGET_SIGTTOU 22
+#if !defined(TARGET_SPARC)
#define TARGET_SIGURG 23
+#else /* TARGET_SPARC */
+#define TARGET_SIGIO 23
+#endif
#define TARGET_SIGXCPU 24
#define TARGET_SIGXFSZ 25
#define TARGET_SIGVTALRM 26
#define TARGET_SIGPROF 27
#define TARGET_SIGWINCH 28
+#if !defined(TARGET_SPARC)
#define TARGET_SIGIO 29
#define TARGET_SIGPWR 30
#define TARGET_SIGSYS 31
+#else /* TARGET_SPARC */
+#define TARGET_SIGPWR 29
+#define TARGET_SIGUSR1 30
+#define TARGET_SIGUSR2 31
+#endif
#define TARGET_SIGRTMIN 32
+#if !defined(TARGET_SPARC)
#define TARGET_SIG_BLOCK 0 /* for blocking signals */
#define TARGET_SIG_UNBLOCK 1 /* for unblocking signals */
#define TARGET_SIG_SETMASK 2 /* for setting the signal mask */
+#else /* TARGET_SPARC */
+#define TARGET_SIG_BLOCK 0x01 /* for blocking signals */
+#define TARGET_SIG_UNBLOCK 0x02 /* for unblocking signals */
+#define TARGET_SIG_SETMASK 0x04 /* for setting the signal mask */
+#endif
struct target_old_sigaction {
target_ulong _sa_handler;
@@ -359,6 +405,30 @@
int sival_int;
target_ulong sival_ptr;
} target_sigval_t;
+#if 0
+#if defined (TARGET_SPARC)
+typedef struct {
+ struct {
+ target_ulong psr;
+ target_ulong pc;
+ target_ulong npc;
+ target_ulong y;
+ target_ulong u_regs[16]; /* globals and ins */
+ } si_regs;
+ int si_mask;
+} __siginfo_t;
+
+typedef struct {
+ unsigned long si_float_regs [32];
+ unsigned long si_fsr;
+ unsigned long si_fpqdepth;
+ struct {
+ unsigned long *insn_addr;
+ unsigned long insn;
+ } si_fpqueue [16];
+} __siginfo_fpu_t;
+#endif
+#endif
#define TARGET_SI_MAX_SIZE 128
#define TARGET_SI_PAD_SIZE ((TARGET_SI_MAX_SIZE/sizeof(int)) - 3)
@@ -954,6 +1024,24 @@
#define TARGET_O_NOFOLLOW 0100000 /* don't follow links */
#define TARGET_O_LARGEFILE 0200000
#define TARGET_O_DIRECT 0400000 /* direct disk access hint */
+#elif defined (TARGET_SPARC)
+#define TARGET_O_RDONLY 0x0000
+#define TARGET_O_WRONLY 0x0001
+#define TARGET_O_RDWR 0x0002
+#define TARGET_O_ACCMODE 0x0003
+#define TARGET_O_APPEND 0x0008
+#define TARGET_FASYNC 0x0040 /* fcntl, for BSD compatibility */
+#define TARGET_O_CREAT 0x0200 /* not fcntl */
+#define TARGET_O_TRUNC 0x0400 /* not fcntl */
+#define TARGET_O_EXCL 0x0800 /* not fcntl */
+#define TARGET_O_SYNC 0x2000
+#define TARGET_O_NONBLOCK 0x4000
+#define TARGET_O_NDELAY (0x0004 | O_NONBLOCK)
+#define TARGET_O_NOCTTY 0x8000 /* not fcntl */
+#define TARGET_O_DIRECTORY 0x10000 /* must be a directory */
+#define TARGET_O_NOFOLLOW 0x20000 /* don't follow links */
+#define TARGET_O_LARGEFILE 0x40000
+#define TARGET_O_DIRECT 0x100000 /* direct disk access hint */
#else
#define TARGET_O_ACCMODE 0003
#define TARGET_O_RDONLY 00
diff -ruN qemu-0.6.0.orig/monitor.c qemu-0.6.0/monitor.c
--- qemu-0.6.0.orig/monitor.c 2004-07-10 20:20:09.000000000 +0200
+++ qemu-0.6.0/monitor.c 2004-09-11 14:50:28.000000000 +0200
@@ -805,6 +805,28 @@
}
#endif
+#if defined(TARGET_SPARC)
+static int monitor_get_psr (struct MonitorDef *md)
+{
+ return (0<<28) | (4<<24) | cpu_single_env->psr \
+ | (cpu_single_env->psrs? PSR_S : 0) \
+ | (cpu_single_env->psrs? PSR_PS : 0) \
+ | (cpu_single_env->psret? PSR_ET : 0) \
+ | cpu_single_env->cwp;
+}
+#define getreg(no) \
+ static int monitor_get_r ## no (struct MonitorDef *md) \
+ { \
+ return cpu_single_env->regwptr[no]; \
+ }
+
+getreg(0); getreg(1); getreg(2); getreg(3); getreg(4);
+getreg(5); getreg(6); getreg(7); getreg(8); getreg(9);
+getreg(10); getreg(11); getreg(12); getreg(13); getreg(14);
+getreg(15); getreg(16); getreg(17); getreg(18); getreg(19);
+getreg(20); getreg(21); getreg(22); getreg(23);
+#endif
+
static MonitorDef monitor_defs[] = {
#ifdef TARGET_I386
@@ -889,6 +911,78 @@
{ "sr14", offsetof(CPUState, sr[14]) },
{ "sr15", offsetof(CPUState, sr[15]) },
/* Too lazy to put BATs and SPRs ... */
+#elif defined(TARGET_SPARC)
+ { "g0", offsetof(CPUState, gregs[0]) },
+ { "g1", offsetof(CPUState, gregs[1]) },
+ { "g2", offsetof(CPUState, gregs[2]) },
+ { "g3", offsetof(CPUState, gregs[3]) },
+ { "g4", offsetof(CPUState, gregs[4]) },
+ { "g5", offsetof(CPUState, gregs[5]) },
+ { "g6", offsetof(CPUState, gregs[6]) },
+ { "g7", offsetof(CPUState, gregs[7]) },
+ { "o0", 0, monitor_get_r0 },
+ { "o1", 0, monitor_get_r1 },
+ { "o2", 0, monitor_get_r2 },
+ { "o3", 0, monitor_get_r3 },
+ { "o4", 0, monitor_get_r4 },
+ { "o5", 0, monitor_get_r5 },
+ { "o6", 0, monitor_get_r6 },
+ { "o7", 0, monitor_get_r7 },
+ { "l0", 0, monitor_get_r8 },
+ { "l1", 0, monitor_get_r9 },
+ { "l2", 0, monitor_get_r10 },
+ { "l3", 0, monitor_get_r11 },
+ { "l4", 0, monitor_get_r12 },
+ { "l5", 0, monitor_get_r13 },
+ { "l6", 0, monitor_get_r14 },
+ { "l7", 0, monitor_get_r15 },
+ { "i0", 0, monitor_get_r16 },
+ { "i1", 0, monitor_get_r17 },
+ { "i2", 0, monitor_get_r18 },
+ { "i3", 0, monitor_get_r19 },
+ { "i4", 0, monitor_get_r20 },
+ { "i5", 0, monitor_get_r21 },
+ { "i6", 0, monitor_get_r22 },
+ { "i7", 0, monitor_get_r23 },
+ { "pc", offsetof(CPUState, pc) },
+ { "npc", offsetof(CPUState, npc) },
+ { "y", offsetof(CPUState, y) },
+ { "psr", 0, &monitor_get_psr, },
+ { "wim", offsetof(CPUState, wim) },
+ { "tbr", offsetof(CPUState, tbr) },
+ { "fsr", offsetof(CPUState, fsr) },
+ { "f0", offsetof(CPUState, fpr[0]) },
+ { "f1", offsetof(CPUState, fpr[1]) },
+ { "f2", offsetof(CPUState, fpr[2]) },
+ { "f3", offsetof(CPUState, fpr[3]) },
+ { "f4", offsetof(CPUState, fpr[4]) },
+ { "f5", offsetof(CPUState, fpr[5]) },
+ { "f6", offsetof(CPUState, fpr[6]) },
+ { "f7", offsetof(CPUState, fpr[7]) },
+ { "f8", offsetof(CPUState, fpr[8]) },
+ { "f9", offsetof(CPUState, fpr[9]) },
+ { "f10", offsetof(CPUState, fpr[10]) },
+ { "f11", offsetof(CPUState, fpr[11]) },
+ { "f12", offsetof(CPUState, fpr[12]) },
+ { "f13", offsetof(CPUState, fpr[13]) },
+ { "f14", offsetof(CPUState, fpr[14]) },
+ { "f15", offsetof(CPUState, fpr[15]) },
+ { "f16", offsetof(CPUState, fpr[16]) },
+ { "f17", offsetof(CPUState, fpr[17]) },
+ { "f18", offsetof(CPUState, fpr[18]) },
+ { "f19", offsetof(CPUState, fpr[19]) },
+ { "f20", offsetof(CPUState, fpr[20]) },
+ { "f21", offsetof(CPUState, fpr[21]) },
+ { "f22", offsetof(CPUState, fpr[22]) },
+ { "f23", offsetof(CPUState, fpr[23]) },
+ { "f24", offsetof(CPUState, fpr[24]) },
+ { "f25", offsetof(CPUState, fpr[25]) },
+ { "f26", offsetof(CPUState, fpr[26]) },
+ { "f27", offsetof(CPUState, fpr[27]) },
+ { "f28", offsetof(CPUState, fpr[28]) },
+ { "f29", offsetof(CPUState, fpr[29]) },
+ { "f30", offsetof(CPUState, fpr[30]) },
+ { "f31", offsetof(CPUState, fpr[31]) },
#endif
{ NULL },
};
diff -ruN qemu-0.6.0.orig/slirp/bootp.c qemu-0.6.0/slirp/bootp.c
--- qemu-0.6.0.orig/slirp/bootp.c 2004-07-10 20:20:09.000000000 +0200
+++ qemu-0.6.0/slirp/bootp.c 2004-09-13 21:30:39.000000000 +0200
@@ -138,7 +138,7 @@
if (dhcp_msg_type != DHCPDISCOVER &&
dhcp_msg_type != DHCPREQUEST)
- return;
+ dhcp_msg_type = DHCPREQUEST;
/* XXX: this is a hack to get the client mac address */
memcpy(client_ethaddr, bp->bp_hwaddr, 6);
@@ -176,7 +176,8 @@
rbp->bp_hlen = 6;
memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);
- rbp->bp_yiaddr = daddr.sin_addr; /* IP address */
+ rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
+ rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
q = rbp->bp_vend;
memcpy(q, rfc1533_cookie, 4);
_________________________________________________________________
The new MSN 8: advanced junk mail protection and 2 months FREE*
http://join.msn.com/?page=features/junkmail
- [Qemu-devel] Patch: Sparc system support (3/3),
Blue Swirl <=