[Qemu-devel] qemu/hw nand.c pxa.h pxa2xx.c pxa2xx_lcd.c spitz.c

2007-05-12 Thread Andrzej Zaborowski
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Andrzej Zaborowski balrog 07/05/12 09:19:36

Modified files:
hw : nand.c pxa.h pxa2xx.c pxa2xx_lcd.c spitz.c 

Log message:
Correct NAND erase block size.  Misc fixes in Spitz code.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/nand.c?cvsroot=qemur1=1.1r2=1.2
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/pxa.h?cvsroot=qemur1=1.3r2=1.4
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/pxa2xx.c?cvsroot=qemur1=1.9r2=1.10
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/pxa2xx_lcd.c?cvsroot=qemur1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/qemu/hw/spitz.c?cvsroot=qemur1=1.4r2=1.5




[Qemu-devel] [PATCH][MIPS] MMU code improvements

2007-05-12 Thread Aurelien Jarno
Hi all,

Please find below a patch to improve the MMU code on the MIPS target.

It fixes map_address() invalidate_tlb() and do_tlbp() for page sizes 
greater than 4kB. The VPN contained in a TLB should be masked with the
page mask of the same TLB as the VPN value may not be aligned. This is
explicitely required at least for tlbp in the MIPS64 PRA manual.

It also replace a few hardcoded values corresponding to the minimum
page size of 4kB by the size of a QEMU page (using TARGET_PAGE_MASK).
It should help to add 1kB pages support.

The other parts are cosmetic fixes.

Cheers,
Aurelien


