NanoPayload

stage2/handlers.S

145:c39fcc82cc15
2016-02-28 Paul Boddie Introduced kernel regions for task register storage. Removed the invoke_task function.
     1 /*     2  * Handler routines.     3  *     4  * Copyright (C) 2015 Nicholas FitzRoy-Dale <wzdd.code@lardcave.net>     5  * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>     6  *     7  * This program is free software: you can redistribute it and/or modify     8  * it under the terms of the GNU General Public License as published by     9  * the Free Software Foundation, either version 3 of the License, or    10  * (at your option) any later version.    11  *    12  * This program is distributed in the hope that it will be useful,    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    15  * GNU General Public License for more details.    16  *    17  * You should have received a copy of the GNU General Public License    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.    19  */    20     21 .text    22 .extern irq_handle    23 .extern current_registers    24 .extern current_stack_pointer    25 .extern current_task    26 .globl interrupt_handler    27 .set noreorder    28 .set noat    29     30 interrupt_handler:    31 	/* gp should have been set in the entrypoint. */    32     33 	jal save_state    34 	nop    35     36 	/* Invoke the handler. */    37     38 	jal irq_handle    39 	nop    40     41 	/* Switch the stack pointer. */    42     43 	la $k0, current_stack_pointer    44 	lw $k1, 0($k0)					/* &stack_pointers[current_task] */    45 	lw $sp, 0($k1)    46     47 	/* Set the current task ASID. */    48     49 	la $k0, current_task    50 	lw $k1, 0($k0)    51 	mtc0 $k1, $10					/* CP0_ENTRYHI */    52 	nop    53     54 	/* Obtain the current task's registers. */    55     56 	j load_and_return    57 	nop    58     59 save_state:    60 	/* Obtain a store of registers for the current task. */    61     62 	la $k0, current_registers    63 	lw $k1, 0($k0)    64     65 	sw $at, 4($k1)    66 	sw $v0, 8($k1)    67 	sw $v1, 12($k1)    68 	sw $a0, 16($k1)    69 	sw $a1, 20($k1)    70 	sw $a2, 24($k1)    71 	sw $a3, 28($k1)    72 	sw $t0, 32($k1)    73 	sw $t1, 36($k1)    74 	sw $t2, 40($k1)    75 	sw $t3, 44($k1)    76 	sw $t4, 48($k1)    77 	sw $t5, 52($k1)    78 	sw $t6, 56($k1)    79 	sw $t7, 60($k1)    80 	sw $s0, 64($k1)    81 	sw $s1, 68($k1)    82 	sw $s2, 72($k1)    83 	sw $s3, 76($k1)    84 	sw $s4, 80($k1)    85 	sw $s5, 84($k1)    86 	sw $s6, 88($k1)    87 	sw $s7, 92($k1)    88 	sw $t8, 96($k1)    89     90 	/* t9, gp and ra are already saved */    91     92 	sw $fp, 108($k1)    93     94 	mfc0 $k0, $14					/* CP0_EPC */    95 	nop    96 	sw $k0, 116($k1)    97     98 	j $ra    99 	nop   100    101 load_and_return:   102 	/* Obtain a store of registers for the current task. */   103    104 	la $k0, current_registers   105 	lw $k1, 0($k0)   106    107 	lw $at, 4($k1)   108 	lw $v0, 8($k1)   109 	lw $v1, 12($k1)   110 	lw $a0, 16($k1)   111 	lw $a1, 20($k1)   112 	lw $a2, 24($k1)   113 	lw $a3, 28($k1)   114 	lw $t0, 32($k1)   115 	lw $t1, 36($k1)   116 	lw $t2, 40($k1)   117 	lw $t3, 44($k1)   118 	lw $t4, 48($k1)   119 	lw $t5, 52($k1)   120 	lw $t6, 56($k1)   121 	lw $t7, 60($k1)   122 	lw $s0, 64($k1)   123 	lw $s1, 68($k1)   124 	lw $s2, 72($k1)   125 	lw $s3, 76($k1)   126 	lw $s4, 80($k1)   127 	lw $s5, 84($k1)   128 	lw $s6, 88($k1)   129 	lw $s7, 92($k1)   130 	lw $t8, 96($k1)   131 	lw $t9, 100($k1)   132 	lw $gp, 104($k1)   133 	lw $fp, 108($k1)   134 	lw $ra, 112($k1)   135    136 	lw $k0, 116($k1)   137 	mtc0 $k0, $14					/* CP0_EPC */   138 	nop   139    140 	eret   141 	nop   142    143 .set reorder   144 .set at