Subversion Repositories HelenOS

Rev

Rev 2071 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2071 Rev 2134
Line 29... Line 29...
29
/** @addtogroup sparc64mm  
29
/** @addtogroup sparc64mm  
30
 * @{
30
 * @{
31
 */
31
 */
32
/**
32
/**
33
 * @file
33
 * @file
-
 
34
 * @brief   D-cache shootdown algorithm.
34
 */
35
 */
35
 
36
 
36
#include <arch/mm/cache.h>
37
#include <arch/mm/cache.h>
37
 
38
 
-
 
39
#ifdef CONFIG_SMP
-
 
40
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
41
 
-
 
42
#include <smp/ipi.h>
-
 
43
#include <arch/interrupt.h>
-
 
44
#include <synch/spinlock.h>
-
 
45
#include <arch.h>
-
 
46
#include <debug.h>
-
 
47
 
-
 
48
/**
-
 
49
 * This spinlock is used by the processors to synchronize during the D-cache
-
 
50
 * shootdown.
-
 
51
 */
-
 
52
SPINLOCK_INITIALIZE(dcachelock);
-
 
53
 
-
 
54
/** Initialize the D-cache shootdown sequence.
-
 
55
 *
-
 
56
 * Start the shootdown sequence by sending out an IPI and wait until all
-
 
57
 * processors spin on the dcachelock spinlock.
-
 
58
 *
-
 
59
 * @param type  Scope of the D-cache shootdown.
-
 
60
 * @param color Color to be invalidated; applicable only for DCACHE_INVL_COLOR
-
 
61
 *      and DCACHE_INVL_FRAME invalidation types.
-
 
62
 * @param frame Frame to be invalidated; applicable only for DCACHE_INVL_FRAME
-
 
63
 *      invalidation types.
-
 
64
 */
-
 
65
void dcache_shootdown_start(dcache_invalidate_type_t type, int color,
-
 
66
    uintptr_t frame)
-
 
67
{
-
 
68
    int i;
-
 
69
 
-
 
70
    CPU->arch.dcache_active = 0;
-
 
71
    spinlock_lock(&dcachelock);
-
 
72
 
-
 
73
    for (i = 0; i < config.cpu_count; i++) {
-
 
74
        cpu_t *cpu;
-
 
75
 
-
 
76
        if (i == CPU->id)
-
 
77
            continue;
-
 
78
 
-
 
79
        cpu = &cpus[i];
-
 
80
        spinlock_lock(&cpu->lock);
-
 
81
        if (cpu->arch.dcache_message_count ==
-
 
82
            DCACHE_MSG_QUEUE_LEN) {
-
 
83
            /*
-
 
84
             * The queue is full, flush the cache entirely.
-
 
85
             */
-
 
86
            cpu->arch.dcache_message_count = 1;
-
 
87
            cpu->arch.dcache_messages[0].type = DCACHE_INVL_ALL;
-
 
88
            cpu->arch.dcache_messages[0].color = 0; /* ignored */
-
 
89
            cpu->arch.dcache_messages[0].frame = 0; /* ignored */
-
 
90
        } else {
-
 
91
            index_t idx = cpu->arch.dcache_message_count++;
-
 
92
            cpu->arch.dcache_messages[idx].type = type;
-
 
93
            cpu->arch.dcache_messages[idx].color = color;
-
 
94
            cpu->arch.dcache_messages[idx].frame = frame;
-
 
95
        }
-
 
96
        spinlock_unlock(&cpu->lock);
-
 
97
    }
-
 
98
 
-
 
99
    ipi_broadcast(IPI_DCACHE_SHOOTDOWN);   
-
 
100
 
-
 
101
busy_wait:
-
 
102
    for (i = 0; i < config.cpu_count; i++)
-
 
103
        if (cpus[i].arch.dcache_active)
-
 
104
            goto busy_wait;
-
 
105
}
-
 
106
 
-
 
107
/** Finish the D-cache shootdown sequence. */
-
 
108
void dcache_shootdown_finalize(void)
-
 
109
{
-
 
110
    spinlock_unlock(&dcachelock);
-
 
111
    CPU->arch.dcache_active = 1;
-
 
112
}
-
 
113
 
-
 
114
/** Process the D-cache shootdown IPI. */
-
 
115
void dcache_shootdown_ipi_recv(void)
-
 
116
{
-
 
117
    int i;
-
 
118
 
-
 
119
    ASSERT(CPU);
-
 
120
 
-
 
121
    CPU->arch.dcache_active = 0;
-
 
122
    spinlock_lock(&dcachelock);
-
 
123
    spinlock_unlock(&dcachelock);
-
 
124
   
-
 
125
    spinlock_lock(&CPU->lock);
-
 
126
    ASSERT(CPU->arch.dcache_message_count < DCACHE_MSG_QUEUE_LEN);
-
 
127
    for (i = 0; i < CPU->arch.dcache_message_count; i++) {
-
 
128
        switch (CPU->arch.dcache_messages[i].type) {
-
 
129
        case DCACHE_INVL_ALL:
-
 
130
            dcache_flush();
-
 
131
            goto flushed;
-
 
132
            break;
-
 
133
        case DCACHE_INVL_COLOR:
-
 
134
            dcache_flush_color(CPU->arch.dcache_messages[i].color);
-
 
135
            break;
-
 
136
        case DCACHE_INVL_FRAME:
-
 
137
            dcache_flush_frame(CPU->arch.dcache_messages[i].color,
-
 
138
                CPU->arch.dcache_messages[i].frame);
-
 
139
            break;
-
 
140
        default:
-
 
141
            panic("unknown type (%d)\n",
-
 
142
                CPU->arch.dcache_messages[i].type);
-
 
143
        }
-
 
144
    }
-
 
145
flushed:
-
 
146
    CPU->arch.dcache_message_count = 0;
-
 
147
    spinlock_unlock(&CPU->lock);
-
 
148
 
-
 
149
    CPU->arch.dcache_active = 1;
-
 
150
}
-
 
151
 
-
 
152
#endif /* CONFIG_VIRT_IDX_DCACHE */
-
 
153
#endif /* CONFIG_SMP */
-
 
154
 
38
/** @}
155
/** @}
39
 */
156
 */
40
 
157