NanoPayload

Annotated stage2/entry.S

137:ca013d9f19c1
2016-02-27 Paul Boddie Masking interrupts should not be necessary.
paul@68 1
/*
paul@114 2
 * Interrupt and TLB miss handling support.
paul@68 3
 *
paul@114 4
 * Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
paul@68 5
 *
paul@68 6
 * This program is free software: you can redistribute it and/or modify
paul@68 7
 * it under the terms of the GNU General Public License as published by
paul@68 8
 * the Free Software Foundation, either version 3 of the License, or
paul@68 9
 * (at your option) any later version.
paul@68 10
 *
paul@68 11
 * This program is distributed in the hope that it will be useful,
paul@68 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@68 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@68 14
 * GNU General Public License for more details.
paul@68 15
 *
paul@68 16
 * You should have received a copy of the GNU General Public License
paul@68 17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
paul@68 18
 */
paul@68 19
paul@68 20
.text
paul@86 21
.extern interrupt_handler
paul@114 22
.globl _tlb_entry
paul@68 23
.globl _irq_entry
paul@68 24
.globl _end_entries
paul@68 25
.set noreorder
paul@68 26
paul@136 27
/* NOTE: Duplicated from cpu.h. */
paul@136 28
paul@136 29
#define page_table_start 0x00040000
paul@136 30
#define page_table_task_size 0x00008000
paul@136 31
#define page_table_task_size_log2 15
paul@136 32
paul@114 33
_tlb_entry:
paul@136 34
	/* Get the bad address. */
paul@136 35
paul@136 36
	mfc0 $k0, $10				/* CP0_ENTRYHI */
paul@136 37
	nop
paul@136 38
	andi $k1, $k0, 0xff			/* ASID */
paul@136 39
paul@136 40
	/* For ASID == 0... */
paul@136 41
paul@136 42
	beqz $k1, _tlb_entry_direct
paul@136 43
	nop
paul@136 44
paul@136 45
	/* For addresses over 0x00080000... */
paul@136 46
paul@136 47
	li $k1, 0xfff80000
paul@136 48
	and $k1, $k0, $k1
paul@136 49
	bnez $k1, _tlb_entry_direct
paul@136 50
	nop
paul@136 51
paul@136 52
	/* Otherwise, load the page table entries. */
paul@136 53
paul@136 54
	andi $k1, $k0, 0xff			/* ASID */
paul@136 55
	sll $k1, $k1, page_table_task_size_log2	/* [ASID] */
paul@136 56
	li $k0, page_table_start		/* page_table */
paul@136 57
	add $k0, $k0, $k1			/* page_table[ASID] */
paul@136 58
paul@136 59
	mfc0 $k1, $4				/* CP0_CONTEXT */
paul@136 60
	nop
paul@136 61
	srl $k1, $k1, 1				/* use 8 byte - not 16 byte - entries */
paul@136 62
	add $k0, $k0, $k1			/* page_table[ASID][entry] */
paul@136 63
paul@136 64
	lw $k1, 0($k0)				/* page_table[ASID][entry][0] */
paul@136 65
	mtc0 $k1, $2				/* CP0_ENTRYLO0 */
paul@136 66
	lw $k1, 4($k0)				/* page_table[ASID][entry][1] */
paul@136 67
	mtc0 $k1, $3				/* CP0_ENTRYLO1 */
paul@136 68
						/* page size is 4KB */
paul@136 69
	mtc0 $zero, $5				/* CP0_PAGEMASK */
paul@136 70
	nop
paul@136 71
paul@136 72
	tlbwr
paul@136 73
	nop
paul@136 74
	eret
paul@136 75
	nop
paul@136 76
paul@136 77
_tlb_entry_direct:
paul@136 78
	/* Otherwise, just translate the address directly. */
paul@136 79
paul@136 80
	li $k1, 0xffffe000
paul@136 81
	and $k0, $k0, $k1			/* VPN2 (8KB resolution) */
paul@136 82
	srl $k0, $k0, 6				/* PFN (maintain 8KB resolution, bit 6 remaining zero) */
paul@136 83
	ori $k0, $k0, 0x1e			/* flags */
paul@136 84
paul@136 85
	mtc0 $k0, $2				/* CP0_ENTRYLO0 */
paul@136 86
	ori $k0, $k0, 0x40			/* page size is 4KB (bit 6 set) */
paul@136 87
	mtc0 $k0, $3				/* CP0_ENTRYLO1 */
paul@136 88
	nop					/* page size is 4KB */
paul@136 89
	mtc0 $zero, $5				/* CP0_PAGEMASK */
paul@136 90
	nop
paul@136 91
paul@136 92
	tlbwr
paul@136 93
	nop
paul@136 94
	eret
paul@136 95
	nop
paul@136 96
paul@136 97
_irq_entry:
paul@127 98
	/* Save registers that the assembler wants to trash. */
paul@127 99
paul@127 100
        sw $t9, -100($sp)
paul@127 101
        sw $gp, -104($sp)
paul@127 102
        sw $ra, -112($sp)
paul@127 103
paul@126 104
	lui $gp, %hi(_GLOBAL_OFFSET_TABLE_)
paul@126 105
	ori $gp, $gp, %lo(_GLOBAL_OFFSET_TABLE_)
paul@122 106
	la $k0, interrupt_handler
paul@68 107
	jr $k0
paul@68 108
	nop
paul@68 109
paul@68 110
_end_entries:
paul@68 111
paul@68 112
.set reorder