summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/haloli/i386/oliproca.asm
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/haloli/i386/oliproca.asm')
-rw-r--r--private/ntos/nthals/haloli/i386/oliproca.asm478
1 files changed, 478 insertions, 0 deletions
diff --git a/private/ntos/nthals/haloli/i386/oliproca.asm b/private/ntos/nthals/haloli/i386/oliproca.asm
new file mode 100644
index 000000000..6e72e8efe
--- /dev/null
+++ b/private/ntos/nthals/haloli/i386/oliproca.asm
@@ -0,0 +1,478 @@
+ title "MP primitives for Compaq SystemPro"
+;++
+;
+;Copyright (c) 1991 Microsoft Corporation
+;
+;Module Name:
+;
+; oliproca.asm
+;
+;Abstract:
+;
+; SystemPro Start Next Processor assemble code
+;
+; This module along with mpspro.c implement the code to start
+; off the second processor on the Compaq SystemPro.
+;
+;Author:
+;
+; Ken Reneris (kenr) 12-Jan-1992
+;
+; Bruno Sartirana (o-obruno) 3-Mar-92
+; Added support for the Olivetti LSX5030.
+;
+;Revision History:
+;
+;--
+
+
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc
+include i386\kimacro.inc
+include mac386.inc
+;LSX5030 start
+include i386\ix8259.inc
+include i386\olimp.inc
+;LSX5030 end
+ .list
+
+ EXTRNP _HalpBuildTiledCR3,1
+ EXTRNP _HalpFreeTiledCR3,0
+
+ extrn _MppIDT:DWORD
+ extrn _MpLowStub:DWORD
+ extrn _MpLowStubPhysicalAddress:DWORD
+ extrn ProcessorControlPort:WORD
+;LSX5030 start
+ extrn _CpuLeft:DWORD
+ extrn _NextCpuToStart:DWORD
+ extrn DbgDelay:DWORD
+;LSX5030 end
+
+
+;
+; Internal defines and structures
+;
+
+PxParamBlock struc
+ SPx_flag dd ?
+ SPx_TiledCR3 dd ?
+ SPx_P0EBP dd ?
+ SPx_ControlPort dd ?
+ SPx_PB db processorstatelength dup (?)
+PxParamBlock ends
+
+
+_TEXT SEGMENT PARA PUBLIC 'CODE' ; Start 32 bit code
+ ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
+
+;++
+;
+; BOOLEAN
+; HalStartNextProcessor (
+; IN PLOADER_BLOCK pLoaderBlock,
+; IN PKPROCESSOR_STATE pProcessorState
+; )
+;
+; Routine Description:
+;
+; This routine is called by the kernel durning kernel initialization
+; to obtain more processors. It is called until no more processors
+; are available.
+;
+; If another processor exists this function is to initialize it to
+; the passed in processorstate structure, and return TRUE.
+;
+; If another processor does not exists, then a FALSE is returned.
+;
+; Also note that the loader block has been setup for the next processor.
+; The new processor logical thread number can be obtained from it, if
+; required.
+;
+; Arguments:
+; pLoaderBlock, - Loader block which has been intialized for the
+; next processor.
+;
+; pProcessorState - The processor state which is to be loaded into
+; the next processor.
+;
+;
+; Return Value:
+;
+; TRUE - ProcessorNumber was dispatched.
+; FALSE - A processor was not dispatched. no other processors exists.
+;
+;--
+
+pLoaderBlock equ dword ptr [ebp+8] ; zero based
+pProcessorState equ dword ptr [ebp+12]
+
+;
+; Local variables
+;
+
+PxFrame equ [ebp - size PxParamBlock]
+
+
+cPublicProc _HalStartNextProcessor ,2
+ push ebp ; save ebp
+ mov ebp, esp ;
+
+ sub esp, size PxParamBlock ; Make room for local vars
+
+ DBG_DISPLAY 0f0h
+
+ push esi
+ push edi
+ push ebx
+
+ xor eax, eax
+ mov PxFrame.SPx_flag, eax
+
+ cmp _CpuLeft, eax
+ je snp_exit ; exit FALSE
+
+ mov esi, OFFSET FLAT:StartPx_RMStub
+ mov ecx, StartPx_RMStub_Len
+ mov edi, _MpLowStub ; Copy RMStub to low memory
+ add edi, size PxParamBlock
+ rep movsb
+
+ lea edi, PxFrame.SPx_PB
+ mov esi, pProcessorState
+ mov ecx, processorstatelength ; Copy processorstate
+ rep movsb ; to PxFrame
+
+
+ stdCall _HalpBuildTiledCR3,<pProcessorState>
+
+ mov PxFrame.SPx_TiledCR3, eax
+ mov PxFrame.SPx_P0EBP, ebp
+
+ mov eax, pLoaderBlock ; lookup processor # we are
+ mov eax, [eax].LpbPrcb ; starting
+ movzx eax, byte ptr [eax].PbNumber
+ movzx edx, ProcessorControlPort[eax*2] ; Get processor's control port
+ mov PxFrame.SPx_ControlPort, edx ; Pass it along
+
+ mov ecx, size PxParamBlock ; copy param block
+ lea esi, PxFrame ; to low memory stub
+ mov edi, _MpLowStub
+ mov eax, edi
+ rep movsb
+
+ add eax, size PxParamBlock
+ mov ebx, OFFSET FLAT:StartPx_RMStub
+ sub eax, ebx ; (eax) = adjusted pointer
+ mov bx, word ptr [PxFrame.SPx_PB.PsContextFrame.CsSegCs]
+ mov [eax.SPrxFlatCS], bx ; patch realmode stub with
+ mov [eax.SPrxPMStub], offset _StartPx_PMStub ; valid long jump
+
+ mov ebx, _MppIDT
+ add ebx, WarmResetVector
+
+ cli
+ push dword ptr [ebx] ; Save current vector
+
+ mov eax, _MpLowStubPhysicalAddress
+ shl eax, 12 ; seg:0
+ add eax, size PxParamBlock
+ mov dword ptr [ebx], eax ; start Px here
+
+;LSX5030 start
+ mov eax, _NextCpuToStart
+ mov dx, word ptr ProcessorControlPort[eax*2]
+ in al, dx
+ or al, RESET ; assert RESET
+ out dx, al
+ and al, not RESET ; the 1-0 transition of PCR
+ ; reset bit resets the
+ ; processor
+ out dx, al ; reset processor
+;LSX5030 end
+
+@@:
+ cmp PxFrame.SPx_flag, 0 ; wait for Px to get it's
+ jz @b ; info
+
+ pop dword ptr [ebx] ; restore WarmResetVector
+
+ sti
+
+ stdCall _HalpFreeTiledCR3 ; free memory used for tiled
+ ; CR3
+
+;LSX5030 start
+ DBG_DISPLAY 0ffh
+
+ dec _CpuLeft ; one less
+ inc _NextCpuToStart ; next CPU # to start
+;LSX5030 end
+
+ mov eax, 1 ; return TRUE
+
+snp_exit:
+ DBG_DISPLAY 0feh
+ pop ebx
+ pop edi
+ pop esi
+ mov esp, ebp
+ pop ebp
+ stdRET _HalStartNextProcessor
+
+_HalStartNextProcessor endp
+
+
+_TEXT ends ; end 32 bit code
+
+
+_TEXT16 SEGMENT DWORD PUBLIC USE16 'CODE' ; start 16 bit code
+
+
+;++
+;
+; VOID
+; StartPx_RMStub
+;
+; Routine Description:
+;
+; When a new processor is started, it starts in real-mode and is
+; sent to a copy of this function which has been copied into low memory.
+; (below 1m and accessable from real-mode).
+;
+; Once CR0 has been set, this function jmp's to a StartPx_PMStub
+;
+; Arguments:
+; none
+;
+; Return Value:
+; does not return, jumps to StartPx_PMStub
+;
+;--
+cPublicProc StartPx_RMStub,0
+ cli
+
+ db 066h ; load the GDT
+ lgdt fword ptr cs:[SPx_PB.PsSpecialRegisters.SrGdtr]
+
+ db 066h ; load the IDT
+ lidt fword ptr cs:[SPx_PB.PsSpecialRegisters.SrIdtr]
+
+ mov eax, cs:[SPx_TiledCR3]
+ mov cr3, eax
+
+ mov ebp, dword ptr cs:[SPx_P0EBP]
+ mov ecx, dword ptr cs:[SPx_PB.PsContextFrame.CsSegDs]
+ mov ebx, dword ptr cs:[SPx_PB.PsSpecialRegisters.SrCr3]
+ mov eax, dword ptr cs:[SPx_PB.PsSpecialRegisters.SrCr0]
+
+ mov cr0, eax ; into prot mode
+
+ db 066h
+ db 0eah ; reload cs:eip
+SPrxPMStub dd 0
+SPrxFlatCS dw 0
+
+StartPx_RMStub_Len equ $ - StartPx_RMStub
+stdENDP StartPx_RMStub
+
+
+_TEXT16 ends ; End 16 bit code
+
+_TEXT SEGMENT ; Start 32 bit code
+
+
+;++
+;
+; VOID
+; StartPx_PMStub
+;
+; Routine Description:
+;
+; This function completes the processor's state loading, and signals
+; the requesting processor that the state has been loaded.
+;
+; Arguments:
+; ebx - requested CR3 for this processors_state
+; cx - requested ds for this processors_state
+; ebp - EBP of P0
+;
+; Return Value:
+; does not return - completes the loading of the processors_state
+;
+;--
+ align 16 ; to make sure we don't cross a page boundry
+ ; before reloading CR3
+
+ public _StartPx_PMStub
+_StartPx_PMStub proc
+
+ ; process is now in the load image copy of this function.
+ ; (ie, it's not the low memory copy)
+
+ mov cr3, ebx ; get real CR3
+ mov ds, cx ; set real ds
+
+ lea esi, PxFrame.SPx_PB.PsSpecialRegisters
+
+ lldt word ptr ds:[esi].SrLdtr ; load ldtr
+ ltr word ptr ds:[esi].SrTr ; load tss
+
+ lea edi, PxFrame.SPx_PB.PsContextFrame
+ mov es, word ptr ds:[edi].CsSegEs ; Set other selectors
+ mov fs, word ptr ds:[edi].CsSegFs
+ mov gs, word ptr ds:[edi].CsSegGs
+ mov ss, word ptr ds:[edi].CsSegSs
+
+ add esi, SrKernelDr0
+ .errnz (SrKernelDr1 - SrKernelDr0 - 1 * 4)
+ .errnz (SrKernelDr2 - SrKernelDr0 - 2 * 4)
+ .errnz (SrKernelDr3 - SrKernelDr0 - 3 * 4)
+ .errnz (SrKernelDr6 - SrKernelDr0 - 4 * 4)
+ .errnz (SrKernelDr7 - SrKernelDr0 - 5 * 4)
+ lodsd
+ mov dr0, eax ; load dr0-dr7
+ lodsd
+ mov dr1, eax
+ lodsd
+ mov dr2, eax
+ lodsd
+ mov dr3, eax
+ lodsd
+ mov dr6, eax
+ lodsd
+ mov dr7, eax
+
+ mov esp, dword ptr ds:[edi].CsEsp
+ mov esi, dword ptr ds:[edi].CsEsi
+ mov ecx, dword ptr ds:[edi].CsEcx
+
+ push dword ptr ds:[edi].CsEflags
+ popfd ; load eflags
+
+ push dword ptr ds:[edi].CsEip ; make a copy of remaining
+ push dword ptr ds:[edi].CsEax ; registers which need
+ push dword ptr ds:[edi].CsEbx ; loaded
+ push dword ptr ds:[edi].CsEdx
+ push dword ptr ds:[edi].CsEdi
+ push dword ptr ds:[edi].CsEbp
+
+
+ ; eax, ebx, edx are still free
+
+;LSX5030 start
+ mov eax, _NextCpuToStart
+ mov dx, word ptr ProcessorControlPort[eax*2]
+ in al, dx ; Get register
+ and al, not IPI_EN ; disable PINTs for now
+ out dx, al
+ ;and dx, Px_SLOT_MASK ; get processor slot (olibus)
+ ;or dx, LEV2_CACHE_REG ; calculate address of the 2nd
+ ; level cache policy register
+ ; for this processor
+ ;in al, dx ; Get register
+ ;and al, not LEV2_CACHE_ON ; turn cache off
+ ;or al, LEV2_CACHE_ON ; turn cache on
+ ;out dx, al
+ ;and dx, Px_SLOT_MASK ; get processor slot (olibus)
+ ;or dx, SLOT_CONFIG_REG_0 ; calculate address of
+ ; configuration register 0 for
+ ; this processor
+ ;in al, dx ; get register
+ ;and al, not INTERNAL_CACHE_ON ; turn internal cache off
+ ;or al, INTERNAL_CACHE_ON ; turn processor's internal
+ ; cache on
+ ;out dx, al
+
+ ;DBG_DISPLAY 0b0h
+
+; sti
+
+ inc [PxFrame.SPx_flag] ; Signal p0 that we are
+ ; done with its data
+ ;DBG_DISPLAY 0bfh
+
+;LSX5030 end
+
+ ; Set remaining registers
+ pop ebp
+ pop edi
+ pop edx
+ pop ebx
+ pop eax
+ ret ; Set eip
+
+_StartPx_PMStub endp
+
+;LSX5030 start
+;++
+;
+; ULONG
+; HalpGetNumberOfProcessors()
+;
+; Routine Description:
+;
+; This routine queries the CMOS to determine the number of processors
+; that can be started.
+; Also, it rearranges the ProcessorControlPort array to make it
+; non-sparse. This means that, eventually, ProcessorControlPort[n]
+; will contain the slot # of the processor n, where n=0,1,2,3.
+; For example, if the machine has two processors, one in slot 0 and
+; the other in slot 3, only the ProcessorControlPort array elements
+; #0 and #1 will be meaningful.
+;
+; Arguments:
+;
+; None.
+;
+; Return Value:
+;
+; The number of available processors in register eax.
+;
+;--
+
+cPublicProc _HalpGetNumberOfProcessors,0
+
+
+ push ebx
+ push ecx
+ push edx
+ mov al, CMOS_GET_MP_STATUS
+ CMOS_READ
+ mov ch, al ; al[7-4] = CPU card present bits
+ ; al[3-0] = CPU diagnostics passed bits
+ shr al, 4 ; al[3-0] = CPU card present bits
+ mov cl, al ; ch[3-0] = CPU card diag passed bits
+ ; cl[3-0] = CPU card present bits
+ and cl, ch ; CPUs actually available (bit mapped)
+
+ mov edx, 1 ; there's always the CPU0, so skip it
+ mov eax, 1 ; logical processor #
+NextCPU:
+ bt ecx, edx
+ jnc IncLoopCounter
+ mov bx, word ptr ProcessorControlPort[edx*2] ; get address of
+ ; PCP #edx
+ mov word ptr ProcessorControlPort[eax*2], bx ; set PCP address
+ ; for processor #eax
+ inc eax
+IncLoopCounter:
+ inc edx
+ cmp edx, MAX_NUMBER_PROCESSORS
+ jl NextCPU
+
+ pop edx
+ pop ecx
+ pop ebx
+
+ stdRET _HalpGetNumberOfProcessors
+
+stdENDP _HalpGetNumberOfProcessors
+
+;LSX5030 end
+
+_TEXT ends ; end 32 bit code
+ end