1 /* -*-C++-*- $NetBSD: mips_arch.cpp,v 1.7 2008/04/28 20:23:20 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #undef DEBUG_KERNADDR_ACCESS 32 #undef DEBUG_CP0_ACCESS 33 34 #include <hpcboot.h> 35 #include <mips/mips_arch.h> 36 #include <console.h> 37 #include <memory.h> 38 39 MIPSArchitecture::MIPSArchitecture(Console *&cons, MemoryManager *&mem) 40 : Architecture(cons, mem) 41 { 42 /* NO-OP */ 43 } 44 45 MIPSArchitecture::~MIPSArchitecture(void) 46 { 47 /* NO-OP */ 48 } 49 50 void 51 MIPSArchitecture::systemInfo() 52 { 53 uint32_t r0, r1; 54 Architecture::systemInfo(); 55 r0 = r1 = 0; 56 57 #ifdef DEBUG_CP0_ACCESS 58 /* CP0 access test */ 59 _kmode = SetKMode(1); 60 61 DPRINTF((TEXT("status register test\n"))); 62 GET_SR(r0); 63 DPRINTF((TEXT("current value: 0x%08x\n"), r0)); 64 SET_SR(r1); 65 GET_SR(r1); 66 DPRINTF((TEXT("write test: 0x%08x\n"), r1)); 67 SET_SR(r0); 68 69 SetKMode(_kmode); 70 #endif // DEBUG_CP0_ACCESS 71 } 72 73 BOOL 74 MIPSArchitecture::init() 75 { 76 if (!_mem->init()) { 77 DPRINTF((TEXT("can't initialize memory manager.\n"))); 78 return FALSE; 79 } 80 81 return TRUE; 82 } 83 84 BOOL 85 MIPSArchitecture::setupLoader() 86 { 87 vaddr_t v; 88 89 #ifdef DEBUG_KERNADDR_ACCESS // kernel address access test 90 #define TEST_MAGIC 0xac1dcafe 91 paddr_t p; 92 uint32_t r0; 93 94 _kmode = SetKMode(1); 95 _mem->getPage(v, p); 96 VOLATILE_REF(ptokv(p)) = TEST_MAGIC; 97 cacheFlush(); 98 r0 = VOLATILE_REF(v); 99 DPRINTF((TEXT("kernel address access test: %S\n"), 100 r0 == TEST_MAGIC ? "OK" : "NG")); 101 SetKMode(_kmode); 102 #endif // DEBUG_KERNADDR_ACCESS 103 104 if (!_mem->getPage(v , _loader_addr)) { 105 DPRINTF((TEXT("can't get page for 2nd loader.\n"))); 106 return FALSE; 107 } 108 DPRINTF((TEXT("2nd bootloader vaddr=0x%08x paddr=0x%08x\n"), 109 (unsigned)v,(unsigned)_loader_addr)); 110 111 memcpy(LPVOID(v), LPVOID(_boot_func), _mem->getPageSize()); 112 DPRINTF((TEXT("2nd bootloader copy done.\n"))); 113 114 return TRUE; 115 } 116 117 void 118 MIPSArchitecture::jump(paddr_t info, paddr_t pvec) 119 { 120 kaddr_t sp; 121 vaddr_t v; 122 paddr_t p; 123 124 // stack for bootloader(but mips loader don't use stack) 125 _mem->getPage(v, p); 126 sp = ptokv(p + _mem->getPageSize() - 0x10); 127 128 info = ptokv(info); 129 pvec = ptokv(pvec); 130 _loader_addr = ptokv(_loader_addr); 131 132 // switch kernel mode. 133 SetKMode(1); 134 if (SetKMode(1) != 1) { 135 DPRINTF((TEXT("SetKMode(1) failed.\n"))); 136 return; 137 } 138 DPRINTF((TEXT("jump to 0x%08x (info=0x%08x, pvec=0x%08x)\n"), 139 _loader_addr, info, pvec)); 140 141 // writeback whole D-cache and invalidate whole I-cache. 142 // 2nd boot-loader access data via kseg0 which were writed via kuseg, 143 cacheFlush(); 144 145 // jump to 2nd-loader(run kseg0) 146 __asm(".set noreorder;" 147 "jr a3;" 148 "move sp, a2;" 149 ".set reorder", info, pvec, sp, _loader_addr); 150 // NOTREACHED 151 } 152