summaryrefslogtreecommitdiffstats
path: root/kernel/arch/mn10300/boot/compressed/head.S
blob: 7b50345b9e840dccc0a299efed88c402324a9da2 (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
/* Boot entry point for a compressed MN10300 kernel
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
	.section	.text

#define DEBUG

#include <linux/linkage.h>
#include <asm/cpu-regs.h>
#include <asm/cache.h>
#ifdef CONFIG_SMP
#include <proc/smp-regs.h>
#endif

	.globl startup_32
startup_32:
#ifdef CONFIG_SMP
	#
	# Secondary CPUs jump directly to the kernel entry point
	#
	# Must save primary CPU's D0-D2 registers as they hold boot parameters
	#
	mov	(CPUID), d3
	and	CPUID_MASK,d3
	beq	startup_primary
	mov	CONFIG_KERNEL_TEXT_ADDRESS,a0
	jmp	(a0)

startup_primary:
#endif /* CONFIG_SMP */

	# first save parameters from bootloader
	mov	param_save_area,a0
	mov	d0,(a0)
	mov	d1,(4,a0)
	mov	d2,(8,a0)

	mov	sp,a3
	mov	decomp_stack+0x2000-4,a0
	mov	a0,sp

	# invalidate and enable both of the caches
	mov	CHCTR,a0
	clr	d0
	movhu	d0,(a0)					# turn off first
	mov	CHCTR_ICINV|CHCTR_DCINV,d0
	movhu	d0,(a0)
	setlb
	mov	(a0),d0
	btst	CHCTR_ICBUSY|CHCTR_DCBUSY,d0		# wait till not busy
	lne

#ifdef CONFIG_MN10300_CACHE_ENABLED
#ifdef CONFIG_MN10300_CACHE_WBACK
	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
#else
	mov	CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
#endif /* WBACK */
	movhu	d0,(a0)					# enable
#endif /* !ENABLED */

	# clear the BSS area
	mov	__bss_start,a0
	mov	_end,a1
	clr	d0
bssclear:
	cmp	a1,a0
	bge	bssclear_end
	movbu	d0,(a0)
	inc	a0
	bra	bssclear
bssclear_end:

	# decompress the kernel
	call	decompress_kernel[],0
#ifdef CONFIG_MN10300_CACHE_WBACK
	call	mn10300_dcache_flush_inv[],0
#endif

	# disable caches again
	mov	CHCTR,a0
	clr	d0
	movhu	d0,(a0)
	setlb
	mov	(a0),d0
	btst	CHCTR_ICBUSY|CHCTR_DCBUSY,d0		# wait till not busy
	lne

	mov	param_save_area,a0
	mov	(a0),d0
	mov	(4,a0),d1
	mov	(8,a0),d2

	# jump to the kernel proper entry point
	mov	a3,sp
	mov	CONFIG_KERNEL_TEXT_ADDRESS,a0
	jmp	(a0)


###############################################################################
#
# Cache flush routines
#
###############################################################################
#ifdef CONFIG_MN10300_CACHE_WBACK
mn10300_dcache_flush_inv:
	movhu	(CHCTR),d0
	btst	CHCTR_DCEN,d0
	beq	mn10300_dcache_flush_inv_end

	mov	L1_CACHE_NENTRIES,d1
	clr	a1

mn10300_dcache_flush_inv_loop:
	mov	(DCACHE_PURGE_WAY0(0),a1),d0	# unconditional purge
	mov	(DCACHE_PURGE_WAY1(0),a1),d0	# unconditional purge
	mov	(DCACHE_PURGE_WAY2(0),a1),d0	# unconditional purge
	mov	(DCACHE_PURGE_WAY3(0),a1),d0	# unconditional purge

	add	L1_CACHE_BYTES,a1
	add	-1,d1
	bne	mn10300_dcache_flush_inv_loop

mn10300_dcache_flush_inv_end:
	ret	[],0
#endif /* CONFIG_MN10300_CACHE_WBACK */


###############################################################################
#
# Data areas
#
###############################################################################
	.data
	.align		4
param_save_area:
	.rept 3
	.word		0
	.endr

	.section	.bss
	.align		4
decomp_stack:
	.space		0x2000