repository.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. /*
  2. * PS3 repository routines.
  3. *
  4. * Copyright (C) 2006 Sony Computer Entertainment Inc.
  5. * Copyright 2006 Sony Corp.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <asm/ps3.h>
  21. #include <asm/lv1call.h>
  22. enum ps3_vendor_id {
  23. PS3_VENDOR_ID_NONE = 0,
  24. PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
  25. };
  26. enum ps3_lpar_id {
  27. PS3_LPAR_ID_CURRENT = 0,
  28. PS3_LPAR_ID_PME = 1,
  29. };
  30. #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
  31. static void _dump_field(const char *hdr, u64 n, const char* func, int line)
  32. {
  33. #if defined(DEBUG)
  34. char s[16];
  35. const char *const in = (const char *)&n;
  36. unsigned int i;
  37. for (i = 0; i < 8; i++)
  38. s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
  39. s[i] = 0;
  40. pr_debug("%s:%d: %s%016lx : %s\n", func, line, hdr, n, s);
  41. #endif
  42. }
  43. #define dump_node_name(_a, _b, _c, _d, _e) \
  44. _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
  45. static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
  46. u64 n4, const char* func, int line)
  47. {
  48. pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
  49. _dump_field("n1: ", n1, func, line);
  50. _dump_field("n2: ", n2, func, line);
  51. _dump_field("n3: ", n3, func, line);
  52. _dump_field("n4: ", n4, func, line);
  53. }
  54. #define dump_node(_a, _b, _c, _d, _e, _f, _g) \
  55. _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
  56. static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
  57. u64 v1, u64 v2, const char* func, int line)
  58. {
  59. pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
  60. _dump_field("n1: ", n1, func, line);
  61. _dump_field("n2: ", n2, func, line);
  62. _dump_field("n3: ", n3, func, line);
  63. _dump_field("n4: ", n4, func, line);
  64. pr_debug("%s:%d: v1: %016lx\n", func, line, v1);
  65. pr_debug("%s:%d: v2: %016lx\n", func, line, v2);
  66. }
  67. /**
  68. * make_first_field - Make the first field of a repository node name.
  69. * @text: Text portion of the field.
  70. * @index: Numeric index portion of the field. Use zero for 'don't care'.
  71. *
  72. * This routine sets the vendor id to zero (non-vendor specific).
  73. * Returns field value.
  74. */
  75. static u64 make_first_field(const char *text, u64 index)
  76. {
  77. u64 n;
  78. strncpy((char *)&n, text, 8);
  79. return PS3_VENDOR_ID_NONE + (n >> 32) + index;
  80. }
  81. /**
  82. * make_field - Make subsequent fields of a repository node name.
  83. * @text: Text portion of the field. Use "" for 'don't care'.
  84. * @index: Numeric index portion of the field. Use zero for 'don't care'.
  85. *
  86. * Returns field value.
  87. */
  88. static u64 make_field(const char *text, u64 index)
  89. {
  90. u64 n;
  91. strncpy((char *)&n, text, 8);
  92. return n + index;
  93. }
  94. /**
  95. * read_node - Read a repository node from raw fields.
  96. * @n1: First field of node name.
  97. * @n2: Second field of node name. Use zero for 'don't care'.
  98. * @n3: Third field of node name. Use zero for 'don't care'.
  99. * @n4: Fourth field of node name. Use zero for 'don't care'.
  100. * @v1: First repository value (high word).
  101. * @v2: Second repository value (low word). Optional parameter, use zero
  102. * for 'don't care'.
  103. */
  104. static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
  105. u64 *_v1, u64 *_v2)
  106. {
  107. int result;
  108. u64 v1;
  109. u64 v2;
  110. if (lpar_id == PS3_LPAR_ID_CURRENT) {
  111. u64 id;
  112. lv1_get_logical_partition_id(&id);
  113. lpar_id = id;
  114. }
  115. result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1,
  116. &v2);
  117. if (result) {
  118. pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
  119. __func__, __LINE__, ps3_result(result));
  120. dump_node_name(lpar_id, n1, n2, n3, n4);
  121. return result;
  122. }
  123. dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
  124. if (_v1)
  125. *_v1 = v1;
  126. if (_v2)
  127. *_v2 = v2;
  128. if (v1 && !_v1)
  129. pr_debug("%s:%d: warning: discarding non-zero v1: %016lx\n",
  130. __func__, __LINE__, v1);
  131. if (v2 && !_v2)
  132. pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
  133. __func__, __LINE__, v2);
  134. return result;
  135. }
  136. int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
  137. u64 *value)
  138. {
  139. return read_node(PS3_LPAR_ID_PME,
  140. make_first_field("bus", bus_index),
  141. make_field(bus_str, 0),
  142. 0, 0,
  143. value, 0);
  144. }
  145. int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
  146. {
  147. int result;
  148. u64 v1;
  149. u64 v2; /* unused */
  150. result = read_node(PS3_LPAR_ID_PME,
  151. make_first_field("bus", bus_index),
  152. make_field("id", 0),
  153. 0, 0,
  154. &v1, &v2);
  155. *bus_id = v1;
  156. return result;
  157. }
  158. int ps3_repository_read_bus_type(unsigned int bus_index,
  159. enum ps3_bus_type *bus_type)
  160. {
  161. int result;
  162. u64 v1;
  163. result = read_node(PS3_LPAR_ID_PME,
  164. make_first_field("bus", bus_index),
  165. make_field("type", 0),
  166. 0, 0,
  167. &v1, 0);
  168. *bus_type = v1;
  169. return result;
  170. }
  171. int ps3_repository_read_bus_num_dev(unsigned int bus_index,
  172. unsigned int *num_dev)
  173. {
  174. int result;
  175. u64 v1;
  176. result = read_node(PS3_LPAR_ID_PME,
  177. make_first_field("bus", bus_index),
  178. make_field("num_dev", 0),
  179. 0, 0,
  180. &v1, 0);
  181. *num_dev = v1;
  182. return result;
  183. }
  184. int ps3_repository_read_dev_str(unsigned int bus_index,
  185. unsigned int dev_index, const char *dev_str, u64 *value)
  186. {
  187. return read_node(PS3_LPAR_ID_PME,
  188. make_first_field("bus", bus_index),
  189. make_field("dev", dev_index),
  190. make_field(dev_str, 0),
  191. 0,
  192. value, 0);
  193. }
  194. int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
  195. unsigned int *dev_id)
  196. {
  197. int result;
  198. u64 v1;
  199. result = read_node(PS3_LPAR_ID_PME,
  200. make_first_field("bus", bus_index),
  201. make_field("dev", dev_index),
  202. make_field("id", 0),
  203. 0,
  204. &v1, 0);
  205. *dev_id = v1;
  206. return result;
  207. }
  208. int ps3_repository_read_dev_type(unsigned int bus_index,
  209. unsigned int dev_index, enum ps3_dev_type *dev_type)
  210. {
  211. int result;
  212. u64 v1;
  213. result = read_node(PS3_LPAR_ID_PME,
  214. make_first_field("bus", bus_index),
  215. make_field("dev", dev_index),
  216. make_field("type", 0),
  217. 0,
  218. &v1, 0);
  219. *dev_type = v1;
  220. return result;
  221. }
  222. int ps3_repository_read_dev_intr(unsigned int bus_index,
  223. unsigned int dev_index, unsigned int intr_index,
  224. enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id)
  225. {
  226. int result;
  227. u64 v1;
  228. u64 v2;
  229. result = read_node(PS3_LPAR_ID_PME,
  230. make_first_field("bus", bus_index),
  231. make_field("dev", dev_index),
  232. make_field("intr", intr_index),
  233. 0,
  234. &v1, &v2);
  235. *intr_type = v1;
  236. *interrupt_id = v2;
  237. return result;
  238. }
  239. int ps3_repository_read_dev_reg_type(unsigned int bus_index,
  240. unsigned int dev_index, unsigned int reg_index,
  241. enum ps3_reg_type *reg_type)
  242. {
  243. int result;
  244. u64 v1;
  245. result = read_node(PS3_LPAR_ID_PME,
  246. make_first_field("bus", bus_index),
  247. make_field("dev", dev_index),
  248. make_field("reg", reg_index),
  249. make_field("type", 0),
  250. &v1, 0);
  251. *reg_type = v1;
  252. return result;
  253. }
  254. int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
  255. unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
  256. {
  257. return read_node(PS3_LPAR_ID_PME,
  258. make_first_field("bus", bus_index),
  259. make_field("dev", dev_index),
  260. make_field("reg", reg_index),
  261. make_field("data", 0),
  262. bus_addr, len);
  263. }
  264. int ps3_repository_read_dev_reg(unsigned int bus_index,
  265. unsigned int dev_index, unsigned int reg_index,
  266. enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
  267. {
  268. int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
  269. reg_index, reg_type);
  270. return result ? result
  271. : ps3_repository_read_dev_reg_addr(bus_index, dev_index,
  272. reg_index, bus_addr, len);
  273. }
  274. #if defined(DEBUG)
  275. int ps3_repository_dump_resource_info(unsigned int bus_index,
  276. unsigned int dev_index)
  277. {
  278. int result = 0;
  279. unsigned int res_index;
  280. pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
  281. bus_index, dev_index);
  282. for (res_index = 0; res_index < 10; res_index++) {
  283. enum ps3_interrupt_type intr_type;
  284. unsigned int interrupt_id;
  285. result = ps3_repository_read_dev_intr(bus_index, dev_index,
  286. res_index, &intr_type, &interrupt_id);
  287. if (result) {
  288. if (result != LV1_NO_ENTRY)
  289. pr_debug("%s:%d ps3_repository_read_dev_intr"
  290. " (%u:%u) failed\n", __func__, __LINE__,
  291. bus_index, dev_index);
  292. break;
  293. }
  294. pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
  295. __func__, __LINE__, bus_index, dev_index, intr_type,
  296. interrupt_id);
  297. }
  298. for (res_index = 0; res_index < 10; res_index++) {
  299. enum ps3_reg_type reg_type;
  300. u64 bus_addr;
  301. u64 len;
  302. result = ps3_repository_read_dev_reg(bus_index, dev_index,
  303. res_index, &reg_type, &bus_addr, &len);
  304. if (result) {
  305. if (result != LV1_NO_ENTRY)
  306. pr_debug("%s:%d ps3_repository_read_dev_reg"
  307. " (%u:%u) failed\n", __func__, __LINE__,
  308. bus_index, dev_index);
  309. break;
  310. }
  311. pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
  312. __func__, __LINE__, bus_index, dev_index, reg_type,
  313. bus_addr, len);
  314. }
  315. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  316. return result;
  317. }
  318. static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
  319. {
  320. int result = 0;
  321. unsigned int dev_index;
  322. pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
  323. for (dev_index = 0; dev_index < num_dev; dev_index++) {
  324. enum ps3_dev_type dev_type;
  325. unsigned int dev_id;
  326. result = ps3_repository_read_dev_type(bus_index, dev_index,
  327. &dev_type);
  328. if (result) {
  329. pr_debug("%s:%d ps3_repository_read_dev_type"
  330. " (%u:%u) failed\n", __func__, __LINE__,
  331. bus_index, dev_index);
  332. break;
  333. }
  334. result = ps3_repository_read_dev_id(bus_index, dev_index,
  335. &dev_id);
  336. if (result) {
  337. pr_debug("%s:%d ps3_repository_read_dev_id"
  338. " (%u:%u) failed\n", __func__, __LINE__,
  339. bus_index, dev_index);
  340. continue;
  341. }
  342. pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
  343. __LINE__, bus_index, dev_index, dev_type, dev_id);
  344. ps3_repository_dump_resource_info(bus_index, dev_index);
  345. }
  346. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  347. return result;
  348. }
  349. int ps3_repository_dump_bus_info(void)
  350. {
  351. int result = 0;
  352. unsigned int bus_index;
  353. pr_debug(" -> %s:%d\n", __func__, __LINE__);
  354. for (bus_index = 0; bus_index < 10; bus_index++) {
  355. enum ps3_bus_type bus_type;
  356. unsigned int bus_id;
  357. unsigned int num_dev;
  358. result = ps3_repository_read_bus_type(bus_index, &bus_type);
  359. if (result) {
  360. pr_debug("%s:%d read_bus_type(%u) failed\n",
  361. __func__, __LINE__, bus_index);
  362. break;
  363. }
  364. result = ps3_repository_read_bus_id(bus_index, &bus_id);
  365. if (result) {
  366. pr_debug("%s:%d read_bus_id(%u) failed\n",
  367. __func__, __LINE__, bus_index);
  368. continue;
  369. }
  370. if (bus_index != bus_id)
  371. pr_debug("%s:%d bus_index != bus_id\n",
  372. __func__, __LINE__);
  373. result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
  374. if (result) {
  375. pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
  376. __func__, __LINE__, bus_index);
  377. continue;
  378. }
  379. pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
  380. __func__, __LINE__, bus_index, bus_type, bus_id,
  381. num_dev);
  382. dump_device_info(bus_index, num_dev);
  383. }
  384. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  385. return result;
  386. }
  387. #endif /* defined(DEBUG) */
  388. static int find_device(unsigned int bus_index, unsigned int num_dev,
  389. unsigned int start_dev_index, enum ps3_dev_type dev_type,
  390. struct ps3_repository_device *dev)
  391. {
  392. int result = 0;
  393. unsigned int dev_index;
  394. pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type);
  395. dev->dev_index = UINT_MAX;
  396. for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) {
  397. enum ps3_dev_type x;
  398. result = ps3_repository_read_dev_type(bus_index, dev_index,
  399. &x);
  400. if (result) {
  401. pr_debug("%s:%d read_dev_type failed\n",
  402. __func__, __LINE__);
  403. return result;
  404. }
  405. if (x == dev_type)
  406. break;
  407. }
  408. if (dev_index == num_dev)
  409. return -1;
  410. pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
  411. __func__, __LINE__, dev_type, dev_index);
  412. result = ps3_repository_read_dev_id(bus_index, dev_index,
  413. &dev->did.dev_id);
  414. if (result) {
  415. pr_debug("%s:%d read_dev_id failed\n",
  416. __func__, __LINE__);
  417. return result;
  418. }
  419. dev->dev_index = dev_index;
  420. pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
  421. dev->did.dev_id);
  422. return result;
  423. }
  424. int ps3_repository_find_device (enum ps3_bus_type bus_type,
  425. enum ps3_dev_type dev_type,
  426. const struct ps3_repository_device *start_dev,
  427. struct ps3_repository_device *dev)
  428. {
  429. int result = 0;
  430. unsigned int bus_index;
  431. unsigned int num_dev;
  432. pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
  433. bus_type, dev_type);
  434. BUG_ON(start_dev && start_dev->bus_index > 10);
  435. for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
  436. bus_index++) {
  437. enum ps3_bus_type x;
  438. result = ps3_repository_read_bus_type(bus_index, &x);
  439. if (result) {
  440. pr_debug("%s:%d read_bus_type failed\n",
  441. __func__, __LINE__);
  442. dev->bus_index = UINT_MAX;
  443. return result;
  444. }
  445. if (x == bus_type)
  446. break;
  447. }
  448. if (bus_index >= 10)
  449. return -ENODEV;
  450. pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
  451. __func__, __LINE__, bus_type, bus_index);
  452. result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
  453. if (result) {
  454. pr_debug("%s:%d read_bus_num_dev failed\n",
  455. __func__, __LINE__);
  456. return result;
  457. }
  458. result = find_device(bus_index, num_dev, start_dev
  459. ? start_dev->dev_index + 1 : 0, dev_type, dev);
  460. if (result) {
  461. pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
  462. return result;
  463. }
  464. result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
  465. if (result) {
  466. pr_debug("%s:%d read_bus_id failed\n",
  467. __func__, __LINE__);
  468. return result;
  469. }
  470. dev->bus_index = bus_index;
  471. pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
  472. __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
  473. return result;
  474. }
  475. int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
  476. enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
  477. {
  478. int result = 0;
  479. unsigned int res_index;
  480. pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
  481. *interrupt_id = UINT_MAX;
  482. for (res_index = 0; res_index < 10; res_index++) {
  483. enum ps3_interrupt_type t;
  484. unsigned int id;
  485. result = ps3_repository_read_dev_intr(dev->bus_index,
  486. dev->dev_index, res_index, &t, &id);
  487. if (result) {
  488. pr_debug("%s:%d read_dev_intr failed\n",
  489. __func__, __LINE__);
  490. return result;
  491. }
  492. if (t == intr_type) {
  493. *interrupt_id = id;
  494. break;
  495. }
  496. }
  497. if (res_index == 10)
  498. return -ENODEV;
  499. pr_debug("%s:%d: found intr_type %u at res_index %u\n",
  500. __func__, __LINE__, intr_type, res_index);
  501. return result;
  502. }
  503. int ps3_repository_find_reg(const struct ps3_repository_device *dev,
  504. enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
  505. {
  506. int result = 0;
  507. unsigned int res_index;
  508. pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
  509. *bus_addr = *len = 0;
  510. for (res_index = 0; res_index < 10; res_index++) {
  511. enum ps3_reg_type t;
  512. u64 a;
  513. u64 l;
  514. result = ps3_repository_read_dev_reg(dev->bus_index,
  515. dev->dev_index, res_index, &t, &a, &l);
  516. if (result) {
  517. pr_debug("%s:%d read_dev_reg failed\n",
  518. __func__, __LINE__);
  519. return result;
  520. }
  521. if (t == reg_type) {
  522. *bus_addr = a;
  523. *len = l;
  524. break;
  525. }
  526. }
  527. if (res_index == 10)
  528. return -ENODEV;
  529. pr_debug("%s:%d: found reg_type %u at res_index %u\n",
  530. __func__, __LINE__, reg_type, res_index);
  531. return result;
  532. }
  533. int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
  534. {
  535. return read_node(PS3_LPAR_ID_CURRENT,
  536. make_first_field("bi", 0),
  537. make_field("pu", 0),
  538. ppe_id,
  539. make_field("rm_size", 0),
  540. rm_size, 0);
  541. }
  542. int ps3_repository_read_region_total(u64 *region_total)
  543. {
  544. return read_node(PS3_LPAR_ID_CURRENT,
  545. make_first_field("bi", 0),
  546. make_field("rgntotal", 0),
  547. 0, 0,
  548. region_total, 0);
  549. }
  550. /**
  551. * ps3_repository_read_mm_info - Read mm info for single pu system.
  552. * @rm_base: Real mode memory base address.
  553. * @rm_size: Real mode memory size.
  554. * @region_total: Maximum memory region size.
  555. */
  556. int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
  557. {
  558. int result;
  559. u64 ppe_id;
  560. lv1_get_logical_ppe_id(&ppe_id);
  561. *rm_base = 0;
  562. result = ps3_repository_read_rm_size(ppe_id, rm_size);
  563. return result ? result
  564. : ps3_repository_read_region_total(region_total);
  565. }
  566. /**
  567. * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
  568. * @num_spu: Number of physical spus.
  569. */
  570. int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
  571. {
  572. int result;
  573. u64 v1;
  574. result = read_node(PS3_LPAR_ID_CURRENT,
  575. make_first_field("bi", 0),
  576. make_field("spun", 0),
  577. 0, 0,
  578. &v1, 0);
  579. *num_spu_reserved = v1;
  580. return result;
  581. }
  582. /**
  583. * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
  584. * @num_resource_id: Number of spu resource ids.
  585. */
  586. int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
  587. {
  588. int result;
  589. u64 v1;
  590. result = read_node(PS3_LPAR_ID_CURRENT,
  591. make_first_field("bi", 0),
  592. make_field("spursvn", 0),
  593. 0, 0,
  594. &v1, 0);
  595. *num_resource_id = v1;
  596. return result;
  597. }
  598. /**
  599. * ps3_repository_read_spu_resource_id - spu resource reservation id value.
  600. * @res_index: Resource reservation index.
  601. * @resource_type: Resource reservation type.
  602. * @resource_id: Resource reservation id.
  603. */
  604. int ps3_repository_read_spu_resource_id(unsigned int res_index,
  605. enum ps3_spu_resource_type* resource_type, unsigned int *resource_id)
  606. {
  607. int result;
  608. u64 v1;
  609. u64 v2;
  610. result = read_node(PS3_LPAR_ID_CURRENT,
  611. make_first_field("bi", 0),
  612. make_field("spursv", 0),
  613. res_index,
  614. 0,
  615. &v1, &v2);
  616. *resource_type = v1;
  617. *resource_id = v2;
  618. return result;
  619. }
  620. int ps3_repository_read_boot_dat_address(u64 *address)
  621. {
  622. return read_node(PS3_LPAR_ID_CURRENT,
  623. make_first_field("bi", 0),
  624. make_field("boot_dat", 0),
  625. make_field("address", 0),
  626. 0,
  627. address, 0);
  628. }
  629. int ps3_repository_read_boot_dat_size(unsigned int *size)
  630. {
  631. int result;
  632. u64 v1;
  633. result = read_node(PS3_LPAR_ID_CURRENT,
  634. make_first_field("bi", 0),
  635. make_field("boot_dat", 0),
  636. make_field("size", 0),
  637. 0,
  638. &v1, 0);
  639. *size = v1;
  640. return result;
  641. }
  642. /**
  643. * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
  644. * address: lpar address of cell_ext_os_area
  645. * @size: size of cell_ext_os_area
  646. */
  647. int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
  648. {
  649. int result;
  650. *size = 0;
  651. result = ps3_repository_read_boot_dat_address(lpar_addr);
  652. return result ? result
  653. : ps3_repository_read_boot_dat_size(size);
  654. }
  655. int ps3_repository_read_num_be(unsigned int *num_be)
  656. {
  657. int result;
  658. u64 v1;
  659. result = read_node(PS3_LPAR_ID_PME,
  660. make_first_field("ben", 0),
  661. 0,
  662. 0,
  663. 0,
  664. &v1, 0);
  665. *num_be = v1;
  666. return result;
  667. }
  668. int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
  669. {
  670. return read_node(PS3_LPAR_ID_PME,
  671. make_first_field("be", be_index),
  672. 0,
  673. 0,
  674. 0,
  675. node_id, 0);
  676. }
  677. int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
  678. {
  679. return read_node(PS3_LPAR_ID_PME,
  680. make_first_field("be", 0),
  681. node_id,
  682. make_field("clock", 0),
  683. 0,
  684. tb_freq, 0);
  685. }
  686. int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
  687. {
  688. int result;
  689. u64 node_id;
  690. *tb_freq = 0;
  691. result = ps3_repository_read_be_node_id(0, &node_id);
  692. return result ? result
  693. : ps3_repository_read_tb_freq(node_id, tb_freq);
  694. }