// Iris: micro-kernel for a capability-based operating system. // mips/start.S: kernel starter at high address. // Copyright 2009 Bas Wijnen // // 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 . // This program is a wrapper around the kernel. // It is position-independant and may be loaded anywhere. // It does not use gp. This means that li and la must not be used. .globl __start .set noreorder __start: // Set t0 to uart0 txd lui $t0, 0xb003 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: lui $a0, 0x8000 base: .word image_end - image 1: // Set kseg0 to uncachable. ori $t0, $zero, 2 mtc0 $t0, $16, 0 // 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 // Set a1 to start address of image. addiu $a1, $ra, image - base // 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 nop image: .incbin "iris.raw" image_end: // 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