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
|
/*
* linux/arch/arm/boot/compressed/head-sa1100.S
*
* Copyright (C) 1999 Nicolas Pitre <nico@cam.org>
*
* SA1100 specific tweaks. This is merged with head.S by the linker.
*/
#include <linux/config.h>
.section ".start", #alloc, #execinstr
__SA1100_start:
#ifndef CONFIG_ARCH_SA1100
#error What am I doing here...
#endif
#ifdef CONFIG_SA1100_BRUTUS
@ need to enter SVC mode
#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */
#define angel_SWI_ARM (0xEF123456 & 0xffffff)
mov r0, #angel_SWIreason_EnterSVC
swi #angel_SWI_ARM
@ turn off interrupts to prevent the angel from running
mrs r0, cpsr
orr r0, r0, #0xc0
msr cpsr, r0
#endif
#ifdef CONFIG_SA1100_VICTOR
@ Copy cmdline to 0xc0000000
mov r1, #0xc0000000
cmp r0, #0
moveq r2, #0
1: ldrneb r2, [r0], #1
cmpne r2, #0
strb r2, [r1], #1
bne 1b
#endif
@ Data cache might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
@ This is done by fetching through currently executed
@ memory to be sure we hit the same cache.
bic r2, pc, #0x1f
add r3, r2, #0x4000 @ 16 kb is quite enough...
1: ldr r0, [r2], #32
teq r2, r3
bne 1b
mcr p15, 0, r0, c7, c10, 4 @ drain WB
mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
@ disabling MMU, enabling I cache
mrc p15, 0, r0, c1, c0, 0 @ read control reg
bic r0, r0, #0x0d @ clear WB, DC, MMU
orr r0, r0, #0x1000 @ set Icache
mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_SA1100_BRUTUS
@ Initialize UART1 for early serial communication
@ since UART3 is used by angelboot. It is routed to
@ alternate GPIO functions on Brutus.
b 1f
GPIO_BASE: .long 0x90040000
#define GPDR 0x04
#define GAFR 0x1c
PPC_BASE: .long 0x90060000
#define PPAR 0x08
UART1_BASE: .long 0x80010000
#define UTCR0 0x00
#define UTCR1 0x04
#define UTCR2 0x08
#define UTCR3 0x0c
#define UTSR0 0x1c
#define UTSR1 0x20
#define BAUD_DIV_230400 0x000
#define BAUD_DIV_115200 0x001
#define BAUD_DIV_57600 0x003
#define BAUD_DIV_38400 0x005
#define BAUD_DIV_19200 0x00b
#define BAUD_DIV_9600 0x017
#define BAUD_DIV BAUD_DIV_9600
1: ldr r0, GPIO_BASE
ldr r1, [r0, #GPDR]
bic r1, r1, #1<<15
orr r1, r1, #1<<14
str r1, [r0, #GPDR]
ldr r1, [r0, #GAFR]
orr r1, r1, #(1<<15)|(1<<14)
str r1, [r0, #GAFR]
ldr r0, PPC_BASE
ldr r1, [r0, #PPAR]
orr r1, r1, #1<<12
str r1, [r0, #PPAR]
ldr r0, UART1_BASE
1: ldr r1, [r0, #UTSR1]
tst r1, #1<<0 @ TBY
bne 1b
mov r1, #0
str r1, [r0, #UTCR3]
mov r1, #0x08 @ 8N1
str r1, [r0, #UTCR0]
mov r1, #BAUD_DIV
str r1, [r0, #UTCR2]
mov r1, r1, lsr #8
str r1, [r0, #UTCR1]
mov r1, #0x03 @ RXE + TXE
str r1, [r0, #UTCR3]
mov r1, #0xff @ flush status reg
str r1, [r0, #UTSR0]
#endif
@ set registers for entry
mov r0, #0
mov r1, #16
|