bcm_machdep.c revision 302190
1299994Sadrian/*- 2299994Sadrian * Copyright (c) 2007 Bruce M. Simpson. 3299994Sadrian * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com> 4299994Sadrian * 5299994Sadrian * All rights reserved. 6299994Sadrian * 7299994Sadrian * Redistribution and use in source and binary forms, with or without 8299994Sadrian * modification, are permitted provided that the following conditions 9299994Sadrian * are met: 10299994Sadrian * 1. Redistributions of source code must retain the above copyright 11299994Sadrian * notice, this list of conditions and the following disclaimer. 12299994Sadrian * 2. Redistributions in binary form must reproduce the above copyright 13299994Sadrian * notice, this list of conditions and the following disclaimer in the 14299994Sadrian * documentation and/or other materials provided with the distribution. 15299994Sadrian * 16299994Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17299994Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18299994Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19299994Sadrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20299994Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21299994Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22299994Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23299994Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24299994Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25299994Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26299994Sadrian * SUCH DAMAGE. 27299994Sadrian */ 28299994Sadrian 29299994Sadrian#include <sys/cdefs.h> 30299994Sadrian__FBSDID("$FreeBSD: head/sys/mips/broadcom/bcm_machdep.c 302190 2016-06-25 04:34:54Z landonf $"); 31299994Sadrian 32299994Sadrian#include "opt_ddb.h" 33299994Sadrian 34299994Sadrian#include <sys/param.h> 35299994Sadrian#include <sys/conf.h> 36299994Sadrian#include <sys/kernel.h> 37299994Sadrian#include <sys/systm.h> 38299994Sadrian#include <sys/imgact.h> 39299994Sadrian#include <sys/bio.h> 40299994Sadrian#include <sys/buf.h> 41299994Sadrian#include <sys/bus.h> 42299994Sadrian#include <sys/cpu.h> 43299994Sadrian#include <sys/cons.h> 44299994Sadrian#include <sys/exec.h> 45299994Sadrian#include <sys/ucontext.h> 46299994Sadrian#include <sys/proc.h> 47299994Sadrian#include <sys/kdb.h> 48299994Sadrian#include <sys/ptrace.h> 49299994Sadrian#include <sys/reboot.h> 50299994Sadrian#include <sys/signalvar.h> 51299994Sadrian#include <sys/sysent.h> 52299994Sadrian#include <sys/sysproto.h> 53299994Sadrian#include <sys/user.h> 54299994Sadrian 55299994Sadrian#include <vm/vm.h> 56299994Sadrian#include <vm/vm_object.h> 57299994Sadrian#include <vm/vm_page.h> 58299994Sadrian 59299994Sadrian#include <machine/cache.h> 60299994Sadrian#include <machine/clock.h> 61299994Sadrian#include <machine/cpu.h> 62299994Sadrian#include <machine/cpuinfo.h> 63299994Sadrian#include <machine/cpufunc.h> 64299994Sadrian#include <machine/cpuregs.h> 65299994Sadrian#include <machine/hwfunc.h> 66299994Sadrian#include <machine/intr_machdep.h> 67299994Sadrian#include <machine/locore.h> 68299994Sadrian#include <machine/md_var.h> 69299994Sadrian#include <machine/pte.h> 70299994Sadrian#include <machine/sigframe.h> 71299994Sadrian#include <machine/trap.h> 72299994Sadrian#include <machine/vmparam.h> 73299994Sadrian 74299994Sadrian#include "bcm_socinfo.h" 75299994Sadrian 76299994Sadrian#ifdef CFE 77299994Sadrian#include <dev/cfe/cfe_api.h> 78299994Sadrian#endif 79299994Sadrian 80299994Sadrian#if 0 81302190Slandonf#define BCM_TRACE(_fmt, ...) printf(_fmt, ##__VA_ARGS__) 82302190Slandonf#else 83302190Slandonf#define BCM_TRACE(_fmt, ...) 84299994Sadrian#endif 85299994Sadrian 86299994Sadrianextern int *edata; 87299994Sadrianextern int *end; 88299994Sadrian 89299994Sadrianvoid 90299994Sadrianplatform_cpu_init() 91299994Sadrian{ 92299994Sadrian /* Nothing special */ 93299994Sadrian} 94299994Sadrian 95299994Sadrianstatic void 96299994Sadrianmips_init(void) 97299994Sadrian{ 98299994Sadrian int i, j; 99299994Sadrian 100299994Sadrian printf("entry: mips_init()\n"); 101299994Sadrian 102299994Sadrian#ifdef CFE 103299994Sadrian /* 104299994Sadrian * Query DRAM memory map from CFE. 105299994Sadrian */ 106299994Sadrian physmem = 0; 107299994Sadrian for (i = 0; i < 10; i += 2) { 108299994Sadrian int result; 109299994Sadrian uint64_t addr, len, type; 110299994Sadrian 111299994Sadrian result = cfe_enummem(i / 2, 0, &addr, &len, &type); 112299994Sadrian if (result < 0) { 113302190Slandonf BCM_TRACE("There is no phys memory for: %d\n", i); 114299994Sadrian phys_avail[i] = phys_avail[i + 1] = 0; 115299994Sadrian break; 116299994Sadrian } 117302190Slandonf if (type != CFE_MI_AVAILABLE) { 118302190Slandonf BCM_TRACE("phys memory is not available: %d\n", i); 119299994Sadrian continue; 120299994Sadrian } 121299994Sadrian 122299994Sadrian phys_avail[i] = addr; 123299994Sadrian if (i == 0 && addr == 0) { 124299994Sadrian /* 125299994Sadrian * If this is the first physical memory segment probed 126299994Sadrian * from CFE, omit the region at the start of physical 127299994Sadrian * memory where the kernel has been loaded. 128299994Sadrian */ 129299994Sadrian phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); 130299994Sadrian } 131302190Slandonf 132302190Slandonf BCM_TRACE("phys memory is available for: %d\n", i); 133302190Slandonf BCM_TRACE(" => addr = %jx\n", addr); 134302190Slandonf BCM_TRACE(" => len = %jd\n", len); 135302190Slandonf 136299994Sadrian phys_avail[i + 1] = addr + len; 137299994Sadrian physmem += len; 138299994Sadrian } 139299994Sadrian 140302190Slandonf BCM_TRACE("Total phys memory is : %ld\n", physmem); 141299994Sadrian realmem = btoc(physmem); 142299994Sadrian#endif 143299994Sadrian 144299994Sadrian for (j = 0; j < i; j++) 145299994Sadrian dump_avail[j] = phys_avail[j]; 146299994Sadrian 147299994Sadrian physmem = realmem; 148299994Sadrian 149299994Sadrian init_param1(); 150299994Sadrian init_param2(physmem); 151299994Sadrian mips_cpu_init(); 152299994Sadrian pmap_bootstrap(); 153299994Sadrian mips_proc0_init(); 154299994Sadrian mutex_init(); 155299994Sadrian kdb_init(); 156299994Sadrian#ifdef KDB 157299994Sadrian if (boothowto & RB_KDB) 158299994Sadrian kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 159299994Sadrian#endif 160299994Sadrian} 161299994Sadrian 162299994Sadrianvoid 163299994Sadrianplatform_reset(void) 164299994Sadrian{ 165299994Sadrian printf("bcm::platform_reset()\n"); 166299994Sadrian intr_disable(); 167302190Slandonf 168302190Slandonf#if defined(CFE) 169302190Slandonf cfe_exit(0, 0); 170302190Slandonf#else 171302190Slandonf /* PMU watchdog reset */ 172299994Sadrian BCM_WRITE_REG32(BCM_REG_CHIPC_PMUWD_OFFS, 2); /* PMU watchdog */ 173302190Slandonf#endif 174302190Slandonf 175302190Slandonf#if 0 176302190Slandonf /* Non-PMU reset 177302190Slandonf * XXX: Need chipc capability flags */ 178302190Slandonf *((volatile uint8_t *)MIPS_PHYS_TO_KSEG1(SENTRY5_EXTIFADR)) = 0x80; 179302190Slandonf#endif 180302190Slandonf 181299994Sadrian for (;;); 182299994Sadrian} 183299994Sadrian 184299994Sadrianvoid 185299994Sadrianplatform_start(__register_t a0, __register_t a1, __register_t a2, 186299994Sadrian __register_t a3) 187299994Sadrian{ 188299994Sadrian vm_offset_t kernend; 189299994Sadrian uint64_t platform_counter_freq; 190299994Sadrian struct bcm_socinfo *socinfo; 191299994Sadrian 192299994Sadrian /* clear the BSS and SBSS segments */ 193299994Sadrian kernend = (vm_offset_t)&end; 194299994Sadrian memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 195299994Sadrian 196299994Sadrian mips_postboot_fixup(); 197299994Sadrian 198299994Sadrian /* Initialize pcpu stuff */ 199299994Sadrian mips_pcpu0_init(); 200299994Sadrian 201302190Slandonf#if 0 202302190Slandonf /* 203302190Slandonf * Probe the Broadcom on-chip PLL clock registers 204302190Slandonf * and discover the CPU pipeline clock and bus clock 205302190Slandonf * multipliers from this. 206302190Slandonf * XXX: Wrong place. You have to ask the ChipCommon 207302190Slandonf * or External Interface cores on the SiBa. 208302190Slandonf */ 209302190Slandonf uint32_t busmult, cpumult, refclock, clkcfg1; 210302190Slandonf#define S5_CLKCFG1_REFCLOCK_MASK 0x0000001F 211302190Slandonf#define S5_CLKCFG1_BUSMULT_MASK 0x000003E0 212302190Slandonf#define S5_CLKCFG1_BUSMULT_SHIFT 5 213302190Slandonf#define S5_CLKCFG1_CPUMULT_MASK 0xFFFFFC00 214302190Slandonf#define S5_CLKCFG1_CPUMULT_SHIFT 10 215302190Slandonf 216302190Slandonf counter_freq = 100000000; /* XXX */ 217302190Slandonf 218302190Slandonf clkcfg1 = s5_rd_clkcfg1(); 219302190Slandonf printf("clkcfg1 = 0x%08x\n", clkcfg1); 220302190Slandonf 221302190Slandonf refclock = clkcfg1 & 0x1F; 222302190Slandonf busmult = ((clkcfg1 & 0x000003E0) >> 5) + 1; 223302190Slandonf cpumult = ((clkcfg1 & 0xFFFFFC00) >> 10) + 1; 224302190Slandonf 225302190Slandonf printf("refclock = %u\n", refclock); 226302190Slandonf printf("busmult = %u\n", busmult); 227302190Slandonf printf("cpumult = %u\n", cpumult); 228302190Slandonf 229302190Slandonf counter_freq = cpumult * refclock; 230302190Slandonf#endif 231302190Slandonf 232299994Sadrian socinfo = bcm_get_socinfo(); 233299994Sadrian platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */ 234299994Sadrian 235299994Sadrian mips_timer_early_init(platform_counter_freq); 236299994Sadrian 237299994Sadrian#ifdef CFE 238299994Sadrian /* 239299994Sadrian * Initialize CFE firmware trampolines before 240299994Sadrian * we initialize the low-level console. 241299994Sadrian * 242299994Sadrian * CFE passes the following values in registers: 243299994Sadrian * a0: firmware handle 244299994Sadrian * a2: firmware entry point 245299994Sadrian * a3: entry point seal 246299994Sadrian */ 247299994Sadrian if (a3 == CFE_EPTSEAL) 248299994Sadrian cfe_init(a0, a2); 249299994Sadrian#endif 250302190Slandonf 251299994Sadrian cninit(); 252299994Sadrian 253299994Sadrian mips_init(); 254299994Sadrian 255302190Slandonf mips_timer_init_params(platform_counter_freq, socinfo->double_count); 256299994Sadrian} 257