Re: [Qemu-devel] [PATCH] Sparc32: dummy implementation of MXCC MMU breakpoint registers

2011-06-18 Thread Robert Reif

Blue Swirl wrote:

Add dummy registers for SuperSPARC MXCC MMU counter breakpoints.

Signed-off-by: Blue Swirlblauwir...@gmail.com
---
  target-sparc/cpu.h   |1 +
  target-sparc/op_helper.c |   26 --
  2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 320530e..b5d5291 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -403,6 +403,7 @@ typedef struct CPUSPARCState {
  uint32_t mmuregs[32];
  uint64_t mxccdata[4];
  uint64_t mxccregs[8];
+uint32_t mmubpctrv, mmubpctrc, mmubpctrs, mmubpaction;
  uint64_t mmubpregs[4];
  uint64_t prom_addr;
  #endif
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b38691e..e9cc1f5 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1940,7 +1940,6 @@ uint64_t helper_ld_asi(target_ulong addr, int
asi, int size, int sign)
  case 0x31: // Turbosparc RAM snoop
  case 0x32: // Turbosparc page table descriptor diagnostic
  case 0x39: /* data cache diagnostic register */
-case 0x4c: /* SuperSPARC MMU Breakpoint Action register */
  ret = 0;
  break;
  case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
@@ -1966,6 +1965,18 @@ uint64_t helper_ld_asi(target_ulong addr, int
asi, int size, int sign)
  ret);
  }
  break;
+case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+ret = env-mmubpctrv;
+break;
+case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+ret = env-mmubpctrc;
+break;
+case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+ret = env-mmubpctrs;
+break;
+case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+ret = env-mmubpaction;
+break;
  case 8: /* User code access, XXX */
  default:
  do_unassigned_access(addr, 0, 0, asi, size);
@@ -2304,7 +2315,6 @@ void helper_st_asi(target_ulong addr, uint64_t
val, int asi, int size)
 // descriptor diagnostic
  case 0x36: /* I-cache flash clear */
  case 0x37: /* D-cache flash clear */
-case 0x4c: /* breakpoint action */
  break;
  case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
  {
@@ -2328,6 +2338,18 @@ void helper_st_asi(target_ulong addr, uint64_t
val, int asi, int size)
  env-mmuregs[reg]);
  }
  break;
+case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+env-mmubpctrv = val  0x;
+break;
+case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+env-mmubpctrc = val  0x3;
+break;
+case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+env-mmubpctrs = val  0x3;
+break;
+case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+env-mmubpaction = val  0x1fff;
+break;
  case 8: /* User code access, XXX */
  case 9: /* Supervisor code access, XXX */
  default:
   

The breakpoint action register is 64 bits wide.



Re: [Qemu-devel] [sparc] Floating point exception issue

2011-01-22 Thread Robert Reif

Blue Swirl wrote:

On Sat, Jan 22, 2011 at 3:30 PM, Mateusz Loskotmate...@loskot.net  wrote:
   

On 18/01/11 21:51, Blue Swirl wrote:
 

On Tue, Jan 18, 2011 at 6:00 PM, Mateusz Loskotmate...@loskot.net  wrote:
   

On 18/01/11 17:36, Blue Swirl wrote:
 

On Tue, Jan 18, 2011 at 3:27 PM, Mateusz Loskotmate...@loskot.net
  wrote:
   

Hi,

Recently, I have reported mysterious issues on NetBSD 5.1
emulated on SPARC. The whole first thread is here:

http://lists.gnu.org/archive/html/qemu-devel/2011-01/msg01509.html

I decided to investigate the problem deeper and with great help
from NetBSD folks, I managed to find reproducible test case.
Initially, it was AWK command:

# echo NaN | awk '{print test}'
awk: floating point exception 8
  source line number 1

and next it boiled down to simple C program (see below).
Details of the investigation are archived in the NetBSD Problem
Report #44389 here:

http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=44389


Here is final version of the test program which reproduces the problem:

#includestdio.h
#includestdlib.h
#includemath.h
#includeerrno.h

int is_number(const char *s)
{
double r;
char *ep;
errno = 0;
r = strtod(s,ep);
if (r == HUGE_VAL)
printf(X:%g\n, r);

if (ep == s || r == HUGE_VAL || errno == ERANGE)
return 0;
while (*ep == ' ' || *ep == '\t' || *ep == '\n')
ep++;
if (*ep == '\0')
return 1;
else
return 0;
}

int main(int argc, char **argv)
{
double v;

if (is_number(NaN)) {
printf(is a number\n);
v = atof(NaN);
} else {
printf(not a number\n);
v = 0.0;
}
printf(%.4f\n, v);

return 0;
}


On NetBSD/SPARC, the program receives SIGFPE:

$ gcc ./nan_test_2.c
  $ ./a.out
  [1]   Floating point exception (core dumped) ./a.out

Specifically, it's caused by r == HUGE_VAL condition in
  if (ep == s || r == HUGE_VAL || errno == ERANGE)
where r is NaN.

All the signs indicate there is a bug in QEMU.
 

I'll install 5.1, but on 4.0 which I had installed, the program works
fine:
$ ./sigfpe
is a number
nan
   

I just tested on NetBSD 5.0/SPARC under QEMU 0.13 (same version I use with
NetBSD 5.1/SPARC) and it works well indeed:

mloskot@qemu-netbsd-50-sparc:~/tmp# ./a.out
is a number
nan
mloskot@qemu-netbsd-50-sparc:~/tmp#

Hmm, this is becoming interesting.

I run QEMU 0.13 on Windows Vista (64-bit).
Perhaps host system and QEMU binaries are relevant here.
I will try on Linux host system later tonight.

BTW, here are my images:

http://mateusz.loskot.net/tmp/qemu/
 

The problem was with NaN handling in fcmped instruction. I've
committed a patch that fixes the problem, please test. Thanks for
reporting and the test case.
   

FYI, this problem seems to be occurring in qemu on Windows only.
I tested git version dated before you applied the fix
and built on Linux and the problem does not happening there.
 

No, it was generic problem. I could reproduce it with your test case
and with a small assembler program which only used fcmped using user
emulator.


   
There is still a floating point exception problem that may or may not be 
related.


Booting an ss5-170 with a real sun ROM image still fails FP tests:

4.1.1  fpureg  regfile  Pass
4.1.2  fpureg  misalign Pass
4.1.3  fpureg  single precision Pass
4.1.4  fpureg  double precision Pass
4.2.1  fpuexceptions   single precision Failed
Exception Didn't Block Store : 0 : exp= , obs= 
4.2.2  fpuexceptions   double precision Failed
Exception Didn't Block Store : 0 : exp= , obs= 




[Qemu-devel] [PATCH] target-sparc/translate.c microSPARC II mask fix

2008-03-05 Thread Robert Reif

Fix microSPARC II SFSR mask.
diff -p -u -r1.96 translate.c
--- target-sparc/translate.c5 Mar 2008 17:59:48 -   1.96
+++ target-sparc/translate.c6 Mar 2008 02:15:30 -
@@ -4259,7 +4259,7 @@ static const sparc_def_t sparc_defs[] = 
 .mmu_bm = 0x4000,
 .mmu_ctpr_mask = 0x00c0,
 .mmu_cxr_mask = 0x00ff,
-.mmu_sfsr_mask = 0x00016bff,
+.mmu_sfsr_mask = 0x00016fff,
 .mmu_trcr_mask = 0x00ff,
 },
 {


[Qemu-devel] [PATCH] hw/sun4m.c show IRQ set or reset

2008-03-02 Thread Robert Reif

Show which CPU IRQ is actually being set or reset when debugging.
diff -p -u -r1.86 sun4m.c
--- hw/sun4m.c  2 Mar 2008 08:48:47 -   1.86
+++ hw/sun4m.c  3 Mar 2008 00:35:29 -
@@ -258,12 +258,15 @@ void cpu_check_irqs(CPUState *env)
 int old_interrupt = env-interrupt_index;
 
 env-interrupt_index = TT_EXTINT | i;
-if (old_interrupt != env-interrupt_index)
+if (old_interrupt != env-interrupt_index) {
+DPRINTF(Set CPU IRQ %d\n, i);
 cpu_interrupt(env, CPU_INTERRUPT_HARD);
+}
 break;
 }
 }
 } else if (!env-pil_in  (env-interrupt_index  ~15) == TT_EXTINT) {
+DPRINTF(Reset CPU IRQ %d\n, env-interrupt_index  15);
 env-interrupt_index = 0;
 cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
 }


[Qemu-devel] [PATCH] hw/slavio_timer.c remove unneeded qemu_irq_lower

