2 * Copyright (c) 2019 Leandro Lupori
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
33 #define PVR_CPU_P8E 0x004b0000
34 #define PVR_CPU_P8NVL 0x004c0000
35 #define PVR_CPU_P8 0x004d0000
36 #define PVR_CPU_P9 0x004e0000
37 #define PVR_CPU_MASK 0xffff0000
39 #define PVR_ISA_207 0x0f000004
40 #define PVR_ISA_300 0x0f000005
41 #define PVR_ISA_MASK 0xffffffff
43 /* loader version of kernel's CPU_MAXSIZE */
44 #define MAX_CPUS ((uint32_t)256u)
46 /* Option Vectors' settings */
48 /* length of ignored OV */
51 /* byte 1 (of any OV) */
58 #define OV5_SPLPAR 0x40
59 #define OV5_DRMEM 0x20
61 #define OV5_ALPHA_PART 0x08
62 #define OV5_DMA_DELAY 0x04
63 #define OV5_DONATE_CPU 0x02
67 #define OV5_MAX_CPUS(n) ((MAX_CPUS >> (3*8 - (n)*8)) & 0xff)
69 /* 13-14: LoPAPR Level */
70 #define LOPAPR_LEVEL 0x0101 /* 1.1 */
71 #define OV5_LOPAPR_LEVEL(n) ((LOPAPR_LEVEL >> (8 - (n)*8)) & 0xff)
73 /* byte 17: Platform Facilities */
75 #define OV5_COMP_ENG 0x40
76 #define OV5_ENC_ENG 0x20
78 /* byte 21: Sub-Processors */
79 #define OV5_NO_SUBPROCS 0
80 #define OV5_SUBPROCS 1
82 /* byte 23: interrupt controller */
83 #define OV5_INTC_XICS 0
88 /* byte 25: HPT MMU Extensions */
89 #define OV5_HPT_EXT_NONE 0
91 /* byte 26: Radix MMU Extensions */
92 #define OV5_RPT_EXT_NONE 0
100 struct opt_vec_ignore {
112 static struct ibm_arch_vec {
113 struct pvr pvr_list[7];
115 struct opt_vec_ignore vec1;
116 struct opt_vec_ignore vec2;
117 struct opt_vec_ignore vec3;
118 struct opt_vec4 vec4;
119 struct opt_vec5 vec5;
120 } __packed ibm_arch_vec = {
122 { PVR_CPU_MASK, PVR_CPU_P8 }, /* POWER8 */
123 { PVR_CPU_MASK, PVR_CPU_P8E }, /* POWER8E */
124 { PVR_CPU_MASK, PVR_CPU_P8NVL }, /* POWER8NVL */
125 { PVR_CPU_MASK, PVR_CPU_P9 }, /* POWER9 */
126 { PVR_ISA_MASK, PVR_ISA_207 }, /* All ISA 2.07 */
127 { PVR_ISA_MASK, PVR_ISA_300 }, /* All ISA 3.00 */
128 { 0, 0xffffffffu } /* terminator */
130 4, /* num_opts (4 actually means 5 option vectors) */
131 { OV_IGN_LEN, OV_IGN }, /* OV1 */
132 { OV_IGN_LEN, OV_IGN }, /* OV2 */
133 { OV_IGN_LEN, OV_IGN }, /* OV3 */
134 /* OV4 (can't be ignored) */ {
135 sizeof(struct opt_vec4) - 2, /* length (n-2) */
137 10 /* Minimum VP entitled capacity percentage * 100
138 * (if absent assume 10%) */
141 sizeof(struct opt_vec5) - 2, /* length (n-2) */
142 0, /* don't ignore */
143 OV5_LPAR | OV5_SPLPAR | OV5_LP | OV5_MSI,
145 0, /* Cooperative Memory Over-commitment */
146 0, /* Associativity Information Option */
147 0, /* Binary Option Controls */
151 OV5_MAX_CPUS(1), /* 10 */
158 0, /* Platform Facilities */
161 0, /* Reserved */ /* 20 */
171 static __inline register_t
176 __asm __volatile ("mfpvr %0" : "=r"(value));
186 /* PSL_HV is bit 3 of 64-bit MSR */
187 __asm __volatile ("mfmsr %0\n\t"
188 "rldicl %0,%0,4,63" : "=r"(hv));
200 /* Perform CAS only for POWER8 and later cores */
201 switch (mfpvr() & PVR_CPU_MASK) {
211 /* Skip CAS when running on PowerNV */
215 ihandle = OF_open("/");
217 printf("cas: failed to open / node\n");
221 if (rc = OF_call_method("ibm,client-architecture-support",
222 ihandle, 1, 1, &ibm_arch_vec, &err))
223 printf("cas: failed to call CAS method\n");
225 printf("cas: error: 0x%08lX\n", err);