1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2013 - 2016 Intel Corporation. 4# 5# This program and the accompanying materials 6# are licensed and made available under the terms and conditions of the BSD License 7# which accompanies this distribution. The full text of the license may be found at 8# http://opensource.org/licenses/bsd-license.php 9# 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12# 13# Module Name: 14# 15# Flat32.S 16# 17# Abstract: 18# 19# This is the code that goes from real-mode to protected mode. 20# It consumes the reset vector, configures the stack. 21# 22# 23#------------------------------------------------------------------------------ 24 25.macro RET32 26 jmp *%esp 27.endm 28 29# 30# ROM/SPI/MEMORY Definitions 31# 32.equ QUARK_DDR3_MEM_BASE_ADDRESS, (0x000000000) # Memory Base Address = 0 33.equ QUARK_MAX_DDR3_MEM_SIZE_BYTES, (0x80000000) # DDR3 Memory Size = 2GB 34.equ QUARK_ESRAM_MEM_SIZE_BYTES, (0x00080000) # eSRAM Memory Size = 512K 35.equ QUARK_STACK_SIZE_BYTES, (0x008000) # Quark stack size = 32K 36 37# 38# RTC/CMOS definitions 39# 40.equ RTC_INDEX, (0x70) 41.equ NMI_DISABLE, (0x80) # Bit7=1 disables NMI 42.equ NMI_ENABLE, (0x00) # Bit7=0 disables NMI 43.equ RTC_DATA, (0x71) 44 45# 46# PCI Configuration definitions 47# 48.equ PCI_CFG, (0x80000000) # PCI configuration access mechanism 49.equ PCI_ADDRESS_PORT, (0xCF8) 50.equ PCI_DATA_PORT, (0xCFC) 51 52# 53# Quark PCI devices 54# 55.equ HOST_BRIDGE_PFA, (0x0000) # B0:D0:F0 (Host Bridge) 56.equ ILB_PFA, (0x00F8) # B0:D31:F0 (Legacy Block) 57 58# 59# ILB PCI Config Registers 60# 61.equ BDE, (0x0D4) # BIOS Decode Enable register 62.equ DECODE_ALL_REGIONS_ENABLE, (0xFF000000) # Decode all BIOS decode ranges 63 64# 65# iLB Reset Register 66# 67.equ ILB_RESET_REG, (0x0CF9) 68.equ CF9_WARM_RESET, (0x02) 69.equ CF9_COLD_RESET, (0x08) 70 71# 72# Host Bridge PCI Config Registers 73# 74.equ MESSAGE_BUS_CONTROL_REG, (0xD0) # Message Bus Control Register 75.equ SB_OPCODE_FIELD, (0x18) # Bit location of Opcode field 76.equ OPCODE_SIDEBAND_REG_READ, (0x10) # Read opcode 77.equ OPCODE_SIDEBAND_REG_WRITE, (0x11) # Write opcode 78.equ OPCODE_SIDEBAND_ALT_REG_READ, (0x06) # Alternate Read opcode 79.equ OPCODE_SIDEBAND_ALT_REG_WRITE, (0x07) # Alternate Write opcode 80.equ OPCODE_WARM_RESET_REQUEST, (0xF4) # Reset Warm 81.equ OPCODE_COLD_RESET_REQUEST, (0xF5) # Reset Cold 82.equ SB_PORT_FIELD, (0x10) # Bit location of Port ID field 83.equ MEMORY_ARBITER_PORT_ID, (0x00) 84.equ HOST_BRIDGE_PORT_ID, (0x03) 85.equ RMU_PORT_ID, (0x04) 86.equ MEMORY_MANAGER_PORT_ID, (0x05) 87.equ SOC_UNIT_PORT_ID, (0x31) 88.equ SB_ADDR_FIELD, (0x08) # Bit location of Register field 89.equ SB_BE_FIELD, (0x04) # Bit location of Byte Enables field 90.equ ALL_BYTE_EN, (0x0F) # All Byte Enables 91.equ MESSAGE_DATA_REG, (0xD4) # Message Data Register 92 93# 94# Memory Arbiter Config Registers 95# 96.equ AEC_CTRL_OFFSET, (0x00) 97 98# 99# Host Bridge Config Registers 100# 101.equ HMISC2_OFFSET, (0x03) # PCI configuration access mechanism 102.equ OR_PM_FIELD, (0x10) 103.equ SMI_EN, (0x00080000) 104 105.equ HMBOUND_OFFSET, (0x08) 106.equ HMBOUND_ADDRESS, (QUARK_DDR3_MEM_BASE_ADDRESS + QUARK_MAX_DDR3_MEM_SIZE_BYTES + QUARK_ESRAM_MEM_SIZE_BYTES) 107.equ HMBOUND_LOCK, (0x01) 108.equ HECREG_OFFSET, (0x09) 109.equ EC_BASE, (0xE0000000) 110.equ EC_ENABLE, (0x01) 111.equ HLEGACY_OFFSET, (0x0A) 112.equ NMI, (0x00004000) 113.equ SMI, (0x00001000) 114.equ INTR, (0x00000400) 115 116# 117# Memory Manager Config Registers 118# 119.equ ESRAMPGCTRL_BLOCK_OFFSET, (0x82) 120.equ BLOCK_ENABLE_PG, (0x10000000) 121.equ BIMRVCTL_OFFSET, (0x19) 122.equ ENABLE_IMR_INTERRUPT, (0x80000000) 123 124# 125# SOC UNIT Debug Registers 126# 127.equ CFGSTICKY_W1_OFFSET, (0x50) 128.equ FORCE_COLD_RESET, (0x00000001) 129.equ CFGSTICKY_RW_OFFSET, (0x51) 130.equ RESET_FOR_ESRAM_LOCK, (0x00000020) 131.equ RESET_FOR_HMBOUND_LOCK, (0x00000040) 132.equ CFGNONSTICKY_W1_OFFSET, (0x52) 133.equ FORCE_WARM_RESET, (0x00000001) 134 135# 136# CR0 cache control bit definition 137# 138.equ CR0_CACHE_DISABLE, 0x040000000 139.equ CR0_NO_WRITE, 0x020000000 140 141ASM_GLOBAL ASM_PFX(PcdGet32(PcdEsramStage1Base)) 142 143 144# 145# Contrary to the name, this file contains 16 bit code as well. 146# 147.text 148#---------------------------------------------------------------------------- 149# 150# Procedure: _ModuleEntryPoint 151# 152# Input: None 153# 154# Output: None 155# 156# Destroys: Assume all registers 157# 158# Description: 159# 160# Transition to non-paged flat-model protected mode from a 161# hard-coded GDT that provides exactly two descriptors. 162# This is a bare bones transition to protected mode only 163# used for a while in PEI and possibly DXE. 164# 165# After enabling protected mode, a far jump is executed to 166# transfer to PEI using the newly loaded GDT. 167# 168# Return: None 169# 170#---------------------------------------------------------------------------- 171ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) 172ASM_PFX(_ModuleEntryPoint): 173 174 # 175 # Warm Reset (INIT#) check. 176 # 177 .byte 0xbe,0x00,0xf0 #movw $0xF000, %si 178 .byte 0x8e,0xde #movw %si, %ds 179 .byte 0xbe,0xf0,0xff #movw $0xFFF0, %si 180 .byte 0x80,0x3c,0xea #cmpb $0xEA, (%si) # Is it warm reset ? 181 jne NotWarmReset # Jump if not. 182 .byte 0xb0,0x08 #movb $0x08, %al 183 .byte 0xba,0xf9,0x0c #movw $0xcf9, %dx 184 .byte 0xee #outb %al, %dx 185 .byte 0xb0,0x55 #movb $0x55, %al 186 .byte 0xe6,0x80 #outb %al, $0x80 187 jmp . 188NotWarmReset: 189 .byte 0x66,0x8b,0xe8 #movl %eax, %ebp 190 191 # 192 # Load the GDT table in GdtDesc 193 # 194 .byte 0x66,0xbe #movl $GdtDesc, %esi 195 .long GdtDesc 196 197 .byte 0x66,0x2e,0x0f,0x01,0x14 #lgdt %cs:(%si) 198 199 # 200 # Transition to 16 bit protected mode 201 # 202 .byte 0x0f,0x20,0xc0 #movl %cr0, %eax # Get control register 0 203 .byte 0x66,0x83,0xc8,0x03 #orl $0x0000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) 204 .byte 0x0f,0x22,0xc0 #movl %eax, %cr0 # Activate protected mode 205 206 # 207 # Now we're in 16 bit protected mode 208 # Set up the selectors for 32 bit protected mode entry 209 # 210 .byte 0xb8 #movw SYS_DATA_SEL, %ax 211 .word SYS_DATA_SEL 212 213 .byte 0x8e,0xd8 #movw %ax, %ds 214 .byte 0x8e,0xc0 #movw %ax, %es 215 .byte 0x8e,0xe0 #movw %ax, %fs 216 .byte 0x8e,0xe8 #movw %ax, %gs 217 .byte 0x8e,0xd0 #movw %ax, %ss 218 219 # 220 # Transition to Flat 32 bit protected mode 221 # The jump to a far pointer causes the transition to 32 bit mode 222 # 223 .byte 0x66,0xbe #movl ProtectedModeEntryLinearAddress, %esi 224 .long ProtectedModeEntryLinearAddress 225 .byte 0x66,0x2e,0xff,0x2c #jmp %cs:(%esi) 226 227# 228# Protected mode portion initializes stack, configures cache, and calls C entry point 229# 230 231#---------------------------------------------------------------------------- 232# 233# Procedure: ProtectedModeEntryPoint 234# 235# Input: Executing in 32 Bit Protected (flat) mode 236# cs: 0-4GB 237# ds: 0-4GB 238# es: 0-4GB 239# fs: 0-4GB 240# gs: 0-4GB 241# ss: 0-4GB 242# 243# Output: This function never returns 244# 245# Destroys: 246# ecx 247# edi 248# esi 249# esp 250# 251# Description: 252# Perform any essential early platform initilaisation 253# Setup a stack 254# Transfer control to EDKII code in eSRAM 255# 256#---------------------------------------------------------------------------- 257ProtectedModeEntryPoint: 258 leal L0, %esp 259 jmp stackless_EarlyPlatformInit 260L0: 261 262 # 263 # Set up stack pointer 264 # 265 movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %esp 266 movl $QUARK_ESRAM_MEM_SIZE_BYTES, %esi 267 addl %esi, %esp # ESP = top of stack (stack grows downwards). 268 269 # 270 # Store the the BIST value in EBP 271 # 272 movl $0, %ebp # No processor BIST on Quark 273 274 # 275 # Push processor count to stack first, then BIST status (AP then BSP) 276 # 277 movl $1, %eax 278 cpuid 279 shrl $16, %ebx 280 andl $0x000000FF, %ebx 281 cmpb $1, %bl 282 jae PushProcessorCount 283 284 # 285 # Some processors report 0 logical processors. Effectively 0 = 1. 286 # So we fix up the processor count 287 # 288 incl %ebx 289 290PushProcessorCount: 291 pushl %ebx 292 293 # 294 # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST 295 # for all processor threads 296 # 297 xorl %ecx, %ecx 298 movb %bl, %cl 299 300PushBist: 301 pushl %ebp 302 loop PushBist 303 304 # 305 # Pass Control into the PEI Core 306 # 307 call PlatformSecLibStartup 308 309 # 310 # PEI Core should never return to here, this is just to capture an invalid return. 311 # 312 jmp . 313 314#---------------------------------------------------------------------------- 315# 316# Procedure: stackless_EarlyPlatformInit 317# 318# Input: esp - Return address 319# 320# Output: None 321# 322# Destroys: Assume all registers 323# 324# Description: 325# Any early platform initialisation required 326# 327# Return: 328# None 329# 330#---------------------------------------------------------------------------- 331stackless_EarlyPlatformInit: 332 333 # 334 # Save return address 335 # 336 movl %esp, %ebp 337 338 # 339 # Ensure cache is disabled. 340 # 341 movl %cr0, %eax 342 orl $(CR0_CACHE_DISABLE + CR0_NO_WRITE), %eax 343 invd 344 movl %eax, %cr0 345 346 # 347 # Disable NMI operation 348 # Good convention suggests you should read back RTC data port after 349 # accessing the RTC index port. 350 # 351 movb $(NMI_DISABLE), %al 352 movw $(RTC_INDEX), %dx 353 outb %al, %dx 354 movw $(RTC_DATA), %dx 355 inb %dx, %al 356 357 # 358 # Disable SMI (Disables SMI wire, not SMI messages) 359 # 360 movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx 361 leal L1, %esp 362 jmp stackless_SideBand_Read 363L1: 364 andl $(~SMI_EN), %eax 365 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMISC2_OFFSET << SB_ADDR_FIELD)), %ecx 366 leal L2, %esp 367 jmp stackless_SideBand_Write 368L2: 369 370 # 371 # Before we get going, check SOC Unit Registers to see if we are required to issue a warm/cold reset 372 # 373 movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx 374 leal L3, %esp 375 jmp stackless_SideBand_Read 376L3: 377 andl $(FORCE_WARM_RESET), %eax 378 jz TestForceColdReset # Zero means bit clear, we're not requested to warm reset so continue as normal 379 jmp IssueWarmReset 380 381TestForceColdReset: 382 movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGNONSTICKY_W1_OFFSET << SB_ADDR_FIELD)), %ecx 383 leal L4, %esp 384 jmp stackless_SideBand_Read 385L4: 386 andl $(FORCE_COLD_RESET), %eax 387 jz TestHmboundLock # Zero means bit clear, we're not requested to cold reset so continue as normal 388 jmp IssueColdReset 389 390 # 391 # Before setting HMBOUND, check it's not locked 392 # 393TestHmboundLock: 394 movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx 395 leal L5, %esp 396 jmp stackless_SideBand_Read 397L5: 398 andl $(HMBOUND_LOCK), %eax 399 jz ConfigHmbound # Zero means bit clear, we have the config we want so continue as normal 400 # 401 # Failed to config - store sticky bit debug 402 # 403 movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx 404 leal L6, %esp 405 jmp stackless_SideBand_Read 406L6: 407 orl $(RESET_FOR_HMBOUND_LOCK), %eax 408 movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx 409 leal L7, %esp 410 jmp stackless_SideBand_Write 411L7: 412 jmp IssueWarmReset 413 414 # 415 # Set up the HMBOUND register 416 # 417ConfigHmbound: 418 movl $(HMBOUND_ADDRESS), %eax # Data (Set HMBOUND location) 419 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HMBOUND_OFFSET << SB_ADDR_FIELD)), %ecx 420 leal L8, %esp 421 jmp stackless_SideBand_Write 422L8: 423 424 # 425 # Enable interrupts to Remote Management Unit when a IMR/SMM/HMBOUND violation occurs. 426 # 427 movl $(ENABLE_IMR_INTERRUPT), %eax # Data (Set interrupt enable mask) 428 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (BIMRVCTL_OFFSET << SB_ADDR_FIELD)), %ecx 429 leal L9, %esp 430 jmp stackless_SideBand_Write 431L9: 432 433 # 434 # Set eSRAM address 435 # 436 movl ASM_PFX(PcdGet32(PcdEsramStage1Base)), %eax # Data (Set eSRAM location) 437 shr $(0x18), %eax 438 addl $(BLOCK_ENABLE_PG), %eax 439 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx 440 leal L10, %esp 441 jmp stackless_SideBand_Write 442L10: 443 444 # 445 # Check that we're not blocked from setting the config that we want. 446 # 447 movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (MEMORY_MANAGER_PORT_ID << SB_PORT_FIELD) | (ESRAMPGCTRL_BLOCK_OFFSET << SB_ADDR_FIELD)), %ecx 448 leal L11, %esp 449 jmp stackless_SideBand_Read 450L11: 451 andl $(BLOCK_ENABLE_PG), %eax 452 jnz ConfigPci # Non-zero means bit set, we have the config we want so continue as normal 453 # 454 # Failed to config - store sticky bit debug 455 # 456 movl $((OPCODE_SIDEBAND_ALT_REG_READ << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx 457 leal L12, %esp 458 jmp stackless_SideBand_Read 459L12: 460 orl $(RESET_FOR_ESRAM_LOCK), %eax # Set the bit we're interested in 461 movl $((OPCODE_SIDEBAND_ALT_REG_WRITE << SB_OPCODE_FIELD) | (SOC_UNIT_PORT_ID << SB_PORT_FIELD) | (CFGSTICKY_RW_OFFSET << SB_ADDR_FIELD)), %ecx 462 leal L13, %esp 463 jmp stackless_SideBand_Write 464L13: 465 jmp IssueWarmReset 466 467 # 468 # Enable PCIEXBAR 469 # 470ConfigPci: 471 movl $(EC_BASE + EC_ENABLE), %eax # Data 472 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (MEMORY_ARBITER_PORT_ID << SB_PORT_FIELD) | (AEC_CTRL_OFFSET << SB_ADDR_FIELD)), %ecx 473 leal L14, %esp 474 jmp stackless_SideBand_Write 475L14: 476 477 movl $(EC_BASE + EC_ENABLE), %eax # Data 478 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HECREG_OFFSET << SB_ADDR_FIELD)), %ecx 479 leal L15, %esp 480 jmp stackless_SideBand_Write 481L15: 482 483 # 484 # Open up full 8MB SPI decode 485 # 486 movl $(PCI_CFG | (ILB_PFA << 8) | BDE), %ebx # PCI Configuration address 487 movl $(DECODE_ALL_REGIONS_ENABLE), %eax 488 leal L16, %esp 489 jmp stackless_PCIConfig_Write 490L16: 491 492 # 493 # Enable NMI operation 494 # Good convention suggests you should read back RTC data port after 495 # accessing the RTC index port. 496 # 497 movb $(NMI_ENABLE), %al 498 movw $(RTC_INDEX), %dx 499 outb %al, %dx 500 movw $(RTC_DATA), %dx 501 inb %dx, %al 502 503 # 504 # Clear Host Bridge SMI, NMI, INTR fields 505 # 506 movl $((OPCODE_SIDEBAND_REG_READ << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx 507 leal L21, %esp 508 jmp stackless_SideBand_Read 509L21: 510 andl $~(NMI + SMI + INTR), %eax # Clear NMI, SMI, INTR fields 511 movl $((OPCODE_SIDEBAND_REG_WRITE << SB_OPCODE_FIELD) | (HOST_BRIDGE_PORT_ID << SB_PORT_FIELD) | (HLEGACY_OFFSET << SB_ADDR_FIELD)), %ecx 512 leal L22, %esp 513 jmp stackless_SideBand_Write 514L22: 515 516 # 517 # Restore return address 518 # 519 movl %ebp, %esp 520 RET32 521 522IssueWarmReset: 523 # 524 # Issue Warm Reset request to Remote Management Unit via iLB 525 # 526 movw $(CF9_WARM_RESET), %ax 527 movw $(ILB_RESET_REG), %dx 528 outw %ax, %dx 529 jmp . # Stay here until we are reset. 530 531IssueColdReset: 532 # 533 # Issue Cold Reset request to Remote Management Unit via iLB 534 # 535 movw $(CF9_COLD_RESET), %ax 536 movw $(ILB_RESET_REG), %dx 537 outw %ax, %dx 538 jmp . # Stay here until we are reset. 539 540#---------------------------------------------------------------------------- 541# 542# Procedure: stackless_SideBand_Read 543# 544# Input: esp - return address 545# ecx[15:8] - Register offset 546# ecx[23:16] - Port ID 547# ecx[31:24] - Opcode 548# 549# Output: eax - Data read 550# 551# Destroys: 552# eax 553# ebx 554# cl 555# esi 556# 557# Description: 558# Perform requested sideband read 559# 560#---------------------------------------------------------------------------- 561stackless_SideBand_Read: 562 563 movl %esp, %esi # Save the return address 564 565 # 566 # Load the SideBand Packet Register to generate the transaction 567 # 568 movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address 569 movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits 570 xchgl %ecx, %eax 571 leal L17, %esp 572 jmp stackless_PCIConfig_Write 573L17: 574 xchgl %ecx, %eax 575 576 # 577 # Read the SideBand Data Register 578 # 579 movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address 580 leal L18, %esp 581 jmp stackless_PCIConfig_Read 582L18: 583 584 movl %esi, %esp # Restore the return address 585 RET32 586 587 588#---------------------------------------------------------------------------- 589# 590# Procedure: stackless_SideBand_Write 591# 592# Input: esp - return address 593# eax - Data 594# ecx[15:8] - Register offset 595# ecx[23:16] - Port ID 596# ecx[31:24] - Opcode 597# 598# Output: None 599# 600# Destroys: 601# ebx 602# cl 603# esi 604# 605# Description: 606# Perform requested sideband write 607# 608# 609#---------------------------------------------------------------------------- 610stackless_SideBand_Write: 611 612 movl %esp, %esi # Save the return address 613 614 # 615 # Load the SideBand Data Register with the data 616 # 617 movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_DATA_REG)), %ebx # PCI Configuration address 618 leal L19, %esp 619 jmp stackless_PCIConfig_Write 620L19: 621 622 # 623 # Load the SideBand Packet Register to generate the transaction 624 # 625 movl $((PCI_CFG) | (HOST_BRIDGE_PFA << 8) | (MESSAGE_BUS_CONTROL_REG)), %ebx # PCI Configuration address 626 movb $(ALL_BYTE_EN << SB_BE_FIELD), %cl # Set all Byte Enable bits 627 xchgl %ecx, %eax 628 leal L20, %esp 629 jmp stackless_PCIConfig_Write 630L20: 631 xchgl %ecx, %eax 632 633 movl %esi, %esp # Restore the return address 634 RET32 635 636 637#---------------------------------------------------------------------------- 638# 639# Procedure: stackless_PCIConfig_Write 640# 641# Input: esp - return address 642# eax - Data to write 643# ebx - PCI Config Address 644# 645# Output: None 646# 647# Destroys: 648# dx 649# 650# Description: 651# Perform a DWORD PCI Configuration write 652# 653#---------------------------------------------------------------------------- 654stackless_PCIConfig_Write: 655 656 # 657 # Write the PCI Config Address to the address port 658 # 659 xchgl %ebx, %eax 660 movw $(PCI_ADDRESS_PORT), %dx 661 outl %eax, %dx 662 xchgl %ebx, %eax 663 664 # 665 # Write the PCI DWORD Data to the data port 666 # 667 movw $(PCI_DATA_PORT), %dx 668 outl %eax, %dx 669 670 RET32 671 672 673#---------------------------------------------------------------------------- 674# 675# Procedure: stackless_PCIConfig_Read 676# 677# Input: esp - return address 678# ebx - PCI Config Address 679# 680# Output: eax - Data read 681# 682# Destroys: 683# eax 684# dx 685# 686# Description: 687# Perform a DWORD PCI Configuration read 688# 689#---------------------------------------------------------------------------- 690stackless_PCIConfig_Read: 691 692 # 693 # Write the PCI Config Address to the address port 694 # 695 xchgl %ebx, %eax 696 movw $(PCI_ADDRESS_PORT), %dx 697 outl %eax, %dx 698 xchgl %ebx, %eax 699 700 # 701 # Read the PCI DWORD Data from the data port 702 # 703 movw $(PCI_DATA_PORT), %dx 704 inl %dx, %eax 705 706 RET32 707 708 709# 710# ROM-based Global-Descriptor Table for the Tiano PEI Phase 711# 712.align 16 713# 714# GDT[0]: 000h: Null entry, never used. 715# 716 717GDT_BASE: 718BootGdtTable: 719# null descriptor 720.equ NULL_SEL, . - GDT_BASE # Selector [0] 721 .word 0 # limit 15:0 722 .word 0 # base 15:0 723 .byte 0 # base 23:16 724 .byte 0 # type 725 .byte 0 # limit 19:16, flags 726 .byte 0 # base 31:24 727 728# linear data segment descriptor 729.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8] 730 .word 0xFFFF # limit 0xFFFFF 731 .word 0 # base 0 732 .byte 0 733 .byte 0x92 # present, ring 0, data, expand-up, writable 734 .byte 0xCF # page-granular, 32-bit 735 .byte 0 736 737# linear code segment descriptor 738.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10] 739 .word 0xFFFF # limit 0xFFFFF 740 .word 0 # base 0 741 .byte 0 742 .byte 0x9A # present, ring 0, data, expand-up, writable 743 .byte 0xCF # page-granular, 32-bit 744 .byte 0 745 746# system data segment descriptor 747.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18] 748 .word 0xFFFF # limit 0xFFFFF 749 .word 0 # base 0 750 .byte 0 751 .byte 0x92 # present, ring 0, data, expand-up, writable 752 .byte 0xCF # page-granular, 32-bit 753 .byte 0 754 755# system code segment descriptor 756.equ SYS_CODE_SEL, . - GDT_BASE 757 .word 0xFFFF # limit 0xFFFFF 758 .word 0 # base 0 759 .byte 0 760 .byte 0x9A # present, ring 0, data, expand-up, writable 761 .byte 0xCF # page-granular, 32-bit 762 .byte 0 763 764# spare segment descriptor 765.equ SYS16_CODE_SEL, . - GDT_BASE 766 .word 0xffff # limit 0xFFFFF 767 .word 0 # base 0 768 .byte 0x0f 769 .byte 0x9b # present, ring 0, data, expand-up, writable 770 .byte 0 # page-granular, 32-bit 771 .byte 0 772 773# spare segment descriptor 774.equ SYS16_DATA_SEL, . - GDT_BASE 775 .word 0xffff # limit 0xFFFFF 776 .word 0 # base 0 777 .byte 0 778 .byte 0x93 # present, ring 0, data, expand-up, not-writable 779 .byte 0 # page-granular, 32-bit 780 .byte 0 781 782# spare segment descriptor 783.equ SPARE5_SEL, . - GDT_BASE 784 .word 0 # limit 0xFFFFF 785 .word 0 # base 0 786 .byte 0 787 .byte 0 # present, ring 0, data, expand-up, writable 788 .byte 0 # page-granular, 32-bit 789 .byte 0 790.equ GDT_SIZE, . - GDT_BASE 791 792# 793# GDT Descriptor 794# 795GdtDesc: # GDT descriptor 796 .word GDT_SIZE - 1 797 .long BootGdtTable 798 799ProtectedModeEntryLinearAddress: 800ProtectedModeEntryLinearOffset: 801 .long ProtectedModeEntryPoint 802 .word LINEAR_CODE_SEL 803