Page 1 of 1

Mapping flash to instruction address bus

Posted: Mon Feb 26, 2018 6:17 am
by kolban
My goal is to map a region of flash memory to the virtual address range of an ESP32 (Instruction bus).

Let us assume I have 64K I wish to map. That is 1 page.

Let us assume that the data exists on flash at offset

0x30 0000 to 0x31 0000

My goal is to map this to address range 0x4080 0000 to 0x4081 0000.

My understanding is that this is all within the rules.

To achieve this task, I execute the following statements in my C program:

Code: Select all

DPORT_PRO_FLASH_MMU_TABLE[192] = 48;
DPORT_APP_FLASH_MMU_TABLE[192] = 48;
After performing this, I use the built-in GDB and perform a dump of the address range using:

Code: Select all

(gdb) x /100x 0x40800000
The result is:

Code: Select all

0x40800000:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800010:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800020:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800030:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800040:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800050:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
0x40800060:	0xbad00bad	0xbad00bad	0xbad00bad	0xbad00bad
which is not what I loaded into flash at 0x30 0000 offset.

I validated what I have in flash by dumping that region of flash to a file and find my data "good" so confidence is "ok" that what is in flash is correct.

Studying the ESP32 Tech Ref, I find that 0x4080 0000 is MMU entry 192 and the 48th page of 64K is 0x30 0000.

Is there more that I need to do in order to cause flash to be mapped? I have been assuming that simply changing the entries in the tables DPORT_PRO_FLASH_MMU_TABLE and DPORT_APP_FLASH_MMU_TABLE would be sufficient ... but that may be too simplistic.

Re: Mapping flash to instruction address bus

Posted: Mon Feb 26, 2018 6:54 am
by ESP_Angus
This looks right at a glance. There are some extra things spi_flash_mmap does around flushing the cache, but this is mostly to avoid stale data. If you hadn't already read from this page, it shouldn't have any stale data.

0xbad00bad is the read result for an unmapped page.

Try calling spi_flash_cache2phys() and spi_flash_phys2cache() to sanity check that those addresses are mapped as you expect.

Re: Mapping flash to instruction address bus

Posted: Mon Feb 26, 2018 3:14 pm
by kolban
I checked the APIs spi_flash_cache2phys and spi_flash_phys2cache after changing the mapping tables and they seem to report the expected outcomes:

Code: Select all

rc from spi_flash_cache2phys(0x40800000) = 0x300000
rc from spi_flash_phys2cache(0x300000, inst) = 0x40800000

Re: Mapping flash to instruction address bus

Posted: Mon Feb 26, 2018 10:29 pm
by ESP_Angus
Well, that's a good sign!

I didn't know this was necessary for unused pages, but try the following (adapted from spi_flash_mmap() implementation in flash_mmap.c):

- Mark the function that manipulates the MMU tables with IRAM_ATTR (and prevent it being inlined, if necessary)
- Before writing to the MMU table call spi_flash_disable_interrupts_caches_and_other_cpu();
- After writing to the MMU table call Cache_Flush(0); Cache_Flush(1); spi_flash_enable_interrupts_caches_and_other_cpu();
- Try and do as little as possible while interrupts are disabled (ie don't call printf() or anything like that)

Re: Mapping flash to instruction address bus

Posted: Thu Mar 01, 2018 12:24 am
by kolban
We have made some progress. Unfortunately, we are sniffing a potential defect. MMU appears to work for address range VAddr1 (see ESP32 Tech Ref for explanations of this term) but not for VAddr2 or VAddr3. An issue has been created for tracking.

https://github.com/espressif/esp-idf/issues/1667