summaryrefslogtreecommitdiff
path: root/src/main.s
blob: b981b2a0c8320a8bb6f49b45d5460bc7cedc6fc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * main.s
 *
 * Copyright © 2018 Thomas White <taw@bitwiz.org.uk>
 *
 * 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/>.
 *
 */

@ vim:ft=armv5

.include "swi_numbers.h"

.section .init

_start:
	LDR	PC, [PC, #24]	@ Reset
	LDR	PC, [PC, #24]	@ Undefined
	LDR	PC, [PC, #24]	@ SWI
	LDR	PC, [PC, #24]	@ Prefetch abort
	LDR	PC, [PC, #24]	@ Data abort
	LDR	PC, [PC, #24]	@ Reserved
	LDR	PC, [PC, #24]	@ IRQ
	LDR	PC, [PC, #24]	@ FIQ
	.word	reset		@ Reset
	.word	hang		@ Undefined
	.word	swi_handler	@ SWI
	.word	hang		@ Prefetch abort
	.word	hang		@ Data abort
	.word	hang		@ Reserved
	.word	hang		@ IRQ
	.word	hang		@ FIQ

hang:
	B	hang

reset:
	/* Get out of HYP mode */
	MRS	R0, CPSR
	BIC	R0, R0, #0x1f
	ORR	R0, R0, #0x13
	MSR	SPSR_cxsf, R0
	ADD	R0, PC, #4
	MSR	ELR_hyp,r0
	ERET

	/* Set up supervisor mode stack */
	LDR	R13, =stack_svc

	/* Relocate vector table */
	MOV	R10, #0x8000
	MOV	R11, #0
	LDMIA	R10!, {R0-R7}
	STMIA	R11!, {R0-R7}
	LDMIA	R10!, {R0-R7}
	STMIA	R11!, {R0-R7}

	/* Set another CPU doing something */
	LDR R0, =flash_status_led
	MOV R1, #0x40000000
	STR R0,[R1, #0xbc]
	SEV

	LDR	R8, =0x3f200000
	LDR	R1, [R8, #0x04]		@ GPFSEL1
	ORR	R1, R1, #1<<18		@ GPIO pin 16 is output
	BIC	R1, R1, #3<<21		@ GPIO pin 17 is input
	ORR	R1, R1, #1<<24		@ GPIO pin 18 is output
	STR	R1, [R8, #0x04]		@ GPFSEL1

	@ Flash green LED
	MRC	P15, 0, R0, C0, C0, 5
	AND	R0, R0, #0x0f
	CMP	R0, #0
	BNE	skip_flash

	MOV	R1, #1<<18
	STR	R1, [R8, #0x1c]		@ GPSET0
	BL	pause
	MOV	R1, #1<<18
	STR	R1, [R8, #0x28]		@ GPCLR0
	BL	pause

skip_flash:

	@ Switch to USR mode and set up stack
	MRS	R0, CPSR
	BIC	R0, R0, #0x1f
	ORR	R0, R0, #0x10
	MSR	CPSR_c, R0
	LDR	R13, =stack_usr

repeat:
	MOV	R0, #0
	SWI	0
	TST	R0, #1<<17
	MOVNE	R0, #1
	SWINE	0
	B	repeat


swi_handler:
	STMDB	R13!, {R8, LR}
	LDR	R8, =0x3f200000
	CMP	R0, #0
	BEQ	get_gpio
	CMP	R0, #1
	BLEQ	flash
	LDMIA	R13!, {R8, PC}^

get_gpio:
	LDR	R0, [R8, #0x34]		@ GPLEV0
	LDMIA	R13!, {R8, PC}^


flash:
	STMDB	R13!, {R1, R2, R4, LR}
	MOV	R4, #5

1:
	MOV	R1, #1<<16
	STR	R1, [R8, #0x28]		@ GPCLR0
	MOV	R1, #1<<18
	STR	R1, [R8, #0x1c]		@ GPSET0

	BL	pause

	MOV	R1, #1<<18
	STR	R1, [R8, #0x28]		@ GPCLR0
	MOV	R1, #1<<16
	STR	R1, [R8, #0x1c]		@ GPSET0

	BL	pause

	MOV	R1, #1<<18
	ORR	R1, #1<<16
	STR	R1, [R8, #0x28]		@ GPCLR0

	SUBS	R4, R4, #1
	BNE	1b

	LDMIA	R13!, {R1, R2, R4, PC}

pause:
	MOV	R2, #0x3f000
1:
	SUBS	R2, R2, #1
	BNE	1b
	MOV	PC, LR