gitlab: Extract default build/test jobs templates
[qemu/ar7.git] / tests / tcg / alpha / system / boot.S
blob9791b1ef7c8fa5dea15f00ed723fd0fe7bba629f
1 /*
2  * Minimal Alpha system boot code.
3  *
4  * Copyright Linaro Ltd 2019
5  */
7         .set    noat
8         .set    nomacro
9         .arch   ev6
10         .text
12 .macro load_pci_io reg
13         /* For typhoon, this is
14          *   0xfffffc0000000000  -- kseg identity map
15          * +      0x10000000000  -- typhoon pio base
16          * +        0x1fc000000  -- typhoon pchip0 pci base
17          * = 0xfffffd01fc000000
18          */
19         ldah    \reg, -3                /* ff..fd0000 */
20         lda     \reg, 0x1fc(\reg)       /* ff..fd01fc */
21         sll     \reg, 24, \reg
22 .endm
24 #define com1Rbr 0x3f8
25 #define com1Thr 0x3f8
26 #define com1Ier 0x3f9
27 #define com1Iir 0x3fa
28 #define com1Lcr 0x3fb
29 #define com1Mcr 0x3fc
30 #define com1Lsr 0x3fd
31 #define com1Msr 0x3fe
32 #define com1Scr 0x3ff
33 #define com1Dll 0x3f8
34 #define com1Dlm 0x3f9
36 #define PAL_halt    0
37 #define PAL_wrent  52
38 #define PAL_wrkgp  55
40         .text
41         .p2align 4
42         .globl  _start
43         .ent    _start
44 _start:
45         br      $gp, .+4
46         ldah    $gp, 0($gp)             !gpdisp!1
47         lda     $gp, 0($gp)             !gpdisp!1
49         ldah    $sp, $stack_end($gp)    !gprelhigh
50         lda     $sp, $stack_end($sp)    !gprellow
52         /* Install kernel gp for exception handlers.  */
53         mov     $gp, $16
54         call_pal PAL_wrkgp
56         /* Install exception handlers.  */
57         ldah    $16, entInt($gp)        !gprelhigh
58         lda     $16, entInt($16)        !gprellow
59         lda     $17, 0
60         call_pal PAL_wrent
62         ldah    $16, entArith($gp)      !gprelhigh
63         lda     $16, entArith($16)      !gprellow
64         lda     $17, 1
65         call_pal PAL_wrent
67         ldah    $16, entMM($gp)         !gprelhigh
68         lda     $16, entMM($16)         !gprellow
69         lda     $17, 2
70         call_pal PAL_wrent
72         ldah    $16, entIF($gp)         !gprelhigh
73         lda     $16, entIF($16)         !gprellow
74         lda     $17, 3
75         call_pal PAL_wrent
77         ldah    $16, entUna($gp)        !gprelhigh
78         lda     $16, entUna($16)        !gprellow
79         lda     $17, 4
80         call_pal PAL_wrent
82         ldah    $16, entSys($gp)        !gprelhigh
83         lda     $16, entSys($16)        !gprellow
84         lda     $17, 5
85         call_pal PAL_wrent
87         /*
88          * Initialize COM1.
89          */
90         load_pci_io $1
91         lda     $2, 0x87                /* outb(0x87, com1Lcr); */
92         stb     $2, com1Lcr($1)
93         stb     $31, com1Dlm($1)        /* outb(0, com1Dlm); */
94         lda     $2, 3                   /* baudconst 3 => 56000 */
95         stb     $2, com1Dll($1)         /* outb(baudconst, com1Dll); */
96         lda     $2, 0x07
97         stb     $2, com1Lcr($1)         /* outb(0x07, com1Lcr) */
98         lda     $2, 0x0f
99         stb     $2, com1Mcr($1)         /* outb(0x0f, com1Mcr) */
101         bsr     $26, main               !samegp
103         /* fall through to _exit */
104         .end    _start
106         .globl  _exit
107         .ent    _exit
108 _exit:
109         .frame  $sp, 0, $26, 0
110         .prologue 0
112         /* We cannot return an error code.  */
113         call_pal PAL_halt
114         .end    _exit
117  * We have received an exception that we don't handle.  Log and exit.
118  */
119         .ent    log_exit
120 log_exit:
121 entInt:
122 entArith:
123 entMM:
124 entIF:
125 entUna:
126 entSys:
127         ldah    $16, $errormsg($gp)     !gprelhigh
128         lda     $16, $errormsg($16)     !gprellow
129         bsr     $26, __sys_outs         !samegp
130         bsr     $26, _exit              !samegp
131         .end    log_exit
133         .section .rodata
134 $errormsg:
135         .string "Terminated by exception.\n"
136         .previous
138         /*
139          * Helper Functions
140          */
142         /* Output a single character to serial port */
143         .global __sys_outc
144         .ent    __sys_outc
145 __sys_outc:
146         .frame  $sp, 0, $26, 0
147         .prologue 0
149         load_pci_io $1
151         /* 
152          * while ((inb(com1Lsr) & 0x20) == 0)
153          *       continue;
154          */
155 1:      ldbu    $0, com1Lsr($1)
156         and     $0, 0x20, $0
157         beq     $0, 1b
159         /* outb(c, com1Thr); */
160         stb     $16, com1Thr($1)
161         ret
162         .end    __sys_outc
164         /* Output a nul-terminated string to serial port */
165         .global __sys_outs
166         .ent    __sys_outs
167 __sys_outs:
168         .frame  $sp, 0, $26, 0
169         .prologue 0
171         load_pci_io $1
173         ldbu    $2, 0($16)
174         beq     $2, 9f
176         /* 
177          * while ((inb(com1Lsr) & 0x20) == 0)
178          *       continue;
179          */
180 1:      ldbu    $0, com1Lsr($1)
181         and     $0, 0x20, $0
182         beq     $0, 1b
184         /* outb(c, com1Thr); */
185         stb     $2, com1Thr($1)
187         addq    $16, 1, $16
188         ldbu    $2, 0($16)
189         bne     $2, 1b
191 9:      ret
192         .end    __sys_outs
195  * Division routines that are normally in libc.
197  * These do not follow the C calling convention.  Arguments are in $24+$25,
198  * the result is in $27.  Register $28 may be clobbered; everything else
199  * must be saved.
201  * We store the remainder in $28, so that we can share code.
203  * We do not signal divide by zero.
204  */
207  * Unsigned 64-bit division.
208  */
210         .globl  __divqu
211         .ent    __divqu
212 __divqu:
213         .frame  $sp, 48, $23
214         subq    $sp, 48, $sp
215         stq     $0, 0($sp)
216         stq     $1, 8($sp)
217         stq     $2, 16($sp)
218         stq     $3, 24($sp)
219         stq     $4, 32($sp)
220         .prologue 0
222 #define mask     $0
223 #define divisor  $1
224 #define compare  $2
225 #define tmp1     $3
226 #define tmp2     $4
227 #define quotient $27
228 #define modulus  $28
230         mov     $24, modulus
231         mov     $25, divisor
232         mov     $31, quotient
233         mov     1, mask
234         beq     $25, 9f
236         /* Shift left until divisor >= modulus.  */
237 1:      cmpult  divisor, modulus, compare
238         blt     divisor, 2f
239         addq    divisor, divisor, divisor
240         addq    mask, mask, mask
241         bne     compare, 1b
243 2:      addq    quotient, mask, tmp2
244         srl     mask, 1, mask
245         cmpule  divisor, modulus, compare
246         subq    modulus, divisor, tmp1
247         cmovne  compare, tmp2, quotient
248         srl     divisor, 1, divisor
249         cmovne  compare, tmp1, modulus
250         bne     mask, 2b
252 9:      ldq     $0, 0($sp)
253         ldq     $1, 8($sp)
254         ldq     $2, 16($sp)
255         ldq     $3, 24($sp)
256         ldq     $4, 32($sp)
257         addq    $sp, 48, $sp
258         ret     $31, ($23), 1
260 #undef mask
261 #undef divisor
262 #undef compare
263 #undef tmp1
264 #undef tmp2
265 #undef quotient
266 #undef modulus
268         .end    __divqu
271  * Unsigned 64-bit remainder.
272  * Note that __divqu above leaves the result in $28.
273  */
275         .globl  __remqu
276         .ent    __remqu
277 __remqu:
278         .frame  $sp, 16, $23
279         subq    $sp, 16, $sp
280         stq     $23, 0($sp)
281         .prologue 0
283         bsr     $23, __divqu
285         ldq     $23, 0($sp)
286         mov     $28, $27
287         addq    $sp, 16, $sp
288         ret     $31, ($23), 1
289         .end    __remqu
292  * Signed 64-bit division.
293  */
295         .globl  __divqs
296         .ent    __divqs
297 __divqs:
298         .prologue 0
300         /* Common case: both arguments are positive.  */
301         bis     $24, $25, $28
302         bge     $28, __divqu
304         /* At least one argument is negative.  */
305         subq    $sp, 32, $sp
306         stq     $23, 0($sp)
307         stq     $24, 8($sp)
308         stq     $25, 16($sp)
310         /* Compute absolute values.  */
311         subq    $31, $24, $28
312         cmovlt  $24, $28, $24
313         subq    $31, $25, $28
314         cmovlt  $25, $28, $25
316         bsr     $23, __divqu
318         ldq     $24, 8($sp)
319         ldq     $25, 16($sp)
321         /* -a / b = a / -b = -(a / b) */
322         subq    $31, $27, $23
323         xor     $24, $25, $28
324         cmovlt  $28, $23, $27
326         ldq     $23, 0($sp)
327         addq    $sp, 32, $sp
328         ret     $31, ($23), 1
329         .end    __divqs
332  * Signed 64-bit remainder.
333  */
335         .globl  __remqs
336         .ent    __remqs
337 __remqs:
338         .prologue 0
340         /* Common case: both arguments are positive.  */
341         bis     $24, $25, $28
342         bge     $28, __remqu
344         /* At least one argument is negative.  */
345         subq    $sp, 32, $sp
346         stq     $23, 0($sp)
347         stq     $24, 8($sp)
348         stq     $25, 16($sp)
350         /* Compute absolute values.  */
351         subq    $31, $24, $28
352         cmovlt  $24, $28, $24
353         subq    $31, $25, $28
354         cmovlt  $25, $28, $25
356         bsr     $23, __divqu
358         ldq     $23, 0($sp)
359         ldq     $24, 8($sp)
360         ldq     $25, 16($sp)
362         /* -a % b = -(a % b); a % -b = a % b.  */
363         subq    $31, $28, $27
364         cmovge  $24, $28, $27
366         addq    $sp, 32, $sp
367         ret     $31, ($23), 1
368         .end    __remqs
371  * Unsigned 32-bit division.
372  */
374         .globl  __divlu
375         .ent    __divlu
376 __divlu:
377         .frame  $sp, 32, $23
378         subq    $sp, 32, $sp
379         stq     $23, 0($sp)
380         stq     $24, 8($sp)
381         stq     $25, 16($sp)
382         .prologue 0
384         /* Zero extend and use the 64-bit routine.  */
385         zap     $24, 0xf0, $24
386         zap     $25, 0xf0, $25
387         bsr     $23, __divqu
389         addl    $27, 0, $27
390         ldq     $23, 0($sp)
391         ldq     $24, 8($sp)
392         ldq     $25, 16($sp)
393         addq    $sp, 32, $sp
394         ret     $31, ($23), 1
395         .end    __divlu
398  * Unsigned 32-bit remainder.
399  */
401         .globl  __remlu
402         .ent    __remlu
403 __remlu:
404         .frame  $sp, 32, $23
405         subq    $sp, 32, $sp
406         stq     $23, 0($sp)
407         stq     $24, 8($sp)
408         stq     $25, 16($sp)
409         .prologue 0
411         /* Zero extend and use the 64-bit routine.  */
412         zap     $24, 0xf0, $24
413         zap     $25, 0xf0, $25
414         bsr     $23, __divqu
416         /* Recall that the remainder is returned in $28.  */
417         addl    $28, 0, $27
418         ldq     $23, 0($sp)
419         ldq     $24, 8($sp)
420         ldq     $25, 16($sp)
421         addq    $sp, 32, $sp
422         ret     $31, ($23), 1
423         .end    __remlu
426  * Signed 32-bit division.
427  */
429         .globl  __divls
430         .ent    __divls
431 __divls:
432         .frame  $sp, 32, $23
433         subq    $sp, 32, $sp
434         stq     $23, 0($sp)
435         stq     $24, 8($sp)
436         stq     $25, 16($sp)
437         .prologue 0
439         /* Sign extend.  */
440         addl    $24, 0, $24
441         addl    $25, 0, $25
443         /* Compute absolute values.  */
444         subq    $31, $24, $28
445         cmovlt  $24, $28, $24
446         subq    $31, $25, $28
447         cmovlt  $25, $28, $25
449         bsr     $23, __divqu
451         ldq     $24, 8($sp)
452         ldq     $25, 16($sp)
454         /* Negate the unsigned result, if necessary.  */
455         xor     $24, $25, $28
456         subl    $31, $27, $23
457         addl    $27, 0, $27
458         addl    $28, 0, $28
459         cmovlt  $28, $23, $27
461         ldq     $23, 0($sp)
462         addq    $sp, 32, $sp
463         ret     $31, ($23), 1
464         .end    __divls
467  * Signed 32-bit remainder.
468  */
470         .globl  __remls
471         .ent    __remls
472 __remls:
473         .frame  $sp, 32, $23
474         subq    $sp, 32, $sp
475         stq     $23, 0($sp)
476         stq     $24, 8($sp)
477         stq     $25, 16($sp)
478         .prologue 0
480         /* Sign extend.  */
481         addl    $24, 0, $24
482         addl    $25, 0, $25
484         /* Compute absolute values.  */
485         subq    $31, $24, $28
486         cmovlt  $24, $28, $24
487         subq    $31, $25, $28
488         cmovlt  $25, $28, $25
490         bsr     $23, __divqu
492         ldq     $23, 0($sp)
493         ldq     $24, 8($sp)
494         ldq     $25, 16($sp)
496         /* Negate the unsigned result, if necessary.  */
497         subl    $31, $28, $27
498         addl    $28, 0, $28
499         cmovge  $24, $28, $27
501         addq    $sp, 32, $sp
502         ret     $31, ($23), 1
503         .end    __remls
505         .data
506         .p2align 4
507 stack:
508         .skip   65536
509 $stack_end:
510         .type   stack,@object
511         .size   stack, . - stack