1 /* -*-C++-*- $NetBSD: sh_arch.h,v 1.6 2002/02/11 17:08:56 uch Exp $ */ 2 3 /*- 4 * Copyright (c) 2001, 2002 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 #ifndef _HPCBOOT_SH_ARCH_H_ 40 #define _HPCBOOT_SH_ARCH_H_ 41 42 #include <arch.h> 43 #include <memory.h> // loadBank 44 #include <console.h> // DPRINTF 45 46 #include <sh3/dev/sh_dev.h> 47 48 // CPU specific macro 49 #include <sh3/cpu/sh3.h> 50 #include <sh3/cpu/sh4.h> 51 52 class SHArchitecture : public Architecture { 53 protected: 54 typedef void(*boot_func_t)(struct BootArgs *, struct PageTag *); 55 SHdev *_dev; 56 57 private: 58 typedef Architecture super; 59 boot_func_t _boot_func; 60 61 protected: 62 // should be created as actual product insntnce. not public. 63 SHArchitecture(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc) 64 : _boot_func(bootfunc), Architecture(cons, mem) { 65 // NO-OP 66 } 67 virtual ~SHArchitecture(void) { /* NO-OP */ } 68 virtual void cache_flush(void) = 0; 69 70 public: 71 virtual BOOL init(void); 72 virtual BOOL setupLoader(void); 73 virtual void systemInfo(void); 74 virtual void jump(kaddr_t info, kaddr_t pvce); 75 76 // returns host machines CPU type. 3 for SH3. 4 for SH4 77 static int cpu_type(void); 78 }; 79 80 // 81 // SH product. setup cache flush routine and 2nd-bootloader. 82 // 83 84 // 85 // SH3 series. 86 /// 87 #define SH_(x) \ 88 class SH ## x : public SHArchitecture { \ 89 private: \ 90 typedef SHArchitecture super; \ 91 public: \ 92 SH ## x(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc)\ 93 : SHArchitecture(cons, mem, bootfunc) { \ 94 DPRINTF((TEXT("CPU: SH") TEXT(#x) TEXT("\n"))); \ 95 _dev = new SH3dev; \ 96 } \ 97 ~SH ## x(void) { \ 98 delete _dev; \ 99 } \ 100 \ 101 virtual BOOL init(void) { \ 102 int sz; \ 103 \ 104 if (!super::init()) \ 105 return FALSE; \ 106 /* SH7709, SH7709A split AREA3 to two area. */ \ 107 sz = SH_AREA_SIZE / 2; \ 108 _mem->loadBank(SH_AREA3_START, sz); \ 109 _mem->loadBank(SH_AREA3_START + sz , sz); \ 110 return TRUE; \ 111 } \ 112 \ 113 virtual void cache_flush(void) { \ 114 SH ## x ## _CACHE_FLUSH(); \ 115 } \ 116 \ 117 static void boot_func(struct BootArgs *, struct PageTag *); \ 118 } 119 120 SH_(7709); 121 SH_(7709A); 122 123 // 124 // SH4 series. 125 /// 126 class SH7750 : public SHArchitecture { 127 private: 128 typedef SHArchitecture super; 129 130 public: 131 SH7750(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc) 132 : SHArchitecture(cons, mem, bootfunc) { 133 DPRINTF((TEXT("CPU: SH7750\n"))); 134 _dev = new SH4dev; 135 } 136 ~SH7750(void) { 137 delete _dev; 138 } 139 140 virtual BOOL init(void) { 141 142 if (!super::init()) 143 return FALSE; 144 _mem->loadBank(SH_AREA3_START, SH_AREA_SIZE); 145 146 return TRUE; 147 } 148 149 virtual void cache_flush(void) { 150 // 151 // To invalidate I-cache, program must run on P2. I can't 152 // do it myself, use WinCE API. (WCE2.10 or later) 153 // 154 CacheSync(CACHE_D_WBINV); 155 CacheSync(CACHE_I_INV); 156 } 157 158 virtual BOOL setupLoader(void) { 159 // 160 // 2nd boot loader access cache address array. run on P2. 161 // 162 if (super::setupLoader()) { 163 (u_int32_t)_loader_addr |= 0x20000000; 164 DPRINTF 165 ((TEXT("loader address moved to P2-area 0x%08x\n"), 166 (unsigned)_loader_addr)); 167 return TRUE; 168 } 169 170 return FALSE; 171 } 172 173 static void boot_func(struct BootArgs *, struct PageTag *); 174 }; 175 176 // 177 // 2nd-bootloader. make sure that PIC and its size is lower than page size. 178 // and can't call subroutine. 179 // 180 #define SH_BOOT_FUNC_(x) \ 181 void \ 182 SH##x##::boot_func(struct BootArgs *bi, struct PageTag *p) \ 183 { \ 184 /* Disable interrupt. block exception.(TLB exception don't occur) */ \ 185 int tmp; \ 186 __asm("stc sr, r5\n" \ 187 "or r4, r5\n" \ 188 "ldc r5, sr\n", 0x500000f0, tmp); \ 189 /* Now I run on P1(P2 for SH4), TLB flush. and disable. */ \ 190 \ 191 SH ## x ## _MMU_DISABLE(); \ 192 do { \ 193 u_int32_t *dst =(u_int32_t *)p->dst; \ 194 u_int32_t *src =(u_int32_t *)p->src; \ 195 u_int32_t sz = p->sz / sizeof (int); \ 196 if (p->src == ~0) \ 197 while (sz--) \ 198 *dst++ = 0; \ 199 else \ 200 while (sz--) \ 201 *dst++ = *src++; \ 202 } while ((p =(struct PageTag *)p->next) != ~0); \ 203 \ 204 SH ## x ## _CACHE_FLUSH(); \ 205 \ 206 /* jump to kernel entry. */ \ 207 __asm("jmp @r7\n" \ 208 "nop\n", bi->argc, bi->argv, \ 209 bi->bootinfo, bi->kernel_entry); \ 210 } 211 212 // suspend/resume external Interrupt. 213 // (don't block) use under privilege mode. 214 // 215 __BEGIN_DECLS 216 u_int32_t suspendIntr(void); 217 void resumeIntr(u_int32_t); 218 __END_DECLS 219 220 #endif // _HPCBOOT_SH_ARCH_H_ 221