1 /* $NetBSD: vr41xx.c,v 1.6 2009/03/14 14:46:00 dsl Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 Shin Takemura. 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 #include <pbsdboot.h> 39 40 extern void vr41xx_asm_code(); 41 extern void vr41xx_asm_code_end(); 42 void vr41xx_asm_code_holder(void); 43 44 void 45 vr41xx_init(SYSTEM_INFO *info) 46 { 47 /* 1KByte page */ 48 system_info.si_pagesize = info->dwPageSize; 49 /* DRAM Bank 0/1 physical addr range */ 50 system_info.si_dramstart = 0x80000000; 51 system_info.si_drammaxsize = 0x08000000; 52 /* Pointer for bootstrap code */ 53 system_info.si_asmcode = (unsigned char*)vr41xx_asm_code; 54 system_info.si_asmcodelen = (unsigned char*)vr41xx_asm_code_end 55 - system_info.si_asmcode; 56 system_info.si_boot = mips_boot; 57 system_info.si_intrvec = 0; 58 } 59 60 void 61 vr41xx_asm_code_holder() 62 { 63 /* 64 * void 65 * startprog(register struct map_s *map) 66 * { 67 * register unsigned char *addr; 68 * register unsigned char *p; 69 * register int i; 70 * 71 * addr = map->base; 72 * i = 0; 73 * while (p = map->leaf[i / map->leafsize][i % map->leafsize]) { 74 * register unsigned char *pe = p + map->pagesize; 75 * while (p < pe) { 76 * *addr++ = *p++; 77 * } 78 * i++; 79 * } 80 * } 81 * 82 * register assignment: 83 * struct map_s *map a0 84 * unsigned char *addr a1 85 * unsigned char *p a2 86 * unsigned char *pe a3 87 * int i t0 88 * 89 * struct map_s { 90 * void *entry; +0 91 * void *base; +4 92 * int pagesize; +8 93 * int leafsize; +12 94 * int nleaves; +16 95 * void *arg0; +20 96 97 * void *arg1; +24 98 99 * void *arg2; +28 100 101 * void *arg3; +32 102 103 * void **leaf[32]; +36 104 * 105 */ 106 __asm( 107 " .set noreorder; " 108 " .globl vr41xx_asm_code;" 109 "vr41xx_asm_code:" 110 " lui a0, 0x0000; " 111 " ori a0, 0x0000; " 112 113 /* addr = map->base; */ 114 "lw a1, 4(a0);" 115 116 /* i = 0; */ 117 "ori t0, zero, 0;" 118 119 " loop_start:" 120 121 /* while (p = map->leaf[i / map->leafsize][i % map->leafsize]) { */ 122 /* t1 = map->leafsize */ 123 "lw t1, 12(a0);" 124 125 /* lo = i / map->leafsize, hi = i % map->leafsize */ 126 "addu t3, zero, t0;" 127 "div t3, t1;" 128 /* t2 = map->leaf */ 129 "addiu t2, a0, 36;" 130 /* t3 = i / map->leafsize */ 131 "nop;" 132 "mflo t3;" 133 /* t2 = map->leaf[i / map->leafsize] */ 134 "sll t3, t3, 2;" 135 "addu t2, t2, t3;" 136 "lw t2, 0(t2);" 137 /* t3 = i % map->leafsize */ 138 "mfhi t3;" 139 140 /* p = map->leaf[i / map->leafsize][i % map->leafsize] */ 141 "sll t3, t3, 2;" 142 "addu t2, t2, t3;" 143 "lw a2, 0(t2);" 144 145 /* if (p == NULL) { */ 146 /* break; */ 147 /* } */ 148 "beq a2, zero, loop_end;" 149 "nop;" 150 151 /* register unsigned char *pe = p + map->pagesize; */ 152 "lw t1, 8(a0);" 153 "add a3, a2, t1;" 154 155 /* while (p < pe) { */ 156 "loop_start2:" 157 "sltu t1, a2, a3;" 158 "beq zero,t1,loop_end2;" 159 "nop;" 160 161 /* *addr++ = *p++; */ 162 "lw t1, 0(a2);" 163 "sw t1, 0(a1);" 164 "addi a2, a2, 4;" 165 "addi a1, a1, 4;" 166 167 /* } */ 168 "beq zero, zero, loop_start2;" 169 "nop;" 170 171 /* i++; */ 172 "loop_end2:" 173 "addi t0, t0, 1;" 174 "beq zero, zero, loop_start;" 175 "nop;" 176 177 " loop_end:" 178 ); 179 180 /* 181 * flush instruction cache 182 */ 183 __asm( 184 " li t0, 0x80000000;" 185 " addu t1, t0, 1024*128;" 186 " subu t1, t1, 128;" 187 "1:" 188 " cache 0, 0(t0);" 189 " cache 0, 16(t0);" 190 " cache 0, 32(t0);" 191 " cache 0, 48(t0);" 192 " cache 0, 64(t0);" 193 " cache 0, 80(t0);" 194 " cache 0, 96(t0);" 195 " cache 0, 112(t0);" 196 " bne t0, t1, 1b;" 197 " addu t0, t0, 128;" 198 ); 199 200 /* 201 * flush data cache 202 */ 203 __asm( 204 " li t0, 0x80000000;" 205 " addu t1, t0, 1024*128;" 206 " subu t1, t1, 128;" 207 "1:" 208 " cache 1, 0(t0);" 209 " cache 1, 16(t0);" 210 " cache 1, 32(t0);" 211 " cache 1, 48(t0);" 212 " cache 1, 64(t0);" 213 " cache 1, 80(t0);" 214 " cache 1, 96(t0);" 215 " cache 1, 112(t0);" 216 " bne t0, t1, 1b;" 217 " addu t0, t0, 128;" 218 ); 219 220 __asm( 221 " lw t0, 0(a0);" /* entry addr */ 222 " lw a1, 24(a0);" /* arg1 */ 223 " lw a2, 28(a0);" /* arg2 */ 224 " lw a3, 32(a0);" /* arg3 */ 225 " lw a0, 20(a0);" /* arg0 */ 226 " jr t0;" 227 " nop;" 228 229 " .globl vr41xx_asm_code_end;" 230 "vr41xx_asm_code_end: nop;" 231 " .set reorder; " 232 ); 233 } 234