xref: /netbsd-src/sys/arch/hpc/stand/hpcboot/mips/mips_arch.cpp (revision ce099b40997c43048fb78bd578195f81d2456523)
1*ce099b40Smartin /* -*-C++-*-	$NetBSD: mips_arch.cpp,v 1.7 2008/04/28 20:23:20 martin Exp $	*/
29173eae7Such 
39173eae7Such /*-
49173eae7Such  * Copyright (c) 2001 The NetBSD Foundation, Inc.
59173eae7Such  * All rights reserved.
69173eae7Such  *
79173eae7Such  * This code is derived from software contributed to The NetBSD Foundation
89173eae7Such  * by UCHIYAMA Yasushi.
99173eae7Such  *
109173eae7Such  * Redistribution and use in source and binary forms, with or without
119173eae7Such  * modification, are permitted provided that the following conditions
129173eae7Such  * are met:
139173eae7Such  * 1. Redistributions of source code must retain the above copyright
149173eae7Such  *    notice, this list of conditions and the following disclaimer.
159173eae7Such  * 2. Redistributions in binary form must reproduce the above copyright
169173eae7Such  *    notice, this list of conditions and the following disclaimer in the
179173eae7Such  *    documentation and/or other materials provided with the distribution.
189173eae7Such  *
199173eae7Such  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209173eae7Such  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219173eae7Such  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229173eae7Such  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239173eae7Such  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249173eae7Such  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259173eae7Such  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269173eae7Such  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279173eae7Such  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289173eae7Such  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299173eae7Such  * POSSIBILITY OF SUCH DAMAGE.
309173eae7Such  */
319173eae7Such #undef DEBUG_KERNADDR_ACCESS
329173eae7Such #undef DEBUG_CP0_ACCESS
339173eae7Such 
349173eae7Such #include <hpcboot.h>
359173eae7Such #include <mips/mips_arch.h>
369173eae7Such #include <console.h>
379173eae7Such #include <memory.h>
389173eae7Such 
MIPSArchitecture(Console * & cons,MemoryManager * & mem)399173eae7Such MIPSArchitecture::MIPSArchitecture(Console *&cons, MemoryManager *&mem)
409173eae7Such 	: Architecture(cons, mem)
419173eae7Such {
429173eae7Such 	/* NO-OP */
439173eae7Such }
449173eae7Such 
~MIPSArchitecture(void)459173eae7Such MIPSArchitecture::~MIPSArchitecture(void)
469173eae7Such {
479173eae7Such 	/* NO-OP */
489173eae7Such }
499173eae7Such 
509173eae7Such void
systemInfo()519173eae7Such MIPSArchitecture::systemInfo()
529173eae7Such {
5324c8a902Suwe 	uint32_t r0, r1;
549173eae7Such 	Architecture::systemInfo();
559173eae7Such 	r0 = r1 = 0;
569173eae7Such 
579173eae7Such #ifdef DEBUG_CP0_ACCESS
589173eae7Such 	/* CP0 access test */
599173eae7Such 	_kmode = SetKMode(1);
609173eae7Such 
619173eae7Such 	DPRINTF((TEXT("status register test\n")));
629173eae7Such 	GET_SR(r0);
639173eae7Such 	DPRINTF((TEXT("current value: 0x%08x\n"), r0));
649173eae7Such 	SET_SR(r1);
659173eae7Such 	GET_SR(r1);
669173eae7Such 	DPRINTF((TEXT("write test:    0x%08x\n"), r1));
679173eae7Such 	SET_SR(r0);
689173eae7Such 
699173eae7Such 	SetKMode(_kmode);
709173eae7Such #endif // DEBUG_CP0_ACCESS
719173eae7Such }
729173eae7Such 
739173eae7Such BOOL
init()749173eae7Such MIPSArchitecture::init()
759173eae7Such {
769173eae7Such 	if (!_mem->init()) {
779173eae7Such 		DPRINTF((TEXT("can't initialize memory manager.\n")));
789173eae7Such 		return FALSE;
799173eae7Such 	}
809173eae7Such 
819173eae7Such 	return TRUE;
829173eae7Such }
839173eae7Such 
849173eae7Such BOOL
setupLoader()859173eae7Such MIPSArchitecture::setupLoader()
869173eae7Such {
879173eae7Such 	vaddr_t v;
889173eae7Such 
899173eae7Such #ifdef DEBUG_KERNADDR_ACCESS // kernel address access test
909173eae7Such #define	TEST_MAGIC		0xac1dcafe
919173eae7Such 	paddr_t p;
9224c8a902Suwe 	uint32_t r0;
939173eae7Such 
949173eae7Such 	_kmode = SetKMode(1);
959173eae7Such 	_mem->getPage(v, p);
969173eae7Such 	VOLATILE_REF(ptokv(p)) = TEST_MAGIC;
979173eae7Such 	cacheFlush();
989173eae7Such 	r0 = VOLATILE_REF(v);
999173eae7Such 	DPRINTF((TEXT("kernel address access test: %S\n"),
1009173eae7Such 	    r0 == TEST_MAGIC ? "OK" : "NG"));
1019173eae7Such 	SetKMode(_kmode);
1029173eae7Such #endif // DEBUG_KERNADDR_ACCESS
1039173eae7Such 
1049173eae7Such 	if (!_mem->getPage(v , _loader_addr)) {
1059173eae7Such 		DPRINTF((TEXT("can't get page for 2nd loader.\n")));
1069173eae7Such 		return FALSE;
1079173eae7Such 	}
1089173eae7Such 	DPRINTF((TEXT("2nd bootloader vaddr=0x%08x paddr=0x%08x\n"),
1099173eae7Such 	    (unsigned)v,(unsigned)_loader_addr));
1109173eae7Such 
1119173eae7Such 	memcpy(LPVOID(v), LPVOID(_boot_func), _mem->getPageSize());
1129173eae7Such 	DPRINTF((TEXT("2nd bootloader copy done.\n")));
1139173eae7Such 
1149173eae7Such 	return TRUE;
1159173eae7Such }
1169173eae7Such 
1179173eae7Such void
jump(paddr_t info,paddr_t pvec)1189173eae7Such MIPSArchitecture::jump(paddr_t info, paddr_t pvec)
1199173eae7Such {
1209173eae7Such 	kaddr_t sp;
1219173eae7Such 	vaddr_t v;
1229173eae7Such 	paddr_t p;
1239173eae7Such 
1249173eae7Such 	// stack for bootloader(but mips loader don't use stack)
1259173eae7Such 	_mem->getPage(v, p);
1269173eae7Such 	sp = ptokv(p + _mem->getPageSize() - 0x10);
1279173eae7Such 
1289173eae7Such 	info = ptokv(info);
1299173eae7Such 	pvec = ptokv(pvec);
1309173eae7Such 	_loader_addr = ptokv(_loader_addr);
1319173eae7Such 
1329173eae7Such 	// switch kernel mode.
1339173eae7Such 	SetKMode(1);
1349173eae7Such 	if (SetKMode(1) != 1) {
1359173eae7Such 		DPRINTF((TEXT("SetKMode(1) failed.\n")));
1369173eae7Such 		return;
1379173eae7Such 	}
138679894e9Senami 	DPRINTF((TEXT("jump to 0x%08x (info=0x%08x, pvec=0x%08x)\n"),
1399173eae7Such 	    _loader_addr, info, pvec));
1409173eae7Such 
1419173eae7Such 	// writeback whole D-cache and invalidate whole I-cache.
1429173eae7Such 	// 2nd boot-loader access data via kseg0 which were writed via kuseg,
1439173eae7Such 	cacheFlush();
1449173eae7Such 
1459173eae7Such 	// jump to 2nd-loader(run kseg0)
1469173eae7Such 	__asm(".set noreorder;"
1479173eae7Such 	    "jr	a3;"
1489173eae7Such 	    "move	sp, a2;"
1499173eae7Such 	    ".set reorder", info, pvec, sp, _loader_addr);
1509173eae7Such 	// NOTREACHED
1519173eae7Such }
152