blob: a03f5e2d5dc75d6ed87cd7f9c3cb2845f88cf69e (
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
|
// $Id: ppc405_cache_core.c,v 1.1.1.1 2013/12/11 21:03:27 bcbrock Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/ssx/ppc405/ppc405_cache_core.c,v $
//-----------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
// *! All Rights Reserved -- Property of IBM
// *! *** IBM Confidential ***
//-----------------------------------------------------------------------------
/// \file ppc405_cache_core.c
/// \brief Core cache management routines required of any PPC405 configuration
/// of SSX that interacts with DMA devices using cacheable memory.
///
/// The entry points in this file are considered 'core' routines that will
/// always be present at runtime in any SSX application.
///
/// \todo The compiler generates wierd assembly language for these cache
/// management APIs - probably due to the "volatile" asm - it may be best to
/// recode them directly in assembler.
#include "ssx.h"
/// Invalidate a range of addresses from the D-cache
///
/// \param p A pointer to the memory area to be invalidated.
///
/// \param bytes The size (in bytes) of the area to invalidate.
///
/// The dcache_invalidate() API is used to invalidate an arbitrary range of
/// memory in the cache. Note that invalidation is a destructive operation
/// that may cause the loss of information. This API will invalidate all
/// cache lines from the line containing the address \a p, to the line
/// containing the address \a p + \a size - 1. (If \a size == 0 this call is
/// a NOP.) It is the caller's responsibility to insure that no useful data is
/// inadverdently invalidated. D-cache invalidation is more-or-less a no-op
/// for data either not in the cache or marked as non-cacheable.
///
/// This API always issues a sync() after the invalidation, even in the event
/// of \a size == 0.
///
/// \note For invalidating small blocks of data where some alignmment
/// constraints are known it may be more efficient to use
/// dcache_invalidate_line() rather than this API.
void
dcache_invalidate(void *p, size_t bytes)
{
size_t lines;
if (bytes != 0) {
lines = 1;
bytes -=
MIN((CACHE_LINE_SIZE - ((unsigned long)p % CACHE_LINE_SIZE)),
bytes);
lines += bytes / CACHE_LINE_SIZE;
if (!cache_aligned(bytes)) {
lines++;
}
while (lines--) {
dcbi(p);
p += CACHE_LINE_SIZE;
}
}
sync();
}
/// Flush and invalidate a range of addresses from the D-cache
///
/// \param p A pointer to a memory area to be invalidated.
///
/// \param bytes The size (in bytes) of the area to invalidate.
///
/// The dcache_flush() API is used to flush and invalidate an arbitrary range
/// of memory from the D-cache. Note that flushing is not a destructive
/// operation in the sense that no information is lost. This API will flush
/// and invalidate all cache lines from the line containing the address \a p,
/// to the line containing the address \a p + \a size - 1. (If \a size == 0
/// this call is a NOP.) D-cache flush is more-or-less a no-op for data
/// either not in the cache or marked as non-cacheable.
///
/// This API always issues a sync() after the flush, even in the event of \a
/// size == 0.
///
/// \note For flushing small blocks of data where some alignmment constraints
/// are known it may be more efficient to use dcache_flush_line() rather than
/// this API.
void
dcache_flush(void *p, size_t bytes)
{
size_t lines;
if (bytes != 0) {
lines = 1;
bytes -=
MIN((CACHE_LINE_SIZE - ((unsigned long)p % CACHE_LINE_SIZE)),
bytes);
lines += bytes / CACHE_LINE_SIZE;
if (!cache_aligned(bytes)) {
lines++;
}
while (lines--) {
dcbf(p);
p += CACHE_LINE_SIZE;
}
}
sync();
}
|