2010-08-05 23:19:58 +03:00
|
|
|
// Iris: micro-kernel for a capability-based operating system.
|
|
|
|
// mips/start.S: kernel starter at high address.
|
|
|
|
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2010-08-22 23:03:06 +03:00
|
|
|
// This program is a wrapper around the kernel.
|
2013-05-12 16:46:11 +03:00
|
|
|
// It is position-independant and may be loaded anywhere.
|
2010-08-22 23:03:06 +03:00
|
|
|
// It does not use gp. This means that li and la must not be used.
|
2010-08-05 23:19:58 +03:00
|
|
|
.globl __start
|
|
|
|
.set noreorder
|
|
|
|
|
|
|
|
__start:
|
2010-08-22 23:03:06 +03:00
|
|
|
// Set t0 to uart0 txd
|
|
|
|
lui $t0, 0xb003
|
|
|
|
|
2010-08-05 23:19:58 +03:00
|
|
|
bal 1f
|
|
|
|
// For some reason the disassembler considers everything
|
|
|
|
// after __start non-code until the next label. So I add a label.
|
|
|
|
start_hack_for_disassembler:
|
2010-08-22 23:03:06 +03:00
|
|
|
lui $a0, 0x8000
|
|
|
|
base:
|
|
|
|
.word image_end - image
|
|
|
|
1:
|
|
|
|
// Set kseg0 to uncachable.
|
|
|
|
ori $t0, $zero, 2
|
|
|
|
mtc0 $t0, $16, 0
|
2010-08-05 23:19:58 +03:00
|
|
|
|
2010-08-22 23:03:06 +03:00
|
|
|
// Flush cache.
|
|
|
|
lui $v1, 0x8000
|
|
|
|
ori $v0, $v1, 0x8000
|
|
|
|
1:
|
|
|
|
// i-cache index invalidate.
|
|
|
|
cache 0, 0($v1)
|
|
|
|
// d-cache index write-back invalidate.
|
|
|
|
cache 1, 0($v1)
|
|
|
|
bne $v1, $v0, 1b
|
|
|
|
addiu $v1, $v1, 32
|
2010-08-05 23:19:58 +03:00
|
|
|
|
2010-08-22 23:03:06 +03:00
|
|
|
// Set a1 to start address of image.
|
|
|
|
addiu $a1, $ra, image - base
|
2010-08-05 23:19:58 +03:00
|
|
|
|
2010-08-22 23:03:06 +03:00
|
|
|
// Set a2 to end address of image.
|
|
|
|
lw $a2, 0($ra)
|
|
|
|
add $a2, $a2, $a1
|
|
|
|
|
|
|
|
// Set t9 to the entry point.
|
|
|
|
lui $t9, START >> 16
|
|
|
|
ori $t9, $t9, START & 0xffff
|
|
|
|
|
|
|
|
// Put the copying code at the end, to prevent overwriting itself.
|
|
|
|
// The copy goes to the start of RAM, so the target is never larger than the source.
|
|
|
|
jr $a2
|
2010-08-05 23:19:58 +03:00
|
|
|
nop
|
|
|
|
|
|
|
|
image:
|
|
|
|
.incbin "iris.raw"
|
|
|
|
image_end:
|
2010-08-22 23:03:06 +03:00
|
|
|
// Copy the image to the start of RAM.
|
|
|
|
// a0 is the destination: 0x80000000, counting up.
|
|
|
|
// a1 is the start of the image, counting up.
|
|
|
|
// a2 is the end of the image, not changing.
|
|
|
|
// a3 is the working register to do the move.
|
|
|
|
1: lw $a3, 0($a1)
|
|
|
|
addiu $a1, $a1, 4
|
|
|
|
sw $a3, 0($a0)
|
|
|
|
bne $a1, $a2, 1b
|
|
|
|
addiu $a0, $a0, 4
|
|
|
|
// Done copying.
|
|
|
|
|
|
|
|
// Make the jump to the new code.
|
|
|
|
jr $t9
|
|
|
|
nop
|