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;
}
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.