Changeset d1e414c in mainline
- Timestamp:
- 2006-03-15T00:51:25Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 91d5ad6
- Parents:
- 51cc6bf6
- Location:
- generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/cpu.h
r51cc6bf6 rd1e414c 39 39 #include <config.h> 40 40 #include <adt/list.h> 41 #include <mm/tlb.h> 41 42 42 43 #define CPU_STACK_SIZE STACK_SIZE … … 49 50 SPINLOCK_DECLARE(lock); 50 51 52 tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN]; 53 count_t tlb_messages_count; 54 51 55 context_t saved_context; 52 56 -
generic/include/mm/tlb.h
r51cc6bf6 rd1e414c 34 34 #include <typedefs.h> 35 35 36 /** 37 * Number of TLB shootdown messages that can be queued in processor 38 * tlb_messages queue. 39 */ 40 #define TLB_MESSAGE_QUEUE_LEN 10 41 36 42 /** Type of TLB shootdown message. */ 37 43 enum tlb_invalidate_type { … … 41 47 TLB_INVL_PAGES /**< Invalidate specified page range belonging to one address space. */ 42 48 }; 43 44 49 typedef enum tlb_invalidate_type tlb_invalidate_type_t; 45 50 … … 49 54 asid_t asid; /**< Address space identifier. */ 50 55 __address page; /**< Page address. */ 56 count_t count; /**< Number of pages to invalidate. */ 51 57 }; 52 53 58 typedef struct tlb_shootdown_msg tlb_shootdown_msg_t; 54 59 … … 56 61 57 62 #ifdef CONFIG_SMP 58 extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t c nt);63 extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t count); 59 64 extern void tlb_shootdown_finalize(void); 60 65 extern void tlb_shootdown_ipi_recv(void); -
generic/src/mm/tlb.c
r51cc6bf6 rd1e414c 28 28 29 29 #include <mm/tlb.h> 30 #include <mm/asid.h> 30 31 #include <arch/mm/tlb.h> 31 32 #include <smp/ipi.h> … … 37 38 #include <arch.h> 38 39 #include <panic.h> 40 #include <debug.h> 39 41 42 /** 43 * This lock is used for synchronisation between sender and 44 * recipients of TLB shootdown message. It must be acquired 45 * before CPU structure lock. 46 */ 40 47 SPINLOCK_INITIALIZE(tlblock); 41 48 … … 46 53 47 54 #ifdef CONFIG_SMP 48 /* must be called with interrupts disabled */ 49 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t cnt) 55 56 /** Send TLB shootdown message. 57 * 58 * This function attempts to deliver TLB shootdown message 59 * to all other processors. 60 * 61 * This function must be called with interrupts disabled. 62 * 63 * @param type Type describing scope of shootdown. 64 * @param asid Address space, if required by type. 65 * @param page Virtual page address, if required by type. 66 * @param count Number of pages, if required by type. 67 */ 68 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, __address page, count_t count) 50 69 { 51 70 int i; … … 54 73 spinlock_lock(&tlblock); 55 74 56 /* 57 * TODO: wrap parameters into a message and 58 * dispatch it to all CPUs excluding this one. 59 */ 75 for (i = 0; i < config.cpu_count; i++) { 76 cpu_t *cpu; 77 78 if (i == CPU->id) 79 continue; 80 81 cpu = &cpus[i]; 82 spinlock_lock(&cpu->lock); 83 if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) { 84 /* 85 * The message queue is full. 86 * Erase the queue and store one TLB_INVL_ALL message. 87 */ 88 cpu->tlb_messages_count = 1; 89 cpu->tlb_messages[0].type = TLB_INVL_ALL; 90 cpu->tlb_messages[0].asid = ASID_INVALID; 91 cpu->tlb_messages[0].page = 0; 92 cpu->tlb_messages[0].count = 0; 93 } else { 94 /* 95 * Enqueue the message. 96 */ 97 cpu->tlb_messages[cpu->tlb_messages_count].type = type; 98 cpu->tlb_messages[cpu->tlb_messages_count].asid = asid; 99 cpu->tlb_messages[cpu->tlb_messages_count].page = page; 100 cpu->tlb_messages[cpu->tlb_messages_count].count = count; 101 cpu->tlb_messages_count++; 102 } 103 spinlock_unlock(&cpu->lock); 104 } 60 105 61 106 tlb_shootdown_ipi_send(); 62 107 63 108 busy_wait: 64 for (i = 0; i <config.cpu_count; i++)109 for (i = 0; i < config.cpu_count; i++) 65 110 if (cpus[i].tlb_active) 66 111 goto busy_wait; 67 112 } 68 113 114 /** Finish TLB shootdown sequence. */ 69 115 void tlb_shootdown_finalize(void) 70 116 { … … 78 124 } 79 125 126 /** Receive TLB shootdown message. */ 80 127 void tlb_shootdown_ipi_recv(void) 81 128 { 129 tlb_invalidate_type_t type; 130 asid_t asid; 131 __address page; 132 count_t count; 133 int i; 134 82 135 CPU->tlb_active = 0; 83 136 spinlock_lock(&tlblock); 84 137 spinlock_unlock(&tlblock); 85 tlb_invalidate_all(); /* TODO: be more finer-grained in what to invalidate */ 138 139 spinlock_lock(&CPU->lock); 140 ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN); 141 142 for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) { 143 type = CPU->tlb_messages[i].type; 144 asid = CPU->tlb_messages[i].asid; 145 page = CPU->tlb_messages[i].page; 146 count = CPU->tlb_messages[i].count; 147 148 switch (type) { 149 case TLB_INVL_ALL: 150 tlb_invalidate_all(); 151 break; 152 case TLB_INVL_ASID: 153 tlb_invalidate_asid(asid); 154 break; 155 case TLB_INVL_PAGES: 156 ASSERT(count); 157 tlb_invalidate_pages(asid, page, count); 158 break; 159 default: 160 panic("unknown type (%d)\n", type); 161 break; 162 } 163 if (type == TLB_INVL_ALL) 164 break; 165 } 166 167 spinlock_unlock(&CPU->lock); 86 168 CPU->tlb_active = 1; 87 169 } 170 88 171 #endif /* CONFIG_SMP */
Note:
See TracChangeset
for help on using the changeset viewer.