1 1.8 dsl /* $NetBSD: tx39xx.c,v 1.8 2009/03/14 21:04:09 dsl Exp $ */ 2 1.3 takemura 3 1.3 takemura /*- 4 1.3 takemura * Copyright (c) 1999 Shin Takemura, UCHIYAMA Yasushi 5 1.3 takemura * All rights reserved. 6 1.3 takemura * 7 1.3 takemura * This software is part of the PocketBSD. 8 1.3 takemura * 9 1.3 takemura * Redistribution and use in source and binary forms, with or without 10 1.3 takemura * modification, are permitted provided that the following conditions 11 1.3 takemura * are met: 12 1.3 takemura * 1. Redistributions of source code must retain the above copyright 13 1.3 takemura * notice, this list of conditions and the following disclaimer. 14 1.3 takemura * 2. Redistributions in binary form must reproduce the above copyright 15 1.3 takemura * notice, this list of conditions and the following disclaimer in the 16 1.3 takemura * documentation and/or other materials provided with the distribution. 17 1.3 takemura * 3. All advertising materials mentioning features or use of this software 18 1.3 takemura * must display the following acknowledgement: 19 1.3 takemura * This product includes software developed by the PocketBSD project 20 1.3 takemura * and its contributors. 21 1.3 takemura * 4. Neither the name of the project nor the names of its contributors 22 1.3 takemura * may be used to endorse or promote products derived from this software 23 1.3 takemura * without specific prior written permission. 24 1.3 takemura * 25 1.3 takemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 1.3 takemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 1.3 takemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 1.3 takemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 1.3 takemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 1.3 takemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 1.3 takemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 1.3 takemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 1.3 takemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 1.3 takemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 1.3 takemura * SUCH DAMAGE. 36 1.3 takemura * 37 1.3 takemura */ 38 1.3 takemura 39 1.3 takemura #include <pbsdboot.h> 40 1.3 takemura 41 1.3 takemura extern void tx39xx_asm_code(); 42 1.3 takemura extern void tx39xx_asm_code_end(); 43 1.7 dsl void tx39xx_asm_code_holder(void); 44 1.3 takemura 45 1.3 takemura #define TX39_SYSADDR_CONFIG_REG 0x10C00000 46 1.3 takemura #define TX39_SYSADDR_CONFIG_REG_LEN 0x00200000 47 1.3 takemura typedef int tx_chipset_tag_t; 48 1.3 takemura u_int32_t __tx39conf_addr; 49 1.3 takemura 50 1.3 takemura u_int32_t 51 1.8 dsl tx_conf_read(tx_chipset_tag_t t, int reg) 52 1.3 takemura { 53 1.3 takemura return *((u_int32_t*)(__tx39conf_addr + reg)); 54 1.3 takemura } 55 1.3 takemura 56 1.3 takemura void 57 1.8 dsl tx_conf_write(tx_chipset_tag_t t, int reg, u_int32_t val) 58 1.3 takemura { 59 1.3 takemura u_int32_t addr = (u_int32_t)t; 60 1.3 takemura *((u_int32_t*)(__tx39conf_addr +reg)) = val; 61 1.3 takemura } 62 1.3 takemura 63 1.3 takemura void 64 1.3 takemura tx39xx_init(SYSTEM_INFO *info) 65 1.3 takemura { 66 1.3 takemura /* 4KByte page */ 67 1.3 takemura system_info.si_pagesize = info->dwPageSize; 68 1.3 takemura /* DRAM Bank 0/1 physical addr range */ 69 1.3 takemura system_info.si_dramstart = 0x04000000; 70 1.3 takemura system_info.si_drammaxsize = 0x04000000; 71 1.3 takemura /* Pointer for bootstrap code */ 72 1.3 takemura system_info.si_asmcode = (unsigned char*)tx39xx_asm_code; 73 1.3 takemura system_info.si_asmcodelen = (unsigned char*)tx39xx_asm_code_end 74 1.3 takemura - system_info.si_asmcode; 75 1.3 takemura system_info.si_boot = mips_boot; 76 1.3 takemura system_info.si_intrvec = 0x80; 77 1.3 takemura 78 1.3 takemura __tx39conf_addr = (int)VirtualAlloc(0, TX39_SYSADDR_CONFIG_REG_LEN, MEM_RESERVE, 79 1.3 takemura PAGE_NOACCESS); 80 1.3 takemura if (!VirtualCopy((LPVOID)__tx39conf_addr, 81 1.3 takemura (LPVOID)(TX39_SYSADDR_CONFIG_REG >> 8), 82 1.3 takemura TX39_SYSADDR_CONFIG_REG_LEN, 83 1.3 takemura PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL)) { 84 1.3 takemura msg_printf(MSG_ERROR, whoami, 85 1.3 takemura TEXT("Mapping TX39 configuration register failed.\n")); 86 1.3 takemura } 87 1.3 takemura } 88 1.3 takemura 89 1.3 takemura void 90 1.3 takemura tx39xx_asm_code_holder() 91 1.3 takemura { 92 1.3 takemura /* 93 1.3 takemura * void 94 1.3 takemura * startprog(register struct map_s *map) 95 1.3 takemura * { 96 1.3 takemura * register unsigned char *addr; 97 1.3 takemura * register unsigned char *p; 98 1.3 takemura * register int i; 99 1.3 takemura * 100 1.3 takemura * addr = map->base; 101 1.3 takemura * i = 0; 102 1.3 takemura * while (p = map->leaf[i / map->leafsize][i % map->leafsize]) { 103 1.3 takemura * register unsigned char *pe = p + map->pagesize; 104 1.3 takemura * while (p < pe) { 105 1.3 takemura * *addr++ = *p++; 106 1.3 takemura * } 107 1.3 takemura * i++; 108 1.3 takemura * } 109 1.3 takemura * } 110 1.3 takemura * 111 1.3 takemura * register assignment: 112 1.3 takemura * struct map_s *map a0 113 1.3 takemura * unsigned char *addr a1 114 1.3 takemura * unsigned char *p a2 115 1.3 takemura * unsigned char *pe a3 116 1.3 takemura * int i t0 117 1.3 takemura * 118 1.3 takemura * struct map_s { 119 1.6 christos * void *entry; +0 120 1.6 christos * void *base; +4 121 1.3 takemura * int pagesize; +8 122 1.3 takemura * int leafsize; +12 123 1.3 takemura * int nleaves; +16 124 1.6 christos * void *arg0; +20 125 1.6 christos * void *arg1; +24 126 1.6 christos * void *arg2; +28 127 1.6 christos * void *arg3; +32 128 1.6 christos * void **leaf[32]; +36 129 1.3 takemura * 130 1.3 takemura */ 131 1.3 takemura __asm( 132 1.3 takemura ".set noreorder;" 133 1.3 takemura ".globl tx39xx_asm_code;" 134 1.3 takemura "tx39xx_asm_code:" 135 1.3 takemura "lui a0, 0x0000;" 136 1.3 takemura "ori a0, 0x0000;" 137 1.3 takemura 138 1.3 takemura /* Disable interrupt */ 139 1.3 takemura "nop;" 140 1.3 takemura "mtc0 zero, $12;" 141 1.3 takemura "nop;" 142 1.5 uch 143 1.3 takemura /* 144 1.3 takemura * Copy kernel to bootaddr 145 1.3 takemura */ 146 1.3 takemura /* addr = map->base; */ 147 1.3 takemura "lw a1, 4(a0);" 148 1.3 takemura 149 1.3 takemura /* i = 0; */ 150 1.3 takemura "ori t0, zero, 0;" 151 1.3 takemura 152 1.3 takemura " loop_start:" 153 1.3 takemura 154 1.3 takemura /* while (p = map->leaf[i / map->leafsize][i % map->leafsize]) { */ 155 1.3 takemura /* t1 = map->leafsize */ 156 1.3 takemura "lw t1, 12(a0);" 157 1.3 takemura 158 1.3 takemura /* lo = i / map->leafsize, hi = i % map->leafsize */ 159 1.3 takemura "addu t3, zero, t0;" 160 1.3 takemura "div t3, t1;" 161 1.3 takemura /* t2 = map->leaf */ 162 1.3 takemura "addiu t2, a0, 36;" 163 1.3 takemura /* t3 = i / map->leafsize */ 164 1.3 takemura "nop;" 165 1.3 takemura "mflo t3;" 166 1.3 takemura /* t2 = map->leaf[i / map->leafsize] */ 167 1.3 takemura "sll t3, t3, 2;" 168 1.3 takemura "addu t2, t2, t3;" 169 1.3 takemura "lw t2, 0(t2);" 170 1.3 takemura /* t3 = i % map->leafsize */ 171 1.3 takemura "mfhi t3;" 172 1.3 takemura 173 1.3 takemura /* p = map->leaf[i / map->leafsize][i % map->leafsize] */ 174 1.3 takemura "sll t3, t3, 2;" 175 1.3 takemura "addu t2, t2, t3;" 176 1.3 takemura "lw a2, 0(t2);" 177 1.3 takemura 178 1.3 takemura /* if (p == NULL) { */ 179 1.3 takemura /* break; */ 180 1.3 takemura /* } */ 181 1.3 takemura "beq a2, zero, loop_end;" 182 1.3 takemura "nop;" 183 1.3 takemura 184 1.3 takemura /* register unsigned char *pe = p + map->pagesize; */ 185 1.3 takemura "lw t1, 8(a0);" 186 1.3 takemura "add a3, a2, t1;" 187 1.3 takemura 188 1.3 takemura /* while (p < pe) { */ 189 1.3 takemura "loop_start2:" 190 1.3 takemura "sltu t1, a2, a3;" 191 1.3 takemura "beq zero,t1,loop_end2;" 192 1.3 takemura "nop;" 193 1.3 takemura 194 1.3 takemura /* *addr++ = *p++; */ 195 1.3 takemura "lw t1, 0(a2);" 196 1.3 takemura "sw t1, 0(a1);" 197 1.3 takemura "addi a2, a2, 4;" 198 1.3 takemura "addi a1, a1, 4;" 199 1.3 takemura 200 1.3 takemura /* } */ 201 1.3 takemura "beq zero, zero, loop_start2;" 202 1.3 takemura "nop;" 203 1.3 takemura 204 1.3 takemura /* i++; */ 205 1.3 takemura "loop_end2:" 206 1.3 takemura "addi t0, t0, 1;" 207 1.3 takemura "beq zero, zero, loop_start;" 208 1.3 takemura "nop;" 209 1.3 takemura 210 1.3 takemura "loop_end:" 211 1.3 takemura "move t3, a0;" 212 1.3 takemura ); 213 1.3 takemura 214 1.3 takemura /* 215 1.3 takemura * Flush cache 216 1.3 takemura */ 217 1.3 takemura __asm( 218 1.3 takemura "li t1, 16384;" 219 1.3 takemura "li t2, 8192;" 220 1.3 takemura 221 1.3 takemura /* Disable I-cache */ 222 1.3 takemura "li t5, ~0x00000020;" 223 1.3 takemura "mfc0 t6, $3;" 224 1.3 takemura "and t5, t5, t6;" 225 1.3 takemura "nop;" 226 1.3 takemura "mtc0 t5, $3;" 227 1.3 takemura /* Stop streaming */ 228 1.3 takemura "beq zero, zero, 1f;" 229 1.3 takemura "nop;" 230 1.3 takemura "1:" 231 1.3 takemura /* Flush I-cache */ 232 1.3 takemura "li t0, 0x80000000;" 233 1.3 takemura "addu t1, t0, t1;" 234 1.3 takemura "subu t1, t1, 128;" 235 1.3 takemura "2:" 236 1.3 takemura ".word 0xbd000000;" 237 1.3 takemura ".word 0xbd000010;" 238 1.3 takemura ".word 0xbd000020;" 239 1.3 takemura ".word 0xbd000030;" 240 1.3 takemura ".word 0xbd000040;" 241 1.3 takemura ".word 0xbd000050;" 242 1.3 takemura ".word 0xbd000060;" 243 1.3 takemura ".word 0xbd000070;" 244 1.3 takemura "bne t0, t1, 2b;" 245 1.3 takemura "addu t0, t0, 128;" 246 1.3 takemura 247 1.3 takemura /* Flush D-cache */ 248 1.3 takemura "li t0, 0x80000000;" 249 1.3 takemura "addu t1, t0, t2;" 250 1.3 takemura 251 1.3 takemura "3:" 252 1.3 takemura "lw t2, 0(t0);" 253 1.3 takemura "bne t1, t0, 3b;" 254 1.3 takemura "addiu t0, t0, 4;" 255 1.3 takemura 256 1.3 takemura /* Enable I-cache */ 257 1.3 takemura "nop;" 258 1.3 takemura "mtc0 t6, $3;" 259 1.3 takemura "nop;" 260 1.3 takemura ); 261 1.3 takemura /* 262 1.3 takemura * Jump to kernel entry 263 1.3 takemura */ 264 1.3 takemura __asm( 265 1.3 takemura 266 1.3 takemura "lw t0, 0(t3);" /* entry addr */ 267 1.3 takemura "lw a1, 24(t3);" /* arg1 */ 268 1.3 takemura "lw a2, 28(t3);" /* arg2 */ 269 1.3 takemura "lw a3, 32(t3);" /* arg3 */ 270 1.3 takemura "lw a0, 20(t3);" /* arg0 */ 271 1.3 takemura "jr t0;" 272 1.3 takemura "nop;" 273 1.3 takemura 274 1.3 takemura ".globl tx39xx_asm_code_end;" 275 1.3 takemura "tx39xx_asm_code_end: nop;" 276 1.3 takemura ".set reorder; " 277 1.3 takemura ); 278 1.3 takemura } 279