From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O8hRQ-0004BZ-SH for qemu-devel@nongnu.org; Sun, 02 May 2010 18:15:12 -0400 Received: from [140.186.70.92] (port=37536 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O8hRP-0004Ao-2L for qemu-devel@nongnu.org; Sun, 02 May 2010 18:15:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O8hRN-0007Hk-3u for qemu-devel@nongnu.org; Sun, 02 May 2010 18:15:10 -0400 Received: from mail.gmx.net ([213.165.64.20]:55161) by eggs.gnu.org with smtp (Exim 4.69) (envelope-from ) id 1O8hRM-0007HZ-K8 for qemu-devel@nongnu.org; Sun, 02 May 2010 18:15:09 -0400 Message-ID: <2FC4BB04CF31478F952129939300295C@FSCPC> From: "Sebastian Herbszt" References: <4BDAD1A3.1040906@loongson.cn><62A72125-4FCF-4B72-82E5-24840460C3D2@suse.de> <4BDD7596.6080207@loongson.cn> In-Reply-To: <4BDD7596.6080207@loongson.cn> Date: Mon, 3 May 2010 00:13:56 +0200 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_009D_01CAEA55.85414F10" Subject: [Qemu-devel] Re: [RFC] [PATCH] add ahci support into qemu List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?utf-8?B?5LmU5bSH?= Cc: Alexander Graf , Joerg Roedel , qemu-devel Developers , Elek Roland This is a multi-part message in MIME format. ------=_NextPart_000_009D_01CAEA55.85414F10 Content-Type: text/plain; format=flowed; charset="utf-8"; reply-type=original Content-Transfer-Encoding: 7bit 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 -#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;iport_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;iirq_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;iport_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; } ------=_NextPart_000_009D_01CAEA55.85414F10 Content-Type: application/octet-stream; name="ahci1.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ahci1.diff" --- hw/ahci.c.orig Sun May 2 15:43:58 2010=0A= +++ hw/ahci.c Sun May 2 22:03:26 2010=0A= @@ -26,8 +26,15 @@=0A= #include "dma.h"=0A= #include "cpu-common.h"=0A= #include =0A= -#define DPRINTF(...)=0A= =0A= +#define DEBUG_AHCI=0A= +=0A= +#ifdef DEBUG_AHCI=0A= +#define DPRINTF(fmt, ...) \=0A= +do { printf("ahci: " fmt , ## __VA_ARGS__); } while (0)=0A= +#else=0A= +#define DPRINTF(fmt, ...) do {} while(0)=0A= +#endif=0A= =0A= enum {=0A= AHCI_PCI_BAR =3D 5,=0A= @@ -203,6 +210,8 @@=0A= uint32_t version;=0A= } ahci_control_regs;=0A= =0A= +#define SATA_PORTS 4=0A= +=0A= typedef struct ahci_port_regs {=0A= uint32_t lst_addr;=0A= uint32_t lst_addr_hi;=0A= @@ -240,7 +249,7 @@=0A= =0A= typedef struct AHCIState{=0A= ahci_control_regs control_regs;=0A= - ahci_port_regs port_regs[2];=0A= + ahci_port_regs port_regs[SATA_PORTS];=0A= int mem;=0A= QEMUTimer *timer;=0A= IDEBus *ide;=0A= @@ -268,8 +277,10 @@=0A= switch(offset)=0A= {=0A= case PORT_SCR:=0A= - if(s->ide && port=3D=3D0) val=3D3;=0A= - else val=3D0;=0A= + if(s->ide && port=3D=3D0)=0A= + val=3D 3 /* DET */ | (1 << 4) /* SPD */ | (1 << 8) /* IPM */;=0A= + else=0A= + val=3D0;=0A= break;=0A= case PORT_IRQ_STAT:=0A= val=3Dpr->irq_stat;=0A= @@ -291,6 +302,7 @@=0A= val=3D p[offset>>2];=0A= break;=0A= }=0A= + DPRINTF("ahci_port_read: port: 0x%x offset: 0x%x val: 0x%x\n", port, = offset, val);=0A= return val;=0A= =0A= }=0A= @@ -299,7 +311,7 @@=0A= {=0A= ahci_port_regs *pr;=0A= int i;=0A= - for(i=3D0;i<2;i++)=0A= + for(i=3D0;iport_regs[i];=0A= =0A= @@ -319,6 +331,7 @@=0A= ahci_port_regs *pr=3D&s->port_regs[port];=0A= uint32_t *p;=0A= =0A= + DPRINTF("ahci_port_write: port: 0x%x offset: 0x%x val: 0x%x\n", port, = offset, val);=0A= switch(offset)=0A= {=0A= case PORT_LST_ADDR:=0A= @@ -396,7 +409,7 @@=0A= val=3Dp[addr>>2];=0A= }=0A= }=0A= - else if(addr>=3D0x100 && addr<0x200)=0A= + else if(addr>=3D0x100 && addr<0x300)=0A= {=0A= val=3Dahci_port_read(s,(addr-0x100)>>7,addr&0x7f);=0A= }=0A= @@ -436,7 +449,7 @@=0A= p=3D(uint32_t *)&s->control_regs;=0A= }=0A= }=0A= - else if(addr>=3D0x100 && addr<0x200)=0A= + else if(addr>=3D0x100 && addr<0x300)=0A= {=0A= ahci_port_write(s,(addr-0x100)>>7,addr&0x7f,val);=0A= }=0A= @@ -459,10 +472,10 @@=0A= =0A= static void ahci_reg_init(AHCIState *s)=0A= {=0A= - s->control_regs.cap=3D2|(0x1f<<8); /*2 ports,32 cmd slot*/=0A= - s->control_regs.ghc=3D1<<31;=0A= - s->control_regs.impl=3D1;/*2 ports*/=0A= - s->control_regs.version=3D0x10100;=0A= + s->control_regs.cap =3D 3 | (0x1f << 8) | (1 << 20) ; /* 4 ports, 32 = command slots, 1.5 Gb/s */=0A= + s->control_regs.ghc =3D 1 << 31; /* AHCI Enable */=0A= + s->control_regs.impl =3D 1; /* Port 0 implemented */=0A= + s->control_regs.version =3D 0x10000;=0A= }=0A= =0A= static void padstr(char *str, const char *src, int len)=0A= @@ -619,19 +632,22 @@=0A= prdt_num=3Dcmd_hdr.opts>>16;=0A= if(prdt_num) cpu_physical_memory_read(cmd_hdr.tbl_addr+0x80,(uint8_t = *)s->prdt_buf,prdt_num*32);=0A= =0A= -=0A= +#ifdef DEBUG_AHCI=0A= + DPRINTF("fis:");=0A= for(i=3D0;iirq_stat |=3D (1<<2);=0A= break;=0A= default:=0A= - hw_error("unkonow command fis[0]=3D%02x fis[1]=3D%02x = fis[2]=3D%02x\n",fis[0],fis[1],fis[2]);break;=0A= + hw_error("unknown command fis[0]=3D%02x fis[1]=3D%02x = fis[2]=3D%02x\n",fis[0],fis[1],fis[2]);break;=0A= }=0A= =0A= }=0A= @@ -698,7 +714,7 @@=0A= AHCIState *s =3D opaque;=0A= ahci_port_regs *pr;=0A= int i,j;=0A= - for(i=3D0;i<2;i++)=0A= + for(i=3D0;iport_regs[i];=0A= for(j=3D0;j<32 && pr->cmd_issue;j++)=0A= @@ -741,23 +757,21 @@=0A= #define PCI_VENDOR_MYDEVICE 0x8086=0A= #define PCI_PRODUCT_MYDEVICE 0x2652=0A= =0A= -#define PCI_CLASS_HEADERTYPE_00h 0x00=0A= -=0A= static int pci_ahci_init(PCIDevice *dev)=0A= {=0A= struct ahci_pci_state *d;=0A= d =3D DO_UPCAST(struct ahci_pci_state, card, dev);=0A= pci_config_set_vendor_id(d->card.config,PCI_VENDOR_MYDEVICE);=0A= pci_config_set_device_id(d->card.config,PCI_PRODUCT_MYDEVICE);=0A= - d->card.config[PCI_COMMAND] =3D 0x07; /* I/O + Memory */=0A= + d->card.config[PCI_COMMAND] =3D PCI_COMMAND_IO | PCI_COMMAND_MEMORY | = PCI_COMMAND_MASTER;=0A= d->card.config[PCI_CLASS_DEVICE] =3D 0;=0A= d->card.config[0x0b] =3D 1;//storage=0A= - d->card.config[0x0c] =3D 0x08; /* Cache line size */=0A= - d->card.config[0x0d] =3D 0x40; /* Latency timer */=0A= - d->card.config[0x0e] =3D PCI_CLASS_HEADERTYPE_00h;=0A= - d->card.config[0x3d] =3D 1; /* interrupt pin 0 */=0A= + d->card.config[PCI_CACHE_LINE_SIZE] =3D 0x08; /* Cache line size */=0A= + d->card.config[PCI_LATENCY_TIMER] =3D 0x00; /* Latency timer */=0A= + d->card.config[PCI_HEADER_TYPE] =3D PCI_HEADER_TYPE_NORMAL;=0A= + d->card.config[PCI_INTERRUPT_PIN] =3D 1; /* interrupt pin 0 */=0A= =0A= - pci_register_bar(&d->card, 5, 0x200,=0A= + pci_register_bar(&d->card, 5, 0x400,=0A= PCI_BASE_ADDRESS_SPACE_MEMORY, ahci_pci_map);=0A= d->ahci=3Dahci_new();=0A= d->ahci->irq =3D d->card.irq[0];=0A= @@ -792,7 +806,7 @@=0A= {=0A= ahci_sysbus_state *d =3D FROM_SYSBUS(ahci_sysbus_state, dev);=0A= d->ahci=3Dahci_new();=0A= - sysbus_init_mmio(dev, 0x200, d->ahci->mem);=0A= + sysbus_init_mmio(dev, 0x400, d->ahci->mem);=0A= sysbus_init_irq(dev, &d->ahci->irq);=0A= return 0;=0A= }=0A= ------=_NextPart_000_009D_01CAEA55.85414F10--