Date: Mon, 25 Jul 2016 18:24:54 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r303313 - projects/powernv/powerpc/powernv Message-ID: <201607251824.u6PIOsG4032937@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Mon Jul 25 18:24:54 2016 New Revision: 303313 URL: https://svnweb.freebsd.org/changeset/base/303313 Log: Add some stub code for resetting the PCI host bridge that currently hoses everything. Modified: projects/powernv/powerpc/powernv/opal.h projects/powernv/powerpc/powernv/opal_pci.c Modified: projects/powernv/powerpc/powernv/opal.h ============================================================================== --- projects/powernv/powerpc/powernv/opal.h Mon Jul 25 17:37:02 2016 (r303312) +++ projects/powernv/powerpc/powernv/opal.h Mon Jul 25 18:24:54 2016 (r303313) @@ -45,6 +45,7 @@ int opal_call(uint64_t token, ...); #define OPAL_RTC_WRITE 4 #define OPAL_CEC_POWER_DOWN 5 #define OPAL_CEC_REBOOT 6 +#define OPAL_HANDLE_INTERRUPT 9 #define OPAL_POLL_EVENTS 10 #define OPAL_PCI_CONFIG_READ_BYTE 13 #define OPAL_PCI_CONFIG_READ_HALF_WORD 14 @@ -56,12 +57,16 @@ int opal_call(uint64_t token, ...); #define OPAL_PCI_PHB_MMIO_ENABLE 27 #define OPAL_PCI_SET_PHB_MEM_WINDOW 28 #define OPAL_PCI_MAP_PE_MMIO_WINDOW 29 +#define OPAL_PCI_SET_XIVE_PE 37 #define OPAL_PCI_RESET 49 +#define OPAL_PCI_POLL 62 #define OPAL_SET_XIVE 19 #define OPAL_GET_XIVE 20 #define OPAL_PCI_SET_PE 31 #define OPAL_START_CPU 41 #define OPAL_PCI_MAP_PE_DMA_WINDOW_REAL 45 +#define OPAL_RETURN_CPU 69 +#define OPAL_REINIT_CPUS 70 /* For OPAL_PCI_SET_PE */ #define OPAL_UNMAP_PE 0 @@ -69,6 +74,7 @@ int opal_call(uint64_t token, ...); #define OPAL_SUCCESS 0 #define OPAL_PARAMETER -1 +#define OPAL_CLOSED -5 #define OPAL_BUSY_EVENT -12 #endif Modified: projects/powernv/powerpc/powernv/opal_pci.c ============================================================================== --- projects/powernv/powerpc/powernv/opal_pci.c Mon Jul 25 17:37:02 2016 (r303312) +++ projects/powernv/powerpc/powernv/opal_pci.c Mon Jul 25 18:24:54 2016 (r303313) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Nathan Whitehorn + * Copyright (c) 2015-2016 Nathan Whitehorn * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -74,12 +74,21 @@ static void opalpci_write_config(device u_int, u_int32_t, int); /* + * bus interface. + */ + +static int opalpci_setup_intr(device_t dev, device_t child, struct resource *r, + int flags, driver_filter_t *filter, driver_intr_t *ithread, + void *arg, void **cookiep); + +/* * Commands */ #define OPAL_M32_WINDOW_TYPE 1 #define OPAL_M64_WINDOW_TYPE 2 #define OPAL_IO_WINDOW_TYPE 3 +#define OPAL_RESET_PHB_COMPLETE 1 #define OPAL_RESET_PCI_IODA_TABLE 6 #define OPAL_DISABLE_M64 0 @@ -91,6 +100,11 @@ static void opalpci_write_config(device #define OPAL_EEH_ACTION_CLEAR_FREEZE_ALL 3 /* + * Constants + */ +#define OPAL_PCI_DEFAULT_PE 1 + +/* * Driver methods. */ static device_method_t opalpci_methods[] = { @@ -102,6 +116,9 @@ static device_method_t opalpci_methods[] DEVMETHOD(pcib_read_config, opalpci_read_config), DEVMETHOD(pcib_write_config, opalpci_write_config), + /* bus overrides */ + DEVMETHOD(bus_setup_intr, opalpci_setup_intr), + DEVMETHOD_END }; @@ -164,24 +181,58 @@ opalpci_attach(device_t dev) device_printf(dev, "OPAL ID %#lx\n", sc->phb_id); /* - * Map all devices on the bus to partitionable endpoint one until - * such time as we start wanting to do things like bhyve. + * Reset PCI IODA table */ - err = opal_call(OPAL_PCI_SET_PE, sc->phb_id, 1 /* Root PE */, - 0, 0, 0, 0, /* All devices */ - OPAL_MAP_PE); + err = opal_call(OPAL_PCI_RESET, sc->phb_id, OPAL_RESET_PCI_IODA_TABLE, + 1); if (err != 0) { - device_printf(dev, "PE mapping failed: %d\n", err); + device_printf(dev, "IODA table reset failed: %d\n", err); return (ENXIO); } /* - * Reset PCI IODA table + * Reset everything. Especially important if we have inherited the + * system from Linux by kexec() */ - err = opal_call(OPAL_PCI_RESET, sc->phb_id, OPAL_RESET_PCI_IODA_TABLE, - 1); +#ifdef NOTYET + if (bootverbose) + device_printf(dev, "Resetting PCI bus\n"); + err = opal_call(OPAL_PCI_RESET, sc->phb_id, OPAL_RESET_PHB_COMPLETE, 1); + if (err < 0) { + device_printf(dev, "PHB reset failed: %d\n", err); + return (ENXIO); + } + while ((err = opal_call(OPAL_PCI_POLL, sc->phb_id)) > 0) + DELAY(1000*err); /* Returns expected delay in ms */ + if (err < 0) { + device_printf(dev, "PHB reset poll failed: %d\n", err); + return (ENXIO); + } + DELAY(10000); + err = opal_call(OPAL_PCI_RESET, sc->phb_id, OPAL_RESET_PHB_COMPLETE, 0); + if (err < 0) { + device_printf(dev, "PHB reset completion failed: %d\n", err); + return (ENXIO); + } + while ((err = opal_call(OPAL_PCI_POLL, sc->phb_id)) > 0) + DELAY(1000*err); /* Returns expected delay in ms */ + if (err < 0) { + device_printf(dev, "PHB reset completion poll failed: %d\n", + err); + return (ENXIO); + } + DELAY(10000); +#endif + + /* + * Map all devices on the bus to partitionable endpoint one until + * such time as we start wanting to do things like bhyve. + */ + err = opal_call(OPAL_PCI_SET_PE, sc->phb_id, OPAL_PCI_DEFAULT_PE, + 0, 0, 0, 0, /* All devices */ + OPAL_MAP_PE); if (err != 0) { - device_printf(dev, "IODA table reset failed: %d\n", err); + device_printf(dev, "PE mapping failed: %d\n", err); return (ENXIO); } @@ -192,8 +243,8 @@ opalpci_attach(device_t dev) != 4) npe = 1; for (i = 0; i < npe; i++) { - err = opal_call(OPAL_PCI_MAP_PE_MMIO_WINDOW, sc->phb_id, 1, - OPAL_M32_WINDOW_TYPE, 0, i); + err = opal_call(OPAL_PCI_MAP_PE_MMIO_WINDOW, sc->phb_id, + OPAL_PCI_DEFAULT_PE, OPAL_M32_WINDOW_TYPE, 0, i); if (err != 0) device_printf(dev, "MMIO %d map failed: %d\n", i, err); } @@ -205,8 +256,9 @@ opalpci_attach(device_t dev) OPAL_M64_WINDOW_TYPE, 0 /* index */, ((uint64_t)m64window[2] << 32) | m64window[3], 0, ((uint64_t)m64window[4] << 32) | m64window[5]); - opal_call(OPAL_PCI_MAP_PE_MMIO_WINDOW, sc->phb_id, 1 /* PE */, - OPAL_M64_WINDOW_TYPE, 0 /* index */, 0); + opal_call(OPAL_PCI_MAP_PE_MMIO_WINDOW, sc->phb_id, + OPAL_PCI_DEFAULT_PE, OPAL_M64_WINDOW_TYPE, + 0 /* index */, 0); opal_call(OPAL_PCI_PHB_MMIO_ENABLE, sc->phb_id, OPAL_M64_WINDOW_TYPE, 0, OPAL_ENABLE_M64_NON_SPLIT); } @@ -214,8 +266,9 @@ opalpci_attach(device_t dev) /* * Also disable the IOMMU for the time being for PE 1 (everything) */ - err = opal_call(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, sc->phb_id, 1, 2, - 0 /* start address */, roundup2(Maxmem, 16*1024*1024)/* all RAM */); + err = opal_call(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, sc->phb_id, + OPAL_PCI_DEFAULT_PE, 2, 0 /* start address */, + roundup2(Maxmem, 16*1024*1024)/* all RAM */); if (err != 0) { device_printf(dev, "DMA mapping failed: %d\n", err); return (ENXIO); @@ -232,7 +285,7 @@ opalpci_attach(device_t dev) * Unfreeze non-config-space PCI operations. Let this fail silently * if e.g. there is no current freeze. */ - opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, 1, + opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, OPAL_PCI_DEFAULT_PE, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); /* @@ -299,7 +352,7 @@ opalpci_read_config(device_t dev, u_int * * XXX: Make this conditional on the existence of a freeze */ - opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, 1, + opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, OPAL_PCI_DEFAULT_PE, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); if (error != OPAL_SUCCESS) @@ -340,8 +393,23 @@ opalpci_write_config(device_t dev, u_int * Poking config state for non-existant devices can make * the host bridge hang up. Clear any errors. */ - opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, 1, - OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + opal_call(OPAL_PCI_EEH_FREEZE_CLEAR, sc->phb_id, + OPAL_PCI_DEFAULT_PE, OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); } } +static int +opalpci_setup_intr(device_t dev, device_t child, struct resource *r, + int flags, driver_filter_t *filter, driver_intr_t *ithread, + void *arg, void **cookiep) +{ + struct opalpci_softc *sc; + + sc = device_get_softc(dev); + opal_call(OPAL_PCI_SET_XIVE_PE, sc->phb_id, OPAL_PCI_DEFAULT_PE, + rman_get_start(r)); + + return BUS_SETUP_INTR(device_get_parent(dev), child, r, flags, filter, + ithread, arg, cookiep); +} +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607251824.u6PIOsG4032937>