2008-03-02 Thread Robert Reif
Remove unneeded qemu_irq_lower because user mode timers don't support 
IRQs and the IRQ is lowered when switching to user mode.
diff -p -u -r1.30 slavio_timer.c
--- hw/slavio_timer.c   26 Jan 2008 09:13:46 -  1.30
+++ hw/slavio_timer.c   3 Mar 2008 00:35:28 -
@@ -192,7 +192,6 @@ static void slavio_timer_mem_writel(void
 uint64_t count;
 
 // set user counter MSW, reset counter
-qemu_irq_lower(s-irq);
 s-limit = TIMER_MAX_COUNT64;
 s-counthigh = val  (TIMER_MAX_COUNT64  32);
 s-reached = 0;
@@ -218,7 +217,6 @@ static void slavio_timer_mem_writel(void
 uint64_t count;
 
 // set user counter LSW, reset counter
-qemu_irq_lower(s-irq);
 s-limit = TIMER_MAX_COUNT64;
 s-count = val  TIMER_MAX_COUNT64;
 s-reached = 0;


Re: [Qemu-devel] qemu-system-sparc and Solaris 1.1.2 / SunOS 4.1.4

2008-02-19 Thread Robert Reif

Andrew Warkentin wrote:



SunOS might run in TME (http://people.csail.mit.edu/fredette/tme/). I 
don't think anything other than Linux runs in QEMU's Sun emulation (or 
for that matter, any of the non-PC QEMU emulators).



Unfortunately TME only emulates a SPARCstation2 (sun4c).

I have only been able to get linux running with QEMU and it seems stable.
I have tried numerous versions of solaris and bsd without success.

I have been unable to get any version of an Open Boot PROM for any
machine working.  We are at the point now where the images actually
run but fail the self tests and hang while accessing the floppy during
the initialization stage.  QEMU hardware emulation is just not good
enough for for this yet.

I would like to see QEMU emulation good enough to be able to run
Open Boot PROM images well enough to load an OS.  At that point
solaris and bsd will probably work and OpenBIOS can be fixed.





Re: [Qemu-devel] qemu-system-sparc and Solaris 1.1.2 / SunOS 4.1.4

2008-02-18 Thread Robert Reif

Jan Holzhueter wrote:


Hi everyone,
we are planing to get rid of some old sparc hardware.
The problem is that there are applications on it that require
sun4m and Solaris 1.1.2 / SunOS 4.1.4.
As known qemu-system-sparc is not able to boot the Solaris Kernel at
the moment.

I get as far as:
  [sparc] Booting file 'cdrom' with parameters ''
Not a bootable ELF image
Not a Linux kernel image
Not a bootable a.out image
Not a bootable ELF image
Not a Linux kernel image
Loading a.out image...
Loaded 7680 bytes
entry point is 0x4000
Jumping to entry point...
checksum 60746d10 != 86693bac, trying to boot anyway
Unhandled Exception 0x0007
PC = 0x002002bc NPC = 0x002002c0
Stopping execution

My question is how far away are you form getting it to work
and in what time frame could it be done?

This is a bigger project for us. So it might even be possible
( nothing confirmed yet I have to check back with some people  )
to donate some money to get it to work.
It doesn't need to work for all Solaris. We just need Solaris 1.1.2.
If someone needs some installation Medium or feedback let me know.

Greetings
Jan Holzhüter



This may be an openbios issue.  Changing openbios boot.c cdrom
oldpath to sd(0,2,0):d gets past this error but it still doesn't boot.





[Qemu-devel] [PATCH] sparc32 mmu register fixes

2008-02-10 Thread Robert Reif
This patch gets openboot prom mmu register self tests passing for lx, 
ss4, ss5 and ss10 prom images.
Index: target-sparc/cpu.h
===
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.61
diff -p -u -r1.61 cpu.h
--- target-sparc/cpu.h  28 Nov 2007 20:54:33 -  1.61
+++ target-sparc/cpu.h  11 Feb 2008 00:07:10 -
@@ -198,6 +198,10 @@ typedef struct CPUSPARCState {
 int interrupt_request;
 int halted;
 uint32_t mmu_bm;
+uint32_t mmu_ctpr_mask;
+uint32_t mmu_cxr_mask;
+uint32_t mmu_sfsr_mask;
+uint32_t mmu_trcr_mask;
 /* NOTE: we allow 8 more registers to handle wrapping */
 target_ulong regbase[NWINDOWS * 16 + 8];
 
Index: target-sparc/helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/helper.c,v
retrieving revision 1.33
diff -p -u -r1.33 helper.c
--- target-sparc/helper.c   25 Dec 2007 07:49:10 -  1.33
+++ target-sparc/helper.c   11 Feb 2008 00:07:11 -
@@ -129,7 +129,7 @@ int get_physical_address (CPUState *env,
 
 /* SPARC reference MMU table walk: Context table-L1-L2-PTE */
 /* Context base + context number */
-pde_ptr = ((env-mmuregs[1]  ~63) 4) + (env-mmuregs[2]  2);
+pde_ptr = (env-mmuregs[1]  4) + (env-mmuregs[2]  2);
 pde = ldl_phys(pde_ptr);
 
 /* Ctx pde */
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.65
diff -p -u -r1.65 op_helper.c
--- target-sparc/op_helper.c1 Jan 2008 17:07:39 -   1.65
+++ target-sparc/op_helper.c11 Feb 2008 00:07:12 -
@@ -591,7 +591,7 @@ void helper_st_asi(int asi, int size)
 
 oldreg = env-mmuregs[reg];
 switch(reg) {
-case 0:
+case 0: // Control Register
 env-mmuregs[reg] = (env-mmuregs[reg]  0xff00) |
 (T1  0x00ff);
 // Mappings generated during no-fault mode or MMU
@@ -600,21 +600,27 @@ void helper_st_asi(int asi, int size)
 (env-mmuregs[reg]  (MMU_E | MMU_NF | env-mmu_bm)))
 tlb_flush(env, 1);
 break;
-case 2:
-env-mmuregs[reg] = T1;
+case 1: // Context Table Pointer Register
+env-mmuregs[reg] = T1  env-mmu_ctpr_mask;
+break;
+case 2: // Context Register
+env-mmuregs[reg] = T1  env-mmu_cxr_mask;
 if (oldreg != env-mmuregs[reg]) {
 /* we flush when the MMU context changes because
QEMU has no MMU context support */
 tlb_flush(env, 1);
 }
 break;
-case 3:
-case 4:
+case 3: // Synchronous Fault Status Register with Clear
+case 4: // Synchronous Fault Address Register
+break;
+case 0x10: // TLB Replacement Control Register
+env-mmuregs[reg] = T1  env-mmu_trcr_mask;
 break;
-case 0x13:
-env-mmuregs[3] = T1;
+case 0x13: // Synchronous Fault Status Register with Read and Clear
+env-mmuregs[3] = T1  env-mmu_sfsr_mask;
 break;
-case 0x14:
+case 0x14: // Synchronous Fault Address Register
 env-mmuregs[4] = T1;
 break;
 default:
Index: target-sparc/translate.c
===
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.86
diff -p -u -r1.86 translate.c
--- target-sparc/translate.c1 Feb 2008 10:50:11 -   1.86
+++ target-sparc/translate.c11 Feb 2008 00:07:14 -
@@ -62,6 +62,10 @@ struct sparc_def_t {
 uint32_t fpu_version;
 uint32_t mmu_version;
 uint32_t mmu_bm;
+uint32_t mmu_ctpr_mask;
+uint32_t mmu_cxr_mask;
+uint32_t mmu_sfsr_mask;
+uint32_t mmu_trcr_mask;
 };
 
 static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
@@ -3758,6 +3762,10 @@ CPUSPARCState *cpu_sparc_init(const char
 env-fsr = def-fpu_version;
 #if !defined(TARGET_SPARC64)
 env-mmu_bm = def-mmu_bm;
+env-mmu_ctpr_mask = def-mmu_ctpr_mask;
+env-mmu_cxr_mask = def-mmu_cxr_mask;
+env-mmu_sfsr_mask = def-mmu_sfsr_mask;
+env-mmu_trcr_mask = def-mmu_trcr_mask;
 env-mmuregs[0] |= def-mmu_version;
 cpu_sparc_set_id(env, 0);
 #endif
@@ -3887,6 +3895,10 @@ static const sparc_def_t sparc_defs[] = 
 .fpu_version = 4  17, /* FPU version 4 (Meiko) */
 .mmu_version = 0x00  24, /* Impl 0, ver 0 */
 .mmu_bm = 0x4000,
+.mmu_ctpr_mask = 0x0070,
+.mmu_cxr_mask = 0x003f,
+

Re: [Qemu-devel] [PATCH] hw/sun4m.c fix power addresses

2008-01-26 Thread Robert Reif

Blue Swirl wrote:


On 1/25/08, Robert Reif [EMAIL PROTECTED] wrote:
 


Blue Swirl wrote:

   


On 1/24/08, Robert Reif [EMAIL PROTECTED] wrote:


 


diff -p -u -r1.81 sun4m.c


   


This breaks my tests, so I guess a fix is also needed for OpenBIOS.


 


Probably, they were tested using ss5/170 and ss10 openboot images.
   



I just noticed that we have confused the devices that OBP calls
'power' and 'power-management'. Power or Aux 2 or Software Powerdown
Control can be used to reset or power down the system. OBP trees
confirm that it is located at 0x7191 on SS-5 and 0xff1a01000 on
SS-10/20. It does not exist on SS-600.

Power-management a.k.a. APC is used to halt the CPU when idle. It is
located at 0x6a00 on SS-5. It does not exist on SS-x0 or SS-600.

So, Aux2 on SS-10/20 and APC on SS-5 should move to the correct locations.

Now, what to do with the rest? These are motherboard devices, they
cannot be added to or removed from real life hardware. Leaving the
devices out to improve historical accuracy would mean that the system
can't be reset or powered down on SS-600, and on SS-10/20/600 Qemu
will consume 100% of host CPU even when the target is idling. This
would not be an improvement in usability for sure.
 

I have a patch waiting to fix the power/aux2 and also aux1.  It adds a 
seperate address for auxio.


power and AUX2 are the same devices on ss5,10 and 20 but at different 
addresse/offsets.  600mp doesn't have it.
auxio is AUX1 and are the sort of the same devices on an ss5 and 10/20 
but at different address/offsets.  600mp doesn't have it.

The AUX1 bit layout of an ss5 (SLAVIO) is also different from a 10/20 (SEC).

I'm not sure how power-management fits in there other than it's an sbus 
device: ffd50130 [EMAIL PROTECTED],a00






Re: [Qemu-devel] [PATCH] hw/slavio_timer.c user timer mode change fix

2008-01-25 Thread Robert Reif

Blue Swirl wrote:


On 1/23/08, Robert Reif [EMAIL PROTECTED] wrote:
 


Change ptimer limit only when mode changes.
Update timer configuration register user timer bits properly.
   



The patch does not apply.


It should apply on top of the first user timer patch that is in CVS now.





Re: [Qemu-devel] [PATCH] hw/slavio_timer.c user timer mode change fix

2008-01-25 Thread Robert Reif

Rediffed against cvs.
diff -p -u -r1.29 slavio_timer.c
--- hw/slavio_timer.c   25 Jan 2008 19:51:27 -  1.29
+++ hw/slavio_timer.c   25 Jan 2008 21:50:35 -
@@ -199,10 +199,8 @@ static void slavio_timer_mem_writel(void
 count = ((uint64_t)s-counthigh  32) | s-count;
 DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
 count);
-if (s-timer) {
+if (s-timer)
 ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
-}
 } else {
 // set limit, reset counter
 qemu_irq_lower(s-irq);
@@ -227,10 +225,8 @@ static void slavio_timer_mem_writel(void
 count = ((uint64_t)s-counthigh)  32 | s-count;
 DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
 count);
-if (s-timer) {
+if (s-timer)
 ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
-}
 } else
 DPRINTF(not user timer\n);
 break;
@@ -265,22 +261,38 @@ static void slavio_timer_mem_writel(void
 unsigned int i;
 
 for (i = 0; i  s-num_slaves; i++) {
-if (val  (1  i)) {
-qemu_irq_lower(s-slave[i]-irq);
-s-slave[i]-limit = -1ULL;
-} else {
-ptimer_stop(s-slave[i]-timer);
-}
-if ((val  (1  i)) != (s-slave_mode  (1  i))) {
-ptimer_stop(s-slave[i]-timer);
-ptimer_set_limit(s-slave[i]-timer,
- LIMIT_TO_PERIODS(s-slave[i]-limit), 1);
-DPRINTF(processor %d timer changed\n,
-s-slave[i]-slave_index);
-ptimer_run(s-slave[i]-timer, 0);
+unsigned int processor = 1  i;
+// check for a change in timer mode for this processor
+if ((val  processor) != (s-slave_mode  processor)) {
+if (val  processor) { // counter - user timer
+qemu_irq_lower(s-slave[i]-irq);
+// counters are always running
+ptimer_stop(s-slave[i]-timer);
+s-slave[i]-running = 0;
+// user timer limit is always the same
+s-slave[i]-limit = TIMER_MAX_COUNT64;
+ptimer_set_limit(s-slave[i]-timer,
+ LIMIT_TO_PERIODS(s-slave[i]-limit), 
1);
+// set this processors user timer bit in config
+// register
+s-slave_mode |= processor;
+DPRINTF(processor %d changed from counter to user 
+timer\n, s-slave[i]-slave_index);
+} else { // user timer - counter
+// stop the user timer if it is running
+if (s-slave[i]-running)
+ptimer_stop(s-slave[i]-timer);
+// start the counter
+ptimer_run(s-slave[i]-timer, 0);
+s-slave[i]-running = 1;
+// clear this processors user timer bit in config 
+// register
+s-slave_mode = ~processor;
+DPRINTF(processor %d changed from user timer to 
+counter\n, s-slave[i]-slave_index);
+}
 }
 }
-s-slave_mode = val  ((1  s-num_slaves) - 1);
 } else
 DPRINTF(not system timer\n);
 break;


Re: [Qemu-devel] [PATCH] hw/sun4m.c fix power addresses

2008-01-25 Thread Robert Reif

Blue Swirl wrote:


On 1/24/08, Robert Reif [EMAIL PROTECTED] wrote:
 


diff -p -u -r1.81 sun4m.c
   



This breaks my tests, so I guess a fix is also needed for OpenBIOS.
 


Probably, they were tested using ss5/170 and ss10 openboot images.





Re: [Qemu-devel] qemu cpu-all.h cpu-exec.c qemu-doc.texi vl.c

2008-01-24 Thread Robert Reif



Exactly which version of gcc is this? It appears to work fine with at
least some gcc 3 versions.

 


gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

Standard Red Hat 9.





[Qemu-devel] [PATCH] hs/iommu.c add turboSPARC mask id register

2008-01-23 Thread Robert Reif

Add microSPARC II and turboSPARC mask ID register support.
Index: hw/iommu.c
===
RCS file: /sources/qemu/qemu/hw/iommu.c,v
retrieving revision 1.25
diff -p -u -r1.25 iommu.c
--- hw/iommu.c  1 Jan 2008 17:06:38 -   1.25
+++ hw/iommu.c  23 Jan 2008 14:06:26 -
@@ -34,7 +34,7 @@ do { printf(IOMMU:  fmt , ##args); } w
 #define DPRINTF(fmt, args...)
 #endif
 
-#define IOMMU_NREGS (3*4096/4)
+#define IOMMU_NREGS (4*4096/4)
 #define IOMMU_CTRL  (0x  2)
 #define IOMMU_CTRL_IMPL 0xf000 /* Implementation */
 #define IOMMU_CTRL_VERS 0x0f00 /* Version */
@@ -95,6 +95,12 @@ do { printf(IOMMU:  fmt , ##args); } w
 #define IOMMU_ARBEN_MASK0x001f
 #define IOMMU_MID   0x0008
 
+#define IOMMU_MASK_ID   (0x3018  2) /* Mask ID */
+#define IOMMU_MASK_ID_MASK  0x00ff
+
+#define IOMMU_MSII_MASK 0x2600 /* microSPARC II mask number */
+#define IOMMU_TS_MASK   0x2300 /* turboSPARC mask number */
+
 /* The format of an iopte in the page tables */
 #define IOPTE_PAGE  0xff00 /* Physical page number (PA[35:12]) */
 #define IOPTE_CACHE 0x0080 /* Cached (in vme IOCACHE or
@@ -206,6 +212,9 @@ static void iommu_mem_writel(void *opaqu
 // addresses, fault cause and address stored to MMU/IOMMU
 s-regs[saddr] = (val  IOMMU_ARBEN_MASK) | IOMMU_MID;
 break;
+case IOMMU_MASK_ID:
+s-regs[saddr] |= (val  IOMMU_MASK_ID_MASK);
+break;
 default:
 s-regs[saddr] = val;
 break;
@@ -337,6 +346,7 @@ static void iommu_reset(void *opaque)
 s-regs[IOMMU_CTRL] = s-version;
 s-regs[IOMMU_ARBEN] = IOMMU_MID;
 s-regs[IOMMU_AFSR] = IOMMU_AFSR_RESV;
+s-regs[IOMMU_MASK_ID] = IOMMU_TS_MASK;
 qemu_irq_lower(s-irq);
 }
 


Re: [Qemu-devel] qemu cpu-all.h cpu-exec.c qemu-doc.texi vl.c

2008-01-23 Thread Robert Reif

Thiemo Seufer wrote:


CVSROOT:/sources/qemu
Module name:qemu
Changes by: Thiemo Seufer ths   08/01/23 19:01:12

Modified files:
	.  : cpu-all.h cpu-exec.c qemu-doc.texi vl.c 


Log message:
Add option to disable TB cache, by Herve Poussineau.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/cpu-all.h?cvsroot=qemur1=1.81r2=1.82
http://cvs.savannah.gnu.org/viewcvs/qemu/cpu-exec.c?cvsroot=qemur1=1.130r2=1.131
http://cvs.savannah.gnu.org/viewcvs/qemu/qemu-doc.texi?cvsroot=qemur1=1.182r2=1.183
http://cvs.savannah.gnu.org/viewcvs/qemu/vl.c?cvsroot=qemur1=1.400r2=1.401



 


This gives the following compile errror:

gcc -Wall -O2 -g -fno-strict-aliasing -fomit-frame-pointer -I. -I.. 
-I/home/wine/qemu/target-i386 -I/home/wine/qemu -MMD -MP -DNEED_CPU_H 
-I/home/wine/qemu/linux-user -I/home/wine/qemu/linux-user/i386 
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
-I/home/wine/qemu/fpu -DHAS_AUDIO -DHAS_AUDIO_CHOICE 
-I/home/wine/qemu/slirp-c -o cpu-exec.o /home/wine/qemu/cpu-exec.c

/home/wine/qemu/cpu-exec.c: In function `cmp1':
/home/wine/qemu/cpu-exec.c:143: unable to find a register to spill in 
class `DIREG'

/home/wine/qemu/cpu-exec.c:143: this is the insn:
(insn 21 78 23 (parallel[
   (set (reg:SI 2 ecx [64])
   (unspec:SI[
   (mem:BLK (reg/f:SI 1 edx [66]) [0 A8])
   (reg:QI 0 al [68])
   (const_int 1 [0x1])
   (reg:SI 2 ecx [67])
   ]  0))
   (use (reg:SI 19 dirflag))
   (clobber (reg/f:SI 1 edx [66]))
   (clobber (reg:CC 17 flags))
   ] ) 623 {strlenqi_1} (insn_list 15 (insn_list 17 (insn_list 19 
(insn_list 20 (nil)

   (expr_list:REG_DEAD (reg:SI 19 dirflag)
   (expr_list:REG_DEAD (reg:SI 2 ecx [67])
   (expr_list:REG_DEAD (reg:QI 0 al [68])
   (expr_list:REG_DEAD (reg/f:SI 1 edx [66])
   (expr_list:REG_UNUSED (reg/f:SI 1 edx [66])
   (expr_list:REG_UNUSED (reg:CC 17 flags)
   (nil
/home/wine/qemu/cpu-exec.c:143: confused by earlier errors, bailing out
make[1]: *** [cpu-exec.o] Error 1
make[1]: Leaving directory `/home/wine/qemu/i386-linux-user'
make: *** [subdir-i386-linux-user] Error 2






[Qemu-devel] [PATCH] hw/sun4m.c fix power addresses

2008-01-23 Thread Robert Reif


diff -p -u -r1.81 sun4m.c
--- hw/sun4m.c  17 Jan 2008 21:04:16 -  1.81
+++ hw/sun4m.c  24 Jan 2008 05:06:38 -
@@ -687,7 +687,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0x7840,
 .esp_base = 0x7880,
 .le_base  = 0x78c0,
-.power_base   = 0x7a00,
+.power_base   = 0x7191,
 .ecc_base = -1,
 .sun4c_intctl_base  = -1,
 .sun4c_counter_base = -1,
@@ -727,7 +727,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0xef040ULL,
 .esp_base = 0xef080ULL,
 .le_base  = 0xef0c0ULL,
-.power_base   = 0xefa00ULL,
+.power_base   = 0xff1a01000ULL,
 .ecc_base = 0xfULL,
 .ecc_version  = 0x1000, // version 0, implementation 1
 .sun4c_intctl_base  = -1,
@@ -811,7 +811,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0xef040ULL,
 .esp_base = 0xef080ULL,
 .le_base  = 0xef0c0ULL,
-.power_base   = 0xefa00ULL,
+.power_base   = 0xff1a01000ULL,
 .ecc_base = 0xfULL,
 .ecc_version  = 0x2000, // version 0, implementation 2
 .sun4c_intctl_base  = -1,


[Qemu-devel] [PATCH] hw/slavio_timer.c user timer limit bit fix

2008-01-22 Thread Robert Reif

Set limit bit when user timer expires.
Clear limit bit when user timer count set.
Set ptimer count when user timer count set.
Index: hw/slavio_timer.c
===
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.28
diff -p -u -r1.28 slavio_timer.c
--- hw/slavio_timer.c   1 Jan 2008 17:06:38 -   1.28
+++ hw/slavio_timer.c   23 Jan 2008 02:33:57 -
@@ -122,10 +122,9 @@ static void slavio_timer_irq(void *opaqu
 
 slavio_timer_get_out(s);
 DPRINTF(callback: count %x%08x\n, s-counthigh, s-count);
-if (!slavio_timer_is_user(s)) {
-s-reached = TIMER_REACHED;
+s-reached = TIMER_REACHED;
+if (!slavio_timer_is_user(s))
 qemu_irq_raise(s-irq);
-}
 }
 
 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
@@ -141,7 +140,7 @@ static uint32_t slavio_timer_mem_readl(v
 if (slavio_timer_is_user(s)) {
 // read user timer MSW
 slavio_timer_get_out(s);
-ret = s-counthigh;
+ret = s-counthigh | s-reached;
 } else {
 // read limit
 // clear irq
@@ -155,7 +154,7 @@ static uint32_t slavio_timer_mem_readl(v
 // of counter (user mode)
 slavio_timer_get_out(s);
 if (slavio_timer_is_user(s)) // read user timer LSW
-ret = s-count  TIMER_COUNT_MASK32;
+ret = s-count  TIMER_MAX_COUNT64;
 else // read limit
 ret = (s-count  TIMER_MAX_COUNT32) | s-reached;
 break;
@@ -190,12 +189,19 @@ static void slavio_timer_mem_writel(void
 switch (saddr) {
 case TIMER_LIMIT:
 if (slavio_timer_is_user(s)) {
+uint64_t count;
 // set user counter MSW, reset counter
 qemu_irq_lower(s-irq);
 s-limit = TIMER_MAX_COUNT64;
-DPRINTF(processor %d user timer reset\n, s-slave_index);
-if (s-timer)
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1);
+s-counthigh = val  (TIMER_MAX_COUNT64  32);
+s-reached = 0;
+count = ((uint64_t)s-counthigh  32) | s-count;
+DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
+count);
+if (s-timer) {
+ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
+}
 } else {
 // set limit, reset counter
 qemu_irq_lower(s-irq);
@@ -210,12 +216,19 @@ static void slavio_timer_mem_writel(void
 break;
 case TIMER_COUNTER:
 if (slavio_timer_is_user(s)) {
+uint64_t count;
 // set user counter LSW, reset counter
 qemu_irq_lower(s-irq);
 s-limit = TIMER_MAX_COUNT64;
-DPRINTF(processor %d user timer reset\n, s-slave_index);
-if (s-timer)
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1);
+s-count = val  TIMER_MAX_COUNT64;
+s-reached = 0;
+count = ((uint64_t)s-counthigh)  32 | s-count;
+DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
+count);
+if (s-timer) {
+ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
+}
 } else
 DPRINTF(not user timer\n);
 break;


[Qemu-devel] [PATCH] hw/slavio_timer.c user timer mode change fix

2008-01-22 Thread Robert Reif

Change ptimer limit only when mode changes.
Update timer configuration register user timer bits properly.
--- hw/slavio_timer.c.old   2008-01-22 21:35:33.0 -0500
+++ hw/slavio_timer.c   2008-01-22 21:36:13.0 -0500
@@ -198,10 +198,8 @@ static void slavio_timer_mem_writel(void
 count = ((uint64_t)s-counthigh  32) | s-count;
 DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
 count);
-if (s-timer) {
+if (s-timer)
 ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
-}
 } else {
 // set limit, reset counter
 qemu_irq_lower(s-irq);
@@ -225,10 +223,8 @@ static void slavio_timer_mem_writel(void
 count = ((uint64_t)s-counthigh)  32 | s-count;
 DPRINTF(processor %d user timer set to %016llx\n, s-slave_index,
 count);
-if (s-timer) {
+if (s-timer)
 ptimer_set_count(s-timer, LIMIT_TO_PERIODS(s-limit - count));
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
-}
 } else
 DPRINTF(not user timer\n);
 break;
@@ -263,22 +259,38 @@ static void slavio_timer_mem_writel(void
 unsigned int i;
 
 for (i = 0; i  s-num_slaves; i++) {
-if (val  (1  i)) {
-qemu_irq_lower(s-slave[i]-irq);
-s-slave[i]-limit = -1ULL;
-} else {
-ptimer_stop(s-slave[i]-timer);
-}
-if ((val  (1  i)) != (s-slave_mode  (1  i))) {
-ptimer_stop(s-slave[i]-timer);
-ptimer_set_limit(s-slave[i]-timer,
- LIMIT_TO_PERIODS(s-slave[i]-limit), 1);
-DPRINTF(processor %d timer changed\n,
-s-slave[i]-slave_index);
-ptimer_run(s-slave[i]-timer, 0);
+unsigned int processor = 1  i;
+// check for a change in timer mode for this processor
+if ((val  processor) != (s-slave_mode  processor)) {
+if (val  processor) { // counter - user timer
+qemu_irq_lower(s-slave[i]-irq);
+// counters are always running
+ptimer_stop(s-slave[i]-timer);
+s-slave[i]-running = 0;
+// user timer limit is always the same
+s-slave[i]-limit = TIMER_MAX_COUNT64;
+ptimer_set_limit(s-slave[i]-timer,
+ LIMIT_TO_PERIODS(s-slave[i]-limit), 
1);
+// set this processors user timer bit in config
+// register
+s-slave_mode |= processor;
+DPRINTF(processor %d changed from counter to user 
+timer\n, s-slave[i]-slave_index);
+} else { // user timer - counter
+// stop the user timer if it is running
+if (s-slave[i]-running)
+ptimer_stop(s-slave[i]-timer);
+// start the counter
+ptimer_run(s-slave[i]-timer, 0);
+s-slave[i]-running = 1;
+// clear this processors user timer bit in config 
+// register
+s-slave_mode = ~processor;
+DPRINTF(processor %d changed from user timer to 
+counter\n, s-slave[i]-slave_index);
+}
 }
 }
-s-slave_mode = val  ((1  s-num_slaves) - 1);
 } else
 DPRINTF(not system timer\n);
 break;


[Qemu-devel] [PATCH] sparc32: add ecc irq

2008-01-06 Thread Robert Reif


Index: hw/eccmemctl.c
===
RCS file: /sources/qemu/qemu/hw/eccmemctl.c,v
retrieving revision 1.2
diff -p -u -r1.2 eccmemctl.c
--- hw/eccmemctl.c  1 Jan 2008 17:06:38 -   1.2
+++ hw/eccmemctl.c  6 Jan 2008 15:03:52 -
@@ -68,7 +68,7 @@
 #define ECC_FAR0_TYPE  0x00f0  /* Transaction type */
 #define ECC_FAR0_SIZE  0x0700  /* Transaction size */
 #define ECC_FAR0_CACHE 0x0800  /* Mapped cacheable */
-#define ECC_FAR0_LOCK  0x1000  /* Error occurred in attomic cycle */
+#define ECC_FAR0_LOCK  0x1000  /* Error occurred in atomic cycle */
 #define ECC_FAR0_BMODE 0x2000  /* Boot mode */
 #define ECC_FAR0_VADDR 0x003fc000  /* VA[12-19] (superset bits) */
 #define ECC_FAR0_S 0x0800  /* Supervisor mode */
@@ -90,6 +90,7 @@
 #define ECC_ADDR_MASK  (ECC_SIZE - 1)
 
 typedef struct ECCState {
+qemu_irq irq;
 uint32_t regs[ECC_NREGS];
 } ECCState;
 
@@ -222,7 +223,7 @@ static void ecc_reset(void *opaque)
 s-regs[i] = 0;
 }
 
-void * ecc_init(target_phys_addr_t base, uint32_t version)
+void * ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version)
 {
 int ecc_io_memory;
 ECCState *s;
@@ -232,6 +233,7 @@ void * ecc_init(target_phys_addr_t base,
 return NULL;
 
 s-regs[0] = version;
+s-irq = irq;
 
 ecc_io_memory = cpu_register_io_memory(0, ecc_mem_read, ecc_mem_write, s);
 cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory);
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.80
diff -p -u -r1.80 sun4m.c
--- hw/sun4m.c  6 Jan 2008 07:50:38 -   1.80
+++ hw/sun4m.c  6 Jan 2008 15:03:52 -
@@ -91,7 +91,7 @@ struct hwdef {
 // IRQ numbers are not PIL ones, but master interrupt controller
 // register bit numbers
 int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
-int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
+int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq, ecc_irq;
 int machine_id; // For NVRAM
 uint32_t iommu_version;
 uint32_t intbit_to_level[32];
@@ -528,7 +528,8 @@ static void sun4m_hw_init(const struct h
graphic_height, graphic_depth, hwdef-machine_id, Sun4m);
 
 if (hwdef-ecc_base != (target_phys_addr_t)-1)
-ecc_init(hwdef-ecc_base, hwdef-ecc_version);
+ecc_init(hwdef-ecc_base, slavio_irq[hwdef-ecc_irq],
+ hwdef-ecc_version);
 }
 
 static void sun4c_hw_init(const struct hwdef *hwdef, int RAM_size,
@@ -742,6 +743,7 @@ static const struct hwdef hwdefs[] = {
 .fd_irq = 22,
 .me_irq = 30,
 .cs_irq = -1,
+.ecc_irq = 28,
 .machine_id = 0x72,
 .iommu_version = 0x0300,
 .intbit_to_level = {
@@ -783,6 +785,7 @@ static const struct hwdef hwdefs[] = {
 .fd_irq = 22,
 .me_irq = 30,
 .cs_irq = -1,
+.ecc_irq = 28,
 .machine_id = 0x71,
 .iommu_version = 0x0100,
 .intbit_to_level = {
@@ -824,6 +827,7 @@ static const struct hwdef hwdefs[] = {
 .fd_irq = 22,
 .me_irq = 30,
 .cs_irq = -1,
+.ecc_irq = 28,
 .machine_id = 0x72,
 .iommu_version = 0x1300,
 .intbit_to_level = {
Index: hw/sun4m.h
===
RCS file: /sources/qemu/qemu/hw/sun4m.h,v
retrieving revision 1.8
diff -p -u -r1.8 sun4m.h
--- hw/sun4m.h  1 Jan 2008 17:04:45 -   1.8
+++ hw/sun4m.h  6 Jan 2008 15:03:53 -
@@ -81,6 +81,6 @@ void lance_init(NICInfo *nd, target_phys
 qemu_irq irq, qemu_irq *reset);
 
 /* eccmemctl.c */
-void *ecc_init(target_phys_addr_t base, uint32_t version);
+void *ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version);
 
 #endif


[Qemu-devel] [PATCH] hw/sun4m.c make error messages consistent

2008-01-05 Thread Robert Reif

Make these 3 error messages consistent with the other 20 in the same file.
diff -p -u -r1.79 sun4m.c
--- hw/sun4m.c  1 Jan 2008 20:57:25 -   1.79
+++ hw/sun4m.c  5 Jan 2008 22:26:07 -
@@ -385,7 +385,7 @@ static void sun4m_hw_init(const struct h
 for(i = 0; i  smp_cpus; i++) {
 env = cpu_init(cpu_model);
 if (!env) {
-fprintf(stderr, Unable to find Sparc CPU definition\n);
+fprintf(stderr, qemu: Unable to find Sparc CPU definition\n);
 exit(1);
 }
 cpu_sparc_set_id(env, i);
@@ -554,7 +554,7 @@ static void sun4c_hw_init(const struct h
 
 env = cpu_init(cpu_model);
 if (!env) {
-fprintf(stderr, Unable to find Sparc CPU definition\n);
+fprintf(stderr, qemu: Unable to find Sparc CPU definition\n);
 exit(1);
 }
 
@@ -1041,7 +1041,7 @@ static void sun4d_hw_init(const struct s
 for (i = 0; i  smp_cpus; i++) {
 env = cpu_init(cpu_model);
 if (!env) {
-fprintf(stderr, Unable to find Sparc CPU definition\n);
+fprintf(stderr, qemu: Unable to find Sparc CPU definition\n);
 exit(1);
 }
 cpu_sparc_set_id(env, i);


Re: [Qemu-devel] [PATCH] fix possible NULL pointer use in hw/ptimer.c

2008-01-04 Thread Robert Reif

Paul Brook wrote:

What about a meaningful exit message? 
   



Out of memory is a fairly comprehensive description of the problem.
In fact I'd say it's much more informative than random widget the user 
doesn't know or care about failed to initialize.
 


If the user requested a target parameter that is beyond the capabilities
of the host system, a meaningful error message can be generated that
instructs the user on how to possibly correct the problem.





[Qemu-devel] [PATCH] sparc32: fix per cpu counter/timer

2008-01-04 Thread Robert Reif

Sun4m SMP machines support a maximum of 4 CPUs.  Linux
knows this and uses fixed size arrays for per-cpu counter/timers
and interrupt controllers.  Sun4m uni-processor machines use
the slaveio chip which has a single per-cpu counter/timer
and interrupt controller.  However it does not fully decode the
address so the same counter/timer or interrupt controller can
be accesses from multiple addresses.

This patch changes the per-cpu counter/timer to work the way
the real hardware works: 4 per-cpu counter/timers for SMP and
1 counter/timer for UP mapped at multiple addresses.

This patch also fixes a number of per-cpu user timer bugs:
limit bit set when limit reached, count saved and used when
written, limit bit reset on count write and system timer configuration
register updated properly for per-cpu user timer mode.

Sun4d currently uses the sun4m counter/timer code.  They are
simular but not the same.  This patch will break the broken
sun4d implementation further.  The real fix is to create a proper
sun4d counter/timer implementation.  Since the sun4d implementation
doesn't currently work anyway, this shouldn't be an issue.
Index: hw/sbi.c
===
RCS file: /sources/qemu/qemu/hw/sbi.c,v
retrieving revision 1.2
diff -p -u -r1.2 sbi.c
--- hw/sbi.c1 Jan 2008 17:06:38 -   1.2
+++ hw/sbi.c5 Jan 2008 00:43:27 -
@@ -34,15 +34,13 @@ do { printf(IRQ:  fmt , ##args); } whi
 #define DPRINTF(fmt, args...)
 #endif
 
-#define MAX_CPUS 16
-
 #define SBI_NREGS 16
 
 typedef struct SBIState {
 uint32_t regs[SBI_NREGS];
-uint32_t intreg_pending[MAX_CPUS];
-qemu_irq *cpu_irqs[MAX_CPUS];
-uint32_t pil_out[MAX_CPUS];
+uint32_t intreg_pending[MAX_SUN4D_CPUS];
+qemu_irq *cpu_irqs[MAX_SUN4D_CPUS];
+uint32_t pil_out[MAX_SUN4D_CPUS];
 } SBIState;
 
 #define SBI_SIZE (SBI_NREGS * 4)
@@ -107,7 +105,7 @@ static void sbi_save(QEMUFile *f, void *
 SBIState *s = opaque;
 unsigned int i;
 
-for (i = 0; i  MAX_CPUS; i++) {
+for (i = 0; i  MAX_SUN4D_CPUS; i++) {
 qemu_put_be32s(f, s-intreg_pending[i]);
 }
 }
@@ -120,7 +118,7 @@ static int sbi_load(QEMUFile *f, void *o
 if (version_id != 1)
 return -EINVAL;
 
-for (i = 0; i  MAX_CPUS; i++) {
+for (i = 0; i  MAX_SUN4D_CPUS; i++) {
 qemu_get_be32s(f, s-intreg_pending[i]);
 }
 sbi_check_interrupts(s);
@@ -133,7 +131,7 @@ static void sbi_reset(void *opaque)
 SBIState *s = opaque;
 unsigned int i;
 
-for (i = 0; i  MAX_CPUS; i++) {
+for (i = 0; i  MAX_SUN4D_CPUS; i++) {
 s-intreg_pending[i] = 0;
 }
 sbi_check_interrupts(s);
@@ -150,7 +148,7 @@ void *sbi_init(target_phys_addr_t addr, 
 if (!s)
 return NULL;
 
-for (i = 0; i  MAX_CPUS; i++) {
+for (i = 0; i  MAX_SUN4D_CPUS; i++) {
 s-cpu_irqs[i] = parent_irq[i];
 }
 
@@ -160,7 +158,7 @@ void *sbi_init(target_phys_addr_t addr, 
 register_savevm(sbi, addr, 1, sbi_save, sbi_load, s);
 qemu_register_reset(sbi_reset, s);
 *irq = qemu_allocate_irqs(sbi_set_irq, s, 32);
-*cpu_irq = qemu_allocate_irqs(sbi_set_timer_irq_cpu, s, MAX_CPUS);
+*cpu_irq = qemu_allocate_irqs(sbi_set_timer_irq_cpu, s, MAX_SUN4D_CPUS);
 sbi_reset(s);
 
 return s;
Index: hw/slavio_intctl.c
===
RCS file: /sources/qemu/qemu/hw/slavio_intctl.c,v
retrieving revision 1.29
diff -p -u -r1.29 slavio_intctl.c
--- hw/slavio_intctl.c  1 Jan 2008 20:57:25 -   1.29
+++ hw/slavio_intctl.c  5 Jan 2008 00:43:27 -
@@ -46,21 +46,20 @@ do { printf(IRQ:  fmt , ##args); } whi
  *
  */
 
-#define MAX_CPUS 16
 #define MAX_PILS 16
 
 typedef struct SLAVIO_INTCTLState {
-uint32_t intreg_pending[MAX_CPUS];
+uint32_t intreg_pending[MAX_SUN4M_CPUS];
 uint32_t intregm_pending;
 uint32_t intregm_disabled;
 uint32_t target_cpu;
 #ifdef DEBUG_IRQ_COUNT
 uint64_t irq_count[32];
 #endif
-qemu_irq *cpu_irqs[MAX_CPUS];
+qemu_irq *cpu_irqs[MAX_SUN4M_CPUS];
 const uint32_t *intbit_to_level;
 uint32_t cputimer_lbit, cputimer_mbit;
-uint32_t pil_out[MAX_CPUS];
+uint32_t pil_out[MAX_SUN4M_CPUS];
 } SLAVIO_INTCTLState;
 
 #define INTCTL_MAXADDR 0xf
@@ -84,7 +83,7 @@ static uint32_t slavio_intctl_mem_readl(
 uint32_t saddr, ret;
 int cpu;
 
-cpu = (addr  (MAX_CPUS - 1) * TARGET_PAGE_SIZE)  12;
+cpu = (addr  (MAX_SUN4M_CPUS - 1) * TARGET_PAGE_SIZE)  12;
 saddr = (addr  INTCTL_MAXADDR)  2;
 switch (saddr) {
 case 0:
@@ -105,7 +104,7 @@ static void slavio_intctl_mem_writel(voi
 uint32_t saddr;
 int cpu;
 
-cpu = (addr  (MAX_CPUS - 1) * TARGET_PAGE_SIZE)  12;
+cpu = (addr  (MAX_SUN4M_CPUS - 1) * TARGET_PAGE_SIZE)  12;
 saddr = (addr  INTCTL_MAXADDR)  2;
 DPRINTF(write cpu %d reg 0x TARGET_FMT_plx  = %x\n, cpu, addr, val);
 switch (saddr) {
@@ -190,7 +189,7 @@ static void 

Re: [Qemu-devel] [RFC] 64 bit i/o

2008-01-02 Thread Robert Reif

Paul Brook wrote:


On Wednesday 02 January 2008, Robert Reif wrote:
 


Sparc32 has a 64 bit counter that should be read and written as 64
bits but that isn't supported in QEMU.  I did a quick hack to add
64 bit i/o and converted sparc32 to use it and it seems to work.
I'm suppling the sparc changes to get comments on if this is worth
pursuing.
   



Couldn't you just latch the value when one half is accessed?

Paul



 

In this one specific case you could do that but this is not the only 
case in sparc32

(TOD, MXCC, ...) and other architectures with 64 bit hardware have similar
requirements.

This is a generic solution that fills a hole in the qemu implementation.





[Qemu-devel] [PATCH] fix possible NULL pointer use in vl.c

2008-01-02 Thread Robert Reif


diff -p -u -r1.392 vl.c
--- vl.c28 Dec 2007 20:59:23 -  1.392
+++ vl.c3 Jan 2008 02:20:42 -
@@ -985,6 +985,8 @@ QEMUTimer *qemu_new_timer(QEMUClock *clo
 QEMUTimer *ts;
 
 ts = qemu_mallocz(sizeof(QEMUTimer));
+if (!ts)
+return NULL;
 ts-clock = clock;
 ts-cb = cb;
 ts-opaque = opaque;


[Qemu-devel] [PATCH] fix possible NULL pointer use in hw/ptimer.c

2008-01-02 Thread Robert Reif


diff -p -u -r1.5 ptimer.c
--- hw/ptimer.c 17 Nov 2007 17:14:47 -  1.5
+++ hw/ptimer.c 3 Jan 2008 02:27:18 -
@@ -185,6 +185,8 @@ ptimer_state *ptimer_init(QEMUBH *bh)
 ptimer_state *s;
 
 s = (ptimer_state *)qemu_mallocz(sizeof(ptimer_state));
+if (!s)
+return NULL;
 s-bh = bh;
 s-timer = qemu_new_timer(vm_clock, ptimer_tick, s);
 return s;


Re: [Qemu-devel] [PATCH] fix possible NULL pointer use in hw/ptimer.c

2008-01-02 Thread Robert Reif

Paul Brook wrote:


s = (ptimer_state *)qemu_mallocz(sizeof(ptimer_state));
+if (!s)
+return NULL;
   



None of the callers bother to check the return value, And even if they did I 
don't think there's any point trying to gracefully handle OOM.  Just abort 
and be done with it.
 

I am in the process of fixing the sparc ptimer caller to gracefully 
handle OOM.

We currently don't check the return value in the init function where the new
timer is created but do check it wherever it is used which is backwards and
wasteful.

You would prefer that qemu just segfaults rather than die gracefully?





[Qemu-devel] [PATCH] sparc32: fix power address

2007-12-30 Thread Robert Reif

Fix obio/power address for ss10 and ss20.
ss600mp doesn't have obio/power so fix slavio_misc to work without it.
Index: hw/slavio_misc.c
===
RCS file: /sources/qemu/qemu/hw/slavio_misc.c,v
retrieving revision 1.16
diff -p -u -r1.16 slavio_misc.c
--- hw/slavio_misc.c1 Dec 2007 15:02:20 -   1.16
+++ hw/slavio_misc.c31 Dec 2007 02:55:57 -
@@ -146,7 +146,7 @@ static void slavio_misc_mem_writeb(void 
 s-mctrl = val  0xff;
 break;
 default:
-if (addr == s-power_base) {
+if (s-power_base != -1  addr == s-power_base) {
 MISC_DPRINTF(Write power management %2.2x\n, val  0xff);
 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
 }
@@ -181,7 +181,7 @@ static uint32_t slavio_misc_mem_readb(vo
 MISC_DPRINTF(Read modem control %2.2x\n, ret);
 break;
 default:
-if (addr == s-power_base) {
+if (s-power_base != -1  addr == s-power_base) {
 MISC_DPRINTF(Read power management %2.2x\n, ret);
 }
 break;
@@ -366,7 +366,9 @@ void *slavio_misc_init(target_phys_addr_
 cpu_register_physical_memory(base + MISC_MDM, MISC_SIZE,
  slavio_misc_io_memory);
 // Power management
-cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
+if (power_base != -1)
+cpu_register_physical_memory(power_base, MISC_SIZE,
+ slavio_misc_io_memory);
 s-power_base = power_base;
 
 /* 16 bit registers */
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.77
diff -p -u -r1.77 sun4m.c
--- hw/sun4m.c  29 Dec 2007 20:09:57 -  1.77
+++ hw/sun4m.c  31 Dec 2007 02:55:58 -
@@ -724,7 +724,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0xef040ULL,
 .esp_base = 0xef080ULL,
 .le_base  = 0xef0c0ULL,
-.power_base   = 0xefa00ULL,
+.power_base   = 0xff1a01000ULL,
 .ecc_base = 0xfULL,
 .ecc_version  = 0x1000, // version 0, implementation 1
 .sun4c_intctl_base  = -1,
@@ -765,7 +765,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0xef0081000ULL,
 .esp_base = 0xef008ULL,
 .le_base  = 0xef006ULL,
-.power_base   = 0xefa00ULL,
+.power_base   = -1,
 .ecc_base = 0xfULL,
 .ecc_version  = 0x, // version 0, implementation 0
 .sun4c_intctl_base  = -1,
@@ -806,7 +806,7 @@ static const struct hwdef hwdefs[] = {
 .dma_base = 0xef040ULL,
 .esp_base = 0xef080ULL,
 .le_base  = 0xef0c0ULL,
-.power_base   = 0xefa00ULL,
+.power_base   = 0xff1a01000ULL,
 .ecc_base = 0xfULL,
 .ecc_version  = 0x2000, // version 0, implementation 2
 .sun4c_intctl_base  = -1,


[Qemu-devel] [PATCH] sparc32: better unassigned memory debug message

2007-12-28 Thread Robert Reif

Pass the asi number in is_asi.  This works because asi 0 is not a valid asi.
Print out the type of access (read, write, exec).
diff -p -u -r1.61 op_helper.c
--- target-sparc/op_helper.c10 Dec 2007 19:58:20 -  1.61
+++ target-sparc/op_helper.c28 Dec 2007 17:07:49 -
@@ -416,7 +416,7 @@ void helper_ld_asi(int asi, int size, in
 break;
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
-do_unassigned_access(T0, 0, 0, 1);
+do_unassigned_access(T0, 0, 0, asi);
 ret = 0;
 break;
 }
@@ -717,7 +717,7 @@ void helper_st_asi(int asi, int size)
 case 9: /* Supervisor code access, XXX */
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
-do_unassigned_access(T0, 1, 0, 1);
+do_unassigned_access(T0, 1, 0, asi);
 return;
 }
 }
@@ -1832,6 +1832,17 @@ void do_unassigned_access(target_phys_ad
generated code */
 saved_env = env;
 env = cpu_single_env;
+#ifdef DEBUG_UNASSIGNED
+if (is_asi)
+printf(Unassigned mem %s access to  TARGET_FMT_plx  asi 0x%02x from 

+   TARGET_FMT_lx \n,
+   is_exec ? exec : is_write ? write : read, addr, is_asi,
+   env-pc);
+else
+printf(Unassigned mem %s access to  TARGET_FMT_plx  from 
+   TARGET_FMT_lx \n,
+   is_exec ? exec : is_write ? write : read, addr, env-pc);
+#endif
 if (env-mmuregs[3]) /* Fault status register */
 env-mmuregs[3] = 1; /* overflow (not read before another fault) */
 if (is_asi)
@@ -1845,10 +1856,6 @@ void do_unassigned_access(target_phys_ad
 env-mmuregs[3] |= (5  2) | 2;
 env-mmuregs[4] = addr; /* Fault address register */
 if ((env-mmuregs[0]  MMU_E)  !(env-mmuregs[0]  MMU_NF)) {
-#ifdef DEBUG_UNASSIGNED
-printf(Unassigned mem access to  TARGET_FMT_plx  from  
TARGET_FMT_lx
-   \n, addr, env-pc);
-#endif
 if (is_exec)
 raise_exception(TT_CODE_ACCESS);
 else


[Qemu-devel] [PATCH] sparc32: add asi debug info

2007-12-28 Thread Robert Reif

Add asi debug info printing.
diff -p -u -r1.61 op_helper.c
--- target-sparc/op_helper.c10 Dec 2007 19:58:20 -  1.61
+++ target-sparc/op_helper.c28 Dec 2007 17:23:29 -
@@ -6,6 +6,7 @@
 //#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
+//#define DEBUG_ASI
 
 #ifdef DEBUG_MMU
 #define DPRINTF_MMU(fmt, args...) \
@@ -21,6 +22,13 @@ do { printf(MXCC:  fmt , ##args); } wh
 #define DPRINTF_MXCC(fmt, args...)
 #endif
 
+#ifdef DEBUG_ASI
+#define DPRINTF_ASI(fmt, args...) \
+do { printf(ASI:  fmt , ##args); } while (0)
+#else
+#define DPRINTF_ASI(fmt, args...)
+#endif
+
 void raise_exception(int tt)
 {
 env-exception_index = tt;
@@ -229,11 +237,34 @@ static void dump_mxcc(CPUState *env)
 }
 #endif
 
+#ifdef DEBUG_ASI
+static void dump_asi(const char * txt, uint32_t addr, int asi, int size,
+ uint32_t r1, uint32_t r2)
+{
+switch (size)
+{
+case 1:
+DPRINTF_ASI(%s %08x asi 0x%02x = %02x\n, txt, addr, asi, r1  0xff);
+break;
+case 2:
+DPRINTF_ASI(%s %08x asi 0x%02x = %04x\n, txt, addr, asi, r1  
0x);
+break;
+case 4:
+DPRINTF_ASI(%s %08x asi 0x%02x = %08x\n, txt, addr, asi, r1);
+break;
+case 8:
+DPRINTF_ASI(%s %08x asi 0x%02x = %016llx\n, txt, addr, asi,
+r2 | ((uint64_t)r1  32));
+break;
+}
+}
+#endif
+
 void helper_ld_asi(int asi, int size, int sign)
 {
 uint32_t ret = 0;
 uint64_t tmp;
-#ifdef DEBUG_MXCC
+#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
 uint32_t last_T0 = T0;
 #endif
 
@@ -435,6 +466,10 @@ void helper_ld_asi(int asi, int size, in
 }
 else
 T1 = ret;
+
+#ifdef DEBUG_ASI
+dump_asi(read , last_T0, asi, size, T1, T0);
+#endif
 }
 
 void helper_st_asi(int asi, int size)
@@ -542,8 +577,8 @@ void helper_st_asi(int asi, int size)
 #ifdef DEBUG_MMU
 dump_mmu(env);
 #endif
-return;
 }
+break;
 case 4: /* write MMU regs */
 {
 int reg = (T0  8)  0x1f;
@@ -587,8 +622,8 @@ void helper_st_asi(int asi, int size)
 #ifdef DEBUG_MMU
 dump_mmu(env);
 #endif
-return;
 }
+break;
 case 0xa: /* User data access */
 switch(size) {
 case 1:
@@ -646,7 +681,7 @@ void helper_st_asi(int asi, int size)
 stl_kernel(dst, temp);
 }
 }
-return;
+break;
 case 0x1f: /* Block fill, stda access */
 {
 // value (T1, T2)
@@ -661,7 +696,7 @@ void helper_st_asi(int asi, int size)
 for (i = 0; i  32; i += 8, dst += 8)
 stq_kernel(dst, val);
 }
-return;
+break;
 case 0x20: /* MMU passthrough */
 {
 switch(size) {
@@ -680,7 +715,7 @@ void helper_st_asi(int asi, int size)
 break;
 }
 }
-return;
+break;
 case 0x2e: /* MMU passthrough, 0xe */
 case 0x2f: /* MMU passthrough, 0xf */
 {
@@ -705,7 +740,7 @@ void helper_st_asi(int asi, int size)
 break;
 }
 }
-return;
+break;
 case 0x30: /* store buffer tags */
 case 0x31: /* store buffer data or Ross RT620 I-cache flush */
 case 0x32: /* store buffer control */
@@ -718,8 +753,11 @@ void helper_st_asi(int asi, int size)
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
 do_unassigned_access(T0, 1, 0, 1);
-return;
+break;
 }
+#ifdef DEBUG_ASI
+dump_asi(write, T0, asi, size, T1, T2);
+#endif
 }
 
 #endif /* CONFIG_USER_ONLY */


[Qemu-devel] [PATCH] sparc32: set SS-5 iommu version to turbosparc to match default cpu

2007-12-28 Thread Robert Reif


diff -p -u -r1.73 sun4m.c
--- hw/sun4m.c  28 Dec 2007 20:59:23 -  1.73
+++ hw/sun4m.c  28 Dec 2007 21:25:06 -
@@ -698,7 +698,7 @@ static const struct hwdef hwdefs[] = {
 .me_irq = 30,
 .cs_irq = 5,
 .machine_id = 0x80,
-.iommu_version = 0x0400,
+.iommu_version = 0x0500,
 .intbit_to_level = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,


[Qemu-devel] [PATCH] hw/m48t59.c make debug printing consistent

2007-12-27 Thread Robert Reif
This patch adds __func__ to 3 of the 4 debug printfs to make it 
consistent with the the one that already uses it.
diff -p -u -r1.17 m48t59.c
--- hw/m48t59.c 17 Nov 2007 17:14:43 -  1.17
+++ hw/m48t59.c 27 Dec 2007 23:34:11 -
@@ -451,7 +451,7 @@ uint32_t m48t59_read (void *opaque, uint
 break;
 }
 if (addr  0x1FF9  addr  0x2000)
-   NVRAM_PRINTF(0x%08x = 0x%08x\n, addr, retval);
+   NVRAM_PRINTF(%s: 0x%08x = 0x%08x\n, __func__, addr, retval);
 
 return retval;
 }
@@ -476,7 +476,7 @@ static void NVRAM_writeb (void *opaque, 
 m48t59_t *NVRAM = opaque;
 
 addr -= NVRAM-io_base;
-NVRAM_PRINTF(0x%08x = 0x%08x\n, addr, val);
+NVRAM_PRINTF(%s: 0x%08x = 0x%08x\n, __func__, addr, val);
 switch (addr) {
 case 0:
 NVRAM-addr = ~0x00FF;
@@ -509,7 +509,7 @@ static uint32_t NVRAM_readb (void *opaqu
 retval = -1;
 break;
 }
-NVRAM_PRINTF(0x%08x = 0x%08x\n, addr, retval);
+NVRAM_PRINTF(%s: 0x%08x = 0x%08x\n, __func__, addr, retval);
 
 return retval;
 }


[Qemu-devel] [PATCH] fix hw/slavio_intctl.c system read address mask

2007-12-27 Thread Robert Reif


diff -p -u -r1.24 slavio_intctl.c
--- hw/slavio_intctl.c  17 Nov 2007 21:01:04 -  1.24
+++ hw/slavio_intctl.c  28 Dec 2007 01:46:54 -
@@ -145,7 +145,7 @@ static uint32_t slavio_intctlm_mem_readl
 SLAVIO_INTCTLState *s = opaque;
 uint32_t saddr, ret;
 
-saddr = (addr  INTCTLM_MAXADDR)  2;
+saddr = (addr  INTCTLM_MASK)  2;
 switch (saddr) {
 case 0:
 ret = s-intregm_pending  ~MASTER_DISABLE;


[Qemu-devel] [PATCH] sparc32: all registers set to 0 on reset

2007-12-19 Thread Robert Reif

All registers are set to 0 on reset.

This requires my prevoius patch which isn't in CVS yet.
diff -p -u -r1.23 slavio_timer.c
--- hw/slavio_timer.c   17 Dec 2007 18:21:57 -  1.23
+++ hw/slavio_timer.c   19 Dec 2007 12:28:30 -
@@ -306,13 +369,11 @@ static void slavio_timer_reset(void *opa
 {
 SLAVIO_TIMERState *s = opaque;
 
-if (slavio_timer_is_user(s))
-s-limit = TIMER_MAX_COUNT64;
-else
-s-limit = TIMER_MAX_COUNT32;
+s-limit = 0;
 s-count = 0;
 s-reached = 0;
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1);
+s-slave_mode = 0;
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
 ptimer_run(s-timer, 0);
 s-running = 1;
 qemu_irq_lower(s-irq);


[Qemu-devel] [PATCH] sparc32: fix count calculation when limit = 0

2007-12-17 Thread Robert Reif

Fix count calculation when counter limit set to 0.
diff -p -u -r1.23 slavio_timer.c
--- hw/slavio_timer.c   17 Dec 2007 18:21:57 -  1.23
+++ hw/slavio_timer.c   18 Dec 2007 02:23:37 -
@@ -97,9 +97,14 @@ static int slavio_timer_is_user(SLAVIO_T
 // Convert from ptimer countdown units
 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
 {
-uint64_t count;
+uint64_t count, limit;
 
-count = s-limit - PERIODS_TO_LIMIT(ptimer_get_count(s-timer));
+if (s-limit == 0) /* free-run processor or system counter */
+limit = TIMER_MAX_COUNT32;
+else
+limit = s-limit;
+
+count = limit - PERIODS_TO_LIMIT(ptimer_get_count(s-timer));
 DPRINTF(get_out: limit % PRIx64  count %x%08x\n, s-limit,
 s-counthigh, s-count);
 s-count = count  TIMER_COUNT_MASK32;


[Qemu-devel] [PATCH] sparc32: make number of per CPU timers match number of CPUs

2007-12-16 Thread Robert Reif

Only create as many per CPU timers as there are CPUs.
Index: hw/slavio_timer.c
===
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.21
diff -p -u -r1.21 slavio_timer.c
--- hw/slavio_timer.c   1 Dec 2007 15:58:22 -   1.21
+++ hw/slavio_timer.c   16 Dec 2007 22:53:33 -
@@ -61,6 +61,7 @@ typedef struct SLAVIO_TIMERState {
 struct SLAVIO_TIMERState *master;
 int slave_index;
 // system only
+unsigned int num_slaves;
 struct SLAVIO_TIMERState *slave[MAX_CPUS];
 uint32_t slave_mode;
 } SLAVIO_TIMERState;
@@ -352,14 +353,16 @@ static SLAVIO_TIMERState *slavio_timer_i
 }
 
 void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
-   qemu_irq *cpu_irqs)
+   qemu_irq *cpu_irqs, unsigned int num_cpus)
 {
 SLAVIO_TIMERState *master;
 unsigned int i;
 
 master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
 
-for (i = 0; i  MAX_CPUS; i++) {
+master-num_slaves = num_cpus;
+
+for (i = 0; i  master-num_slaves; i++) {
 master-slave[i] = slavio_timer_init(base + (target_phys_addr_t)
  CPU_TIMER_OFFSET(i),
  cpu_irqs[i], master, i);
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.69
diff -p -u -r1.69 sun4m.c
--- hw/sun4m.c  10 Dec 2007 20:00:11 -  1.69
+++ hw/sun4m.c  16 Dec 2007 22:53:33 -
@@ -436,7 +436,7 @@ static void sun4m_hw_init(const struct h
 hwdef-nvram_size, 8);
 
 slavio_timer_init_all(hwdef-counter_base, slavio_irq[hwdef-clock1_irq],
-  slavio_cpu_irq);
+  slavio_cpu_irq, smp_cpus);
 
 slavio_serial_ms_kbd_init(hwdef-ms_kb_base, slavio_irq[hwdef-ms_kb_irq],
   nographic);
Index: hw/sun4m.h
===
RCS file: /sources/qemu/qemu/hw/sun4m.h,v
retrieving revision 1.4
diff -p -u -r1.4 sun4m.h
--- hw/sun4m.h  9 Dec 2007 17:03:50 -   1.4
+++ hw/sun4m.h  16 Dec 2007 22:53:33 -
@@ -36,7 +36,7 @@ void slavio_irq_info(void *opaque);
 
 /* slavio_timer.c */
 void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
-   qemu_irq *cpu_irqs);
+   qemu_irq *cpu_irqs, unsigned int num_cpus);
 
 /* slavio_serial.c */
 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,


Re: [Qemu-devel] [PATCH] sparc32: make number of per CPU timers match number of CPUs

2007-12-16 Thread Robert Reif

Robert Reif wrote:


Only create as many per CPU timers as there are CPUs.


This time with the right patch.
Index: hw/slavio_timer.c
===
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.21
diff -p -u -r1.21 slavio_timer.c
--- hw/slavio_timer.c   1 Dec 2007 15:58:22 -   1.21
+++ hw/slavio_timer.c   16 Dec 2007 23:14:34 -
@@ -61,6 +61,7 @@ typedef struct SLAVIO_TIMERState {
 struct SLAVIO_TIMERState *master;
 int slave_index;
 // system only
+unsigned int num_slaves;
 struct SLAVIO_TIMERState *slave[MAX_CPUS];
 uint32_t slave_mode;
 } SLAVIO_TIMERState;
@@ -230,7 +231,7 @@ static void slavio_timer_mem_writel(void
 if (s-master == NULL) {
 unsigned int i;
 
-for (i = 0; i  MAX_CPUS; i++) {
+for (i = 0; i  s-num_slaves; i++) {
 if (val  (1  i)) {
 qemu_irq_lower(s-slave[i]-irq);
 s-slave[i]-limit = -1ULL;
@@ -244,7 +245,7 @@ static void slavio_timer_mem_writel(void
 ptimer_run(s-slave[i]-timer, 0);
 }
 }
-s-slave_mode = val  ((1  MAX_CPUS) - 1);
+s-slave_mode = val  ((1  s-num_slaves) - 1);
 } else
 DPRINTF(not system timer\n);
 break;
@@ -352,14 +353,16 @@ static SLAVIO_TIMERState *slavio_timer_i
 }
 
 void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
-   qemu_irq *cpu_irqs)
+   qemu_irq *cpu_irqs, unsigned int num_cpus)
 {
 SLAVIO_TIMERState *master;
 unsigned int i;
 
 master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
 
-for (i = 0; i  MAX_CPUS; i++) {
+master-num_slaves = num_cpus;
+
+for (i = 0; i  master-num_slaves; i++) {
 master-slave[i] = slavio_timer_init(base + (target_phys_addr_t)
  CPU_TIMER_OFFSET(i),
  cpu_irqs[i], master, i);
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.69
diff -p -u -r1.69 sun4m.c
--- hw/sun4m.c  10 Dec 2007 20:00:11 -  1.69
+++ hw/sun4m.c  16 Dec 2007 23:14:35 -
@@ -436,7 +436,7 @@ static void sun4m_hw_init(const struct h
 hwdef-nvram_size, 8);
 
 slavio_timer_init_all(hwdef-counter_base, slavio_irq[hwdef-clock1_irq],
-  slavio_cpu_irq);
+  slavio_cpu_irq, smp_cpus);
 
 slavio_serial_ms_kbd_init(hwdef-ms_kb_base, slavio_irq[hwdef-ms_kb_irq],
   nographic);
Index: hw/sun4m.h
===
RCS file: /sources/qemu/qemu/hw/sun4m.h,v
retrieving revision 1.4
diff -p -u -r1.4 sun4m.h
--- hw/sun4m.h  9 Dec 2007 17:03:50 -   1.4
+++ hw/sun4m.h  16 Dec 2007 23:14:35 -
@@ -36,7 +36,7 @@ void slavio_irq_info(void *opaque);
 
 /* slavio_timer.c */
 void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
-   qemu_irq *cpu_irqs);
+   qemu_irq *cpu_irqs, unsigned int num_cpus);
 
 /* slavio_serial.c */
 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,


[Qemu-devel] [PATCH] sparc32: fix setting counter limit to 0

2007-12-16 Thread Robert Reif

Set the proper limit when set to 0.
Index: hw/slavio_timer.c
===
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.21
diff -p -u -r1.21 slavio_timer.c
--- hw/slavio_timer.c   1 Dec 2007 15:58:22 -   1.21
+++ hw/slavio_timer.c   16 Dec 2007 23:28:13 -
@@ -174,7 +175,6 @@ static void slavio_timer_mem_writel(void
 {
 SLAVIO_TIMERState *s = opaque;
 uint32_t saddr;
-int reload = 0;
 
 DPRINTF(write  TARGET_FMT_plx  %08x\n, addr, val);
 saddr = (addr  TIMER_MAXADDR)  2;
@@ -190,9 +190,10 @@ static void slavio_timer_mem_writel(void
 // set limit, reset counter
 qemu_irq_lower(s-irq);
 s-limit = val  TIMER_MAX_COUNT32;
-if (!s-limit)
-s-limit = TIMER_MAX_COUNT32;
-ptimer_set_limit(s-timer, s-limit  9, 1);
+if (s-limit == 0) /* free-run */
+ptimer_set_limit(s-timer, 
LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 1);
+else
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 1);
 }
 break;
 case TIMER_COUNTER:
@@ -208,9 +209,10 @@ static void slavio_timer_mem_writel(void
 case TIMER_COUNTER_NORST:
 // set limit without resetting counter
 s-limit = val  TIMER_MAX_COUNT32;
-if (!s-limit)
-s-limit = TIMER_MAX_COUNT32;
-ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), reload);
+if (s-limit == 0) /* free-run */
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(TIMER_MAX_COUNT32), 0);
+else
+ptimer_set_limit(s-timer, LIMIT_TO_PERIODS(s-limit), 0);
 break;
 case TIMER_STATUS:
 if (slavio_timer_is_user(s)) {


Re: [Qemu-devel] high resolution timer question

2007-12-11 Thread Robert Reif

Blue Swirl wrote:


On 12/10/07, Robert Reif [EMAIL PROTECTED] wrote:
 


Writing data to a serial port on the sparc emulation happens immediately.
I would like to throttle the write speed to match the actual baud rate.
What's the best way to do this in qemu?  Will QEMUTimer work for a
1 millisecond timer?
   



Do you mean that you want the serial port to match the host speed so
that for example, at 9600 baud, target would only receive 9600 bits
per second? Or do you mean that the emulated CPU should see bits
arriving at the same rate that the real CPU would see compared to CPU
execution speed?

On the positive side, this would fix a bug with serial interrupts
arriving too fast which can trigger Linux panics. But this would also
complicate the design because currently the devices do not need to
emulate any internal buffers.

 


The problem I'm having is with sparc32 using a sun openboot image in
nographics mode where the prom uses serial port A as the system console.
The serial port output shows up in the host terminal window that qemu
was started in.

Characters written to serial port A are not reliably making it to the 
screen.

Turning on serial debugging shows that the characters are written to the
serial port.  The characters do make it to the screen when debugging.

If characters are not queued, then that might explain the loss but it looks
like the characters are going to a write(fd, ...) so is stdio loosing 
the characters?


I thought slowing down the rate to realistic speeds might help but that 
doesn't

seem to be where the problem really is.





Re: [Qemu-devel] high resolution timer question

2007-12-11 Thread Robert Reif

Robert Reif wrote:


The problem I'm having is with sparc32 using a sun openboot image in
nographics mode where the prom uses serial port A as the system console.
The serial port output shows up in the host terminal window that qemu
was started in.

Characters written to serial port A are not reliably making it to the 
screen.

Turning on serial debugging shows that the characters are written to the
serial port.  The characters do make it to the screen when debugging.


The problem seems to be caused by multiple streams outputting to the screen.
It looks like different ways of outputting to the same device may use 
different

streams!





Re: [Qemu-devel] high resolution timer question

2007-12-11 Thread Robert Reif

Robert Reif wrote:

Characters written to serial port A are not reliably making it to the 
screen.

Turning on serial debugging shows that the characters are written to the
serial port.  The characters do make it to the screen when debugging.



The problem seems to be caused by multiple streams outputting to the 
screen.
It looks like different ways of outputting to the same device may use 
different

streams!


Please disregard this possible cause.  I left a debugging printf in by 
accident.

The real problem is still there though.





[Qemu-devel] high resolution timer question

2007-12-10 Thread Robert Reif

Writing data to a serial port on the sparc emulation happens immediately.
I would like to throttle the write speed to match the actual baud rate. 
What's the best way to do this in qemu?  Will QEMUTimer work for a

1 millisecond timer?





[Qemu-devel] [PATCH] sparc32 sun4m eccmemctl

2007-12-09 Thread Robert Reif

This patch adds sparc32 sun4m SMP ECC memory controller support.

Three files are attached:

The first is a diff to existing code.
The second is a diff for the new eccmemctl.c.
The third is the openboot outputs for the 3 systems that support this chip.

This patch is necessary for using sun openboot prom images because they
expect the device to be present and will fault when it's not there.

A prom node will need to be added to openbios for this chip.
Index: Makefile.target
===
RCS file: /sources/qemu/qemu/Makefile.target,v
retrieving revision 1.230
diff -p -u -r1.230 Makefile.target
--- Makefile.target 2 Dec 2007 02:20:02 -   1.230
+++ Makefile.target 9 Dec 2007 14:03:20 -
@@ -482,7 +482,7 @@ VL_OBJS+= cirrus_vga.o parallel.o ptimer
 else
 VL_OBJS+= sun4m.o tcx.o pcnet.o iommu.o m48t59.o slavio_intctl.o
 VL_OBJS+= slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o 
sparc32_dma.o
-VL_OBJS+= cs4231.o ptimer.o
+VL_OBJS+= cs4231.o ptimer.o eccmemctl.o
 endif
 endif
 ifeq ($(TARGET_BASE_ARCH), arm)
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.67
diff -p -u -r1.67 sun4m.c
--- hw/sun4m.c  4 Dec 2007 20:58:31 -   1.67
+++ hw/sun4m.c  9 Dec 2007 14:03:24 -
@@ -82,6 +82,8 @@ struct hwdef {
 uint32_t intbit_to_level[32];
 uint64_t max_mem;
 const char * const default_cpu_model;
+target_phys_addr_t ecc_base;
+uint32_t ecc_version;
 };
 
 /* TSC handling */
@@ -479,6 +481,9 @@ static void sun4m_hw_init(const struct h
 nvram_init(nvram, (uint8_t *)nd_table[0].macaddr, kernel_cmdline,
boot_device, RAM_size, kernel_size, graphic_width,
graphic_height, graphic_depth, hwdef-machine_id);
+
+if (hwdef-ecc_base != (target_phys_addr_t)-1)
+ecc_init(hwdef-ecc_base, hwdef-ecc_version);
 }
 
 static const struct hwdef hwdefs[] = {
@@ -517,6 +522,7 @@ static const struct hwdef hwdefs[] = {
 },
 .max_mem = 0x1000,
 .default_cpu_model = Fujitsu MB86904,
+.ecc_base = -1,
 },
 /* SS-10 */
 {
@@ -553,6 +559,8 @@ static const struct hwdef hwdefs[] = {
 },
 .max_mem = 0x, // XXX actually first 62GB ok
 .default_cpu_model = TI SuperSparc II,
+.ecc_base = 0xfULL,
+.ecc_version = 0x1000, // version 0, implementation 1
 },
 /* SS-600MP */
 {
@@ -589,6 +597,8 @@ static const struct hwdef hwdefs[] = {
 },
 .max_mem = 0x, // XXX actually first 62GB ok
 .default_cpu_model = TI SuperSparc II,
+.ecc_base = 0xfULL,
+.ecc_version = 0x, // version 0, implementation 0
 },
 };
 
Index: hw/sun4m.h
===
RCS file: /sources/qemu/qemu/hw/sun4m.h,v
retrieving revision 1.3
diff -p -u -r1.3 sun4m.h
--- hw/sun4m.h  4 Dec 2007 20:58:31 -   1.3
+++ hw/sun4m.h  9 Dec 2007 14:03:24 -
@@ -72,4 +72,7 @@ void espdma_memory_write(void *opaque, u
 void lance_init(NICInfo *nd, target_phys_addr_t leaddr, void *dma_opaque,
 qemu_irq irq, qemu_irq *reset);
 
+/* eccmemctl.c */
+void *ecc_init(target_phys_addr_t base, uint32_t version);
+
 #endif
--- qemu/hw/eccmemctl.c 1969-12-31 19:00:00.0 -0500
+++ qemu.ecc/hw/eccmemctl.c 2007-12-09 09:12:16.0 -0500
@@ -0,0 +1,266 @@
+/*
+ * QEMU Sparc Sun4m ECC memory controller emulation
+ *
+ * Copyright (c) 2007 Robert Reif
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include hw.h
+#include sun4m.h
+#include sysemu.h
+
+//#define DEBUG_ECC
+
+#ifdef DEBUG_ECC
+#define DPRINTF(fmt, args...)   \
+do { printf(ECC:  fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
+/* There are 3 versions

[Qemu-devel] [PATCH] sparc32 add a few more ASI

2007-12-09 Thread Robert Reif


diff -p -u -r1.60 op_helper.c
--- target-sparc/op_helper.c28 Nov 2007 18:08:28 -  1.60
+++ target-sparc/op_helper.c9 Dec 2007 20:33:02 -
@@ -411,6 +411,9 @@ void helper_ld_asi(int asi, int size, in
 break;
 }
 break;
+case 0x39: /* data cache diagnostic register */
+ret = 0;
+break;
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
 do_unassigned_access(T0, 0, 0, 1);
@@ -703,9 +706,13 @@ void helper_st_asi(int asi, int size)
 }
 }
 return;
-case 0x31: /* Ross RT620 I-cache flush */
+case 0x30: /* store buffer tags */
+case 0x31: /* store buffer data or Ross RT620 I-cache flush */
+case 0x32: /* store buffer control */
 case 0x36: /* I-cache flash clear */
 case 0x37: /* D-cache flash clear */
+case 0x38: /* breakpoint diagnostics */
+case 0x4c: /* breakpoint action */
 break;
 case 9: /* Supervisor code access, XXX */
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */


[Qemu-devel] [PATCH] sparc32 add SPARCstation 20 machine type

2007-12-09 Thread Robert Reif


Index: vl.c
===
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.377
diff -p -u -r1.377 vl.c
--- vl.c6 Dec 2007 22:11:20 -   1.377
+++ vl.c10 Dec 2007 01:17:59 -
@@ -7838,6 +7838,7 @@ static void register_machines(void)
 qemu_register_machine(ss5_machine);
 qemu_register_machine(ss10_machine);
 qemu_register_machine(ss600mp_machine);
+qemu_register_machine(ss20_machine);
 #endif
 #elif defined(TARGET_ARM)
 qemu_register_machine(integratorcp_machine);
Index: hw/boards.h
===
RCS file: /sources/qemu/qemu/hw/boards.h,v
retrieving revision 1.4
diff -p -u -r1.4 boards.h
--- hw/boards.h 25 Nov 2007 01:57:38 -  1.4
+++ hw/boards.h 10 Dec 2007 01:17:59 -
@@ -52,7 +52,7 @@ extern QEMUMachine shix_machine;
 extern QEMUMachine r2d_machine;
 
 /* sun4m.c */
-extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine;
+extern QEMUMachine ss5_machine, ss10_machine, ss600mp_machine, ss20_machine;
 
 /* sun4u.c */
 extern QEMUMachine sun4u_machine;
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.68
diff -p -u -r1.68 sun4m.c
--- hw/sun4m.c  9 Dec 2007 17:03:50 -   1.68
+++ hw/sun4m.c  10 Dec 2007 01:17:59 -
@@ -600,6 +600,44 @@ static const struct hwdef hwdefs[] = {
 .max_mem = 0x, // XXX actually first 62GB ok
 .default_cpu_model = TI SuperSparc II,
 },
+/* SS-20 */
+{
+.iommu_base   = 0xfe000ULL,
+.tcx_base = 0xe2000ULL,
+.cs_base  = -1,
+.slavio_base  = 0xff000ULL,
+.ms_kb_base   = 0xff100ULL,
+.serial_base  = 0xff110ULL,
+.nvram_base   = 0xff120ULL,
+.fd_base  = 0xff170ULL,
+.counter_base = 0xff130ULL,
+.intctl_base  = 0xff140ULL,
+.dma_base = 0xef040ULL,
+.esp_base = 0xef080ULL,
+.le_base  = 0xef0c0ULL,
+.power_base   = 0xefa00ULL,
+.ecc_base = 0xfULL,
+.ecc_version  = 0x2000, // version 0, implementation 2
+.vram_size= 0x0010,
+.nvram_size   = 0x2000,
+.esp_irq = 18,
+.le_irq = 16,
+.clock_irq = 7,
+.clock1_irq = 19,
+.ms_kb_irq = 14,
+.ser_irq = 15,
+.fd_irq = 22,
+.me_irq = 30,
+.cs_irq = -1,
+.machine_id = 0x72,
+.iommu_version = 0x1300,
+.intbit_to_level = {
+2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
+6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
+},
+.max_mem = 0x, // XXX actually first 62GB ok
+.default_cpu_model = TI SuperSparc II,
+},
 };
 
 /* SPARCstation 5 hardware initialisation */
@@ -632,6 +670,16 @@ static void ss600mp_init(int RAM_size, i
   kernel_cmdline, initrd_filename, cpu_model);
 }
 
+/* SPARCstation 20 hardware initialisation */
+static void ss20_init(int RAM_size, int vga_ram_size,
+  const char *boot_device, DisplayState *ds,
+  const char *kernel_filename, const char *kernel_cmdline,
+  const char *initrd_filename, const char *cpu_model)
+{
+sun4m_hw_init(hwdefs[3], RAM_size, boot_device, ds, kernel_filename,
+  kernel_cmdline, initrd_filename, cpu_model);
+}
+
 QEMUMachine ss5_machine = {
 SS-5,
 Sun4m platform, SPARCstation 5,
@@ -649,3 +697,10 @@ QEMUMachine ss600mp_machine = {
 Sun4m platform, SPARCserver 600MP,
 ss600mp_init,
 };
+
+QEMUMachine ss20_machine = {
+SS-20,
+Sun4m platform, SPARCstation 20,
+ss20_init,
+};
+


Re: [Qemu-devel] [PATCH] sparc32 machine specific maximums

2007-12-04 Thread Robert Reif

Blue Swirl wrote:


On 12/4/07, Robert Reif [EMAIL PROTECTED] wrote:
 


I would be surprised if an SMP kernel actually worked on a multi CPU SS5.
   



Prepare for a surprise:

 

That's interesting because the fact that it works shows how inaccurate 
the emulation is.


Now could you please really surprise me by booting Solaris 2.5 using a 
real sun openprom image ;-)






Re: [Qemu-devel] [PATCH] sparc32 machine specific maximums

2007-12-03 Thread Robert Reif

Blue Swirl wrote:


On 12/3/07, Robert Reif [EMAIL PROTECTED] wrote:
 


This patch sets the maximum number of CPUs and memory to what is
supported by the actual hardware.
   



While it's not historically accurate to emulate a Sparcstation 5 with
16 CPUs and 2 gigabytes of memory, it doesn't break anything to have
this capability. We don't throttle the power of the CPU, speed of the
network, serial or disk devices either, so they may be unrealistically
fast. The timers are not accurate at all compared to CPU execution
speed.

Currently the memory on SS-5 machine is limited by the location of
IOMMU and that the memory lies in one linear bank starting from zero.
With more advanced banking and 4G patches, the entire physical
address space could be filled with RAM.

 


I would be surprised if an SMP kernel actually worked on a multi CPU SS5.
Currently OSs like solaris and bsd that actually use more than a minimal
amount of hardware don't work in QEMU.  That's because QEMUs
system emulation is both incomplete and inaccurate.  If you want to make 
a 16

CPU, 64 Gb machine, define a QEMU specific machine.  There are no real
32 bit sparc systems like that. I would like to see real sun openboot ROM
images work on realistic emulated hardware so QEMU could be used for
real OS development.





[Qemu-devel] [PATCH] sparc32 machine specific maximums

2007-12-02 Thread Robert Reif
This patch sets the maximum number of CPUs and memory to what is 
supported by the actual hardware.
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.66
diff -p -u -r1.66 sun4m.c
--- hw/sun4m.c  2 Dec 2007 04:51:10 -   1.66
+++ hw/sun4m.c  2 Dec 2007 23:03:18 -
@@ -82,6 +82,7 @@ struct hwdef {
 uint32_t intbit_to_level[32];
 uint64_t max_mem;
 const char * const default_cpu_model;
+unsigned int max_cpus;
 };
 
 /* TSC handling */
@@ -345,10 +346,16 @@ static void sun4m_hw_init(const struct h
 if (!cpu_model)
 cpu_model = hwdef-default_cpu_model;
 
+if (smp_cpus  hwdef-max_cpus) {
+fprintf(stderr, qemu: Too many CPUs for this machine: %d, maximum 
%d\n,
+smp_cpus, hwdef-max_cpus);
+exit(1);
+}
+
 for(i = 0; i  smp_cpus; i++) {
 env = cpu_init(cpu_model);
 if (!env) {
-fprintf(stderr, Unable to find Sparc CPU definition\n);
+fprintf(stderr, qemu: Unable to find Sparc CPU definition\n);
 exit(1);
 }
 cpu_sparc_set_id(env, i);
@@ -514,8 +521,9 @@ static const struct hwdef hwdefs[] = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
 },
-.max_mem = 0x1000,
+.max_mem = 0x1000, // 256M (8 32M SIMMs)
 .default_cpu_model = Fujitsu MB86904,
+.max_cpus = 1,
 },
 /* SS-10 */
 {
@@ -550,8 +558,9 @@ static const struct hwdef hwdefs[] = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
 },
-.max_mem = 0x, // XXX actually first 62GB ok
+.max_mem = 0x2000, // 512M (8 64M SIMMs)
 .default_cpu_model = TI SuperSparc II,
+.max_cpus = 4,
 },
 /* SS-600MP */
 {
@@ -586,8 +595,9 @@ static const struct hwdef hwdefs[] = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
 },
-.max_mem = 0x, // XXX actually first 62GB ok
+.max_mem = 0x4000, // 1G (64 16M SIMMs)
 .default_cpu_model = TI SuperSparc II,
+.max_cpus = 4,
 },
 };
 


[Qemu-devel] [PATCH] sparc32 iommu fix

2007-11-20 Thread Robert Reif

Set initial value of AFSR register properly.
Index: hw/iommu.c
===
RCS file: /sources/qemu/qemu/hw/iommu.c,v
retrieving revision 1.19
diff -p -u -r1.19 iommu.c
--- hw/iommu.c  17 Nov 2007 17:14:42 -  1.19
+++ hw/iommu.c  21 Nov 2007 04:30:28 -
@@ -311,6 +311,7 @@ static void iommu_reset(void *opaque)
 s-iostart = 0;
 s-regs[IOMMU_CTRL] = s-version;
 s-regs[IOMMU_ARBEN] = IOMMU_MID;
+s-regs[IOMMU_AFSR] = 0x0080;
 }
 
 void *iommu_init(target_phys_addr_t addr, uint32_t version)


[Qemu-devel] [PATCH] sparc32 MMU fixes

2007-11-19 Thread Robert Reif

This patch adds support for some more MMU registers:
   0x10   TLB replacement control
   0x13   read/write access to 0x03 SFSR
   0x14   read/write access to 0x04 SFAR
Only support for 1 real register was added (0x10) but 16 were added
to CPUSPARCState because we don't check for invalid register
accesses yet.  Different CPUs use different registers and there isn't
enough documentation to work out what is valid or not so we just
waste some space.

This patch also preserves the bits we are not interested in for tlb
flushing in the processor control register (0x00).
Index: target-sparc/cpu.h
===
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.58
diff -p -u -r1.58 cpu.h
--- target-sparc/cpu.h  10 Nov 2007 15:15:54 -  1.58
+++ target-sparc/cpu.h  20 Nov 2007 01:23:33 -
@@ -215,7 +215,7 @@ typedef struct CPUSPARCState {
 uint64_t dtlb_tag[64];
 uint64_t dtlb_tte[64];
 #else
-uint32_t mmuregs[16];
+uint32_t mmuregs[32];
 uint64_t mxccdata[4];
 uint64_t mxccregs[8];
 #endif
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.57
diff -p -u -r1.57 op_helper.c
--- target-sparc/op_helper.c19 Nov 2007 19:14:10 -  1.57
+++ target-sparc/op_helper.c20 Nov 2007 01:23:33 -
@@ -248,11 +248,15 @@ void helper_ld_asi(int asi, int size, in
 break;
 case 4: /* read MMU regs */
 {
-int reg = (T0  8)  0xf;
+int reg = (T0  8)  0x1f;
 
 ret = env-mmuregs[reg];
 if (reg == 3) /* Fault status cleared on read */
-env-mmuregs[reg] = 0;
+env-mmuregs[3] = 0;
+else if (reg == 0x13) /* Fault status read */
+ret = env-mmuregs[3];
+else if (reg == 0x14) /* Fault address read */
+ret = env-mmuregs[4];
 DPRINTF_MMU(mmu_read: reg[%d] = 0x%08x\n, reg, ret);
 }
 break;
@@ -493,17 +497,18 @@ void helper_st_asi(int asi, int size)
 }
 case 4: /* write MMU regs */
 {
-int reg = (T0  8)  0xf;
+int reg = (T0  8)  0x1f;
 uint32_t oldreg;
 
 oldreg = env-mmuregs[reg];
 switch(reg) {
 case 0:
-env-mmuregs[reg] = ~(MMU_E | MMU_NF | env-mmu_bm);
-env-mmuregs[reg] |= T1  (MMU_E | MMU_NF | env-mmu_bm);
+env-mmuregs[reg] = (env-mmuregs[reg]  0xff00) |
+(T1  0x00ff);
 // Mappings generated during no-fault mode or MMU
 // disabled mode are invalid in normal mode
-if (oldreg != env-mmuregs[reg])
+if ((oldreg  (MMU_E | MMU_NF | env-mmu_bm)) != 
+(env-mmuregs[reg]  (MMU_E | MMU_NF | env-mmu_bm)))
 tlb_flush(env, 1);
 break;
 case 2:
@@ -517,6 +522,12 @@ void helper_st_asi(int asi, int size)
 case 3:
 case 4:
 break;
+case 0x13:
+env-mmuregs[3] = T1;
+break;
+case 0x14:
+env-mmuregs[4] = T1;
+break;
 default:
 env-mmuregs[reg] = T1;
 break;


Re: [Qemu-devel] [RFC][PATCH] fix sparc32 mxcc 64 bit read word order

2007-11-18 Thread Robert Reif

Blue Swirl wrote:


On 11/16/07, Robert Reif [EMAIL PROTECTED] wrote:
 


This patch fixes the word order for 64 bit reads of the mxcc registers.
 



Otherwise everything seems OK, but it breaks NetBSD version 3 on SS10:
clock0 at obio0 slot 0 offset 0x20: mk48t08
timer0 at obio0 slot 0 offset 0x30data fault: pc=0xf0111a0c
addr=0x0 sfsr=126PERR=0,LVL=1,AT=1,FT=1,FAV,OW
panic: kernel fault
halted

halt, power off

Without the patch I get:
clock0 at obio0 slot 0 offset 0x20: mk48t08
timer0 at obio0 slot 0 offset 0x30: delay constant 99
zs0 at obio0 slot 0 offset 0x10 level 12 softpri 6
zstty0 at zs0 channel 0 (console i/o)
zstty1 at zs0 channel 1
scsi-disk: Unsupported command length, command 79



 

This is a classic case of two wrongs make a right.  OpenBios need to be 
fixed to set mbus module id to start at 8, not 0 for mbus based machines.



Index: drivers/obio.c
===
--- drivers/obio.c  (revision 178)
+++ drivers/obio.c  (working copy)
@@ -891,7 +891,15 @@
 push_str(cache-coherence?);
 fword(property);
 
-PUSH(i);
+   switch (machine_id) {
+case 0x71:
+case 0x72:
+PUSH(i + 8);
+break;
+case 0x80:
+PUSH(i);
+break;
+}
 fword(encode-int);
 push_str(mid);
 fword(property);


Re: [Qemu-devel] [RFC][PATCH] fix sparc32 mxcc 64 bit read word order

2007-11-18 Thread Robert Reif

Blue Swirl wrote:


On 11/18/07, Robert Reif [EMAIL PROTECTED] wrote:
 


Blue Swirl wrote:

   


On 11/16/07, Robert Reif [EMAIL PROTECTED] wrote:


 


This patch fixes the word order for 64 bit reads of the mxcc registers.


 


Otherwise everything seems OK, but it breaks NetBSD version 3 on SS10:
clock0 at obio0 slot 0 offset 0x20: mk48t08
timer0 at obio0 slot 0 offset 0x30data fault: pc=0xf0111a0c
addr=0x0 sfsr=126PERR=0,LVL=1,AT=1,FT=1,FAV,OW
panic: kernel fault
halted

halt, power off

Without the patch I get:
clock0 at obio0 slot 0 offset 0x20: mk48t08
timer0 at obio0 slot 0 offset 0x30: delay constant 99
zs0 at obio0 slot 0 offset 0x10 level 12 softpri 6
zstty0 at zs0 channel 0 (console i/o)
zstty1 at zs0 channel 1
scsi-disk: Unsupported command length, command 79





 


This is a classic case of two wrongs make a right.  OpenBios need to be
fixed to set mbus module id to start at 8, not 0 for mbus based machines.
   



Turbosparc manual says that the module id is hardwired to 0x8, so
would it be OK if mid was  i + 8 for all machines?



 

Probably but I don't know for sure.  I just fired up a SPARCclassic X 
which has a microSPARC CPU and the mid was 0.  You may need to check the 
CPU type for the SS5.  I don't have the time right now to dig out a 
microSPARC SS5 to check it out.






Re: [Qemu-devel] [PATCH] add iommu version to sparc32

2007-11-15 Thread Robert Reif



Add iommu version to sparc32.  Also reset iommu after initialization.
   



Should the version be tied to CPU model instead of machine type? At
least for Turbosparc this seems to be the case. 
 


On SMP systems the IOMMU is on the system board in a separate ASIC.  On
single CPU systems the IOMMU is integrated into the CPU.  Without checking
the FEH, the SS 5 was the only single CPU system that shipped with more than
one family of CPUs (MicroSparc II and TurboSparc and they do have different
IOMMU versions).  That could be special cased.

Unfortunately QEMU will allow you to specify unrealistic systems.  We 
should

probably add allowable CPU types to specific machine types to catch this.





Re: [Qemu-devel] [RFC][PATCH] fix sparc32 mxcc 64 bit read word order

2007-11-15 Thread Robert Reif



This patch fixes the word order for 64 bit reads of the mxcc registers.
 



Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.52
diff -p -u -r1.52 op_helper.c
--- target-sparc/op_helper.c11 Nov 2007 19:46:09 -  1.52
+++ target-sparc/op_helper.c15 Nov 2007 23:04:48 -
@@ -196,8 +196,8 @@ void helper_ld_asi(int asi, int size, in
 switch (T0) {
 case 0x01c00a00: /* MXCC control register */
 if (size == 8) {
-ret = env-mxccregs[3];
-T0 = env-mxccregs[3]  32;
+ret = env-mxccregs[3]  32;
+T0 = env-mxccregs[3];
 } else
 DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
 break;
@@ -209,8 +209,8 @@ void helper_ld_asi(int asi, int size, in
 break;
 case 0x01c00f00: /* MBus port address register */
 if (size == 8) {
-ret = env-mxccregs[7];
-T0 = env-mxccregs[7]  32;
+ret = env-mxccregs[7]  32;
+T0 = env-mxccregs[7];
 } else
 DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
 break;


[Qemu-devel] [PATCH] sparc32 fix MXCC error bit clearing

2007-11-15 Thread Robert Reif

Fix MXCC error register bit clearing.
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.52
diff -p -u -r1.52 op_helper.c
--- target-sparc/op_helper.c11 Nov 2007 19:46:09 -  1.52
+++ target-sparc/op_helper.c15 Nov 2007 23:28:12 -
@@ -438,13 +446,11 @@ void helper_st_asi(int asi, int size)
 DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
 break;
 case 0x01c00e00: /* MXCC error register  */
+// writing a 1 bit clears the error
 if (size == 8)
-env-mxccregs[6] = ((uint64_t)T1  32) | T2;
+env-mxccregs[6] = ~(((uint64_t)T1  32) | T2);
 else
 DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
-if (env-mxccregs[6] == 0xULL) {
-// this is probably a reset
-}
 break;
 case 0x01c00f00: /* MBus port address register */
 if (size == 8)


[Qemu-devel] [PATCH] sparc32 add new MXCC register

2007-11-15 Thread Robert Reif

Add new MXCC register.
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.52
diff -r1.52 op_helper.c
209a210,217
 case 0x01c00c00: /* Module reset register */
 if (size == 8) {
 ret = env-mxccregs[5]  32;
 T0 = env-mxccregs[5];
 // should we do something here?
 } else
 DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
 size);
 break;


[Qemu-devel] [PATCH] sparc32 remove unnecessary 0xffffffff

2007-11-15 Thread Robert Reif

Remove unnecessary masking of lower word with 0x.
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.52
diff -p -u -r1.52 op_helper.c
--- target-sparc/op_helper.c11 Nov 2007 19:46:09 -  1.52
+++ target-sparc/op_helper.c15 Nov 2007 23:10:36 -
@@ -263,7 +263,7 @@ void helper_ld_asi(int asi, int size, in
 case 8:
 tmp = ldq_code(T0  ~7);
 ret = tmp  32;
-T0 = tmp  0x;
+T0 = tmp;
 break;
 }
 break;
@@ -282,7 +282,7 @@ void helper_ld_asi(int asi, int size, in
 case 8:
 tmp = ldq_user(T0  ~7);
 ret = tmp  32;
-T0 = tmp  0x;
+T0 = tmp;
 break;
 }
 break;
@@ -301,7 +301,7 @@ void helper_ld_asi(int asi, int size, in
 case 8:
 tmp = ldq_kernel(T0  ~7);
 ret = tmp  32;
-T0 = tmp  0x;
+T0 = tmp;
 break;
 }
 break;
@@ -325,7 +325,7 @@ void helper_ld_asi(int asi, int size, in
 case 8:
 tmp = ldq_phys(T0  ~7);
 ret = tmp  32;
-T0 = tmp  0x;
+T0 = tmp;
 break;
 }
 break;
@@ -349,7 +349,7 @@ void helper_ld_asi(int asi, int size, in
 tmp = ldq_phys((target_phys_addr_t)(T0  ~7)
| ((target_phys_addr_t)(asi  0xf)  32));
 ret = tmp  32;
-T0 = tmp  0x;
+T0 = tmp;
 break;
 }
 break;


[Qemu-devel] [PATCH] add iommu version to sparc32

2007-11-12 Thread Robert Reif

Add iommu version to sparc32.  Also reset iommu after initialization.
Index: hw/iommu.c
===
RCS file: /sources/qemu/qemu/hw/iommu.c,v
retrieving revision 1.17
diff -p -u -r1.17 iommu.c
--- hw/iommu.c  6 Oct 2007 11:28:21 -   1.17
+++ hw/iommu.c  12 Nov 2007 22:54:57 -
@@ -37,7 +37,6 @@ do { printf(IOMMU:  fmt , ##args); } w
 #define IOMMU_CTRL  (0x  2)
 #define IOMMU_CTRL_IMPL 0xf000 /* Implementation */
 #define IOMMU_CTRL_VERS 0x0f00 /* Version */
-#define IOMMU_VERSION   0x0400
 #define IOMMU_CTRL_RNGE 0x001c /* Mapping RANGE */
 #define IOMMU_RNGE_16MB 0x /* 0xff00 - 0x */
 #define IOMMU_RNGE_32MB 0x0004 /* 0xfe00 - 0x */
@@ -104,6 +103,7 @@ typedef struct IOMMUState {
 target_phys_addr_t addr;
 uint32_t regs[IOMMU_NREGS];
 target_phys_addr_t iostart;
+uint32_t version;
 } IOMMUState;
 
 static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
@@ -158,7 +158,7 @@ static void iommu_mem_writew(void *opaqu
 break;
 }
 DPRINTF(iostart =  TARGET_FMT_plx \n, s-iostart);
-s-regs[saddr] = ((val  IOMMU_CTRL_MASK) | IOMMU_VERSION);
+s-regs[saddr] = ((val  IOMMU_CTRL_MASK) | s-version);
 break;
 case IOMMU_BASE:
 s-regs[saddr] = val  IOMMU_BASE_MASK;
@@ -308,10 +308,11 @@ static void iommu_reset(void *opaque)
 
 memset(s-regs, 0, IOMMU_NREGS * 4);
 s-iostart = 0;
-s-regs[IOMMU_CTRL] = IOMMU_VERSION;
+s-regs[IOMMU_CTRL] = s-version;
+s-regs[IOMMU_ARBEN] = IOMMU_MID;
 }
 
-void *iommu_init(target_phys_addr_t addr)
+void *iommu_init(target_phys_addr_t addr, uint32_t version)
 {
 IOMMUState *s;
 int iommu_io_memory;
@@ -321,12 +322,14 @@ void *iommu_init(target_phys_addr_t addr
 return NULL;
 
 s-addr = addr;
+s-version = version;
 
 iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, 
iommu_mem_write, s);
 cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory);
 
 register_savevm(iommu, addr, 2, iommu_save, iommu_load, s);
 qemu_register_reset(iommu_reset, s);
+iommu_reset(s);
 return s;
 }
 
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.60
diff -p -u -r1.60 sun4m.c
--- hw/sun4m.c  11 Nov 2007 17:56:38 -  1.60
+++ hw/sun4m.c  12 Nov 2007 22:54:57 -
@@ -69,6 +69,7 @@ struct hwdef {
 int intctl_g_intr, esp_irq, le_irq, clock_irq, clock1_irq;
 int ser_irq, ms_kb_irq, fd_irq, me_irq, cs_irq;
 int machine_id; // For NVRAM
+uint32_t iommu_version;
 uint32_t intbit_to_level[32];
 };
 
@@ -343,7 +344,7 @@ static void *sun4m_hw_init(const struct 
 /* allocate RAM */
 cpu_register_physical_memory(0, RAM_size, 0);
 
-iommu = iommu_init(hwdef-iommu_base);
+iommu = iommu_init(hwdef-iommu_base, hwdef-iommu_version);
 slavio_intctl = slavio_intctl_init(hwdef-intctl_base,
hwdef-intctl_base + 0x1ULL,
hwdef-intbit_to_level[0],
@@ -509,6 +510,7 @@ static const struct hwdef hwdefs[] = {
 .me_irq = 30,
 .cs_irq = 5,
 .machine_id = 0x80,
+.iommu_version = 0x0400,
 .intbit_to_level = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
@@ -542,6 +544,7 @@ static const struct hwdef hwdefs[] = {
 .me_irq = 30,
 .cs_irq = -1,
 .machine_id = 0x72,
+.iommu_version = 0x0300,
 .intbit_to_level = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,
@@ -575,6 +578,7 @@ static const struct hwdef hwdefs[] = {
 .me_irq = 30,
 .cs_irq = -1,
 .machine_id = 0x71,
+.iommu_version = 0x0100,
 .intbit_to_level = {
 2, 3, 5, 7, 9, 11, 0, 14,   3, 5, 7, 9, 11, 13, 12, 12,
 6, 0, 4, 10, 8, 0, 11, 0,   0, 0, 0, 0, 15, 0, 15, 0,


[Qemu-devel] [PATCH] sparc32 asi cleanups and debug printf

2007-11-10 Thread Robert Reif

This patch makes debugging asi and mxcc accesses easier to follow.
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.51
diff -p -u -r1.51 op_helper.c
--- target-sparc/op_helper.c7 Nov 2007 17:03:37 -   1.51
+++ target-sparc/op_helper.c10 Nov 2007 18:22:34 -
@@ -6,6 +6,7 @@
 //#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
+//#define DEBUG_ASI
 
 #ifdef DEBUG_MMU
 #define DPRINTF_MMU(fmt, args...) \
@@ -187,7 +188,7 @@ void helper_ld_asi(int asi, int size, in
 {
 uint32_t ret = 0;
 uint64_t tmp;
-#ifdef DEBUG_MXCC
+#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
 uint32_t last_T0 = T0;
 #endif
 
@@ -199,26 +200,34 @@ void helper_ld_asi(int asi, int size, in
 ret = env-mxccregs[3];
 T0 = env-mxccregs[3]  32;
 } else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 case 0x01c00a04: /* MXCC control register */
 if (size == 4)
 ret = env-mxccregs[3];
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
+break;
+case 0x01c00c00: /* Module reset register */
+if (size == 8) {
+ret = env-mxccregs[5];
+T0 = env-mxccregs[5]  32;
+// should we do something here?
+} else
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 case 0x01c00f00: /* MBus port address register */
 if (size == 8) {
 ret = env-mxccregs[7];
 T0 = env-mxccregs[7]  32;
 } else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 default:
-DPRINTF_MXCC(%08x: unimplemented address, size: %d\n, T0, size);
+DPRINTF_MXCC(read %08x: unimplemented address, size: %d\n, T0, 
size);
 break;
 }
-DPRINTF_MXCC(asi = %d, size = %d, sign = %d, T0 = %08x - ret = %08x,
+DPRINTF_MXCC(read(asi %d, size %d, sign %d) T0 = %08x - ret = %08x, 
  T0 = %08x\n, asi, size, sign, last_T0, ret, T0);
 #ifdef DEBUG_MXCC
 dump_mxcc(env);
@@ -355,6 +364,10 @@ void helper_ld_asi(int asi, int size, in
 break;
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
+#ifdef DEBUG_ASI
+printf(read: %08x asi 0x%02x size %d unsupported address,
+   last_T0, asi, size);
+#endif
 do_unassigned_access(T0, 0, 0, 1);
 ret = 0;
 break;
@@ -374,6 +387,11 @@ void helper_ld_asi(int asi, int size, in
 }
 else
 T1 = ret;
+
+#ifdef DEBUG_ASI
+printf(helper_ld_asi(asi 0x%02x, size %d, sign %d) T0 = %08x - 
+   T0 = %08x T1 = %08x\n, asi, size, sign, last_T0, T0, T1);
+#endif
 }
 
 void helper_st_asi(int asi, int size)
@@ -385,31 +403,31 @@ void helper_st_asi(int asi, int size)
 if (size == 8)
 env-mxccdata[0] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c8: /* MXCC stream data register 1 */
 if (size == 8)
 env-mxccdata[1] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c00010: /* MXCC stream data register 2 */
 if (size == 8)
 env-mxccdata[2] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c00018: /* MXCC stream data register 3 */
 if (size == 8)
 env-mxccdata[3] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c00100: /* MXCC stream source */
 if (size == 8)
 env-mxccregs[0] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+ 

Re: [Qemu-devel] [PATCH] sparc32 asi cleanups and debug printf

2007-11-10 Thread Robert Reif

Blue Swirl wrote:


DPRINTF_ASI would be nice.

 


Here is a revised patch:

Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.51
diff -p -u -r1.51 op_helper.c
--- target-sparc/op_helper.c7 Nov 2007 17:03:37 -   1.51
+++ target-sparc/op_helper.c10 Nov 2007 21:24:04 -
@@ -6,6 +6,7 @@
 //#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
+//#define DEBUG_ASI
 
 #ifdef DEBUG_MMU
 #define DPRINTF_MMU(fmt, args...) \
@@ -21,6 +22,13 @@ do { printf(MXCC:  fmt , ##args); } wh
 #define DPRINTF_MXCC(fmt, args...)
 #endif
 
+#ifdef DEBUG_ASI
+#define DPRINTF_ASI(fmt, args...) \
+do { printf(ASI:  fmt , ##args); } while (0)
+#else
+#define DPRINTF_ASI(fmt, args...)
+#endif
+
 void raise_exception(int tt)
 {
 env-exception_index = tt;
@@ -187,7 +195,7 @@ void helper_ld_asi(int asi, int size, in
 {
 uint32_t ret = 0;
 uint64_t tmp;
-#ifdef DEBUG_MXCC
+#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
 uint32_t last_T0 = T0;
 #endif
 
@@ -199,26 +207,34 @@ void helper_ld_asi(int asi, int size, in
 ret = env-mxccregs[3];
 T0 = env-mxccregs[3]  32;
 } else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 case 0x01c00a04: /* MXCC control register */
 if (size == 4)
 ret = env-mxccregs[3];
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
+break;
+case 0x01c00c00: /* Module reset register */
+if (size == 8) {
+ret = env-mxccregs[5];
+T0 = env-mxccregs[5]  32;
+// should we do something here?
+} else
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 case 0x01c00f00: /* MBus port address register */
 if (size == 8) {
 ret = env-mxccregs[7];
 T0 = env-mxccregs[7]  32;
 } else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(read %08x: unimplemented access size: %d\n, T0, 
size);
 break;
 default:
-DPRINTF_MXCC(%08x: unimplemented address, size: %d\n, T0, size);
+DPRINTF_MXCC(read %08x: unimplemented address, size: %d\n, T0, 
size);
 break;
 }
-DPRINTF_MXCC(asi = %d, size = %d, sign = %d, T0 = %08x - ret = %08x,
+DPRINTF_MXCC(read(asi %d, size %d, sign %d) T0 = %08x - ret = %08x, 
  T0 = %08x\n, asi, size, sign, last_T0, ret, T0);
 #ifdef DEBUG_MXCC
 dump_mxcc(env);
@@ -355,6 +371,8 @@ void helper_ld_asi(int asi, int size, in
 break;
 case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
 default:
+DPRINTF_ASI(read: %08x asi 0x%02x size %d unsupported address,
+   last_T0, asi, size);
 do_unassigned_access(T0, 0, 0, 1);
 ret = 0;
 break;
@@ -374,6 +392,9 @@ void helper_ld_asi(int asi, int size, in
 }
 else
 T1 = ret;
+
+DPRINTF_ASI(helper_ld_asi(asi 0x%02x, size %d, sign %d) T0 = %08x - 
+   T0 = %08x T1 = %08x\n, asi, size, sign, last_T0, T0, T1);
 }
 
 void helper_st_asi(int asi, int size)
@@ -385,31 +406,31 @@ void helper_st_asi(int asi, int size)
 if (size == 8)
 env-mxccdata[0] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c8: /* MXCC stream data register 1 */
 if (size == 8)
 env-mxccdata[1] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c00010: /* MXCC stream data register 2 */
 if (size == 8)
 env-mxccdata[2] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access size: %d\n, 
T0, size);
 break;
 case 0x01c00018: /* MXCC stream data register 3 */
 if (size == 8)
 env-mxccdata[3] = ((uint64_t)T1  32) | T2;
 else
-DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+DPRINTF_MXCC(write %08x: unimplemented access 

Re: [Qemu-devel] [PATCH] sparc32 boot mode flag fix

2007-11-06 Thread Robert Reif



This patch also performs a CPU reset after the CPU is registered rather
than before.
   



Why is this change needed?

 


Reset should be doing CPU dependent stuff and the CPU dependent setup
is performed when the CPU is registered.





[Qemu-devel] [PATCH] sparc32 boot mode flag fix

2007-11-05 Thread Robert Reif

This patch adds CPU dependent boot mode flag support.

Different CPUs use different bits for the boot mode flag.  The constant
MMU_BM is replaced with a variable which is set for the selected CPU.

This patch also removes the MMU flags from being saved in the
translation block code as a result of an off line discussion with Paul 
Brook.


This patch also performs a CPU reset after the CPU is registered rather
than before.

This patch has successfully booted the debian installer and the initrd 
kernel

in sparc-test successfully for both an ss5 and ss10.  It also makes running
an ss10 openboot rom image behave a little better.
Index: cpu-exec.c
===
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.120
diff -p -u -r1.120 cpu-exec.c
--- cpu-exec.c  14 Oct 2007 07:07:04 -  1.120
+++ cpu-exec.c  6 Nov 2007 00:12:56 -
@@ -181,10 +181,8 @@ static inline TranslationBlock *tb_find_
 flags = (((env-pstate  PS_PEF)  1) | ((env-fprs  FPRS_FEF)  2))
 | (env-pstate  PS_PRIV) | ((env-lsu  (DMMU_E | IMMU_E))  2);
 #else
-// FPU enable . MMU Boot . MMU enabled . MMU no-fault . Supervisor
-flags = (env-psref  4) | (((env-mmuregs[0]  MMU_BM)  14)  3)
-| ((env-mmuregs[0]  (MMU_E | MMU_NF))  1)
-| env-psrs;
+// FPU enable . Supervisor
+flags = (env-psref  4) | env-psrs;
 #endif
 cs_base = env-npc;
 pc = env-pc;
Index: target-sparc/cpu.h
===
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.56
diff -p -u -r1.56 cpu.h
--- target-sparc/cpu.h  14 Oct 2007 17:07:21 -  1.56
+++ target-sparc/cpu.h  6 Nov 2007 00:13:00 -
@@ -147,7 +147,6 @@
 /* MMU */
 #define MMU_E (10)
 #define MMU_NF(11)
-#define MMU_BM(114)
 
 #define PTE_ENTRYTYPE_MASK 3
 #define PTE_ACCESS_MASK0x1c
@@ -200,6 +199,7 @@ typedef struct CPUSPARCState {
 int interrupt_index;
 int interrupt_request;
 int halted;
+uint32_t mmu_bm;
 /* NOTE: we allow 8 more registers to handle wrapping */
 target_ulong regbase[NWINDOWS * 16 + 8];
 
Index: target-sparc/helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/helper.c,v
retrieving revision 1.28
diff -p -u -r1.28 helper.c
--- target-sparc/helper.c   14 Oct 2007 07:07:08 -  1.28
+++ target-sparc/helper.c   6 Nov 2007 00:13:00 -
@@ -114,7 +114,7 @@ int get_physical_address (CPUState *env,
 
 if ((env-mmuregs[0]  MMU_E) == 0) { /* MMU disabled */
 // Boot mode: instruction fetches are taken from PROM
-if (rw == 2  (env-mmuregs[0]  MMU_BM)) {
+if (rw == 2  (env-mmuregs[0]  env-mmu_bm)) {
 *physical = 0xff000ULL | (address  0x3ULL);
 *prot = PAGE_READ | PAGE_EXEC;
 return 0;
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.50
diff -p -u -r1.50 op_helper.c
--- target-sparc/op_helper.c29 Oct 2007 14:39:49 -  1.50
+++ target-sparc/op_helper.c6 Nov 2007 00:13:01 -
@@ -493,8 +493,8 @@ void helper_st_asi(int asi, int size)
 oldreg = env-mmuregs[reg];
 switch(reg) {
 case 0:
-env-mmuregs[reg] = ~(MMU_E | MMU_NF | MMU_BM);
-env-mmuregs[reg] |= T1  (MMU_E | MMU_NF | MMU_BM);
+env-mmuregs[reg] = ~(MMU_E | MMU_NF | env-mmu_bm);
+env-mmuregs[reg] |= T1  (MMU_E | MMU_NF | env-mmu_bm);
 // Mappings generated during no-fault mode or MMU
 // disabled mode are invalid in normal mode
 if (oldreg != env-mmuregs[reg])
Index: target-sparc/translate.c
===
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.78
diff -p -u -r1.78 translate.c
--- target-sparc/translate.c17 Oct 2007 17:34:57 -  1.78
+++ target-sparc/translate.c6 Nov 2007 00:13:03 -
@@ -59,6 +59,7 @@ struct sparc_def_t {
 target_ulong iu_version;
 uint32_t fpu_version;
 uint32_t mmu_version;
+uint32_t mmu_bm;
 };
 
 static uint16_t *gen_opc_ptr;
@@ -3482,7 +3483,7 @@ void cpu_reset(CPUSPARCState *env)
 #else
 env-pc = 0;
 env-mmuregs[0] = ~(MMU_E | MMU_NF);
-env-mmuregs[0] |= MMU_BM;
+env-mmuregs[0] |= env-mmu_bm;
 #endif
 env-npc = env-pc + 4;
 #endif
@@ -3496,7 +3497,6 @@ CPUSPARCState *cpu_sparc_init(void)
 if (!env)
 return NULL;
 cpu_exec_init(env);
-cpu_reset(env);
 return (env);
 }
 
@@ -3515,30 +3515,35 @@ static const sparc_def_t sparc_defs[] = 
 .iu_version = 0x04  24, /* Impl 0, ver 4 */
 .fpu_version = 4  17, /* FPU version 4 (Meiko) */
 .mmu_version = 0x04  24, /* 

[Qemu-devel] [PATCH] sparc32: hw/slavio_misc.c sysctrl register is 32 bits

2007-11-04 Thread Robert Reif

The sysctrl register is actually 32 bits.  Add code to access it as 32 bits.

Index: hw/slavio_misc.c
===
RCS file: /sources/qemu/qemu/hw/slavio_misc.c,v
retrieving revision 1.10
diff -p -u -r1.10 slavio_misc.c
--- hw/slavio_misc.c6 Oct 2007 11:28:21 -   1.10
+++ hw/slavio_misc.c4 Nov 2007 15:21:17 -
@@ -44,10 +44,12 @@ typedef struct MiscState {
 qemu_irq irq;
 uint8_t config;
 uint8_t aux1, aux2;
-uint8_t diag, mctrl, sysctrl;
+uint8_t diag, mctrl;
+uint32_t sysctrl;
 } MiscState;
 
 #define MISC_SIZE 1
+#define SYSCTRL_SIZE 4
 
 static void slavio_misc_update_irq(void *opaque)
 {
@@ -116,13 +118,6 @@ static void slavio_misc_mem_writeb(void 
 MISC_DPRINTF(Write modem control %2.2x\n, val  0xff);
 s-mctrl = val  0xff;
 break;
-case 0x1f0:
-MISC_DPRINTF(Write system control %2.2x\n, val  0xff);
-if (val  1) {
-s-sysctrl = 0x2;
-qemu_system_reset_request();
-}
-break;
 case 0xa00:
 MISC_DPRINTF(Write power management %2.2x\n, val  0xff);
 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
@@ -156,10 +151,6 @@ static uint32_t slavio_misc_mem_readb(vo
 ret = s-mctrl;
 MISC_DPRINTF(Read modem control %2.2x\n, ret);
 break;
-case 0x1f0:
-MISC_DPRINTF(Read system control %2.2x\n, ret);
-ret = s-sysctrl;
-break;
 case 0xa00:
 MISC_DPRINTF(Read power management %2.2x\n, ret);
 break;
@@ -178,6 +169,47 @@ static CPUWriteMemoryFunc *slavio_misc_m
 slavio_misc_mem_writeb,
 slavio_misc_mem_writeb,
 };
+ 
+static uint32_t slavio_misc_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+MiscState *s = opaque;
+uint32_t ret = 0;
+
+switch (addr) {
+case 0x1f0:
+MISC_DPRINTF(Read system control %08x\n, ret);
+ret = s-sysctrl;
+break;
+}
+return ret;
+}
+
+static void slavio_misc_mem_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+{
+MiscState *s = opaque;
+
+switch (addr) {
+case 0x1f0:
+MISC_DPRINTF(Write system control %08x\n, val);
+if (val  1) {
+s-sysctrl = 0x2;
+qemu_system_reset_request();
+}
+break;
+}
+}
+
+static CPUReadMemoryFunc *slavio_misc_mem_read32[3] = {
+slavio_misc_mem_readl,
+slavio_misc_mem_readl,
+slavio_misc_mem_readl,
+};
+
+static CPUWriteMemoryFunc *slavio_misc_mem_write32[3] = {
+slavio_misc_mem_writel,
+slavio_misc_mem_writel,
+slavio_misc_mem_writel,
+};
 
 static void slavio_misc_save(QEMUFile *f, void *opaque)
 {
@@ -191,7 +223,7 @@ static void slavio_misc_save(QEMUFile *f
 qemu_put_8s(f, s-aux2);
 qemu_put_8s(f, s-diag);
 qemu_put_8s(f, s-mctrl);
-qemu_put_8s(f, s-sysctrl);
+qemu_put_be32s(f, s-sysctrl);
 }
 
 static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
@@ -208,20 +240,21 @@ static int slavio_misc_load(QEMUFile *f,
 qemu_get_8s(f, s-aux2);
 qemu_get_8s(f, s-diag);
 qemu_get_8s(f, s-mctrl);
-qemu_get_8s(f, s-sysctrl);
+qemu_get_be32s(f, s-sysctrl);
 return 0;
 }
 
 void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base,
qemu_irq irq)
 {
-int slavio_misc_io_memory;
+int slavio_misc_io_memory, slavio_misc_io_memory32;
 MiscState *s;
 
 s = qemu_mallocz(sizeof(MiscState));
 if (!s)
 return NULL;
 
+/* 8 bit registers */
 slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, 
slavio_misc_mem_write, s);
 // Slavio control
 cpu_register_physical_memory(base + 0x180, MISC_SIZE,
@@ -238,12 +271,15 @@ void *slavio_misc_init(target_phys_addr_
 // Modem control
 cpu_register_physical_memory(base + 0x1b0, MISC_SIZE,
  slavio_misc_io_memory);
-// System control
-cpu_register_physical_memory(base + 0x1f0, MISC_SIZE,
- slavio_misc_io_memory);
 // Power management
 cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
 
+/* 32 bit registers */
+slavio_misc_io_memory32 = cpu_register_io_memory(0, 
slavio_misc_mem_read32, slavio_misc_mem_write32, s);
+// System control
+cpu_register_physical_memory(base + 0x1f0, SYSCTRL_SIZE,
+ slavio_misc_io_memory32);
+
 s-irq = irq;
 
 register_savevm(slavio_misc, base, 1, slavio_misc_save, 
slavio_misc_load, s);


Re: [Qemu-devel] [PATCH] sparc32: hw/slavio_misc.c sysctrl register is 32 bits

2007-11-04 Thread Robert Reif
Please use this version.  The previous version didn't mask off the top 
address bit.


The sysctrl register is actually 32 bits.  Add code to access it as 32 
bits.



Index: hw/slavio_misc.c
===
RCS file: /sources/qemu/qemu/hw/slavio_misc.c,v
retrieving revision 1.10
diff -p -u -r1.10 slavio_misc.c
--- hw/slavio_misc.c6 Oct 2007 11:28:21 -   1.10
+++ hw/slavio_misc.c4 Nov 2007 15:29:45 -
@@ -44,10 +44,12 @@ typedef struct MiscState {
 qemu_irq irq;
 uint8_t config;
 uint8_t aux1, aux2;
-uint8_t diag, mctrl, sysctrl;
+uint8_t diag, mctrl;
+uint32_t sysctrl;
 } MiscState;
 
 #define MISC_SIZE 1
+#define SYSCTRL_SIZE 4
 
 static void slavio_misc_update_irq(void *opaque)
 {
@@ -116,13 +118,6 @@ static void slavio_misc_mem_writeb(void 
 MISC_DPRINTF(Write modem control %2.2x\n, val  0xff);
 s-mctrl = val  0xff;
 break;
-case 0x1f0:
-MISC_DPRINTF(Write system control %2.2x\n, val  0xff);
-if (val  1) {
-s-sysctrl = 0x2;
-qemu_system_reset_request();
-}
-break;
 case 0xa00:
 MISC_DPRINTF(Write power management %2.2x\n, val  0xff);
 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
@@ -156,10 +151,6 @@ static uint32_t slavio_misc_mem_readb(vo
 ret = s-mctrl;
 MISC_DPRINTF(Read modem control %2.2x\n, ret);
 break;
-case 0x1f0:
-MISC_DPRINTF(Read system control %2.2x\n, ret);
-ret = s-sysctrl;
-break;
 case 0xa00:
 MISC_DPRINTF(Read power management %2.2x\n, ret);
 break;
@@ -178,6 +169,47 @@ static CPUWriteMemoryFunc *slavio_misc_m
 slavio_misc_mem_writeb,
 slavio_misc_mem_writeb,
 };
+ 
+static uint32_t slavio_misc_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+MiscState *s = opaque;
+uint32_t ret = 0;
+
+switch (addr  0xfff) {
+case 0x1f0:
+MISC_DPRINTF(Read system control %08x\n, ret);
+ret = s-sysctrl;
+break;
+}
+return ret;
+}
+
+static void slavio_misc_mem_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+{
+MiscState *s = opaque;
+
+switch (addr  0xfff) {
+case 0x1f0:
+MISC_DPRINTF(Write system control %08x\n, val);
+if (val  1) {
+s-sysctrl = 0x2;
+qemu_system_reset_request();
+}
+break;
+}
+}
+
+static CPUReadMemoryFunc *slavio_misc_mem_read32[3] = {
+slavio_misc_mem_readl,
+slavio_misc_mem_readl,
+slavio_misc_mem_readl,
+};
+
+static CPUWriteMemoryFunc *slavio_misc_mem_write32[3] = {
+slavio_misc_mem_writel,
+slavio_misc_mem_writel,
+slavio_misc_mem_writel,
+};
 
 static void slavio_misc_save(QEMUFile *f, void *opaque)
 {
@@ -191,7 +223,7 @@ static void slavio_misc_save(QEMUFile *f
 qemu_put_8s(f, s-aux2);
 qemu_put_8s(f, s-diag);
 qemu_put_8s(f, s-mctrl);
-qemu_put_8s(f, s-sysctrl);
+qemu_put_be32s(f, s-sysctrl);
 }
 
 static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
@@ -208,20 +240,21 @@ static int slavio_misc_load(QEMUFile *f,
 qemu_get_8s(f, s-aux2);
 qemu_get_8s(f, s-diag);
 qemu_get_8s(f, s-mctrl);
-qemu_get_8s(f, s-sysctrl);
+qemu_get_be32s(f, s-sysctrl);
 return 0;
 }
 
 void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base,
qemu_irq irq)
 {
-int slavio_misc_io_memory;
+int slavio_misc_io_memory, slavio_misc_io_memory32;
 MiscState *s;
 
 s = qemu_mallocz(sizeof(MiscState));
 if (!s)
 return NULL;
 
+/* 8 bit registers */
 slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, 
slavio_misc_mem_write, s);
 // Slavio control
 cpu_register_physical_memory(base + 0x180, MISC_SIZE,
@@ -238,12 +271,15 @@ void *slavio_misc_init(target_phys_addr_
 // Modem control
 cpu_register_physical_memory(base + 0x1b0, MISC_SIZE,
  slavio_misc_io_memory);
-// System control
-cpu_register_physical_memory(base + 0x1f0, MISC_SIZE,
- slavio_misc_io_memory);
 // Power management
 cpu_register_physical_memory(power_base, MISC_SIZE, slavio_misc_io_memory);
 
+/* 32 bit registers */
+slavio_misc_io_memory32 = cpu_register_io_memory(0, 
slavio_misc_mem_read32, slavio_misc_mem_write32, s);
+// System control
+cpu_register_physical_memory(base + 0x1f0, SYSCTRL_SIZE,
+ slavio_misc_io_memory32);
+
 s-irq = irq;
 
 register_savevm(slavio_misc, base, 1, slavio_misc_save, 
slavio_misc_load, s);


[Qemu-devel] sparc hflags support?

2007-11-04 Thread Robert Reif

I'm looking at adding more complete support for different sparc32
CPUs, MMUs,  cache controllers and systems.

Each CPU/MMU/cache controller combination is slightly different and
requires its own unique state.  For example the two CPUs currently
supported save the boot mode in different bits in the MMU control
register: 0x2000 for the SuperSparc and 0x4000 for the TurboSparc.
Others bits will need to be saved in the MMU and cache controllers
as better hardware emulation is added.

It looks like other architectures handle this by computing hflags
in the target directories but sparc determines the flags value to save
in common code. 


Are there plans to add hflags support to sparc?  I'm willing work
on it but I don't have the experience yet to tackle a job like this
without help.





Re: [Qemu-devel] [RFC] sparc32 MXCC support

2007-10-14 Thread Robert Reif

Blue Swirl wrote:


On 10/13/07, Robert Reif [EMAIL PROTECTED] wrote:
 


I'm trying to add SuperSparc II MXCC support and need some feedback.

Is there a better way to read and write physical memory in 64bit chunks?
I'm not sure what I'm doing is portable between 32/64 and big/little endian.
   



Thank you for your effort. Applying the patch allows NetBSD on SS-10
to boot as far as on SS-5, previously it crashed.

I think the code is portable, but I think changing the register type
to uint32_t and using a DPRINTF system like used in for example
hw/iommu.c should make the code slightly clearer.


I don't have access to chip specs but from reading linux and *bsd code it
appears that the registers are 64 bits wide but sometimes accessed as 32 
bits to get

only the bottom 32 bits.  Do you mean using two uint32_t for a 64 bit
register?  How about a union of 2 uint32_t and a uint64_t.  Is that 
portable?
Never mind.  I just found out there is an ldq_phys and stq_phys.  I'll 
use those.


I looked at DPRINTF but would need a DPRINTF_MMU and DPRINTF_MXCC ...
Would that be acceptable?



For the memory access, ldl/q_phys/stl/q_phys is used in other block
copy routines. For longer blocks or if the address can be unaligned,
cpu_physical_memory_read() could be a better choice.
 

 


+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, int cpu);
   



unsigned int cpu?
 


OK


+printf(ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = 
%08x: unsupported size\n, asi, size, sign, T0);
   



If it's an error to access the registers with different size, you
should use do_unassigned_access() to report this.

 

These are more for me to make sure I catch all the necessary accesses 
without adding unnecessary code.
linux 2.4 and netbsd only use the ones I have implemented.  openboot 
uses more and
also some undocumented ones which are caught by this but I don't know 
how to handle

them yet.  I will use do_unassigned_access where necessary now.

Thanks for the review.





[Qemu-devel] [PATCH] sparc32: add MXCC support

2007-10-14 Thread Robert Reif

Updated patch base of feedback.

This patch adds SuperSparc MXCC support.
DPRINTF_MMU and DPRINTF_MXCC added.

I decided not to use do_unassigned_access() at this time because I don't 
know what real hardware does.
Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.55
diff -p -u -r1.55 sun4m.c
--- hw/sun4m.c  6 Oct 2007 11:28:21 -   1.55
+++ hw/sun4m.c  14 Oct 2007 15:07:52 -
@@ -327,7 +327,7 @@ static void *sun4m_hw_init(const struct 
 
 for(i = 0; i  smp_cpus; i++) {
 env = cpu_init();
-cpu_sparc_register(env, def);
+cpu_sparc_register(env, def, i);
 envs[i] = env;
 if (i == 0) {
 qemu_register_reset(main_cpu_reset, env);
Index: linux-user/main.c
===
RCS file: /sources/qemu/qemu/linux-user/main.c,v
retrieving revision 1.132
diff -p -u -r1.132 main.c
--- linux-user/main.c   12 Oct 2007 06:47:46 -  1.132
+++ linux-user/main.c   14 Oct 2007 15:07:53 -
@@ -2139,7 +2139,7 @@ int main(int argc, char **argv)
 fprintf(stderr, Unable to find Sparc CPU definition\n);
 exit(1);
 }
-cpu_sparc_register(env, def);
+cpu_sparc_register(env, def, 0);
env-pc = regs-pc;
env-npc = regs-npc;
 env-y = regs-y;
Index: target-sparc/cpu.h
===
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.53
diff -p -u -r1.53 cpu.h
--- target-sparc/cpu.h  12 Oct 2007 06:47:46 -  1.53
+++ target-sparc/cpu.h  14 Oct 2007 15:07:53 -
@@ -210,6 +210,8 @@ typedef struct CPUSPARCState {
 uint64_t dtlb_tte[64];
 #else
 uint32_t mmuregs[16];
+uint64_t mxccdata[4];
+uint64_t mxccregs[8];
 #endif
 /* temporary float registers */
 float32 ft0, ft1;
@@ -266,7 +268,7 @@ int cpu_sparc_close(CPUSPARCState *s);
 int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
  ...));
-int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, unsigned 
int cpu);
 
 #define GET_PSR(env) (env-version | (env-psr  PSR_ICC) | \
   (env-psref? PSR_EF : 0) |\
Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -p -u -r1.41 op_helper.c
--- target-sparc/op_helper.c1 Oct 2007 17:07:58 -   1.41
+++ target-sparc/op_helper.c14 Oct 2007 15:07:54 -
@@ -2,9 +2,24 @@
 
 //#define DEBUG_PCALL
 //#define DEBUG_MMU
+//#define DEBUG_MXCC
 //#define DEBUG_UNALIGNED
 //#define DEBUG_UNASSIGNED
 
+#ifdef DEBUG_MMU
+#define DPRINTF_MMU(fmt, args...) \
+do { printf(MMU:  fmt , ##args); } while (0)
+#else
+#define DPRINTF_MMU(fmt, args...)
+#endif
+
+#ifdef DEBUG_MXCC
+#define DPRINTF_MXCC(fmt, args...) \
+do { printf(MXCC:  fmt , ##args); } while (0)
+#else
+#define DPRINTF_MXCC(fmt, args...)
+#endif
+
 void raise_exception(int tt)
 {
 env-exception_index = tt;
@@ -139,12 +154,57 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1,
 
 #ifndef TARGET_SPARC64
 #ifndef CONFIG_USER_ONLY
+
+#ifdef DEBUG_MXCC
+void dump_mxcc(CPUState *env)
+{
+printf(mxccdata: %016llx %016llx %016llx %016llx\n,
+env-mxccdata[0], env-mxccdata[1], env-mxccdata[2], 
env-mxccdata[3]);
+printf(mxccregs: %016llx %016llx %016llx %016llx\n
+ %016llx %016llx %016llx %016llx\n,
+env-mxccregs[0], env-mxccregs[1], env-mxccregs[2], env-mxccregs[3],
+env-mxccregs[4], env-mxccregs[5], env-mxccregs[6], 
env-mxccregs[7]);
+}
+#endif
+
 void helper_ld_asi(int asi, int size, int sign)
 {
 uint32_t ret = 0;
+#ifdef DEBUG_MXCC
+uint32_t last_T0 = T0;
+#endif
 
 switch (asi) {
 case 2: /* SuperSparc MXCC registers */
+switch (T0) {
+case 0x01c00a00: /* MXCC control register */
+if (size == 8) {
+ret = env-mxccregs[3];
+T0 = env-mxccregs[3]  32;
+} else
+DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+break;
+case 0x01c00a04: /* MXCC control register */
+if (size == 4)
+ret = env-mxccregs[3];
+else
+DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 
size);
+break;
+case 0x01c00f00: /* MBus port address register */
+if (size == 8) {
+ret = env-mxccregs[7];
+T0 = env-mxccregs[7]  32;
+} else
+DPRINTF_MXCC(%08x: unimplemented access size: %d\n, T0, 

[Qemu-devel] [PATCH] sparc32 use stq_* for 64bit stores

2007-10-14 Thread Robert Reif

Use stq_* for 64 bit stores.

This fixes one bug where T1 was used twice rather than T1 and T2.

Should the address be 64 bit alligned?  i.e. T0  ~7 rather than T0  ~3?

Should these unaligned address cause traps?

Index: target-sparc/op_helper.c
===
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.44
diff -p -u -r1.44 op_helper.c
--- target-sparc/op_helper.c14 Oct 2007 17:07:21 -  1.44
+++ target-sparc/op_helper.c14 Oct 2007 18:28:37 -
@@ -515,8 +515,7 @@ void helper_st_asi(int asi, int size)
 stl_user(T0  ~3, T1);
 break;
 case 8:
-stl_user(T0  ~3, T1);
-stl_user((T0 + 4)  ~3, T2);
+stq_user(T0  ~3, ((uint64_t)T1  32) | T2);
 break;
 }
 break;
@@ -533,8 +532,7 @@ void helper_st_asi(int asi, int size)
 stl_kernel(T0  ~3, T1);
 break;
 case 8:
-stl_kernel(T0  ~3, T1);
-stl_kernel((T0 + 4)  ~3, T2);
+stq_kernel(T0  ~3, ((uint64_t)T1  32) | T2);
 break;
 }
 break;
@@ -591,8 +589,7 @@ void helper_st_asi(int asi, int size)
 stl_phys(T0  ~3, T1);
 break;
 case 8:
-stl_phys(T0  ~3, T1);
-stl_phys((T0 + 4)  ~3, T2);
+stq_phys(T0  ~3, ((uint64_t)T1  32) | T2);
 break;
 }
 }
@@ -615,10 +612,8 @@ void helper_st_asi(int asi, int size)
| ((target_phys_addr_t)(asi  0xf)  32), T1);
 break;
 case 8:
-stl_phys((target_phys_addr_t)(T0  ~3)
-   | ((target_phys_addr_t)(asi  0xf)  32), T1);
-stl_phys((target_phys_addr_t)((T0 + 4)  ~3)
-   | ((target_phys_addr_t)(asi  0xf)  32), T1);
+stq_phys((target_phys_addr_t)(T0  ~3)
+   | ((target_phys_addr_t)(asi  0xf)  32), 
((uint64_t)T1  32) | T2);
 break;
 }
 }


Re: [Qemu-devel] [PATCH] sparc32 use stq_* for 64bit stores

2007-10-14 Thread Robert Reif

Blue Swirl wrote:


On 10/14/07, Robert Reif [EMAIL PROTECTED] wrote:
 


Should the address be 64 bit alligned?  i.e. T0  ~7 rather than T0  ~3?

Should these unaligned address cause traps?
   



Yes, but the checks are already generated from translate.c
(gen_op_check_align_T0_7).
 


De we to align then again?





[Qemu-devel] [PATCH] sparc32 slaveio_timer user timer fixes

2007-10-06 Thread Robert Reif

Some more user timer fixes.

Index: hw/slavio_timer.c
===
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.17
diff -p -u -r1.17 slavio_timer.c
--- hw/slavio_timer.c   6 Oct 2007 11:28:21 -   1.17
+++ hw/slavio_timer.c   6 Oct 2007 12:28:53 -
@@ -54,16 +54,24 @@ typedef struct SLAVIO_TIMERState {
 ptimer_state *timer;
 uint32_t count, counthigh, reached;
 uint64_t limit;
-int stopped;
-int mode; // 0 = processor, 1 = user, 2 = system
+// processor only
+int running;
+struct SLAVIO_TIMERState *master;
+int slave_index;
+// system only
 struct SLAVIO_TIMERState *slave[MAX_CPUS];
 uint32_t slave_mode;
 } SLAVIO_TIMERState;
 
 #define TIMER_MAXADDR 0x1f
-#define TIMER_SIZE (TIMER_MAXADDR + 1)
+#define SYS_TIMER_SIZE 0x14
 #define CPU_TIMER_SIZE 0x10
 
+static int slavio_timer_is_user(SLAVIO_TIMERState *s)
+{
+return s-master  (s-master-slave_mode  (1  s-slave_index));
+}
+
 // Update count, set irq, update expire_time
 // Convert from ptimer countdown units
 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
@@ -84,9 +92,10 @@ static void slavio_timer_irq(void *opaqu
 
 slavio_timer_get_out(s);
 DPRINTF(callback: count %x%08x\n, s-counthigh, s-count);
-s-reached = 0x8000;
-if (s-mode != 1)
+if (!slavio_timer_is_user(s)) {
+s-reached = 0x8000;
 qemu_irq_raise(s-irq);
+}
 }
 
 static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
@@ -99,35 +108,39 @@ static uint32_t slavio_timer_mem_readl(v
 case 0:
 // read limit (system counter mode) or read most signifying
 // part of counter (user mode)
-if (s-mode != 1) {
+if (slavio_timer_is_user(s)) {
+// read user timer MSW
+slavio_timer_get_out(s);
+ret = s-counthigh;
+} else {
+// read limit
 // clear irq
 qemu_irq_lower(s-irq);
 s-reached = 0;
 ret = s-limit  0x7fff;
 }
-else {
-slavio_timer_get_out(s);
-ret = s-counthigh  0x7fff;
-}
 break;
 case 1:
 // read counter and reached bit (system mode) or read lsbits
 // of counter (user mode)
 slavio_timer_get_out(s);
-if (s-mode != 1)
-ret = (s-count  0x7fff) | s-reached;
-else
-ret = s-count;
+if (slavio_timer_is_user(s)) // read user timer LSW
+ret = s-count  0xffe00;
+else // read limit
+ret = (s-count  0x7e00) | s-reached;
 break;
 case 3:
+// only available in processor counter/timer
 // read start/stop status
-ret = s-stopped;
+ret = s-running;
 break;
 case 4:
+// only available in system counter
 // read user/system mode
 ret = s-slave_mode;
 break;
 default:
+DPRINTF(invalid read address  TARGET_FMT_plx \n, addr);
 ret = 0;
 break;
 }
@@ -146,20 +159,31 @@ static void slavio_timer_mem_writel(void
 saddr = (addr  TIMER_MAXADDR)  2;
 switch (saddr) {
 case 0:
-if (s-mode == 1) {
-// set user counter limit MSW, reset counter
+if (slavio_timer_is_user(s)) {
+// set user counter MSW, reset counter
 qemu_irq_lower(s-irq);
-s-limit = 0xfe00ULL;
-s-limit |= (uint64_t)val  32;
+s-limit = 0x7e00ULL;
+DPRINTF(processor %d user timer reset\n, s-slave_index);
+ptimer_set_limit(s-timer, s-limit  9, 1);
+} else {
+// set limit, reset counter
+qemu_irq_lower(s-irq);
+s-limit = val  0x7e00ULL;
 if (!s-limit)
-s-limit = 0x7e00ULL;
+s-limit = 0x7e00ULL;
 ptimer_set_limit(s-timer, s-limit  9, 1);
-break;
 }
-// set limit, reset counter
-reload = 1;
-qemu_irq_lower(s-irq);
-// fall through
+break;
+case 1:
+if (slavio_timer_is_user(s)) {
+// set user counter LSW, reset counter
+qemu_irq_lower(s-irq);
+s-limit = 0x7e00ULL;
+DPRINTF(processor %d user timer reset\n, s-slave_index);
+ptimer_set_limit(s-timer, s-limit  9, 1);
+} else
+DPRINTF(not user timer\n);
+break;
 case 2:
 // set limit without resetting counter
 s-limit = val  0x7e00ULL;
@@ -167,52 +191,42 @@ static void slavio_timer_mem_writel(void
 s-limit = 0x7e00ULL;
 ptimer_set_limit(s-timer, s-limit  9, reload);
 break;
-case 1:
-// set user counter limit LSW, reset counter
-if (s-mode == 1) {
-

[Qemu-devel] [PATCH] Add support to sparc for loading a real bios image.

2007-10-05 Thread Robert Reif

Add support to sparc for loading a real bios image.

Index: hw/sun4m.c
===
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.52
diff -p -u -r1.52 sun4m.c
--- hw/sun4m.c  5 Oct 2007 13:08:35 -   1.52
+++ hw/sun4m.c  6 Oct 2007 00:05:16 -
@@ -49,7 +49,7 @@
 #define KERNEL_LOAD_ADDR 0x4000
 #define CMDLINE_ADDR 0x007ff000
 #define INITRD_LOAD_ADDR 0x0080
-#define PROM_SIZE_MAX(256 * 1024)
+#define PROM_SIZE_MAX(512 * 1024)
 #define PROM_PADDR   0xff000ULL
 #define PROM_VADDR   0xffd0
 #define PROM_FILENAME   openbios-sparc32
@@ -435,9 +435,12 @@ static void sun4m_load_kernel(long vram_
 snprintf(buf, sizeof(buf), %s/%s, bios_dir, bios_name);
 ret = load_elf(buf, PROM_PADDR - PROM_VADDR, NULL, NULL, NULL);
 if (ret  0) {
-   fprintf(stderr, qemu: could not load prom '%s'\n,
+ret = load_image(buf, phys_ram_base + prom_offset);
+   if (ret  0) {
+   fprintf(stderr, qemu: could not load prom '%s'\n,
buf);
-   exit(1);
+   exit(1);
+   }
 }
 
 kernel_size = 0;


[Qemu-devel] sparc32 CVS broken

2007-10-01 Thread Robert Reif

Sparc32 CVS exits after illegal instruction trap.

Nvram id QEMU_BIOS, version 1, machine id 0x80
CPUs: 1
Welcome to OpenBIOS v1.0RC1 built on Aug 11 2007 08:00
  Type 'help' for detailed information

[sparc] Kernel already loaded
qemu: fatal: Trap 0x02 while interrupts disabled, Error state
pc: ffd0108c  npc: ffd01090
General Registers:
%g0:    %g1: 0002   %g2: 04401fc2   %g3: ffd7f018   
%g4: 0028   %g5:    %g6:    %g7:    
Current Register Window:
%o0: 000a   %o1: 0022d570   %o2: ffd3b8a6   %o3: ffdd2ce0   
%o4: ffd08568   %o5: ffd08578   %o6: ffdd2a30   %o7: ffd0100c   
%l0: ffd7f15c   %l1: 4000   %l2: 4004   %l3: ffd3c000   
%l4: ffd7f000   %l5: ffd7f000   %l6: ffd80c00   %l7: ffd0   
%i0: ffd7f15c   %i1:    %i2:    %i3:    
%i4:    %i5:    %i6: ffdd2c98   %i7: ffd06310   

Floating Point Registers:
%f00: 0.00 0.00 0.00 0.00
%f04: 0.00 0.00 0.00 0.00
%f08: 0.00 0.00 0.00 0.00
%f12: 0.00 0.00 0.00 0.00
%f16: 0.00 0.00 0.00 0.00
%f20: 0.00 0.00 0.00 0.00
%f24: 0.00 0.00 0.00 0.00
%f28: 0.00 0.00 0.00 0.00
psr: 0x04401fc2 - Z--- SP- wim: 0x0010
fsr: 0x0008
./qemu-nog: line 4:  5400 Aborted qemu-system-sparc -kernel 
vmlinux-2.6.11+tcx -initrd linux.img -append root=/dev/ram console=ttyS0 
video=tcxfb:off -nographic


[Qemu-devel] sparc32 counter/timer issues

2007-09-21 Thread Robert Reif

I'm trying to run a real ss10 openboot prom image rather than
the supplied prom image and found some issues with the way
counters and timers are implemented.  It appears that the processor
and system counter/timers are not independent.  The system
config register actually configures the processor counter/timers
and the config register is actually a bit mask of the counter/timer
to configure. 1, 2, 4, and 8 are used to as config values for each
processor counter/timer and 0xf is used for setting all of them. 
This isn't apparent in the slaveio documentation because it is

for a single cpu only.

Because the system config register configures the processor
timers, it needs access to all the processor timers (or the
processor timers need access to the system timer).  This isn't
how it's currently implemented.





Re: [Qemu-devel] sparc32 counter/timer issues

2007-09-21 Thread Robert Reif

With the patch and ss10 boot prom I get:

TIMER: write 000ff13c 
TIMER: write 000ff1310010 0001
TIMER: write 000ff130 
TIMER: write 000ff134 
TIMER: write 000ff13c 0001
TIMER: write 000ff130 
TIMER: write 000ff134 
TIMER: get_out: limit 7e00 count 0
TIMER: read 000ff130 = 

with the last two lines repeating forever.





[Qemu-devel] sparc32 networking working?

2007-09-02 Thread Robert Reif

I'm trying to use sparc32 on linux i686 RH9 and am unable to
to get this working with current CVS.  My old scripts that
didn't set any networking options no longer work.  When
running a debian sparc netinst cd the setup finds a dhcp
connection but is unable to connect to the internet.

Adding -user to the command line causes it to output this:
Invalid vlan (0) with no nics

Adding -nic lance to the command line cause it to output this:
qemu-system-sparc: invalid option -- '-nic'

Any idea on what to do next.  If I remember correctly, the
last time I tried this (a few months ago) I was able to successfully
do a debian network install.





[Qemu-devel] Current CVS build errors on RH9

2007-09-01 Thread Robert Reif

It's been a few months since I comipled from source so I
just tried with current CVS and got these errors on RH9:

/home/wine/qemu/linux-user/syscall.c: In function `sys_tgkill':
/home/wine/qemu/linux-user/syscall.c:170: `__NR_tgkill' undeclared 
(first use in this function)
/home/wine/qemu/linux-user/syscall.c:170: (Each undeclared identifier is 
reported only once

/home/wine/qemu/linux-user/syscall.c:170: for each function it appears in.)

in various subdirectories and:

/home/wine/qemu/vl.c:59:24: linux/hpet.h: No such file or directory
/home/wine/qemu/vl.c: In function `hpet_start_timer':
/home/wine/qemu/vl.c:1222: storage size of `info' isn't known
/home/wine/qemu/vl.c:1230: `HPET_IRQFREQ' undeclared (first use in this 
function)

/home/wine/qemu/vl.c:1230: (Each undeclared identifier is reported only once
/home/wine/qemu/vl.c:1230: for each function it appears in.)
/home/wine/qemu/vl.c:1239: `HPET_INFO' undeclared (first use in this 
function)
/home/wine/qemu/vl.c:1244: `HPET_EPI' undeclared (first use in this 
function)
/home/wine/qemu/vl.c:1249: `HPET_IE_ON' undeclared (first use in this 
function)

/home/wine/qemu/vl.c:1222: warning: unused variable `info'

in various other subdirectories.