This source file includes following definitions.
- max
- mpf_checksum
- mpc_family
- smp_read_mpc
- smp_scan_config
- install_trampoline
- smp_alloc_memory
- get_kernel_stack
- smp_store_cpu_info
- smp_commence
- smp_callin
- smp_boot_cpus
- smp_message_pass
- smp_invalidate
- smp_reschedule_irq
- smp_message_irq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <linux/kernel.h>
25 #include <linux/string.h>
26 #include <linux/timer.h>
27 #include <linux/sched.h>
28 #include <linux/mm.h>
29 #include <linux/kernel_stat.h>
30 #include <linux/delay.h>
31 #include <linux/mc146818rtc.h>
32 #include <asm/i82489.h>
33 #include <linux/smp.h>
34 #include <asm/pgtable.h>
35 #include <asm/bitops.h>
36 #include <asm/pgtable.h>
37 #include <asm/smp.h>
38
39
40
41
42
43 extern __inline int max(int a,int b)
44 {
45 if(a>b)
46 return a;
47 return b;
48 }
49
50
51 int smp_found_config=0;
52
53 unsigned long cpu_present_map = 0;
54 int smp_num_cpus;
55 int smp_threads_ready=0;
56 volatile int cpu_number_map[NR_CPUS];
57 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
58 volatile unsigned long smp_invalidate_needed;
59 struct cpuinfo_x86 cpu_data[NR_CPUS];
60 static unsigned int num_processors = 1;
61 int smp_top_cpu = 0;
62 static unsigned long io_apic_addr = 0xFEC00000;
63 unsigned char boot_cpu_id = 0;
64 static unsigned char *kstack_base,*kstack_end;
65 static int smp_activated = 0;
66 int apic_version[NR_CPUS];
67 static volatile int smp_commenced=0;
68 unsigned long apic_addr=0xFEE00000;
69 unsigned long nlong = 0;
70 unsigned char *apic_reg=((unsigned char *)(&nlong))-0x20;
71 unsigned long apic_retval;
72 unsigned char *kernel_stacks[NR_CPUS];
73
74 static volatile unsigned char smp_cpu_in_msg[NR_CPUS];
75 static volatile unsigned long smp_msg_data;
76 static volatile int smp_src_cpu;
77 static volatile int smp_msg_id;
78
79 volatile unsigned long kernel_flag=0;
80 volatile unsigned char active_kernel_processor = NO_PROC_ID;
81 volatile unsigned long kernel_counter=0;
82 volatile unsigned long syscall_count=0;
83
84 volatile unsigned long ipi_count;
85 #ifdef __SMP_PROF__
86 volatile unsigned long smp_spins[NR_CPUS]={0};
87 volatile unsigned long smp_spins_syscall[NR_CPUS]={0};
88 volatile unsigned long smp_spins_syscall_cur[NR_CPUS]={0};
89 volatile unsigned long smp_spins_sys_idle[NR_CPUS]={0};
90 volatile unsigned long smp_idle_count[1+NR_CPUS]={0,};
91 #endif
92 #if defined (__SMP_PROF__)
93 volatile unsigned long smp_idle_map=0;
94 #endif
95
96 volatile unsigned long smp_proc_in_lock[NR_CPUS] = {0,};
97 volatile unsigned long smp_process_available=0;
98
99
100
101 #ifdef SMP_DEBUG
102 #define SMP_PRINTK(x) printk x
103 #else
104 #define SMP_PRINTK(x)
105 #endif
106
107
108
109
110
111
112 static int mpf_checksum(unsigned char *mp, int len)
113 {
114 int sum=0;
115 while(len--)
116 sum+=*mp++;
117 return sum&0xFF;
118 }
119
120
121
122
123
124 static char *mpc_family(int family,int model)
125 {
126 static char n[32];
127 static char *model_defs[]=
128 {
129 "80486DX","80486DX",
130 "80486SX","80486DX/2 or 80487",
131 "80486SL","Intel5X2(tm)",
132 "Unknown","Unknown",
133 "80486DX/4"
134 };
135 if(family==0x6)
136 return("Pentium(tm) Pro");
137 if(family==0x5)
138 return("Pentium(tm)");
139 if(family==0x0F && model==0x0F)
140 return("Special controller");
141 if(family==0x04 && model<9)
142 return model_defs[model];
143 sprintf(n,"Unknown CPU [%d:%d]",family, model);
144 return n;
145 }
146
147
148
149
150
151 static int smp_read_mpc(struct mp_config_table *mpc)
152 {
153 char str[16];
154 int count=sizeof(*mpc);
155 int apics=0;
156 unsigned char *mpt=((unsigned char *)mpc)+count;
157
158 if(memcmp(mpc->mpc_signature,MPC_SIGNATURE,4))
159 {
160 printk("Bad signature [%c%c%c%c].\n",
161 mpc->mpc_signature[0],
162 mpc->mpc_signature[1],
163 mpc->mpc_signature[2],
164 mpc->mpc_signature[3]);
165 return 1;
166 }
167 if(mpf_checksum((unsigned char *)mpc,mpc->mpc_length))
168 {
169 printk("Checksum error.\n");
170 return 1;
171 }
172 if(mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04)
173 {
174 printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec);
175 return 1;
176 }
177 memcpy(str,mpc->mpc_oem,8);
178 str[8]=0;
179 printk("OEM ID: %s ",str);
180 memcpy(str,mpc->mpc_productid,12);
181 str[12]=0;
182 printk("Product ID: %s ",str);
183 printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
184
185
186 apic_addr = mpc->mpc_lapic;
187
188
189
190
191
192 while(count<mpc->mpc_length)
193 {
194 switch(*mpt)
195 {
196 case MP_PROCESSOR:
197 {
198 struct mpc_config_processor *m=
199 (struct mpc_config_processor *)mpt;
200 if(m->mpc_cpuflag&CPU_ENABLED)
201 {
202 printk("Processor #%d %s APIC version %d\n",
203 m->mpc_apicid,
204 mpc_family((m->mpc_cpufeature&
205 CPU_FAMILY_MASK)>>8,
206 (m->mpc_cpufeature&
207 CPU_MODEL_MASK)>>4),
208 m->mpc_apicver);
209 #ifdef SMP_DEBUG
210 if(m->mpc_featureflag&(1<<0))
211 printk(" Floating point unit present.\n");
212 if(m->mpc_featureflag&(1<<7))
213 printk(" Machine Exception supported.\n");
214 if(m->mpc_featureflag&(1<<8))
215 printk(" 64 bit compare & exchange supported.\n");
216 if(m->mpc_featureflag&(1<<9))
217 printk(" Internal APIC present.\n");
218 #endif
219 if(m->mpc_cpuflag&CPU_BOOTPROCESSOR)
220 {
221 SMP_PRINTK((" Bootup CPU\n"));
222 boot_cpu_id=m->mpc_apicid;
223 nlong = boot_cpu_id<<24;
224 }
225 else
226 num_processors++;
227
228 if(m->mpc_apicid>NR_CPUS)
229 printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS);
230 else
231 {
232 cpu_present_map|=(1<<m->mpc_apicid);
233 apic_version[m->mpc_apicid]=m->mpc_apicver;
234 }
235 }
236 mpt+=sizeof(*m);
237 count+=sizeof(*m);
238 break;
239 }
240 case MP_BUS:
241 {
242 struct mpc_config_bus *m=
243 (struct mpc_config_bus *)mpt;
244 memcpy(str,m->mpc_bustype,6);
245 str[6]=0;
246 SMP_PRINTK(("Bus #%d is %s\n",
247 m->mpc_busid,
248 str));
249 mpt+=sizeof(*m);
250 count+=sizeof(*m);
251 break;
252 }
253 case MP_IOAPIC:
254 {
255 struct mpc_config_ioapic *m=
256 (struct mpc_config_ioapic *)mpt;
257 if(m->mpc_flags&MPC_APIC_USABLE)
258 {
259 apics++;
260 printk("I/O APIC #%d Version %d at 0x%lX.\n",
261 m->mpc_apicid,m->mpc_apicver,
262 m->mpc_apicaddr);
263 io_apic_addr = m->mpc_apicaddr;
264 }
265 mpt+=sizeof(*m);
266 count+=sizeof(*m);
267 break;
268 }
269 case MP_INTSRC:
270 {
271 struct mpc_config_intsrc *m=
272 (struct mpc_config_intsrc *)mpt;
273
274 mpt+=sizeof(*m);
275 count+=sizeof(*m);
276 break;
277 }
278 case MP_LINTSRC:
279 {
280 struct mpc_config_intlocal *m=
281 (struct mpc_config_intlocal *)mpt;
282 mpt+=sizeof(*m);
283 count+=sizeof(*m);
284 break;
285 }
286 }
287 }
288 if(apics>1)
289 printk("Warning: Multiple APIC's not supported.\n");
290 return num_processors;
291 }
292
293
294
295
296
297 void smp_scan_config(unsigned long base, unsigned long length)
298 {
299 unsigned long *bp=(unsigned long *)base;
300 struct intel_mp_floating *mpf;
301
302 SMP_PRINTK(("Scan SMP from %p for %ld bytes.\n",
303 bp,length));
304 if(sizeof(*mpf)!=16)
305 printk("Error: MPF size\n");
306
307 while(length>0)
308 {
309 if(*bp==SMP_MAGIC_IDENT)
310 {
311 mpf=(struct intel_mp_floating *)bp;
312 if(mpf->mpf_length==1 &&
313 !mpf_checksum((unsigned char *)bp,16) &&
314 (mpf->mpf_specification == 1
315 || mpf->mpf_specification == 4) )
316 {
317 printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
318 if(mpf->mpf_feature2&(1<<7))
319 printk(" IMCR and PIC compatibility mode.\n");
320 else
321 printk(" Virtual Wire compatibility mode.\n");
322 smp_found_config=1;
323
324
325
326 if(mpf->mpf_feature1!=0)
327 {
328 num_processors=2;
329 printk("I/O APIC at 0xFEC00000.\n");
330 printk("Bus#0 is ");
331 }
332 switch(mpf->mpf_feature1)
333 {
334 case 1:
335 case 5:
336 printk("ISA\n");
337 break;
338 case 2:
339 printk("EISA with no IRQ8 chaining\n");
340 break;
341 case 6:
342 case 3:
343 printk("EISA\n");
344 break;
345 case 4:
346 case 7:
347 printk("MCA\n");
348 break;
349 case 0:
350 break;
351 default:
352 printk("???\nUnknown standard configuration %d\n",
353 mpf->mpf_feature1);
354 return;
355 }
356 if(mpf->mpf_feature1>4)
357 printk("Bus #1 is PCI\n");
358
359
360
361 if(mpf->mpf_physptr)
362 smp_read_mpc((void *)mpf->mpf_physptr);
363 else
364 {
365 unsigned long cfg;
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 cfg=pg0[0];
385 pg0[0] = (apic_addr | 7);
386 local_invalidate();
387
388 boot_cpu_id = GET_APIC_ID(*((volatile unsigned long *) APIC_ID));
389 nlong = boot_cpu_id<<24;
390
391
392
393
394
395 pg0[0]= cfg;
396 local_invalidate();
397
398
399
400
401
402
403
404
405
406
407
408 if (boot_cpu_id)
409 cpu_present_map=1 | (1 << boot_cpu_id);
410 else
411 cpu_present_map=3;
412 }
413 printk("Processors: %d\n", num_processors);
414
415
416
417 return;
418 }
419 }
420 bp+=4;
421 length-=16;
422 }
423 }
424
425
426
427
428
429 static unsigned char trampoline_data[]={
430 #include "trampoline.hex"
431 };
432
433
434
435
436
437
438
439 static void install_trampoline(unsigned char *mp)
440 {
441 memcpy(mp,trampoline_data,sizeof(trampoline_data));
442 }
443
444
445
446
447
448
449
450
451 unsigned long smp_alloc_memory(unsigned long mem_base)
452 {
453 int size=(num_processors-1)*PAGE_SIZE;
454
455
456
457
458
459 if(mem_base+size>=0x9F000)
460 panic("smp_alloc_memory: Insufficient low memory for kernel stacks.\n");
461 kstack_base=(void *)mem_base;
462 mem_base+=size;
463 kstack_end=(void *)mem_base;
464 return mem_base;
465 }
466
467
468
469
470
471 static void *get_kernel_stack(void)
472 {
473 void *stack=kstack_base;
474 if(kstack_base>=kstack_end)
475 return NULL;
476 kstack_base+=PAGE_SIZE;
477 return stack;
478 }
479
480
481
482
483
484
485
486 void smp_store_cpu_info(int id)
487 {
488 struct cpuinfo_x86 *c=&cpu_data[id];
489 c->hard_math=hard_math;
490 c->x86=x86;
491 c->x86_model=x86_model;
492 c->x86_mask=x86_mask;
493 c->x86_capability=x86_capability;
494 c->fdiv_bug=fdiv_bug;
495 c->wp_works_ok=wp_works_ok;
496 c->hlt_works_ok=hlt_works_ok;
497 c->have_cpuid=have_cpuid;
498 c->udelay_val=loops_per_sec;
499 strcpy(c->x86_vendor_id, x86_vendor_id);
500 }
501
502
503
504
505
506
507
508
509
510
511
512 void smp_commence(void)
513 {
514
515
516
517 smp_commenced=1;
518 }
519
520 void smp_callin(void)
521 {
522 int cpuid=GET_APIC_ID(apic_read(APIC_ID));
523 unsigned long l;
524
525
526
527
528 SMP_PRINTK(("CALLIN %d\n",smp_processor_id()));
529 l=apic_read(APIC_SPIV);
530 l|=(1<<8);
531 apic_write(APIC_SPIV,l);
532 sti();
533
534
535
536 calibrate_delay();
537
538
539
540 smp_store_cpu_info(cpuid);
541
542
543
544 set_bit(cpuid, (unsigned long *)&cpu_callin_map[0]);
545
546
547
548 load_ldt(0);
549
550
551 local_invalidate();
552 while(!smp_commenced);
553 if (cpu_number_map[cpuid] == -1)
554 while(1);
555 local_invalidate();
556 SMP_PRINTK(("Commenced..\n"));
557
558 load_TR(cpu_number_map[cpuid]);
559
560 }
561
562
563
564
565
566 void smp_boot_cpus(void)
567 {
568 int i,j;
569 int cpucount=0;
570 unsigned long cfg;
571 void *stack;
572 extern unsigned long init_user_stack[];
573
574
575
576
577
578 for (i = 0; i < NR_CPUS; i++)
579 cpu_number_map[i] = -1;
580
581
582
583
584
585 kernel_stacks[boot_cpu_id]=(void *)init_user_stack;
586
587 smp_store_cpu_info(boot_cpu_id);
588
589 cpu_present_map |= (1 << smp_processor_id());
590 cpu_number_map[boot_cpu_id] = 0;
591 active_kernel_processor=boot_cpu_id;
592
593
594
595
596
597
598 if (!smp_found_config)
599 return;
600
601
602
603
604
605 apic_reg = vremap(apic_addr,4096);
606
607 if(apic_reg == NULL)
608 panic("Unable to map local apic.\n");
609
610 #ifdef SMP_DEBUG
611 {
612 int reg;
613
614
615
616
617
618
619
620
621 reg = apic_read(APIC_VERSION);
622 SMP_PRINTK(("Getting VERSION: %x\n", reg));
623
624 apic_write(APIC_VERSION, 0);
625 reg = apic_read(APIC_VERSION);
626 SMP_PRINTK(("Getting VERSION: %x\n", reg));
627
628
629
630
631
632
633
634
635
636
637
638
639
640 reg = apic_read(APIC_LVT0);
641 SMP_PRINTK(("Getting LVT0: %x\n", reg));
642
643 reg = apic_read(APIC_LVT1);
644 SMP_PRINTK(("Getting LVT1: %x\n", reg));
645 }
646 #endif
647
648
649
650
651
652 cfg=apic_read(APIC_SPIV);
653 cfg|=(1<<8);
654 apic_write(APIC_SPIV,cfg);
655
656 udelay(10);
657
658
659
660
661
662 SMP_PRINTK(("CPU map: %lx\n", cpu_present_map));
663
664 for(i=0;i<NR_CPUS;i++)
665 {
666
667
668
669 if (i == boot_cpu_id)
670 {
671 smp_top_cpu=max(smp_top_cpu,i);
672 continue;
673 }
674
675 if (cpu_present_map & (1 << i))
676 {
677 unsigned long send_status, accept_status;
678 int timeout, num_starts;
679
680
681
682
683
684 stack=get_kernel_stack();
685 if(stack==NULL)
686 panic("No memory for processor stacks.\n");
687 kernel_stacks[i]=stack;
688 install_trampoline(stack);
689
690 printk("Booting processor %d stack %p: ",i,stack);
691
692
693
694
695
696
697 SMP_PRINTK(("Setting warm reset code and vector.\n"));
698
699
700
701
702
703 cfg=pg0[0];
704
705 CMOS_WRITE(0xa, 0xf);
706 pg0[0]=7;
707 local_invalidate();
708 *((volatile unsigned short *) 0x469) = ((unsigned long)stack)>>4;
709 *((volatile unsigned short *) 0x467) = 0;
710
711
712
713
714
715 pg0[0]= cfg;
716 local_invalidate();
717
718
719
720
721
722 apic_write(APIC_ESR, 0);
723 accept_status = (apic_read(APIC_ESR) & 0xEF);
724
725
726
727
728
729 send_status = 0;
730 accept_status = 0;
731
732
733
734
735
736 SMP_PRINTK(("Asserting INIT.\n"));
737
738
739
740
741
742 cfg=apic_read(APIC_ICR2);
743 cfg&=0x00FFFFFF;
744 apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));
745 cfg=apic_read(APIC_ICR);
746 cfg&=~0xCDFFF;
747 cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
748 | APIC_DEST_ASSERT | APIC_DEST_DM_INIT);
749 apic_write(APIC_ICR, cfg);
750
751 udelay(200);
752 SMP_PRINTK(("Deasserting INIT.\n"));
753
754 cfg=apic_read(APIC_ICR2);
755 cfg&=0x00FFFFFF;
756 apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));
757 cfg=apic_read(APIC_ICR);
758 cfg&=~0xCDFFF;
759 cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
760 | APIC_DEST_DM_INIT);
761 apic_write(APIC_ICR, cfg);
762
763
764
765
766
767
768
769
770
771 if ( apic_version[i] & 0xF0 )
772 num_starts = 2;
773 else
774 num_starts = 0;
775
776
777
778
779
780 for (j = 0; !(send_status || accept_status)
781 && (j < num_starts) ; j++)
782 {
783 SMP_PRINTK(("Sending STARTUP #%d.\n",j));
784
785 apic_write(APIC_ESR, 0);
786
787
788
789
790
791 cfg=apic_read(APIC_ICR2);
792 cfg&=0x00FFFFFF;
793 apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));
794 cfg=apic_read(APIC_ICR);
795 cfg&=~0xCDFFF;
796 cfg |= (APIC_DEST_FIELD
797 | APIC_DEST_DM_STARTUP
798 | (((int) stack) >> 12) );
799 apic_write(APIC_ICR, cfg);
800
801 timeout = 0;
802 do {
803 udelay(10);
804 } while ( (send_status = (apic_read(APIC_ICR) & 0x1000))
805 && (timeout++ < 1000));
806 udelay(200);
807
808 accept_status = (apic_read(APIC_ESR) & 0xEF);
809 }
810
811 if (send_status)
812 printk("APIC never delivered???\n");
813 if (accept_status)
814 printk("APIC delivery error (%lx).\n", accept_status);
815
816 if( !(send_status || accept_status) )
817 {
818 for(timeout=0;timeout<50000;timeout++)
819 {
820 if(cpu_callin_map[0]&(1<<i))
821 break;
822 udelay(100);
823 }
824 if(cpu_callin_map[0]&(1<<i))
825 {
826 cpucount++;
827
828 cpu_number_map[i] = cpucount;
829 smp_top_cpu=max(smp_top_cpu,i);
830
831 }
832 else
833 {
834 if(*((volatile unsigned char *)8192)==0xA5)
835 printk("Stuck ??\n");
836 else
837 printk("Not responding.\n");
838 }
839 }
840
841
842 *((volatile unsigned long *)8192) = 0;
843 }
844
845
846
847
848
849 if (cpu_number_map[i] == -1)
850 cpu_present_map &= ~(1 << i);
851 }
852
853
854
855
856
857
858
859
860
861 cfg = pg0[0];
862 pg0[0] = 3;
863 local_invalidate();
864
865
866
867
868
869
870 CMOS_WRITE(0, 0xf);
871
872 *((volatile long *) 0x467) = 0;
873
874
875
876
877
878 pg0[0] = cfg;
879 local_invalidate();
880
881
882
883
884
885 if(cpucount==0)
886 {
887 printk("Error: only one processor found.\n");
888 cpu_present_map=(1<<smp_processor_id());
889 }
890 else
891 {
892 unsigned long bogosum=0;
893 for(i=0;i<32;i++)
894 {
895 if(cpu_present_map&(1<<i))
896 bogosum+=cpu_data[i].udelay_val;
897 }
898 printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
899 cpucount+1,
900 (bogosum+2500)/500000,
901 ((bogosum+2500)/5000)%100);
902 smp_activated=1;
903 smp_num_cpus=cpucount+1;
904 }
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921 void smp_message_pass(int target, int msg, unsigned long data, int wait)
922 {
923 unsigned long cfg;
924 unsigned long target_map;
925 int p=smp_processor_id();
926 int irq=0x2d;
927 int ct=0;
928 static volatile int message_cpu = NO_PROC_ID;
929
930
931
932
933
934 if(!smp_activated || !smp_commenced)
935 return;
936
937
938
939
940
941
942
943
944 if(msg==MSG_RESCHEDULE)
945 {
946 irq=0x30;
947 if(smp_cpu_in_msg[p])
948 return;
949 }
950
951
952
953
954
955
956
957 if(message_cpu!=NO_PROC_ID && msg!=MSG_STOP_CPU)
958 {
959 panic("CPU #%d: Message pass %d but pass in progress by %d of %d\n",
960 smp_processor_id(),msg,message_cpu, smp_msg_id);
961 }
962 message_cpu=smp_processor_id();
963
964
965
966
967
968
969 smp_cpu_in_msg[p]++;
970
971
972
973
974
975 if(msg!=MSG_RESCHEDULE)
976 {
977 smp_src_cpu=p;
978 smp_msg_id=msg;
979 smp_msg_data=data;
980 }
981
982
983
984
985
986
987
988
989
990 while(ct<1000)
991 {
992 cfg=apic_read(APIC_ICR);
993 if(!(cfg&(1<<12)))
994 break;
995 ct++;
996 udelay(10);
997 }
998
999
1000
1001
1002
1003 if(ct==1000)
1004 printk("CPU #%d: previous IPI still not cleared after 10mS", smp_processor_id());
1005
1006
1007
1008
1009
1010 cfg=apic_read(APIC_ICR2);
1011 cfg&=0x00FFFFFF;
1012 apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(target));
1013 cfg=apic_read(APIC_ICR);
1014 cfg&=~0xFDFFF;
1015 cfg|=APIC_DEST_FIELD|APIC_DEST_DM_FIXED|irq;
1016
1017
1018
1019
1020
1021 if(target==MSG_ALL_BUT_SELF)
1022 {
1023 cfg|=APIC_DEST_ALLBUT;
1024 target_map=cpu_present_map;
1025 cpu_callin_map[0]=(1<<smp_src_cpu);
1026 }
1027 else if(target==MSG_ALL)
1028 {
1029 cfg|=APIC_DEST_ALLINC;
1030 target_map=cpu_present_map;
1031 cpu_callin_map[0]=0;
1032 }
1033 else
1034 {
1035 target_map=(1<<target);
1036 cpu_callin_map[0]=0;
1037 }
1038
1039
1040
1041
1042
1043 apic_write(APIC_ICR, cfg);
1044
1045
1046
1047
1048
1049 switch(wait)
1050 {
1051 case 1:
1052 while(cpu_callin_map[0]!=target_map);
1053 break;
1054 case 2:
1055 while(smp_invalidate_needed);
1056 break;
1057 }
1058
1059
1060
1061
1062
1063 smp_cpu_in_msg[p]--;
1064 message_cpu=NO_PROC_ID;
1065 }
1066
1067
1068
1069
1070
1071
1072
1073 void smp_invalidate(void)
1074 {
1075 unsigned long flags;
1076 if(smp_activated && smp_processor_id()!=active_kernel_processor)
1077 panic("CPU #%d:Attempted invalidate IPI when not AKP(=%d)\n",smp_processor_id(),active_kernel_processor);
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 smp_invalidate_needed=cpu_present_map&~(1<<smp_processor_id());
1088
1089
1090
1091
1092
1093
1094 save_flags(flags);
1095 cli();
1096 smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0L, 2);
1097
1098
1099
1100
1101
1102 local_invalidate();
1103
1104 restore_flags(flags);
1105
1106
1107
1108
1109
1110
1111 }
1112
1113
1114
1115
1116
1117 void smp_reschedule_irq(int cpl, struct pt_regs *regs)
1118 {
1119 #ifdef DEBUGGING_SMP_RESCHED
1120 static int ct=0;
1121 if(ct==0)
1122 {
1123 printk("Beginning scheduling on CPU#%d\n",smp_processor_id());
1124 ct=1;
1125 }
1126 #endif
1127 if(smp_processor_id()!=active_kernel_processor)
1128 panic("SMP Reschedule on CPU #%d, but #%d is active.\n",
1129 smp_processor_id(), active_kernel_processor);
1130
1131 need_resched=1;
1132
1133
1134
1135
1136 apic_read(APIC_SPIV);
1137 apic_write(APIC_EOI, 0);
1138 }
1139
1140
1141
1142
1143
1144 void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs)
1145 {
1146 int i=smp_processor_id();
1147
1148
1149
1150 switch(smp_msg_id)
1151 {
1152 case 0:
1153 return;
1154
1155
1156
1157
1158
1159 case MSG_INVALIDATE_TLB:
1160 if(clear_bit(i,(unsigned long *)&smp_invalidate_needed))
1161 local_invalidate();
1162 set_bit(i, (unsigned long *)&cpu_callin_map[0]);
1163
1164 break;
1165
1166
1167
1168
1169 case MSG_STOP_CPU:
1170 while(1)
1171 {
1172 if(cpu_data[smp_processor_id()].hlt_works_ok)
1173 __asm__("hlt");
1174 }
1175 default:
1176 printk("CPU #%d sent invalid cross CPU message to CPU #%d: %X(%lX).\n",
1177 smp_src_cpu,smp_processor_id(),smp_msg_id,smp_msg_data);
1178 break;
1179 }
1180
1181
1182
1183
1184 apic_read(APIC_SPIV);
1185 apic_write(APIC_EOI, 0);
1186 }