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; }
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); }
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; }