cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

prom_64.c (15020B)


      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}