xref: /netbsd/sys/arch/hpcmips/stand/pbsdboot/vr41xx.c (revision bf9ec67e)
1 /* $NetBSD: vr41xx.c,v 1.4 2000/01/16 11:14:49 uch 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 __P((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  *   caddr_t entry;	+0
91  *   caddr_t base;	+4
92  *   int pagesize;	+8
93  *   int leafsize;	+12
94  *   int nleaves;	+16
95  *   caddr_t arg0;	+20
96 
97  *   caddr_t arg1;  +24
98 
99  *   caddr_t arg2;	+28
100 
101  *   caddr_t arg3;	+32
102 
103  *   caddr_t *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