/* -*-C++-*- $NetBSD: sh_dev.cpp,v 1.5 2008/04/28 20:23:20 martin Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by UCHIYAMA Yasushi.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <hpcboot.h>
#include <hpcmenu.h>
#include <console.h>
#include <sh3/sh_mmu.h>
#include <sh3/dev/sh_dev.h>
#include <sh3/dev/sh.h>
SHdev::SHdev()
{
_menu = &HpcMenuInterface::Instance();
_cons = Console::Instance();
}
void
SHdev::dump(uint8_t bit)
{
uint32_t reg = 0;
int kmode;
DPRINTF((TEXT("DEBUG BIT: ")));
bitdisp(bit);
if (bit & DUMP_CPU) {
// Cache
MemoryManager_SHMMU::CacheDump();
// MMU
MemoryManager_SHMMU::MMUDump();
// Status register
kmode = SetKMode(1);
__asm(
"stc sr, r0\n"
"mov.l r0, @r4", ®);
SetKMode(kmode);
DPRINTF((TEXT("SR: ")));
bitdisp(reg);
}
if (bit & DUMP_DEV) {
kmode = SetKMode(1);
print_stack_pointer();
// SCIF
scif_dump(HPC_PREFERENCE.serial_speed);
SetKMode(kmode);
}
}
void
SHdev::print_stack_pointer(void)
{
int sp;
__asm("mov.l r15, @r4", &sp);
DPRINTF((TEXT("SP 0x%08x\n"), sp));
}
//
// SH3/SH4 common functions.
//
// SCIF
void
SHdev::scif_dump(int bps)
{
uint16_t r16;
uint32_t r;
int n;
print_stack_pointer();
DPRINTF((TEXT("<<<SCIF>>>\n")));
/* mode */
r = _scif_reg_read(SH3_SCSMR2);
n = 1 << ((r & SCSMR2_CKS) << 1);
DPRINTF((TEXT("mode: %dbit %S-parity %d stop bit clock PCLOCK/%d\n"),
r & SCSMR2_CHR ? 7 : 8,
r & SCSMR2_PE ? r & SCSMR2_OE ? "odd" : "even" : "non",
r & SCSMR2_STOP ? 2 : 1,
n));
/* bit rate */
r = _scif_reg_read(SH3_SCBRR2);
DPRINTF((TEXT("SCBRR=%d(%dbps) estimated PCLOCK %dHz\n"), r, bps,
32 * bps *(r + 1) * n));
/* control */
#define DBG_BIT_PRINT(r, m) _dbg_bit_print(r, SCSCR2_##m, #m)
DPRINTF((TEXT("SCSCR2: ")));
r = _scif_reg_read(SH3_SCSCR2);
DBG_BIT_PRINT(r, TIE);
DBG_BIT_PRINT(r, RIE);
DBG_BIT_PRINT(r, TE);
DBG_BIT_PRINT(r, RE);
DPRINTF((TEXT("CKE=%d\n"), r & SCSCR2_CKE));
#undef DBG_BIT_PRINT
/* status */
#define DBG_BIT_PRINT(r, m) _dbg_bit_print(r, SCSSR2_##m, #m)
r16 = _reg_read_2(SH3_SCSSR2);
DPRINTF((TEXT("SCSSR2: ")));
DBG_BIT_PRINT(r16, ER);
DBG_BIT_PRINT(r16, TEND);
DBG_BIT_PRINT(r16, TDFE);
DBG_BIT_PRINT(r16, BRK);
DBG_BIT_PRINT(r16, FER);
DBG_BIT_PRINT(r16, PER);
DBG_BIT_PRINT(r16, RDF);
DBG_BIT_PRINT(r16, DR);
#undef DBG_BIT_PRINT
/* FIFO control */
#define DBG_BIT_PRINT(r, m) _dbg_bit_print(r, SCFCR2_##m, #m)
r = _scif_reg_read(SH3_SCFCR2);
DPRINTF((TEXT("SCFCR2: ")));
DBG_BIT_PRINT(r, RTRG1);
DBG_BIT_PRINT(r, RTRG0);
DBG_BIT_PRINT(r, TTRG1);
DBG_BIT_PRINT(r, TTRG0);
DBG_BIT_PRINT(r, MCE);
DBG_BIT_PRINT(r, TFRST);
DBG_BIT_PRINT(r, RFRST);
DBG_BIT_PRINT(r, LOOP);
DPRINTF((TEXT("\n")));
#undef DBG_BIT_PRINT
}
// INTC
void
SHdev::icu_dump_priority(struct intr_priority *tab)
{
DPRINTF((TEXT("<<<INTC>>>\n")));
DPRINTF((TEXT("----interrupt priority----\n")));
for (; tab->name; tab++) {
DPRINTF((TEXT("%-10S %d\n"), tab->name,
(_reg_read_2(tab->reg) >> tab->shift) & SH_IPR_MASK));
}
DPRINTF((TEXT("--------------------------\n")));
}