qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Sebastian Herbszt" <herbszt@gmx.de>
To: 乔崇 <qiaochong@loongson.cn>
Cc: Alexander Graf <agraf@suse.de>, Joerg Roedel <joro@8bytes.org>,
	qemu-devel Developers <qemu-devel@nongnu.org>,
	Elek Roland <elek.roland@gmail.com>
Subject: [Qemu-devel] Re: [RFC] [PATCH] add ahci support into qemu
Date: Mon, 3 May 2010 00:13:56 +0200	[thread overview]
Message-ID: <2FC4BB04CF31478F952129939300295C@FSCPC> (raw)
In-Reply-To: <4BDD7596.6080207@loongson.cn>

[-- Attachment #1: Type: text/plain, Size: 5691 bytes --]

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;
 }

[-- Attachment #2: ahci1.diff --]
[-- Type: application/octet-stream, Size: 5636 bytes --]

--- 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;
 }

  parent reply	other threads:[~2010-05-02 22:15 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-30 12:48 [Qemu-devel] add ahci support into qemu 乔崇
2010-05-02  8:05 ` Alexander Graf
2010-05-02 12:52   ` [Qemu-devel] [RFC] [PATCH] " 乔崇
2010-05-02 15:36     ` [Qemu-devel] " Sebastian Herbszt
2010-05-02 15:49       ` Avi Kivity
2010-05-02 15:56       ` Elek Roland
2010-05-03 21:08         ` Elek Roland
2010-05-04 20:56           ` Sebastian Herbszt
2010-05-02 22:13     ` Sebastian Herbszt [this message]
2010-05-04  1:07       ` 乔崇
2010-05-04 20:51         ` Sebastian Herbszt
2010-05-05 19:37           ` Stuart Brady
2010-05-06 19:10             ` [Qemu-devel] " Sebastian Herbszt
2010-05-04  0:01     ` [Qemu-devel] " Alexander Graf
2010-05-04  0:28       ` 乔崇
2010-05-09 19:16         ` Alexander Graf
2010-05-10 11:24           ` 乔崇

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2FC4BB04CF31478F952129939300295C@FSCPC \
    --to=herbszt@gmx.de \
    --cc=agraf@suse.de \
    --cc=elek.roland@gmail.com \
    --cc=joro@8bytes.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qiaochong@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).