Index: target-mips/helper.c
===
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.37
diff -u -d -p -r1.37 helper.c
--- target-mips/helper.c9 May 2007 09:34:30 -   1.37
+++ target-mips/helper.c12 May 2007 13:46:50 -
@@ -47,15 +47,14 @@ static int map_address (CPUState *env, t
 for (i = 0; i  env-tlb_in_use; i++) {
 tlb_t *tlb = env-tlb[i];
 /* 1k pages are not supported. */
-target_ulong mask = tlb-PageMask | 0x1FFF;
+target_ulong mask = tlb-PageMask | ~(TARGET_PAGE_MASK  1);
 target_ulong tag = address  ~mask;
-int n;
+target_ulong VPN = tlb-VPN  ~mask;
 
 /* Check ASID, virtual page number  size */
-if ((tlb-G == 1 || tlb-ASID == ASID) 
-tlb-VPN == tag) {
+if ((tlb-G == 1 || tlb-ASID == ASID)  VPN == tag) {
 /* TLB match */
-n = !!(address  mask  ~(mask  1));
+int n = !!(address  mask  ~(mask  1));
 /* Check access rights */
if (!(n ? tlb-V1 : tlb-V0))
 return TLBRET_INVALID;
@@ -492,7 +491,7 @@ void invalidate_tlb (CPUState *env, int 
 target_ulong mask;
 
 tlb = env-tlb[idx];
-/* The qemu TLB is flushed then the ASID changes, so no need to
+/* The qemu TLB is flushed when the ASID changes, so no need to
flush these entries again.  */
 if (tlb-G == 0  tlb-ASID != ASID) {
 return;
@@ -508,9 +507,9 @@ void invalidate_tlb (CPUState *env, int 
 }
 
 /* 1k pages are not supported. */
-mask = tlb-PageMask | 0x1FFF;
+mask = tlb-PageMask | ~(TARGET_PAGE_MASK  1);
 if (tlb-V0) {
-addr = tlb-VPN;
+addr = tlb-VPN  ~mask;
 end = addr | (mask  1);
 while (addr  end) {
 tlb_flush_page (env, addr);
@@ -518,8 +517,7 @@ void invalidate_tlb (CPUState *env, int 
 }
 }
 if (tlb-V1) {
-addr = tlb-VPN | ((mask  1) + 1);
-addr = tlb-VPN + TARGET_PAGE_SIZE;
+addr = (tlb-VPN  ~mask) | ((mask  1) + 1);
 end = addr | mask;
 while (addr  end) {
 tlb_flush_page (env, addr);
Index: target-mips/op.c
===
RCS file: /sources/qemu/qemu/target-mips/op.c,v
retrieving revision 1.49
diff -u -d -p -r1.49 op.c
--- target-mips/op.c11 May 2007 17:08:26 -  1.49
+++ target-mips/op.c12 May 2007 13:46:50 -
@@ -1283,7 +1283,7 @@ void op_mtc0_context (void)
 void op_mtc0_pagemask (void)
 {
 /* 1k pages not implemented */
-env-CP0_PageMask = T0  0x1FFFE000;
+env-CP0_PageMask = T0  (0x1FFF  (TARGET_PAGE_MASK  1));
 RETURN();
 }
 
Index: target-mips/op_helper.c
===
RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v
retrieving revision 1.42
diff -u -d -p -r1.42 op_helper.c
--- target-mips/op_helper.c 17 Apr 2007 15:26:47 -  1.42
+++ target-mips/op_helper.c 12 May 2007 13:46:50 -
@@ -411,7 +411,7 @@ static void fill_tlb (int idx)
 
 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
 tlb = env-tlb[idx];
-tlb-VPN = env-CP0_EntryHi  ~(target_ulong)0x1FFF;
+tlb-VPN = env-CP0_EntryHi  (TARGET_PAGE_MASK  1);
 tlb-ASID = env-CP0_EntryHi  0xFF;
 tlb-PageMask = env-CP0_PageMask;
 tlb-G = env-CP0_EntryLo0  env-CP0_EntryLo1  1;
@@ -447,16 +447,18 @@ void do_tlbwr (void)
 void do_tlbp (void)
 {
 tlb_t *tlb;
-target_ulong tag;
 uint8_t ASID;
 int i;
 
-tag = env-CP0_EntryHi  (int32_t)0xE000;
 ASID = env-CP0_EntryHi  0xFF;
 for (i = 0; i  env-nb_tlb; i++) {
 tlb = env-tlb[i];
+/* 1k pages are not supported. */
+target_ulong mask = tlb-PageMask | ~(TARGET_PAGE_MASK  1);
+target_ulong tag = env-CP0_EntryHi  ~mask;
+target_ulong VPN = tlb-VPN  ~mask;
 /* Check ASID, virtual page number  size */
-if ((tlb-G == 1 || tlb-ASID == ASID)  tlb-VPN == tag) {
+if ((tlb-G == 1 || tlb-ASID == ASID)  VPN == tag) {
 /* TLB match */
 env-CP0_Index = i;
 break;
@@ -467,8 +469,12 @@ void do_tlbp (void)
 for (i = env-nb_tlb; i  env-tlb_in_use; i++) {
tlb = env-tlb[i];
 

[Qemu-devel] [MIPS][PATCH] Fix mfc0 and dmtc0 instructions on MIPS64

2007-05-12 Thread Aurelien Jarno

Hi all,

The patch below fixes the mfc0 and dmtc0 instructions for the 
MIPS64 target:

- The mfc0 instruction should return the 32 lowest bits of the 
  coprocessor 0 register sign extended to 64-bit.
- The mtc0 instruction should do the same as the dmtc0 instruction for 
  64-bit coprocessor registers instead of copying only the low 32 bits.
- The XContest register does not exists on MIPS32 CPU.

Note that this patch does not fix the mfc0 and dmtc0 instructions 
for the EntryHi coprocessor 0 register, as it would break the MIPS64
target. I will send the fix in a later patch.

Bye,
Aurelien


--- target-mips/cpu.h   7 May 2007 13:55:33 -   1.31
+++ target-mips/cpu.h   12 May 2007 00:40:00 -
@@ -212,7 +212,9 @@ struct CPUMIPSState {
 target_ulong CP0_LLAddr;
 target_ulong CP0_WatchLo;
 int32_t CP0_WatchHi;
+#ifdef TARGET_MIPS64
 target_ulong CP0_XContext;
+#endif
 int32_t CP0_Framemask;
 int32_t CP0_Debug;
 #define CPDB_DBD   31
--- target-mips/op.c11 May 2007 17:08:26 -  1.49
+++ target-mips/op.c12 May 2007 00:40:01 -
@@ -1006,7 +1006,7 @@ void op_jnz_T2 (void)
 /* CP0 functions */
 void op_mfc0_index (void)
 {
-T0 = env-CP0_Index;
+T0 = (int32_t)env-CP0_Index;
 RETURN();
 }
 
@@ -1036,25 +1036,25 @@ void op_mfc0_context (void)
 
 void op_mfc0_pagemask (void)
 {
-T0 = env-CP0_PageMask;
+T0 = (int32_t)env-CP0_PageMask;
 RETURN();
 }
 
 void op_mfc0_pagegrain (void)
 {
-T0 = env-CP0_PageGrain;
+T0 = (int32_t)env-CP0_PageGrain;
 RETURN();
 }
 
 void op_mfc0_wired (void)
 {
-T0 = env-CP0_Wired;
+T0 = (int32_t)env-CP0_Wired;
 RETURN();
 }
 
 void op_mfc0_hwrena (void)
 {
-T0 = env-CP0_HWREna;
+T0 = (int32_t)env-CP0_HWREna;
 RETURN();
 }
 
@@ -1078,37 +1078,37 @@ void op_mfc0_entryhi (void)
 
 void op_mfc0_compare (void)
 {
-T0 = env-CP0_Compare;
+T0 = (int32_t)env-CP0_Compare;
 RETURN();
 }
 
 void op_mfc0_status (void)
 {
-T0 = env-CP0_Status;
+T0 = (int32_t)env-CP0_Status;
 RETURN();
 }
 
 void op_mfc0_intctl (void)
 {
-T0 = env-CP0_IntCtl;
+T0 = (int32_t)env-CP0_IntCtl;
 RETURN();
 }
 
 void op_mfc0_srsctl (void)
 {
-T0 = env-CP0_SRSCtl;
+T0 = (int32_t)env-CP0_SRSCtl;
 RETURN();
 }
 
 void op_mfc0_srsmap (void)
 {
-T0 = env-CP0_SRSMap;
+T0 = (int32_t)env-CP0_SRSMap;
 RETURN();
 }
 
 void op_mfc0_cause (void)
 {
-T0 = env-CP0_Cause;
+T0 = (int32_t)env-CP0_Cause;
 RETURN();
 }
 
@@ -1120,55 +1120,55 @@ void op_mfc0_epc (void)
 
 void op_mfc0_prid (void)
 {
-T0 = env-CP0_PRid;
+T0 = (int32_t)env-CP0_PRid;
 RETURN();
 }
 
 void op_mfc0_ebase (void)
 {
-T0 = env-CP0_EBase;
+T0 = (int32_t)env-CP0_EBase;
 RETURN();
 }
 
 void op_mfc0_config0 (void)
 {
-T0 = env-CP0_Config0;
+T0 = (int32_t)env-CP0_Config0;
 RETURN();
 }
 
 void op_mfc0_config1 (void)
 {
-T0 = env-CP0_Config1;
+T0 = (int32_t)env-CP0_Config1;
 RETURN();
 }
 
 void op_mfc0_config2 (void)
 {
-T0 = env-CP0_Config2;
+T0 = (int32_t)env-CP0_Config2;
 RETURN();
 }
 
 void op_mfc0_config3 (void)
 {
-T0 = env-CP0_Config3;
+T0 = (int32_t)env-CP0_Config3;
 RETURN();
 }
 
 void op_mfc0_config6 (void)
 {
-T0 = env-CP0_Config6;
+T0 = (int32_t)env-CP0_Config6;
 RETURN();
 }
 
 void op_mfc0_config7 (void)
 {
-T0 = env-CP0_Config7;
+T0 = (int32_t)env-CP0_Config7;
 RETURN();
 }
 
 void op_mfc0_lladdr (void)
 {
-T0 = (int32_t)env-CP0_LLAddr  4;
+T0 = (int32_t)(env-CP0_LLAddr  4);
 RETURN();
 }
 
@@ -1180,25 +1180,19 @@ void op_mfc0_watchlo0 (void)
 
 void op_mfc0_watchhi0 (void)
 {
-T0 = env-CP0_WatchHi;
-RETURN();
-}
-
-void op_mfc0_xcontext (void)
-{
-T0 = (int32_t)env-CP0_XContext;
+T0 = (int32_t)env-CP0_WatchHi;
 RETURN();
 }
 
 void op_mfc0_framemask (void)
 {
-T0 = env-CP0_Framemask;
+T0 = (int32_t)env-CP0_Framemask;
 RETURN();
 }
 
 void op_mfc0_debug (void)
 {
-T0 = env-CP0_Debug;
+T0 = (int32_t)env-CP0_Debug;
 if (env-hflags  MIPS_HFLAG_DM)
 T0 |= 1  CP0DB_DM;
 RETURN();
@@ -1212,31 +1206,31 @@ void op_mfc0_depc (void)
 
 void op_mfc0_performance0 (void)
 {
-T0 = env-CP0_Performance0;
+T0 = (int32_t)env-CP0_Performance0;
 RETURN();
 }
 
 void op_mfc0_taglo (void)
 {
-T0 = env-CP0_TagLo;
+T0 = (int32_t)env-CP0_TagLo;
 RETURN();
 }
 
 void op_mfc0_datalo (void)
 {
-T0 = env-CP0_DataLo;
+T0 = (int32_t)env-CP0_DataLo;
 RETURN();
 }
 
 void op_mfc0_taghi (void)
 {
-T0 = env-CP0_TagHi;
+T0 = (int32_t)env-CP0_TagHi;
 RETURN();
 }
 
 void op_mfc0_datahi (void)
 {
-T0 = env-CP0_DataHi;
+T0 = (int32_t)env-CP0_DataHi;
 RETURN();
 }
 
@@ -1248,7 +1242,7 @@ void op_mfc0_errorepc (void)
 
 void op_mfc0_desave (void)
 {
-T0 = env-CP0_DESAVE;
+T0 = (int32_t)env-CP0_DESAVE;
 RETURN();
 }
 
@@ -1262,7 +1256,7 @@ void op_mtc0_entrylo0 (void)
 {
 /* Large 

[Qemu-devel] [PATCH][MIPS] Full MIPS64 MMU implementation

2007-05-12 Thread Aurelien Jarno
Hi all,

The patch below finally adds full support for MIPS64 MMU. With it I am
able to boot a 64-bit MALTA kernel up to a kernel panic, as it does not
detect any devices. There is probably a bug somewhere in map_address().

Note that the long hardcoded masks are a bit ugly, but I am working on
a patch to add a per-CPU SEGBITS value.

Cheers,
Aurelien


diff -u target-mips/helper.c target-mips/helper.c
--- target-mips/helper.c12 May 2007 13:49:53 -
+++ target-mips/helper.c12 May 2007 13:53:39 -
@@ -50,6 +50,9 @@
 target_ulong mask = tlb-PageMask | ~(TARGET_PAGE_MASK  1);
 target_ulong tag = address  ~mask;
 target_ulong VPN = tlb-VPN  ~mask;
+#ifdef TARGET_MIPS64
+tag = 0xC0FFULL;
+#endif
 
 /* Check ASID, virtual page number  size */
 if ((tlb-G == 1 || tlb-ASID == ASID)  VPN == tag) {
@@ -285,10 +288,16 @@
 }
 /* Raise exception */
 env-CP0_BadVAddr = address;
-env-CP0_Context = (env-CP0_Context  0xff80) |
+env-CP0_Context = (env-CP0_Context  ~0x007f) |
   ((address  9)0x0070);
 env-CP0_EntryHi =
 (env-CP0_EntryHi  0xFF) | (address  (TARGET_PAGE_MASK  1));
+#ifdef TARGET_MIPS64
+env-CP0_EntryHi = 0xc0ffULL;
+env-CP0_XContext = (env-CP0_XContext  0xfffeULL) |
+((address  31)  0x00018000ULL) |
+((address  9)  0x7ff0ULL);
+#endif
 env-exception_index = exception;
 env-error_code = error_code;
 ret = 1;
@@ -401,8 +410,19 @@
 goto set_EPC;
 case EXCP_TLBL:
 cause = 2;
-if (env-error_code == 1  !(env-CP0_Status  (1  CP0St_EXL)))
-offset = 0x000;
+if (env-error_code == 1  !(env-CP0_Status  (1  CP0St_EXL))) {
+#ifdef TARGET_MIPS64
+int R = env-CP0_BadVAddr  62;
+int UX = (env-CP0_Status  (1  CP0St_UX)) != 0;
+int SX = (env-CP0_Status  (1  CP0St_SX)) != 0;
+int KX = (env-CP0_Status  (1  CP0St_KX)) != 0;
+
+if ((R == 0  UX) || (R == 1  SX) || (R == 3  KX))
+offset = 0x080;
+else
+#endif
+offset = 0x000;
+}
 goto set_EPC;
 case EXCP_IBE:
 cause = 6;
@@ -438,8 +458,19 @@
 goto set_EPC;
 case EXCP_TLBS:
 cause = 3;
-if (env-error_code == 1  !(env-CP0_Status  (1  CP0St_EXL)))
-offset = 0x000;
+if (env-error_code == 1  !(env-CP0_Status  (1  CP0St_EXL))) {
+#ifdef TARGET_MIPS64
+int R = env-CP0_BadVAddr  62;
+int UX = (env-CP0_Status  (1  CP0St_UX)) != 0;
+int SX = (env-CP0_Status  (1  CP0St_SX)) != 0;
+int KX = (env-CP0_Status  (1  CP0St_KX)) != 0;
+
+if ((R == 0  UX) || (R == 1  SX) || (R == 3  KX))
+offset = 0x080;
+else
+#endif
+offset = 0x000;
+}
 set_EPC:
 if (!(env-CP0_Status  (1  CP0St_EXL))) {
 if (env-hflags  MIPS_HFLAG_BMASK) {
@@ -510,6 +541,11 @@
 mask = tlb-PageMask | ~(TARGET_PAGE_MASK  1);
 if (tlb-V0) {
 addr = tlb-VPN  ~mask;
+#ifdef TARGET_MIPS64
+if (addr = 0xC0FF8000ULL) {
+addr |= 0x3F00ULL;
+}
+#endif
 end = addr | (mask  1);
 while (addr  end) {
 tlb_flush_page (env, addr);
@@ -518,6 +554,11 @@
 }
 if (tlb-V1) {
 addr = (tlb-VPN  ~mask) | ((mask  1) + 1);
+#ifdef TARGET_MIPS64
+if (addr = 0xC0FF8000ULL) {
+addr |= 0x3F00ULL;
+}
+#endif
 end = addr | mask;
 while (addr  end) {
 tlb_flush_page (env, addr);
diff -u target-mips/op.c target-mips/op.c
--- target-mips/op.c12 May 2007 13:49:54 -
+++ target-mips/op.c12 May 2007 13:53:39 -
@@ -1313,8 +1313,10 @@
 target_ulong old, val;
 
 /* 1k pages not implemented */
-/* Ignore MIPS64 TLB for now */
-val = (target_ulong)(int32_t)T0  ~(target_ulong)0x1F00;
+val = T0  ((TARGET_PAGE_MASK  1) | 0xFF);
+#ifdef TARGET_MIPS64
+val = T0  0xC0FFULL;
+#endif
 old = env-CP0_EntryHi;
 env-CP0_EntryHi = val;
 /* If the ASID changes, flush qemu's TLB.  */
diff -u target-mips/op_helper.c target-mips/op_helper.c
--- target-mips/op_helper.c 12 May 2007 13:49:54 -
+++ target-mips/op_helper.c 12 May 2007 13:53:39 -
@@ -412,6 +412,9 @@
 /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */
 tlb = env-tlb[idx];
 tlb-VPN = env-CP0_EntryHi  (TARGET_PAGE_MASK  1);
+#ifdef TARGET_MIPS64
+tlb-VPN = env-CP0_EntryHi  0xC0FFULL;
+#endif
 tlb-ASID = env-CP0_EntryHi  0xFF;
 tlb-PageMask = env-CP0_PageMask;
 tlb-G = env-CP0_EntryLo0  env-CP0_EntryLo1  1;

-- 
  .''`.  Aurelien Jarno 

[Qemu-devel] Block driver and constant sector size

2007-05-12 Thread Jonathan Phenix

Hi,

currently the block driver in qemu only handles blocks (or sectors) 
which are 512 bytes long, this is ideal if the device you are emulating 
have a block size which is a multiple of 512. Unfortunately, this is not 
always the case, for example an audio CD (CD-DA) or a CD in mode 2 have 
a sector size of 2352, which is not a multiple of 512. Typical data CD 
are encoded in mode 1 with an ISO9660 file system, and this mode uses a 
sector size of 2048, which is a multiple of 512, this is the reason why 
the problem probably didn't come up yet. You can dump about any CDs in 
mode 2 under Linux with the cdrdao read-cd --read-raw [...] command 
for example.


In order to let the block driver read these raw images, I would like to 
change:


BlockDriverState *bdrv_new(const char *device_name);

to:

BlockDriverState *bdrv_new(const char *device_name, int sector_size);

and change:

int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);

of the BlockDriver structure to:

int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char 
*filename, int sector_size);


Then, each probe functions should be modified to reject sector size 
which is not 512 bytes, except for the raw block driver, which will be 
modified to accept any block sizes. This change would probably solve the 
whole problem without having a negative impact on the rest of the code.


Is it the right way to solve the problem? If this solution is accepted, 
I will code it and submit a patch.


Regards,

Jonathan Phénix





[Qemu-devel] qemu cpu-exec.c

2007-05-12 Thread Thiemo Seufer
CVSROOT:/sources/qemu
Module name:qemu
Changes by: Thiemo Seufer ths 07/05/12 16:57:43

Modified files:
.  : cpu-exec.c 

Log message:
Update debug output.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/cpu-exec.c?cvsroot=qemur1=1.103r2=1.104




[Qemu-devel] Patch: support OSS on solaris

2007-05-12 Thread Ben Taylor

I've recrafted my patch for supporting OpenSound System on Solaris by
checking for it automatically, instead of providing an option.  Also added
a status flag on whether OSS is enabled or not.

Ben--- qemu.ORIG/configure	2007-05-09 10:06:06.0 -0400
+++ qemu/configure	2007-05-12 13:30:31.292001000 -0400
@@ -157,6 +157,9 @@
 kqemu=yes
 fi
 fi
+if test -f /usr/include/sys/soundcard.h ; then
+oss=yes
+fi
 ;;
 *)
 oss=yes
@@ -667,6 +670,7 @@
 fmod_support=
 fi
 echo FMOD support  $fmod $fmod_support
+echo OSS support   $oss
 if test -n $sparc_cpu; then
 echo Target Sparc Arch $sparc_cpu
 fi


[Qemu-devel] I2C/SMBus framework

2007-05-12 Thread Paul Brook
The attached patch implements an I2C/SMBus framework for qemu.

It provides an API for connecting emulated I2C devices, and implements SMBus 
as a layer on top of that.

Currently the only i2c device in CVS is the piix eeprom. I've tested this as 
much as I can - linux successfully reads the eeprom contents.
I've also used the same framework for several different boards.

I will apply in a day or so if there are no serious objections.

Paul

Index: Makefile.target
===
RCS file: /sources/qemu/qemu/Makefile.target,v
retrieving revision 1.169
diff -u -p -r1.169 Makefile.target
--- Makefile.target	8 May 2007 21:05:55 -	1.169
+++ Makefile.target	12 May 2007 17:50:21 -
@@ -401,6 +401,8 @@ SOUND_HW += fmopl.o adlib.o
 endif
 AUDIODRV+= wavcapture.o
 
+VL_OBJS += i2c.o smbus.o
+
 # SCSI layer
 VL_OBJS+= scsi-disk.o cdrom.o lsi53c895a.o
 
Index: vl.h
===
RCS file: /sources/qemu/qemu/vl.h,v
retrieving revision 1.234
diff -u -p -r1.234 vl.h
--- vl.h	9 May 2007 20:25:36 -	1.234
+++ vl.h	12 May 2007 17:50:21 -
@@ -1125,17 +1125,16 @@ int pit_get_out(PITState *pit, int chann
 void pcspk_init(PITState *);
 int pcspk_audio_init(AudioState *, qemu_irq *pic);
 
+#include hw/i2c.h
+
 #include hw/smbus.h
 
 /* acpi.c */
 extern int acpi_enabled;
-void piix4_pm_init(PCIBus *bus, int devfn);
+i2c_bus *piix4_pm_init(PCIBus *bus, int devfn);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 void acpi_bios_init(void);
 
-/* smbus_eeprom.c */
-SMBusDevice *smbus_eeprom_device_init(uint8_t addr, uint8_t *buf);
-
 /* pc.c */
 extern QEMUMachine pc_machine;
 extern QEMUMachine isapc_machine;
Index: hw/acpi.c
===
RCS file: /sources/qemu/qemu/hw/acpi.c,v
retrieving revision 1.10
diff -u -p -r1.10 acpi.c
--- hw/acpi.c	15 Apr 2007 23:54:20 -	1.10
+++ hw/acpi.c	12 May 2007 17:50:21 -
@@ -35,7 +35,7 @@ typedef struct PIIX4PMState {
 uint8_t apms;
 QEMUTimer *tmr_timer;
 int64_t tmr_overflow_time;
-SMBusDevice *smb_dev[128];
+i2c_bus *smbus;
 uint8_t smb_stat;
 uint8_t smb_ctl;
 uint8_t smb_cmd;
@@ -63,9 +63,6 @@ typedef struct PIIX4PMState {
 #define SMBHSTDAT1 0x06
 #define SMBBLKDAT 0x07
 
-/* Note: only used for piix4_smbus_register_device */
-static PIIX4PMState *piix4_pm_state;
-
 static uint32_t get_pmtmr(PIIX4PMState *s)
 {
 uint32_t d;
@@ -258,59 +255,44 @@ static void smb_transaction(PIIX4PMState
 uint8_t read = s-smb_addr  0x01;
 uint8_t cmd = s-smb_cmd;
 uint8_t addr = s-smb_addr  1;
-SMBusDevice *dev = s-smb_dev[addr];
+i2c_bus *bus = s-smbus;
 
 #ifdef DEBUG
 printf(SMBus trans addr=0x%02x prot=0x%02x\n, addr, prot);
 #endif
-if (!dev) goto error;
-
 switch(prot) {
 case 0x0:
-if (!dev-quick_cmd) goto error;
-(*dev-quick_cmd)(dev, read);
+smbus_quick_command(bus, addr, read);
 break;
 case 0x1:
 if (read) {
-if (!dev-receive_byte) goto error;
-s-smb_data0 = (*dev-receive_byte)(dev);
-}
-else {
-if (!dev-send_byte) goto error;
-(*dev-send_byte)(dev, cmd);
+s-smb_data0 = smbus_receive_byte(bus, addr);
+} else {
+smbus_send_byte(bus, addr, cmd);
 }
 break;
 case 0x2:
 if (read) {
-if (!dev-read_byte) goto error;
-s-smb_data0 = (*dev-read_byte)(dev, cmd);
-}
-else {
-if (!dev-write_byte) goto error;
-(*dev-write_byte)(dev, cmd, s-smb_data0);
+s-smb_data0 = smbus_read_byte(bus, addr, cmd);
+} else {
+smbus_write_byte(bus, addr, cmd, s-smb_data0);
 }
 break;
 case 0x3:
 if (read) {
 uint16_t val;
-if (!dev-read_word) goto error;
-val = (*dev-read_word)(dev, cmd);
+smbus_read_word(bus, addr, cmd);
 s-smb_data0 = val;
 s-smb_data1 = val  8;
-}
-else {
-if (!dev-write_word) goto error;
-(*dev-write_word)(dev, cmd, (s-smb_data1  8) | s-smb_data0);
+} else {
+smbus_write_word(bus, addr, cmd, (s-smb_data1  8) | s-smb_data0);
 }
 break;
 case 0x5:
 if (read) {
-if (!dev-read_block) goto error;
-s-smb_data0 = (*dev-read_block)(dev, cmd, s-smb_data);
-}
-else {
-if (!dev-write_block) goto error;
-(*dev-write_block)(dev, cmd, s-smb_data0, s-smb_data);
+s-smb_data0 = smbus_read_block(bus, addr, cmd, s-smb_data);
+} else {
+smbus_write_block(bus, addr, cmd, s-smb_data, s-smb_data0);
 }
 break;
 default:
@@ -469,7 +451,7 @@ static int pm_load(QEMUFile* f,void* opa
 return 0;
 }