VOGONS


First post, by jakethompson1

User metadata
Rank Oldbie
Rank
Oldbie

After ROMs are copied to shadow RAM and the shadow RAM write protection is enabled, 486 chipsets block any writes to shadow RAM in both DRAM and external cache.

Q71264 shows that Windows 386-enhanced mode, in addition to possibly other software, actually relies on the fact that shadow RAM areas will not be clobbered by other software.

The 486 CPU does not offer a way to mark cache lines as "read only" as the CPU fills the internal cache. As the OPTi 82C895 datasheet says:

Cache shadow RAM area in L2/L1 caches (optional)...Although write protection of these areas will still be honored in the L2 (external) cache, the L1 cache does not have a write protection mechanism and the ROM code may be overwritten or modified if stored in the L1 cache.

As a consequence, 486 internal cache and shadow RAM areas could temporarily become out-of-sync, as write-through cycles would update the CPU's internal cache, but the writes to external cache (and shadow RAM) would be discarded by the chipset. This can be entirely avoided by forbidding internal caching of shadow RAM, but that would introduce a speed penalty.

Looking briefly at the 80486 data book, it appears you could use EADS# to force an invalidation during a write-through cycle, even if the supposed bus master that is updating RAM is the CPU itself. I don't know if any chipsets bothered to do that to protect from shadow RAM writes into internal cache. Also, for a write back enhanced CPU, during cache fill it appears there is a way to mark a line as "shared" (requiring write-through) during fill, to retain that protection.

The SiS 496 suggests that perhaps it does that EADS# trick, but does not support marking lines as shared during fill, so it doesn't work on write back enhanced CPUs:

System designer should be aware that for Intel P24D and P24T CPU operating in write back mode, shadow cacheable areas are not write protected in CPU's internal cache because once the data line being filled in CPU's level 1 cache, there will be no observable bus cycle outside the CPU while CPU write on these cache lines. The line by line write-back / write-through mode (WB/WT# pin) is not supported by the 85C496. Therefore programmers must make sure that software do not write on these locations unless they really meant to change it's contents. For Cyrix Cx486DX, Cx486DX2 these areas can still be write protected by setting the WT1 bit in CPU's CCR2 register.

In practice, was this just not an issue?

Reply 1 of 2, by bakemono

User metadata
Rank Oldbie
Rank
Oldbie

In protected mode, the memory range can be marked as read-only in the page table. Not sure if DPMI hosts actually do this. Under Windows it's a non-issue because user processes won't have the adapter area mapped into their virtual memory. In real mode, maybe some buggy code could crash itself by trying to write garbage over shadow RAM? The data would have to already be in L1 when the write happens, because a write-through doesn't cause a line to be allocated on 486s.

GBAJAM 2024 submission on itch: https://90soft90.itch.io/wreckage

Reply 2 of 2, by mkarcher

User metadata
Rank l33t
Rank
l33t
jakethompson1 wrote on 2025-04-13, 02:59:

After ROMs are copied to shadow RAM and the shadow RAM write protection is enabled, 486 chipsets block any writes to shadow RAM in both DRAM and external cache.

DRAM: Yes, sure. External cache: I hope so, but I wouldn't bet my life on every chipset blocking shadow writes to L2 cache. The L2 cache logic is on a critical path for FSB timings (to get 2-1-1-1 for high FSB clocks working), so every extra consideration will slow it down. Granted, you already have "non-cacheable areas" and "top of memory" limits for the L2, so "block writes on shadow" might not add a significant extra time.

jakethompson1 wrote on 2025-04-13, 02:59:

Q71264 shows that Windows 386-enhanced mode, in addition to possibly other software, actually relies on the fact that shadow RAM areas will not be clobbered by other software.

I think clobbering of the shadow RAM regions is mostly a non-issue, because it makes no sense to intentionally write to the BIOS area during normal operation. In the general case, you don't know whether the area is backed by real ROMs, by shadow RAM or by EMM386 providing VM86 shadowing (using write-protected pages, which will prevent writes in L1 cache by triggering an exception on every attempt). Granted, there is the potential of writes to the BIOS area due to bugs, that were benign on cache-less systems because the writes just get lost in that case, but might temporarily mess up the cache on systems with cached BIOS. So it makes sense to have some mechanism that prevents writes to shadow memory changing the contents temporarily in the case you need to work around a bug like that, but experience shows it is generally not needed. The KB Article addresses a more relevant issue: Memory management solutions that intenionally modify what's visible in the BIOS area, like QEMMs stealthing, which indeed is a real concern for the ROM breakpoint stuff Microsoft uses in Windows.

jakethompson1 wrote on 2025-04-13, 02:59:

Cache shadow RAM area in L2/L1 caches (optional)...Although write protection of these areas will still be honored in the L2 (external) cache, the L1 cache does not have a write protection mechanism and the ROM code may be overwritten or modified if stored in the L1 cache.

As a consequence, 486 internal cache and shadow RAM areas could temporarily become out-of-sync, as write-through cycles would update the CPU's internal cache, but the writes to external cache (and shadow RAM) would be discarded by the chipset. This can be entirely avoided by forbidding internal caching of shadow RAM, but that would introduce a speed penalty.

Forbidding internal caching of the shadow RAM is a consequence of that setting of the OPTi chipset, and this option is exactly meant to let you choose the trade-off between "correctness" (i.e. ROM can not be modified) and "performance" (i.e. (shadow) ROM can be cached in L1 cache). This option is common on a lot of 486 chipsets, and is typically called "shadow cacheable" in the BIOS setup screen.

jakethompson1 wrote on 2025-04-13, 02:59:

Looking briefly at the 80486 data book, it appears you could use EADS# to force an invalidation during a write-through cycle, even if the supposed bus master that is updating RAM is the CPU itself. I don't know if any chipsets bothered to do that to protect from shadow RAM writes into internal cache. Also, for a write back enhanced CPU, during cache fill it appears there is a way to mark a line as "shared" (requiring write-through) during fill, to retain that protection.

Your analysis sounds correct. That's actually a quite clever way of addressing the issue, as it shouldn't hit performance unless actual shadow writes happen, which should be a rare exception. The only drawback of this approach is additional logic complexity and maybe general performance loss caused by the extra complexity (we are still talking about the FSB/L2-interface which is timing critical).

jakethompson1 wrote on 2025-04-13, 02:59:

The SiS 496 suggests that perhaps it does that EADS# trick, but does not support marking lines as shared during fill, so it doesn't work on write back enhanced CPUs:

[...]

In practice, was this just not an issue?

Reading the quoted datasheet fragment (or everything in the datasheet concerning shadowing), it definitiely sounds like the SiS chipset is doing the EADS# trick, indeed. As they assumingly support the EADS# trick, but do not force WT on the shadow regions, one might suspect that the EADS# trick has been implemented in earlier SiS chipsets as well that don't support L1WB at all, and just taken over to newer chipsets with L1WB support.