fabim,
Acho que sua dúvida é mais em relação aos hardwares que fazem o tratamento dos barramentos no microprocessadores. Os microprocessadores têm hardwares especialmente dedicados ao tratamento de bus - os controladores de RAM (SRAM, SDRAM, DDR, DDR2, DDR3, etc.) e geralemente um para tratamento de barramento paralelo genérico, que é usado para a FLASH mas poderia ser usado para acessar qualquer outro dispositivo (CIs endereçáveis, FPGA, buffers, etc.)
Então, para entender o que acontece em relação aos barramentos, é muito menos questão de entender o que acontece no core do microprocessador e enteder o que acontece nos controladores de memória, incluindo aí a cache, que não deixa de ser um outro hardware dedicado dentro do core.
Por exemplo, num coldfire que usamos aqui, o MCF5207:
http://cache.freescale.com/files/32bit/ ... 5208RM.pdfDê uma olhada nos capítulos 5 (Cache), 6 (SRAM interna), 17 (Flexbus, que é o controlador de barramento paralelo, dê uma olhada especial na página 295), e 18 (Controlador de SDRAM).
O SO configura tudo pra você, então quando você está mexendo em alto nível, você não tem visibilidade do que está acontecendo nos controladores de HW de mais baixo nível. Mas tudo o que o SO faz nesses casos é configurar corretamente estes perféricos, de modo que você não tenha que esquentar muito a cabeça com isso.
Quanto aos casos que você descreveu:
O caso 1) é o caso em que se roda diretamente da flash. Geralmente se usa logo no começo do boot, quando a RAM ainda não está configurada. Então, um dos primeiros passos do código que roda diretamente na flash é configrar a RAM, cache, essas coisas.
Geralmente, configurado a RAM, você copia seu código da FLASH para a RAM e começa excutar o código de lá. É bem mais rápido porque a RAM temo menos latência, e se tudo tiver configurado corretamente, a RAM vai poder usar a cache para otimizar a execução do código. É mais ou menos o que você descreveu no 2), mas com uma RAM no lugar da FLASH. Apesar de que se você não tiver uma RAM externa por exemplo, deve ser possível usar a cache diretamente, eu é que nunca precisei disso.
No caso 3) apesar das arquiteturas Harvards poderem endereçar RAM e FLASHes no mesmo range de endereços, ainda assim o uP sabe quando está acessando a flash e quando está acessano a RAM, pq vc define range de endereços diferentes para eles. Por exemplo, posso ter uma ram de 64MB no range 0-0x003FFFFF e uma FLASH de 256M no range 0x80000000-0x80FFFFFF. Se eu escrever no endereço 0x80400000, o uP sabe que estou escrevendo na FLASH e vai gravar seguindo os passos que seu controlador indicar. Se eu for ler uma instrução do endereço 0x00001000, o uP sabe que é da RAM, e sendo uma instrução e o cache estiver configurado, ele provavelmente vai pegar um bloco inteiro da SDRAM e passar pra cache, de acordo com o que estiver programado no controlador de cache. Se o outro acesso for no endereço 0x00001001, a cache e o controlador SDRAM se entendem via HW, e o endereço passado já é pego diretamente da cache sem precisar pegar da SDRAM.
Espero ter dado uma esclarecida - o ponto é que tem muito mais HW dando ajuda no processador do que o core, e o core não faz tudo sozinho.
But to us there is but one God, plus or minus one - Corinthians 8:6±2. (xkcd.com)