NetBSD-Bugs archive

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

kern/53716: PCengines APU2 requires AHCI enabler



>Number:         53716
>Category:       kern
>Synopsis:       PCengines APU2 requires AHCI enabler
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Nov 10 13:30:00 +0000 2018
>Originator:     Shinichi Doyashiki
>Release:        NetBSD 8.0_STABLE
>Organization:
	at home
>Environment:
System: NetBSD devel.csel.org 8.0_STABLE NetBSD 8.0_STABLE (APU1C_8) #2: Sat Oct 6 20:53:12 JST 2018 clare%devel.csel.org@localhost:/export/stage/stable-8/src/sys/arch/amd64/compile/APU1C_8 amd64
Architecture: x86_64
Machine: amd64
>Description:
	The PCengines APU2C4 uses AMD Hudson AHCI SATA controller,
	but its BIOS does not initialize the PCI hardware as
	we desired.

	Since we have no DMA handling for AMD Hudson IDE chipset,
	we require switching the chipset from IDE/Legacy mode to
	AHCI mode, to get reasonable performance.

>How-To-Repeat:
	Get an APU2C4 hardware, and boot NetBSD kernel on it.

>Fix:
	I wrote a quick hack patch as following:

cvs diff: Diffing .
Index: ahcisata_pci.c
===================================================================
RCS file: /export/cvsroot/netbsd/src/sys/dev/pci/ahcisata_pci.c,v
retrieving revision 1.38
diff -u -r1.38 ahcisata_pci.c
--- ahcisata_pci.c	13 Oct 2016 17:11:09 -0000	1.38
+++ ahcisata_pci.c	10 Nov 2018 12:47:42 -0000
@@ -238,6 +238,39 @@
 	force = ((ahci_pci_has_quirk( PCI_VENDOR(pa->pa_id),
 	    PCI_PRODUCT(pa->pa_id)) & AHCI_PCI_QUIRK_FORCE) != 0);
 
+        /*
+         * The PCengines APU2's system BIOS does not handle AHCI device
+         * as we desired.  We should fix it by re-program registers.
+         * In general, AMD Hudson SATA device should be used in AHCI mode
+	  * rather than IDE mode, since we have no DMA driver for it.
+         *
+         * see ftp://kolibrios.org/users/art_zh/doc/public/A50_RPR.pdf
+         * for register programming details.
+         */
+        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
+            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_HUDSON_SATA)
+        {
+                int reg;
+
+                printf("ahcisata: re-program IDE to AHCI\n");
+                /* make subclass/interface register is writeable */
+                reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
+                reg |= 1;
+                pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg);
+                /* rewrite subclass/interface register */
+                reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x08);
+                reg &= ~0x0000FF00; /* clear register 0x09 */
+                reg |=  0x00000100; /* set 0x09 to 0x01 */
+                reg &= ~0x00FF0000; /* clear register 0x0A */
+                reg |=  0x00060000; /* set 0x0A to 0x06 */
+                pci_conf_write(pa->pa_pc, pa->pa_tag, 0x08, reg);
+                pa->pa_class = reg; /* writeback to the our cache */
+                /* make subclass/interface register is not writeable */
+                reg = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
+                reg &= ~1;
+                pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, reg);
+        }
+
 	/* if wrong class and not forced by quirks, don't match */
 	if ((PCI_CLASS(pa->pa_class) != PCI_CLASS_MASS_STORAGE ||
 	    ((PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_SATA ||



Home | Main Index | Thread Index | Old Index