summaryrefslogtreecommitdiff
path: root/src/main.s
blob: e45da64d21f10b84a6c1bb31b3969bf67f461980 (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
@ Tiny bare metal example
@ vim:ft=armv5

.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:

	@ Hang all except one of the processors
	MRC	P15, 0, R0, C0, C0, 5
	AND	R0, R0, #3
	CMP	R0, #0
	BNE	hang

	@ 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

	LDR	R13, =stack_svc		@ Set up stack for SVC mode

	@ 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}

	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
	MOV	R1, #1<<18
	STR	R1, [R8, #0x1c]		@ GPSET0
	BL	pause
	MOV	R1, #1<<18
	STR	R1, [R8, #0x28]		@ GPCLR0
	BL	pause

	@ 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

flashloop:
	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	flashloop

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

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