AHCI patches + Allwinner SATA
cover AHCI patches + Allwinner SATA
Hi John and Beniamino,
This patch series adds bear-minimum Allwinner SATA support.
P1 is a trivial to help debug AHCI.
Regards,
Peter
Peter Crosthwaite (4):
ahci: Add some MMIO debug printfs
ahci: split realize and init
ahci: Add allwinner AHCI
arm: allwinner-a10: Add SATA
hw/arm/allwinner-a10.c | 11 +++ hw/ide/ahci.c | 155 ++++++++++++++++++++++++++++++++++++----- hw/ide/ahci.h | 19 ++++- hw/ide/ich.c | 10 ++- include/hw/arm/allwinner-a10.h | 5 ++ 5 files changed, 179 insertions(+), 21 deletions(-)
Signature · 1 line
1.9.1
RFC 1/4 ahci: Add some MMIO debug printfs
These are useful for bringup of AHCI.
--- hw/ide/ahci.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
hw/ide/ahci.c +15 -6
@@ -378,17 +378,23 @@ static uint64_t ahci_mem_read(void *opaque, hwaddr addr, unsigned size)int ofst = addr - aligned;uint64_t lo =ahci_mem_read_32 (opaque, aligned);uint64_t hi; +uint64_t val;/* if < 8 byte read does not cross 4 byte boundary */ if (ofst + size <=4 ) { -return lo >> (ofst *8 ); + val = lo >> (ofst *8 ); + }else { + g_assert_cmpint(size, >, 1); + +/* If the 64bit read is unaligned, we will produce undefined +* results. AHCI does not support unaligned 64bit reads. */ + hi =ahci_mem_read_32 (opaque, aligned +4 ); + val = (hi <<32 | lo) >> (ofst *8 ); } - g_assert_cmpint(size, >, 1); -/* If the 64bit read is unaligned, we will produce undefined -* results. AHCI does not support unaligned 64bit reads. */ - hi =ahci_mem_read_32 (opaque, aligned +4 ); -return (hi <<32 | lo) >> (ofst *8 ); +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); +return val; }
@@ -397,6 +403,9 @@ static void ahci_mem_write(void *opaque, hwaddr addr, {AHCIState *s = opaque; +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); +/* Only aligned reads are allowed on AHCI */ if (addr &3 ) { fprintf(stderr, "ahci: Mis-aligned write to addr 0x"
Signature · 1 line
1.9.1
RFC 2/4 ahci: split realize and init
In reply to Peter CrosthwaiteDo the init level tasks asap and the realize later (mainly when num_ports is available). This allows sub-class realize routines to work with the device post-init.
--- hw/ide/ahci.c | 36 +++++++++++++++++++++++------------- hw/ide/ahci.h | 3 ++- hw/ide/ich.c | 10 +++++++++- 3 files changed, 34 insertions(+), 15 deletions(-)
hw/ide/ahci.c +23 -13
@@ -1436,24 +1436,26 @@ static const IDEDMAOps ahci_dma_ops = { .cmd_done = ahci_cmd_done, }; -void ahci_init (AHCIState *s,DeviceState *qdev,AddressSpace *as,int ports) +void ahci_init (AHCIState *s,DeviceState *qdev) { -qemu_irq *irqs; -int i; - - s->as = as; - s->ports = ports; - s->dev =g_new0 (AHCIDevice, ports); s->container = qdev; -ahci_reg_init (s);/* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */ memory_region_init_io (&s->mem,OBJECT (qdev), &ahci_mem_ops, s,"ahci" ,AHCI_MEM_BAR_SIZE );memory_region_init_io (&s->idp,OBJECT (qdev), &ahci_idp_ops, s,"ahci-idp" ,32 ); +} - irqs =qemu_allocate_irqs (ahci_irq_set, s, s->ports); +void ahci_realize (AHCIState *s,DeviceState *qdev,AddressSpace *as,int ports) +{ +qemu_irq *irqs; +int i; + s->as = as; + s->ports = ports; + s->dev =g_new0 (AHCIDevice, ports); +ahci_reg_init (s); + irqs =qemu_allocate_irqs (ahci_irq_set, s, s->ports);for (i =0 ; i < s->ports; i++) {AHCIDevice *ad = &s->dev[i];
@@ -1648,17 +1650,24 @@ static void sysbus_ahci_reset(DeviceState *dev)ahci_reset (&s->ahci); } -static void sysbus_ahci_realize (DeviceState *dev,Error **errp) +static void sysbus_ahci_init (Object *obj) { -SysBusDevice *sbd =SYS_BUS_DEVICE (dev); -SysbusAHCIState *s =SYSBUS_AHCI (dev); +SysbusAHCIState *s =SYSBUS_AHCI (obj); +SysBusDevice *sbd =SYS_BUS_DEVICE (obj); -ahci_init (&s->ahci, dev, &address_space_memory, s->num_ports); +ahci_init (&s->ahci,DEVICE (obj));sysbus_init_mmio (sbd, &s->ahci.mem);sysbus_init_irq (sbd, &s->ahci.irq); } +static void sysbus_ahci_realize (DeviceState *dev,Error **errp) +{ +SysbusAHCIState *s =SYSBUS_AHCI (dev); + +ahci_realize (&s->ahci, dev, &address_space_memory, s->num_ports); +} +static Property sysbus_ahci_properties[] = {DEFINE_PROP_UINT32 ("num-ports" , SysbusAHCIState, num_ports,1 ),DEFINE_PROP_END_OF_LIST (),
@@ -1679,6 +1688,7 @@ static const TypeInfo sysbus_ahci_info = { .name = TYPE_SYSBUS_AHCI, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(SysbusAHCIState), + .instance_init = sysbus_ahci_init, .class_init = sysbus_ahci_class_init, };
hw/ide/ahci.h +2 -1
@@ -366,7 +366,8 @@ typedef struct SDBFIS {uint32_t payload; }QEMU_PACKED SDBFIS ; -void ahci_init (AHCIState *s,DeviceState *qdev,AddressSpace *as,int ports); +void ahci_realize (AHCIState *s,DeviceState *qdev,AddressSpace *as,int ports); +void ahci_init (AHCIState *s,DeviceState *qdev);void ahci_uninit (AHCIState *s);void ahci_reset (AHCIState *s);
hw/ide/ich.c +9 -1
@@ -97,6 +97,13 @@ static void pci_ich9_reset(DeviceState *dev)ahci_reset (&d->ahci); } +static void pci_ich9_ahci_init (Object *obj) +{ +struct AHCIPCIState *d =ICH_AHCI (obj); + +ahci_init (&d->ahci,DEVICE (obj)); +} +static void pci_ich9_ahci_realize (PCIDevice *dev,Error **errp) {struct AHCIPCIState *d;
@@ -104,7 +111,7 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)uint8_t *sata_cap; d =ICH_AHCI (dev); -ahci_init (&d->ahci,DEVICE (dev),pci_get_address_space (dev),6 ); +ahci_realize (&d->ahci,DEVICE (dev),pci_get_address_space (dev),6 );pci_config_set_prog_interface (dev->config,AHCI_PROGMODE_MAJOR_REV_1 );
@@ -171,6 +178,7 @@ static const TypeInfo ich_ahci_info = { .name = TYPE_ICH9_AHCI, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(AHCIPCIState), + .instance_init = pci_ich9_ahci_init, .class_init = ich_ahci_class_init, };
Signature · 1 line
1.9.1
RFC 3/4 ahci: Add allwinner AHCI
In reply to Peter CrosthwaiteAdd a Sysbus AHCI subclass for the Allwinner AHCI. It has a few extra vendor specific registers that are used for phy and power init.
--- hw/ide/ahci.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/ide/ahci.h | 16 ++++++++++ 2 files changed, 114 insertions(+)
hw/ide/ahci.c +98 -0
@@ -1692,9 +1692,107 @@ static const TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, }; +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +#define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) + +static uint64_t allwinner_ahci_mem_read (void *opaque,hwaddr addr, +unsigned size) +{ +AllwinnerAHCIState *a = opaque; +uint64_t val = a->regs[addr/4 ]; + +switch (addr /4 ) { +case ALLWINNER_AHCI_PHYCS0R : + val |=0x2 <<28 ; +break ; +case ALLWINNER_AHCI_PHYCS2R : + val &= ~(0x1 <<24 ); +break ; + } +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); +return val; +} + +static void allwinner_ahci_mem_write (void *opaque,hwaddr addr, +uint64_t val,unsigned size) +{ +AllwinnerAHCIState *a = opaque; + +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); + a->regs[addr/4 ] = val; +} + +static const MemoryRegionOps allwinner_ahci_mem_ops = { + .read = allwinner_ahci_mem_read, + .write = allwinner_ahci_mem_write, + .valid.min_access_size =4 , + .valid.max_access_size =4 , + .endianness =DEVICE_LITTLE_ENDIAN , +}; + +static void allwinner_ahci_init (Object *obj) +{ +SysbusAHCIState *s =SYSBUS_AHCI (obj); +AllwinnerAHCIState *a =ALLWINNER_AHCI (obj); + +memory_region_init_io (&a->mmio,OBJECT (obj), &allwinner_ahci_mem_ops, a, +"allwinner_ahci" ,ALLWINNER_AHCI_MMIO_SIZE ); +memory_region_add_subregion (&s->ahci.mem,ALLWINNER_AHCI_MMIO_OFF , + &a->mmio); +} + +static const VMStateDescription vmstate_allwinner_ahci = { + .name ="a10.pic" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32_ARRAY (regs, AllwinnerAHCIState, +ALLWINNER_AHCI_MMIO_SIZE /4 ), +VMSTATE_END_OF_LIST () + } +}; + +static void allwinner_ahci_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->vmsd = &vmstate_allwinner_ahci; +} + +static const TypeInfo allwinner_ahci_info = { + .name =TYPE_ALLWINNER_AHCI , + .parent =TYPE_SYSBUS_AHCI , + .instance_size =sizeof (AllwinnerAHCIState), + .instance_init = allwinner_ahci_init, + .class_init = allwinner_ahci_class_init, +}; +static void sysbus_ahci_register_types (void ) {type_register_static (&sysbus_ahci_info); +type_register_static (&allwinner_ahci_info); }type_init (sysbus_ahci_register_types)
hw/ide/ahci.h +16 -0
@@ -386,4 +386,20 @@ typedef struct SysbusAHCIState { uint32_t num_ports; } SysbusAHCIState; +#define TYPE_ALLWINNER_AHCI "allwinner-ahci" +#define ALLWINNER_AHCI (obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \ + TYPE_ALLWINNER_AHCI) + +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +typedef struct AllwinnerAHCIState { +/*< private >*/ +SysbusAHCIState parent_obj; +/*< public >*/ + +MemoryRegion mmio; +uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE /4 ]; +}AllwinnerAHCIState ; +#endif /* HW_IDE_AHCI_H */
Signature · 1 line
1.9.1
RFC 4/4 arm: allwinner-a10: Add SATA
In reply to Peter CrosthwaiteAdd the Allwinner A10 AHCI controller module to the SoC.
--- hw/arm/allwinner-a10.c | 11 +++++++++++ include/hw/arm/allwinner-a10.h | 5 +++++ 2 files changed, 16 insertions(+)
hw/arm/allwinner-a10.c +11 -0
@@ -42,6 +42,9 @@ static void aw_a10_init(Object *obj)object_initialize (&s->ccm,sizeof (s->ccm),TYPE_AW_A10_CCM );qdev_set_parent_bus (DEVICE (&s->ccm),sysbus_get_default ()); + +object_initialize (&s->sata,sizeof (s->sata),TYPE_ALLWINNER_AHCI ); +qdev_set_parent_bus (DEVICE (&s->sata),sysbus_get_default ()); }static void aw_a10_realize (DeviceState *dev,Error **errp)
@@ -104,6 +107,14 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbusdev =SYS_BUS_DEVICE (&s->ccm);sysbus_mmio_map (sysbusdev,0 ,AW_A10_CCM_REG_BASE ); +object_property_set_bool (OBJECT (&s->sata), true,"realized" , &err); +if (err) { +error_propagate (errp, err); +return ; + } +sysbus_mmio_map (SYS_BUS_DEVICE (&s->sata),0 ,AW_A10_SATA_BASE ); +sysbus_connect_irq (SYS_BUS_DEVICE (&s->sata),0 , s->irq[56 ]); +/* FIXME use a qdev chardev prop instead of serial_hds[] */ serial_mm_init (get_system_memory (),AW_A10_UART0_REG_BASE ,2 , s->irq[1 ],115200 , serial_hds[0 ],DEVICE_NATIVE_ENDIAN );
include/hw/arm/allwinner-a10.h +5 -0
@@ -8,6 +8,8 @@#include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" #include "hw/misc/allwinner-a10-ccm.h" +#include "hw/ide/pci.h" +#include "hw/ide/ahci.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h"
@@ -18,6 +20,7 @@#define AW_A10_PIT_REG_BASE 0x01c20c00#define AW_A10_UART0_REG_BASE 0x01c28000#define AW_A10_EMAC_BASE 0x01c0b000 +#define AW_A10_SATA_BASE 0x01c18000#define AW_A10_SDRAM_BASE 0x40000000
@@ -35,6 +38,8 @@ typedef struct AwA10State {AwA10PICState intc;AwEmacState emac;AwA10CCMState ccm; + +AllwinnerAHCIState sata; } AwA10State;#define ALLWINNER_H_
Signature · 1 line
1.9.1
Quoted 3 lines · Peter Crosthwaite
Hi John and Beniamino,
This patch series adds bear-minimum Allwinner SATA support.
Hi Peter,
can you suggest a qemu command line to test this?
Beniamino
Re: [Qemu-devel] [RFC 4/4] arm: allwinner-a10: Add SATA
In reply to Peter CrosthwaiteQuoted 60 lines · Peter Crosthwaite
Add the Allwinner A10 AHCI controller module to the SoC.
Signed-off-by Peter Crosthwaite <[email protected]>--- hw/arm/allwinner-a10.c | 11 +++++++++++ include/hw/arm/allwinner-a10.h | 5 +++++ 2 files changed, 16 insertions(+)hw/arm/allwinner-a10.c +11
-0@@ -42,6 +42,9 @@ static void aw_a10_init(Object *obj)object_initialize (&s->ccm,sizeof (s->ccm),TYPE_AW_A10_CCM );qdev_set_parent_bus (DEVICE (&s->ccm),sysbus_get_default ()); + +object_initialize (&s->sata,sizeof (s->sata),TYPE_ALLWINNER_AHCI ); +qdev_set_parent_bus (DEVICE (&s->sata),sysbus_get_default ()); }static void aw_a10_realize (DeviceState *dev,Error **errp)@@ -104,6 +107,14 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbusdev =SYS_BUS_DEVICE (&s->ccm);sysbus_mmio_map (sysbusdev,0 ,AW_A10_CCM_REG_BASE ); +object_property_set_bool (OBJECT (&s->sata), true,"realized" , &err); +if (err) { +error_propagate (errp, err); +return ; + } +sysbus_mmio_map (SYS_BUS_DEVICE (&s->sata),0 ,AW_A10_SATA_BASE ); +sysbus_connect_irq (SYS_BUS_DEVICE (&s->sata),0 , s->irq[56 ]); +/* FIXME use a qdev chardev prop instead of serial_hds[] */ serial_mm_init (get_system_memory (),AW_A10_UART0_REG_BASE ,2 , s->irq[1 ],115200 , serial_hds[0 ],DEVICE_NATIVE_ENDIAN );include/hw/arm/allwinner-a10.h +3
-0@@ -8,6 +8,8 @@#include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" #include "hw/misc/allwinner-a10-ccm.h" +#include "hw/ide/pci.h" +#include "hw/ide/ahci.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" @@ -18,6 +20,7 @@#define AW_A10_PIT_REG_BASE 0x01c20c00#define AW_A10_UART0_REG_BASE 0x01c28000#define AW_A10_EMAC_BASE 0x01c0b000 +#define AW_A10_SATA_BASE 0x01c18000#define AW_A10_SDRAM_BASE 0x40000000
include/hw/arm/allwinner-a10.h typedef struct AwA10State { · line 45
Quoted 8 lines
include/hw/arm/allwinner-a10.h +2
-0@@ -35,6 +38,8 @@ typedef struct AwA10State {AwA10PICState intc;AwEmacState emac;AwA10CCMState ccm; + +AllwinnerAHCIState sata; } AwA10State;#define ALLWINNER_H_
Does this series have a pre-requisite patchset for this to apply cleanly?
--js
Re: [Qemu-devel] [RFC 3/4] ahci: Add allwinner AHCI
In reply to Peter CrosthwaiteIs there any spec or documentation I can cross-reference this against?
I gather this exists within the vendor-specific reserved region from 0xA0 to 0xFF just prior to the port registers, so this all /looks/ like it's right, I just don't have any way to verify it.
Quoted 64 lines · Peter Crosthwaite
Add a Sysbus AHCI subclass for the Allwinner AHCI. It has a few extra vendor specific registers that are used for phy and power init.
Signed-off-by Peter Crosthwaite <[email protected]>--- hw/ide/ahci.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/ide/ahci.h | 16 ++++++++++ 2 files changed, 114 insertions(+)hw/ide/ahci.c +47
-0@@ -1692,9 +1692,107 @@ static const TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, }; +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +#define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) + +static uint64_t allwinner_ahci_mem_read (void *opaque,hwaddr addr, +unsigned size) +{ +AllwinnerAHCIState *a = opaque; +uint64_t val = a->regs[addr/4 ]; + +switch (addr /4 ) { +case ALLWINNER_AHCI_PHYCS0R : + val |=0x2 <<28 ; +break ; +case ALLWINNER_AHCI_PHYCS2R : + val &= ~(0x1 <<24 ); +break ; + } +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); +return val; +} + +static void allwinner_ahci_mem_write (void *opaque,hwaddr addr, +uint64_t val,unsigned size) +{ +AllwinnerAHCIState *a = opaque; +
hw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1751
Quoted 10 lines
hw/ide/ahci.c +10
-0+DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); + a->regs[addr/4 ] = val; +} + +static const MemoryRegionOps allwinner_ahci_mem_ops = { + .read = allwinner_ahci_mem_read, + .write = allwinner_ahci_mem_write, + .valid.min_access_size =4 , + .valid.max_access_size =4 ,
Are you sure devices won't try to read individual bytes for error codes out of these vendor registers?
Quoted 73 lines
hw/ide/ahci.c +41
-0+ .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void allwinner_ahci_init (Object *obj) +{ +SysbusAHCIState *s =SYSBUS_AHCI (obj); +AllwinnerAHCIState *a =ALLWINNER_AHCI (obj); + +memory_region_init_io (&a->mmio,OBJECT (obj), &allwinner_ahci_mem_ops, a, +"allwinner_ahci" ,ALLWINNER_AHCI_MMIO_SIZE ); +memory_region_add_subregion (&s->ahci.mem,ALLWINNER_AHCI_MMIO_OFF , + &a->mmio); +} + +static const VMStateDescription vmstate_allwinner_ahci = { + .name ="a10.pic" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32_ARRAY (regs, AllwinnerAHCIState, +ALLWINNER_AHCI_MMIO_SIZE /4 ), +VMSTATE_END_OF_LIST () + } +}; + +static void allwinner_ahci_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->vmsd = &vmstate_allwinner_ahci; +} + +static const TypeInfo allwinner_ahci_info = { + .name =TYPE_ALLWINNER_AHCI , + .parent =TYPE_SYSBUS_AHCI , + .instance_size =sizeof (AllwinnerAHCIState), + .instance_init = allwinner_ahci_init, + .class_init = allwinner_ahci_class_init, +}; +static void sysbus_ahci_register_types (void ) {type_register_static (&sysbus_ahci_info); +type_register_static (&allwinner_ahci_info); }type_init (sysbus_ahci_register_types)hw/ide/ahci.h +16
-0@@ -386,4 +386,20 @@ typedef struct SysbusAHCIState { uint32_t num_ports; } SysbusAHCIState; +#define TYPE_ALLWINNER_AHCI "allwinner-ahci" +#define ALLWINNER_AHCI (obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \ + TYPE_ALLWINNER_AHCI) + +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +typedef struct AllwinnerAHCIState { +/*< private >*/ +SysbusAHCIState parent_obj; +/*< public >*/ + +MemoryRegion mmio; +uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE /4 ]; +}AllwinnerAHCIState ; +#endif /* HW_IDE_AHCI_H */
Re: [Qemu-devel] [RFC 4/4] arm: allwinner-a10: Add SATA
In reply to John SnowQuoted 69 lines · John Snow
Quoted 66 lines · Peter Crosthwaite
Add the Allwinner A10 AHCI controller module to the SoC.
Signed-off-by Peter Crosthwaite <[email protected]>--- hw/arm/allwinner-a10.c | 11 +++++++++++ include/hw/arm/allwinner-a10.h | 5 +++++ 2 files changed, 16 insertions(+)hw/arm/allwinner-a10.c +11
-0@@ -42,6 +42,9 @@ static void aw_a10_init(Object *obj)object_initialize (&s->ccm,sizeof (s->ccm),TYPE_AW_A10_CCM );qdev_set_parent_bus (DEVICE (&s->ccm),sysbus_get_default ()); + +object_initialize (&s->sata,sizeof (s->sata),TYPE_ALLWINNER_AHCI ); +qdev_set_parent_bus (DEVICE (&s->sata),sysbus_get_default ()); }static void aw_a10_realize (DeviceState *dev,Error **errp)@@ -104,6 +107,14 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbusdev =SYS_BUS_DEVICE (&s->ccm);sysbus_mmio_map (sysbusdev,0 ,AW_A10_CCM_REG_BASE ); +object_property_set_bool (OBJECT (&s->sata), true,"realized" , &err); +if (err) { +error_propagate (errp, err); +return ; + } +sysbus_mmio_map (SYS_BUS_DEVICE (&s->sata),0 ,AW_A10_SATA_BASE ); +sysbus_connect_irq (SYS_BUS_DEVICE (&s->sata),0 , s->irq[56 ]); +/* FIXME use a qdev chardev prop instead of serial_hds[] */ serial_mm_init (get_system_memory (),AW_A10_UART0_REG_BASE ,2 , s->irq[1 ],115200 , serial_hds[0 ],DEVICE_NATIVE_ENDIAN );include/hw/arm/allwinner-a10.h +5
-0@@ -8,6 +8,8 @@#include "hw/intc/allwinner-a10-pic.h" #include "hw/net/allwinner_emac.h" #include "hw/misc/allwinner-a10-ccm.h" +#include "hw/ide/pci.h" +#include "hw/ide/ahci.h" #include "sysemu/sysemu.h" #include "exec/address-spaces.h" @@ -18,6 +20,7 @@#define AW_A10_PIT_REG_BASE 0x01c20c00#define AW_A10_UART0_REG_BASE 0x01c28000#define AW_A10_EMAC_BASE 0x01c0b000 +#define AW_A10_SATA_BASE 0x01c18000#define AW_A10_SDRAM_BASE 0x40000000@@ -35,6 +38,8 @@ typedef struct AwA10State {AwA10PICState intc;AwEmacState emac;AwA10CCMState ccm; + +AllwinnerAHCIState sata; } AwA10State;
Quoted 4 lines
include/hw/arm/allwinner-a10.h typedef struct AwA10State { · line 45
Quoted 2 lines
include/hw/arm/allwinner-a10.h +0
-0#define ALLWINNER_H_ Does this series have a pre-requisite patchset for this to apply cleanly?
Yes I need to drop out the CCM patches that I have in the branch in V2. Sorry.
Regards,
Peter
Quoted 2 lines
--js
Re: [Qemu-devel] [RFC 3/4] ahci: Add allwinner AHCI
In reply to John SnowQuoted 2 lines · John Snow
Is there any spec or documentation I can cross-reference this against?
Not that I know of. I am running off a combination of experiments (looking at messages from P1) and the Linux driver source.
Quoted 74 lines
I gather this exists within the vendor-specific reserved region from
0xA0to0xFFjust prior to the port registers, so this all /looks/ like it's right, I just don't have any way to verify it.Quoted 69 lines · Peter Crosthwaite
Add a Sysbus AHCI subclass for the Allwinner AHCI. It has a few extra vendor specific registers that are used for phy and power init.
Signed-off-by Peter Crosthwaite <[email protected]>--- hw/ide/ahci.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/ide/ahci.h | 16 ++++++++++ 2 files changed, 114 insertions(+)hw/ide/ahci.c +52
-0@@ -1692,9 +1692,107 @@ static const TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, }; +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +#define ALLWINNER_AHCI_BISTAFR ((0xa0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTCR ((0xa4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTFCTR ((0xa8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTSR ((0xac - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_BISTDECR ((0xb0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR0 ((0xb4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_DIAGNR1 ((0xb8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_OOBR ((0xbc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS0R ((0xc0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS1R ((0xc4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PHYCS2R ((0xc8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TIMER1MS ((0xe0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM1R ((0xe8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_GPARAM2R ((0xec - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_PPARAMR ((0xf0 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_TESTR ((0xf4 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_VERSIONR ((0xf8 - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_IDR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) +#define ALLWINNER_AHCI_RWCR ((0xfc - ALLWINNER_AHCI_MMIO_OFF) / 4) + +static uint64_t allwinner_ahci_mem_read (void *opaque,hwaddr addr, +unsigned size) +{ +AllwinnerAHCIState *a = opaque; +uint64_t val = a->regs[addr/4 ]; + +switch (addr /4 ) { +case ALLWINNER_AHCI_PHYCS0R : + val |=0x2 <<28 ; +break ; +case ALLWINNER_AHCI_PHYCS2R : + val &= ~(0x1 <<24 ); +break ; + } +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); +return val; +} + +static void allwinner_ahci_mem_write (void *opaque,hwaddr addr, +uint64_t val,unsigned size) +{ +AllwinnerAHCIState *a = opaque; + +DPRINTF (-1 ,"addr=0x%" HWADDR_PRIx" val=0x%" PRIx64", size=%d\n" , + addr, val, size); + a->regs[addr/4 ] = val; +} +
Quoted 9 lines
hw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1751
Quoted 5 lines
hw/ide/ahci.c +5
-0+static const MemoryRegionOps allwinner_ahci_mem_ops = { + .read = allwinner_ahci_mem_read, + .write = allwinner_ahci_mem_write, + .valid.min_access_size =4 , + .valid.max_access_size =4 ,Are you sure devices won't try to read individual bytes for error codes out of these vendor registers?
No idea.
Regards,
Peter
Quoted 73 lines
Quoted 73 lines
hw/ide/ahci.c +41
-0+ .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void allwinner_ahci_init (Object *obj) +{ +SysbusAHCIState *s =SYSBUS_AHCI (obj); +AllwinnerAHCIState *a =ALLWINNER_AHCI (obj); + +memory_region_init_io (&a->mmio,OBJECT (obj), &allwinner_ahci_mem_ops, a, +"allwinner_ahci" ,ALLWINNER_AHCI_MMIO_SIZE ); +memory_region_add_subregion (&s->ahci.mem,ALLWINNER_AHCI_MMIO_OFF , + &a->mmio); +} + +static const VMStateDescription vmstate_allwinner_ahci = { + .name ="a10.pic" , + .version_id =1 , + .minimum_version_id =1 , + .fields = (VMStateField []) { +VMSTATE_UINT32_ARRAY (regs, AllwinnerAHCIState, +ALLWINNER_AHCI_MMIO_SIZE /4 ), +VMSTATE_END_OF_LIST () + } +}; + +static void allwinner_ahci_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); + + dc->vmsd = &vmstate_allwinner_ahci; +} + +static const TypeInfo allwinner_ahci_info = { + .name =TYPE_ALLWINNER_AHCI , + .parent =TYPE_SYSBUS_AHCI , + .instance_size =sizeof (AllwinnerAHCIState), + .instance_init = allwinner_ahci_init, + .class_init = allwinner_ahci_class_init, +}; +static void sysbus_ahci_register_types (void ) {type_register_static (&sysbus_ahci_info); +type_register_static (&allwinner_ahci_info); }type_init (sysbus_ahci_register_types)hw/ide/ahci.h +16
-0@@ -386,4 +386,20 @@ typedef struct SysbusAHCIState { uint32_t num_ports; } SysbusAHCIState; +#define TYPE_ALLWINNER_AHCI "allwinner-ahci" +#define ALLWINNER_AHCI (obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \ + TYPE_ALLWINNER_AHCI) + +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80 + +typedef struct AllwinnerAHCIState { +/*< private >*/ +SysbusAHCIState parent_obj; +/*< public >*/ + +MemoryRegion mmio; +uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE /4 ]; +}AllwinnerAHCIState ; +#endif /* HW_IDE_AHCI_H */
Quoted 9 lines · Beniamino Galvani
Quoted 3 lines · Peter Crosthwaite
Hi John and Beniamino,
This patch series adds bear-minimum Allwinner SATA support.
Hi Peter,
can you suggest a qemu command line to test this?
-drive file=path/to/rootfs.ext4,if=none,id=sata
-device ide-drive,drive=sata,bus=ide.0
--append "root=/dev/sda"
Regards,
Peter
Quoted 1 line
Beniamino
Re: [Qemu-devel] [RFC 3/4] ahci: Add allwinner AHCI
In reply to Peter Crosthwaitehw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1696
Quoted 8 lines · Peter Crosthwaite
hw/ide/ahci.c +2
-0@@ -1692,9 +1692,107 @@ static const TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, }; +#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80
These are already defined in the header file.
hw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1767
Quoted 2 lines
hw/ide/ahci.c +2
-0+static const VMStateDescription vmstate_allwinner_ahci = { + .name ="a10.pic" ,
.name = "allwinner-ahci" ?
Beniamino
Quoted 15 lines · Peter Crosthwaite
Hi John and Beniamino,
This patch series adds bear-minimum Allwinner SATA support.
P1 is a trivial to help debug AHCI.
Regards,
PeterPeter Crosthwaite (4):
ahci: Add some MMIO debug printfs
ahci: split realize and init
ahci: Add allwinner AHCI
arm: allwinner-a10: Add SATA
Quoted 7 lines
hw/arm/allwinner-a10.c | 11 +++ hw/ide/ahci.c | 155 ++++++++++++++++++++++++++++++++++++----- hw/ide/ahci.h | 19 ++++- hw/ide/ich.c | 10 ++- include/hw/arm/allwinner-a10.h | 5 ++ 5 files changed, 179 insertions(+), 21 deletions(-)
Will you be sending the V2 that applies to current master, or do you intend to try to get this in for 2.5?
Re: [Qemu-devel] [RFC 3/4] ahci: Add allwinner AHCI
In reply to Beniamino GalvaniQuoted 7 lines · Beniamino Galvani
Quoted 6 lines · Peter Crosthwaite
hw/ide/ahci.c +0
-0@@ -1692,9 +1692,107 @@ static const TypeInfo sysbus_ahci_info = { .class_init = sysbus_ahci_class_init, };
Quoted 5 lines
hw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1696
Quoted 2 lines
hw/ide/ahci.c +2
-0+#define ALLWINNER_AHCI_MMIO_OFF 0x80 +#define ALLWINNER_AHCI_MMIO_SIZE 0x80These are already defined in the header file.
Dropped.
Quoted 5 lines
hw/ide/ahci.c static const TypeInfo sysbus_ahci_info = { · line 1767
Quoted 2 lines
hw/ide/ahci.c +2
-0+static const VMStateDescription vmstate_allwinner_ahci = { + .name ="a10.pic" ,.name = "allwinner-ahci" ?
Fixed. I also tweaked the name of the memory region to use - instead of _ to match this.
Thanks.
Regards,
Peter
Quoted 1 line
Beniamino
Quoted 26 lines · John Snow
Quoted 15 lines · Peter Crosthwaite
Hi John and Beniamino,
This patch series adds bear-minimum Allwinner SATA support.
P1 is a trivial to help debug AHCI.
Regards,
PeterPeter Crosthwaite (4):
ahci: Add some MMIO debug printfs
ahci: split realize and init
ahci: Add allwinner AHCI
arm: allwinner-a10: Add SATAQuoted 7 lines
hw/arm/allwinner-a10.c | 11 +++ hw/ide/ahci.c | 155 ++++++++++++++++++++++++++++++++++++----- hw/ide/ahci.h | 19 ++++- hw/ide/ich.c | 10 ++- include/hw/arm/allwinner-a10.h | 5 ++ 5 files changed, 179 insertions(+), 21 deletions(-)
Quoted 2 lines
Will you be sending the V2 that applies to current master, or do you intend to try to get this in for 2.5?
Both :) It would be good to get the functionality for 2.5. New version on list (I called it V1 as this is the RFC).
Regards,
Peter