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