summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/armish/stand/boot/machdep.c52
-rw-r--r--sys/arch/armish/stand/boot/pciide.c10
-rw-r--r--sys/arch/armish/stand/boot/wd.c3
3 files changed, 59 insertions, 6 deletions
diff --git a/sys/arch/armish/stand/boot/machdep.c b/sys/arch/armish/stand/boot/machdep.c
index dbd33e526ad..eca4ec3fea5 100644
--- a/sys/arch/armish/stand/boot/machdep.c
+++ b/sys/arch/armish/stand/boot/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.2 2006/07/29 16:08:20 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.3 2006/07/30 20:46:30 drahn Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <arm/pte.h>
+#include <dev/pci/pcireg.h>
#include "libsa.h"
@@ -26,6 +27,8 @@
#define ATU_OIOWTVR 0xffffe15c
#define ATU_ATUCR 0xffffe180
#define ATU_PCSR 0xffffe184
+#define ATU_OCCAR 0xffffe1a4
+#define ATU_OCCDR 0xffffe1ac
#define ATUCR_OUT_EN (1U << 1)
@@ -56,6 +59,53 @@ machdep(void)
__asm volatile ("mcr p6, 0, %0, c1, c1, 0" :: "r" (0x00000032));
cninit();
+
+{
+ /*
+ * this code does a device probe on pci space,
+ * It looks for a wd compatible controller.
+ * however when it reads the device register, it does
+ * not check if a bus fault occurs on the access.
+ * Since the bootloader doesn't handle faults, this
+ * crashes the bootloader if it reads a non-existant
+ * device.
+ * The tag computation comes from arm/xscale/i80321_pci.c
+ * i80321_pci_conf_setup()
+ */
+ int device, bar;
+ for (device = 1; device < 4; device++) {
+ u_int32_t tag, result, size;
+ volatile u_int32_t *occar = (u_int32_t *)ATU_OCCAR;
+ volatile u_int32_t *occdr = (u_int32_t *)ATU_OCCDR;
+
+ tag = 1 << (device + 16) | (device << 11);
+ *occar = tag;
+ result = *occdr;
+ if (result == ~0)
+ continue;
+ *occar = tag | PCI_CLASS_REG;
+ result = *occdr;
+
+ if (PCI_CLASS(result) != PCI_CLASS_MASS_STORAGE)
+ continue;
+ if (PCI_SUBCLASS(result) != PCI_SUBCLASS_MASS_STORAGE_ATA &&
+ PCI_SUBCLASS(result) != PCI_SUBCLASS_MASS_STORAGE_SATA &&
+ PCI_SUBCLASS(result) != PCI_SUBCLASS_MASS_STORAGE_MISC)
+ continue;
+
+ *occar = tag | PCI_MAPREG_START;
+ result = *occdr;
+
+ /* verify result is an IO BAR */
+ if (PCI_MAPREG_TYPE(result) == PCI_MAPREG_TYPE_IO) {
+ extern u_int32_t wdc_base_addr;
+ wdc_base_addr = PCI_MAPREG_MEM_ADDR(result);
+ DPRINTF(("setting wdc_base addr to %x\n",
+ wdc_base_addr));
+ }
+ }
+}
+
}
int
diff --git a/sys/arch/armish/stand/boot/pciide.c b/sys/arch/armish/stand/boot/pciide.c
index f27f173e982..e4cef71102a 100644
--- a/sys/arch/armish/stand/boot/pciide.c
+++ b/sys/arch/armish/stand/boot/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
+/* $OpenBSD: pciide.c,v 1.3 2006/07/30 20:46:30 drahn Exp $ */
/* $NetBSD: pciide.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -39,6 +39,8 @@
#include "libsa.h"
#include "wdvar.h"
+u_int32_t wdc_base_addr = 0;
+
int
pciide_init(struct wdc_channel *chp, u_int chan)
{
@@ -48,7 +50,7 @@ pciide_init(struct wdc_channel *chp, u_int chan)
/*
* two channels per chip, one drive per channel
*/
- if (chan >= PCIIDE_NUM_CHANNELS)
+ if (chan >= PCIIDE_NUM_CHANNELS || wdc_base_addr == 0)
return (ENXIO);
chp->ndrives = 1;
@@ -57,8 +59,8 @@ pciide_init(struct wdc_channel *chp, u_int chan)
/*
* XXX map?
*/
- cmdreg = 0x90000200 + chan * 0x10;
- ctlreg = 0x90000208 + chan * 0x10;
+ cmdreg = wdc_base_addr + chan * 0x10;
+ ctlreg = wdc_base_addr+0x8 + chan * 0x10;
/* set up cmd regsiters */
chp->c_cmdbase = (u_int8_t *)cmdreg;
diff --git a/sys/arch/armish/stand/boot/wd.c b/sys/arch/armish/stand/boot/wd.c
index 7fc9fceac41..662a246edb8 100644
--- a/sys/arch/armish/stand/boot/wd.c
+++ b/sys/arch/armish/stand/boot/wd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wd.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
+/* $OpenBSD: wd.c,v 1.3 2006/07/30 20:46:30 drahn Exp $ */
/* $NetBSD: wd.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -72,6 +72,7 @@ wdprobe(void)
DPRINTF(("wd%d: channel %d drive %d\n",
unit, chan, drive));
unit++;
+ wd++;
}
}