1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/types.h>
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unistd.h>
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h>
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h>
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h>
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "../../util/header.h"
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define __stringify_1(x)        #x
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define __stringify(x)          __stringify_1(x)
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define mfspr(rn)       ({unsigned long rval; \
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 asm volatile("mfspr %0," __stringify(rn) \
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				      : "=r" (rval)); rval; })
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define SPRN_PVR        0x11F	/* Processor Version Register */
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define PVR_VER(pvr)    (((pvr) >>  16) & 0xFFFF) /* Version field */
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define PVR_REV(pvr)    (((pvr) >>   0) & 0xFFFF) /* Revison field */
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengget_cpuid(char *buffer, size_t sz)
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned long pvr;
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int nb;
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pvr = mfspr(SPRN_PVR);
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	nb = scnprintf(buffer, sz, "%lu,%lu$", PVR_VER(pvr), PVR_REV(pvr));
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* look for end marker to ensure the entire data fit */
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (strchr(buffer, '$')) {
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		buffer[nb-1] = '\0';
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return 0;
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return -1;
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
37