repository.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  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. unsigned int *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, unsigned int *reg_type)
  241. {
  242. int result;
  243. u64 v1;
  244. result = read_node(PS3_LPAR_ID_PME,
  245. make_first_field("bus", bus_index),
  246. make_field("dev", dev_index),
  247. make_field("reg", reg_index),
  248. make_field("type", 0),
  249. &v1, 0);
  250. *reg_type = v1;
  251. return result;
  252. }
  253. int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
  254. unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
  255. {
  256. return read_node(PS3_LPAR_ID_PME,
  257. make_first_field("bus", bus_index),
  258. make_field("dev", dev_index),
  259. make_field("reg", reg_index),
  260. make_field("data", 0),
  261. bus_addr, len);
  262. }
  263. int ps3_repository_read_dev_reg(unsigned int bus_index,
  264. unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type,
  265. u64 *bus_addr, u64 *len)
  266. {
  267. int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
  268. reg_index, reg_type);
  269. return result ? result
  270. : ps3_repository_read_dev_reg_addr(bus_index, dev_index,
  271. reg_index, bus_addr, len);
  272. }
  273. #if defined(DEBUG)
  274. int ps3_repository_dump_resource_info(unsigned int bus_index,
  275. unsigned int dev_index)
  276. {
  277. int result = 0;
  278. unsigned int res_index;
  279. pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
  280. bus_index, dev_index);
  281. for (res_index = 0; res_index < 10; res_index++) {
  282. enum ps3_interrupt_type intr_type;
  283. unsigned int interrupt_id;
  284. result = ps3_repository_read_dev_intr(bus_index, dev_index,
  285. res_index, &intr_type, &interrupt_id);
  286. if (result) {
  287. if (result != LV1_NO_ENTRY)
  288. pr_debug("%s:%d ps3_repository_read_dev_intr"
  289. " (%u:%u) failed\n", __func__, __LINE__,
  290. bus_index, dev_index);
  291. break;
  292. }
  293. pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
  294. __func__, __LINE__, bus_index, dev_index, intr_type,
  295. interrupt_id);
  296. }
  297. for (res_index = 0; res_index < 10; res_index++) {
  298. enum ps3_region_type reg_type;
  299. u64 bus_addr;
  300. u64 len;
  301. result = ps3_repository_read_dev_reg(bus_index, dev_index,
  302. res_index, &reg_type, &bus_addr, &len);
  303. if (result) {
  304. if (result != LV1_NO_ENTRY)
  305. pr_debug("%s:%d ps3_repository_read_dev_reg"
  306. " (%u:%u) failed\n", __func__, __LINE__,
  307. bus_index, dev_index);
  308. break;
  309. }
  310. pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
  311. __func__, __LINE__, bus_index, dev_index, reg_type,
  312. bus_addr, len);
  313. }
  314. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  315. return result;
  316. }
  317. static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
  318. {
  319. int result = 0;
  320. unsigned int dev_index;
  321. pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
  322. for (dev_index = 0; dev_index < num_dev; dev_index++) {
  323. enum ps3_dev_type dev_type;
  324. unsigned int dev_id;
  325. result = ps3_repository_read_dev_type(bus_index, dev_index,
  326. &dev_type);
  327. if (result) {
  328. pr_debug("%s:%d ps3_repository_read_dev_type"
  329. " (%u:%u) failed\n", __func__, __LINE__,
  330. bus_index, dev_index);
  331. break;
  332. }
  333. result = ps3_repository_read_dev_id(bus_index, dev_index,
  334. &dev_id);
  335. if (result) {
  336. pr_debug("%s:%d ps3_repository_read_dev_id"
  337. " (%u:%u) failed\n", __func__, __LINE__,
  338. bus_index, dev_index);
  339. continue;
  340. }
  341. pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
  342. __LINE__, bus_index, dev_index, dev_type, dev_id);
  343. ps3_repository_dump_resource_info(bus_index, dev_index);
  344. }
  345. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  346. return result;
  347. }
  348. int ps3_repository_dump_bus_info(void)
  349. {
  350. int result = 0;
  351. unsigned int bus_index;
  352. pr_debug(" -> %s:%d\n", __func__, __LINE__);
  353. for (bus_index = 0; bus_index < 10; bus_index++) {
  354. enum ps3_bus_type bus_type;
  355. unsigned int bus_id;
  356. unsigned int num_dev;
  357. result = ps3_repository_read_bus_type(bus_index, &bus_type);
  358. if (result) {
  359. pr_debug("%s:%d read_bus_type(%u) failed\n",
  360. __func__, __LINE__, bus_index);
  361. break;
  362. }
  363. result = ps3_repository_read_bus_id(bus_index, &bus_id);
  364. if (result) {
  365. pr_debug("%s:%d read_bus_id(%u) failed\n",
  366. __func__, __LINE__, bus_index);
  367. continue;
  368. }
  369. if (bus_index != bus_id)
  370. pr_debug("%s:%d bus_index != bus_id\n",
  371. __func__, __LINE__);
  372. result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
  373. if (result) {
  374. pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
  375. __func__, __LINE__, bus_index);
  376. continue;
  377. }
  378. pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
  379. __func__, __LINE__, bus_index, bus_type, bus_id,
  380. num_dev);
  381. dump_device_info(bus_index, num_dev);
  382. }
  383. pr_debug(" <- %s:%d\n", __func__, __LINE__);
  384. return result;
  385. }
  386. #endif /* defined(DEBUG) */
  387. static int find_device(unsigned int bus_index, unsigned int num_dev,
  388. unsigned int start_dev_index, enum ps3_dev_type dev_type,
  389. struct ps3_repository_device *dev)
  390. {
  391. int result = 0;
  392. unsigned int dev_index;
  393. pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type);
  394. dev->dev_index = UINT_MAX;
  395. for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) {
  396. enum ps3_dev_type x;
  397. result = ps3_repository_read_dev_type(bus_index, dev_index,
  398. &x);
  399. if (result) {
  400. pr_debug("%s:%d read_dev_type failed\n",
  401. __func__, __LINE__);
  402. return result;
  403. }
  404. if (x == dev_type)
  405. break;
  406. }
  407. BUG_ON(dev_index == num_dev);
  408. pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
  409. __func__, __LINE__, dev_type, dev_index);
  410. result = ps3_repository_read_dev_id(bus_index, dev_index,
  411. &dev->did.dev_id);
  412. if (result) {
  413. pr_debug("%s:%d read_dev_id failed\n",
  414. __func__, __LINE__);
  415. return result;
  416. }
  417. dev->dev_index = dev_index;
  418. pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
  419. dev->did.dev_id);
  420. return result;
  421. }
  422. int ps3_repository_find_device (enum ps3_bus_type bus_type,
  423. enum ps3_dev_type dev_type,
  424. const struct ps3_repository_device *start_dev,
  425. struct ps3_repository_device *dev)
  426. {
  427. int result = 0;
  428. unsigned int bus_index;
  429. unsigned int num_dev;
  430. pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
  431. bus_type, dev_type);
  432. dev->bus_index = UINT_MAX;
  433. for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
  434. bus_index++) {
  435. enum ps3_bus_type x;
  436. result = ps3_repository_read_bus_type(bus_index, &x);
  437. if (result) {
  438. pr_debug("%s:%d read_bus_type failed\n",
  439. __func__, __LINE__);
  440. return result;
  441. }
  442. if (x == bus_type)
  443. break;
  444. }
  445. BUG_ON(bus_index == 10);
  446. pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
  447. __func__, __LINE__, bus_type, bus_index);
  448. result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
  449. if (result) {
  450. pr_debug("%s:%d read_bus_num_dev failed\n",
  451. __func__, __LINE__);
  452. return result;
  453. }
  454. result = find_device(bus_index, num_dev, start_dev
  455. ? start_dev->dev_index + 1 : 0, dev_type, dev);
  456. if (result) {
  457. pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
  458. return result;
  459. }
  460. result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
  461. if (result) {
  462. pr_debug("%s:%d read_bus_id failed\n",
  463. __func__, __LINE__);
  464. return result;
  465. }
  466. dev->bus_index = bus_index;
  467. pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
  468. __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
  469. return result;
  470. }
  471. int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
  472. enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
  473. {
  474. int result = 0;
  475. unsigned int res_index;
  476. pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
  477. *interrupt_id = UINT_MAX;
  478. for (res_index = 0; res_index < 10; res_index++) {
  479. enum ps3_interrupt_type t;
  480. unsigned int id;
  481. result = ps3_repository_read_dev_intr(dev->bus_index,
  482. dev->dev_index, res_index, &t, &id);
  483. if (result) {
  484. pr_debug("%s:%d read_dev_intr failed\n",
  485. __func__, __LINE__);
  486. return result;
  487. }
  488. if (t == intr_type) {
  489. *interrupt_id = id;
  490. break;
  491. }
  492. }
  493. BUG_ON(res_index == 10);
  494. pr_debug("%s:%d: found intr_type %u at res_index %u\n",
  495. __func__, __LINE__, intr_type, res_index);
  496. return result;
  497. }
  498. int ps3_repository_find_region(const struct ps3_repository_device *dev,
  499. enum ps3_region_type reg_type, u64 *bus_addr, u64 *len)
  500. {
  501. int result = 0;
  502. unsigned int res_index;
  503. pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
  504. *bus_addr = *len = 0;
  505. for (res_index = 0; res_index < 10; res_index++) {
  506. enum ps3_region_type t;
  507. u64 a;
  508. u64 l;
  509. result = ps3_repository_read_dev_reg(dev->bus_index,
  510. dev->dev_index, res_index, &t, &a, &l);
  511. if (result) {
  512. pr_debug("%s:%d read_dev_reg failed\n",
  513. __func__, __LINE__);
  514. return result;
  515. }
  516. if (t == reg_type) {
  517. *bus_addr = a;
  518. *len = l;
  519. break;
  520. }
  521. }
  522. BUG_ON(res_index == 10);
  523. pr_debug("%s:%d: found reg_type %u at res_index %u\n",
  524. __func__, __LINE__, reg_type, res_index);
  525. return result;
  526. }
  527. int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
  528. {
  529. return read_node(PS3_LPAR_ID_CURRENT,
  530. make_first_field("bi", 0),
  531. make_field("pu", 0),
  532. ppe_id,
  533. make_field("rm_size", 0),
  534. rm_size, 0);
  535. }
  536. int ps3_repository_read_region_total(u64 *region_total)
  537. {
  538. return read_node(PS3_LPAR_ID_CURRENT,
  539. make_first_field("bi", 0),
  540. make_field("rgntotal", 0),
  541. 0, 0,
  542. region_total, 0);
  543. }
  544. /**
  545. * ps3_repository_read_mm_info - Read mm info for single pu system.
  546. * @rm_base: Real mode memory base address.
  547. * @rm_size: Real mode memory size.
  548. * @region_total: Maximum memory region size.
  549. */
  550. int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
  551. {
  552. int result;
  553. u64 ppe_id;
  554. lv1_get_logical_ppe_id(&ppe_id);
  555. *rm_base = 0;
  556. result = ps3_repository_read_rm_size(ppe_id, rm_size);
  557. return result ? result
  558. : ps3_repository_read_region_total(region_total);
  559. }
  560. /**
  561. * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
  562. * @num_spu: Number of physical spus.
  563. */
  564. int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
  565. {
  566. int result;
  567. u64 v1;
  568. result = read_node(PS3_LPAR_ID_CURRENT,
  569. make_first_field("bi", 0),
  570. make_field("spun", 0),
  571. 0, 0,
  572. &v1, 0);
  573. *num_spu_reserved = v1;
  574. return result;
  575. }
  576. /**
  577. * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
  578. * @num_resource_id: Number of spu resource ids.
  579. */
  580. int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
  581. {
  582. int result;
  583. u64 v1;
  584. result = read_node(PS3_LPAR_ID_CURRENT,
  585. make_first_field("bi", 0),
  586. make_field("spursvn", 0),
  587. 0, 0,
  588. &v1, 0);
  589. *num_resource_id = v1;
  590. return result;
  591. }
  592. /**
  593. * ps3_repository_read_spu_resource_id - spu resource reservation id value.
  594. * @res_index: Resource reservation index.
  595. * @resource_type: Resource reservation type.
  596. * @resource_id: Resource reservation id.
  597. */
  598. int ps3_repository_read_spu_resource_id(unsigned int res_index,
  599. enum ps3_spu_resource_type* resource_type, unsigned int *resource_id)
  600. {
  601. int result;
  602. u64 v1;
  603. u64 v2;
  604. result = read_node(PS3_LPAR_ID_CURRENT,
  605. make_first_field("bi", 0),
  606. make_field("spursv", 0),
  607. res_index,
  608. 0,
  609. &v1, &v2);
  610. *resource_type = v1;
  611. *resource_id = v2;
  612. return result;
  613. }
  614. int ps3_repository_read_boot_dat_address(u64 *address)
  615. {
  616. return read_node(PS3_LPAR_ID_CURRENT,
  617. make_first_field("bi", 0),
  618. make_field("boot_dat", 0),
  619. make_field("address", 0),
  620. 0,
  621. address, 0);
  622. }
  623. int ps3_repository_read_boot_dat_size(unsigned int *size)
  624. {
  625. int result;
  626. u64 v1;
  627. result = read_node(PS3_LPAR_ID_CURRENT,
  628. make_first_field("bi", 0),
  629. make_field("boot_dat", 0),
  630. make_field("size", 0),
  631. 0,
  632. &v1, 0);
  633. *size = v1;
  634. return result;
  635. }
  636. /**
  637. * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
  638. * address: lpar address of cell_ext_os_area
  639. * @size: size of cell_ext_os_area
  640. */
  641. int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
  642. {
  643. int result;
  644. *size = 0;
  645. result = ps3_repository_read_boot_dat_address(lpar_addr);
  646. return result ? result
  647. : ps3_repository_read_boot_dat_size(size);
  648. }
  649. int ps3_repository_read_num_be(unsigned int *num_be)
  650. {
  651. int result;
  652. u64 v1;
  653. result = read_node(PS3_LPAR_ID_PME,
  654. make_first_field("ben", 0),
  655. 0,
  656. 0,
  657. 0,
  658. &v1, 0);
  659. *num_be = v1;
  660. return result;
  661. }
  662. int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
  663. {
  664. return read_node(PS3_LPAR_ID_PME,
  665. make_first_field("be", be_index),
  666. 0,
  667. 0,
  668. 0,
  669. node_id, 0);
  670. }
  671. int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
  672. {
  673. return read_node(PS3_LPAR_ID_PME,
  674. make_first_field("be", 0),
  675. node_id,
  676. make_field("clock", 0),
  677. 0,
  678. tb_freq, 0);
  679. }
  680. int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
  681. {
  682. int result;
  683. u64 node_id;
  684. *tb_freq = 0;
  685. result = ps3_repository_read_be_node_id(0, &node_id);
  686. return result ? result
  687. : ps3_repository_read_tb_freq(node_id, tb_freq);
  688. }