Changeset View
Changeset View
Standalone View
Standalone View
stand/powerpc/ofw/cas.c
Show All 23 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <openfirm.h> | #include <openfirm.h> | ||||
#include <stand.h> | #include <stand.h> | ||||
#define CAS_DEBUG 0 | |||||
#if CAS_DEBUG | |||||
jhibbits: Why not make this a #ifdef instead? | |||||
Done Inline ActionsOk, I've used #if just because it's a bit less typing to enable/disable it. luporl: Ok, I've used #if just because it's a bit less typing to enable/disable it. | |||||
#define DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) | |||||
#else | |||||
#define DPRINTF(fmt, ...) do { ; } while (0) | |||||
#endif | |||||
/* PVR */ | /* PVR */ | ||||
#define PVR_CPU_P8E 0x004b0000 | #define PVR_CPU_P8E 0x004b0000 | ||||
#define PVR_CPU_P8NVL 0x004c0000 | #define PVR_CPU_P8NVL 0x004c0000 | ||||
#define PVR_CPU_P8 0x004d0000 | #define PVR_CPU_P8 0x004d0000 | ||||
#define PVR_CPU_P9 0x004e0000 | #define PVR_CPU_P9 0x004e0000 | ||||
#define PVR_CPU_MASK 0xffff0000 | #define PVR_CPU_MASK 0xffff0000 | ||||
#define PVR_ISA_207 0x0f000004 | #define PVR_ISA_207 0x0f000004 | ||||
Show All 38 Lines | |||||
/* byte 21: Sub-Processors */ | /* byte 21: Sub-Processors */ | ||||
#define OV5_NO_SUBPROCS 0 | #define OV5_NO_SUBPROCS 0 | ||||
#define OV5_SUBPROCS 1 | #define OV5_SUBPROCS 1 | ||||
/* byte 23: interrupt controller */ | /* byte 23: interrupt controller */ | ||||
#define OV5_INTC_XICS 0 | #define OV5_INTC_XICS 0 | ||||
/* byte 24: MMU */ | /* byte 24: MMU */ | ||||
#define OV5_MMU_INDEX 24 | |||||
#define OV5_MMU_HPT 0 | #define OV5_MMU_HPT 0 | ||||
#define OV5_MMU_RADIX 0x40 | |||||
#define OV5_MMU_EITHER 0x80 | |||||
#define OV5_MMU_DYNAMIC 0xc0 | |||||
/* byte 25: HPT MMU Extensions */ | /* byte 25: HPT MMU Extensions */ | ||||
#define OV5_HPT_EXT_NONE 0 | #define OV5_HPT_EXT_INDEX 25 | ||||
#define OV5_HPT_GTSE 0x40 | |||||
/* byte 26: Radix MMU Extensions */ | /* byte 26: Radix MMU Extensions */ | ||||
#define OV5_RPT_EXT_NONE 0 | #define OV5_RADIX_EXT_INDEX 26 | ||||
#define OV5_RADIX_GTSE 0x40 | |||||
struct pvr { | struct pvr { | ||||
uint32_t mask; | uint32_t mask; | ||||
uint32_t val; | uint32_t val; | ||||
}; | }; | ||||
struct opt_vec_ignore { | struct opt_vec_ignore { | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | /* OV5 */ { | ||||
0, /* Platform Facilities */ | 0, /* Platform Facilities */ | ||||
0, /* Reserved */ | 0, /* Reserved */ | ||||
0, /* Reserved */ | 0, /* Reserved */ | ||||
0, /* Reserved */ /* 20 */ | 0, /* Reserved */ /* 20 */ | ||||
OV5_NO_SUBPROCS, | OV5_NO_SUBPROCS, | ||||
0, /* DRMEM_V2 */ | 0, /* DRMEM_V2 */ | ||||
OV5_INTC_XICS, | OV5_INTC_XICS, | ||||
OV5_MMU_HPT, | OV5_MMU_HPT, | ||||
OV5_HPT_EXT_NONE, | 0, | ||||
OV5_RPT_EXT_NONE | 0 | ||||
} | } | ||||
}; | }; | ||||
static __inline register_t | int | ||||
mfpvr(void) | ppc64_cas(void) | ||||
{ | { | ||||
register_t value; | phandle_t pkg; | ||||
ihandle_t inst; | |||||
cell_t err; | |||||
uint8_t buf[16], idx, val; | |||||
int i, len, rc, radix_mmu; | |||||
const char *var; | |||||
char *ov5; | |||||
__asm __volatile ("mfpvr %0" : "=r"(value)); | pkg = OF_finddevice("/chosen"); | ||||
if (pkg == -1) { | |||||
return (value); | printf("cas: couldn't find /chosen\n"); | ||||
return (-1); | |||||
} | } | ||||
static __inline int | len = OF_getprop(pkg, "ibm,arch-vec-5-platform-support", buf, | ||||
ppc64_hv(void) | sizeof(buf)); | ||||
{ | if (len == -1) | ||||
int hv; | /* CAS not supported */ | ||||
return (0); | |||||
/* PSL_HV is bit 3 of 64-bit MSR */ | radix_mmu = 0; | ||||
__asm __volatile ("mfmsr %0\n\t" | ov5 = ibm_arch_vec.vec5.data; | ||||
"rldicl %0,%0,4,63" : "=r"(hv)); | for (i = 0; i < len; i += 2) { | ||||
idx = buf[i]; | |||||
val = buf[i + 1]; | |||||
DPRINTF("idx 0x%02x val 0x%02x\n", idx, val); | |||||
return (hv); | switch (idx) { | ||||
} | case OV5_MMU_INDEX: | ||||
/* | |||||
* Note that testing for OV5_MMU_RADIX/OV5_MMU_EITHER | |||||
* also covers OV5_MMU_DYNAMIC. | |||||
*/ | |||||
if ((val & OV5_MMU_RADIX) || (val & OV5_MMU_EITHER)) | |||||
radix_mmu = 1; | |||||
int | case OV5_RADIX_EXT_INDEX: | ||||
ppc64_cas(void) | if (val & OV5_RADIX_GTSE) | ||||
{ | ov5[idx] = OV5_RADIX_GTSE; | ||||
int rc; | |||||
ihandle_t ihandle; | |||||
cell_t err; | |||||
/* Perform CAS only for POWER8 and later cores */ | |||||
switch (mfpvr() & PVR_CPU_MASK) { | |||||
case PVR_CPU_P8: | |||||
case PVR_CPU_P8E: | |||||
case PVR_CPU_P8NVL: | |||||
case PVR_CPU_P9: | |||||
break; | break; | ||||
case OV5_HPT_EXT_INDEX: | |||||
default: | default: | ||||
return (0); | break; | ||||
} | } | ||||
} | |||||
/* Skip CAS when running on PowerNV */ | if (radix_mmu && (var = getenv("radix_mmu")) != NULL && var[0] != '0') | ||||
if (ppc64_hv()) | ov5[OV5_MMU_INDEX] = OV5_MMU_RADIX; | ||||
return (0); | else | ||||
radix_mmu = 0; | |||||
ihandle = OF_open("/"); | inst = OF_open("/"); | ||||
Done Inline ActionsDefaulting off for radix_mmu, even on power9? jhibbits: Defaulting off for radix_mmu, even on power9? | |||||
Done Inline Actionsluporl: Yes, we are holding making radix default because of D31232. BTW, do you think it is ok to… | |||||
Done Inline ActionsThat's all I wanted to know, thanks! jhibbits: That's all I wanted to know, thanks! | |||||
if (ihandle == -1) { | if (inst == -1) { | ||||
printf("cas: failed to open / node\n"); | printf("cas: failed to open / node\n"); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
if (rc = OF_call_method("ibm,client-architecture-support", | DPRINTF("MMU 0x%02x RADIX_EXT 0x%02x\n", | ||||
ihandle, 1, 1, &ibm_arch_vec, &err)) | ov5[OV5_MMU_INDEX], ov5[OV5_RADIX_EXT_INDEX]); | ||||
printf("cas: failed to call CAS method\n"); | rc = OF_call_method("ibm,client-architecture-support", | ||||
else if (err) { | inst, 1, 1, &ibm_arch_vec, &err); | ||||
printf("cas: error: 0x%08lX\n", err); | if (rc != 0 || err) { | ||||
printf("cas: CAS method returned an error: rc %d err %jd\n", | |||||
rc, (intmax_t)err); | |||||
rc = -1; | rc = -1; | ||||
} | } | ||||
OF_close(ihandle); | OF_close(inst); | ||||
printf("cas: selected %s MMU\n", radix_mmu ? "radix" : "hash"); | |||||
return (rc); | return (rc); | ||||
} | } |
Why not make this a #ifdef instead?