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