qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Patch: Sparc system support (3/3)
@ 2004-09-18  7:44 Blue Swirl
  2004-09-18 17:46 ` Hetz Ben Hamo
  2004-09-19  0:48 ` Derek Fawcus
  0 siblings, 2 replies; 6+ messages in thread
From: Blue Swirl @ 2004-09-18  7:44 UTC (permalink / raw)
  To: qemu-devel

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(&registers[100]);
     _store_xer(env, from_le32(&registers[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(&registers[i], env->gregs[i]);
+    }
+    /* fill in register window */
+    for(i = 0; i < 24; i++) {
+        to_le32(&registers[i + 8], env->regwptr[i]);
+    }
+    /* fill in fprs */
+    for (i = 0; i < 32; i++) {
+        to_le32(&registers[i + 32], *((uint32_t *)&env->fpr[i]));
+    }
+    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+    to_le32(&registers[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(&registers[65], tmp);
+    to_le32(&registers[66], (uint32_t)env->wim);
+    to_le32(&registers[67], (uint32_t)env->tbr);
+    to_le32(&registers[68], (uint32_t)env->pc);
+    to_le32(&registers[69], (uint32_t)env->npc);
+    to_le32(&registers[70], (uint32_t)env->fsr);
+    to_le32(&registers[71], 0); /* csr */
+    to_le32(&registers[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(&registers[i]);
+    }
+    /* fill in register window */
+    for(i = 0; i < 24; i++) {
+        env->regwptr[i] = from_le32(&registers[i]);
+    }
+    /* fill in fprs */
+    for (i = 0; i < 32; i++) {
+        *((uint32_t *)&env->fpr[i]) = from_le32(&registers[i + 32]);
+    }
+    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+    env->y = from_le32(&registers[64]);
+    tmp = from_le32(&registers[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(&registers[66]);
+    env->tbr = from_le32(&registers[67]);
+    env->pc = from_le32(&registers[68]);
+    env->npc = from_le32(&registers[69]);
+    env->fsr = from_le32(&registers[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(&current->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(&current->sigmask_lock);
+        current->blocked = set;
+        recalc_sigpending(current);
+        spin_unlock_irq(&current->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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] Patch: Sparc system support (3/3)
  2004-09-18  7:44 Blue Swirl
@ 2004-09-18 17:46 ` Hetz Ben Hamo
  2004-09-18 18:15   ` Bochnig, Martin
  2004-09-19  0:48 ` Derek Fawcus
  1 sibling, 1 reply; 6+ messages in thread
From: Hetz Ben Hamo @ 2004-09-18 17:46 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl

On Saturday 18 September 2004 10:44 am, Blue Swirl wrote:
> 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.

Hi,

One question: doesn't the sun machine that you emulate requires SCSI devices 
for storage? (if I recall correctly, only the UltraSparc based machines came 
with IDE drives)..

Thanks,
Hetz

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] Patch: Sparc system support (3/3)
  2004-09-18 17:46 ` Hetz Ben Hamo
@ 2004-09-18 18:15   ` Bochnig, Martin
  0 siblings, 0 replies; 6+ messages in thread
From: Bochnig, Martin @ 2004-09-18 18:15 UTC (permalink / raw)
  To: qemu-devel

Hetz Ben Hamo wrote:

> One question: doesn't the sun machine that you emulate requires SCSI devices 
> for storage? (if I recall correctly, only the UltraSparc based machines came 
> with IDE drives)..

While the latter is true, I cannot see any connection with the rest of 
your question.
As the targeted guest OS's (SunOS5.x/Solaris2.x as well as LinUX and 
*BSD) do support both ide and scsi, they should be able to 'see'/access 
their installation medium w/o problems.

I assume, BlueSwirl is facing other problems right now.


mb



> Thanks,
> Hetz

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] Patch: Sparc system support (3/3)
@ 2004-09-18 18:36 Blue Swirl
  2004-09-18 21:38 ` Pavel Janík
  0 siblings, 1 reply; 6+ messages in thread
From: Blue Swirl @ 2004-09-18 18:36 UTC (permalink / raw)
  To: hetz, qemu-devel

>One question: doesn't the sun machine that you emulate requires SCSI 
>devices
>for storage? (if I recall correctly, only the UltraSparc based machines 
>came
>with IDE drives)..

Eventually yes, for now my aim is to get a simple diskless client booting. 
Sun4m architecture was used in diskless JavaStations as well as complete 
workstations with SCSI disks, so it's easy scale the system.

Today I got Proll loading Linux completely for the first time. Linux starts 
executing, but stops at an unimplemented instruction, which shouldn't even 
be there. Mysterious. Could be related to the UDP checksum problems.

If you want to try it, please convert the Proll ELF executable to binary 
with objdump on Sparc machine like this:
objcopy -O binary proll.elf proll.bin

It can load a.out format kernel:
elftoaout -o 0A00020F.PROL vmlinux
qemu-system-sparc -tftp 0A00020F.PROL -user-net -kernel proll.bin

Oh, and tftp patch needs a small hack:
--- slirp/tftp.c        2004-09-18 11:49:34.000000000 +0200
+++ slirp/tftp.c~       2004-09-18 11:29:01.000000000 +0200
@@ -280,7 +280,7 @@

   /* do sanity checks on the filename */

-  if ((spt->filename[0] == '/')
+  if ((spt->filename[0] != '/')
       || (spt->filename[strlen(spt->filename) - 1] == '/')
       ||  strstr(spt->filename, "/../")) {
     n = 2; /* access violation */

_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*. 
http://join.msn.com/?page=features/featuredemail

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] Patch: Sparc system support (3/3)
  2004-09-18 18:36 [Qemu-devel] Patch: Sparc system support (3/3) Blue Swirl
@ 2004-09-18 21:38 ` Pavel Janík
  0 siblings, 0 replies; 6+ messages in thread
From: Pavel Janík @ 2004-09-18 21:38 UTC (permalink / raw)
  To: qemu-devel

   From: "Blue Swirl" <blueswir1@hotmail.com>
   Date: Sat, 18 Sep 2004 20:36:22 +0200

Hi,

   > Today I got Proll loading Linux completely for the first time.

That's wonderful news! Thanks for your work.
-- 
Pavel Janík

It "works"...sorta.  It will compile the kernel.  But in my development
using lots of STL and C++, I've become an expert at generating "Internal
compiler error" with it.  YMMV.
                  -- Bob McElrath in linux-kernel about RH GCC 2.96

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] Patch: Sparc system support (3/3)
  2004-09-18  7:44 Blue Swirl
  2004-09-18 17:46 ` Hetz Ben Hamo
@ 2004-09-19  0:48 ` Derek Fawcus
  1 sibling, 0 replies; 6+ messages in thread
From: Derek Fawcus @ 2004-09-19  0:48 UTC (permalink / raw)
  To: qemu-devel

BTW - some of these set's of patches are broken - it looks like your MUA
      has wrapped the lines.

DF

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-09-19  0:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-18 18:36 [Qemu-devel] Patch: Sparc system support (3/3) Blue Swirl
2004-09-18 21:38 ` Pavel Janík
  -- strict thread matches above, loose matches on Subject: below --
2004-09-18  7:44 Blue Swirl
2004-09-18 17:46 ` Hetz Ben Hamo
2004-09-18 18:15   ` Bochnig, Martin
2004-09-19  0:48 ` Derek Fawcus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).