Пример #1
0
static bool add_address_range(struct dt_node *root,
			      const struct HDIF_ms_area_id *id,
			      const struct HDIF_ms_area_address_range *arange)
{
	struct dt_node *mem;
	u64 reg[2];
	char *name;
	u32 chip_id;
	size_t namesz = sizeof("memory@") + STR_MAX_CHARS(reg[0]);

	name = (char*)malloc(namesz);

	prlog(PR_DEBUG, "  Range: 0x%016llx..0x%016llx "
	      "on Chip 0x%x mattr: 0x%x\n",
	      (long long)arange->start, (long long)arange->end,
	      pcid_to_chip_id(arange->chip), arange->mirror_attr);

	/* reg contains start and length */
	reg[0] = cleanup_addr(be64_to_cpu(arange->start));
	reg[1] = cleanup_addr(be64_to_cpu(arange->end)) - reg[0];

	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));

	if (be16_to_cpu(id->flags) & MS_AREA_SHARED) {
		/* Only enter shared nodes once. */ 
		mem = find_shared(root, be16_to_cpu(id->share_id),
				  reg[0], reg[1]);
		if (mem) {
			append_chip_id(mem, chip_id);
			return true;
		}
	}
	snprintf(name, namesz, "memory@%llx", (long long)reg[0]);

	mem = dt_new(root, name);
	dt_add_property_string(mem, "device_type", "memory");
	dt_add_property_cells(mem, "ibm,chip-id", chip_id);
	dt_add_property_u64s(mem, "reg", reg[0], reg[1]);
	if (be16_to_cpu(id->flags) & MS_AREA_SHARED)
		dt_add_property_cells(mem, DT_PRIVATE "share-id",
				      be16_to_cpu(id->share_id));

	free(name);

	return true;
}
Пример #2
0
static void add_chip_id_to_ram_area(const struct HDIF_common_hdr *msarea,
				    struct dt_node *ram_area)
{
	const struct HDIF_array_hdr *arr;
	const struct HDIF_ms_area_address_range *arange;
	unsigned int size;
	u32 chip_id;

	/* Safe to assume pointers are valid here. */
	arr = HDIF_get_idata(msarea, 4, &size);
	arange = (void *)arr + be32_to_cpu(arr->offset);
	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));
	dt_add_property_cells(ram_area, "ibm,chip-id", chip_id);
}
Пример #3
0
static struct dt_node *add_cpu_node(struct dt_node *cpus,
				    const struct HDIF_common_hdr *paca,
				    const struct sppaca_cpu_id *id,
				    bool okay)
{
	const struct sppaca_cpu_timebase *timebase;
	const struct sppaca_cpu_cache *cache;
	const struct sppaca_cpu_attr *attr;
	struct dt_node *cpu;
	u32 no, size, ve_flags, l2_phandle, chip_id;

	/* We use the process_interrupt_line as the res id */
	no = be32_to_cpu(id->process_interrupt_line);

	ve_flags = be32_to_cpu(id->verify_exists_flags);
	prlog(PR_INFO, "CPU[%i]: PIR=%i RES=%i %s %s(%u threads)\n",
	       paca_index(paca), be32_to_cpu(id->pir), no,
	       ve_flags & CPU_ID_PACA_RESERVED
	       ? "**RESERVED**" : cpu_state(ve_flags),
	       ve_flags & CPU_ID_SECONDARY_THREAD
	       ? "[secondary] " : 
	       (be32_to_cpu(id->pir) == boot_cpu->pir ? "[boot] " : ""),
	       ((ve_flags & CPU_ID_NUM_SECONDARY_THREAD_MASK)
		>> CPU_ID_NUM_SECONDARY_THREAD_SHIFT) + 1);

	timebase = HDIF_get_idata(paca, SPPACA_IDATA_TIMEBASE, &size);
	if (!timebase || size < sizeof(*timebase)) {
		prerror("CPU[%i]: bad timebase size %u @ %p\n",
			paca_index(paca), size, timebase);
		return NULL;
	}

	cache = HDIF_get_idata(paca, SPPACA_IDATA_CACHE_SIZE, &size);
	if (!cache || size < sizeof(*cache)) {
		prerror("CPU[%i]: bad cache size %u @ %p\n",
			paca_index(paca), size, cache);
		return NULL;
	}

	cpu = add_core_common(cpus, cache, timebase, no, okay);

	/* Core attributes */
	attr = HDIF_get_idata(paca, SPPACA_IDATA_CPU_ATTR, &size);
	if (attr)
		add_core_attr(cpu, be32_to_cpu(attr->attr));

	/* Add cache info */
	l2_phandle = add_core_cache_info(cpus, cache, no, okay);
	dt_add_property_cells(cpu, "l2-cache", l2_phandle);

	/* We append the secondary cpus in __cpu_parse */
	dt_add_property_cells(cpu, "ibm,ppc-interrupt-server#s", no);

	dt_add_property_cells(cpu, DT_PRIVATE "hw_proc_id",
			      be32_to_cpu(id->hardware_proc_id));
	dt_add_property_cells(cpu, "ibm,pir", be32_to_cpu(id->pir));

	chip_id = pcid_to_chip_id(be32_to_cpu(id->processor_chip_id));
	dt_add_property_cells(cpu, "ibm,chip-id", chip_id);

	return cpu;
}