SHARE
TWEET

chmeee

a guest Sep 11th, 2019 104 in 24 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. commit b9879e693631f5842e63845c53f2fd29aae1a6c8
  2. Author: Justin Hibbits <chmeeedalf@gmail.com>
  3. Date:   Wed Sep 11 14:26:09 2019
  4.  
  5.     powerpc/powernv: Add OPAL NVRAM driver
  6.    
  7.     Add a very basic OPAL NVRAM driver, which can be used by the IBM
  8.     power-utils toolkit for reading and writing NVRAM on powernv systems.
  9.  
  10. diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
  11. index f702cc0ef8f..267cd84b829 100644
  12. --- a/sys/conf/files.powerpc
  13. +++ b/sys/conf/files.powerpc
  14. @@ -192,6 +192,7 @@ powerpc/powernv/opal_flash.c    optional    powernv opalflash
  15.  powerpc/powernv/opal_hmi.c optional    powernv
  16.  powerpc/powernv/opal_i2c.c optional    iicbus fdt powernv
  17.  powerpc/powernv/opal_i2cm.c    optional    iicbus fdt powernv
  18. +powerpc/powernv/opal_nvram.c   optional    powernv nvram
  19.  powerpc/powernv/opal_pci.c optional    powernv pci
  20.  powerpc/powernv/opal_sensor.c  optional    powernv
  21.  powerpc/powernv/opalcall.S optional    powernv
  22. diff --git a/sys/modules/opal_nvram/Makefile b/sys/modules/opal_nvram/Makefile
  23. new file mode 100644
  24. index 00000000000..aca711070fc
  25. --- /dev/null
  26. +++ b/sys/modules/opal_nvram/Makefile
  27. @@ -0,0 +1,10 @@
  28. +# $FreeBSD$
  29. +
  30. +.PATH: ${SRCTOP}/sys/powerpc/powernv
  31. +
  32. +KMOD=  opal_nvram
  33. +SRCS=  opal_nvram.c
  34. +SRCS+= bus_if.h device_if.h
  35. +SRCS+= ofw_bus_if.h
  36. +
  37. +.include <bsd.kmod.mk>
  38. diff --git a/sys/powerpc/powernv/opal.h b/sys/powerpc/powernv/opal.h
  39. index b519316c066..b1137ca1ce2 100644
  40. --- a/sys/powerpc/powernv/opal.h
  41. +++ b/sys/powerpc/powernv/opal.h
  42. @@ -45,6 +45,8 @@ int opal_call(uint64_t token, ...);
  43.  #define OPAL_RTC_WRITE         4
  44.  #define    OPAL_CEC_POWER_DOWN     5
  45.  #define    OPAL_CEC_REBOOT         6
  46. +#define    OPAL_READ_NVRAM         7
  47. +#define    OPAL_WRITE_NVRAM        8
  48.  #define    OPAL_HANDLE_INTERRUPT       9
  49.  #define    OPAL_POLL_EVENTS        10
  50.  #define    OPAL_PCI_CONFIG_READ_BYTE   13
  51. diff --git a/sys/powerpc/powernv/opal_nvram.c b/sys/powerpc/powernv/opal_nvram.c
  52. new file mode 100644
  53. index 00000000000..bcebb528a9f
  54. --- /dev/null
  55. +++ b/sys/powerpc/powernv/opal_nvram.c
  56. @@ -0,0 +1,273 @@
  57. +/*-
  58. + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  59. + *
  60. + * Copyright (c) 2006 Maxim Sobolev <sobomax@FreeBSD.org>
  61. + * All rights reserved.
  62. + *
  63. + * Redistribution and use in source and binary forms, with or without
  64. + * modification, are permitted provided that the following conditions
  65. + * are met:
  66. + * 1. Redistributions of source code must retain the above copyright
  67. + *    notice, this list of conditions and the following disclaimer.
  68. + * 2. Redistributions in binary form must reproduce the above copyright
  69. + *    notice, this list of conditions and the following disclaimer in the
  70. + *    documentation and/or other materials provided with the distribution.
  71. + *
  72. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  73. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75. + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  76. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  78. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  79. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  80. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  81. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  82. + * POSSIBILITY OF SUCH DAMAGE.
  83. + *
  84. + * $FreeBSD$
  85. + */
  86. +
  87. +#include <sys/param.h>
  88. +#include <sys/systm.h>
  89. +#include <sys/module.h>
  90. +#include <sys/bus.h>
  91. +#include <sys/conf.h>
  92. +#include <sys/disk.h>
  93. +#include <sys/kernel.h>
  94. +#include <sys/uio.h>
  95. +
  96. +#include <dev/ofw/openfirm.h>
  97. +#include <dev/ofw/ofw_bus.h>
  98. +#include <dev/ofw/ofw_bus_subr.h>
  99. +
  100. +#include <machine/bus.h>
  101. +#include <machine/md_var.h>
  102. +#include <machine/pio.h>
  103. +#include <machine/resource.h>
  104. +
  105. +#include "opal.h"
  106. +
  107. +#include <sys/rman.h>
  108. +
  109. +#include <vm/vm.h>
  110. +#include <vm/pmap.h>
  111. +
  112. +struct chrp_header {
  113. +   uint8_t     sig;
  114. +   uint8_t     csum;
  115. +   uint16_t    len;
  116. +   char        name[12];
  117. +};
  118. +
  119. +struct opal_nvram_softc {
  120. +   device_t     sc_dev;
  121. +   phandle_t    sc_node;
  122. +   uint32_t     sc_size;
  123. +   uint8_t     *sc_buf;
  124. +   vm_paddr_t   sc_buf_phys;
  125. +
  126. +   struct cdev     *sc_cdev;
  127. +   int      sc_isopen;
  128. +};
  129. +
  130. +/*
  131. + * Device interface.
  132. + */
  133. +static int     opal_nvram_probe(device_t);
  134. +static int     opal_nvram_attach(device_t);
  135. +static int     opal_nvram_detach(device_t);
  136. +
  137. +/*
  138. + * Driver methods.
  139. + */
  140. +static device_method_t opal_nvram_methods[] = {
  141. +   /* Device interface */
  142. +   DEVMETHOD(device_probe,     opal_nvram_probe),
  143. +   DEVMETHOD(device_attach,    opal_nvram_attach),
  144. +   DEVMETHOD(device_detach,    opal_nvram_detach),
  145. +
  146. +   { 0, 0 }
  147. +};
  148. +
  149. +static driver_t    opal_nvram_driver = {
  150. +   "opal_nvram",
  151. +   opal_nvram_methods,
  152. +   sizeof(struct opal_nvram_softc)
  153. +};
  154. +
  155. +static devclass_t opal_nvram_devclass;
  156. +
  157. +DRIVER_MODULE(opal_nvram, ofwbus, opal_nvram_driver, opal_nvram_devclass, 0, 0);
  158. +
  159. +/*
  160. + * Cdev methods.
  161. + */
  162. +
  163. +static d_open_t    opal_nvram_open;
  164. +static d_close_t   opal_nvram_close;
  165. +static d_read_t    opal_nvram_read;
  166. +static d_write_t   opal_nvram_write;
  167. +static d_ioctl_t   opal_nvram_ioctl;
  168. +
  169. +static struct cdevsw opal_nvram_cdevsw = {
  170. +   .d_version =    D_VERSION,
  171. +   .d_flags =  D_NEEDGIANT,
  172. +   .d_open =   opal_nvram_open,
  173. +   .d_close =  opal_nvram_close,
  174. +   .d_read =   opal_nvram_read,
  175. +   .d_write =  opal_nvram_write,
  176. +   .d_ioctl =  opal_nvram_ioctl,
  177. +   .d_name =   "nvram",
  178. +};
  179. +
  180. +static int
  181. +opal_nvram_probe(device_t dev)
  182. +{
  183. +
  184. +   if (!ofw_bus_is_compatible(dev, "ibm,opal-nvram"))
  185. +       return (ENXIO);
  186. +
  187. +   device_set_desc(dev, "OPAL NVRAM");
  188. +   return (0);
  189. +}
  190. +
  191. +static int
  192. +opal_nvram_attach(device_t dev)
  193. +{
  194. +   struct opal_nvram_softc *sc;
  195. +   phandle_t node;
  196. +   int err;
  197. +
  198. +   node = ofw_bus_get_node(dev);
  199. +   sc = device_get_softc(dev);
  200. +
  201. +   sc->sc_dev = dev;
  202. +   sc->sc_node = node;
  203. +
  204. +   err = OF_getencprop(node, "#bytes", &sc->sc_size,
  205. +       sizeof(sc->sc_size));
  206. +
  207. +   if (err < 0)
  208. +       return (ENXIO);
  209. +
  210. +   sc->sc_buf = contigmalloc(2 * PAGE_SIZE, M_DEVBUF, M_WAITOK,
  211. +       0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
  212. +   sc->sc_buf_phys = pmap_kextract((vm_offset_t)sc->sc_buf);
  213. +   sc->sc_cdev = make_dev(&opal_nvram_cdevsw, 0, 0, 0, 0600,
  214. +       "nvram");
  215. +   sc->sc_cdev->si_drv1 = sc;
  216. +
  217. +   return 0;
  218. +}
  219. +
  220. +static int
  221. +opal_nvram_detach(device_t dev)
  222. +{
  223. +   struct opal_nvram_softc *sc;
  224. +
  225. +   sc = device_get_softc(dev);
  226. +
  227. +   if (sc->sc_cdev != NULL)
  228. +       destroy_dev(sc->sc_cdev);
  229. +  
  230. +   return 0;
  231. +}
  232. +
  233. +static int
  234. +opal_nvram_open(struct cdev *dev, int flags, int fmt, struct thread *td)
  235. +{
  236. +   struct opal_nvram_softc *sc = dev->si_drv1;
  237. +
  238. +   if (sc->sc_isopen)
  239. +       return EBUSY;
  240. +   sc->sc_isopen = 1;
  241. +   return 0;
  242. +}
  243. +
  244. +static int
  245. +opal_nvram_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
  246. +{
  247. +   struct opal_nvram_softc *sc = dev->si_drv1;
  248. +
  249. +   sc->sc_isopen = 0;
  250. +   return 0;
  251. +}
  252. +
  253. +static int
  254. +opal_nvram_read(struct cdev *dev, struct uio *uio, int ioflag)
  255. +{
  256. +   int rv, amnt, data_available;
  257. +   struct opal_nvram_softc *sc = dev->si_drv1;
  258. +
  259. +   rv = 0;
  260. +   while (uio->uio_resid > 0) {
  261. +       amnt = MIN(uio->uio_resid, sc->sc_size - uio->uio_offset);
  262. +       if (amnt == 0)
  263. +           break;
  264. +
  265. +       rv = opal_call(OPAL_READ_NVRAM, sc->sc_buf_phys,
  266. +           amnt, uio->uio_offset);
  267. +       if (rv != OPAL_SUCCESS) {
  268. +           switch (rv) {
  269. +           case OPAL_HARDWARE:
  270. +               rv = EIO;
  271. +               break;
  272. +           case OPAL_PARAMETER:
  273. +               rv = EINVAL;
  274. +               break;
  275. +           }
  276. +           break;
  277. +       }
  278. +       rv = uiomove(sc->sc_buf, amnt, uio);
  279. +       if (rv != 0)
  280. +           break;
  281. +   }
  282. +   return rv;
  283. +}
  284. +
  285. +static int
  286. +opal_nvram_write(struct cdev *dev, struct uio *uio, int ioflag)
  287. +{
  288. +   int rv, amnt;
  289. +   struct opal_nvram_softc *sc = dev->si_drv1;
  290. +
  291. +   rv = 0;
  292. +   while (uio->uio_resid > 0) {
  293. +       amnt = MIN(uio->uio_resid, sc->sc_size - uio->uio_offset);
  294. +       if (amnt == 0) {
  295. +           rv = ENOSPC;
  296. +           break;
  297. +       }
  298. +       rv = uiomove(sc->sc_buf, amnt, uio);
  299. +       if (rv != 0)
  300. +           break;
  301. +       rv = opal_call(OPAL_WRITE_NVRAM, sc->sc_buf_phys, amnt,
  302. +           uio->uio_offset);
  303. +       if (rv != OPAL_SUCCESS) {
  304. +           switch (rv) {
  305. +           case OPAL_HARDWARE:
  306. +               rv = EIO;
  307. +               break;
  308. +           case OPAL_PARAMETER:
  309. +               rv = EINVAL;
  310. +               break;
  311. +           }
  312. +           break;
  313. +       }
  314. +   }
  315. +   return rv;
  316. +}
  317. +
  318. +static int
  319. +opal_nvram_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
  320. +    struct thread *td)
  321. +{
  322. +   struct opal_nvram_softc *sc = dev->si_drv1;
  323. +
  324. +   switch (cmd) {
  325. +   case DIOCGMEDIASIZE:
  326. +       return (sc->sc_size);
  327. +   }
  328. +   return (EINVAL);
  329. +}
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top