1#- 2# Copyright (c) 2009 Nathan Whitehorn 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# 27 28#include <sys/param.h> 29#include <sys/lock.h> 30#include <sys/mutex.h> 31#include <sys/systm.h> 32#include <sys/smp.h> 33 34#include <machine/ofw_machdep.h> 35#include <machine/platform.h> 36#include <machine/platformvar.h> 37#include <machine/smp.h> 38#include <machine/vmparam.h> 39 40/** 41 * @defgroup PLATFORM platform - KObj methods for PowerPC platform 42 * implementations 43 * @brief A set of methods required by all platform implementations. 44 * These are used to bring up secondary CPUs, supply the physical memory 45 * map, etc. 46 *@{ 47 */ 48 49INTERFACE platform; 50 51# 52# Default implementations 53# 54CODE { 55 static void platform_null_attach(platform_t plat) 56 { 57 return; 58 } 59 static int platform_null_smp_first_cpu(platform_t plat, 60 struct cpuref *cpuref) 61 { 62 cpuref->cr_hwref = -1; 63 cpuref->cr_cpuid = 0; 64 return (0); 65 } 66 static int platform_null_smp_next_cpu(platform_t plat, 67 struct cpuref *_cpuref) 68 { 69 return (ENOENT); 70 } 71 static struct cpu_group *platform_null_smp_topo(platform_t plat) 72 { 73#ifdef SMP 74 return (smp_topo_none()); 75#else 76 return (NULL); 77#endif 78 } 79 static vm_offset_t platform_null_real_maxaddr(platform_t plat) 80 { 81 return (VM_MAX_ADDRESS); 82 } 83 static void platform_null_smp_ap_init(platform_t plat) 84 { 85 return; 86 } 87 static void platform_null_smp_probe_threads(void) 88 { 89 return; 90 } 91 static int platform_null_node_numa_domain(platform_t plat, 92 phandle_t node) 93 { 94 return (0); 95 } 96}; 97 98/** 99 * @brief Probe for whether we are on this platform, returning the standard 100 * newbus probe codes. If we have Open Firmware or a flattened device tree, 101 * it is guaranteed to be available at this point. 102 */ 103METHOD int probe { 104 platform_t _plat; 105}; 106 107 108/** 109 * @brief Attach this platform module. This happens before the MMU is online, 110 * so the platform module can install its own high-priority MMU module at 111 * this point. 112 */ 113METHOD int attach { 114 platform_t _plat; 115} DEFAULT platform_null_attach; 116 117 118/** 119 * @brief Return the system's physical memory map. 120 * 121 * It shall provide the total and the available regions of RAM. 122 * The available regions need not take the kernel into account. 123 * 124 * @param _memp Array of physical memory chunks 125 * @param _memsz Number of physical memory chunks 126 * @param _availp Array of available physical memory chunks 127 * @param _availsz Number of available physical memory chunks 128 */ 129 130METHOD void mem_regions { 131 platform_t _plat; 132 struct mem_region *_memp; 133 int *_memsz; 134 struct mem_region *_availp; 135 int *_availsz; 136}; 137 138 139/** 140 * @brief Return the system's physical memory map. 141 * 142 * It shall provide the total RAM with the corresponding domains. 143 * 144 * @param _memp Array of physical memory chunks 145 * @param _memsz Number of physical memory chunks 146 */ 147 148METHOD void numa_mem_regions { 149 platform_t _plat; 150 struct numa_mem_region *_memp; 151 int *_memsz; 152}; 153 154/** 155 * @brief Return the maximum address accessible in real mode 156 * (for use with hypervisors) 157 */ 158METHOD vm_offset_t real_maxaddr { 159 platform_t _plat; 160} DEFAULT platform_null_real_maxaddr; 161 162 163/** 164 * @brief Get the CPU's timebase frequency, in ticks per second. 165 * 166 * @param _cpu CPU whose timebase to query 167 */ 168 169METHOD u_long timebase_freq { 170 platform_t _plat; 171 struct cpuref *_cpu; 172}; 173 174# SMP bits 175 176/** 177 * @brief Fill the first CPU's cpuref 178 * 179 * @param _cpuref CPU 180 */ 181METHOD int smp_first_cpu { 182 platform_t _plat; 183 struct cpuref *_cpuref; 184} DEFAULT platform_null_smp_first_cpu; 185 186/** 187 * @brief Fill the next CPU's cpuref 188 * 189 * @param _cpuref CPU 190 */ 191METHOD int smp_next_cpu { 192 platform_t _plat; 193 struct cpuref *_cpuref; 194} DEFAULT platform_null_smp_next_cpu; 195 196/** 197 * @brief Find the boot processor 198 * 199 * @param _cpuref CPU 200 */ 201METHOD int smp_get_bsp { 202 platform_t _plat; 203 struct cpuref *_cpuref; 204} DEFAULT platform_null_smp_first_cpu; 205 206/** 207 * @brief Start a CPU 208 * 209 * @param _cpuref CPU 210 */ 211METHOD int smp_start_cpu { 212 platform_t _plat; 213 struct pcpu *_cpu; 214}; 215 216/** 217 * @brief Start a CPU 218 * 219 */ 220METHOD void smp_ap_init { 221 platform_t _plat; 222} DEFAULT platform_null_smp_ap_init; 223 224/** 225 * @brief Probe mp_ncores and smp_threads_per_core for early MI code 226 */ 227METHOD void smp_probe_threads { 228 platform_t _plat; 229} DEFAULT platform_null_smp_probe_threads; 230 231/** 232 * @brief Return SMP topology 233 */ 234METHOD cpu_group_t smp_topo { 235 platform_t _plat; 236} DEFAULT platform_null_smp_topo; 237 238/** 239 * @brief Reset system 240 */ 241METHOD void reset { 242 platform_t _plat; 243}; 244 245/** 246 * @brief Suspend the CPU 247 */ 248METHOD void sleep { 249 platform_t _plat; 250}; 251 252/** 253 * @brief Attempt to synchronize timebase of current CPU with others. 254 * Entered (approximately) simultaneously on all CPUs, including the BSP. 255 * Passed the timebase value on the BSP as of shortly before the call. 256 */ 257METHOD void smp_timebase_sync { 258 platform_t _plat; 259 u_long _tb; 260 int _ap; 261}; 262 263/** 264 * @brief Return the NUMA domain for the given device tree node. Always returns 265 * a valid domain. 266 * 267 */ 268METHOD int node_numa_domain { 269 platform_t _plat; 270 phandle_t _node; 271} DEFAULT platform_null_node_numa_domain; 272