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