summaryrefslogtreecommitdiff
path: root/include/lisa/cpu.h
blob: 228c9a698fe7b08c14e4c58f613ec5faa2cb3d42 (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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
/*
****************************************************************************
*                              PUBLIC INTERFACE
*
*     $Workfile:   cpu.h  $
*     $Author: save $
*
*     Copyright (C) 2002 by OSE Systems. All rights reserved.
*
****************************************************************************
*/
 
/*
 ****************************************************************************
	CONTENTS
	--------

	1  Description
	2  History of development
	3  Include files
	4  Manifest constants
	5  Macros
	6  Types
	7  Global Functions
	8  Process prototypes
	9  Global variables



 ****************************************************************************
 */

#ifndef _CPU_H
#define _CPU_H

#ifdef __cplusplus
extern "C" {
#endif

/*
 ****************************************************************************
 * 1  DESCRIPTION.
 ****************************************************************************
 * CPU specific definitions for the ARM family.
 *
 * Contains facilities to manipulate the interrupt mask. These facilities
 * are available for supervisor processes compiled to 32 bit ARM code, not
 * for THUMB mode. 
 * 
 * Also contains an architecture dependent structure to report the processor
 * state at unexpected exceptions.
 */

/*
 ****************************************************************************
 * 2  HISTORY OF DEVELOPMENT.
 *
 *    2002.07.17 guek
 *               - Optimize LOCK functions for use in supervisor mode only.
 *                 Calls from user mode are ignored, calls from exception
 *                 handling modes is a user error.
 *    2002.03.04 guek
 *               - Hide obsolete LOCK_PUSH, LOCK_POP macros unless
 *                 USE_OBSOLETE_LOCK_PUSH defined by caller. 
 *    2001.10.10 kjsv
 *               - Changed macro name, FLUSH_CACHE -> INVALIDATE_CACHE
 *    2001.09.27 johk
 *               - Added the FLUSH_CACHE macro
 *
 *    Moved PVCS Rev 1.4 to ClearCase.
 *
 */

/*
 ****************************************************************************
 * 3  INCLUDE FILES.
 ****************************************************************************
 */
#include "osetypes.h"

/*
 ****************************************************************************
 * 4  MANIFEST CONSTANTS.
 ****************************************************************************
 */


/*
 ****************************************************************************
 * 5  MACROS.
 ****************************************************************************
 */
#define SUPERV_MODE	0x13	/* Supervisor mode bits */
#define IRQ_DISABLE	0x80	/* IRQ interrupt mask */
#define FIQ_DISABLE	0x40	/* FIQ interrupt mask */

/* It may be needed to mask FIQ interrupts when manipulating some obscure 
 * interrupt controllers. In that case, board.c in the BSP must define 
 * BSP_MASK_FIQ. Usually that is not needed as FIQ and IRQ have separate
 * register sets.
 */
#ifdef BSP_MASK_FIQ
#define ZZLOCKED ((SUPERV_MODE) | (IRQ_DISABLE) | (FIQ_DISABLE))
#else
#define ZZLOCKED ((SUPERV_MODE) | (IRQ_DISABLE))
#endif  
#define ZZUNLOCKED (SUPERV_MODE)


/*
 ****************************************************************************
 * 6  TYPES.
 ****************************************************************************
 */

/* Type that can hold a Machine Status Register. */
typedef U32 Msr;

/* Register Dump Struct, used to report Unexpected Exceptions.
 * The address of the struct ose_regdump is passed in the 'extra' parameter 
 * to the Kernel Error Handler. 
 * 
 * ARM Note:
 * Note that the ARM architecture contains instructions that can modify
 * several registers. Some of these registers may be updated before the
 * exception is taken. See the relevant ARM Processor Core datasheet,
 * keyword Data Abort Model. 
 */

#define CPU_REGDUMP_MAGIC	(0x0001DAEA) /* Current magic number */

typedef struct cpu_mode_reg_bank /* Mode specific core register bank */
{
  U32		sp;
  U32		lr;
  U32		psr;		/* current cpsr for user mode,
				 * mode specific spsr for other modes.
				 */
} CPU_REG_BANK;

struct cpu_core			/* Complete set of core registers */
{
  U32		r[13];		/* Shared r0-r12 for all modes but FIQ,
				 * FIQ has own set for r8-r12
				 */
  CPU_REG_BANK	user;
  CPU_REG_BANK	supervisor;
  CPU_REG_BANK	abort;
  CPU_REG_BANK	undefined;
  CPU_REG_BANK	irq;

  U32		fiq_r8;
  U32		fiq_r9;
  U32		fiq_r10;
  U32		fiq_r11;
  U32		fiq_r12;
  CPU_REG_BANK	fiq;
};

struct cpu_dumpsection		/* Dump section */
{
  U32		identity;	/* Identifies contents of this dump part.
				 * Zero for a set of basic processor core
				 * registers, saved in form of a struct
				 * cpu_core.
				 * Other identities may be allocated to 
				 * provide more detailed or processors 
				 * specific information in the future. */
  U32		size;		/* Size of dump part, in bytes */
  U32		address;	/* Address of dump part (word aligned) */
};

struct cpu_regdump		/* Register Dump */
{
  U32		pc;		/* Program counter at exception */
  U32		sp;		/* Stack pointer at exception */
  U32		sr;		/* Status register before exception */
  U32		vector;		/* Exception Vector address offset counted 
				 * from the Reset vector */
  U32		fault_data_set;	/* Nonzero if fault_data_addr is set up */
  U32		fault_data_addr; /* Faulting address of data exceptions */
  U32		magic;		/* Magic number, to handle compatibility */
  U32		no_sects;	/* Number of parts (Currently one) */
  struct cpu_dumpsection sect[1];/* Basic register dump information 
				  * (and in the future, more detailed or 
				  * processor dependent information) */
};

/*
 ****************************************************************************
 * 7 GLOBAL FUNCTIONS
 ****************************************************************************
 */

/*
 *===========================================================================
 * LOCK_PUSH()		Disable IRQ, save old IRQ mask. (OBSOLETE - use LOCK_SAVE)
 * LOCK_POP()		Restore saved IRQ mask. (OBSOLETE - use LOCK_RESTORE)
 * LOCK()		Disable IRQ 
 * UNLOCK()		Enable IRQ 
 * LOCK_SAVE(mask)	Disable IRQ and save previous IRQ mask in argument
 * LOCK_RESTORE(mask)	Restore IRQ mask from argument
 *
 * Note! LOCK_SAVE and LOCK_RESTORE are macros, do not use & operator on
 * the argument. Use a variable of type 'Msr' for portability. 
 * LOCK_SAVE + LOCK_RESTORE is faster than LOCK_PUSH + LOCK_POP as a 
 * register variable may be used.
 *
 * Note! LOCK_PUSH and LOCK_POP are obsolete, and WILL BE REMOVED in the next
 * release.
 *===========================================================================
 */


#ifdef USE_OBSOLETE_LOCK_PUSH
static Msr zzbsp_pushed_lock;	/* Saved mask for lock_pop */
#else
#define LOCK_PUSH() Define_USE_OBSOLETE_LOCK_PUSH_to_enable_LOCK_PUSH_or_use_LOCK_SAVE()
#define LOCK_POP() Define_USE_OBSOLETE_LOCK_PUSH_to_enable_LOCK_POP_or_use_LOCK_RESTORE()
#endif

/* ARM zzlock_save returns unsigned char for backward compatibility */
unsigned char zzlock_save(Msr new_mask); 
void zzlock_set(Msr new_mask);

#ifndef __lint
				/* NOT lint */
#ifdef __ARMCC_VERSION
				/* ARM Ltd toolkits, SDT and ADS */
#ifdef __thumb
				/* 16 bit THUMB code */

#ifdef USE_OBSOLETE_LOCK_PUSH
#define  LOCK_PUSH() 	\
  zzbsp_pushed_lock = zzlock_save(ZZLOCKED)

#define LOCK_POP() 	\
  zzlock_set(zzbsp_pushed_lock)
#endif

#define LOCK()	\
  zzlock_set(ZZLOCKED)

#define UNLOCK()	\
  zzlock_set(ZZUNLOCKED)

#define LOCK_SAVE(mask)		\
  (mask) = zzlock_save(ZZLOCKED)

#define LOCK_RESTORE(mask)	\
  zzlock_set(mask)

#else
				/* 32 bit ARM code - inline */

#ifdef USE_OBSOLETE_LOCK_PUSH
#define  LOCK_PUSH() 	\
do 	\
{ 	\
  register Msr sr;	\
  __asm { MRS	sr, CPSR ;	\
          MSR	CPSR_c, ZZLOCKED }	\
  zzbsp_pushed_lock = sr;	\
} while (0)


#define LOCK_POP() 	\
  __asm { MSR	CPSR_c, zzbsp_pushed_lock }	
#endif


#define LOCK()	\
  __asm { MSR	CPSR_c, ZZLOCKED }	


#define UNLOCK()	\
  __asm { MSR	CPSR_c, ZZUNLOCKED }	


/* ARM LOCK_SAVE returns unsigned char for backward compatibility */
#define LOCK_SAVE(mask)		\
do				\
{				\
  register unsigned char zzmacro_local_sr;	\
  __asm { MRS	zzmacro_local_sr, CPSR ;	\
          MSR	CPSR_c, ZZLOCKED }	\
  (mask) = zzmacro_local_sr;	\
} while (0)


#define LOCK_RESTORE(mask)	\
  __asm { MSR	CPSR_c, (mask) }	
   
#endif /* 32 bit ARM code - inline */
#endif /* ARM Ltd, SDT and ADS  */

#else /* __lint */
#ifdef USE_OBSOLETE_LOCK_PUSH
#define  LOCK_PUSH() 	\
  zzbsp_pushed_lock = zzlock_save(ZZLOCKED)

#define LOCK_POP() 	\
  zzlock_set(zzbsp_pushed_lock)
#endif

#define LOCK()	\
  zzlock_set(ZZLOCKED)

#define UNLOCK()	\
  zzlock_set(ZZUNLOCKED)

#define LOCK_SAVE(mask)		\
  (mask) = zzlock_save(ZZLOCKED)

#define LOCK_RESTORE(mask)	\
  zzlock_set(mask)
#endif /* __lint */


/*
 *===========================================================================
 *                      MEMBAR
 *===========================================================================
 * Description: Issue a memory barrier, force previously issued memory
 *				operations to complete before continuing.
 *
 * Parameters:  None
 *
 * Returns:     None
 *
 */

#define MEMBAR()


/*
 *===========================================================================
 *                      INVALIDATE_CACHE
 *===========================================================================
 * Description: Automatically identifies the target CPU and depending on 
 *              the CPU found applies the following methods of invalidating 
 *              the cache/s:
 *              
 *              720      - (Unified cache) The entire cache is invalidated
 *              920, 922 - (Harvard cache) D-cache entrys with base addresses 
 *                         ranging from address to address+length are
 *                         invalidated.
 *              940      - (Harvard cache) The entire D-cache is invalidated
 *
 * Parameters:  address:  Base address to start invalidating cache
 *              length:   Number of bytes to invalidate.
 *
 * Returns:     Nothing.
 */

#define INVALIDATE_CACHE(address, length) \
do \
{	\
  register unsigned long zzlocal_idcode; \
  register unsigned long zzlocal_tmp = 0; \
  __asm { MRC p15, 0, zzlocal_idcode, c0, c0, 0 } \
  zzlocal_idcode = ((zzlocal_idcode >> 4) & 0xFFF); \
  switch(zzlocal_idcode) \
  { \
    case 0x720: \
      __asm { MCR p15, 0, zzlocal_tmp, c7, c7, 0 } \
      break; \
    case 0x920: \
    case 0x922: \
      { \
         register unsigned long base = (U32) address; \
         register unsigned long limit = (U32) address+length; \
         for(; base<limit; base += 32) \
           { __asm { MCR p15, 0, base, c7, c6, 1 } } \
      } \
      break; \
    case 0x940: \
      __asm { MCR p15, 0, zzlocal_tmp, c7, c6, 0 } \
      break; \
    default : \
      break; \
   } \
} while (0)


/*
 ****************************************************************************
 * 8  PROCESS PROTOTYPES.
 ****************************************************************************
 */


/*
 ****************************************************************************
 * 9  GLOBAL VARIABLES.
 ****************************************************************************
 */

#ifdef __cplusplus
}
#endif

#endif /* # ifndef __CPU_H */