1 /* -*-C++-*- $NetBSD: sh_arch.h,v 1.12 2008/04/28 20:23:20 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2001, 2002, 2004 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _HPCBOOT_SH_ARCH_H_ 33 #define _HPCBOOT_SH_ARCH_H_ 34 35 #include <arch.h> 36 #include <memory.h> // loadBank 37 #include <console.h> // DPRINTF 38 39 #include <sh3/dev/sh_dev.h> 40 41 // CPU specific macro 42 #include <sh3/cpu/sh3.h> 43 #include <sh3/cpu/sh4.h> 44 45 class SHArchitecture : public Architecture { 46 protected: 47 typedef void(*boot_func_t)(struct BootArgs *, struct PageTag *); 48 SHdev *_dev; 49 50 private: 51 typedef Architecture super; 52 boot_func_t _boot_func; 53 54 protected: 55 // should be created as actual product insntnce. not public. 56 SHArchitecture(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc) 57 : _boot_func(bootfunc), Architecture(cons, mem) { 58 // NO-OP 59 } 60 virtual ~SHArchitecture(void) { /* NO-OP */ } 61 virtual void cache_flush(void) = 0; 62 63 public: 64 virtual BOOL init(void); 65 virtual BOOL setupLoader(void); 66 virtual void systemInfo(void); 67 virtual void jump(kaddr_t info, kaddr_t pvec); 68 69 // returns host machines CPU type. 3 for SH3. 4 for SH4 70 static int cpu_type(void); 71 }; 72 73 // 74 // SH product. setup cache flush routine and 2nd-bootloader. 75 // 76 77 // 78 // SH3 series. 79 /// 80 #define SH_(x) \ 81 class SH ## x : public SHArchitecture { \ 82 private: \ 83 typedef SHArchitecture super; \ 84 public: \ 85 SH ## x(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc)\ 86 : SHArchitecture(cons, mem, bootfunc) { \ 87 DPRINTF((TEXT("CPU: SH") TEXT(#x) TEXT("\n"))); \ 88 _dev = new SH3dev; \ 89 } \ 90 ~SH ## x(void) { \ 91 delete _dev; \ 92 } \ 93 \ 94 virtual BOOL init(void) { \ 95 int sz; \ 96 \ 97 if (!super::init()) \ 98 return FALSE; \ 99 /* SH7709, SH7709A split AREA3 to two area. */ \ 100 sz = SH_AREA_SIZE / 2; \ 101 _mem->loadBank(SH_AREA3_START, sz); \ 102 _mem->loadBank(SH_AREA3_START + sz , sz); \ 103 return TRUE; \ 104 } \ 105 \ 106 virtual void cache_flush(void) { \ 107 SH ## x ## _CACHE_FLUSH(); \ 108 } \ 109 \ 110 static void boot_func(struct BootArgs *, struct PageTag *); \ 111 } 112 113 SH_(7709); 114 SH_(7709A); 115 SH_(7707); 116 117 // 118 // SH4 series. 119 /// 120 class SH7750 : public SHArchitecture { 121 private: 122 typedef SHArchitecture super; 123 124 public: 125 SH7750(Console *&cons, MemoryManager *&mem, boot_func_t bootfunc) 126 : SHArchitecture(cons, mem, bootfunc) { 127 DPRINTF((TEXT("CPU: SH7750\n"))); 128 _dev = new SH4dev; 129 } 130 ~SH7750(void) { 131 delete _dev; 132 } 133 134 virtual BOOL init(void) { 135 136 if (!super::init()) 137 return FALSE; 138 _mem->loadBank(SH_AREA3_START, SH_AREA_SIZE); 139 140 return TRUE; 141 } 142 143 virtual void cache_flush(void) { 144 // 145 // To invalidate I-cache, program must run on P2. I can't 146 // do it myself, use WinCE API. (WCE2.10 or later) 147 // 148 CacheSync(CACHE_D_WBINV); 149 CacheSync(CACHE_I_INV); 150 } 151 152 virtual BOOL setupLoader(void) { 153 // 154 // 2nd boot loader access cache address array. run on P2. 155 // 156 if (super::setupLoader()) { 157 (uint32_t)_loader_addr |= 0x20000000; 158 DPRINTF 159 ((TEXT("loader address moved to P2-area 0x%08x\n"), 160 (unsigned)_loader_addr)); 161 return TRUE; 162 } 163 164 return FALSE; 165 } 166 167 static void boot_func(struct BootArgs *, struct PageTag *); 168 }; 169 170 // 171 // 2nd-bootloader. make sure that PIC and its size is lower than page size. 172 // and can't call subroutine. 173 // 174 #define SH_BOOT_FUNC_(x) \ 175 void \ 176 SH##x##::boot_func(struct BootArgs *bi, struct PageTag *p) \ 177 { \ 178 /* Disable interrupt. block exception.(TLB exception don't occur) */ \ 179 int tmp; \ 180 __asm("stc sr, r5\n" \ 181 "or r4, r5\n" \ 182 "ldc r5, sr\n", 0x500000f0, tmp); \ 183 /* Now I run on P1(P2 for SH4), TLB flush. and disable. */ \ 184 \ 185 SH ## x ## _MMU_DISABLE(); \ 186 do { \ 187 uint32_t *dst =(uint32_t *)p->dst; \ 188 uint32_t *src =(uint32_t *)p->src; \ 189 uint32_t sz = p->sz / sizeof (int); \ 190 if (p->src == ~0) \ 191 while (sz--) \ 192 *dst++ = 0; \ 193 else \ 194 while (sz--) \ 195 *dst++ = *src++; \ 196 } while ((p =(struct PageTag *)p->next) != ~0); \ 197 \ 198 SH ## x ## _CACHE_FLUSH(); \ 199 \ 200 /* jump to kernel entry. */ \ 201 __asm("jmp @r7\n" \ 202 "nop\n", bi->argc, bi->argv, \ 203 bi->bootinfo, bi->kernel_entry); \ 204 } 205 206 // suspend/resume external Interrupt. 207 // (don't block) use under privilege mode. 208 // 209 __BEGIN_DECLS 210 uint32_t suspendIntr(void); 211 void resumeIntr(uint32_t); 212 __END_DECLS 213 214 #endif // _HPCBOOT_SH_ARCH_H_ 215