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