start.S revision 1.3 1 1.3 matt /* $NetBSD: start.S,v 1.3 2014/02/06 19:20:11 matt Exp $ */
2 1.1 pooka
3 1.1 pooka /*-
4 1.1 pooka * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1 pooka * All rights reserved.
6 1.1 pooka *
7 1.1 pooka * This code was written by Alessandro Forin and Neil Pittman
8 1.1 pooka * at Microsoft Research and contributed to The NetBSD Foundation
9 1.1 pooka * by Microsoft Corporation.
10 1.1 pooka *
11 1.1 pooka * Redistribution and use in source and binary forms, with or without
12 1.1 pooka * modification, are permitted provided that the following conditions
13 1.1 pooka * are met:
14 1.1 pooka * 1. Redistributions of source code must retain the above copyright
15 1.1 pooka * notice, this list of conditions and the following disclaimer.
16 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 pooka * notice, this list of conditions and the following disclaimer in the
18 1.1 pooka * documentation and/or other materials provided with the distribution.
19 1.1 pooka *
20 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 1.1 pooka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.1 pooka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.1 pooka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.1 pooka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.1 pooka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.1 pooka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.1 pooka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.1 pooka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.1 pooka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.1 pooka * POSSIBILITY OF SUCH DAMAGE.
31 1.1 pooka */
32 1.1 pooka
33 1.1 pooka /* Trivial support for printing stuff on the serial line from C pgms.
34 1.1 pooka */
35 1.1 pooka #include <mips/asm.h>
36 1.1 pooka #include <mips/cpuregs.h>
37 1.1 pooka #define __ASSEMBLER__ 1
38 1.1 pooka #include <machine/emipsreg.h>
39 1.1 pooka
40 1.1 pooka /* Offsets in the CXTINFO structure
41 1.1 pooka */
42 1.1 pooka #define TS_AT (1 * 4)
43 1.1 pooka #define TS_V0 (2 * 4)
44 1.1 pooka #define TS_V1 (3 * 4)
45 1.1 pooka #define TS_A0 (4 * 4)
46 1.1 pooka #define TS_A1 (5 * 4)
47 1.1 pooka #define TS_A2 (6 * 4)
48 1.1 pooka #define TS_A3 (7 * 4)
49 1.1 pooka #define TS_T0 (8 * 4)
50 1.1 pooka #define TS_T1 (9 * 4)
51 1.1 pooka #define TS_T2 (10 * 4)
52 1.1 pooka #define TS_T3 (11 * 4)
53 1.1 pooka #define TS_T4 (12 * 4)
54 1.1 pooka #define TS_T5 (13 * 4)
55 1.1 pooka #define TS_T6 (14 * 4)
56 1.1 pooka #define TS_T7 (15 * 4)
57 1.1 pooka #define TS_S0 (16 * 4)
58 1.1 pooka #define TS_S1 (17 * 4)
59 1.1 pooka #define TS_S2 (18 * 4)
60 1.1 pooka #define TS_S3 (19 * 4)
61 1.1 pooka #define TS_S4 (20 * 4)
62 1.1 pooka #define TS_S5 (21 * 4)
63 1.1 pooka #define TS_S6 (22 * 4)
64 1.1 pooka #define TS_S7 (23 * 4)
65 1.1 pooka #define TS_T8 (24 * 4)
66 1.1 pooka #define TS_T9 (25 * 4)
67 1.1 pooka #define TS_K0 (26 * 4)
68 1.1 pooka #define TS_K1 (27 * 4)
69 1.1 pooka #define TS_GP (28 * 4)
70 1.1 pooka #define TS_SP (29 * 4)
71 1.1 pooka #define TS_FP (30 * 4)
72 1.1 pooka #define fp s8
73 1.1 pooka #define TS_RA (31 * 4)
74 1.1 pooka
75 1.1 pooka #define TS_PC (32 * 4)
76 1.1 pooka #define TS_SR (33 * 4)
77 1.1 pooka #define TS_HI (34 * 4)
78 1.1 pooka #define TS_LO (35 * 4)
79 1.1 pooka #define TS_EC (36 * 4)
80 1.1 pooka #define SIZEOF_CXTINFO (37*4)
81 1.1 pooka
82 1.1 pooka /* PROM_MODE means the user plans to keep this code around while running an OS.
83 1.1 pooka * So we act kind of like PROM code (BIOS?), but we live in RAM.
84 1.1 pooka * So we need to safeguard ourselves against corruptions, some unavoidable.
85 1.1 pooka * Like the overriding of the exception vectors, rigth where our "start" code is.
86 1.1 pooka */
87 1.1 pooka
88 1.1 pooka IMPORT(main,4)
89 1.1 pooka IMPORT(_end,4)
90 1.1 pooka
91 1.1 pooka .set noreorder
92 1.1 pooka
93 1.1 pooka EXPORT(start)
94 1.1 pooka bgezal zero,_C_LABEL(real_start)
95 1.1 pooka nop
96 1.1 pooka
97 1.1 pooka
98 1.1 pooka /* Does not handle the exception, really.
99 1.1 pooka * But to test interrupts should be enough
100 1.1 pooka */
101 1.1 pooka .org 0x00000080
102 1.2 pooka NESTED_NOPROFILE(ExceptionHandler,SIZEOF_CXTINFO,$31)
103 1.1 pooka la k1, UserInterruptHandler
104 1.1 pooka lw k1,0(k1)
105 1.1 pooka bne k1,zero,Dispatch
106 1.1 pooka mfc0 k0, MIPS_COP_0_EXC_PC
107 1.1 pooka j k0
108 1.1 pooka nop /* do not! pop status */
109 1.1 pooka
110 1.1 pooka EXPORT(UserInterruptHandler)
111 1.1 pooka .word 0
112 1.1 pooka
113 1.1 pooka EXPORT(Dispatch)
114 1.1 pooka /* Save state on stack */
115 1.1 pooka addiu sp, sp, -SIZEOF_CXTINFO
116 1.1 pooka /* save registers */
117 1.1 pooka .set noat
118 1.1 pooka sw AT, TS_AT(sp)
119 1.1 pooka .set at
120 1.1 pooka sw v0, TS_V0(sp)
121 1.1 pooka sw v1, TS_V1(sp)
122 1.1 pooka sw a0, TS_A0(sp)
123 1.1 pooka sw a1, TS_A1(sp)
124 1.1 pooka sw a2, TS_A2(sp)
125 1.1 pooka sw a3, TS_A3(sp)
126 1.1 pooka sw t0, TS_T0(sp)
127 1.1 pooka sw t1, TS_T1(sp)
128 1.1 pooka sw t2, TS_T2(sp)
129 1.1 pooka sw t3, TS_T3(sp)
130 1.1 pooka sw t4, TS_T4(sp)
131 1.1 pooka sw t5, TS_T5(sp)
132 1.1 pooka sw t6, TS_T6(sp)
133 1.1 pooka sw t7, TS_T7(sp)
134 1.1 pooka sw s0, TS_S0(sp)
135 1.1 pooka sw s1, TS_S1(sp)
136 1.1 pooka sw s2, TS_S2(sp)
137 1.1 pooka sw s3, TS_S3(sp)
138 1.1 pooka sw s4, TS_S4(sp)
139 1.1 pooka sw s5, TS_S5(sp)
140 1.1 pooka sw s6, TS_S6(sp)
141 1.1 pooka sw s7, TS_S7(sp)
142 1.1 pooka sw t8, TS_T8(sp)
143 1.1 pooka sw t9, TS_T9(sp)
144 1.1 pooka sw k0, TS_K0(sp)
145 1.1 pooka sw k1, TS_K1(sp)
146 1.1 pooka sw gp, TS_GP(sp)
147 1.1 pooka /* sp: later */
148 1.1 pooka sw fp, TS_FP(sp)
149 1.1 pooka sw ra, TS_RA(sp)
150 1.1 pooka
151 1.1 pooka mfc0 a0, MIPS_COP_0_STATUS
152 1.1 pooka mflo t0
153 1.1 pooka mfhi t1
154 1.1 pooka sw a0, TS_SR(sp)
155 1.1 pooka sw t0, TS_LO(sp)
156 1.1 pooka sw t1, TS_HI(sp)
157 1.1 pooka sw k0, TS_PC(sp)
158 1.1 pooka
159 1.1 pooka /* Save original stack */
160 1.1 pooka move a0,sp
161 1.1 pooka addiu t0, sp, SIZEOF_CXTINFO
162 1.1 pooka jalr k1
163 1.1 pooka sw t0, TS_SP(sp)
164 1.1 pooka
165 1.1 pooka /* Returned value is new PCXINFO */
166 1.1 pooka move a0,v0
167 1.1 pooka
168 1.1 pooka /* First load most registers */
169 1.1 pooka .set noat
170 1.1 pooka lw AT, TS_AT(a0)
171 1.1 pooka lw v0, TS_V0(a0)
172 1.1 pooka lw v1, TS_V1(a0)
173 1.1 pooka /* a0 later */
174 1.1 pooka lw a1, TS_A1(a0)
175 1.1 pooka lw a2, TS_A2(a0)
176 1.1 pooka lw a3, TS_A3(a0)
177 1.1 pooka lw t0, TS_T0(a0)
178 1.1 pooka lw t1, TS_T1(a0)
179 1.1 pooka lw t2, TS_T2(a0)
180 1.1 pooka lw t3, TS_T3(a0)
181 1.1 pooka lw t4, TS_T4(a0)
182 1.1 pooka lw t5, TS_T5(a0)
183 1.1 pooka lw t6, TS_T6(a0)
184 1.1 pooka lw t7, TS_T7(a0)
185 1.1 pooka lw s0, TS_S0(a0)
186 1.1 pooka lw s1, TS_S1(a0)
187 1.1 pooka lw s2, TS_S2(a0)
188 1.1 pooka lw s3, TS_S3(a0)
189 1.1 pooka lw s4, TS_S4(a0)
190 1.1 pooka lw s5, TS_S5(a0)
191 1.1 pooka lw s6, TS_S6(a0)
192 1.1 pooka lw s7, TS_S7(a0)
193 1.1 pooka lw t8, TS_T8(a0)
194 1.1 pooka lw t9, TS_T9(a0)
195 1.1 pooka /* k0,k1 not restored */
196 1.1 pooka lw gp, TS_GP(a0)
197 1.1 pooka /* sp later */
198 1.1 pooka lw fp, TS_FP(a0)
199 1.1 pooka lw ra, TS_RA(a0)
200 1.1 pooka
201 1.1 pooka lw k1, TS_HI(a0)
202 1.1 pooka lw k0, TS_LO(a0)
203 1.1 pooka mthi k1
204 1.1 pooka mtlo k0
205 1.1 pooka lw k1, TS_SR(a0)
206 1.1 pooka mtc0 k1, MIPS_COP_0_STATUS
207 1.1 pooka /* NB: After this instruction we cannot take any interrupts or traps
208 1.1 pooka */
209 1.1 pooka lw sp, TS_SP(a0)
210 1.1 pooka
211 1.1 pooka /* Put pc into k0 */
212 1.1 pooka lw k0, TS_PC(a0)
213 1.1 pooka lw a0, TS_A0(a0)
214 1.1 pooka j k0
215 1.1 pooka rfe
216 1.1 pooka .set at
217 1.1 pooka
218 1.2 pooka END(ExceptionHandler)
219 1.1 pooka
220 1.1 pooka .org 0x00000200
221 1.1 pooka EXPORT(real_start)
222 1.1 pooka .ent _C_LABEL(real_start)
223 1.1 pooka
224 1.1 pooka #ifdef SECONDARY_BOOTBLOCK
225 1.1 pooka /*
226 1.1 pooka * If this is the program that goes into FLASH we must copy ourselves down to RAM.
227 1.1 pooka * FLASH default on the MLx is at 0xf0000000, DRAM at 0.
228 1.1 pooka */
229 1.1 pooka addi a0,ra,-8 /* Compensate for the first two instructions */
230 1.1 pooka
231 1.1 pooka /* Get the address(relative) of TextStart
232 1.1 pooka */
233 1.1 pooka bgezal zero, _C_LABEL(MipsStart2) /* Always jumps */
234 1.1 pooka nop
235 1.1 pooka
236 1.1 pooka /* All of the static data, since we are at it.
237 1.1 pooka */
238 1.1 pooka TextStart: /* + 0 */
239 1.1 pooka /* Text start at final link address */
240 1.1 pooka .int start
241 1.1 pooka
242 1.1 pooka DataEnd: /* + 4 */
243 1.1 pooka /* Data end == bss start */
244 1.1 pooka .int _edata
245 1.1 pooka
246 1.1 pooka BssEnd: /* + 8 */
247 1.1 pooka /* Bss end */
248 1.1 pooka .int _end
249 1.1 pooka
250 1.1 pooka RelocToRAM: /* *+12 */
251 1.1 pooka .int InRAM
252 1.1 pooka
253 1.1 pooka MipsStart2:
254 1.1 pooka
255 1.1 pooka /* Source = a0, Dst = t2 */
256 1.1 pooka lw t2, 0(ra) /* _C_LABEL(TextStart) */
257 1.1 pooka
258 1.1 pooka /* EndPtr = t3 */
259 1.1 pooka /* in bdelay slot */
260 1.1 pooka
261 1.1 pooka /* If a0 != t2 then we are running in Flash but should run in RAM
262 1.1 pooka * In that case copy .text. Otherwise skip to .bss.
263 1.1 pooka */
264 1.1 pooka beq a0,t2,ZroLoop-4
265 1.1 pooka lw t3, 4(ra) /* _C_LABEL(DataEnd) */
266 1.1 pooka
267 1.1 pooka CpyLoop:
268 1.1 pooka /* loop copying 2 words at a time */
269 1.1 pooka lw t4,0(a0)
270 1.1 pooka lw t5,4(a0)
271 1.1 pooka addiu a0,a0,8
272 1.1 pooka sw t4,0(t2)
273 1.1 pooka addiu t2,t2,8
274 1.1 pooka sltu t1,t2,t3
275 1.1 pooka bne t1,zero,CpyLoop
276 1.1 pooka sw t5,-4(t2)
277 1.1 pooka
278 1.1 pooka /* zero the bss
279 1.1 pooka */
280 1.1 pooka lw t4, 8(ra) /* _C_LABEL(BssEnd) */
281 1.1 pooka ZroLoop:
282 1.1 pooka sltu t1,t3,t4
283 1.1 pooka sw zero,0(t3)
284 1.1 pooka bne t1,zero,ZroLoop
285 1.1 pooka addiu t3,t3,4
286 1.1 pooka
287 1.1 pooka /* Jump to RAM copy (below)
288 1.1 pooka */
289 1.1 pooka lw t1, 12(ra) /* _C_LABEL(RelocToRAM) */
290 1.1 pooka jr t1
291 1.1 pooka nop
292 1.1 pooka
293 1.1 pooka /*
294 1.1 pooka * Execute from here after copying out of FLASH into RAM
295 1.1 pooka */
296 1.1 pooka InRAM:
297 1.1 pooka
298 1.1 pooka #endif /* SECONDARY_BOOTBLOCK */
299 1.1 pooka
300 1.1 pooka /* Get a stack
301 1.1 pooka */
302 1.1 pooka #ifdef __GP_SUPPORT__
303 1.1 pooka la gp, _C_LABEL (_gp)
304 1.1 pooka #endif
305 1.1 pooka la sp,_end
306 1.1 pooka addiu sp,sp,(8*1024) /* BUGBUG arbitrary */
307 1.1 pooka
308 1.1 pooka /* Jump to main
309 1.1 pooka */
310 1.1 pooka jal main
311 1.1 pooka add a0,sp,zero
312 1.1 pooka
313 1.1 pooka /* Load failed, reset the processor and jump back to the origins.
314 1.1 pooka */
315 1.1 pooka EXPORT(_rtt) /* ahem */
316 1.1 pooka li t0,0x1260ff80 /* NB: On new builds this is a SYS-RESET as well */
317 1.1 pooka mtc0 t0,MIPS_COP_0_STATUS
318 1.1 pooka
319 1.1 pooka lui t0,(BRAM_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
320 1.1 pooka jr t0
321 1.1 pooka nop
322 1.1 pooka
323 1.1 pooka EXPORT(Stop)
324 1.1 pooka b Stop
325 1.1 pooka nop
326 1.1 pooka
327 1.1 pooka END(real_start)
328 1.1 pooka
329 1.1 pooka .set noreorder
330 1.1 pooka .set noat
331 1.1 pooka .set nomacro
332 1.1 pooka
333 1.1 pooka /* void Delay(UINT32 count)
334 1.1 pooka */
335 1.1 pooka LEAF(Delay)
336 1.1 pooka bne a0,zero,_C_LABEL(Delay)
337 1.1 pooka subu a0,1
338 1.1 pooka j ra
339 1.1 pooka nop
340 1.1 pooka END(Delay)
341 1.1 pooka
342 1.1 pooka /* UINT32 GetPsr(void)
343 1.1 pooka * Returns the PSR (coprocessor 0 status)
344 1.1 pooka */
345 1.1 pooka LEAF(GetPsr)
346 1.1 pooka mfc0 v0, MIPS_COP_0_STATUS
347 1.1 pooka j ra
348 1.1 pooka nop
349 1.1 pooka END(GetPsr)
350 1.1 pooka
351 1.1 pooka /* void SetPsr(UINT32 Psr)
352 1.1 pooka * Sets the PSR (coprocessor 0 status)
353 1.1 pooka */
354 1.1 pooka LEAF(SetPsr)
355 1.1 pooka mtc0 a0,MIPS_COP_0_STATUS
356 1.1 pooka j ra
357 1.1 pooka nop
358 1.1 pooka END(SetPsr)
359 1.1 pooka
360 1.1 pooka /* UINT32 GetCause(void)
361 1.1 pooka * Returns the Cause register (coprocessor 0)
362 1.1 pooka */
363 1.1 pooka LEAF(GetCause)
364 1.1 pooka mfc0 v0,MIPS_COP_0_CAUSE
365 1.1 pooka j ra
366 1.1 pooka nop
367 1.1 pooka END(GetCause)
368 1.1 pooka
369 1.1 pooka /* UINT32 GetEpc(void)
370 1.1 pooka * Returns the Epc register (coprocessor 0)
371 1.1 pooka */
372 1.1 pooka LEAF(GetEpc)
373 1.1 pooka mfc0 v0,MIPS_COP_0_EXC_PC
374 1.1 pooka j ra
375 1.1 pooka nop
376 1.1 pooka END(GetEpc)
377 1.1 pooka
378 1.1 pooka
379 1.1 pooka /* int PutWord(UINT32 Word);
380 1.1 pooka * Returns: 0 if ok, -1 otherwise
381 1.1 pooka */
382 1.1 pooka NESTED(PutWord,12,$31)
383 1.1 pooka subu sp,sp,12
384 1.1 pooka sw s0,8(sp)
385 1.1 pooka sw s1,4(sp)
386 1.1 pooka sw ra,0(sp)
387 1.1 pooka
388 1.1 pooka or s1,a0,zero
389 1.1 pooka /* Spit all nibbles
390 1.1 pooka */
391 1.1 pooka li s0,8
392 1.1 pooka PutWordLoop:
393 1.1 pooka srl a0,s1,32-4
394 1.1 pooka li t0,10
395 1.1 pooka sltu t1,a0,t0
396 1.1 pooka bnez t1,$Digit
397 1.1 pooka li a1,'0'
398 1.1 pooka subu a0,a0,t0
399 1.1 pooka li a1,'a'
400 1.1 pooka $Digit:
401 1.1 pooka sll s1,s1,4
402 1.1 pooka jal PutChar
403 1.1 pooka add a0,a0,a1
404 1.1 pooka
405 1.1 pooka subu s0,s0,1
406 1.1 pooka bne v0,zero,PutWordDone /* printed ok? */
407 1.1 pooka li v0,-1
408 1.1 pooka
409 1.1 pooka /* done yet? */
410 1.1 pooka bne s0,zero,PutWordLoop
411 1.1 pooka nop
412 1.1 pooka
413 1.1 pooka /* done
414 1.1 pooka */
415 1.1 pooka li v0,0
416 1.1 pooka PutWordDone:
417 1.1 pooka lw ra,0(sp)
418 1.1 pooka lw s1,4(sp)
419 1.1 pooka lw s0,8(sp)
420 1.1 pooka jr ra
421 1.1 pooka addiu sp,sp,12
422 1.1 pooka
423 1.1 pooka END(PutWord)
424 1.1 pooka
425 1.1 pooka /* int Puts(char *String);
426 1.1 pooka * Returns: 0 if ok, -1 otherwise
427 1.1 pooka */
428 1.1 pooka NESTED(Puts,8,$31)
429 1.1 pooka subu sp,sp,8
430 1.1 pooka sw s0,4(sp)
431 1.1 pooka sw ra,0(sp)
432 1.1 pooka
433 1.1 pooka or s0,a0,zero
434 1.1 pooka /* Spit all chars until zero
435 1.1 pooka */
436 1.1 pooka PutsLoop:
437 1.1 pooka lbu a0,0(s0)
438 1.1 pooka addiu s0,s0,1
439 1.1 pooka beq a0,zero,PutsDoneOk
440 1.1 pooka nop
441 1.1 pooka jal PutChar
442 1.1 pooka nop
443 1.1 pooka beq v0,zero,PutsLoop
444 1.1 pooka nop
445 1.1 pooka
446 1.1 pooka /* Timed out
447 1.1 pooka */
448 1.1 pooka b PutsDone
449 1.1 pooka li v0,-1
450 1.1 pooka
451 1.1 pooka /* done
452 1.1 pooka */
453 1.1 pooka PutsDoneOk:
454 1.1 pooka li v0,0
455 1.1 pooka PutsDone:
456 1.1 pooka lw ra,0(sp)
457 1.1 pooka lw s0,4(sp)
458 1.1 pooka jr ra
459 1.1 pooka addiu sp,sp,8
460 1.1 pooka
461 1.1 pooka END(Puts)
462 1.1 pooka
463 1.1 pooka
464 1.1 pooka /* int GetChar(void);
465 1.1 pooka * Returns: a non-negative value if ok, -1 otherwise
466 1.1 pooka */
467 1.1 pooka LEAF(GetChar)
468 1.1 pooka lui t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
469 1.1 pooka lui t1,1000 /* n*65k spins max */
470 1.1 pooka RxNotReady:
471 1.1 pooka lw t4,USARTST(t0) /* ChannelStatus */
472 1.1 pooka andi t4,t4,USI_RXRDY
473 1.1 pooka bgtz t4,$GotByte
474 1.1 pooka subu t1,t1,1
475 1.1 pooka /* still ok to spin? */
476 1.1 pooka bgtz t1,RxNotReady
477 1.1 pooka nop
478 1.1 pooka /* Timed out
479 1.1 pooka */
480 1.1 pooka jr ra
481 1.1 pooka li v0,-1
482 1.1 pooka
483 1.1 pooka /* Gottabyte
484 1.1 pooka */
485 1.1 pooka $GotByte:
486 1.1 pooka lw v0,USARTRX(t0) /* RxData */
487 1.1 pooka jr ra
488 1.1 pooka andi v0,0xff
489 1.1 pooka END(GetChar)
490 1.1 pooka
491 1.1 pooka /* int PutChar(UINT8 v);
492 1.1 pooka * Returns: 0 if ok, -1 otherwise
493 1.1 pooka */
494 1.1 pooka LEAF(PutChar)
495 1.1 pooka lui t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
496 1.1 pooka lui t1,1000 /* n*65k spins max */
497 1.1 pooka li v0,0
498 1.1 pooka TxNotReady:
499 1.1 pooka lw t4,USARTST(t0) /* ChannelStatus */
500 1.1 pooka andi t4,t4,USI_TXRDY
501 1.1 pooka bgtz t4,TxReady
502 1.1 pooka subu t1,t1,1
503 1.1 pooka /* still ok to spin? */
504 1.1 pooka bgtz t1,TxNotReady
505 1.1 pooka nop
506 1.1 pooka /* Timed out
507 1.1 pooka */
508 1.1 pooka jr ra
509 1.1 pooka li v0,-1
510 1.1 pooka
511 1.1 pooka /* Send it
512 1.1 pooka */
513 1.1 pooka TxReady:
514 1.1 pooka jr ra
515 1.1 pooka sw a0,USARTTX(t0)
516 1.1 pooka
517 1.1 pooka END(PutChar)
518 1.1 pooka
519 1.1 pooka /* Second arg is a function to call with the first arg:
520 1.1 pooka * void switch_stack_and_call(void *arg, void (*function)(void *));
521 1.1 pooka */
522 1.1 pooka LEAF(switch_stack_and_call)
523 1.1 pooka /* Get a stack and jump. It would be a very bad idea to return but..
524 1.1 pooka */
525 1.3 matt lui sp,%hi(_end)
526 1.3 matt addiu sp,%lo(_end)
527 1.1 pooka jr a1
528 1.1 pooka addiu sp,sp,(2*1024) /* BUGBUG arbitrary */
529 1.1 pooka
530 1.1 pooka END(switch_stack_and_call)
531 1.1 pooka
532