NanoPayload

Annotated stage2/handlers.S

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