--- /dev/null
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2013-2015 Intel Corporation.\r
+;\r
+; This program and the accompanying materials\r
+; are licensed and made available under the terms and conditions of the BSD License\r
+; which accompanies this distribution. The full text of the license may be found at\r
+; http://opensource.org/licenses/bsd-license.php\r
+;\r
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+; Flat32.asm\r
+;\r
+; Abstract:\r
+;\r
+; This is the code that goes from real-mode to protected mode.\r
+; It consumes the reset vector, configures the stack.\r
+;\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+\r
+;\r
+; Define assembler characteristics\r
+;\r
+.586p\r
+.model flat, c\r
+\r
+;\r
+; Include processor definitions\r
+;\r
+\r
+INCLUDE Platform.inc\r
+\r
+\r
+;\r
+; CR0 cache control bit definition\r
+;\r
+CR0_CACHE_DISABLE EQU 040000000h\r
+CR0_NO_WRITE EQU 020000000h\r
+\r
+;\r
+; External and public declarations\r
+; TopOfStack is used by C code\r
+; SecStartup is the entry point to the C code\r
+; Neither of these names can be modified without\r
+; updating the C code.\r
+;\r
+EXTRN PlatformSecLibStartup: NEAR\r
+EXTERNDEF C PcdGet32 (PcdEsramStage1Base):DWORD\r
+\r
+;\r
+; Contrary to the name, this file contains 16 bit code as well.\r
+;\r
+_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE'\r
+ ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: _ModuleEntryPoint\r
+;\r
+; Input: None\r
+;\r
+; Output: None\r
+;\r
+; Destroys: Assume all registers\r
+;\r
+; Description:\r
+;\r
+; Transition to non-paged flat-model protected mode from a\r
+; hard-coded GDT that provides exactly two descriptors.\r
+; This is a bare bones transition to protected mode only\r
+; used for a while in PEI and possibly DXE.\r
+;\r
+; After enabling protected mode, a far jump is executed to\r
+; transfer to PEI using the newly loaded GDT.\r
+;\r
+; Return: None\r
+;\r
+;----------------------------------------------------------------------------\r
+align 16\r
+_ModuleEntryPoint PROC C PUBLIC\r
+\r
+ ;\r
+ ; Warm Reset (INIT#) check.\r
+ ;\r
+ mov si, 0F000h\r
+ mov ds, si\r
+ mov si, 0FFF0h\r
+ cmp BYTE PTR [si], 0EAh ; Is it warm reset ?\r
+ jne NotWarmReset ; JIf not.\r
+\r
+ mov al, 08\r
+ mov dx, 0cf9h\r
+ out dx, al\r
+ mov al, 055h\r
+ out 080h, al;\r
+ jmp $\r
+NotWarmReset:\r
+\r
+ ;\r
+ ; Load the GDT table in GdtDesc\r
+ ;\r
+ mov esi, OFFSET GdtDesc\r
+ db 66h\r
+ lgdt fword ptr cs:[si]\r
+\r
+ ;\r
+ ; Transition to 16 bit protected mode\r
+ ;\r
+ mov eax, cr0 ; Get control register 0\r
+ or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1)\r
+ mov cr0, eax ; Activate protected mode\r
+\r
+ ;\r
+ ; Now we're in 16 bit protected mode\r
+ ; Set up the selectors for 32 bit protected mode entry\r
+ ;\r
+ mov ax, SYS_DATA_SEL\r
+ mov ds, ax\r
+ mov es, ax\r
+ mov fs, ax\r
+ mov gs, ax\r
+ mov ss, ax\r
+\r
+ ;\r
+ ; Transition to Flat 32 bit protected mode\r
+ ; The jump to a far pointer causes the transition to 32 bit mode\r
+ ;\r
+ mov esi, offset ProtectedModeEntryLinearAddress\r
+ jmp fword ptr cs:[si]\r
+\r
+_ModuleEntryPoint ENDP\r
+\r
+_TEXT_REALMODE ENDS\r
+\r
+.code\r
+;\r
+; Protected mode portion initializes stack, configures cache, and calls C entry point\r
+;\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: ProtectedModeEntryPoint\r
+;\r
+; Input: Executing in 32 Bit Protected (flat) mode\r
+; cs: 0-4GB\r
+; ds: 0-4GB\r
+; es: 0-4GB\r
+; fs: 0-4GB\r
+; gs: 0-4GB\r
+; ss: 0-4GB\r
+;\r
+; Output: This function never returns\r
+;\r
+; Destroys:\r
+; ecx\r
+; edi\r
+; esi\r
+; esp\r
+;\r
+; Description:\r
+; Perform any essential early platform initilaisation\r
+; Setup a stack\r
+; Call the main EDKII Sec C code\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+ProtectedModeEntryPoint PROC NEAR C PUBLIC\r
+\r
+ JMP32 stackless_EarlyPlatformInit\r
+\r
+ ;\r
+ ; Set up stack pointer\r
+ ;\r
+ mov esp, PcdGet32(PcdEsramStage1Base)\r
+ mov esi, QUARK_ESRAM_MEM_SIZE_BYTES\r
+ add esp, esi ; ESP = top of stack (stack grows downwards).\r
+\r
+ ;\r
+ ; Store the the BIST value in EBP\r
+ ;\r
+ mov ebp, 00h ; No processor BIST on Quark\r
+\r
+ ;\r
+ ; Push processor count to stack first, then BIST status (AP then BSP)\r
+ ;\r
+ mov eax, 1\r
+ cpuid\r
+ shr ebx, 16\r
+ and ebx, 0000000FFh\r
+ cmp bl, 1\r
+ jae PushProcessorCount\r
+\r
+ ;\r
+ ; Some processors report 0 logical processors. Effectively 0 = 1.\r
+ ; So we fix up the processor count\r
+ ;\r
+ inc ebx\r
+\r
+PushProcessorCount:\r
+ push ebx\r
+\r
+ ;\r
+ ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST\r
+ ; for all processor threads\r
+ ;\r
+ xor ecx, ecx\r
+ mov cl, bl\r
+PushBist:\r
+ push ebp\r
+ loop PushBist\r
+\r
+ ;\r
+ ; Pass Control into the PEI Core\r
+ ;\r
+ call PlatformSecLibStartup\r
+\r
+ ;\r
+ ; PEI Core should never return to here, this is just to capture an invalid return.\r
+ ;\r
+ jmp $\r
+\r
+ProtectedModeEntryPoint ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: stackless_EarlyPlatformInit\r
+;\r
+; Input: esp - Return address\r
+;\r
+; Output: None\r
+;\r
+; Destroys:\r
+; eax\r
+; ecx\r
+; dx\r
+; ebp\r
+;\r
+; Description:\r
+; Any essential early platform initialisation required:\r
+; (1) Disable Cache\r
+; (2) Disable NMI's/SMI's\r
+; (3) Setup HMBOUND (defines what memory accesses go to MMIO/RAM)\r
+; (4) Setup eSRAM (provide early memory to the system)\r
+; (5) Setup PCIEXBAR access mechanism\r
+; (6) Open up full SPI flash decode\r
+;\r
+;----------------------------------------------------------------------------\r
+stackless_EarlyPlatformInit PROC NEAR C PUBLIC\r
+\r
+ ;\r
+ ; Save return address\r
+ ;\r
+ mov ebp, esp\r
+\r
+ ;\r
+ ; Ensure cache is disabled.\r
+ ;\r
+ mov eax, cr0\r
+ or eax, CR0_CACHE_DISABLE + CR0_NO_WRITE\r
+ invd\r
+ mov cr0, eax\r
+\r
+ ;\r
+ ; Disable NMI\r
+ ; Good convention suggests you should read back RTC data port after\r
+ ; accessing the RTC index port.\r
+ ;\r
+ mov al, NMI_DISABLE\r
+ mov dx, RTC_INDEX\r
+ out dx, al\r
+ mov dx, RTC_DATA\r
+ in al, dx\r
+\r
+ ;\r
+ ; Disable SMI (Disables SMI wire, not SMI messages)\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, NOT (SMI_EN)\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMISC2_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ ;\r
+ ; Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGNONSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, FORCE_WARM_RESET\r
+ jz TestForceColdReset ; Zero means bit clear, we're not requested to warm reset so continue as normal\r
+ jmp IssueWarmReset\r
+\r
+TestForceColdReset:\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_W1_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, FORCE_COLD_RESET\r
+ jz TestHmboundLock ; Zero means bit clear, we're not requested to cold reset so continue as normal\r
+ jmp IssueColdReset\r
+\r
+ ;\r
+ ; Before setting HMBOUND, check it's not locked\r
+ ;\r
+TestHmboundLock:\r
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, HMBOUND_LOCK\r
+ jz ConfigHmbound ; Zero means bit clear, we have the config we want so continue as normal\r
+ ;\r
+ ; Failed to config - store sticky bit debug\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ or eax, RESET_FOR_HMBOUND_LOCK ; Set the bit we're interested in\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+ jmp IssueWarmReset\r
+\r
+ ;\r
+ ; Set up the HMBOUND register\r
+ ;\r
+ConfigHmbound:\r
+ mov eax, HMBOUND_ADDRESS ; Data (Set HMBOUND location)\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HMBOUND_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ ;\r
+ ; Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs.\r
+ ;\r
+ mov eax, ENABLE_IMR_INTERRUPT ; Data (Set interrupt enable mask)\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (BIMRVCTL_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ ;\r
+ ; Set eSRAM address\r
+ ;\r
+ mov eax, PcdGet32 (PcdEsramStage1Base) ; Data (Set eSRAM location)\r
+ shr eax, 18h ; Data (Set eSRAM location)\r
+ add eax, BLOCK_ENABLE_PG\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+ ;\r
+ ; Check that we're not blocked from setting the config that we want.\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (MEMORY_MANAGER_PORT_ID SHL SB_PORT_FIELD) OR (ESRAMPGCTRL_BLOCK_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, BLOCK_ENABLE_PG\r
+ jnz ConfigPci ; Non-zero means bit set, we have the config we want so continue as normal\r
+ ;\r
+ ; Failed to config - store sticky bit debug\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_READ SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ or eax, RESET_FOR_ESRAM_LOCK ; Set the bit we're interested in\r
+ mov ecx, (OPCODE_SIDEBAND_ALT_REG_WRITE SHL SB_OPCODE_FIELD) OR (SOC_UNIT_PORT_ID SHL SB_PORT_FIELD) OR (CFGSTICKY_RW_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+ jmp IssueWarmReset\r
+\r
+ ;\r
+ ; Enable PCIEXBAR\r
+ ;\r
+ConfigPci:\r
+ mov eax, (EC_BASE + EC_ENABLE) ; Data\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (MEMORY_ARBITER_PORT_ID SHL SB_PORT_FIELD) OR (AEC_CTRL_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ mov eax, (EC_BASE + EC_ENABLE) ; Data\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HECREG_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ ;\r
+ ; Open up full 8MB SPI decode\r
+ ;\r
+ mov ebx, PCI_CFG OR (ILB_PFA SHL 8) OR BDE ; PCI Configuration address\r
+ mov eax, DECODE_ALL_REGIONS_ENABLE\r
+ JMP32 stackless_PCIConfig_Write\r
+\r
+ ;\r
+ ; Enable NMI operation\r
+ ; Good convention suggests you should read back RTC data port after\r
+ ; accessing the RTC index port.\r
+ ;\r
+ mov al, NMI_ENABLE\r
+ mov dx, RTC_INDEX\r
+ out dx, al\r
+ mov dx, RTC_DATA\r
+ in al, dx\r
+\r
+ ;\r
+ ; Clear Host Bridge SMI, NMI, INTR fields\r
+ ;\r
+ mov ecx, (OPCODE_SIDEBAND_REG_READ SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Read\r
+ and eax, NOT(NMI + SMI + INTR) ; Clear NMI, SMI, INTR fields\r
+ mov ecx, (OPCODE_SIDEBAND_REG_WRITE SHL SB_OPCODE_FIELD) OR (HOST_BRIDGE_PORT_ID SHL SB_PORT_FIELD) OR (HLEGACY_OFFSET SHL SB_ADDR_FIELD)\r
+ JMP32 stackless_SideBand_Write\r
+\r
+ ;\r
+ ; Restore return address\r
+ ;\r
+ mov esp, ebp\r
+ RET32\r
+\r
+IssueWarmReset:\r
+ ;\r
+ ; Issue Warm Reset request to Remote Management Unit via iLB\r
+ ;\r
+ mov ax, CF9_WARM_RESET\r
+ mov dx, ILB_RESET_REG\r
+ out dx, ax\r
+ jmp $ ; Stay here until we are reset.\r
+\r
+IssueColdReset:\r
+ ;\r
+ ; Issue Cold Reset request to Remote Management Unit via iLB\r
+ ;\r
+ mov ax, CF9_COLD_RESET\r
+ mov dx, ILB_RESET_REG\r
+ out dx, ax\r
+ jmp $ ; Stay here until we are reset.\r
+\r
+stackless_EarlyPlatformInit ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: stackless_SideBand_Read\r
+;\r
+; Input: esp - return address\r
+; ecx[15:8] - Register offset\r
+; ecx[23:16] - Port ID\r
+; ecx[31:24] - Opcode\r
+;\r
+; Output: eax - Data read\r
+;\r
+; Destroys:\r
+; eax\r
+; ebx\r
+; cl\r
+; esi\r
+;\r
+; Description:\r
+; Perform requested sideband read\r
+;\r
+;----------------------------------------------------------------------------\r
+stackless_SideBand_Read PROC NEAR C PUBLIC\r
+\r
+ mov esi, esp ; Save the return address\r
+\r
+ ;\r
+ ; Load the SideBand Packet Register to generate the transaction\r
+ ;\r
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address\r
+ mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits\r
+ xchg eax, ecx\r
+ JMP32 stackless_PCIConfig_Write\r
+ xchg eax, ecx\r
+\r
+ ;\r
+ ; Read the SideBand Data Register\r
+ ;\r
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address\r
+ JMP32 stackless_PCIConfig_Read\r
+\r
+ mov esp, esi ; Restore the return address\r
+ RET32\r
+\r
+stackless_SideBand_Read ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: stackless_SideBand_Write\r
+;\r
+; Input: esp - return address\r
+; eax - Data\r
+; ecx[15:8] - Register offset\r
+; ecx[23:16] - Port ID\r
+; ecx[31:24] - Opcode\r
+;\r
+; Output: None\r
+;\r
+; Destroys:\r
+; ebx\r
+; cl\r
+; esi\r
+;\r
+; Description:\r
+; Perform requested sideband write\r
+;\r
+;\r
+;----------------------------------------------------------------------------\r
+stackless_SideBand_Write PROC NEAR C PUBLIC\r
+\r
+ mov esi, esp ; Save the return address\r
+\r
+ ;\r
+ ; Load the SideBand Data Register with the data\r
+ ;\r
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_DATA_REG ; PCI Configuration address\r
+ JMP32 stackless_PCIConfig_Write\r
+\r
+ ;\r
+ ; Load the SideBand Packet Register to generate the transaction\r
+ ;\r
+ mov ebx, PCI_CFG OR (HOST_BRIDGE_PFA SHL 8) OR MESSAGE_BUS_CONTROL_REG ; PCI Configuration address\r
+ mov cl, (ALL_BYTE_EN SHL SB_BE_FIELD) ; Set all Byte Enable bits\r
+ xchg eax, ecx\r
+ JMP32 stackless_PCIConfig_Write\r
+ xchg eax, ecx\r
+\r
+ mov esp, esi ; Restore the return address\r
+ RET32\r
+\r
+stackless_SideBand_Write ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: stackless_PCIConfig_Write\r
+;\r
+; Input: esp - return address\r
+; eax - Data to write\r
+; ebx - PCI Config Address\r
+;\r
+; Output: None\r
+;\r
+; Destroys:\r
+; dx\r
+;\r
+; Description:\r
+; Perform a DWORD PCI Configuration write\r
+;\r
+;----------------------------------------------------------------------------\r
+stackless_PCIConfig_Write PROC NEAR C PUBLIC\r
+\r
+ ;\r
+ ; Write the PCI Config Address to the address port\r
+ ;\r
+ xchg eax, ebx\r
+ mov dx, PCI_ADDRESS_PORT\r
+ out dx, eax\r
+ xchg eax, ebx\r
+\r
+ ;\r
+ ; Write the PCI DWORD Data to the data port\r
+ ;\r
+ mov dx, PCI_DATA_PORT\r
+ out dx, eax\r
+\r
+ RET32\r
+\r
+stackless_PCIConfig_Write ENDP\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: stackless_PCIConfig_Read\r
+;\r
+; Input: esp - return address\r
+; ebx - PCI Config Address\r
+;\r
+; Output: eax - Data read\r
+;\r
+; Destroys:\r
+; eax\r
+; dx\r
+;\r
+; Description:\r
+; Perform a DWORD PCI Configuration read\r
+;\r
+;----------------------------------------------------------------------------\r
+stackless_PCIConfig_Read PROC NEAR C PUBLIC\r
+\r
+ ;\r
+ ; Write the PCI Config Address to the address port\r
+ ;\r
+ xchg eax, ebx\r
+ mov dx, PCI_ADDRESS_PORT\r
+ out dx, eax\r
+ xchg eax, ebx\r
+\r
+ ;\r
+ ; Read the PCI DWORD Data from the data port\r
+ ;\r
+ mov dx, PCI_DATA_PORT\r
+ in eax, dx\r
+\r
+ RET32\r
+\r
+stackless_PCIConfig_Read ENDP\r
+\r
+;\r
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase\r
+;\r
+align 16\r
+PUBLIC BootGdtTable\r
+\r
+;\r
+; GDT[0]: 0x00: Null entry, never used.\r
+;\r
+NULL_SEL equ $ - GDT_BASE ; Selector [0]\r
+GDT_BASE:\r
+BootGdtTable DD 0\r
+ DD 0\r
+;\r
+; Linear data segment descriptor\r
+;\r
+LINEAR_SEL equ $ - GDT_BASE ; Selector [0x8]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 092h ; present, ring 0, data, expand-up, writable\r
+ DB 0CFh ; page-granular, 32-bit\r
+ DB 0\r
+;\r
+; Linear code segment descriptor\r
+;\r
+LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x10]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 09Bh ; present, ring 0, data, expand-up, not-writable\r
+ DB 0CFh ; page-granular, 32-bit\r
+ DB 0\r
+;\r
+; System data segment descriptor\r
+;\r
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 093h ; present, ring 0, data, expand-up, not-writable\r
+ DB 0CFh ; page-granular, 32-bit\r
+ DB 0\r
+\r
+;\r
+; System code segment descriptor\r
+;\r
+SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 09Ah ; present, ring 0, data, expand-up, writable\r
+ DB 0CFh ; page-granular, 32-bit\r
+ DB 0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_CODE_SEL equ $ - GDT_BASE ; Selector [0x28]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0Fh\r
+ DB 09Bh ; present, ring 0, code, expand-up, writable\r
+ DB 00h ; byte-granular, 16-bit\r
+ DB 0\r
+;\r
+; Spare segment descriptor\r
+;\r
+SYS16_DATA_SEL equ $ - GDT_BASE ; Selector [0x30]\r
+ DW 0FFFFh ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 093h ; present, ring 0, data, expand-up, not-writable\r
+ DB 00h ; byte-granular, 16-bit\r
+ DB 0\r
+\r
+;\r
+; Spare segment descriptor\r
+;\r
+SPARE5_SEL equ $ - GDT_BASE ; Selector [0x38]\r
+ DW 0 ; limit 0xFFFF\r
+ DW 0 ; base 0\r
+ DB 0\r
+ DB 0 ; present, ring 0, data, expand-up, writable\r
+ DB 0 ; page-granular, 32-bit\r
+ DB 0\r
+GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes\r
+\r
+;\r
+; GDT Descriptor\r
+;\r
+GdtDesc: ; GDT descriptor\r
+ DW GDT_SIZE - 1 ; GDT limit\r
+ DD OFFSET BootGdtTable ; GDT base address\r
+\r
+ProtectedModeEntryLinearAddress LABEL FWORD\r
+ProtectedModeEntryLinearOffset LABEL DWORD\r
+ DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code\r
+ DW LINEAR_CODE_SEL\r
+\r
+END\r