nvram.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * c 2001 PPC 64 Team, IBM Corp
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. *
  9. * /dev/nvram driver for PPC64
  10. *
  11. * This perhaps should live in drivers/char
  12. */
  13. #include <linux/types.h>
  14. #include <linux/errno.h>
  15. #include <linux/init.h>
  16. #include <linux/spinlock.h>
  17. #include <asm/uaccess.h>
  18. #include <asm/nvram.h>
  19. #include <asm/rtas.h>
  20. #include <asm/prom.h>
  21. #include <asm/machdep.h>
  22. /* Max bytes to read/write in one go */
  23. #define NVRW_CNT 0x20
  24. static unsigned int nvram_size;
  25. static int nvram_fetch, nvram_store;
  26. static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
  27. static DEFINE_SPINLOCK(nvram_lock);
  28. struct err_log_info {
  29. int error_type;
  30. unsigned int seq_num;
  31. };
  32. struct nvram_os_partition {
  33. const char *name;
  34. int req_size; /* desired size, in bytes */
  35. int min_size; /* minimum acceptable size (0 means req_size) */
  36. long size; /* size of data portion of partition */
  37. long index; /* offset of data portion of partition */
  38. };
  39. static struct nvram_os_partition rtas_log_partition = {
  40. .name = "ibm,rtas-log",
  41. .req_size = 2079,
  42. .min_size = 1055,
  43. .index = -1
  44. };
  45. static const char *pseries_nvram_os_partitions[] = {
  46. "ibm,rtas-log",
  47. NULL
  48. };
  49. static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
  50. {
  51. unsigned int i;
  52. unsigned long len;
  53. int done;
  54. unsigned long flags;
  55. char *p = buf;
  56. if (nvram_size == 0 || nvram_fetch == RTAS_UNKNOWN_SERVICE)
  57. return -ENODEV;
  58. if (*index >= nvram_size)
  59. return 0;
  60. i = *index;
  61. if (i + count > nvram_size)
  62. count = nvram_size - i;
  63. spin_lock_irqsave(&nvram_lock, flags);
  64. for (; count != 0; count -= len) {
  65. len = count;
  66. if (len > NVRW_CNT)
  67. len = NVRW_CNT;
  68. if ((rtas_call(nvram_fetch, 3, 2, &done, i, __pa(nvram_buf),
  69. len) != 0) || len != done) {
  70. spin_unlock_irqrestore(&nvram_lock, flags);
  71. return -EIO;
  72. }
  73. memcpy(p, nvram_buf, len);
  74. p += len;
  75. i += len;
  76. }
  77. spin_unlock_irqrestore(&nvram_lock, flags);
  78. *index = i;
  79. return p - buf;
  80. }
  81. static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index)
  82. {
  83. unsigned int i;
  84. unsigned long len;
  85. int done;
  86. unsigned long flags;
  87. const char *p = buf;
  88. if (nvram_size == 0 || nvram_store == RTAS_UNKNOWN_SERVICE)
  89. return -ENODEV;
  90. if (*index >= nvram_size)
  91. return 0;
  92. i = *index;
  93. if (i + count > nvram_size)
  94. count = nvram_size - i;
  95. spin_lock_irqsave(&nvram_lock, flags);
  96. for (; count != 0; count -= len) {
  97. len = count;
  98. if (len > NVRW_CNT)
  99. len = NVRW_CNT;
  100. memcpy(nvram_buf, p, len);
  101. if ((rtas_call(nvram_store, 3, 2, &done, i, __pa(nvram_buf),
  102. len) != 0) || len != done) {
  103. spin_unlock_irqrestore(&nvram_lock, flags);
  104. return -EIO;
  105. }
  106. p += len;
  107. i += len;
  108. }
  109. spin_unlock_irqrestore(&nvram_lock, flags);
  110. *index = i;
  111. return p - buf;
  112. }
  113. static ssize_t pSeries_nvram_get_size(void)
  114. {
  115. return nvram_size ? nvram_size : -ENODEV;
  116. }
  117. /* nvram_write_os_partition, nvram_write_error_log
  118. *
  119. * We need to buffer the error logs into nvram to ensure that we have
  120. * the failure information to decode. If we have a severe error there
  121. * is no way to guarantee that the OS or the machine is in a state to
  122. * get back to user land and write the error to disk. For example if
  123. * the SCSI device driver causes a Machine Check by writing to a bad
  124. * IO address, there is no way of guaranteeing that the device driver
  125. * is in any state that is would also be able to write the error data
  126. * captured to disk, thus we buffer it in NVRAM for analysis on the
  127. * next boot.
  128. *
  129. * In NVRAM the partition containing the error log buffer will looks like:
  130. * Header (in bytes):
  131. * +-----------+----------+--------+------------+------------------+
  132. * | signature | checksum | length | name | data |
  133. * |0 |1 |2 3|4 15|16 length-1|
  134. * +-----------+----------+--------+------------+------------------+
  135. *
  136. * The 'data' section would look like (in bytes):
  137. * +--------------+------------+-----------------------------------+
  138. * | event_logged | sequence # | error log |
  139. * |0 3|4 7|8 error_log_size-1|
  140. * +--------------+------------+-----------------------------------+
  141. *
  142. * event_logged: 0 if event has not been logged to syslog, 1 if it has
  143. * sequence #: The unique sequence # for each event. (until it wraps)
  144. * error log: The error log from event_scan
  145. */
  146. int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
  147. int length, unsigned int err_type, unsigned int error_log_cnt)
  148. {
  149. int rc;
  150. loff_t tmp_index;
  151. struct err_log_info info;
  152. if (part->index == -1) {
  153. return -ESPIPE;
  154. }
  155. if (length > part->size) {
  156. length = part->size;
  157. }
  158. info.error_type = err_type;
  159. info.seq_num = error_log_cnt;
  160. tmp_index = part->index;
  161. rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
  162. if (rc <= 0) {
  163. pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
  164. return rc;
  165. }
  166. rc = ppc_md.nvram_write(buff, length, &tmp_index);
  167. if (rc <= 0) {
  168. pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
  169. return rc;
  170. }
  171. return 0;
  172. }
  173. int nvram_write_error_log(char * buff, int length,
  174. unsigned int err_type, unsigned int error_log_cnt)
  175. {
  176. return nvram_write_os_partition(&rtas_log_partition, buff, length,
  177. err_type, error_log_cnt);
  178. }
  179. /* nvram_read_error_log
  180. *
  181. * Reads nvram for error log for at most 'length'
  182. */
  183. int nvram_read_error_log(char * buff, int length,
  184. unsigned int * err_type, unsigned int * error_log_cnt)
  185. {
  186. int rc;
  187. loff_t tmp_index;
  188. struct err_log_info info;
  189. if (rtas_log_partition.index == -1)
  190. return -1;
  191. if (length > rtas_log_partition.size)
  192. length = rtas_log_partition.size;
  193. tmp_index = rtas_log_partition.index;
  194. rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index);
  195. if (rc <= 0) {
  196. printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
  197. return rc;
  198. }
  199. rc = ppc_md.nvram_read(buff, length, &tmp_index);
  200. if (rc <= 0) {
  201. printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
  202. return rc;
  203. }
  204. *error_log_cnt = info.seq_num;
  205. *err_type = info.error_type;
  206. return 0;
  207. }
  208. /* This doesn't actually zero anything, but it sets the event_logged
  209. * word to tell that this event is safely in syslog.
  210. */
  211. int nvram_clear_error_log(void)
  212. {
  213. loff_t tmp_index;
  214. int clear_word = ERR_FLAG_ALREADY_LOGGED;
  215. int rc;
  216. if (rtas_log_partition.index == -1)
  217. return -1;
  218. tmp_index = rtas_log_partition.index;
  219. rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
  220. if (rc <= 0) {
  221. printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
  222. return rc;
  223. }
  224. return 0;
  225. }
  226. /* pseries_nvram_init_os_partition
  227. *
  228. * This sets up a partition with an "OS" signature.
  229. *
  230. * The general strategy is the following:
  231. * 1.) If a partition with the indicated name already exists...
  232. * - If it's large enough, use it.
  233. * - Otherwise, recycle it and keep going.
  234. * 2.) Search for a free partition that is large enough.
  235. * 3.) If there's not a free partition large enough, recycle any obsolete
  236. * OS partitions and try again.
  237. * 4.) Will first try getting a chunk that will satisfy the requested size.
  238. * 5.) If a chunk of the requested size cannot be allocated, then try finding
  239. * a chunk that will satisfy the minum needed.
  240. *
  241. * Returns 0 on success, else -1.
  242. */
  243. static int __init pseries_nvram_init_os_partition(struct nvram_os_partition
  244. *part)
  245. {
  246. loff_t p;
  247. int size;
  248. /* Scan nvram for partitions */
  249. nvram_scan_partitions();
  250. /* Look for ours */
  251. p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size);
  252. /* Found one but too small, remove it */
  253. if (p && size < part->min_size) {
  254. pr_info("nvram: Found too small %s partition,"
  255. " removing it...\n", part->name);
  256. nvram_remove_partition(part->name, NVRAM_SIG_OS, NULL);
  257. p = 0;
  258. }
  259. /* Create one if we didn't find */
  260. if (!p) {
  261. p = nvram_create_partition(part->name, NVRAM_SIG_OS,
  262. part->req_size, part->min_size);
  263. if (p == -ENOSPC) {
  264. pr_info("nvram: No room to create %s partition, "
  265. "deleting any obsolete OS partitions...\n",
  266. part->name);
  267. nvram_remove_partition(NULL, NVRAM_SIG_OS,
  268. pseries_nvram_os_partitions);
  269. p = nvram_create_partition(part->name, NVRAM_SIG_OS,
  270. part->req_size, part->min_size);
  271. }
  272. }
  273. if (p <= 0) {
  274. pr_err("nvram: Failed to find or create %s"
  275. " partition, err %d\n", part->name, (int)p);
  276. return -1;
  277. }
  278. part->index = p;
  279. part->size = nvram_get_partition_size(p) - sizeof(struct err_log_info);
  280. return 0;
  281. }
  282. static int __init pseries_nvram_init_log_partitions(void)
  283. {
  284. (void) pseries_nvram_init_os_partition(&rtas_log_partition);
  285. return 0;
  286. }
  287. machine_arch_initcall(pseries, pseries_nvram_init_log_partitions);
  288. int __init pSeries_nvram_init(void)
  289. {
  290. struct device_node *nvram;
  291. const unsigned int *nbytes_p;
  292. unsigned int proplen;
  293. nvram = of_find_node_by_type(NULL, "nvram");
  294. if (nvram == NULL)
  295. return -ENODEV;
  296. nbytes_p = of_get_property(nvram, "#bytes", &proplen);
  297. if (nbytes_p == NULL || proplen != sizeof(unsigned int)) {
  298. of_node_put(nvram);
  299. return -EIO;
  300. }
  301. nvram_size = *nbytes_p;
  302. nvram_fetch = rtas_token("nvram-fetch");
  303. nvram_store = rtas_token("nvram-store");
  304. printk(KERN_INFO "PPC64 nvram contains %d bytes\n", nvram_size);
  305. of_node_put(nvram);
  306. ppc_md.nvram_read = pSeries_nvram_read;
  307. ppc_md.nvram_write = pSeries_nvram_write;
  308. ppc_md.nvram_size = pSeries_nvram_get_size;
  309. return 0;
  310. }