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# $FreeBSD$ 27# 28 29#include <sys/param.h> 30#include <sys/lock.h> 31#include <sys/mutex.h> 32#include <sys/systm.h> 33#include <sys/smp.h> 34 35#include <machine/ofw_machdep.h> 36#include <machine/platform.h> 37#include <machine/platformvar.h> 38#include <machine/smp.h> 39#include <machine/vmparam.h> 40 41/** 42 * @defgroup PLATFORM platform - KObj methods for PowerPC platform 43 * implementations 44 * @brief A set of methods required by all platform implementations. 45 * These are used to bring up secondary CPUs, supply the physical memory 46 * map, etc. 47 *@{ 48 */ 49 50INTERFACE platform; 51 52# 53# Default implementations 54# 55CODE { 56 static void platform_null_attach(platform_t plat) 57 { 58 return; 59 } 60 static int platform_null_smp_first_cpu(platform_t plat, 61 struct cpuref *cpuref) 62 { 63 cpuref->cr_hwref = -1; 64 cpuref->cr_cpuid = 0; 65 return (0); 66 } 67 static int platform_null_smp_next_cpu(platform_t plat, 68 struct cpuref *_cpuref) 69 { 70 return (ENOENT); 71 } 72 static struct cpu_group *platform_null_smp_topo(platform_t plat) 73 { 74#ifdef SMP 75 return (smp_topo_none()); 76#else 77 return (NULL); 78#endif 79 } 80 static vm_offset_t platform_null_real_maxaddr(platform_t plat) 81 { 82 return (VM_MAX_ADDRESS); 83 } 84 static void platform_null_smp_ap_init(platform_t plat) 85 { 86 return; 87 } 88 static void platform_null_smp_probe_threads(void) 89 { 90 return; 91 } 92 static int platform_null_node_numa_domain(platform_t plat, 93 phandle_t node) 94 { 95 return (0); 96 } 97}; 98 99/** 100 * @brief Probe for whether we are on this platform, returning the standard 101 * newbus probe codes. If we have Open Firmware or a flattened device tree, 102 * it is guaranteed to be available at this point. 103 */ 104METHOD int probe { 105 platform_t _plat; 106}; 107 108 109/** 110 * @brief Attach this platform module. This happens before the MMU is online, 111 * so the platform module can install its own high-priority MMU module at 112 * this point. 113 */ 114METHOD int attach { 115 platform_t _plat; 116} DEFAULT platform_null_attach; 117 118 119/** 120 * @brief Return the system's physical memory map. 121 * 122 * It shall provide the total and the available regions of RAM. 123 * The available regions need not take the kernel into account. 124 * 125 * @param _memp Array of physical memory chunks 126 * @param _memsz Number of physical memory chunks 127 * @param _availp Array of available physical memory chunks 128 * @param _availsz Number of available physical memory chunks 129 */ 130 131METHOD void mem_regions { 132 platform_t _plat; 133 struct mem_region *_memp; 134 int *_memsz; 135 struct mem_region *_availp; 136 int *_availsz; 137}; 138 139 140/** 141 * @brief Return the system's physical memory map. 142 * 143 * It shall provide the total RAM with the corresponding domains. 144 * 145 * @param _memp Array of physical memory chunks 146 * @param _memsz Number of physical memory chunks 147 */ 148 149METHOD void numa_mem_regions { 150 platform_t _plat; 151 struct numa_mem_region *_memp; 152 int *_memsz; 153}; 154 155/** 156 * @brief Return the maximum address accessible in real mode 157 * (for use with hypervisors) 158 */ 159METHOD vm_offset_t real_maxaddr { 160 platform_t _plat; 161} DEFAULT platform_null_real_maxaddr; 162 163 164/** 165 * @brief Get the CPU's timebase frequency, in ticks per second. 166 * 167 * @param _cpu CPU whose timebase to query 168 */ 169 170METHOD u_long timebase_freq { 171 platform_t _plat; 172 struct cpuref *_cpu; 173}; 174 175# SMP bits 176 177/** 178 * @brief Fill the first CPU's cpuref 179 * 180 * @param _cpuref CPU 181 */ 182METHOD int smp_first_cpu { 183 platform_t _plat; 184 struct cpuref *_cpuref; 185} DEFAULT platform_null_smp_first_cpu; 186 187/** 188 * @brief Fill the next CPU's cpuref 189 * 190 * @param _cpuref CPU 191 */ 192METHOD int smp_next_cpu { 193 platform_t _plat; 194 struct cpuref *_cpuref; 195} DEFAULT platform_null_smp_next_cpu; 196 197/** 198 * @brief Find the boot processor 199 * 200 * @param _cpuref CPU 201 */ 202METHOD int smp_get_bsp { 203 platform_t _plat; 204 struct cpuref *_cpuref; 205} DEFAULT platform_null_smp_first_cpu; 206 207/** 208 * @brief Start a CPU 209 * 210 * @param _cpuref CPU 211 */ 212METHOD int smp_start_cpu { 213 platform_t _plat; 214 struct pcpu *_cpu; 215}; 216 217/** 218 * @brief Start a CPU 219 * 220 */ 221METHOD void smp_ap_init { 222 platform_t _plat; 223} DEFAULT platform_null_smp_ap_init; 224 225/** 226 * @brief Probe mp_ncores and smp_threads_per_core for early MI code 227 */ 228METHOD void smp_probe_threads { 229 platform_t _plat; 230} DEFAULT platform_null_smp_probe_threads; 231 232/** 233 * @brief Return SMP topology 234 */ 235METHOD cpu_group_t smp_topo { 236 platform_t _plat; 237} DEFAULT platform_null_smp_topo; 238 239/** 240 * @brief Reset system 241 */ 242METHOD void reset { 243 platform_t _plat; 244}; 245 246/** 247 * @brief Suspend the CPU 248 */ 249METHOD void sleep { 250 platform_t _plat; 251}; 252 253/** 254 * @brief Attempt to synchronize timebase of current CPU with others. 255 * Entered (approximately) simultaneously on all CPUs, including the BSP. 256 * Passed the timebase value on the BSP as of shortly before the call. 257 */ 258METHOD void smp_timebase_sync { 259 platform_t _plat; 260 u_long _tb; 261 int _ap; 262}; 263 264/** 265 * @brief Return the NUMA domain for the given device tree node. Always returns 266 * a valid domain. 267 * 268 */ 269METHOD int node_numa_domain { 270 platform_t _plat; 271 phandle_t _node; 272} DEFAULT platform_null_node_numa_domain; 273