linux/arch/sparc/kernel/prom_64.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Procedures for creating, accessing and interpreting the device tree.
   4 *
   5 * Paul Mackerras       August 1996.
   6 * Copyright (C) 1996-2005 Paul Mackerras.
   7 * 
   8 *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
   9 *    {engebret|bergner}@us.ibm.com 
  10 *
  11 *  Adapted for sparc64 by David S. Miller davem@davemloft.net
  12 */
  13
  14#include <linux/memblock.h>
  15#include <linux/kernel.h>
  16#include <linux/string.h>
  17#include <linux/types.h>
  18#include <linux/cpu.h>
  19#include <linux/mm.h>
  20#include <linux/of.h>
  21
  22#include <asm/prom.h>
  23#include <asm/oplib.h>
  24#include <asm/irq.h>
  25#include <asm/asi.h>
  26#include <asm/upa.h>
  27#include <asm/smp.h>
  28
  29#include "prom.h"
  30
  31void * __init prom_early_alloc(unsigned long size)
  32{
  33        void *ret = memblock_alloc(size, SMP_CACHE_BYTES);
  34
  35        if (!ret) {
  36                prom_printf("prom_early_alloc(%lu) failed\n", size);
  37                prom_halt();
  38        }
  39
  40        prom_early_allocated += size;
  41
  42        return ret;
  43}
  44
  45/* The following routines deal with the black magic of fully naming a
  46 * node.
  47 *
  48 * Certain well known named nodes are just the simple name string.
  49 *
  50 * Actual devices have an address specifier appended to the base name
  51 * string, like this "foo@addr".  The "addr" can be in any number of
  52 * formats, and the platform plus the type of the node determine the
  53 * format and how it is constructed.
  54 *
  55 * For children of the ROOT node, the naming convention is fixed and
  56 * determined by whether this is a sun4u or sun4v system.
  57 *
  58 * For children of other nodes, it is bus type specific.  So
  59 * we walk up the tree until we discover a "device_type" property
  60 * we recognize and we go from there.
  61 *
  62 * As an example, the boot device on my workstation has a full path:
  63 *
  64 *      /pci@1e,600000/ide@d/disk@0,0:c
  65 */
  66static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
  67{
  68        const char *name = of_get_property(dp, "name", NULL);
  69        struct linux_prom64_registers *regs;
  70        struct property *rprop;
  71        u32 high_bits, low_bits, type;
  72
  73        rprop = of_find_property(dp, "reg", NULL);
  74        if (!rprop)
  75                return;
  76
  77        regs = rprop->value;
  78        if (!of_node_is_root(dp->parent)) {
  79                sprintf(tmp_buf, "%s@%x,%x",
  80                        name,
  81                        (unsigned int) (regs->phys_addr >> 32UL),
  82                        (unsigned int) (regs->phys_addr & 0xffffffffUL));
  83                return;
  84        }
  85
  86        type = regs->phys_addr >> 60UL;
  87        high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
  88        low_bits = (regs->phys_addr & 0xffffffffUL);
  89
  90        if (type == 0 || type == 8) {
  91                const char *prefix = (type == 0) ? "m" : "i";
  92
  93                if (low_bits)
  94                        sprintf(tmp_buf, "%s@%s%x,%x",
  95                                name, prefix,
  96                                high_bits, low_bits);
  97                else
  98                        sprintf(tmp_buf, "%s@%s%x",
  99                                name,
 100                                prefix,
 101                                high_bits);
 102        } else if (type == 12) {
 103                sprintf(tmp_buf, "%s@%x",
 104                        name, high_bits);
 105        }
 106}
 107
 108static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
 109{
 110        const char *name = of_get_property(dp, "name", NULL);
 111        struct linux_prom64_registers *regs;
 112        struct property *prop;
 113
 114        prop = of_find_property(dp, "reg", NULL);
 115        if (!prop)
 116                return;
 117
 118        regs = prop->value;
 119        if (!of_node_is_root(dp->parent)) {
 120                sprintf(tmp_buf, "%s@%x,%x",
 121                        name,
 122                        (unsigned int) (regs->phys_addr >> 32UL),
 123                        (unsigned int) (regs->phys_addr & 0xffffffffUL));
 124                return;
 125        }
 126
 127        prop = of_find_property(dp, "upa-portid", NULL);
 128        if (!prop)
 129                prop = of_find_property(dp, "portid", NULL);
 130        if (prop) {
 131                unsigned long mask = 0xffffffffUL;
 132
 133                if (tlb_type >= cheetah)
 134                        mask = 0x7fffff;
 135
 136                sprintf(tmp_buf, "%s@%x,%x",
 137                        name,
 138                        *(u32 *)prop->value,
 139                        (unsigned int) (regs->phys_addr & mask));
 140        }
 141}
 142
 143/* "name@slot,offset"  */
 144static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
 145{
 146        const char *name = of_get_property(dp, "name", NULL);
 147        struct linux_prom_registers *regs;
 148        struct property *prop;
 149
 150        prop = of_find_property(dp, "reg", NULL);
 151        if (!prop)
 152                return;
 153
 154        regs = prop->value;
 155        sprintf(tmp_buf, "%s@%x,%x",
 156                name,
 157                regs->which_io,
 158                regs->phys_addr);
 159}
 160
 161/* "name@devnum[,func]" */
 162static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
 163{
 164        const char *name = of_get_property(dp, "name", NULL);
 165        struct linux_prom_pci_registers *regs;
 166        struct property *prop;
 167        unsigned int devfn;
 168
 169        prop = of_find_property(dp, "reg", NULL);
 170        if (!prop)
 171                return;
 172
 173        regs = prop->value;
 174        devfn = (regs->phys_hi >> 8) & 0xff;
 175        if (devfn & 0x07) {
 176                sprintf(tmp_buf, "%s@%x,%x",
 177                        name,
 178                        devfn >> 3,
 179                        devfn & 0x07);
 180        } else {
 181                sprintf(tmp_buf, "%s@%x",
 182                        name,
 183                        devfn >> 3);
 184        }
 185}
 186
 187/* "name@UPA_PORTID,offset" */
 188static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
 189{
 190        const char *name = of_get_property(dp, "name", NULL);
 191        struct linux_prom64_registers *regs;
 192        struct property *prop;
 193
 194        prop = of_find_property(dp, "reg", NULL);
 195        if (!prop)
 196                return;
 197
 198        regs = prop->value;
 199
 200        prop = of_find_property(dp, "upa-portid", NULL);
 201        if (!prop)
 202                return;
 203
 204        sprintf(tmp_buf, "%s@%x,%x",
 205                name,
 206                *(u32 *) prop->value,
 207                (unsigned int) (regs->phys_addr & 0xffffffffUL));
 208}
 209
 210/* "name@reg" */
 211static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
 212{
 213        const char *name = of_get_property(dp, "name", NULL);
 214        struct property *prop;
 215        u32 *regs;
 216
 217        prop = of_find_property(dp, "reg", NULL);
 218        if (!prop)
 219                return;
 220
 221        regs = prop->value;
 222
 223        sprintf(tmp_buf, "%s@%x", name, *regs);
 224}
 225
 226/* "name@addrhi,addrlo" */
 227static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
 228{
 229        const char *name = of_get_property(dp, "name", NULL);
 230        struct linux_prom64_registers *regs;
 231        struct property *prop;
 232
 233        prop = of_find_property(dp, "reg", NULL);
 234        if (!prop)
 235                return;
 236
 237        regs = prop->value;
 238
 239        sprintf(tmp_buf, "%s@%x,%x",
 240                name,
 241                (unsigned int) (regs->phys_addr >> 32UL),
 242                (unsigned int) (regs->phys_addr & 0xffffffffUL));
 243}
 244
 245/* "name@bus,addr" */
 246static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
 247{
 248        const char *name = of_get_property(dp, "name", NULL);
 249        struct property *prop;
 250        u32 *regs;
 251
 252        prop = of_find_property(dp, "reg", NULL);
 253        if (!prop)
 254                return;
 255
 256        regs = prop->value;
 257
 258        /* This actually isn't right... should look at the #address-cells
 259         * property of the i2c bus node etc. etc.
 260         */
 261        sprintf(tmp_buf, "%s@%x,%x",
 262                name, regs[0], regs[1]);
 263}
 264
 265/* "name@reg0[,reg1]" */
 266static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
 267{
 268        const char *name = of_get_property(dp, "name", NULL);
 269        struct property *prop;
 270        u32 *regs;
 271
 272        prop = of_find_property(dp, "reg", NULL);
 273        if (!prop)
 274                return;
 275
 276        regs = prop->value;
 277
 278        if (prop->length == sizeof(u32) || regs[1] == 1) {
 279                sprintf(tmp_buf, "%s@%x",
 280                        name, regs[0]);
 281        } else {
 282                sprintf(tmp_buf, "%s@%x,%x",
 283                        name, regs[0], regs[1]);
 284        }
 285}
 286
 287/* "name@reg0reg1[,reg2reg3]" */
 288static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
 289{
 290        const char *name = of_get_property(dp, "name", NULL);
 291        struct property *prop;
 292        u32 *regs;
 293
 294        prop = of_find_property(dp, "reg", NULL);
 295        if (!prop)
 296                return;
 297
 298        regs = prop->value;
 299
 300        if (regs[2] || regs[3]) {
 301                sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
 302                        name, regs[0], regs[1], regs[2], regs[3]);
 303        } else {
 304                sprintf(tmp_buf, "%s@%08x%08x",
 305                        name, regs[0], regs[1]);
 306        }
 307}
 308
 309static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
 310{
 311        struct device_node *parent = dp->parent;
 312
 313        if (parent != NULL) {
 314                if (of_node_is_type(parent, "pci") ||
 315                    of_node_is_type(parent, "pciex")) {
 316                        pci_path_component(dp, tmp_buf);
 317                        return;
 318                }
 319                if (of_node_is_type(parent, "sbus")) {
 320                        sbus_path_component(dp, tmp_buf);
 321                        return;
 322                }
 323                if (of_node_is_type(parent, "upa")) {
 324                        upa_path_component(dp, tmp_buf);
 325                        return;
 326                }
 327                if (of_node_is_type(parent, "ebus")) {
 328                        ebus_path_component(dp, tmp_buf);
 329                        return;
 330                }
 331                if (of_node_name_eq(parent, "usb") ||
 332                    of_node_name_eq(parent, "hub")) {
 333                        usb_path_component(dp, tmp_buf);
 334                        return;
 335                }
 336                if (of_node_is_type(parent, "i2c")) {
 337                        i2c_path_component(dp, tmp_buf);
 338                        return;
 339                }
 340                if (of_node_is_type(parent, "firewire")) {
 341                        ieee1394_path_component(dp, tmp_buf);
 342                        return;
 343                }
 344                if (of_node_is_type(parent, "virtual-devices")) {
 345                        vdev_path_component(dp, tmp_buf);
 346                        return;
 347                }
 348                /* "isa" is handled with platform naming */
 349        }
 350
 351        /* Use platform naming convention.  */
 352        if (tlb_type == hypervisor) {
 353                sun4v_path_component(dp, tmp_buf);
 354                return;
 355        } else {
 356                sun4u_path_component(dp, tmp_buf);
 357        }
 358}
 359
 360char * __init build_path_component(struct device_node *dp)
 361{
 362        const char *name = of_get_property(dp, "name", NULL);
 363        char tmp_buf[64], *n;
 364
 365        tmp_buf[0] = '\0';
 366        __build_path_component(dp, tmp_buf);
 367        if (tmp_buf[0] == '\0')
 368                strcpy(tmp_buf, name);
 369
 370        n = prom_early_alloc(strlen(tmp_buf) + 1);
 371        strcpy(n, tmp_buf);
 372
 373        return n;
 374}
 375
 376static const char *get_mid_prop(void)
 377{
 378        return (tlb_type == spitfire ? "upa-portid" : "portid");
 379}
 380
 381bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
 382                                       int cpu, unsigned int *thread)
 383{
 384        const char *mid_prop = get_mid_prop();
 385        int this_cpu_id;
 386
 387        /* On hypervisor based platforms we interrogate the 'reg'
 388         * property.  On everything else we look for a 'upa-portid',
 389         * 'portid', or 'cpuid' property.
 390         */
 391
 392        if (tlb_type == hypervisor) {
 393                struct property *prop = of_find_property(cpun, "reg", NULL);
 394                u32 *regs;
 395
 396                if (!prop) {
 397                        pr_warn("CPU node missing reg property\n");
 398                        return false;
 399                }
 400                regs = prop->value;
 401                this_cpu_id = regs[0] & 0x0fffffff;
 402        } else {
 403                this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
 404
 405                if (this_cpu_id < 0) {
 406                        mid_prop = "cpuid";
 407                        this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
 408                }
 409                if (this_cpu_id < 0) {
 410                        pr_warn("CPU node missing cpu ID property\n");
 411                        return false;
 412                }
 413        }
 414        if (this_cpu_id == cpu) {
 415                if (thread) {
 416                        int proc_id = cpu_data(cpu).proc_id;
 417
 418                        /* On sparc64, the cpu thread information is obtained
 419                         * either from OBP or the machine description.  We've
 420                         * actually probed this information already long before
 421                         * this interface gets called so instead of interrogating
 422                         * both the OF node and the MDESC again, just use what
 423                         * we discovered already.
 424                         */
 425                        if (proc_id < 0)
 426                                proc_id = 0;
 427                        *thread = proc_id;
 428                }
 429                return true;
 430        }
 431        return false;
 432}
 433
 434static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
 435{
 436        struct device_node *dp;
 437        const char *mid_prop;
 438
 439        mid_prop = get_mid_prop();
 440        for_each_node_by_type(dp, "cpu") {
 441                int cpuid = of_getintprop_default(dp, mid_prop, -1);
 442                const char *this_mid_prop = mid_prop;
 443                void *ret;
 444
 445                if (cpuid < 0) {
 446                        this_mid_prop = "cpuid";
 447                        cpuid = of_getintprop_default(dp, this_mid_prop, -1);
 448                }
 449                if (cpuid < 0) {
 450                        prom_printf("OF: Serious problem, cpu lacks "
 451                                    "%s property", this_mid_prop);
 452                        prom_halt();
 453                }
 454#ifdef CONFIG_SMP
 455                if (cpuid >= NR_CPUS) {
 456                        printk(KERN_WARNING "Ignoring CPU %d which is "
 457                               ">= NR_CPUS (%d)\n",
 458                               cpuid, NR_CPUS);
 459                        continue;
 460                }
 461#endif
 462                ret = func(dp, cpuid, arg);
 463                if (ret)
 464                        return ret;
 465        }
 466        return NULL;
 467}
 468
 469static void *check_cpu_node(struct device_node *dp, int cpuid, int id)
 470{
 471        if (id == cpuid)
 472                return dp;
 473        return NULL;
 474}
 475
 476struct device_node *of_find_node_by_cpuid(int cpuid)
 477{
 478        return of_iterate_over_cpus(check_cpu_node, cpuid);
 479}
 480
 481static void *record_one_cpu(struct device_node *dp, int cpuid, int arg)
 482{
 483        ncpus_probed++;
 484#ifdef CONFIG_SMP
 485        set_cpu_present(cpuid, true);
 486        set_cpu_possible(cpuid, true);
 487#endif
 488        return NULL;
 489}
 490
 491void __init of_populate_present_mask(void)
 492{
 493        if (tlb_type == hypervisor)
 494                return;
 495
 496        ncpus_probed = 0;
 497        of_iterate_over_cpus(record_one_cpu, 0);
 498}
 499
 500static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg)
 501{
 502        struct device_node *portid_parent = NULL;
 503        int portid = -1;
 504
 505        if (of_find_property(dp, "cpuid", NULL)) {
 506                int limit = 2;
 507
 508                portid_parent = dp;
 509                while (limit--) {
 510                        portid_parent = portid_parent->parent;
 511                        if (!portid_parent)
 512                                break;
 513                        portid = of_getintprop_default(portid_parent,
 514                                                       "portid", -1);
 515                        if (portid >= 0)
 516                                break;
 517                }
 518        }
 519
 520#ifndef CONFIG_SMP
 521        /* On uniprocessor we only want the values for the
 522         * real physical cpu the kernel booted onto, however
 523         * cpu_data() only has one entry at index 0.
 524         */
 525        if (cpuid != real_hard_smp_processor_id())
 526                return NULL;
 527        cpuid = 0;
 528#endif
 529
 530        cpu_data(cpuid).clock_tick =
 531                of_getintprop_default(dp, "clock-frequency", 0);
 532
 533        if (portid_parent) {
 534                cpu_data(cpuid).dcache_size =
 535                        of_getintprop_default(dp, "l1-dcache-size",
 536                                              16 * 1024);
 537                cpu_data(cpuid).dcache_line_size =
 538                        of_getintprop_default(dp, "l1-dcache-line-size",
 539                                              32);
 540                cpu_data(cpuid).icache_size =
 541                        of_getintprop_default(dp, "l1-icache-size",
 542                                              8 * 1024);
 543                cpu_data(cpuid).icache_line_size =
 544                        of_getintprop_default(dp, "l1-icache-line-size",
 545                                              32);
 546                cpu_data(cpuid).ecache_size =
 547                        of_getintprop_default(dp, "l2-cache-size", 0);
 548                cpu_data(cpuid).ecache_line_size =
 549                        of_getintprop_default(dp, "l2-cache-line-size", 0);
 550                if (!cpu_data(cpuid).ecache_size ||
 551                    !cpu_data(cpuid).ecache_line_size) {
 552                        cpu_data(cpuid).ecache_size =
 553                                of_getintprop_default(portid_parent,
 554                                                      "l2-cache-size",
 555                                                      (4 * 1024 * 1024));
 556                        cpu_data(cpuid).ecache_line_size =
 557                                of_getintprop_default(portid_parent,
 558                                                      "l2-cache-line-size", 64);
 559                }
 560
 561                cpu_data(cpuid).core_id = portid + 1;
 562                cpu_data(cpuid).proc_id = portid;
 563        } else {
 564                cpu_data(cpuid).dcache_size =
 565                        of_getintprop_default(dp, "dcache-size", 16 * 1024);
 566                cpu_data(cpuid).dcache_line_size =
 567                        of_getintprop_default(dp, "dcache-line-size", 32);
 568
 569                cpu_data(cpuid).icache_size =
 570                        of_getintprop_default(dp, "icache-size", 16 * 1024);
 571                cpu_data(cpuid).icache_line_size =
 572                        of_getintprop_default(dp, "icache-line-size", 32);
 573
 574                cpu_data(cpuid).ecache_size =
 575                        of_getintprop_default(dp, "ecache-size",
 576                                              (4 * 1024 * 1024));
 577                cpu_data(cpuid).ecache_line_size =
 578                        of_getintprop_default(dp, "ecache-line-size", 64);
 579
 580                cpu_data(cpuid).core_id = 0;
 581                cpu_data(cpuid).proc_id = -1;
 582        }
 583
 584        return NULL;
 585}
 586
 587void __init of_fill_in_cpu_data(void)
 588{
 589        if (tlb_type == hypervisor)
 590                return;
 591
 592        of_iterate_over_cpus(fill_in_one_cpu, 0);
 593
 594        smp_fill_in_sib_core_maps();
 595}
 596
 597void __init of_console_init(void)
 598{
 599        char *msg = "OF stdout device is: %s\n";
 600        struct device_node *dp;
 601        phandle node;
 602
 603        of_console_path = prom_early_alloc(256);
 604        if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) {
 605                prom_printf("Cannot obtain path of stdout.\n");
 606                prom_halt();
 607        }
 608        of_console_options = strrchr(of_console_path, ':');
 609        if (of_console_options) {
 610                of_console_options++;
 611                if (*of_console_options == '\0')
 612                        of_console_options = NULL;
 613        }
 614
 615        node = prom_inst2pkg(prom_stdout);
 616        if (!node) {
 617                prom_printf("Cannot resolve stdout node from "
 618                            "instance %08x.\n", prom_stdout);
 619                prom_halt();
 620        }
 621
 622        dp = of_find_node_by_phandle(node);
 623
 624        if (!of_node_is_type(dp, "display") && !of_node_is_type(dp, "serial")) {
 625                prom_printf("Console device_type is neither display "
 626                            "nor serial.\n");
 627                prom_halt();
 628        }
 629
 630        of_console_device = dp;
 631
 632        printk(msg, of_console_path);
 633}
 634