1183370Simp/*- 2183370Simp * Copyright (c) 2007 Bruce M. Simpson. 3183370Simp * All rights reserved. 4183370Simp * 5183370Simp * Redistribution and use in source and binary forms, with or without 6183370Simp * modification, are permitted provided that the following conditions 7183370Simp * are met: 8183370Simp * 1. Redistributions of source code must retain the above copyright 9183370Simp * notice, this list of conditions and the following disclaimer. 10183370Simp * 2. Redistributions in binary form must reproduce the above copyright 11183370Simp * notice, this list of conditions and the following disclaimer in the 12183370Simp * documentation and/or other materials provided with the distribution. 13183370Simp * 14183370Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15183370Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16183370Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17183370Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18183370Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19183370Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20183370Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21183370Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22183370Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23183370Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24183370Simp * SUCH DAMAGE. 25183370Simp */ 26183370Simp 27183370Simp/* 28183370Simp * Driver to swallow up memory ranges reserved by CFE platform firmware. 29183370Simp * CFE on Sentry5 doesn't specify reserved ranges, so this is not useful 30183370Simp * at the present time. 31183370Simp * TODO: Don't attach this off nexus. 32183370Simp */ 33183370Simp 34183370Simp#include <sys/cdefs.h> 35183370Simp__FBSDID("$FreeBSD$"); 36183370Simp 37183370Simp#include <sys/param.h> 38183370Simp#include <sys/systm.h> 39183370Simp#include <sys/kernel.h> 40183370Simp#include <sys/socket.h> 41183370Simp 42183370Simp#include <sys/module.h> 43183370Simp#include <sys/bus.h> 44183370Simp 45183370Simp#include <machine/bus.h> 46183370Simp#include <machine/resource.h> 47183370Simp#include <sys/rman.h> 48183370Simp 49183370Simp#include <dev/cfe/cfe_api.h> 50183370Simp#include <dev/cfe/cfe_error.h> 51183370Simp 52183370Simp#define MAX_CFE_RESERVATIONS 16 53183370Simp 54183370Simpstruct cferes_softc { 55183370Simp int rnum; 56183370Simp int rid[MAX_CFE_RESERVATIONS]; 57183370Simp struct resource *res[MAX_CFE_RESERVATIONS]; 58183370Simp}; 59183370Simp 60183370Simpstatic int 61183370Simpcferes_probe(device_t dev) 62183370Simp{ 63183370Simp 64265999Sian return (BUS_PROBE_NOWILDCARD); 65183370Simp} 66183370Simp 67183370Simpstatic int 68183370Simpcferes_attach(device_t dev) 69183370Simp{ 70183370Simp 71183370Simp return (0); 72183370Simp} 73183370Simp 74183370Simpstatic void 75183370Simpcferes_identify(driver_t* driver, device_t parent) 76183370Simp{ 77183370Simp device_t child; 78183370Simp int i; 79183370Simp struct resource *res; 80183370Simp int result; 81183370Simp int rid; 82183370Simp struct cferes_softc *sc; 83183370Simp uint64_t addr, len, type; 84183370Simp 85183370Simp child = BUS_ADD_CHILD(parent, 100, "cferes", -1); 86183370Simp device_set_driver(child, driver); 87183370Simp sc = device_get_softc(child); 88183370Simp 89183370Simp sc->rnum = 0; 90183370Simp for (i = 0; i < ~0U; i++) { 91183370Simp result = cfe_enummem(i, CFE_FLG_FULL_ARENA, &addr, &len, &type); 92183370Simp if (result < 0) 93183370Simp break; 94183370Simp if (type != CFE_MI_RESERVED) { 95183370Simp if (bootverbose) 96183370Simp printf("%s: skipping non reserved range 0x%0jx(%jd)\n", 97183370Simp device_getnameunit(child), 98183370Simp (uintmax_t)addr, (uintmax_t)len); 99183370Simp continue; 100183370Simp } 101183370Simp 102183370Simp bus_set_resource(child, SYS_RES_MEMORY, sc->rnum, addr, len); 103183370Simp rid = sc->rnum; 104183370Simp res = bus_alloc_resource_any(child, SYS_RES_MEMORY, &rid, 0); 105183370Simp if (res == NULL) { 106183370Simp bus_delete_resource(child, SYS_RES_MEMORY, sc->rnum); 107183370Simp continue; 108183370Simp } 109183370Simp sc->rid[sc->rnum] = rid; 110183370Simp sc->res[sc->rnum] = res; 111183370Simp 112183370Simp sc->rnum++; 113183370Simp if (sc->rnum == MAX_CFE_RESERVATIONS) 114183370Simp break; 115183370Simp } 116183370Simp 117183370Simp if (sc->rnum == 0) { 118183370Simp device_delete_child(parent, child); 119183370Simp return; 120183370Simp } 121183370Simp 122183370Simp device_set_desc(child, "CFE reserved memory"); 123183370Simp} 124183370Simp 125183370Simpstatic int 126183370Simpcferes_detach(device_t dev) 127183370Simp{ 128183370Simp int i; 129183370Simp struct cferes_softc *sc = device_get_softc(dev); 130183370Simp 131183370Simp for (i = 0; i < sc->rnum; i++) { 132183370Simp bus_release_resource(dev, SYS_RES_MEMORY, sc->rid[i], 133183370Simp sc->res[i]); 134183370Simp } 135183370Simp 136183370Simp return (0); 137183370Simp} 138183370Simp 139183370Simpstatic device_method_t cferes_methods[] = { 140183370Simp /* Device interface */ 141183370Simp DEVMETHOD(device_identify, cferes_identify), 142183370Simp DEVMETHOD(device_probe, cferes_probe), 143183370Simp DEVMETHOD(device_attach, cferes_attach), 144183370Simp DEVMETHOD(device_detach, cferes_detach), 145183370Simp DEVMETHOD(device_shutdown, bus_generic_shutdown), 146183370Simp DEVMETHOD(device_suspend, bus_generic_suspend), 147183370Simp DEVMETHOD(device_resume, bus_generic_resume), 148183370Simp { 0, 0 } 149183370Simp}; 150183370Simp 151183370Simpstatic driver_t cferes_driver = { 152183370Simp "cferes", 153183370Simp cferes_methods, 154183370Simp sizeof (struct cferes_softc) 155183370Simp}; 156183370Simp 157183370Simpstatic devclass_t cferes_devclass; 158183370Simp 159183370SimpDRIVER_MODULE(cfe, nexus, cferes_driver, cferes_devclass, 0, 0); 160