Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Procedures for creating, accessing and interpreting the device tree.
0004  *
0005  * Paul Mackerras   August 1996.
0006  * Copyright (C) 1996-2005 Paul Mackerras.
0007  * 
0008  *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
0009  *    {engebret|bergner}@us.ibm.com 
0010  *
0011  *  Adapted for sparc64 by David S. Miller davem@davemloft.net
0012  */
0013 
0014 #include <linux/memblock.h>
0015 #include <linux/kernel.h>
0016 #include <linux/string.h>
0017 #include <linux/types.h>
0018 #include <linux/cpu.h>
0019 #include <linux/mm.h>
0020 #include <linux/of.h>
0021 
0022 #include <asm/prom.h>
0023 #include <asm/oplib.h>
0024 #include <asm/irq.h>
0025 #include <asm/asi.h>
0026 #include <asm/upa.h>
0027 #include <asm/smp.h>
0028 
0029 #include "prom.h"
0030 
0031 void * __init prom_early_alloc(unsigned long size)
0032 {
0033     void *ret = memblock_alloc(size, SMP_CACHE_BYTES);
0034 
0035     if (!ret) {
0036         prom_printf("prom_early_alloc(%lu) failed\n", size);
0037         prom_halt();
0038     }
0039 
0040     prom_early_allocated += size;
0041 
0042     return ret;
0043 }
0044 
0045 /* The following routines deal with the black magic of fully naming a
0046  * node.
0047  *
0048  * Certain well known named nodes are just the simple name string.
0049  *
0050  * Actual devices have an address specifier appended to the base name
0051  * string, like this "foo@addr".  The "addr" can be in any number of
0052  * formats, and the platform plus the type of the node determine the
0053  * format and how it is constructed.
0054  *
0055  * For children of the ROOT node, the naming convention is fixed and
0056  * determined by whether this is a sun4u or sun4v system.
0057  *
0058  * For children of other nodes, it is bus type specific.  So
0059  * we walk up the tree until we discover a "device_type" property
0060  * we recognize and we go from there.
0061  *
0062  * As an example, the boot device on my workstation has a full path:
0063  *
0064  *  /pci@1e,600000/ide@d/disk@0,0:c
0065  */
0066 static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
0067 {
0068     const char *name = of_get_property(dp, "name", NULL);
0069     struct linux_prom64_registers *regs;
0070     struct property *rprop;
0071     u32 high_bits, low_bits, type;
0072 
0073     rprop = of_find_property(dp, "reg", NULL);
0074     if (!rprop)
0075         return;
0076 
0077     regs = rprop->value;
0078     if (!of_node_is_root(dp->parent)) {
0079         sprintf(tmp_buf, "%s@%x,%x",
0080             name,
0081             (unsigned int) (regs->phys_addr >> 32UL),
0082             (unsigned int) (regs->phys_addr & 0xffffffffUL));
0083         return;
0084     }
0085 
0086     type = regs->phys_addr >> 60UL;
0087     high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
0088     low_bits = (regs->phys_addr & 0xffffffffUL);
0089 
0090     if (type == 0 || type == 8) {
0091         const char *prefix = (type == 0) ? "m" : "i";
0092 
0093         if (low_bits)
0094             sprintf(tmp_buf, "%s@%s%x,%x",
0095                 name, prefix,
0096                 high_bits, low_bits);
0097         else
0098             sprintf(tmp_buf, "%s@%s%x",
0099                 name,
0100                 prefix,
0101                 high_bits);
0102     } else if (type == 12) {
0103         sprintf(tmp_buf, "%s@%x",
0104             name, high_bits);
0105     }
0106 }
0107 
0108 static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
0109 {
0110     const char *name = of_get_property(dp, "name", NULL);
0111     struct linux_prom64_registers *regs;
0112     struct property *prop;
0113 
0114     prop = of_find_property(dp, "reg", NULL);
0115     if (!prop)
0116         return;
0117 
0118     regs = prop->value;
0119     if (!of_node_is_root(dp->parent)) {
0120         sprintf(tmp_buf, "%s@%x,%x",
0121             name,
0122             (unsigned int) (regs->phys_addr >> 32UL),
0123             (unsigned int) (regs->phys_addr & 0xffffffffUL));
0124         return;
0125     }
0126 
0127     prop = of_find_property(dp, "upa-portid", NULL);
0128     if (!prop)
0129         prop = of_find_property(dp, "portid", NULL);
0130     if (prop) {
0131         unsigned long mask = 0xffffffffUL;
0132 
0133         if (tlb_type >= cheetah)
0134             mask = 0x7fffff;
0135 
0136         sprintf(tmp_buf, "%s@%x,%x",
0137             name,
0138             *(u32 *)prop->value,
0139             (unsigned int) (regs->phys_addr & mask));
0140     }
0141 }
0142 
0143 /* "name@slot,offset"  */
0144 static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
0145 {
0146     const char *name = of_get_property(dp, "name", NULL);
0147     struct linux_prom_registers *regs;
0148     struct property *prop;
0149 
0150     prop = of_find_property(dp, "reg", NULL);
0151     if (!prop)
0152         return;
0153 
0154     regs = prop->value;
0155     sprintf(tmp_buf, "%s@%x,%x",
0156         name,
0157         regs->which_io,
0158         regs->phys_addr);
0159 }
0160 
0161 /* "name@devnum[,func]" */
0162 static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
0163 {
0164     const char *name = of_get_property(dp, "name", NULL);
0165     struct linux_prom_pci_registers *regs;
0166     struct property *prop;
0167     unsigned int devfn;
0168 
0169     prop = of_find_property(dp, "reg", NULL);
0170     if (!prop)
0171         return;
0172 
0173     regs = prop->value;
0174     devfn = (regs->phys_hi >> 8) & 0xff;
0175     if (devfn & 0x07) {
0176         sprintf(tmp_buf, "%s@%x,%x",
0177             name,
0178             devfn >> 3,
0179             devfn & 0x07);
0180     } else {
0181         sprintf(tmp_buf, "%s@%x",
0182             name,
0183             devfn >> 3);
0184     }
0185 }
0186 
0187 /* "name@UPA_PORTID,offset" */
0188 static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
0189 {
0190     const char *name = of_get_property(dp, "name", NULL);
0191     struct linux_prom64_registers *regs;
0192     struct property *prop;
0193 
0194     prop = of_find_property(dp, "reg", NULL);
0195     if (!prop)
0196         return;
0197 
0198     regs = prop->value;
0199 
0200     prop = of_find_property(dp, "upa-portid", NULL);
0201     if (!prop)
0202         return;
0203 
0204     sprintf(tmp_buf, "%s@%x,%x",
0205         name,
0206         *(u32 *) prop->value,
0207         (unsigned int) (regs->phys_addr & 0xffffffffUL));
0208 }
0209 
0210 /* "name@reg" */
0211 static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
0212 {
0213     const char *name = of_get_property(dp, "name", NULL);
0214     struct property *prop;
0215     u32 *regs;
0216 
0217     prop = of_find_property(dp, "reg", NULL);
0218     if (!prop)
0219         return;
0220 
0221     regs = prop->value;
0222 
0223     sprintf(tmp_buf, "%s@%x", name, *regs);
0224 }
0225 
0226 /* "name@addrhi,addrlo" */
0227 static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
0228 {
0229     const char *name = of_get_property(dp, "name", NULL);
0230     struct linux_prom64_registers *regs;
0231     struct property *prop;
0232 
0233     prop = of_find_property(dp, "reg", NULL);
0234     if (!prop)
0235         return;
0236 
0237     regs = prop->value;
0238 
0239     sprintf(tmp_buf, "%s@%x,%x",
0240         name,
0241         (unsigned int) (regs->phys_addr >> 32UL),
0242         (unsigned int) (regs->phys_addr & 0xffffffffUL));
0243 }
0244 
0245 /* "name@bus,addr" */
0246 static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
0247 {
0248     const char *name = of_get_property(dp, "name", NULL);
0249     struct property *prop;
0250     u32 *regs;
0251 
0252     prop = of_find_property(dp, "reg", NULL);
0253     if (!prop)
0254         return;
0255 
0256     regs = prop->value;
0257 
0258     /* This actually isn't right... should look at the #address-cells
0259      * property of the i2c bus node etc. etc.
0260      */
0261     sprintf(tmp_buf, "%s@%x,%x",
0262         name, regs[0], regs[1]);
0263 }
0264 
0265 /* "name@reg0[,reg1]" */
0266 static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
0267 {
0268     const char *name = of_get_property(dp, "name", NULL);
0269     struct property *prop;
0270     u32 *regs;
0271 
0272     prop = of_find_property(dp, "reg", NULL);
0273     if (!prop)
0274         return;
0275 
0276     regs = prop->value;
0277 
0278     if (prop->length == sizeof(u32) || regs[1] == 1) {
0279         sprintf(tmp_buf, "%s@%x",
0280             name, regs[0]);
0281     } else {
0282         sprintf(tmp_buf, "%s@%x,%x",
0283             name, regs[0], regs[1]);
0284     }
0285 }
0286 
0287 /* "name@reg0reg1[,reg2reg3]" */
0288 static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
0289 {
0290     const char *name = of_get_property(dp, "name", NULL);
0291     struct property *prop;
0292     u32 *regs;
0293 
0294     prop = of_find_property(dp, "reg", NULL);
0295     if (!prop)
0296         return;
0297 
0298     regs = prop->value;
0299 
0300     if (regs[2] || regs[3]) {
0301         sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
0302             name, regs[0], regs[1], regs[2], regs[3]);
0303     } else {
0304         sprintf(tmp_buf, "%s@%08x%08x",
0305             name, regs[0], regs[1]);
0306     }
0307 }
0308 
0309 static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
0310 {
0311     struct device_node *parent = dp->parent;
0312 
0313     if (parent != NULL) {
0314         if (of_node_is_type(parent, "pci") ||
0315             of_node_is_type(parent, "pciex")) {
0316             pci_path_component(dp, tmp_buf);
0317             return;
0318         }
0319         if (of_node_is_type(parent, "sbus")) {
0320             sbus_path_component(dp, tmp_buf);
0321             return;
0322         }
0323         if (of_node_is_type(parent, "upa")) {
0324             upa_path_component(dp, tmp_buf);
0325             return;
0326         }
0327         if (of_node_is_type(parent, "ebus")) {
0328             ebus_path_component(dp, tmp_buf);
0329             return;
0330         }
0331         if (of_node_name_eq(parent, "usb") ||
0332             of_node_name_eq(parent, "hub")) {
0333             usb_path_component(dp, tmp_buf);
0334             return;
0335         }
0336         if (of_node_is_type(parent, "i2c")) {
0337             i2c_path_component(dp, tmp_buf);
0338             return;
0339         }
0340         if (of_node_is_type(parent, "firewire")) {
0341             ieee1394_path_component(dp, tmp_buf);
0342             return;
0343         }
0344         if (of_node_is_type(parent, "virtual-devices")) {
0345             vdev_path_component(dp, tmp_buf);
0346             return;
0347         }
0348         /* "isa" is handled with platform naming */
0349     }
0350 
0351     /* Use platform naming convention.  */
0352     if (tlb_type == hypervisor) {
0353         sun4v_path_component(dp, tmp_buf);
0354         return;
0355     } else {
0356         sun4u_path_component(dp, tmp_buf);
0357     }
0358 }
0359 
0360 char * __init build_path_component(struct device_node *dp)
0361 {
0362     const char *name = of_get_property(dp, "name", NULL);
0363     char tmp_buf[64], *n;
0364 
0365     tmp_buf[0] = '\0';
0366     __build_path_component(dp, tmp_buf);
0367     if (tmp_buf[0] == '\0')
0368         strcpy(tmp_buf, name);
0369 
0370     n = prom_early_alloc(strlen(tmp_buf) + 1);
0371     strcpy(n, tmp_buf);
0372 
0373     return n;
0374 }
0375 
0376 static const char *get_mid_prop(void)
0377 {
0378     return (tlb_type == spitfire ? "upa-portid" : "portid");
0379 }
0380 
0381 bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
0382                        int cpu, unsigned int *thread)
0383 {
0384     const char *mid_prop = get_mid_prop();
0385     int this_cpu_id;
0386 
0387     /* On hypervisor based platforms we interrogate the 'reg'
0388      * property.  On everything else we look for a 'upa-portid',
0389      * 'portid', or 'cpuid' property.
0390      */
0391 
0392     if (tlb_type == hypervisor) {
0393         struct property *prop = of_find_property(cpun, "reg", NULL);
0394         u32 *regs;
0395 
0396         if (!prop) {
0397             pr_warn("CPU node missing reg property\n");
0398             return false;
0399         }
0400         regs = prop->value;
0401         this_cpu_id = regs[0] & 0x0fffffff;
0402     } else {
0403         this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
0404 
0405         if (this_cpu_id < 0) {
0406             mid_prop = "cpuid";
0407             this_cpu_id = of_getintprop_default(cpun, mid_prop, -1);
0408         }
0409         if (this_cpu_id < 0) {
0410             pr_warn("CPU node missing cpu ID property\n");
0411             return false;
0412         }
0413     }
0414     if (this_cpu_id == cpu) {
0415         if (thread) {
0416             int proc_id = cpu_data(cpu).proc_id;
0417 
0418             /* On sparc64, the cpu thread information is obtained
0419              * either from OBP or the machine description.  We've
0420              * actually probed this information already long before
0421              * this interface gets called so instead of interrogating
0422              * both the OF node and the MDESC again, just use what
0423              * we discovered already.
0424              */
0425             if (proc_id < 0)
0426                 proc_id = 0;
0427             *thread = proc_id;
0428         }
0429         return true;
0430     }
0431     return false;
0432 }
0433 
0434 static void *of_iterate_over_cpus(void *(*func)(struct device_node *, int, int), int arg)
0435 {
0436     struct device_node *dp;
0437     const char *mid_prop;
0438 
0439     mid_prop = get_mid_prop();
0440     for_each_node_by_type(dp, "cpu") {
0441         int cpuid = of_getintprop_default(dp, mid_prop, -1);
0442         const char *this_mid_prop = mid_prop;
0443         void *ret;
0444 
0445         if (cpuid < 0) {
0446             this_mid_prop = "cpuid";
0447             cpuid = of_getintprop_default(dp, this_mid_prop, -1);
0448         }
0449         if (cpuid < 0) {
0450             prom_printf("OF: Serious problem, cpu lacks "
0451                     "%s property", this_mid_prop);
0452             prom_halt();
0453         }
0454 #ifdef CONFIG_SMP
0455         if (cpuid >= NR_CPUS) {
0456             printk(KERN_WARNING "Ignoring CPU %d which is "
0457                    ">= NR_CPUS (%d)\n",
0458                    cpuid, NR_CPUS);
0459             continue;
0460         }
0461 #endif
0462         ret = func(dp, cpuid, arg);
0463         if (ret)
0464             return ret;
0465     }
0466     return NULL;
0467 }
0468 
0469 static void *check_cpu_node(struct device_node *dp, int cpuid, int id)
0470 {
0471     if (id == cpuid)
0472         return dp;
0473     return NULL;
0474 }
0475 
0476 struct device_node *of_find_node_by_cpuid(int cpuid)
0477 {
0478     return of_iterate_over_cpus(check_cpu_node, cpuid);
0479 }
0480 
0481 static void *record_one_cpu(struct device_node *dp, int cpuid, int arg)
0482 {
0483     ncpus_probed++;
0484 #ifdef CONFIG_SMP
0485     set_cpu_present(cpuid, true);
0486     set_cpu_possible(cpuid, true);
0487 #endif
0488     return NULL;
0489 }
0490 
0491 void __init of_populate_present_mask(void)
0492 {
0493     if (tlb_type == hypervisor)
0494         return;
0495 
0496     ncpus_probed = 0;
0497     of_iterate_over_cpus(record_one_cpu, 0);
0498 }
0499 
0500 static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg)
0501 {
0502     struct device_node *portid_parent = NULL;
0503     int portid = -1;
0504 
0505     if (of_find_property(dp, "cpuid", NULL)) {
0506         int limit = 2;
0507 
0508         portid_parent = dp;
0509         while (limit--) {
0510             portid_parent = portid_parent->parent;
0511             if (!portid_parent)
0512                 break;
0513             portid = of_getintprop_default(portid_parent,
0514                                "portid", -1);
0515             if (portid >= 0)
0516                 break;
0517         }
0518     }
0519 
0520 #ifndef CONFIG_SMP
0521     /* On uniprocessor we only want the values for the
0522      * real physical cpu the kernel booted onto, however
0523      * cpu_data() only has one entry at index 0.
0524      */
0525     if (cpuid != real_hard_smp_processor_id())
0526         return NULL;
0527     cpuid = 0;
0528 #endif
0529 
0530     cpu_data(cpuid).clock_tick =
0531         of_getintprop_default(dp, "clock-frequency", 0);
0532 
0533     if (portid_parent) {
0534         cpu_data(cpuid).dcache_size =
0535             of_getintprop_default(dp, "l1-dcache-size",
0536                           16 * 1024);
0537         cpu_data(cpuid).dcache_line_size =
0538             of_getintprop_default(dp, "l1-dcache-line-size",
0539                           32);
0540         cpu_data(cpuid).icache_size =
0541             of_getintprop_default(dp, "l1-icache-size",
0542                           8 * 1024);
0543         cpu_data(cpuid).icache_line_size =
0544             of_getintprop_default(dp, "l1-icache-line-size",
0545                           32);
0546         cpu_data(cpuid).ecache_size =
0547             of_getintprop_default(dp, "l2-cache-size", 0);
0548         cpu_data(cpuid).ecache_line_size =
0549             of_getintprop_default(dp, "l2-cache-line-size", 0);
0550         if (!cpu_data(cpuid).ecache_size ||
0551             !cpu_data(cpuid).ecache_line_size) {
0552             cpu_data(cpuid).ecache_size =
0553                 of_getintprop_default(portid_parent,
0554                               "l2-cache-size",
0555                               (4 * 1024 * 1024));
0556             cpu_data(cpuid).ecache_line_size =
0557                 of_getintprop_default(portid_parent,
0558                               "l2-cache-line-size", 64);
0559         }
0560 
0561         cpu_data(cpuid).core_id = portid + 1;
0562         cpu_data(cpuid).proc_id = portid;
0563     } else {
0564         cpu_data(cpuid).dcache_size =
0565             of_getintprop_default(dp, "dcache-size", 16 * 1024);
0566         cpu_data(cpuid).dcache_line_size =
0567             of_getintprop_default(dp, "dcache-line-size", 32);
0568 
0569         cpu_data(cpuid).icache_size =
0570             of_getintprop_default(dp, "icache-size", 16 * 1024);
0571         cpu_data(cpuid).icache_line_size =
0572             of_getintprop_default(dp, "icache-line-size", 32);
0573 
0574         cpu_data(cpuid).ecache_size =
0575             of_getintprop_default(dp, "ecache-size",
0576                           (4 * 1024 * 1024));
0577         cpu_data(cpuid).ecache_line_size =
0578             of_getintprop_default(dp, "ecache-line-size", 64);
0579 
0580         cpu_data(cpuid).core_id = 0;
0581         cpu_data(cpuid).proc_id = -1;
0582     }
0583 
0584     return NULL;
0585 }
0586 
0587 void __init of_fill_in_cpu_data(void)
0588 {
0589     if (tlb_type == hypervisor)
0590         return;
0591 
0592     of_iterate_over_cpus(fill_in_one_cpu, 0);
0593 
0594     smp_fill_in_sib_core_maps();
0595 }
0596 
0597 void __init of_console_init(void)
0598 {
0599     char *msg = "OF stdout device is: %s\n";
0600     struct device_node *dp;
0601     phandle node;
0602 
0603     of_console_path = prom_early_alloc(256);
0604     if (prom_ihandle2path(prom_stdout, of_console_path, 256) < 0) {
0605         prom_printf("Cannot obtain path of stdout.\n");
0606         prom_halt();
0607     }
0608     of_console_options = strrchr(of_console_path, ':');
0609     if (of_console_options) {
0610         of_console_options++;
0611         if (*of_console_options == '\0')
0612             of_console_options = NULL;
0613     }
0614 
0615     node = prom_inst2pkg(prom_stdout);
0616     if (!node) {
0617         prom_printf("Cannot resolve stdout node from "
0618                 "instance %08x.\n", prom_stdout);
0619         prom_halt();
0620     }
0621 
0622     dp = of_find_node_by_phandle(node);
0623 
0624     if (!of_node_is_type(dp, "display") && !of_node_is_type(dp, "serial")) {
0625         prom_printf("Console device_type is neither display "
0626                 "nor serial.\n");
0627         prom_halt();
0628     }
0629 
0630     of_console_device = dp;
0631 
0632     printk(msg, of_console_path);
0633 }