sh_arch.cpp revision 1.1 1 /* $NetBSD: sh_arch.cpp,v 1.1 2001/02/09 18:35:16 uch 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", ®);
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