malta_machdep.c revision 202849
1178173Simp/*- 2178173Simp * Copyright (c) 2006 Wojciech A. Koszek <wkoszek@FreeBSD.org> 3178173Simp * All rights reserved. 4178173Simp * 5178173Simp * Redistribution and use in source and binary forms, with or without 6178173Simp * modification, are permitted provided that the following conditions 7178173Simp * are met: 8178173Simp * 1. Redistributions of source code must retain the above copyright 9178173Simp * notice, this list of conditions and the following disclaimer. 10178173Simp * 2. Redistributions in binary form must reproduce the above copyright 11178173Simp * notice, this list of conditions and the following disclaimer in the 12178173Simp * documentation and/or other materials provided with the distribution. 13178173Simp * 14178173Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15178173Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16178173Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17178173Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18178173Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19178173Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20178173Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21178173Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22178173Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23178173Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24178173Simp * SUCH DAMAGE. 25178173Simp * 26178173Simp * $FreeBSD: head/sys/mips/malta/malta_machdep.c 202849 2010-01-23 00:18:12Z imp $ 27178173Simp */ 28178173Simp#include <sys/cdefs.h> 29178173Simp__FBSDID("$FreeBSD: head/sys/mips/malta/malta_machdep.c 202849 2010-01-23 00:18:12Z imp $"); 30178173Simp 31178173Simp#include "opt_ddb.h" 32178173Simp 33178173Simp#include <sys/param.h> 34178173Simp#include <sys/conf.h> 35178173Simp#include <sys/kernel.h> 36178173Simp#include <sys/systm.h> 37178173Simp#include <sys/imgact.h> 38178173Simp#include <sys/bio.h> 39178173Simp#include <sys/buf.h> 40178173Simp#include <sys/bus.h> 41178173Simp#include <sys/cpu.h> 42178173Simp#include <sys/cons.h> 43178173Simp#include <sys/exec.h> 44178173Simp#include <sys/ucontext.h> 45178173Simp#include <sys/proc.h> 46178173Simp#include <sys/kdb.h> 47178173Simp#include <sys/ptrace.h> 48178173Simp#include <sys/reboot.h> 49178173Simp#include <sys/signalvar.h> 50178173Simp#include <sys/sysent.h> 51178173Simp#include <sys/sysproto.h> 52178173Simp#include <sys/user.h> 53178173Simp 54178173Simp#include <vm/vm.h> 55178173Simp#include <vm/vm_object.h> 56178173Simp#include <vm/vm_page.h> 57178173Simp#include <vm/vm_pager.h> 58178173Simp 59178173Simp#include <machine/clock.h> 60178173Simp#include <machine/cpu.h> 61178173Simp#include <machine/cpuregs.h> 62178173Simp#include <machine/hwfunc.h> 63178173Simp#include <machine/md_var.h> 64178173Simp#include <machine/pmap.h> 65178173Simp#include <machine/trap.h> 66178173Simp 67178173Simp#ifdef TICK_USE_YAMON_FREQ 68182901Sgonzo#include <mips/malta/yamon.h> 69178173Simp#endif 70178173Simp 71178173Simp#ifdef TICK_USE_MALTA_RTC 72178173Simp#include <mips/mips4k/malta/maltareg.h> 73178173Simp#include <dev/mc146818/mc146818reg.h> 74178173Simp#include <isa/rtc.h> 75178173Simp#endif 76178173Simp 77182901Sgonzo#include <mips/malta/maltareg.h> 78178173Simp 79178173Simpextern int *edata; 80178173Simpextern int *end; 81178173Simp 82178173Simpvoid lcd_init(void); 83178173Simpvoid lcd_puts(char *); 84178173Simpvoid malta_reset(void); 85178173Simp 86178173Simp/* 87178173Simp * Offsets to MALTA LCD characters. 88178173Simp */ 89178173Simpstatic int malta_lcd_offs[] = { 90178173Simp MALTA_ASCIIPOS0, 91178173Simp MALTA_ASCIIPOS1, 92178173Simp MALTA_ASCIIPOS2, 93178173Simp MALTA_ASCIIPOS3, 94178173Simp MALTA_ASCIIPOS4, 95178173Simp MALTA_ASCIIPOS5, 96178173Simp MALTA_ASCIIPOS6, 97178173Simp MALTA_ASCIIPOS7 98178173Simp}; 99178173Simp 100202035Simpvoid 101202035Simpplatform_cpu_init() 102202035Simp{ 103202035Simp /* Nothing special */ 104202035Simp} 105202035Simp 106178173Simp/* 107178173Simp * Put character to Malta LCD at given position. 108178173Simp */ 109178173Simpstatic void 110178173Simpmalta_lcd_putc(int pos, char c) 111178173Simp{ 112178173Simp void *addr; 113178173Simp char *ch; 114178173Simp 115178173Simp if (pos < 0 || pos > 7) 116178173Simp return; 117178173Simp addr = (void *)(MALTA_ASCII_BASE + malta_lcd_offs[pos]); 118178173Simp ch = (char *)MIPS_PHYS_TO_KSEG0(addr); 119178173Simp *ch = c; 120178173Simp} 121178173Simp 122178173Simp/* 123178173Simp * Print given string on LCD. 124178173Simp */ 125178173Simpstatic void 126178173Simpmalta_lcd_print(char *str) 127178173Simp{ 128178173Simp int i; 129178173Simp 130178173Simp if (str == NULL) 131178173Simp return; 132178173Simp 133178173Simp for (i = 0; *str != '\0'; i++, str++) 134178173Simp malta_lcd_putc(i, *str); 135178173Simp} 136178173Simp 137178173Simpvoid 138178173Simplcd_init(void) 139178173Simp{ 140178173Simp malta_lcd_print("FreeBSD_"); 141178173Simp} 142178173Simp 143178173Simpvoid 144178173Simplcd_puts(char *s) 145178173Simp{ 146178173Simp malta_lcd_print(s); 147178173Simp} 148178173Simp 149178173Simp#ifdef TICK_USE_MALTA_RTC 150178173Simpstatic __inline uint8_t 151178173Simprtcin(uint8_t addr) 152178173Simp{ 153178173Simp 154178173Simp *((volatile uint8_t *) 155178173Simp MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCADR))) = addr; 156178173Simp return (*((volatile uint8_t *) 157178173Simp MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCDAT)))); 158178173Simp} 159178173Simp 160178173Simpstatic __inline void 161178173Simpwritertc(uint8_t addr, uint8_t val) 162178173Simp{ 163178173Simp 164178173Simp *((volatile uint8_t *) 165178173Simp MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCADR))) = addr; 166178173Simp *((volatile uint8_t *) 167178173Simp MIPS_PHYS_TO_KSEG1(MALTA_PCI0_ADDR(MALTA_RTCDAT))) = val; 168178173Simp} 169178173Simp#endif 170178173Simp 171178173Simpstatic void 172178173Simpmips_init(void) 173178173Simp{ 174178173Simp int i; 175178173Simp 176178173Simp for (i = 0; i < 10; i++) { 177178173Simp phys_avail[i] = 0; 178178173Simp } 179178173Simp 180178173Simp /* phys_avail regions are in bytes */ 181178173Simp phys_avail[0] = MIPS_KSEG0_TO_PHYS((vm_offset_t)&end); 182178173Simp phys_avail[1] = ctob(realmem); 183178173Simp 184178173Simp physmem = realmem; 185178173Simp 186178173Simp init_param1(); 187178173Simp init_param2(physmem); 188178173Simp mips_cpu_init(); 189178173Simp pmap_bootstrap(); 190178173Simp mips_proc0_init(); 191178173Simp mutex_init(); 192178173Simp kdb_init(); 193202849Simp#ifdef KDB 194202849Simp if (boothowto & RB_KDB) 195202849Simp kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); 196178173Simp#endif 197178173Simp} 198178173Simp 199178173Simpvoid 200178173Simpplatform_halt(void) 201178173Simp{ 202178173Simp 203178173Simp} 204178173Simp 205178173Simp 206178173Simpvoid 207178173Simpplatform_identify(void) 208178173Simp{ 209178173Simp 210178173Simp} 211178173Simp 212178173Simp/* 213178173Simp * Perform a board-level soft-reset. 214178173Simp * Note that this is not emulated by gxemul. 215178173Simp */ 216178173Simpvoid 217178173Simpplatform_reset(void) 218178173Simp{ 219178173Simp char *c; 220178173Simp 221178173Simp c = (char *)MIPS_PHYS_TO_KSEG0(MALTA_SOFTRES); 222178173Simp *c = MALTA_GORESET; 223178173Simp} 224178173Simp 225178173Simpvoid 226178173Simpplatform_trap_enter(void) 227178173Simp{ 228178173Simp 229178173Simp} 230178173Simp 231178173Simpvoid 232178173Simpplatform_trap_exit(void) 233178173Simp{ 234178173Simp 235178173Simp} 236178173Simp 237202035Simpstatic uint64_t 238202035Simpmalta_cpu_freq(void) 239202035Simp{ 240202035Simp uint64_t platform_counter_freq = 0; 241202035Simp 242202035Simp#if defined(TICK_USE_YAMON_FREQ) 243202035Simp /* 244202035Simp * If we are running on a board which uses YAMON firmware, 245202035Simp * then query CPU pipeline clock from the syscon object. 246202035Simp * If unsuccessful, use hard-coded default. 247202035Simp */ 248202035Simp platform_counter_freq = yamon_getcpufreq(); 249202035Simp 250202035Simp#elif defined(TICK_USE_MALTA_RTC) 251202035Simp /* 252202035Simp * If we are running on a board with the MC146818 RTC, 253202035Simp * use it to determine CPU pipeline clock frequency. 254202035Simp */ 255202035Simp u_int64_t counterval[2]; 256202035Simp 257202035Simp /* Set RTC to binary mode. */ 258202035Simp writertc(RTC_STATUSB, (rtcin(RTC_STATUSB) | RTCSB_BCD)); 259202035Simp 260202035Simp /* Busy-wait for falling edge of RTC update. */ 261202035Simp while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) 262202035Simp ; 263202035Simp while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) 264202035Simp ; 265202035Simp counterval[0] = mips_rd_count(); 266202035Simp 267202035Simp /* Busy-wait for falling edge of RTC update. */ 268202035Simp while (((rtcin(RTC_STATUSA) & RTCSA_TUP) == 0)) 269202035Simp ; 270202035Simp while (((rtcin(RTC_STATUSA)& RTCSA_TUP) != 0)) 271202035Simp ; 272202035Simp counterval[1] = mips_rd_count(); 273202035Simp 274202035Simp platform_counter_freq = counterval[1] - counterval[0]; 275202035Simp#endif 276202035Simp 277202035Simp if (platform_counter_freq == 0) 278202035Simp platform_counter_freq = MIPS_DEFAULT_HZ; 279202035Simp 280202035Simp return (platform_counter_freq); 281202035Simp} 282202035Simp 283178173Simpvoid 284178173Simpplatform_start(__register_t a0, __register_t a1, __register_t a2, 285178173Simp __register_t a3) 286178173Simp{ 287178173Simp vm_offset_t kernend; 288178173Simp uint64_t platform_counter_freq; 289178173Simp int argc = a0; 290178173Simp char **argv = (char **)a1; 291178173Simp char **envp = (char **)a2; 292178173Simp unsigned int memsize = a3; 293178173Simp int i; 294178173Simp 295178173Simp /* clear the BSS and SBSS segments */ 296178173Simp kernend = round_page((vm_offset_t)&end); 297178173Simp memset(&edata, 0, kernend - (vm_offset_t)(&edata)); 298178173Simp 299202035Simp mips_pcpu0_init(); 300202035Simp platform_counter_freq = malta_cpu_freq(); 301202035Simp mips_timer_early_init(platform_counter_freq); 302202035Simp 303178173Simp cninit(); 304178173Simp printf("entry: platform_start()\n"); 305178173Simp 306178173Simp bootverbose = 1; 307178173Simp if (bootverbose) { 308178173Simp printf("cmd line: "); 309178173Simp for (i = 0; i < argc; i++) 310178173Simp printf("%s ", argv[i]); 311178173Simp printf("\n"); 312178173Simp 313178173Simp printf("envp:\n"); 314178173Simp for (i = 0; envp[i]; i += 2) 315178173Simp printf("\t%s = %s\n", envp[i], envp[i+1]); 316178173Simp 317178173Simp printf("memsize = %08x\n", memsize); 318178173Simp } 319178173Simp 320178173Simp realmem = btoc(memsize); 321178173Simp mips_init(); 322178173Simp 323178173Simp mips_timer_init_params(platform_counter_freq, 0); 324178173Simp} 325