7 Replies Latest reply on Aug 26, 2014 1:36 AM by Krzysztof_Czarnowski

    intel_qrk_esram_map_range fails


      I’m using Intel Galileo board and


      (Yes, I know there is a newer version.)


      I'm trying to overlay some kernel dynamically allocated memory with eSRAM (in a kernel module), but a simple the call to intel_qrk_esram_map_range() fails. Has anyone tried this? Anything obvious I miss? If nothing comes up I'll probably dig deeper later today...


      The failure details:

      // get contigues pages for the overlay of entire ESRAM

      pages_addr = __get_free_pages(GFP_KERNEL, 7);

      DEB("Allocated: pages_addr=0x%08x (vaddr=%p)\n", pages_addr, __va(pages_addr));

      if (pages_addr == 0) {

            KERR("Failed to __get_free_pages()\n");

            goto Failure;


      // setup esram overlay

      //res = intel_qrk_esram_map_range(__va(pages_addr), 1 << 7, "esram_umap");

      res = intel_qrk_esram_map_range(__va(pages_addr), 0x1000, "esram_umap");

      if (res) {

            KERR("Failed to intel_qrk_esram_map_range(): %d\n", res);

            goto Failure;


      with –EINVAL result, dmesg output:

      [  582.982418] ESRAM_UMAP Quark eSRAM userspace support driver.

      [  582.989049] ESRAM_UMAP DEB: Allocated: pages_addr=0xcea00000 (vaddr=8ea00000)

      [  582.989097] ESRAM_UMAP Failed to intel_qrk_esram_map_range(): -22

      But there is some side-effect of the call in /sys/devices/platform/intel-qrk-esram.0/stats:

      root@clanton:~# diff esram-stats-{before,after}

      --- esram-stats-before

      +++ esram-stats-after

      @@ -7,9 +7,9 @@

      esram-ctrl.pages : 128

      esram-ctrl.dram-flush-priorityi : 2

      esram-block : 0x00000000

      -free page : 128

      -used page : 0

      +free page : 127

      +used page : 1

      refresh : 0ms

      page enable retries : 0

      page disable retries   : 0

      -ecc next page : 127

      +ecc next page : 126


      root@clanton:~# cat /sys/devices/platform/intel-qrk-esram.0/map


              Page virt 0x8ea00000 phys 0xcea00000

              Refcount 1

      I’ve skimmed through the source in intel_qrk_esram.c but no quick conclusion…

        • 1. Re: intel_qrk_esram_map_range fails



          In order for us to be able to provide a better response to your problem, may we know what are you trying to do with the eSRAM? Then, where are you running these commands? This will give us a better understanding of what is it you are trying to do.



          • 2. Re: intel_qrk_esram_map_range fails

            Hello JPMontero_Intel,


            As I wrote above:

            -- got a Galileo board

            -- upgraded firmware with sysimage-galileo-1.0.0.cap included in arduino-1.5.3 package (with IDE)

            -- booting from microSD card, binary image LINUX_IMAGE_FOR_SD_Intel_Galileo_v1.0.0

            -- the code snippet comes from a standalone linux module, compiled with  Board_Support_Package_Sources_for_Intel_Quark_v1.0.0. I've added a recipe to linux-yocto-clanton.

            -- the code runs in driver's "init" function.

            -- dmesg was run just after loading the driver with insmod...

            Hmm... If there is anything else, let me know.


            Best regards,


            • 3. Re: intel_qrk_esram_map_range fails

              And can you have a look at my questions on Ehsan's Re: Using ESRAM from user-space code thread?

              • 4. Re: intel_qrk_esram_map_range fails

                I've updated firmware and SD image to v1.0.2.

                Nothing seems to have changed...

                • 5. Re: intel_qrk_esram_map_range fails

                  The eSRAM is not physically addressed as a stand-alone piece of memory, you basically map a portion of your physical memory into the eSRAM ( either as a 512K block or in 4K page granularity ) – what happens then is that the mapped area of memory resides on-chip with low latency access ( similar in effect to L2 cache as Pete mentioned ).
                  One key point to note is that there is no coherency maintained between the local data stored in eSRAM & that contained in the physical memory. When you hand back the eSRAM block there is an option to sync the memories, similar to a cache writeback but that needs to be implicitly called as part of your software system.


                  • 6. Re: intel_qrk_esram_map_range fails

                    OK,but this information is basically available in docs (like Quark_SWDevManLx_330235_001.pdf) and does not answer my question.


                    In the meantime I've made some progress ;-)

                    In the code above I used directly __get_free_pages() to get a contiguous memory chunk of required size. This was not strictly required but is possible, right? However the physical address returned (0xcea00000, see the code snippet above) seems not to be an existing/available memory. In fact from "cat /proc/iomem" it follows that the address falls into one of the holes in

                    10000000-febfffff : PCI Bus 0000:00

                    (The output from /proc/iomem is included below.)

                    However when I changed the code and requested memory with kmalloc() I get a chunk with physical adress 0x0e900000 which falls in

                    00100000-0efdefff : System RAM

                    and then the eSRAM overlay call to intel_qrk_esram_map_range() succeeds.


                    So this very issue is kind of solved, but there is ANOTHER question about __get_free_pages() faulty (?) behaviour. But this is a separate issue, probably...


                    However, when I started to compare eSRAM performance with that of "regular" RAM, I found some other issues. They seem similar to those reported by Ehsan

                    Using ESRAM from user-space code

                    but I think I've dug a bit deeper... I will make a separate post shortly.@



                    root@clanton:~# cat /proc/iomem

                    00000000-0000ffff : reserved

                    00010000-00096fff : System RAM

                    00097000-00097fff : reserved

                    00098000-0009ffff : System RAM

                    000a0000-000bffff : PCI Bus 0000:00

                      000a0000-000bffff : Video RAM area

                    000c0000-000dffff : pnp 00:00

                    000f0000-000fffff : System ROM

                    00100000-0efdefff : System RAM

                      01000000-012c8591 : Kernel code

                      012c8592-014383bf : Kernel data

                      01486000-014eefff : Kernel bss

                    0efdf000-0f01efff : ACPI Tables

                    0f01f000-0f0defff : reserved

                    0f0df000-0fddefff : ACPI Non-volatile Storage

                    0fddf000-0fdeefff : reserved

                    0fdef000-0fdeffff : System RAM

                    0fdf0000-0fffffff : RAM buffer

                    10000000-febfffff : PCI Bus 0000:00

                      10000000-101fffff : PCI Bus 0000:01

                      10200000-103fffff : PCI Bus 0000:01

                      10400000-105fffff : PCI Bus 0000:02

                      10600000-107fffff : PCI Bus 0000:02

                      90000000-90001fff : 0000:00:14.7

                      90002000-90003fff : 0000:00:14.6

                        90002000-90003fff : stmmaceth

                      90004000-90005fff : 0000:00:14.2

                        90004000-90005fff : pch_udc

                      90006000-90006fff : 0000:00:15.2

                        90006000-90006fff : qrk-gip

                      90007000-90007fff : 0000:00:15.2

                        90007000-90007fff : qrk-gip

                      90008000-90008fff : 0000:00:15.1

                        90008000-90008fff : CE4100 SPI

                      90009000-90009fff : 0000:00:15.0

                        90009000-90009fff : CE4100 SPI

                      9000a000-9000afff : 0000:00:14.5

                      9000b000-9000bfff : 0000:00:14.5

                        9000b000-9000b01f : serial

                      9000c000-9000cfff : 0000:00:14.4

                        9000c000-9000cfff : ohci_hcd

                      9000d000-9000dfff : 0000:00:14.3

                        9000d000-9000dfff : ehci_hcd

                      9000e000-9000efff : 0000:00:14.1

                      9000f000-9000ffff : 0000:00:14.1

                        9000f000-9000f01f : serial

                      90010000-90010fff : 0000:00:14.0

                        90010000-90010fff : mmc0

                      e0000000-e1ffffff : PCI MMCONFIG 0000 [bus 00-1f]

                        e0000000-e1ffffff : reserved

                          e0000000-e1ffffff : pnp 00:00

                    fec00000-fec003ff : IOAPIC 0

                    fed00000-fed003ff : HPET 0

                    fed1c000-fed1ffff : reserved

                      fed1c000-fed1ffff : pnp 00:00

                    fee00000-fee00fff : Local APIC

                    ff800000-ffffffff : pnp 00:00

                    • 7. Re: intel_qrk_esram_map_range fails

                      The above mentioned "other issues" (weird performance measurement results) are posted here:

                      Memory performance on Galileo/Quark.