66 asm("mov eax, [ecx] "); |
66 asm("mov eax, [ecx] "); |
67 asm("atomic_set: "); |
67 asm("atomic_set: "); |
68 asm("mov edx, eax "); |
68 asm("mov edx, eax "); |
69 asm("cmp eax, 0 "); |
69 asm("cmp eax, 0 "); |
70 asm("jnz short atomic_set_1 "); |
70 asm("jnz short atomic_set_1 "); |
71 asm("mov edx, [%a0]" : : "i" (&TheScheduler.iActiveCpus1)); |
71 asm("mov edx, [%a0]" : : "i" (&TheScheduler.iIpiAcceptCpus)); |
72 asm("shl edx, 16 "); |
72 asm("shl edx, 16 "); |
73 asm("atomic_set_1: "); |
73 asm("atomic_set_1: "); |
74 asm("or edx, [esi+%0]" : : "i" _FOFF(TSubScheduler,iCpuMask)); |
74 asm("or edx, [esi+%0]" : : "i" _FOFF(TSubScheduler,iCpuMask)); |
75 asm("lock cmpxchg [ecx], edx "); |
75 asm("lock cmpxchg [ecx], edx "); |
76 asm("jne short atomic_set "); |
76 asm("jne short atomic_set "); |
88 asm("crash_halt: "); |
88 asm("crash_halt: "); |
89 asm("hlt "); |
89 asm("hlt "); |
90 asm("jmp short crash_halt "); |
90 asm("jmp short crash_halt "); |
91 |
91 |
92 asm("first_to_crash: "); |
92 asm("first_to_crash: "); |
93 asm("mov ebp, [esi+60+%0]" : : "i" _FOFF(TSubScheduler,iExtras)); // points to SCpuData |
93 asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler,iSSX.iTss)); // points to SCpuData |
94 asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData,iRegs)); |
94 asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData,iRegs)); |
95 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEsi)); |
95 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEsi)); |
96 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEbp)); |
96 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEbp)); |
97 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEax)); |
97 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEax)); |
98 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEdx)); |
98 asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEdx)); |
109 asm("mov [eax+4], ds "); |
109 asm("mov [eax+4], ds "); |
110 asm("mov [eax+8], es "); |
110 asm("mov [eax+8], es "); |
111 asm("mov [eax+12], fs "); |
111 asm("mov [eax+12], fs "); |
112 asm("mov [eax+16], gs "); |
112 asm("mov [eax+16], gs "); |
113 asm("mov [eax+20], ss "); |
113 asm("mov [eax+20], ss "); |
114 asm("lea ebx, [esi+52+%0]" : : "i" _FOFF(TSubScheduler,iExtras)); // points to i_IrqNestCount |
114 asm("lea ebx, [esi+%0]" : : "i" _FOFF(TSubScheduler,iSSX.iIrqNestCount)); |
115 asm("mov eax, 0x80000000 "); |
115 asm("mov eax, 0x80000000 "); |
116 asm("lock xchg eax, [ebx] "); |
116 asm("lock xchg eax, [ebx] "); |
117 asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet,iIrqNestCount)); |
117 asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet,iIrqNestCount)); |
118 |
118 |
119 // send NMI to every other processor |
119 // send NMI to every other processor |
135 asm("cli "); |
135 asm("cli "); |
136 asm("mov eax, [esi+%0] " : : "i" _FOFF(TSubScheduler,iCpuMask)); |
136 asm("mov eax, [esi+%0] " : : "i" _FOFF(TSubScheduler,iCpuMask)); |
137 asm("not eax "); |
137 asm("not eax "); |
138 asm("mov edx, %0": :"i" (addressof_CrashState)); |
138 asm("mov edx, %0": :"i" (addressof_CrashState)); |
139 asm("lock and [edx+2], ax "); |
139 asm("lock and [edx+2], ax "); |
140 asm("mov dword ptr [esi+44+%0], 1" : : "i" _FOFF(TSubScheduler, iExtras)); // flag that this CPU is done |
140 asm("mov dword ptr [esi+%0], 1" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState)); // flag that this CPU is done |
141 asm("xor ecx, ecx "); |
141 asm("xor ecx, ecx "); |
142 asm("wait_other_cpus: "); |
142 asm("wait_other_cpus: "); |
143 asm("mov ax, [edx+2] "); |
143 asm("mov ax, [edx+2] "); |
144 asm("cmp ax, 0 "); |
144 asm("cmp ax, 0 "); |
145 asm("jz short wait_other_cpus_done "); |
145 asm("jz short wait_other_cpus_done "); |