]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/powerpc/platforms/ps3/repository.c
[POWERPC] ps3: repository misc fixes
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / ps3 / repository.c
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
21 #include <asm/ps3.h>
22 #include <asm/lv1call.h>
23
24 enum ps3_vendor_id {
25         PS3_VENDOR_ID_NONE = 0,
26         PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
27 };
28
29 enum ps3_lpar_id {
30         PS3_LPAR_ID_CURRENT = 0,
31         PS3_LPAR_ID_PME = 1,
32 };
33
34 #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
35 static void _dump_field(const char *hdr, u64 n, const char* func, int line)
36 {
37 #if defined(DEBUG)
38         char s[16];
39         const char *const in = (const char *)&n;
40         unsigned int i;
41
42         for (i = 0; i < 8; i++)
43                 s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
44         s[i] = 0;
45
46         pr_debug("%s:%d: %s%016lx : %s\n", func, line, hdr, n, s);
47 #endif
48 }
49
50 #define dump_node_name(_a, _b, _c, _d, _e) \
51         _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
52 static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
53         u64 n4, const char* func, int line)
54 {
55         pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
56         _dump_field("n1: ", n1, func, line);
57         _dump_field("n2: ", n2, func, line);
58         _dump_field("n3: ", n3, func, line);
59         _dump_field("n4: ", n4, func, line);
60 }
61
62 #define dump_node(_a, _b, _c, _d, _e, _f, _g) \
63         _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
64 static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
65         u64 v1, u64 v2, const char* func, int line)
66 {
67         pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
68         _dump_field("n1: ", n1, func, line);
69         _dump_field("n2: ", n2, func, line);
70         _dump_field("n3: ", n3, func, line);
71         _dump_field("n4: ", n4, func, line);
72         pr_debug("%s:%d: v1: %016lx\n", func, line, v1);
73         pr_debug("%s:%d: v2: %016lx\n", func, line, v2);
74 }
75
76 /**
77  * make_first_field - Make the first field of a repository node name.
78  * @text: Text portion of the field.
79  * @index: Numeric index portion of the field.  Use zero for 'don't care'.
80  *
81  * This routine sets the vendor id to zero (non-vendor specific).
82  * Returns field value.
83  */
84
85 static u64 make_first_field(const char *text, u64 index)
86 {
87         u64 n;
88
89         strncpy((char *)&n, text, 8);
90         return PS3_VENDOR_ID_NONE + (n >> 32) + index;
91 }
92
93 /**
94  * make_field - Make subsequent fields of a repository node name.
95  * @text: Text portion of the field.  Use "" for 'don't care'.
96  * @index: Numeric index portion of the field.  Use zero for 'don't care'.
97  *
98  * Returns field value.
99  */
100
101 static u64 make_field(const char *text, u64 index)
102 {
103         u64 n;
104
105         strncpy((char *)&n, text, 8);
106         return n + index;
107 }
108
109 /**
110  * read_node - Read a repository node from raw fields.
111  * @n1: First field of node name.
112  * @n2: Second field of node name.  Use zero for 'don't care'.
113  * @n3: Third field of node name.  Use zero for 'don't care'.
114  * @n4: Fourth field of node name.  Use zero for 'don't care'.
115  * @v1: First repository value (high word).
116  * @v2: Second repository value (low word).  Optional parameter, use zero
117  *      for 'don't care'.
118  */
119
120 static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
121         u64 *_v1, u64 *_v2)
122 {
123         int result;
124         u64 v1;
125         u64 v2;
126
127         if (lpar_id == PS3_LPAR_ID_CURRENT) {
128                 u64 id;
129                 lv1_get_logical_partition_id(&id);
130                 lpar_id = id;
131         }
132
133         result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1,
134                 &v2);
135
136         if (result) {
137                 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
138                         __func__, __LINE__, ps3_result(result));
139                 dump_node_name(lpar_id, n1, n2, n3, n4);
140                 return result;
141         }
142
143         dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
144
145         if (_v1)
146                 *_v1 = v1;
147         if (_v2)
148                 *_v2 = v2;
149
150         if (v1 && !_v1)
151                 pr_debug("%s:%d: warning: discarding non-zero v1: %016lx\n",
152                         __func__, __LINE__, v1);
153         if (v2 && !_v2)
154                 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
155                         __func__, __LINE__, v2);
156
157         return result;
158 }
159
160 int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
161         u64 *value)
162 {
163         return read_node(PS3_LPAR_ID_PME,
164                 make_first_field("bus", bus_index),
165                 make_field(bus_str, 0),
166                 0, 0,
167                 value, 0);
168 }
169
170 int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
171 {
172         int result;
173         u64 v1;
174         u64 v2; /* unused */
175
176         result = read_node(PS3_LPAR_ID_PME,
177                 make_first_field("bus", bus_index),
178                 make_field("id", 0),
179                 0, 0,
180                 &v1, &v2);
181         *bus_id = v1;
182         return result;
183 }
184
185 int ps3_repository_read_bus_type(unsigned int bus_index,
186         enum ps3_bus_type *bus_type)
187 {
188         int result;
189         u64 v1;
190
191         result = read_node(PS3_LPAR_ID_PME,
192                 make_first_field("bus", bus_index),
193                 make_field("type", 0),
194                 0, 0,
195                 &v1, 0);
196         *bus_type = v1;
197         return result;
198 }
199
200 int ps3_repository_read_bus_num_dev(unsigned int bus_index,
201         unsigned int *num_dev)
202 {
203         int result;
204         u64 v1;
205
206         result = read_node(PS3_LPAR_ID_PME,
207                 make_first_field("bus", bus_index),
208                 make_field("num_dev", 0),
209                 0, 0,
210                 &v1, 0);
211         *num_dev = v1;
212         return result;
213 }
214
215 int ps3_repository_read_dev_str(unsigned int bus_index,
216         unsigned int dev_index, const char *dev_str, u64 *value)
217 {
218         return read_node(PS3_LPAR_ID_PME,
219                 make_first_field("bus", bus_index),
220                 make_field("dev", dev_index),
221                 make_field(dev_str, 0),
222                 0,
223                 value, 0);
224 }
225
226 int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
227         unsigned int *dev_id)
228 {
229         int result;
230         u64 v1;
231
232         result = read_node(PS3_LPAR_ID_PME,
233                 make_first_field("bus", bus_index),
234                 make_field("dev", dev_index),
235                 make_field("id", 0),
236                 0,
237                 &v1, 0);
238         *dev_id = v1;
239         return result;
240 }
241
242 int ps3_repository_read_dev_type(unsigned int bus_index,
243         unsigned int dev_index, enum ps3_dev_type *dev_type)
244 {
245         int result;
246         u64 v1;
247
248         result = read_node(PS3_LPAR_ID_PME,
249                 make_first_field("bus", bus_index),
250                 make_field("dev", dev_index),
251                 make_field("type", 0),
252                 0,
253                 &v1, 0);
254         *dev_type = v1;
255         return result;
256 }
257
258 int ps3_repository_read_dev_intr(unsigned int bus_index,
259         unsigned int dev_index, unsigned int intr_index,
260         enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id)
261 {
262         int result;
263         u64 v1;
264         u64 v2;
265
266         result = read_node(PS3_LPAR_ID_PME,
267                 make_first_field("bus", bus_index),
268                 make_field("dev", dev_index),
269                 make_field("intr", intr_index),
270                 0,
271                 &v1, &v2);
272         *intr_type = v1;
273         *interrupt_id = v2;
274         return result;
275 }
276
277 int ps3_repository_read_dev_reg_type(unsigned int bus_index,
278         unsigned int dev_index, unsigned int reg_index,
279         enum ps3_reg_type *reg_type)
280 {
281         int result;
282         u64 v1;
283
284         result = read_node(PS3_LPAR_ID_PME,
285                 make_first_field("bus", bus_index),
286                 make_field("dev", dev_index),
287                 make_field("reg", reg_index),
288                 make_field("type", 0),
289                 &v1, 0);
290         *reg_type = v1;
291         return result;
292 }
293
294 int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
295         unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
296 {
297         return read_node(PS3_LPAR_ID_PME,
298                 make_first_field("bus", bus_index),
299                 make_field("dev", dev_index),
300                 make_field("reg", reg_index),
301                 make_field("data", 0),
302                 bus_addr, len);
303 }
304
305 int ps3_repository_read_dev_reg(unsigned int bus_index,
306         unsigned int dev_index, unsigned int reg_index,
307         enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
308 {
309         int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
310                 reg_index, reg_type);
311         return result ? result
312                 : ps3_repository_read_dev_reg_addr(bus_index, dev_index,
313                 reg_index, bus_addr, len);
314 }
315
316 #if defined(DEBUG)
317 int ps3_repository_dump_resource_info(unsigned int bus_index,
318         unsigned int dev_index)
319 {
320         int result = 0;
321         unsigned int res_index;
322
323         pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
324                 bus_index, dev_index);
325
326         for (res_index = 0; res_index < 10; res_index++) {
327                 enum ps3_interrupt_type intr_type;
328                 unsigned int interrupt_id;
329
330                 result = ps3_repository_read_dev_intr(bus_index, dev_index,
331                         res_index, &intr_type, &interrupt_id);
332
333                 if (result) {
334                         if (result !=  LV1_NO_ENTRY)
335                                 pr_debug("%s:%d ps3_repository_read_dev_intr"
336                                         " (%u:%u) failed\n", __func__, __LINE__,
337                                         bus_index, dev_index);
338                         break;
339                 }
340
341                 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
342                         __func__, __LINE__, bus_index, dev_index, intr_type,
343                         interrupt_id);
344         }
345
346         for (res_index = 0; res_index < 10; res_index++) {
347                 enum ps3_reg_type reg_type;
348                 u64 bus_addr;
349                 u64 len;
350
351                 result = ps3_repository_read_dev_reg(bus_index, dev_index,
352                         res_index, &reg_type, &bus_addr, &len);
353
354                 if (result) {
355                         if (result !=  LV1_NO_ENTRY)
356                                 pr_debug("%s:%d ps3_repository_read_dev_reg"
357                                         " (%u:%u) failed\n", __func__, __LINE__,
358                                         bus_index, dev_index);
359                         break;
360                 }
361
362                 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
363                         __func__, __LINE__, bus_index, dev_index, reg_type,
364                         bus_addr, len);
365         }
366
367         pr_debug(" <- %s:%d\n", __func__, __LINE__);
368         return result;
369 }
370
371 static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
372 {
373         int result = 0;
374         unsigned int dev_index;
375
376         pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
377
378         for (dev_index = 0; dev_index < num_dev; dev_index++) {
379                 enum ps3_dev_type dev_type;
380                 unsigned int dev_id;
381
382                 result = ps3_repository_read_dev_type(bus_index, dev_index,
383                         &dev_type);
384
385                 if (result) {
386                         pr_debug("%s:%d ps3_repository_read_dev_type"
387                                 " (%u:%u) failed\n", __func__, __LINE__,
388                                 bus_index, dev_index);
389                         break;
390                 }
391
392                 result = ps3_repository_read_dev_id(bus_index, dev_index,
393                         &dev_id);
394
395                 if (result) {
396                         pr_debug("%s:%d ps3_repository_read_dev_id"
397                                 " (%u:%u) failed\n", __func__, __LINE__,
398                                 bus_index, dev_index);
399                         continue;
400                 }
401
402                 pr_debug("%s:%d  (%u:%u): dev_type %u, dev_id %u\n", __func__,
403                         __LINE__, bus_index, dev_index, dev_type, dev_id);
404
405                 ps3_repository_dump_resource_info(bus_index, dev_index);
406         }
407
408         pr_debug(" <- %s:%d\n", __func__, __LINE__);
409         return result;
410 }
411
412 int ps3_repository_dump_bus_info(void)
413 {
414         int result = 0;
415         unsigned int bus_index;
416
417         pr_debug(" -> %s:%d\n", __func__, __LINE__);
418
419         for (bus_index = 0; bus_index < 10; bus_index++) {
420                 enum ps3_bus_type bus_type;
421                 unsigned int bus_id;
422                 unsigned int num_dev;
423
424                 result = ps3_repository_read_bus_type(bus_index, &bus_type);
425
426                 if (result) {
427                         pr_debug("%s:%d read_bus_type(%u) failed\n",
428                                 __func__, __LINE__, bus_index);
429                         break;
430                 }
431
432                 result = ps3_repository_read_bus_id(bus_index, &bus_id);
433
434                 if (result) {
435                         pr_debug("%s:%d read_bus_id(%u) failed\n",
436                                 __func__, __LINE__, bus_index);
437                         continue;
438                 }
439
440                 if (bus_index != bus_id)
441                         pr_debug("%s:%d bus_index != bus_id\n",
442                                 __func__, __LINE__);
443
444                 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
445
446                 if (result) {
447                         pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
448                                 __func__, __LINE__, bus_index);
449                         continue;
450                 }
451
452                 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
453                         __func__, __LINE__, bus_index, bus_type, bus_id,
454                         num_dev);
455
456                 dump_device_info(bus_index, num_dev);
457         }
458
459         pr_debug(" <- %s:%d\n", __func__, __LINE__);
460         return result;
461 }
462 #endif /* defined(DEBUG) */
463
464 static int find_device(unsigned int bus_index, unsigned int num_dev,
465         unsigned int start_dev_index, enum ps3_dev_type dev_type,
466         struct ps3_repository_device *dev)
467 {
468         int result = 0;
469         unsigned int dev_index;
470
471         pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type);
472
473         dev->dev_index = UINT_MAX;
474
475         for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) {
476                 enum ps3_dev_type x;
477
478                 result = ps3_repository_read_dev_type(bus_index, dev_index,
479                         &x);
480
481                 if (result) {
482                         pr_debug("%s:%d read_dev_type failed\n",
483                                 __func__, __LINE__);
484                         return result;
485                 }
486
487                 if (x == dev_type)
488                         break;
489         }
490
491         if (dev_index == num_dev)
492                 return -1;
493
494         pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
495                 __func__, __LINE__, dev_type, dev_index);
496
497         result = ps3_repository_read_dev_id(bus_index, dev_index,
498                 &dev->did.dev_id);
499
500         if (result) {
501                 pr_debug("%s:%d read_dev_id failed\n",
502                         __func__, __LINE__);
503                 return result;
504         }
505
506         dev->dev_index = dev_index;
507
508         pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
509                 dev->did.dev_id);
510
511         return result;
512 }
513
514 int ps3_repository_find_device (enum ps3_bus_type bus_type,
515         enum ps3_dev_type dev_type,
516         const struct ps3_repository_device *start_dev,
517         struct ps3_repository_device *dev)
518 {
519         int result = 0;
520         unsigned int bus_index;
521         unsigned int num_dev;
522
523         pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
524                 bus_type, dev_type);
525
526         BUG_ON(start_dev && start_dev->bus_index > 10);
527
528         for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
529                 bus_index++) {
530                 enum ps3_bus_type x;
531
532                 result = ps3_repository_read_bus_type(bus_index, &x);
533
534                 if (result) {
535                         pr_debug("%s:%d read_bus_type failed\n",
536                                 __func__, __LINE__);
537                         dev->bus_index = UINT_MAX;
538                         return result;
539                 }
540                 if (x == bus_type)
541                         break;
542         }
543
544         if (bus_index >= 10)
545                 return -ENODEV;
546
547         pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
548                 __func__, __LINE__, bus_type, bus_index);
549
550         result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
551
552         if (result) {
553                 pr_debug("%s:%d read_bus_num_dev failed\n",
554                         __func__, __LINE__);
555                 return result;
556         }
557
558         result = find_device(bus_index, num_dev, start_dev
559                 ? start_dev->dev_index + 1 : 0, dev_type, dev);
560
561         if (result) {
562                 pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
563                 return result;
564         }
565
566         result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
567
568         if (result) {
569                 pr_debug("%s:%d read_bus_id failed\n",
570                         __func__, __LINE__);
571                 return result;
572         }
573
574         dev->bus_index = bus_index;
575
576         pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
577                 __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
578
579         return result;
580 }
581
582 int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
583         enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
584 {
585         int result = 0;
586         unsigned int res_index;
587
588         pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
589
590         *interrupt_id = UINT_MAX;
591
592         for (res_index = 0; res_index < 10; res_index++) {
593                 enum ps3_interrupt_type t;
594                 unsigned int id;
595
596                 result = ps3_repository_read_dev_intr(dev->bus_index,
597                         dev->dev_index, res_index, &t, &id);
598
599                 if (result) {
600                         pr_debug("%s:%d read_dev_intr failed\n",
601                                 __func__, __LINE__);
602                         return result;
603                 }
604
605                 if (t == intr_type) {
606                         *interrupt_id = id;
607                         break;
608                 }
609         }
610
611         if (res_index == 10)
612                 return -ENODEV;
613
614         pr_debug("%s:%d: found intr_type %u at res_index %u\n",
615                 __func__, __LINE__, intr_type, res_index);
616
617         return result;
618 }
619
620 int ps3_repository_find_reg(const struct ps3_repository_device *dev,
621         enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
622 {
623         int result = 0;
624         unsigned int res_index;
625
626         pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
627
628         *bus_addr = *len = 0;
629
630         for (res_index = 0; res_index < 10; res_index++) {
631                 enum ps3_reg_type t;
632                 u64 a;
633                 u64 l;
634
635                 result = ps3_repository_read_dev_reg(dev->bus_index,
636                         dev->dev_index, res_index, &t, &a, &l);
637
638                 if (result) {
639                         pr_debug("%s:%d read_dev_reg failed\n",
640                                 __func__, __LINE__);
641                         return result;
642                 }
643
644                 if (t == reg_type) {
645                         *bus_addr = a;
646                         *len = l;
647                         break;
648                 }
649         }
650
651         if (res_index == 10)
652                 return -ENODEV;
653
654         pr_debug("%s:%d: found reg_type %u at res_index %u\n",
655                 __func__, __LINE__, reg_type, res_index);
656
657         return result;
658 }
659
660 int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
661 {
662         return read_node(PS3_LPAR_ID_CURRENT,
663                 make_first_field("bi", 0),
664                 make_field("pu", 0),
665                 ppe_id,
666                 make_field("rm_size", 0),
667                 rm_size, 0);
668 }
669
670 int ps3_repository_read_region_total(u64 *region_total)
671 {
672         return read_node(PS3_LPAR_ID_CURRENT,
673                 make_first_field("bi", 0),
674                 make_field("rgntotal", 0),
675                 0, 0,
676                 region_total, 0);
677 }
678
679 /**
680  * ps3_repository_read_mm_info - Read mm info for single pu system.
681  * @rm_base: Real mode memory base address.
682  * @rm_size: Real mode memory size.
683  * @region_total: Maximum memory region size.
684  */
685
686 int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
687 {
688         int result;
689         u64 ppe_id;
690
691         lv1_get_logical_ppe_id(&ppe_id);
692         *rm_base = 0;
693         result = ps3_repository_read_rm_size(ppe_id, rm_size);
694         return result ? result
695                 : ps3_repository_read_region_total(region_total);
696 }
697
698 /**
699  * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
700  * @num_spu: Number of physical spus.
701  */
702
703 int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
704 {
705         int result;
706         u64 v1;
707
708         result = read_node(PS3_LPAR_ID_CURRENT,
709                 make_first_field("bi", 0),
710                 make_field("spun", 0),
711                 0, 0,
712                 &v1, 0);
713         *num_spu_reserved = v1;
714         return result;
715 }
716
717 /**
718  * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
719  * @num_resource_id: Number of spu resource ids.
720  */
721
722 int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
723 {
724         int result;
725         u64 v1;
726
727         result = read_node(PS3_LPAR_ID_CURRENT,
728                 make_first_field("bi", 0),
729                 make_field("spursvn", 0),
730                 0, 0,
731                 &v1, 0);
732         *num_resource_id = v1;
733         return result;
734 }
735
736 /**
737  * ps3_repository_read_spu_resource_id - spu resource reservation id value.
738  * @res_index: Resource reservation index.
739  * @resource_type: Resource reservation type.
740  * @resource_id: Resource reservation id.
741  */
742
743 int ps3_repository_read_spu_resource_id(unsigned int res_index,
744         enum ps3_spu_resource_type* resource_type, unsigned int *resource_id)
745 {
746         int result;
747         u64 v1;
748         u64 v2;
749
750         result = read_node(PS3_LPAR_ID_CURRENT,
751                 make_first_field("bi", 0),
752                 make_field("spursv", 0),
753                 res_index,
754                 0,
755                 &v1, &v2);
756         *resource_type = v1;
757         *resource_id = v2;
758         return result;
759 }
760
761 int ps3_repository_read_boot_dat_address(u64 *address)
762 {
763         return read_node(PS3_LPAR_ID_CURRENT,
764                 make_first_field("bi", 0),
765                 make_field("boot_dat", 0),
766                 make_field("address", 0),
767                 0,
768                 address, 0);
769 }
770
771 int ps3_repository_read_boot_dat_size(unsigned int *size)
772 {
773         int result;
774         u64 v1;
775
776         result = read_node(PS3_LPAR_ID_CURRENT,
777                 make_first_field("bi", 0),
778                 make_field("boot_dat", 0),
779                 make_field("size", 0),
780                 0,
781                 &v1, 0);
782         *size = v1;
783         return result;
784 }
785
786 /**
787   * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
788   * address: lpar address of cell_ext_os_area
789   * @size: size of cell_ext_os_area
790   */
791
792 int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
793 {
794         int result;
795
796         *size = 0;
797         result = ps3_repository_read_boot_dat_address(lpar_addr);
798         return result ? result
799                 : ps3_repository_read_boot_dat_size(size);
800 }
801
802 int ps3_repository_read_num_be(unsigned int *num_be)
803 {
804         int result;
805         u64 v1;
806
807         result = read_node(PS3_LPAR_ID_PME,
808                 make_first_field("ben", 0),
809                 0,
810                 0,
811                 0,
812                 &v1, 0);
813         *num_be = v1;
814         return result;
815 }
816
817 int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
818 {
819         return read_node(PS3_LPAR_ID_PME,
820                 make_first_field("be", be_index),
821                 0,
822                 0,
823                 0,
824                 node_id, 0);
825 }
826
827 int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
828 {
829         return read_node(PS3_LPAR_ID_PME,
830                 make_first_field("be", 0),
831                 node_id,
832                 make_field("clock", 0),
833                 0,
834                 tb_freq, 0);
835 }
836
837 int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
838 {
839         int result;
840         u64 node_id;
841
842         *tb_freq = 0;
843         result = ps3_repository_read_be_node_id(0, &node_id);
844         return result ? result
845                 : ps3_repository_read_tb_freq(node_id, tb_freq);
846 }