Esempio n. 1
0
void vpd_iohub_load(struct dt_node *hub_node)
{
	char record[4] = "LXR0";
	const void *valid_lx;
	uint8_t lx_size;
	int r;
	const uint32_t *p;
	const uint8_t *lx;
	unsigned int lxrn;

	p = dt_prop_get_def(hub_node, "ibm,vpd-lx-info", NULL);
	if (!p)
		return;

	lxrn = p[0];
        lx = (const char *)&p[1];

	/* verify the lid preload has started */
	if (!vpd_lid || !vpd_lid_no) {
		prlog(PR_WARNING, "VPD: WARNING: Unable to load VPD lid");
		return;
	}

	r = fsp_wait_lid_loaded(vpd_lid_no);

	if (r)
		goto fail;

	/* Validate it */
	if (lxrn < 9)
		record[3] = '0' + lxrn;
	else
		memcpy(record, "VINI", 4);

	valid_lx = vpd_find(vpd_lid, vpd_lid_size, record, "LX", &lx_size);
	if (!valid_lx || lx_size != 8) {
		prerror("VPD: Cannot find validation LX record\n");
		goto fail;
	}
	if (memcmp(valid_lx, lx, 8) != 0) {
		prerror("VPD: LX record mismatch !\n");
		goto fail;
	}

	printf("VPD: Loaded %zu bytes\n", vpd_lid_size);

	dt_add_property(hub_node, "ibm,io-vpd", vpd_lid, vpd_lid_size);
	free(vpd_lid);
	return;

fail:
	free(vpd_lid);
	vpd_lid = NULL;
	prerror("VPD: Failed to load VPD LID\n");
	return;
}
Esempio n. 2
0
char *vpd_gets(const char *key, char *buffer, int size, enum vpd_region region)
{
	const void *string_address;
	int string_size;

	string_address = vpd_find(key, &string_size, region);

	if (!string_address)
		return NULL;

	if (size > (string_size + 1)) {
		memcpy(buffer, string_address, string_size);
		buffer[string_size] = '\0';
	} else {
		memcpy(buffer, string_address, size - 1);
		buffer[size - 1] = '\0';
	}
	return buffer;
}
Esempio n. 3
0
static void add_size_to_ram_area(struct dt_node *ram_node,
				 const struct HDIF_common_hdr *hdr,
				 int indx_vpd)
{
	const void	*fruvpd;
	unsigned int	fruvpd_sz;
	const void	*kw;
	char		*str;
	uint8_t		kwsz;

	fruvpd = HDIF_get_idata(hdr, indx_vpd, &fruvpd_sz);
	if (!CHECK_SPPTR(fruvpd))
		return;

	/* DIMM Size */
	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "SZ", &kwsz);
	if (!kw)
		return;

	str = zalloc(kwsz + 1);
	memcpy(str, kw, kwsz);
	dt_add_property_string(ram_node, "size", str);
	free(str);
}
Esempio n. 4
0
/* Helper to load a VPD LID. Pass a ptr to the corresponding LX keyword */
static void *vpd_lid_load(const uint8_t *lx, uint8_t lxrn, size_t *size)
{
    /* Now this is a guess game as we don't have the info from the
     * pHyp folks. But basically, it seems to boil down to loading
     * a LID whose name is 0x80e000yy where yy is the last 2 digits
     * of the LX record in hex.
     *
     * [ Correction: After a chat with some folks, it looks like it's
     * actually 4 digits, though the lid number is limited to fff
     * so we weren't far off. ]
     *
     * For safety, we look for a matching LX record in an LXRn
     * (n = lxrn argument) or in VINI if lxrn=0xff
     */
    uint32_t lid_no = 0x80e00000 | ((lx[6] & 0xf) << 8) | lx[7];

    /* We don't quite know how to get to the LID directory so
     * we don't know the size. Let's allocate 16K. All the VPD LIDs
     * I've seen so far are much smaller.
     */
#define VPD_LID_MAX_SIZE	0x4000
    void *data = malloc(VPD_LID_MAX_SIZE);
    char record[4] = "LXR0";
    const void *valid_lx;
    uint8_t lx_size;
    int rc;

    if (!data) {
        prerror("VPD: Failed to allocate memory for LID\n");
        return NULL;
    }

    /* Adjust LID number for flash side */
    lid_no = fsp_adjust_lid_side(lid_no);
    printf("VPD: Trying to load VPD LID 0x%08x...\n", lid_no);

    *size = VPD_LID_MAX_SIZE;

    /* Load it from the FSP */
    rc = fsp_fetch_data(0, FSP_DATASET_NONSP_LID, lid_no, 0, data, size);
    if (rc) {
        prerror("VPD: Error %d loading VPD LID\n", rc);
        goto fail;
    }

    /* Validate it */
    if (lxrn < 9)
        record[3] = '0' + lxrn;
    else
        memcpy(record, "VINI", 4);

    valid_lx = vpd_find(data, *size, record, "LX", &lx_size);
    if (!valid_lx || lx_size != 8) {
        prerror("VPD: Cannot find validation LX record\n");
        goto fail;
    }
    if (memcmp(valid_lx, lx, 8) != 0) {
        prerror("VPD: LX record mismatch !\n");
        goto fail;
    }

    printf("VPD: Loaded %zu bytes\n", *size);

    /* Got it ! */
    return realloc(data, *size);
fail:
    free(data);
    return NULL;
}