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