Changeset 454f1da in mainline for kernel/arch/sparc64/src/mm/cache.c
- Timestamp:
- 2007-03-26T19:35:28Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5d7daff
- Parents:
- 4638401
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/src/mm/cache.c
r4638401 r454f1da 32 32 /** 33 33 * @file 34 * @brief D-cache shootdown algorithm. 34 35 */ 35 36 36 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 */
Note:
See TracChangeset
for help on using the changeset viewer.