qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

boot.S (3468B)


      1 /*
      2  * Minimal Nios2 system boot code.
      3  *
      4  * Copyright Linaro Ltd 2022
      5  * SPDX-License-Identifier: GPL-2.0-or-later
      6  */
      7 
      8 #include "semicall.h"
      9 
     10         .text
     11 	.set	noat
     12 
     13 _start:
     14 	/* Linker script defines stack at end of ram. */
     15 	movia	sp, __stack
     16 
     17 	/* Install trampoline to _fast_tlb_miss at hardcoded vector. */
     18 	movia	r4, 0xc0000100
     19 	movia	r5, _ftm_tramp
     20 	movi	r6, .L__ftm_end - _ftm_tramp
     21 	call	memcpy
     22 
     23 	/* Zero the bss to satisfy C. */
     24 	movia	r4, __bss_start
     25 	movia	r6, __bss_end
     26 	sub	r6, r6, r4
     27 	movi	r5, 0
     28 	call	memset
     29 
     30 	/* Test! */
     31 	call	main
     32 
     33 	/* Exit with main's return value. */
     34 	movi	r4, HOSTED_EXIT
     35 	mov	r5, r2
     36 	semihosting_call
     37 
     38 	.globl	_start
     39 	.type	_start, @function
     40 	.size	_start, . - _start
     41 
     42 _ftm_tramp:
     43 	movia	et, _fast_tlb_miss
     44 	jmp	et
     45 .L__ftm_end:
     46 
     47 	.type	_ftm_tramp, @function
     48 	.size	_ftm_tramp, . - _ftm_tramp
     49 
     50 #define dst	r4
     51 #define src	r5
     52 #define len	r6
     53 
     54 memcpy:
     55 	/* Store return value right away, per API */
     56 	mov	r2, dst
     57 
     58 	/* Check for both dst and src aligned. */
     59 	or	at, dst, src
     60 	andi	at, at, 3
     61 	bne	at, zero, .L_mc_test1
     62 
     63 	/* Copy blocks of 8. */
     64 
     65 	movi	at, 8
     66 	bltu	len, at, .L_mc_test4
     67 
     68 .L_mc_loop8:
     69 	ldw	r8, 0(src)
     70 	ldw	r9, 4(src)
     71 	addi	src, src, 8
     72 	addi	dst, dst, 8
     73 	subi	len, len, 8
     74 	stw	r8, -8(dst)
     75 	stw	r9, -4(dst)
     76 	bgeu	len, at, .L_mc_loop8
     77 
     78 	/* Copy final aligned block of 4. */
     79 
     80 .L_mc_test4:
     81 	movi	at, 4
     82 	bltu	len, at, .L_mc_test1
     83 
     84 	ldw	r8, 0(src)
     85 	addi	src, src, 4
     86 	addi	dst, dst, 4
     87 	subi	len, len, 4
     88 	stw	r8, -4(dst)
     89 
     90 	/* Copy single bytes to finish. */
     91 
     92 .L_mc_test1:
     93 	beq	len, zero, .L_mc_done
     94 
     95 .L_mc_loop1:
     96 	ldb	r8, 0(src)
     97 	addi	src, src, 1
     98 	addi	dst, dst, 1
     99 	subi	len, len, 1
    100 	stb	r8, -1(dst)
    101 	bne	len, zero, .L_mc_loop1
    102 
    103 .L_mc_done:
    104 	ret
    105 
    106 #undef dst
    107 #undef src
    108 #undef len
    109 
    110 	.global	memcpy
    111 	.type	memcpy, @function
    112 	.size	memcpy, . - memcpy
    113 
    114 #define dst	r4
    115 #define val	r5
    116 #define len	r6
    117 
    118 memset:
    119 	/* Store return value right away, per API */
    120 	mov	r2, dst
    121 
    122 	/* Check for small blocks; fall back to bytewise. */
    123 	movi	r3, 8
    124 	bltu	len, r3, .L_ms_test1
    125 
    126 	/* Replicate the byte across the word. */
    127 	andi	val, val, 0xff
    128 	slli	at, val, 8
    129 	or	val, val, at
    130 	slli	at, val, 16
    131 	or	val, val, at
    132 
    133 	/* Check for destination alignment; realign if needed. */
    134 	andi	at, dst, 3
    135 	bne	at, zero, .L_ms_align
    136 
    137 	/* Set blocks of 8. */
    138 
    139 .L_ms_loop8:
    140 	stw	val, 0(dst)
    141 	stw	val, 4(dst)
    142 	addi	dst, dst, 8
    143 	subi	len, len, 8
    144 	bgeu	len, r3, .L_ms_loop8
    145 
    146 	/* Set final aligned block of 4. */
    147 
    148 .L_ms_test4:
    149 	movi	at, 4
    150 	bltu	len, at, .L_ms_test1
    151 
    152 	stw	r8, 0(dst)
    153 	addi	dst, dst, 4
    154 	subi	len, len, 4
    155 	stw	r8, -4(dst)
    156 
    157 	/* Set single bytes to finish. */
    158 
    159 .L_ms_test1:
    160 	beq	len, zero, .L_ms_done
    161 
    162 .L_ms_loop1:
    163 	stb	r8, 0(dst)
    164 	addi	dst, dst, 1
    165 	subi	len, len, 1
    166 	bne	len, zero, .L_ms_loop1
    167 
    168 .L_ms_done:
    169 	ret
    170 
    171 	/* Realign for a large block, len >= 8. */
    172 .L_ms_align:
    173 	andi	at, dst, 1
    174 	beq	at, zero, 2f
    175 
    176 	stb	val, 0(dst)
    177 	addi	dst, dst, 1
    178 	subi	len, len, 1
    179 
    180 2:	andi	at, dst, 2
    181 	beq	at, zero, 4f
    182 
    183 	sth	val, 0(dst)
    184 	addi	dst, dst, 2
    185 	subi	len, len, 2
    186 
    187 4:	bgeu	len, r3, .L_ms_loop8
    188 	br	.L_ms_test4
    189 
    190 #undef dst
    191 #undef val
    192 #undef len
    193 
    194 	.global	memset
    195 	.type	memset, @function
    196 	.size	memset, . - memset
    197 
    198 /*
    199  * void __sys_outc(char c);
    200  */
    201 __sys_outc:
    202 	subi	sp, sp, 16
    203 	stb	r4, 0(sp)	/* buffer[0] = c */
    204 	movi	at, 1
    205 	stw	at, 4(sp)	/* STDOUT_FILENO */
    206 	stw	sp, 8(sp)	/* buffer */
    207 	stw	at, 12(sp)	/* len */
    208 
    209 	movi	r4, HOSTED_WRITE
    210 	addi	r5, sp, 4
    211 	semihosting_call
    212 
    213 	addi	sp, sp, 16
    214 	ret
    215 
    216 	.global	__sys_outc
    217 	.type	__sys_outc, @function
    218 	.size	__sys_outc, . - __sys_outc