Home | History | Annotate | Line # | Download | only in sh3
sh_arch.cpp revision 1.1.2.2
      1 /*	$NetBSD: sh_arch.cpp,v 1.1.2.2 2001/02/11 19:10:12 bouyer 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  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 #include <sh3/sh_arch.h>
     40 #include "scifreg.h"
     41 
     42 struct SHArchitecture::intr_priority SHArchitecture::ipr_table[] = {
     43 	{ "TMU0",	ICU_IPRA_REG16, 12 },
     44 	{ "TMU1",	ICU_IPRA_REG16,  8 },
     45 	{ "TMU2",	ICU_IPRA_REG16,  4 },
     46 	{ "RTC",	ICU_IPRA_REG16,  0 },
     47 	{ "WDT",	ICU_IPRB_REG16, 12 },
     48 	{ "REF",	ICU_IPRB_REG16,  8 },
     49 	{ "SCI",	ICU_IPRB_REG16,  4 },
     50 	{ "reserve",	ICU_IPRB_REG16,  0 },
     51 	{ "IRQ3",	ICU_IPRC_REG16, 12 },
     52 	{ "IRQ2",	ICU_IPRC_REG16,  8 },
     53 	{ "IRQ1",	ICU_IPRC_REG16,  4 },
     54 	{ "IRQ0",	ICU_IPRC_REG16,  0 },
     55 	{ "PINT0-7",	ICU_IPRD_REG16, 12 },
     56 	{ "PINT8-15",	ICU_IPRD_REG16,  8 },
     57 	{ "IRQ5",	ICU_IPRD_REG16,  4 },
     58 	{ "IRQ4",	ICU_IPRD_REG16,  0 },
     59 	{ "DMAC",	ICU_IPRE_REG16, 12 },
     60 	{ "IrDA",	ICU_IPRE_REG16,  8 },
     61 	{ "SCIF",	ICU_IPRE_REG16,  4 },
     62 	{ "ADC",	ICU_IPRE_REG16,  0 },
     63 	{ 0, 0, 0} /* terminator */
     64 };
     65 
     66 BOOL
     67 SHArchitecture::init(void)
     68 {
     69 	if (!_mem->init()) {
     70 		DPRINTF((TEXT("can't initialize memory manager.\n")));
     71 		return FALSE;
     72 	}
     73 	// set D-RAM information
     74 	_mem->loadBank(DRAM_BANK0_START, DRAM_BANK_SIZE);
     75 	_mem->loadBank(DRAM_BANK1_START, DRAM_BANK_SIZE);
     76 
     77 	return TRUE;
     78 }
     79 
     80 BOOL
     81 SHArchitecture::setupLoader()
     82 {
     83 	vaddr_t v;
     84 
     85 	if (!_mem->getPage(v , _loader_addr)) {
     86 		DPRINTF((TEXT("can't get page for 2nd loader.\n")));
     87 		return FALSE;
     88 	}
     89 	DPRINTF((TEXT("2nd bootloader vaddr=0x%08x paddr=0x%08x\n"),
     90 		 (unsigned)v,(unsigned)_loader_addr));
     91 
     92 	memcpy(LPVOID(v), LPVOID(_boot_func), _mem->getPageSize());
     93 	DPRINTF((TEXT("2nd bootloader copy done.\n")));
     94 
     95 	return TRUE;
     96 }
     97 
     98 void
     99 SHArchitecture::jump(paddr_t info, paddr_t pvec)
    100 {
    101 	kaddr_t sp;
    102 	vaddr_t v;
    103 	paddr_t p;
    104 
    105 	// stack for bootloader
    106 	_mem->getPage(v, p);
    107 	sp = ptokv(p + _mem->getPageSize() / 2);
    108 
    109 	info = ptokv(info);
    110 	pvec = ptokv(pvec);
    111 	_loader_addr = ptokv(_loader_addr);
    112 	DPRINTF((TEXT("BootArgs 0x%08x Stack 0x%08x\nBooting kernel...\n"),
    113 		 info, sp));
    114 
    115 	// Change to privilege-mode.
    116 	SetKMode(1);
    117 
    118 	// Disable external interrupt.
    119 	suspendIntr();
    120 
    121 	// Cache flush(for 2nd bootloader)
    122 	cache_flush();
    123 
    124 	// jump to 2nd loader.(run P1) at this time I still use MMU.
    125 	__asm("mov	r6, r15\n"
    126 	      "jmp	@r7\n"
    127 	      "nop\n", info, pvec, sp, _loader_addr);
    128 	// NOTREACHED
    129 }
    130 
    131 // disable external interrupt and save its priority.
    132 u_int32_t
    133 suspendIntr(void)
    134 {
    135 	u_int32_t sr;
    136 	__asm("stc	sr, r0\n"
    137 	      "mov.l	r0, @r4\n"
    138 	      "or	r5, r0\n"
    139 	      "ldc	r0, sr\n", &sr, 0x000000f0);
    140 	return sr & 0x000000f0;
    141 }
    142 
    143 // resume external interrupt priority.
    144 void
    145 resumeIntr(u_int32_t s)
    146 {
    147 	__asm("stc	sr, r0\n"
    148 	      "and	r5, r0\n"
    149 	      "or	r4, r0\n"
    150 	      "ldc	r0, sr\n", s, 0xffffff0f);
    151 }
    152 
    153 void
    154 SHArchitecture::print_stack_pointer(void)
    155 {
    156 	int sp;
    157 	__asm("mov.l	r15, @r4", &sp);
    158 	DPRINTF((TEXT("SP 0x%08x\n"), sp));
    159 }
    160 
    161 void
    162 SHArchitecture::systemInfo()
    163 {
    164 	u_int32_t reg;
    165 
    166 	Architecture::systemInfo();
    167 
    168 	_kmode = SetKMode(1);
    169 
    170 	// Cache
    171 	reg = VOLATILE_REF(CCR);
    172 	DPRINTF((TEXT("Cache ")));
    173 	if (reg & CCR_CE)
    174 		DPRINTF((TEXT("Enabled. %s-mode, P0/U0/P3 Write-%s, P1 Write-%s\n"),
    175 			 reg & CCR_RA ? TEXT("RAM") : TEXT("normal"),
    176 			 reg & CCR_WT ? TEXT("Through") : TEXT("Back"),
    177 			 reg & CCR_CB ? TEXT("Back") : TEXT("Through")));
    178 	else
    179 		DPRINTF((TEXT("Disabled.\n")));
    180 
    181 	// MMU
    182 	reg = VOLATILE_REF(MMUCR);
    183 	DPRINTF((TEXT("MMU ")));
    184 	if (reg & MMUCR_AT)
    185 		DPRINTF((TEXT("Enabled. %s index-mode, %s virtual storage mode\n"),
    186 			 reg & MMUCR_IX
    187 			 ? TEXT("ASID + VPN") : TEXT("VPN only"),
    188 			 reg & MMUCR_SV ? TEXT("single") : TEXT("multiple")));
    189 	else
    190 		DPRINTF((TEXT("Disabled.\n")));
    191 
    192 	// Status register
    193 	reg = 0;
    194 	__asm("stc	sr, r0\n"
    195 	      "mov.l	r0, @r4", &reg);
    196 	DPRINTF((TEXT("SR 0x%08x\n"), reg));
    197 
    198 	// SCIF
    199 	scif_dump(19200);
    200 
    201 	// ICU
    202 	print_stack_pointer();
    203 	icu_dump();
    204 
    205 #if 0	// Frame Buffer (this test is destructive.)
    206 	hd64461_framebuffer_test();
    207 #endif
    208 
    209 	SetKMode(_kmode);
    210 }
    211 
    212 void
    213 SHArchitecture::icu_dump(void)
    214 {
    215 	print_stack_pointer();
    216 
    217 	DPRINTF((TEXT("ICR0   0x%08x\n"), reg_read16(ICU_ICR0_REG16)));
    218 	DPRINTF((TEXT("ICR1   0x%08x\n"), reg_read16(ICU_ICR1_REG16)));
    219 	DPRINTF((TEXT("ICR2   0x%08x\n"), reg_read16(ICU_ICR2_REG16)));
    220 	DPRINTF((TEXT("PINTER 0x%08x\n"), reg_read16(ICU_PINTER_REG16)));
    221 	DPRINTF((TEXT("IPRA   0x%08x\n"), reg_read16(ICU_IPRA_REG16)));
    222 	DPRINTF((TEXT("IPRB   0x%08x\n"), reg_read16(ICU_IPRB_REG16)));
    223 	DPRINTF((TEXT("IPRC   0x%08x\n"), reg_read16(ICU_IPRC_REG16)));
    224 	DPRINTF((TEXT("IPRD   0x%08x\n"), reg_read16(ICU_IPRD_REG16)));
    225 	DPRINTF((TEXT("IPRE   0x%08x\n"), reg_read16(ICU_IPRE_REG16)));
    226 	DPRINTF((TEXT("IRR0   0x%08x\n"), reg_read8(ICU_IRR0_REG8)));
    227 	DPRINTF((TEXT("IRR1   0x%08x\n"), reg_read8(ICU_IRR1_REG8)));
    228 	DPRINTF((TEXT("IRR2   0x%08x\n"), reg_read8(ICU_IRR2_REG8)));
    229 	icu_control();
    230 	icu_priority();
    231 }
    232 
    233 void
    234 SHArchitecture::icu_priority(void)
    235 {
    236 	struct intr_priority *tab;
    237 	DPRINTF((TEXT("----interrupt priority----\n")));
    238 	for (tab = ipr_table; tab->name; tab++) {
    239 		DPRINTF((TEXT("%-10S %d\n"), tab->name,
    240 			 (reg_read16(tab->reg) >> tab->shift) & ICU_IPR_MASK));
    241 	}
    242 	DPRINTF((TEXT("--------------------------\n")));
    243 }
    244 
    245 void
    246 SHArchitecture::icu_control(void)
    247 {
    248 	const char *sense_select[] = {
    249 		"falling edge",
    250 		"raising edge",
    251 		"low level",
    252 		"reserved",
    253 	};
    254 	u_int16_t r;
    255 	// PINT0-15
    256 	DPRINTF((TEXT("PINT enable(on |)  :")));
    257 	bitdisp(reg_read16(ICU_PINTER_REG16));
    258 	DPRINTF((TEXT("PINT detect(high |):")));
    259 	bitdisp(reg_read16(ICU_ICR2_REG16));
    260 	// NMI
    261 	r = reg_read16(ICU_ICR0_REG16);
    262 	DPRINTF((TEXT("NMI(%S %S-edge),"),
    263 		 r & ICU_ICR0_NMIL ? "High" : "Low",
    264 		 r & ICU_ICR0_NMIE ? "raising" : "falling"));
    265 	r = reg_read16(ICU_ICR1_REG16);
    266 	DPRINTF((TEXT(" %S maskable,"), r & ICU_ICR1_MAI ? "" : "never"));
    267 	DPRINTF((TEXT("  SR.BL %S\n"),
    268 		 r & ICU_ICR1_BLMSK ? "ignored" : "maskable"));
    269 	// IRQ0-5
    270 	DPRINTF((TEXT("IRQ[3:0] : %S source\n"),
    271 		 r & ICU_ICR1_IRQLVL ? "IRL 15level" :
    272 		 "dependent IRQ[0:3](IRL disabled)"));
    273 	if (r & ICU_ICR1_IRQLVL) {
    274 		DPRINTF((TEXT("IRLS[0:3] %S\n"),
    275 			 r & ICU_ICR1_IRLSEN ? "enabled" : "disabled"));
    276 	}
    277 	// sense select
    278 	for (int i = 5; i >= 0; i--) {
    279 		DPRINTF((TEXT("IRQ[%d] %S\n"), i,
    280 			 sense_select [
    281 				 (r >>(i * 2)) & ICU_SENSE_SELECT_MASK]));
    282 	}
    283 }
    284 
    285 SH_BOOT_FUNC_(7709);
    286 SH_BOOT_FUNC_(7709A);
    287 
    288 //
    289 // Debug Functions.
    290 //
    291 void
    292 SHArchitecture::scif_dump(int bps)
    293 {
    294 	u_int16_t r16;
    295 	u_int8_t r8;
    296 	int n;
    297 
    298 	/* mode */
    299 	r8 = SHREG_SCSMR2;
    300 	n = 1 <<((r8 & SCSMR2_CKS) << 1);
    301 	DPRINTF((TEXT("mode: %dbit %S-parity %d stop bit clock PCLOCK/%d\n"),
    302 		 r8 & SCSMR2_CHR ? 7 : 8,
    303 		 r8 & SCSMR2_PE	? r8 & SCSMR2_OE ? "odd" : "even" : "non",
    304 		 r8 & SCSMR2_STOP ? 2 : 1,
    305 		 n));
    306 	/* bit rate */
    307 	r8 = SHREG_SCBRR2;
    308 	DPRINTF((TEXT("SCBRR=%d(%dbps) estimated PCLOCK %dHz\n"), r8, bps,
    309 		 32 * bps *(r8 + 1) * n));
    310 
    311 	/* control */
    312 #define DBG_BIT_PRINT(r, m)	_dbg_bit_print(r, SCSCR2_##m, #m)
    313 	DPRINTF((TEXT("SCSCR2: ")));
    314 	r8 = SHREG_SCSCR2;
    315 	DBG_BIT_PRINT(r8, TIE);
    316 	DBG_BIT_PRINT(r8, RIE);
    317 	DBG_BIT_PRINT(r8, TE);
    318 	DBG_BIT_PRINT(r8, RE);
    319 	DPRINTF((TEXT("CKE=%d\n"), r8 & SCSCR2_CKE));
    320 #undef	DBG_BIT_PRINT
    321 
    322 	/* status */
    323 #define DBG_BIT_PRINT(r, m)	_dbg_bit_print(r, SCSSR2_##m, #m)
    324 	r16 = SHREG_SCSSR2;
    325 	DPRINTF((TEXT("SCSSR2: ")));
    326 	DBG_BIT_PRINT(r16, ER);
    327 	DBG_BIT_PRINT(r16, TEND);
    328 	DBG_BIT_PRINT(r16, TDFE);
    329 	DBG_BIT_PRINT(r16, BRK);
    330 	DBG_BIT_PRINT(r16, FER);
    331 	DBG_BIT_PRINT(r16, PER);
    332 	DBG_BIT_PRINT(r16, RDF);
    333 	DBG_BIT_PRINT(r16, DR);
    334 #undef	DBG_BIT_PRINT
    335 
    336 	/* FIFO control */
    337 #define DBG_BIT_PRINT(r, m)	_dbg_bit_print(r, SCFCR2_##m, #m)
    338 	r8 = SHREG_SCFCR2;
    339 	DPRINTF((TEXT("SCFCR2: ")));
    340 	DBG_BIT_PRINT(r8, RTRG1);
    341 	DBG_BIT_PRINT(r8, RTRG0);
    342 	DBG_BIT_PRINT(r8, TTRG1);
    343 	DBG_BIT_PRINT(r8, TTRG0);
    344 	DBG_BIT_PRINT(r8, MCE);
    345 	DBG_BIT_PRINT(r8, TFRST);
    346 	DBG_BIT_PRINT(r8, RFRST);
    347 	DBG_BIT_PRINT(r8, LOOP);
    348 	DPRINTF((TEXT("\n")));
    349 #undef	DBG_BIT_PRINT
    350 }
    351 
    352 void
    353 SHArchitecture::hd64461_framebuffer_test()
    354 {
    355 	DPRINTF((TEXT("frame buffer test start\n")));
    356 #if SH7709TEST
    357 	u_int32_t sh7707_fb_dma_addr;
    358 	u_int16_t val;
    359 	int s;
    360 
    361 	s = suspendIntr();
    362 	VOLATILE_REF16(SH7707_LCDAR_REG16) = SH7707_LCDAR_LCDDMR0;
    363 	val = VOLATILE_REF16(SH7707_LCDDMR_REG16);
    364 	sh7707_fb_dma_addr = val;
    365 	VOLATILE_REF16(SH7707_LCDAR_REG16) = SH7707_LCDAR_LCDDMR1;
    366 	val = VOLATILE_REF16(SH7707_LCDDMR_REG16);
    367 	sh7707_fb_dma_addr |= (val << 16);
    368 	resumeIntr(s);
    369 
    370 	DPRINTF((TEXT("SH7707 frame buffer dma address: 0x%08x\n"),
    371 		 sh7707_fb_dma_addr));
    372 #else
    373 	u_int8_t *fb = reinterpret_cast<u_int8_t *>(HD64461_FB_ADDR);
    374 
    375 	for (int i = 0; i < 480 * 240 * 2 / 8; i++)
    376 		*fb++ = 0xff;
    377 #endif
    378 	DPRINTF((TEXT("frame buffer test end\n")));
    379 }
    380