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