1ae36cccdSWarner Losh /*- 2*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*718cf2ccSPedro F. Giffuni * 4ae36cccdSWarner Losh * Copyright (c) 2007 Bruce M. Simpson. 5ae36cccdSWarner Losh * All rights reserved. 6ae36cccdSWarner Losh * 7ae36cccdSWarner Losh * Redistribution and use in source and binary forms, with or without 8ae36cccdSWarner Losh * modification, are permitted provided that the following conditions 9ae36cccdSWarner Losh * are met: 10ae36cccdSWarner Losh * 1. Redistributions of source code must retain the above copyright 11ae36cccdSWarner Losh * notice, this list of conditions and the following disclaimer. 12ae36cccdSWarner Losh * 2. Redistributions in binary form must reproduce the above copyright 13ae36cccdSWarner Losh * notice, this list of conditions and the following disclaimer in the 14ae36cccdSWarner Losh * documentation and/or other materials provided with the distribution. 15ae36cccdSWarner Losh * 16ae36cccdSWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17ae36cccdSWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18ae36cccdSWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ae36cccdSWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20ae36cccdSWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ae36cccdSWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22ae36cccdSWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23ae36cccdSWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24ae36cccdSWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25ae36cccdSWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26ae36cccdSWarner Losh * SUCH DAMAGE. 27ae36cccdSWarner Losh */ 28ae36cccdSWarner Losh 29ae36cccdSWarner Losh /* 30ae36cccdSWarner Losh * Driver to swallow up memory ranges reserved by CFE platform firmware. 31ae36cccdSWarner Losh * CFE on Sentry5 doesn't specify reserved ranges, so this is not useful 32ae36cccdSWarner Losh * at the present time. 33ae36cccdSWarner Losh * TODO: Don't attach this off nexus. 34ae36cccdSWarner Losh */ 35ae36cccdSWarner Losh 36ae36cccdSWarner Losh #include <sys/cdefs.h> 37ae36cccdSWarner Losh __FBSDID("$FreeBSD$"); 38ae36cccdSWarner Losh 39ae36cccdSWarner Losh #include <sys/param.h> 40ae36cccdSWarner Losh #include <sys/systm.h> 41ae36cccdSWarner Losh #include <sys/kernel.h> 42ae36cccdSWarner Losh #include <sys/socket.h> 43ae36cccdSWarner Losh 44ae36cccdSWarner Losh #include <sys/module.h> 45ae36cccdSWarner Losh #include <sys/bus.h> 46ae36cccdSWarner Losh 47ae36cccdSWarner Losh #include <machine/bus.h> 48ae36cccdSWarner Losh #include <machine/resource.h> 49ae36cccdSWarner Losh #include <sys/rman.h> 50ae36cccdSWarner Losh 51ae36cccdSWarner Losh #include <dev/cfe/cfe_api.h> 52ae36cccdSWarner Losh #include <dev/cfe/cfe_error.h> 53ae36cccdSWarner Losh 54ae36cccdSWarner Losh #define MAX_CFE_RESERVATIONS 16 55ae36cccdSWarner Losh 56ae36cccdSWarner Losh struct cferes_softc { 57ae36cccdSWarner Losh int rnum; 58ae36cccdSWarner Losh int rid[MAX_CFE_RESERVATIONS]; 59ae36cccdSWarner Losh struct resource *res[MAX_CFE_RESERVATIONS]; 60ae36cccdSWarner Losh }; 61ae36cccdSWarner Losh 62ae36cccdSWarner Losh static int 63ae36cccdSWarner Losh cferes_probe(device_t dev) 64ae36cccdSWarner Losh { 65ae36cccdSWarner Losh 66feeec74dSNathan Whitehorn return (BUS_PROBE_NOWILDCARD); 67ae36cccdSWarner Losh } 68ae36cccdSWarner Losh 69ae36cccdSWarner Losh static int 70ae36cccdSWarner Losh cferes_attach(device_t dev) 71ae36cccdSWarner Losh { 72ae36cccdSWarner Losh 73ae36cccdSWarner Losh return (0); 74ae36cccdSWarner Losh } 75ae36cccdSWarner Losh 76ae36cccdSWarner Losh static void 77ae36cccdSWarner Losh cferes_identify(driver_t* driver, device_t parent) 78ae36cccdSWarner Losh { 79ae36cccdSWarner Losh device_t child; 80ae36cccdSWarner Losh int i; 81ae36cccdSWarner Losh struct resource *res; 82ae36cccdSWarner Losh int result; 83ae36cccdSWarner Losh int rid; 84ae36cccdSWarner Losh struct cferes_softc *sc; 85ae36cccdSWarner Losh uint64_t addr, len, type; 86ae36cccdSWarner Losh 87ae36cccdSWarner Losh child = BUS_ADD_CHILD(parent, 100, "cferes", -1); 88ae36cccdSWarner Losh device_set_driver(child, driver); 89ae36cccdSWarner Losh sc = device_get_softc(child); 90ae36cccdSWarner Losh 91ae36cccdSWarner Losh sc->rnum = 0; 92ae36cccdSWarner Losh for (i = 0; i < ~0U; i++) { 93ae36cccdSWarner Losh result = cfe_enummem(i, CFE_FLG_FULL_ARENA, &addr, &len, &type); 94ae36cccdSWarner Losh if (result < 0) 95ae36cccdSWarner Losh break; 96ae36cccdSWarner Losh if (type != CFE_MI_RESERVED) { 97ae36cccdSWarner Losh if (bootverbose) 98ae36cccdSWarner Losh printf("%s: skipping non reserved range 0x%0jx(%jd)\n", 99ae36cccdSWarner Losh device_getnameunit(child), 100ae36cccdSWarner Losh (uintmax_t)addr, (uintmax_t)len); 101ae36cccdSWarner Losh continue; 102ae36cccdSWarner Losh } 103ae36cccdSWarner Losh 104ae36cccdSWarner Losh bus_set_resource(child, SYS_RES_MEMORY, sc->rnum, addr, len); 105ae36cccdSWarner Losh rid = sc->rnum; 106ae36cccdSWarner Losh res = bus_alloc_resource_any(child, SYS_RES_MEMORY, &rid, 0); 107ae36cccdSWarner Losh if (res == NULL) { 108ae36cccdSWarner Losh bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum); 109ae36cccdSWarner Losh continue; 110ae36cccdSWarner Losh } 111ae36cccdSWarner Losh sc->rid[sc->rnum] = rid; 112ae36cccdSWarner Losh sc->res[sc->rnum] = res; 113ae36cccdSWarner Losh 114ae36cccdSWarner Losh sc->rnum++; 115ae36cccdSWarner Losh if (sc->rnum == MAX_CFE_RESERVATIONS) 116ae36cccdSWarner Losh break; 117ae36cccdSWarner Losh } 118ae36cccdSWarner Losh 119ae36cccdSWarner Losh if (sc->rnum == 0) { 120ae36cccdSWarner Losh device_delete_child(parent, child); 121ae36cccdSWarner Losh return; 122ae36cccdSWarner Losh } 123ae36cccdSWarner Losh 124ae36cccdSWarner Losh device_set_desc(child, "CFE reserved memory"); 125ae36cccdSWarner Losh } 126ae36cccdSWarner Losh 127ae36cccdSWarner Losh static int 128ae36cccdSWarner Losh cferes_detach(device_t dev) 129ae36cccdSWarner Losh { 130ae36cccdSWarner Losh int i; 131ae36cccdSWarner Losh struct cferes_softc *sc = device_get_softc(dev); 132ae36cccdSWarner Losh 133ae36cccdSWarner Losh for (i = 0; i < sc->rnum; i++) { 134ae36cccdSWarner Losh bus_release_resource(dev, SYS_RES_MEMORY, sc->rid[i], 135ae36cccdSWarner Losh sc->res[i]); 136ae36cccdSWarner Losh } 137ae36cccdSWarner Losh 138ae36cccdSWarner Losh return (0); 139ae36cccdSWarner Losh } 140ae36cccdSWarner Losh 141ae36cccdSWarner Losh static device_method_t cferes_methods[] = { 142ae36cccdSWarner Losh /* Device interface */ 143ae36cccdSWarner Losh DEVMETHOD(device_identify, cferes_identify), 144ae36cccdSWarner Losh DEVMETHOD(device_probe, cferes_probe), 145ae36cccdSWarner Losh DEVMETHOD(device_attach, cferes_attach), 146ae36cccdSWarner Losh DEVMETHOD(device_detach, cferes_detach), 147ae36cccdSWarner Losh DEVMETHOD(device_shutdown, bus_generic_shutdown), 148ae36cccdSWarner Losh DEVMETHOD(device_suspend, bus_generic_suspend), 149ae36cccdSWarner Losh DEVMETHOD(device_resume, bus_generic_resume), 150ae36cccdSWarner Losh { 0, 0 } 151ae36cccdSWarner Losh }; 152ae36cccdSWarner Losh 153ae36cccdSWarner Losh static driver_t cferes_driver = { 154ae36cccdSWarner Losh "cferes", 155ae36cccdSWarner Losh cferes_methods, 156ae36cccdSWarner Losh sizeof (struct cferes_softc) 157ae36cccdSWarner Losh }; 158ae36cccdSWarner Losh 159ae36cccdSWarner Losh static devclass_t cferes_devclass; 160ae36cccdSWarner Losh 161ae36cccdSWarner Losh DRIVER_MODULE(cfe, nexus, cferes_driver, cferes_devclass, 0, 0); 162