Skip to main content
Fixing paragraph breaks.
Source Link
Giacomo1968
  • 56k
  • 22
  • 167
  • 214

The iMC is exposed as a set of registers in the PCI(e) configuration space and/or MSR registers. Upon a reset the values of the registers (e.g. the SAD registers) controlling the standard hole (from physical address 0xa0000 to 0xfffff, included) default to not reclaiming any memory transaction.

When a core performs a load to, say 0xffff0, the iMC won't reclaim it. The load then reaches the System Agent that acts as the default destination (à là subtractive decoding like in a PCI bridge). If an internal PCI(e) reclaims such load, it is dispatched to it (e.g. the legacy VGA framebuffer). In this case, no sane PCI(e) would, so the System Agent sends the memory load down the DMI link.

Downstream the load reaches the PCH which, upon a reset, reads the (possibly virtual) strapon pins to know where the firmware flash ROM is located (typically through the SPI bus, or the LPC bus) and then reads the flash descriptor to find out the flash region and to default map the BIOS region just at the end of the 4GiB limit (where the PCI hole is located). Furthermore, by default, the PCH aliases the region just under 4GiB to 0xe0000-0xfffff.
So

So the load to 0xffff0 is aliased to 0xfffffff0, reclaimed by the ROM, and decoded to the appropriate offset.

As you can easily see, this is all by default. As

As you go back in time the architecture changes but the principle remains the same. In the original 8086, there was probably just a simple shared bus and, as everybody with minimal knowledge of digital electronics knows, it's pretty easy to map devices at fixed addresses on a single shared bus (that's how the legacy IO port numbers arose).

It's worth noting that your understanding of an x86 booting is very far from the actual, modern thing. Not only modern x86s (not supporting x86S) boot with a CS base of 0xffff0000, but since Haswell, the first thing a CPU does upon an INIT is to fetch (through ucode) the FIT and execute the ACMs (which will eventually go back to the legacy boot).
Furthermore

Furthermore, it is usually the PCH that wakes up first and asserts the right pin/virtual wire to boot the CPU. The PCH firmware responsible for this is the BUP (Bring UP) and it's located in the same flash ROM of the CPU firmware (just in a different region). Since the flash ROM is attached directly to the PCH, it's easy to imagine how it's accessed.
Even

Even before the PCH is powered, the BMC (Server), the SuperIO chip (desktop), or the embedded controller (laptop) is powered and these usually are ucontrollers (i.e. they have their internal ROM). So actually, that's plenty of possible software that runs before the first x86 instruction is fetched.

Finally, it was customary for the firmware to configure the iMC/NB to reclaim writes to the range 0xe0000-0xfffff and then read and copy this whole range to itself. Finally, the writes were routed back to the PCH (which, by default, won't route them through the SPI/LCP) and the reads were reclaimed instead. This had the effect of copying the firmware in memory, a thing known as shadowing.

The iMC is exposed as a set of registers in the PCI(e) configuration space and/or MSR registers. Upon a reset the values of the registers (e.g. the SAD registers) controlling the standard hole (from physical address 0xa0000 to 0xfffff, included) default to not reclaiming any memory transaction.

When a core performs a load to, say 0xffff0, the iMC won't reclaim it. The load then reaches the System Agent that acts as the default destination (à là subtractive decoding like in a PCI bridge). If an internal PCI(e) reclaims such load, it is dispatched to it (e.g. the legacy VGA framebuffer). In this case, no sane PCI(e) would, so the System Agent sends the memory load down the DMI link.

Downstream the load reaches the PCH which, upon a reset, reads the (possibly virtual) strapon pins to know where the firmware flash ROM is located (typically through the SPI bus, or the LPC bus) and then reads the flash descriptor to find out the flash region and to default map the BIOS region just at the end of the 4GiB limit (where the PCI hole is located). Furthermore, by default, the PCH aliases the region just under 4GiB to 0xe0000-0xfffff.
So the load to 0xffff0 is aliased to 0xfffffff0, reclaimed by the ROM, and decoded to the appropriate offset.

As you can easily see, this is all by default. As you go back in time the architecture changes but the principle remains the same. In the original 8086, there was probably just a simple shared bus and, as everybody with minimal knowledge of digital electronics knows, it's pretty easy to map devices at fixed addresses on a single shared bus (that's how the legacy IO port numbers arose).

It's worth noting that your understanding of an x86 booting is very far from the actual, modern thing. Not only modern x86s (not supporting x86S) boot with a CS base of 0xffff0000, but since Haswell, the first thing a CPU does upon an INIT is to fetch (through ucode) the FIT and execute the ACMs (which will eventually go back to the legacy boot).
Furthermore, it is usually the PCH that wakes up first and asserts the right pin/virtual wire to boot the CPU. The PCH firmware responsible for this is the BUP (Bring UP) and it's located in the same flash ROM of the CPU firmware (just in a different region). Since the flash ROM is attached directly to the PCH, it's easy to imagine how it's accessed.
Even before the PCH is powered, the BMC (Server), the SuperIO chip (desktop), or the embedded controller (laptop) is powered and these usually are ucontrollers (i.e. they have their internal ROM). So actually, that's plenty of possible software that runs before the first x86 instruction is fetched.

