page ,132 title MULTIPLE CPU HANDLER ;*****************************************************************; ;*****************************************************************; ;** **; ;** (C)Copyright 1985-1996, American Megatrends Inc. **; ;** **; ;** All Rights Reserved. **; ;** **; ;** 6145-F, Northbelt Parkway, Norcross, **; ;** **; ;** Georgia - 30071, USA. Phone-(770)-246-8600. **; ;** **; ;*****************************************************************; ;*****************************************************************; ;*****************************************************************; INCLUDE CPUMAC.MAC INCLUDE CPUSTRUC.DEF INCLUDE CPUEQU.EQU extrn InitCPU@Runtime :near ;*****************************************************************************; cgroup group _text _text segment word public 'CODE' assume cs:cgroup ;*****************************************************************************; .486p Public InitCPU@Shutdown InitCPU@Shutdown PROC NEAR ;-----------------------------------------------; ; SO FAR KNOWLEDGE GOES, DO NOT DO ANYTHING ; ; HERE. THIS HOOK IS MAINTAINED IF IN FUTURE ; ; WE NEED TO DO SOMETHING !!!! ; ;-----------------------------------------------; ret ;;;; jmp InitCPU@Runtime InitCPU@Shutdown ENDP ;*****************************************************************************; Public InitializeAPIC Public initialize_apic Public InitLocalApic Public DoInitAPIC InitializeAPIC PROC NEAR initialize_apic PROC NEAR mov ah,0c6h call CheckPtCPU ;==== C6 00 ================== DoInitAPIC:: push ds push cs call EnableFlatMode ; DS = 4GB limit call IncSubChkPt ;==== C6 01 ================= call InitLocalAPIC ; Initializes Local APIC push cs call DisableFlatMode ; DS = 64KB limit call IncSubChkPt ;==== C6 04 ================= pop ds ret initialize_apic ENDP InitializeAPIC ENDP InitLocalApic PROC NEAR in al,21h mov ah,al jcxz $+2 in al,0a1h push ax mov al,0ffh out 21h,al jcxz $+2 jcxz $+2 out 0a1h,al call IncSubChkPt ;==== Next sub check point ==== cli mov ebx,0fee00370h ; ERRINT reg mov eax,dword ptr[ebx] ; Read curent ERRINT reg mov al,0fh mov dword ptr[ebx],eax ; Set ERRINT to vector 0Fh mov bx,00f0h ; SVR mov eax,dword ptr[ebx] ; Read SVR data and al,0fh ; Clear SVR, use vector 00fh or ah,00000001b ; Set bit-8, Enable APIC mov dword ptr[ebx],eax ; Write SVR mov bx,0350h ; EBX = LVT1 mov eax,dword ptr[ebx] ; Read current LVT1 and eax,0fffe58ffh ; Not masked, active high, edge or ah,07h ; Enable ExtInt (IRQ0 - IRQ15) mov dword ptr[ebx],eax ; Write to LVT1 mov bl,60h ; EBX = LVT2 mov eax,dword ptr[ebx] ; Read current LVT2 and eax,0fffe58ffh ; Not masked, active high, edge or eax,0fffe0400h ; Enable NMI mov dword ptr[ebx],eax ; Write to LVT2 call IncSubChkPt ;==== Next sub check point ==== pop ax out 0a1h,al jcxz $+2 jcxz $+2 mov al,ah out 21h,al ret InitLocalApic ENDP ;*****************************************************************************; Public CheckPtCPU CheckPtCPU PROC NEAR push ax push dx mov dx,80h mov al,0 out dx,ax pop dx pop ax ret CheckPtCPU ENDP ;-----------------------------------------------------------------------------; Public IncSubChkPt IncSubChkPt PROC NEAR push ax push dx mov dx,80h in ax,dx inc al out dx,ax pop dx pop ax ret IncSubChkPt ENDP ;*****************************************************************************; ;*****************************************************************************; ;***************** **************************; ;***************** MP Library Routines **************************; ;***************** **************************; ;*****************************************************************************; ;*****************************************************************************; Public InitAP InitAP PROC NEAR ret InitAP ENDP ;-----------------------------------------------------------------------------; Public WakeUpAP WakeUpAP PROC NEAR PASCAL routx:dword, sseg:word ret WakeUpAP ENDP ;-----------------------------------------------------------------------------; Public SpinLockBSP SpinLockBSP PROC NEAR PASCAL mpseg:word ret SpinLockBSP ENDP ;-----------------------------------------------------------------------------; Public SpinLockAP SpinLockAP PROC NEAR ret SpinLockAP ENDP ;-----------------------------------------------------------------------------; Public BeginLockSection BeginLockSection PROC NEAR ret BeginLockSection ENDP ;-----------------------------------------------------------------------------; Public EndLockSection EndLockSection PROC NEAR ret EndLockSection ENDP ;*****************************************************************************; ;*****************************************************************************; ;*****************************************************************************; ;******** ********; ;******** FLAT MODE ACCESS ROUTINES ********; ;******** ********; ;*****************************************************************************; ;*****************************************************************************; ;*****************************************************************************; extrn enable_8042_bit_20 :near extrn enable_addr_bit_20 :near extrn disable_8042_bit_20 :near extrn disable_addr_bit_20 :near ;-----------------------------------------------------------------------------; ; ENABLE FLAT MODE ; ;-----------------------------------------------------------------------------; ; Enables Processors flat mode for DS ; ; Input : none ; ; Output : DS = 0, DS selector limit = 4GB ; ; Reg use : does not destroy any register except DS ; ;-----------------------------------------------------------------------------; Public EnableFlatMode EnableFlatMode PROC NEAR push ax push dx mov dl,1 ; 4GB limit call SetLimitToDS ; Set segment limit as 4GB xor ax,ax ; Real mode segment val = 0 mov ds,ax ; DS = 0, but limit is 4GB pop dx pop ax retf EnableFlatMode ENDP ;-----------------------------------------------------------------------------; ; DISABLE FLAT MODE ; ;-----------------------------------------------------------------------------; ; Enables Processors flat mode for DS ; ; Input : none ; ; Output : DS = 0, DS selector limit = 4GB ; ; Reg use : does not destroy any register except DS ; ;-----------------------------------------------------------------------------; Public DisableFlatMode DisableFlatMode PROC NEAR push dx mov dl,0 ; 64KB limit call SetLimitToDS ; Set segment limit as 4GB call disable_8042_bit_20 ; Disable GateA20 line pop dx retf DisableFlatMode ENDP ;-----------------------------------------------------------------------------; ; SET LIMIT TO DS ; ;-----------------------------------------------------------------------------; ; Sets the segment limit to DS register ; ; Input : DL = 0: 64KB limit ; ; 1: 4GB limit ; ; Output : none ; ; Reg use : does not destroy any register ; ;-----------------------------------------------------------------------------; SetLimitToDS: pushf push eax push ebx cli ; Disable interrupt mov al,8dh out 70h,al ; Disable NMI xor eax,eax xor ebx,ebx mov ax,cs shl eax,4 mov bx,offset FlatGDT add eax,ebx ; EAX = 32 bit linear address mov bx,offset GDTDesc mov cs:[bx].PSEUDODESCSTRUC.dGDTaddr,eax call enable_8042_bit_20 ; Enable GateA20 line lgdt cs:fword ptr GDTDesc ; Load GDTR mov eax,cr0 or al,01 ; Enable protected mode mov cr0,eax ; Write to control reg0 jmp pm_flush_queue pm_flush_queue: mov ax,(offset DataDesc4GB - offset FlatGDT) or dl,dl ; 4GB limit ? jnz ok_limit ; Yes.. mov ax,(offset DataDesc64KB - offset FlatGDT) ok_limit: mov ds,ax ; DS = data desc, 4GB limit mov eax,cr0 and al,0feh ; Disable protected mode mov cr0,eax ; Write to CR0 jmp rm_flush_queue rm_flush_queue: pop ebx pop eax popf ret ;*****************************************************************************; ;* *; ;* PERMANENT DATA AREA *; ;* *; ;*****************************************************************************; ;---------------------------------------; ; Definition of Descriptors ; ;---------------------------------------; DESCSTRUC STRUCT wLimit0_15 word ? ; Segment limit (A0 - A15) wBase0_15 word ? ; Base address (A0 - A15) bBase16_23 byte ? ; Base address (A16 - A23) bAtribute byte ? ; Defines attribute of the seg bLimit16_19 byte ? ; Granularity/seg limit 16-19 bBase24_31 byte ? ; Base address (A24 - A31) DESCSTRUC ENDS PSEUDODESCSTRUC STRUCT wGDTLimit word ? ; Current GDT limit dGDTaddr dword ? ; GDT 32-bit address PSEUDODESCSTRUC ENDS ;---------------------------------------; ; Descriptor Flag EQUATES ; ;---------------------------------------; Accessed EQU 00000001b ; Segment is accessed Writable EQU 00000010b ; Segment is writable (data) Readable EQU 00000010b ; Segment is readable (code) ExpandDown EQU 00000100b ; Segment is expand-down mode DPL0 EQU 00000000b ; Descriptor Previlage level-0 DPL1 EQU 00100000b ; Descriptor Previlage level-1 DPL2 EQU 01000000b ; Descriptor Previlage level-2 DPL3 EQU 01100000b ; Descriptor Previlage level-3 Available EQU 00010000b ; Segment available for system Big EQU 01000000b ; Big mode (32bit operand) on Granularity4K EQU 10000000b ; Segment limit = 4GB ;---------------------------------------; ; GLOBAL DESCRIPTOR TABLE ; ;---------------------------------------; ; Format of this table : ; ; -------------------- ; ; ; ; 1st entry : Null descriptor ; ; 2nd entry : GDT descriptor ; ; 3rd entry : Code seg descriptor ; ; 4th entry : Data seg descriptor ; ; 5th entry : Stack seg descriptor ; ;---------------------------------------; even FlatGDT: NullDesc DESCSTRUC {0,0,0,0,0,0} DataDesc4GB DESCSTRUC {\ 0ffffh, 0000h, 00h, (90h or DPL0 or Writable), (0fh or Granularity4K), 00h\ } DataDesc64KB DESCSTRUC {\ 0ffffh, 0000h, 00h, (90h or DPL0 or Writable), 00h, 00h\ } FlatGDTEnd: ;-----------------------------------------------------------------------------; GDTDesc PSEUDODESCSTRUC {\ (offset FlatGDTEnd - offset FlatGDT), 00000000h\ } ;*****************************************************************; ;*****************************************************************; ;** **; ;** (C)Copyright 1985-1996, American Megatrends Inc. **; ;** **; ;** All Rights Reserved. **; ;** **; ;** 6145-F, Northbelt Parkway, Norcross, **; ;** **; ;** Georgia - 30071, USA. Phone-(770)-246-8600. **; ;** **; ;*****************************************************************; ;*****************************************************************; _text ends end