summaryrefslogtreecommitdiffstats
path: root/arch/m68k/include/asm/coldfire/mcf5xxx.h
blob: 4e239a31d356721cd64d5dfdb584c49a161d5ad1 (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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/*
 * Copyright (c) 2008 Carsten Schlote <c.schlote@konzeptpark.de>
 * See file CREDITS for list of people who contributed to this project.
 *
 * This file is part of U-Boot V2.
 *
 * U-Boot V2 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.
 *
 * U-Boot V2 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 U-Boot V2.  If not, see <http://www.gnu.org/licenses/>.
 */

/** @file
 *  Definitions common across all ColdFire processors
 */
#ifndef __MCF5XXX__H
#define __MCF5XXX__H

/*
 * Common M68K & ColdFire definitions
 */
#define ADDRESS                  uint32_t
#define INSTRUCTION              uint16_t
#define ILLEGAL                  0x4AFC
#define CPU_WORD_SIZE            16

/*
 *  Definitions for CPU status register (SR)
 */
#define MCF5XXX_SR_T            (0x8000)
#define MCF5XXX_SR_S            (0x2000)
#define MCF5XXX_SR_M            (0x1000)
#define MCF5XXX_SR_IPL          (0x0700)
#define MCF5XXX_SR_IPL_0        (0x0000)
#define MCF5XXX_SR_IPL_1        (0x0100)
#define MCF5XXX_SR_IPL_2        (0x0200)
#define MCF5XXX_SR_IPL_3        (0x0300)
#define MCF5XXX_SR_IPL_4        (0x0400)
#define MCF5XXX_SR_IPL_5        (0x0500)
#define MCF5XXX_SR_IPL_6        (0x0600)
#define MCF5XXX_SR_IPL_7        (0x0700)
#define MCF5XXX_SR_X            (0x0010)
#define MCF5XXX_SR_N            (0x0008)
#define MCF5XXX_SR_Z            (0x0004)
#define MCF5XXX_SR_V            (0x0002)
#define MCF5XXX_SR_C            (0x0001)

/*
 *  Definitions for CPU cache control register
 */
#define MCF5XXX_CACR_CENB       (0x80000000)
#define MCF5XXX_CACR_DEC        (0x80000000)
#define MCF5XXX_CACR_DW         (0x40000000)
#define MCF5XXX_CACR_DESB       (0x20000000)
#define MCF5XXX_CACR_CPDI       (0x10000000)
#define MCF5XXX_CACR_DDPI       (0x10000000)
#define MCF5XXX_CACR_CPD        (0x10000000)
#define MCF5XXX_CACR_CFRZ       (0x08000000)
#define MCF5XXX_CACR_DHLCK      (0x08000000)
#define MCF5XXX_CACR_DDCM_WT    (0x00000000)
#define MCF5XXX_CACR_DDCM_CB    (0x02000000)
#define MCF5XXX_CACR_DDCM_IP    (0x04000000)
#define MCF5XXX_CACR_DDCM_II    (0x06000000)
#define MCF5XXX_CACR_CINV       (0x01000000)
#define MCF5XXX_CACR_DCINVA     (0x01000000)
#define MCF5XXX_CACR_DIDI       (0x00800000)
#define MCF5XXX_CACR_DDSP       (0x00800000)
#define MCF5XXX_CACR_DISD       (0x00400000)
#define MCF5XXX_CACR_INVI       (0x00200000)
#define MCF5XXX_CACR_INVD       (0x00100000)
#define MCF5XXX_CACR_BEC        (0x00080000)
#define MCF5XXX_CACR_BCINVA     (0x00040000)
#define MCF5XXX_CACR_IEC        (0x00008000)
#define MCF5XXX_CACR_DNFB       (0x00002000)
#define MCF5XXX_CACR_IDPI       (0x00001000)
#define MCF5XXX_CACR_IHLCK      (0x00000800)
#define MCF5XXX_CACR_CEIB       (0x00000400)
#define MCF5XXX_CACR_IDCM       (0x00000400)
#define MCF5XXX_CACR_DCM_WR     (0x00000000)
#define MCF5XXX_CACR_DCM_CB     (0x00000100)
#define MCF5XXX_CACR_DCM_IP     (0x00000200)
#define MCF5XXX_CACR_DCM        (0x00000200)
#define MCF5XXX_CACR_DCM_II     (0x00000300)
#define MCF5XXX_CACR_DBWE       (0x00000100)
#define MCF5XXX_CACR_ICINVA     (0x00000100)
#define MCF5XXX_CACR_IDSP       (0x00000080)
#define MCF5XXX_CACR_DWP        (0x00000020)
#define MCF5XXX_CACR_EUSP       (0x00000020)
#define MCF5XXX_CACR_EUST       (0x00000020)
#define MCF5XXX_CACR_DF         (0x00000010)
#define MCF5XXX_CACR_CLNF_00    (0x00000000)
#define MCF5XXX_CACR_CLNF_01    (0x00000002)
#define MCF5XXX_CACR_CLNF_10    (0x00000004)
#define MCF5XXX_CACR_CLNF_11    (0x00000006)

/*
 *  Definition for CPU access control register
 */
#define MCF5XXX_ACR_AB(a)       ((a)&0xFF000000)
#define MCF5XXX_ACR_AM(a)       (((a)&0xFF000000) >> 8)
#define MCF5XXX_ACR_EN          (0x00008000)
#define MCF5XXX_ACR_SM_USER     (0x00000000)
#define MCF5XXX_ACR_SM_SUPER    (0x00002000)
#define MCF5XXX_ACR_SM_IGNORE   (0x00006000)
#define MCF5XXX_ACR_ENIB        (0x00000080)
#define MCF5XXX_ACR_CM          (0x00000040)
#define MCF5XXX_ACR_DCM_WR      (0x00000000)
#define MCF5XXX_ACR_DCM_CB      (0x00000020)
#define MCF5XXX_ACR_DCM_IP      (0x00000040)
#define MCF5XXX_ACR_DCM_II      (0x00000060)
#define MCF5XXX_ACR_CM          (0x00000040)
#define MCF5XXX_ACR_BWE         (0x00000020)
#define MCF5XXX_ACR_WP          (0x00000004)

/*
 *  Definitions for CPU core sram control registers
 */
#define MCF5XXX_RAMBAR_BA(a)    ((a)&0xFFFFC000)
#define MCF5XXX_RAMBAR_PRI_00   (0x00000000)
#define MCF5XXX_RAMBAR_PRI_01   (0x00004000)
#define MCF5XXX_RAMBAR_PRI_10   (0x00008000)
#define MCF5XXX_RAMBAR_PRI_11   (0x0000C000)
#define MCF5XXX_RAMBAR_WP       (0x00000100)
#define MCF5XXX_RAMBAR_CI       (0x00000020)
#define MCF5XXX_RAMBAR_SC       (0x00000010)
#define MCF5XXX_RAMBAR_SD       (0x00000008)
#define MCF5XXX_RAMBAR_UC       (0x00000004)
#define MCF5XXX_RAMBAR_UD       (0x00000002)
#define MCF5XXX_RAMBAR_V        (0x00000001)


#ifndef __ASSEMBLY__

extern char __MBAR[];


/*
 * Extention to thhe basic POSIX data types
 */
typedef volatile uint8_t        vuint8_t;  /*  8 bits */
typedef volatile uint16_t       vuint16_t; /* 16 bits */
typedef volatile uint32_t       vuint32_t; /* 32 bits */

/*
 * Routines and macros for accessing Input/Output devices
 */

#define mcf_iord_8(ADDR)        *((vuint8_t *)(ADDR))
#define mcf_iord_16(ADDR)       *((vuint16_t *)(ADDR))
#define mcf_iord_32(ADDR)       *((vuint32_t *)(ADDR))

#define mcf_iowr_8(ADDR,DATA)   *((vuint8_t *)(ADDR)) = (DATA)
#define mcf_iowr_16(ADDR,DATA)  *((vuint16_t *)(ADDR)) = (DATA)
#define mcf_iowr_32(ADDR,DATA)  *((vuint32_t *)(ADDR)) = (DATA)

/*
 * The ColdFire family of processors has a simplified exception stack
 * frame that looks like the following:
 *
 *              3322222222221111 111111
 *              1098765432109876 5432109876543210
 *           8 +----------------+----------------+
 *             |         Program Counter         |
 *           4 +----------------+----------------+
 *             |FS/Fmt/Vector/FS|      SR        |
 *   SP -->  0 +----------------+----------------+
 *
 * The stack self-aligns to a 4-byte boundary at an exception, with
 * the FS/Fmt/Vector/FS field indicating the size of the adjustment
 * (SP += 0,1,2,3 bytes).
 */
#define MCF5XXX_RD_SF_FORMAT(PTR)   \
    ((*((uint16_t *)(PTR)) >> 12) & 0x00FF)

#define MCF5XXX_RD_SF_VECTOR(PTR)   \
    ((*((uint16_t *)(PTR)) >>  2) & 0x00FF)

#define MCF5XXX_RD_SF_FS(PTR)       \
    ( ((*((uint16_t *)(PTR)) & 0x0C00) >> 8) | (*((uint16_t *)(PTR)) & 0x0003) )

#define MCF5XXX_SF_SR(PTR)  *((uint16_t *)(PTR)+1)
#define MCF5XXX_SF_PC(PTR)  *((uint32_t *)(PTR)+1)

/*
 * Functions provided as inline code to access supervisor mode
 * registers from C.
 *
 * Note: Most registers are write-only. So you must use shadow registers in
 *       RAM to track the state of each register!
 */
static __inline__ uint16_t  mcf5xxx_rd_sr(void)            { uint16_t rc; __asm__ __volatile__( "move.w %%sr,%0\n" : "=r" (rc) ); return rc; }
static __inline__ void mcf5xxx_wr_sr(uint16_t value)       { __asm__ __volatile__( "move.w %0,%%sr\n" : : "r" (value) ); }

static __inline__ int asm_set_ipl(uint32_t value)
{
	uint32_t oldipl,newipl;
	value = (value & 0x7) << 8U;
	oldipl = mcf5xxx_rd_sr();
	newipl = oldipl & ~0x0700U;
	newipl |= value;
	mcf5xxx_wr_sr(newipl);
	oldipl = (oldipl & 0x0700U) >> 8U;
	return oldipl;
}

static __inline__ void mcf5xxx_cpushl_bc(uint32_t* value)   { __asm__ __volatile__( " move.l %0,%%a0 \n .word 0xF4E8\n nop\n" : : "a" (value) : "a0"); }
                                                                                                     // cpushl bc,%%a0@ ???

static __inline__ void mcf5xxx_wr_cacr(uint32_t value)     { __asm__ __volatile__( "movec %0,%%cacr\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_asid(uint32_t value)     { __asm__ __volatile__( "movec %0,%%asid\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acr0(uint32_t value)     { __asm__ __volatile__( "movec %0,#4\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acr1(uint32_t value)     { __asm__ __volatile__( "movec %0,#5\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acr2(uint32_t value)     { __asm__ __volatile__( "movec %0,#6\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acr3(uint32_t value)     { __asm__ __volatile__( "movec %0,#7\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_mmubar(uint32_t value)   { __asm__ __volatile__( "movec %0,%%mmubar\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_other_a7(uint32_t value) { __asm__ __volatile__( "movec %0,%%other_sp\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_vbr(uint32_t value)      { __asm__ __volatile__( "movec %0,%%vbr\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_macsr(uint32_t value)    { __asm__ __volatile__( "movec %0,%%macsr\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_mask(uint32_t value)     { __asm__ __volatile__( "movec %0,%%mask\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acc0(uint32_t value)     { __asm__ __volatile__( "movec %0,%%acc0\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_accext01(uint32_t value) { __asm__ __volatile__( "movec %0,%%accext01\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_accext23(uint32_t value) { __asm__ __volatile__( "movec %0,%%accext23\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acc1(uint32_t value)     { __asm__ __volatile__( "movec %0,%%acc1\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acc2(uint32_t value)     { __asm__ __volatile__( "movec %0,%%acc2\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_acc3(uint32_t value)     { __asm__ __volatile__( "movec %0,%%acc3\n nop\n" : : "r" (value) ); }
//static __inline__ void mcf5xxx_wr_sr(uint32_t value)       { __asm__ __volatile__( "movec %0,%%sr\n nop\n" : : "r" (value) ); }
//static __inline__ void mcf5xxx_wr_pc(uint32_t value)       { __asm__ __volatile__( "movec %0,#0x080F\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_rombar0(uint32_t value)  { __asm__ __volatile__( "movec %0,%%rombar0\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_rombar1(uint32_t value)  { __asm__ __volatile__( "movec %0,%%rombar1\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_rambar0(uint32_t value)  { __asm__ __volatile__( "movec %0,%%rambar0\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_rambar1(uint32_t value)  { __asm__ __volatile__( "movec %0,%%rambar1\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_mpcr(uint32_t value)     { __asm__ __volatile__( "movec %0,%%mpcr\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_secmbar(uint32_t value)  { __asm__ __volatile__( "movec %0,%%mbar1\n nop\n" : : "r" (value) ); }
static __inline__ void mcf5xxx_wr_mbar(uint32_t value)     { __asm__ __volatile__( "movec %0,%%mbar0\n nop\n" : : "r" (value) ); }

#endif

/*
 * Now do specific ColdFire processor
 */

#if   (defined(CONFIG_ARCH_MCF54xx))
#include "asm/coldfire/mcf548x.h"

#else
#error "Error: Yet unsupported ColdFire processor."
#endif


#endif  /* __MCF5XXX__H */