Changeset b1c57a8 in mainline for kernel/arch/ia32
- Timestamp:
- 2014-10-09T15:03:55Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e367939c
- Parents:
- 21799398 (diff), 207e8880 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- kernel/arch/ia32
- Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/Makefile.inc
r21799398 rb1c57a8 85 85 arch/$(KARCH)/src/smp/mps.c \ 86 86 arch/$(KARCH)/src/smp/smp.c \ 87 arch/$(KARCH)/src/smp/smp_call.c \ 87 88 arch/$(KARCH)/src/atomic.S \ 88 89 arch/$(KARCH)/src/smp/ipi.c \ -
kernel/arch/ia32/include/arch/atomic.h
r21799398 rb1c57a8 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2012 Adam Hraska 3 4 * All rights reserved. 4 5 * … … 113 114 } 114 115 116 115 117 /** ia32 specific fast spinlock */ 116 118 NO_TRACE static inline void atomic_lock_arch(atomic_t *val) … … 142 144 } 143 145 146 147 #define _atomic_cas_impl(pptr, exp_val, new_val, old_val, prefix) \ 148 ({ \ 149 switch (sizeof(typeof(*(pptr)))) { \ 150 case 1: \ 151 asm volatile ( \ 152 prefix " cmpxchgb %[newval], %[ptr]\n" \ 153 : /* Output operands. */ \ 154 /* Old/current value is returned in eax. */ \ 155 [oldval] "=a" (old_val), \ 156 /* (*ptr) will be read and written to, hence "+" */ \ 157 [ptr] "+m" (*pptr) \ 158 : /* Input operands. */ \ 159 /* Expected value must be in eax. */ \ 160 [expval] "a" (exp_val), \ 161 /* The new value may be in any register. */ \ 162 [newval] "r" (new_val) \ 163 : "memory" \ 164 ); \ 165 break; \ 166 case 2: \ 167 asm volatile ( \ 168 prefix " cmpxchgw %[newval], %[ptr]\n" \ 169 : /* Output operands. */ \ 170 /* Old/current value is returned in eax. */ \ 171 [oldval] "=a" (old_val), \ 172 /* (*ptr) will be read and written to, hence "+" */ \ 173 [ptr] "+m" (*pptr) \ 174 : /* Input operands. */ \ 175 /* Expected value must be in eax. */ \ 176 [expval] "a" (exp_val), \ 177 /* The new value may be in any register. */ \ 178 [newval] "r" (new_val) \ 179 : "memory" \ 180 ); \ 181 break; \ 182 case 4: \ 183 asm volatile ( \ 184 prefix " cmpxchgl %[newval], %[ptr]\n" \ 185 : /* Output operands. */ \ 186 /* Old/current value is returned in eax. */ \ 187 [oldval] "=a" (old_val), \ 188 /* (*ptr) will be read and written to, hence "+" */ \ 189 [ptr] "+m" (*pptr) \ 190 : /* Input operands. */ \ 191 /* Expected value must be in eax. */ \ 192 [expval] "a" (exp_val), \ 193 /* The new value may be in any register. */ \ 194 [newval] "r" (new_val) \ 195 : "memory" \ 196 ); \ 197 break; \ 198 } \ 199 }) 200 201 202 #ifndef local_atomic_cas 203 204 #define local_atomic_cas(pptr, exp_val, new_val) \ 205 ({ \ 206 /* Use proper types and avoid name clashes */ \ 207 typeof(*(pptr)) _old_val_cas; \ 208 typeof(*(pptr)) _exp_val_cas = exp_val; \ 209 typeof(*(pptr)) _new_val_cas = new_val; \ 210 _atomic_cas_impl(pptr, _exp_val_cas, _new_val_cas, _old_val_cas, ""); \ 211 \ 212 _old_val_cas; \ 213 }) 214 215 #else 216 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/ 217 #error Architecture specific cpu local atomics already defined! Check your includes. 218 #endif 219 220 221 #ifndef local_atomic_exchange 222 /* 223 * Issuing a xchg instruction always implies lock prefix semantics. 224 * Therefore, it is cheaper to use a cmpxchg without a lock prefix 225 * in a loop. 226 */ 227 #define local_atomic_exchange(pptr, new_val) \ 228 ({ \ 229 /* Use proper types and avoid name clashes */ \ 230 typeof(*(pptr)) _exp_val_x; \ 231 typeof(*(pptr)) _old_val_x; \ 232 typeof(*(pptr)) _new_val_x = new_val; \ 233 \ 234 do { \ 235 _exp_val_x = *pptr; \ 236 _old_val_x = local_atomic_cas(pptr, _exp_val_x, _new_val_x); \ 237 } while (_old_val_x != _exp_val_x); \ 238 \ 239 _old_val_x; \ 240 }) 241 242 #else 243 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/ 244 #error Architecture specific cpu local atomics already defined! Check your includes. 245 #endif 246 247 144 248 #endif 145 249 -
kernel/arch/ia32/include/arch/cpu.h
r21799398 rb1c57a8 61 61 unsigned int stepping; 62 62 cpuid_feature_info_t fi; 63 63 64 unsigned int id; /** CPU's local, ie physical, APIC ID. */ 65 64 66 tss_t *tss; 65 67 -
kernel/arch/ia32/include/arch/interrupt.h
r21799398 rb1c57a8 69 69 #define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE + 1) 70 70 #define VECTOR_DEBUG_IPI (IVT_FREEBASE + 2) 71 #define VECTOR_SMP_CALL_IPI (IVT_FREEBASE + 3) 71 72 72 73 extern void (* disable_irqs_function)(uint16_t); -
kernel/arch/ia32/include/arch/smp/apic.h
r21799398 rb1c57a8 353 353 extern void l_apic_init(void); 354 354 extern void l_apic_eoi(void); 355 extern int l_apic_send_custom_ipi(uint8_t, uint8_t); 355 356 extern int l_apic_broadcast_custom_ipi(uint8_t); 356 357 extern int l_apic_send_init_ipi(uint8_t); -
kernel/arch/ia32/src/cpu/cpu.c
r21799398 rb1c57a8 160 160 void cpu_print_report(cpu_t* cpu) 161 161 { 162 printf("cpu%u: (%s family=%u model=%u stepping=%u ) %" PRIu16 " MHz\n",163 cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family,164 cpu->arch.model, cpu->arch.stepping, cpu-> frequency_mhz);162 printf("cpu%u: (%s family=%u model=%u stepping=%u apicid=%u) %" PRIu16 163 " MHz\n", cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, 164 cpu->arch.model, cpu->arch.stepping, cpu->arch.id, cpu->frequency_mhz); 165 165 } 166 166 -
kernel/arch/ia32/src/ia32.c
r21799398 rb1c57a8 122 122 } 123 123 124 void arch_post_cpu_init( )124 void arch_post_cpu_init(void) 125 125 { 126 126 #ifdef CONFIG_SMP -
kernel/arch/ia32/src/interrupt.c
r21799398 rb1c57a8 54 54 #include <symtab.h> 55 55 #include <stacktrace.h> 56 #include <smp/smp_call.h> 57 #include <proc/task.h> 56 58 57 59 /* … … 170 172 tlb_shootdown_ipi_recv(); 171 173 } 174 175 static void arch_smp_call_ipi_recv(unsigned int n, istate_t *istate) 176 { 177 trap_virtual_eoi(); 178 smp_call_ipi_recv(); 179 } 172 180 #endif 173 181 … … 230 238 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true, 231 239 (iroutine_t) tlb_shootdown_ipi); 240 exc_register(VECTOR_SMP_CALL_IPI, "smp_call", true, 241 (iroutine_t) arch_smp_call_ipi_recv); 232 242 #endif 233 243 } -
kernel/arch/ia32/src/smp/apic.c
r21799398 rb1c57a8 264 264 } 265 265 266 #define DELIVS_PENDING_SILENT_RETRIES 4 267 266 /* Waits for the destination cpu to accept the previous ipi. */ 268 267 static void l_apic_wait_for_delivery(void) 269 268 { 270 269 icr_t icr; 271 unsigned retries = 0; 272 270 273 271 do { 274 if (retries++ > DELIVS_PENDING_SILENT_RETRIES) {275 retries = 0;276 #ifdef CONFIG_DEBUG277 log(LF_ARCH, LVL_DEBUG, "IPI is pending.");278 #endif279 delay(20);280 }281 272 icr.lo = l_apic[ICRlo]; 282 } while (icr.delivs == DELIVS_PENDING); 283 273 } while (icr.delivs != DELIVS_IDLE); 274 } 275 276 /** Send one CPU an IPI vector. 277 * 278 * @param apicid Physical APIC ID of the destination CPU. 279 * @param vector Interrupt vector to be sent. 280 * 281 * @return 0 on failure, 1 on success. 282 */ 283 int l_apic_send_custom_ipi(uint8_t apicid, uint8_t vector) 284 { 285 icr_t icr; 286 287 /* Wait for a destination cpu to accept our previous ipi. */ 288 l_apic_wait_for_delivery(); 289 290 icr.lo = l_apic[ICRlo]; 291 icr.hi = l_apic[ICRhi]; 292 293 icr.delmod = DELMOD_FIXED; 294 icr.destmod = DESTMOD_PHYS; 295 icr.level = LEVEL_ASSERT; 296 icr.shorthand = SHORTHAND_NONE; 297 icr.trigger_mode = TRIGMOD_LEVEL; 298 icr.vector = vector; 299 icr.dest = apicid; 300 301 /* Send the IPI by writing to l_apic[ICRlo]. */ 302 l_apic[ICRhi] = icr.hi; 303 l_apic[ICRlo] = icr.lo; 304 305 return apic_poll_errors(); 284 306 } 285 307 … … 294 316 { 295 317 icr_t icr; 318 319 /* Wait for a destination cpu to accept our previous ipi. */ 320 l_apic_wait_for_delivery(); 296 321 297 322 icr.lo = l_apic[ICRlo]; … … 304 329 305 330 l_apic[ICRlo] = icr.lo; 306 307 l_apic_wait_for_delivery();308 331 309 332 return apic_poll_errors(); -
kernel/arch/ia32/src/smp/smp.c
r21799398 rb1c57a8 55 55 #include <memstr.h> 56 56 #include <arch/drivers/i8259.h> 57 #include <cpu.h> 57 58 58 59 #ifdef CONFIG_SMP … … 77 78 io_apic = (uint32_t *) km_map((uintptr_t) io_apic, PAGE_SIZE, 78 79 PAGE_WRITE | PAGE_NOT_CACHEABLE); 80 } 81 } 82 83 static void cpu_arch_id_init(void) 84 { 85 ASSERT(ops != NULL); 86 ASSERT(cpus != NULL); 87 88 for (unsigned int i = 0; i < config.cpu_count; ++i) { 89 cpus[i].arch.id = ops->cpu_apic_id(i); 79 90 } 80 91 } … … 92 103 93 104 ASSERT(ops != NULL); 105 106 /* 107 * SMP initialized, cpus array allocated. Assign each CPU its 108 * physical APIC ID. 109 */ 110 cpu_arch_id_init(); 94 111 95 112 /*
Note:
See TracChangeset
for help on using the changeset viewer.