Finally, it was customary for the firmware to configure the iMC/NB to reclaim writes to the range 0xe0000-0xfffff and then read and copy this whole range to itself. Finally, the writes were routed back to the PCH (which, by default, won't route them through the SPI/LCP) and the reads were reclaimed instead. This had the effect of copying the firmware in memory, a thing known as shadowing.

The iMC is exposed as a set of registers in the PCI(e) configuration space and/or MSR registers. Upon a reset the values of the registers (e.g. the SAD registers) controlling the standard hole (from physical address 0xa0000 to 0xfffff, included) default to not reclaiming any memory transaction.

When a core performs a load to, say 0xffff0, the iMC won't reclaim it. The load then reaches the System Agent that acts as the default destination (à là subtractive decoding like in a PCI bridge). If an internal PCI(e) reclaims such load, it is dispatched to it (e.g. the legacy VGA framebuffer). In this case, no sane PCI(e) would, so the System Agent sends the memory load down the DMI link.

Downstream the load reaches the PCH which, upon a reset, reads the (possibly virtual) strapon pins to know where the firmware flash ROM is located (typically through the SPI bus, or the LPC bus) and then reads the flash descriptor to find out the flash region and to default map the BIOS region just at the end of the 4GiB limit (where the PCI hole is located). Furthermore, by default, the PCH aliases the region just under 4GiB to 0xe0000-0xfffff.

So the load to 0xffff0 is aliased to 0xfffffff0, reclaimed by the ROM, and decoded to the appropriate offset.

As you can easily see, this is all by default.

As you go back in time the architecture changes but the principle remains the same. In the original 8086, there was probably just a simple shared bus and, as everybody with minimal knowledge of digital electronics knows, it's pretty easy to map devices at fixed addresses on a single shared bus (that's how the legacy IO port numbers arose).

It's worth noting that your understanding of an x86 booting is very far from the actual, modern thing. Not only modern x86s (not supporting x86S) boot with a CS base of 0xffff0000, but since Haswell, the first thing a CPU does upon an INIT is to fetch (through ucode) the FIT and execute the ACMs (which will eventually go back to the legacy boot).

Furthermore, it is usually the PCH that wakes up first and asserts the right pin/virtual wire to boot the CPU. The PCH firmware responsible for this is the BUP (Bring UP) and it's located in the same flash ROM of the CPU firmware (just in a different region). Since the flash ROM is attached directly to the PCH, it's easy to imagine how it's accessed.

Even before the PCH is powered, the BMC (Server), the SuperIO chip (desktop), or the embedded controller (laptop) is powered and these usually are ucontrollers (i.e. they have their internal ROM). So actually, that's plenty of possible software that runs before the first x86 instruction is fetched.

Finally, it was customary for the firmware to configure the iMC/NB to reclaim writes to the range 0xe0000-0xfffff and then read and copy this whole range to itself. Finally, the writes were routed back to the PCH (which, by default, won't route them through the SPI/LCP) and the reads were reclaimed instead. This had the effect of copying the firmware in memory, a thing known as shadowing.

Source Link

The iMC is exposed as a set of registers in the PCI(e) configuration space and/or MSR registers. Upon a reset the values of the registers (e.g. the SAD registers) controlling the standard hole (from physical address 0xa0000 to 0xfffff, included) default to not reclaiming any memory transaction.

When a core performs a load to, say 0xffff0, the iMC won't reclaim it. The load then reaches the System Agent that acts as the default destination (à là subtractive decoding like in a PCI bridge). If an internal PCI(e) reclaims such load, it is dispatched to it (e.g. the legacy VGA framebuffer). In this case, no sane PCI(e) would, so the System Agent sends the memory load down the DMI link.

Downstream the load reaches the PCH which, upon a reset, reads the (possibly virtual) strapon pins to know where the firmware flash ROM is located (typically through the SPI bus, or the LPC bus) and then reads the flash descriptor to find out the flash region and to default map the BIOS region just at the end of the 4GiB limit (where the PCI hole is located). Furthermore, by default, the PCH aliases the region just under 4GiB to 0xe0000-0xfffff.
So the load to 0xffff0 is aliased to 0xfffffff0, reclaimed by the ROM, and decoded to the appropriate offset.

As you can easily see, this is all by default. As you go back in time the architecture changes but the principle remains the same. In the original 8086, there was probably just a simple shared bus and, as everybody with minimal knowledge of digital electronics knows, it's pretty easy to map devices at fixed addresses on a single shared bus (that's how the legacy IO port numbers arose).

It's worth noting that your understanding of an x86 booting is very far from the actual, modern thing. Not only modern x86s (not supporting x86S) boot with a CS base of 0xffff0000, but since Haswell, the first thing a CPU does upon an INIT is to fetch (through ucode) the FIT and execute the ACMs (which will eventually go back to the legacy boot).
Furthermore, it is usually the PCH that wakes up first and asserts the right pin/virtual wire to boot the CPU. The PCH firmware responsible for this is the BUP (Bring UP) and it's located in the same flash ROM of the CPU firmware (just in a different region). Since the flash ROM is attached directly to the PCH, it's easy to imagine how it's accessed.
Even before the PCH is powered, the BMC (Server), the SuperIO chip (desktop), or the embedded controller (laptop) is powered and these usually are ucontrollers (i.e. they have their internal ROM). So actually, that's plenty of possible software that runs before the first x86 instruction is fetched.

Finally, it was customary for the firmware to configure the iMC/NB to reclaim writes to the range 0xe0000-0xfffff and then read and copy this whole range to itself. Finally, the writes were routed back to the PCH (which, by default, won't route them through the SPI/LCP) and the reads were reclaimed instead. This had the effect of copying the firmware in memory, a thing known as shadowing.