qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Re: [RFC] [PATCH] add ahci support into qemu


From: 乔崇
Subject: Re: [Qemu-devel] Re: [RFC] [PATCH] add ahci support into qemu
Date: Tue, 04 May 2010 09:07:36 +0800
User-agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090706)

I add Sebastian Herbsz's patch,add WIN_WIN_STANDBYNOW1 support to fix hw_error on linux shut down etc.

I am  not familiar with  git send-email,I am studying it now :).


Sebastian Herbszt 写道:
Hi again,

please consider the following minor changes:
- debug output with DEBUG_AHCI
- set port count to 4
- change return value of PxSSTS to include SPD and IPM
- change cap and version default values according to Intel #301473-002

Regards,
Sebastian

--- hw/ahci.c.orig Sun May  2 15:43:58 2010
+++ hw/ahci.c Sun May  2 22:03:26 2010
@@ -26,8 +26,15 @@
#include "dma.h"
#include "cpu-common.h"
#include <hw/ide/internal.h>
-#define DPRINTF(...)

+#define DEBUG_AHCI
+
+#ifdef DEBUG_AHCI
+#define DPRINTF(fmt, ...) \
+do { printf("ahci: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while(0)
+#endif

enum {
 AHCI_PCI_BAR  = 5,
@@ -203,6 +210,8 @@
 uint32_t  version;
} ahci_control_regs;

+#define SATA_PORTS 4
+
typedef struct ahci_port_regs {
 uint32_t lst_addr;
 uint32_t lst_addr_hi;
@@ -240,7 +249,7 @@

typedef struct AHCIState{
 ahci_control_regs control_regs;
- ahci_port_regs port_regs[2];
+ ahci_port_regs port_regs[SATA_PORTS];
 int mem;
 QEMUTimer *timer;
 IDEBus *ide;
@@ -268,8 +277,10 @@
 switch(offset)
 {
  case PORT_SCR:
-   if(s->ide && port==0) val=3;
-   else val=0;
+   if(s->ide && port==0)
+    val= 3 /* DET */ | (1 << 4) /* SPD */ | (1 << 8) /* IPM */;
+   else
+    val=0;
   break;
  case PORT_IRQ_STAT:
   val=pr->irq_stat;
@@ -291,6 +302,7 @@
   val= p[offset>>2];
   break;
 }
+ DPRINTF("ahci_port_read: port: 0x%x offset: 0x%x val: 0x%x\n", port, offset, val);
 return val;

}
@@ -299,7 +311,7 @@
{
 ahci_port_regs *pr;
 int i;
- for(i=0;i<2;i++)
+ for(i=0;i<SATA_PORTS;i++)
 {
  pr=&s->port_regs[i];

@@ -319,6 +331,7 @@
 ahci_port_regs *pr=&s->port_regs[port];
 uint32_t *p;

+ DPRINTF("ahci_port_write: port: 0x%x offset: 0x%x val: 0x%x\n", port, offset, val);
 switch(offset)
 {
  case PORT_LST_ADDR:
@@ -396,7 +409,7 @@
    val=p[addr>>2];
  }
 }
- else if(addr>=0x100 && addr<0x200)
+ else if(addr>=0x100 && addr<0x300)
 {
  val=ahci_port_read(s,(addr-0x100)>>7,addr&0x7f);
 }
@@ -436,7 +449,7 @@
    p=(uint32_t *)&s->control_regs;
  }
 }
- else if(addr>=0x100 && addr<0x200)
+ else if(addr>=0x100 && addr<0x300)
 {
  ahci_port_write(s,(addr-0x100)>>7,addr&0x7f,val);
 }
@@ -459,10 +472,10 @@

static void ahci_reg_init(AHCIState *s)
{
- s->control_regs.cap=2|(0x1f<<8); /*2 ports,32 cmd slot*/
- s->control_regs.ghc=1<<31;
- s->control_regs.impl=1;/*2 ports*/
- s->control_regs.version=0x10100;
+ s->control_regs.cap = 3 | (0x1f << 8) | (1 << 20) ; /* 4 ports, 32 command slots, 1.5 Gb/s */
+ s->control_regs.ghc = 1 << 31; /* AHCI Enable */
+ s->control_regs.impl = 1; /* Port 0 implemented */
+ s->control_regs.version = 0x10000;
}

static void padstr(char *str, const char *src, int len)
@@ -619,19 +632,22 @@
 prdt_num=cmd_hdr.opts>>16;
if(prdt_num) cpu_physical_memory_read(cmd_hdr.tbl_addr+0x80,(uint8_t *)s->prdt_buf,prdt_num*32);

-
+#ifdef DEBUG_AHCI
+        DPRINTF("fis:");
 for(i=0;i<cmd_len;i++)
 {
-  if((i&0xf)==0)DPRINTF("\n%02x:",i);
-  DPRINTF("%02x ",fis[i]);
+  if((i&0xf)==0) printf("\n%02x:",i);
+  printf("%02x ",fis[i]);
 }
+        printf("\n");
+#endif

 switch(fis[0])
 {
  case 0x27:
   break;
  default:
- hw_error("unkonow command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break; + hw_error("unknown command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
 }

 switch(fis[1])
@@ -641,7 +657,7 @@
  case 0:
   break;
  default:
- hw_error("unkonow command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break; + hw_error("unknown command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
 }

 if(fis[1]==0)
@@ -684,7 +700,7 @@
    pr->irq_stat |= (1<<2);
    break;
   default:
- hw_error("unkonow command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break; + hw_error("unknown command fis[0]=%02x fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
  }

 }
@@ -698,7 +714,7 @@
 AHCIState *s = opaque;
 ahci_port_regs *pr;
 int i,j;
- for(i=0;i<2;i++)
+ for(i=0;i<SATA_PORTS;i++)
 {
  pr=&s->port_regs[i];
  for(j=0;j<32 && pr->cmd_issue;j++)
@@ -741,23 +757,21 @@
#define PCI_VENDOR_MYDEVICE  0x8086
#define PCI_PRODUCT_MYDEVICE 0x2652

-#define PCI_CLASS_HEADERTYPE_00h 0x00
-
static int pci_ahci_init(PCIDevice *dev)
{
 struct ahci_pci_state *d;
 d = DO_UPCAST(struct ahci_pci_state, card, dev);
 pci_config_set_vendor_id(d->card.config,PCI_VENDOR_MYDEVICE);
 pci_config_set_device_id(d->card.config,PCI_PRODUCT_MYDEVICE);
- d->card.config[PCI_COMMAND]  = 0x07;  /* I/O + Memory */
+ d->card.config[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
 d->card.config[PCI_CLASS_DEVICE] = 0;
 d->card.config[0x0b]  = 1;//storage
- d->card.config[0x0c]  = 0x08;  /* Cache line size */
- d->card.config[0x0d]  = 0x40;  /* Latency timer */
- d->card.config[0x0e]  = PCI_CLASS_HEADERTYPE_00h;
- d->card.config[0x3d] = 1;    /* interrupt pin 0 */
+ d->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
+ d->card.config[PCI_LATENCY_TIMER] = 0x00; /* Latency timer */
+ d->card.config[PCI_HEADER_TYPE]  = PCI_HEADER_TYPE_NORMAL;
+ d->card.config[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */

- pci_register_bar(&d->card, 5, 0x200,
+ pci_register_bar(&d->card, 5, 0x400,
   PCI_BASE_ADDRESS_SPACE_MEMORY, ahci_pci_map);
 d->ahci=ahci_new();
 d->ahci->irq = d->card.irq[0];
@@ -792,7 +806,7 @@
{
    ahci_sysbus_state *d = FROM_SYSBUS(ahci_sysbus_state, dev);
 d->ahci=ahci_new();
-    sysbus_init_mmio(dev, 0x200, d->ahci->mem);
+    sysbus_init_mmio(dev, 0x400, d->ahci->mem);
    sysbus_init_irq(dev, &d->ahci->irq);
    return 0;
}


--

乔崇 qiaochong.ac.cn
龙芯技术服务中心
office:010-62600855-108
mobile:13521990614

2009年 11月 16日 星期一 10:31:04 CST
>From 30cc6d82d4b3ad71672801f6126934a84ec39925 Mon Sep 17 00:00:00 2001
From: Sebastian Herbszt <address@hidden>
Date: Tue, 4 May 2010 07:17:47 +0800
Subject: [PATCH] fix port count,cap and version etc to ahci.

- debug output with DEBUG_AHCI
- set port count to 4
- change return value of PxSSTS to include SPD and IPM
- change cap and version default values according to Intel #301473-002

Signed-off-by: QiaoChong <address@hidden>
---
 hw/ahci.c |   68 ++++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/hw/ahci.c b/hw/ahci.c
index a332a45..b6a81af 100644
--- a/hw/ahci.c
+++ b/hw/ahci.c
@@ -26,8 +26,15 @@
 #include "dma.h"
 #include "cpu-common.h"
 #include <hw/ide/internal.h>
-#define DPRINTF(...)
 
+#define DEBUG_AHCI
+
+#ifdef DEBUG_AHCI
+#define DPRINTF(fmt, ...) \
+do { printf("ahci: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while(0)
+#endif
 
 enum {
        AHCI_PCI_BAR            = 5,
@@ -203,6 +210,8 @@ typedef struct ahci_control_regs {
        uint32_t  version;
 } ahci_control_regs;
 
+#define SATA_PORTS 4
+
 typedef struct ahci_port_regs {
        uint32_t lst_addr;
        uint32_t lst_addr_hi;
@@ -240,7 +249,7 @@ typedef struct ahci_sg {
 
 typedef struct AHCIState{
        ahci_control_regs control_regs;
-       ahci_port_regs port_regs[2];
+       ahci_port_regs port_regs[SATA_PORTS];
        int mem;
        QEMUTimer *timer;
        IDEBus *ide;
@@ -268,8 +277,10 @@ static uint32_t  ahci_port_read(AHCIState *s,int port,int 
offset)
        switch(offset)
        {
                case PORT_SCR:
-                       if(s->ide && port==0) val=3;
-                       else val=0;
+                       if(s->ide && port==0)
+                               val= 3 /* DET */ | (1 << 4) /* SPD */ | (1 << 
8) /* IPM */;
+                       else
+                               val=0;
                        break;
                case PORT_IRQ_STAT:
                        val=pr->irq_stat;
@@ -291,6 +302,7 @@ static uint32_t  ahci_port_read(AHCIState *s,int port,int 
offset)
                        val= p[offset>>2];
                        break;
        }
+       DPRINTF("ahci_port_read: port: 0x%x offset: 0x%x val: 0x%x\n", port, 
offset, val);
        return val;
 
 }
@@ -299,7 +311,7 @@ static void ahci_check_irq(AHCIState *s)
 {
        ahci_port_regs *pr;
        int i;
-       for(i=0;i<2;i++)
+       for(i=0;i<SATA_PORTS;i++)
        {
                pr=&s->port_regs[i];
 
@@ -319,6 +331,7 @@ static void  ahci_port_write(AHCIState *s,int port,int 
offset,uint32_t val)
        ahci_port_regs *pr=&s->port_regs[port];
        uint32_t *p;
 
+       DPRINTF("ahci_port_write: port: 0x%x offset: 0x%x val: 0x%x\n", port, 
offset, val);
        switch(offset)
        {
                case PORT_LST_ADDR:
@@ -396,7 +409,7 @@ static uint32_t ahci_mem_readl(void *ptr, 
target_phys_addr_t addr)
                                val=p[addr>>2];
                }
        }
-       else if(addr>=0x100 && addr<0x200)
+       else if(addr>=0x100 && addr<0x300)
        {
                val=ahci_port_read(s,(addr-0x100)>>7,addr&0x7f);
        }
@@ -436,7 +449,7 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t 
addr, uint32_t val)
                                p=(uint32_t *)&s->control_regs;
                }
        }
-       else if(addr>=0x100 && addr<0x200)
+       else if(addr>=0x100 && addr<0x300)
        {
                ahci_port_write(s,(addr-0x100)>>7,addr&0x7f,val);
        }
@@ -459,10 +472,10 @@ static CPUWriteMemoryFunc *ahci_writefn[3]={
 
 static void ahci_reg_init(AHCIState *s)
 {
-       s->control_regs.cap=2|(0x1f<<8); /*2 ports,32 cmd slot*/
-       s->control_regs.ghc=1<<31;
-       s->control_regs.impl=1;/*2 ports*/
-       s->control_regs.version=0x10100;
+       s->control_regs.cap = 3 | (0x1f << 8) | (1 << 20) ; /* 4 ports, 32 
command slots, 1.5 Gb/s */
+       s->control_regs.ghc = 1 << 31; /* AHCI Enable */
+       s->control_regs.impl = 1; /* Port 0 implemented */
+       s->control_regs.version = 0x10000;
 }
 
 static void padstr(char *str, const char *src, int len)
@@ -619,19 +632,22 @@ static void handle_cmd(AHCIState *s,int port,int slot)
        prdt_num=cmd_hdr.opts>>16;
        if(prdt_num) cpu_physical_memory_read(cmd_hdr.tbl_addr+0x80,(uint8_t 
*)s->prdt_buf,prdt_num*32);
 
-
+#ifdef DEBUG_AHCI
+        DPRINTF("fis:");
        for(i=0;i<cmd_len;i++)
        {
-               if((i&0xf)==0)DPRINTF("\n%02x:",i);
-               DPRINTF("%02x ",fis[i]);
+               if((i&0xf)==0) printf("\n%02x:",i);
+               printf("%02x ",fis[i]);
        }
+        printf("\n");
+#endif
 
        switch(fis[0])
        {
                case 0x27:
                        break;
                default:
-                       hw_error("unkonow command fis[0]=%02x fis[1]=%02x 
fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
+                       hw_error("unknown command fis[0]=%02x fis[1]=%02x 
fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
        }
 
        switch(fis[1])
@@ -641,7 +657,7 @@ static void handle_cmd(AHCIState *s,int port,int slot)
                case 0:
                        break;
                default:
-                       hw_error("unkonow command fis[0]=%02x fis[1]=%02x 
fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
+                       hw_error("unknown command fis[0]=%02x fis[1]=%02x 
fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
        }
 
        if(fis[1]==0)
@@ -684,7 +700,7 @@ static void handle_cmd(AHCIState *s,int port,int slot)
                                pr->irq_stat |= (1<<2);
                                break;
                        default:
-                               hw_error("unkonow command fis[0]=%02x 
fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
+                               hw_error("unknown command fis[0]=%02x 
fis[1]=%02x fis[2]=%02x\n",fis[0],fis[1],fis[2]);break;
                }
 
        }
@@ -698,7 +714,7 @@ static void ahci_timer_function(void *opaque)
        AHCIState *s = opaque;
        ahci_port_regs *pr;
        int i,j;
-       for(i=0;i<2;i++)
+       for(i=0;i<SATA_PORTS;i++)
        {
                pr=&s->port_regs[i];
                for(j=0;j<32 && pr->cmd_issue;j++)
@@ -741,23 +757,21 @@ static void ahci_pci_map(PCIDevice *pci_dev, int 
region_num,
 #define PCI_VENDOR_MYDEVICE  0x8086
 #define PCI_PRODUCT_MYDEVICE 0x2652
 
-#define PCI_CLASS_HEADERTYPE_00h       0x00
-
 static int pci_ahci_init(PCIDevice *dev)
 {
        struct ahci_pci_state *d;
        d = DO_UPCAST(struct ahci_pci_state, card, dev);
        pci_config_set_vendor_id(d->card.config,PCI_VENDOR_MYDEVICE);
        pci_config_set_device_id(d->card.config,PCI_PRODUCT_MYDEVICE);
-       d->card.config[PCI_COMMAND]             = 0x07;         /* I/O + Memory 
*/
+       d->card.config[PCI_COMMAND]             = PCI_COMMAND_IO | 
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
        d->card.config[PCI_CLASS_DEVICE]        = 0;
        d->card.config[0x0b]            = 1;//storage
-       d->card.config[0x0c]            = 0x08;         /* Cache line size */
-       d->card.config[0x0d]            = 0x40;         /* Latency timer */
-       d->card.config[0x0e]            = PCI_CLASS_HEADERTYPE_00h;
-       d->card.config[0x3d] = 1;    /* interrupt pin 0 */
+       d->card.config[PCI_CACHE_LINE_SIZE]     = 0x08; /* Cache line size */
+       d->card.config[PCI_LATENCY_TIMER]       = 0x00; /* Latency timer */
+       d->card.config[PCI_HEADER_TYPE]         = PCI_HEADER_TYPE_NORMAL;
+       d->card.config[PCI_INTERRUPT_PIN]       = 1; /* interrupt pin 0 */
 
-       pci_register_bar(&d->card, 5, 0x200,
+       pci_register_bar(&d->card, 5, 0x400,
                        PCI_BASE_ADDRESS_SPACE_MEMORY, ahci_pci_map);
        d->ahci=ahci_new();
        d->ahci->irq = d->card.irq[0];
@@ -792,7 +806,7 @@ static int ahci_sysbus_init(SysBusDevice *dev)
 {
     ahci_sysbus_state *d = FROM_SYSBUS(ahci_sysbus_state, dev);
        d->ahci=ahci_new();
-    sysbus_init_mmio(dev, 0x200, d->ahci->mem);
+    sysbus_init_mmio(dev, 0x400, d->ahci->mem);
     sysbus_init_irq(dev, &d->ahci->irq);
     return 0;
 }
-- 
1.5.6.5

>From c07ddd1f9c9ec664a0ef3ee4ad43d930045c9ff7 Mon Sep 17 00:00:00 2001
From: QiaoChong <address@hidden>
Date: Sun, 2 May 2010 21:54:14 +0800
Subject: [PATCH] add  WIN_STANDBYNOW1 process into ahci.

Signed-off-by: QiaoChong <address@hidden>
---
 hw/ahci.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/hw/ahci.c b/hw/ahci.c
index b6a81af..cb4a851 100644
--- a/hw/ahci.c
+++ b/hw/ahci.c
@@ -676,6 +676,7 @@ static void handle_cmd(AHCIState *s,int port,int slot)
                                write_to_sglist(ide_state->identify_data, 
sizeof(ide_state->identify_data),s->prdt_buf,prdt_num);
                                pr->irq_stat |= (1<<2);
                                break;
+                       case WIN_STANDBYNOW1:
                        case WIN_SETFEATURES:
                                pr->irq_stat |= (1<<2);
                                break;
-- 
1.5.6.5

>From e94912b03ed33080d550eb5764fc99911498101b Mon Sep 17 00:00:00 2001
From: QiaoChong <address@hidden>
Date: Tue, 4 May 2010 07:31:30 +0800
Subject: [PATCH] ahci pci ids  into pci_ids.h,add warning messages.

move ahci pci device id define into pci_ids.h,add warning messages for
unsupported features.

Signed-off-by: QiaoChong <address@hidden>
---
 hw/ahci.c    |   10 +++++-----
 hw/pci_ids.h |    1 +
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/hw/ahci.c b/hw/ahci.c
index cb4a851..e1aed4a 100644
--- a/hw/ahci.c
+++ b/hw/ahci.c
@@ -662,7 +662,9 @@ static void handle_cmd(AHCIState *s,int port,int slot)
 
        if(fis[1]==0)
        {
-
+#ifdef DEBUG_AHCI
+                       printf("now,just ignore command fis[0]=%02x fis[1]=%02x 
fis[2]=%02x\n",fis[0],fis[1],fis[2]);
+#endif
        }
 
        if(fis[1]==(1<<7))
@@ -755,15 +757,13 @@ static void ahci_pci_map(PCIDevice *pci_dev, int 
region_num,
        cpu_register_physical_memory(addr, size, s->mem);
 }
 
-#define PCI_VENDOR_MYDEVICE  0x8086
-#define PCI_PRODUCT_MYDEVICE 0x2652
 
 static int pci_ahci_init(PCIDevice *dev)
 {
        struct ahci_pci_state *d;
        d = DO_UPCAST(struct ahci_pci_state, card, dev);
-       pci_config_set_vendor_id(d->card.config,PCI_VENDOR_MYDEVICE);
-       pci_config_set_device_id(d->card.config,PCI_PRODUCT_MYDEVICE);
+       pci_config_set_vendor_id(d->card.config,PCI_VENDOR_ID_INTEL);
+       pci_config_set_device_id(d->card.config,PCI_DEVICE_ID_INTEL_ICH6R_AHCI);
        d->card.config[PCI_COMMAND]             = PCI_COMMAND_IO | 
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
        d->card.config[PCI_CLASS_DEVICE]        = 0;
        d->card.config[0x0b]            = 1;//storage
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index fe7a121..4d4de93 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -97,3 +97,4 @@
 #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
 #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
 #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
+#define PCI_DEVICE_ID_INTEL_ICH6R_AHCI    0x2652
-- 
1.5.6.5


reply via email to

[Prev in Thread] Current Thread [Next in Thread]