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/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}; 92 93/** 94 * @brief Probe for whether we are on this platform, returning the standard 95 * newbus probe codes. If we have Open Firmware or a flattened device tree, 96 * it is guaranteed to be available at this point. 97 */ 98METHOD int probe { 99 platform_t _plat; 100}; 101 102 103/** 104 * @brief Attach this platform module. This happens before the MMU is online, 105 * so the platform module can install its own high-priority MMU module at 106 * this point. 107 */ 108METHOD int attach { 109 platform_t _plat; 110} DEFAULT platform_null_attach; 111 112 113/** 114 * @brief Return the system's physical memory map. 115 * 116 * It shall provide the total and the available regions of RAM. 117 * The available regions need not take the kernel into account. 118 * 119 * @param _memp Array of physical memory chunks 120 * @param _memsz Number of physical memory chunks 121 * @param _availp Array of available physical memory chunks 122 * @param _availsz Number of available physical memory chunks 123 */ 124 125METHOD void mem_regions { 126 platform_t _plat; 127 struct mem_region *_memp; 128 int *_memsz; 129 struct mem_region *_availp; 130 int *_availsz; 131}; 132 133/** 134 * @brief Return the maximum address accessible in real mode 135 * (for use with hypervisors) 136 */ 137METHOD vm_offset_t real_maxaddr { 138 platform_t _plat; 139} DEFAULT platform_null_real_maxaddr; 140 141 142/** 143 * @brief Get the CPU's timebase frequency, in ticks per second. 144 * 145 * @param _cpu CPU whose timebase to query 146 */ 147 148METHOD u_long timebase_freq { 149 platform_t _plat; 150 struct cpuref *_cpu; 151}; 152 153# SMP bits 154 155/** 156 * @brief Fill the first CPU's cpuref 157 * 158 * @param _cpuref CPU 159 */ 160METHOD int smp_first_cpu { 161 platform_t _plat; 162 struct cpuref *_cpuref; 163} DEFAULT platform_null_smp_first_cpu; 164 165/** 166 * @brief Fill the next CPU's cpuref 167 * 168 * @param _cpuref CPU 169 */ 170METHOD int smp_next_cpu { 171 platform_t _plat; 172 struct cpuref *_cpuref; 173} DEFAULT platform_null_smp_next_cpu; 174 175/** 176 * @brief Find the boot processor 177 * 178 * @param _cpuref CPU 179 */ 180METHOD int smp_get_bsp { 181 platform_t _plat; 182 struct cpuref *_cpuref; 183} DEFAULT platform_null_smp_first_cpu; 184 185/** 186 * @brief Start a CPU 187 * 188 * @param _cpuref CPU 189 */ 190METHOD int smp_start_cpu { 191 platform_t _plat; 192 struct pcpu *_cpu; 193}; 194 195/** 196 * @brief Start a CPU 197 * 198 */ 199METHOD void smp_ap_init { 200 platform_t _plat; 201} DEFAULT platform_null_smp_ap_init; 202 203/** 204 * @brief Probe mp_ncores and smp_threads_per_core for early MI code 205 */ 206METHOD void smp_probe_threads { 207 platform_t _plat; 208} DEFAULT platform_null_smp_probe_threads; 209 210/** 211 * @brief Return SMP topology 212 */ 213METHOD cpu_group_t smp_topo { 214 platform_t _plat; 215} DEFAULT platform_null_smp_topo; 216 217/** 218 * @brief Reset system 219 */ 220METHOD void reset { 221 platform_t _plat; 222}; 223 224/** 225 * @brief Suspend the CPU 226 */ 227METHOD void sleep { 228 platform_t _plat; 229}; 230 231/** 232 * @brief Attempt to synchronize timebase of current CPU with others. 233 * Entered (approximately) simultaneously on all CPUs, including the BSP. 234 * Passed the timebase value on the BSP as of shortly before the call. 235 */ 236METHOD void smp_timebase_sync { 237 platform_t _plat; 238 u_long _tb; 239 int _ap; 240}; 241 242