How to add OEMDeviceTable? RRS feed

  • Question

  • Hi,

    I am trying to add OEMDeviceTable to my BSP.

    My config.bib looks like this:


    ARGS    80000000             00001000   RESERVED ; 4K
    VFB     80001000             00100000   RESERVED ; Video frame buffer 1MB
    NK        81000000             04000000 RAMIMAGE ; 64 MB
    RAM     85000000             1B000000   RAM ; 432 MB

    ROMSTART = 0x81000000
    ROMWIDTH =32
    ROMSIZE = 0x04000000


    ;  Export Definition

            EXPORT  g_oalAddressTable[DATA]
            EXPORT g_oalDeviceTable[DATA]
    ;  Table format: cached address, physical address, size



            DCD 0, 0, 0;
            DCD 0x80000000, 0x00000000, 512 ;SDRAM 512MB
            DCD 0, 0, 0; End

    g_oalDeviceTable; We shifted the physical address by 8 bits right     
            DCD 0xAF400000, 0x00500000, 1, 0;PERIPHERIAL
            DCD 0x00000000, 0x00000000, 0, 0;end of table

    I have added the following code in the beginning of startup.s:

            adr     r0, g_oalAddressTable
            adr     r1, g_oalDeviceTable
            ldr     r3, =CE_NEW_MAPPING_TABLE
            STR     r3,[r0]
            add     r0,r0,#4
            ldr     r2, =0x0FFFFFFF
            and     r1,r1,r2
            ldr     r2, =0x80000000
            add     r1, r2,r1
            STR     r1, [r0]

    The system hangs after it executes the following code:

    adr     r0, g_oalAddressTable
    bl      KernelStart

    It works fine if I remove everything related to  OEMDeviceTable. Do you have any ideas what is wrong here?


    • Edited by Jker Thursday, November 3, 2011 3:04 PM
    Thursday, November 3, 2011 12:06 PM

All replies

  • why don't you try to hardcode the thing at first, just to see what happens, i.e.

      EXPORT g_oalAddressTable[DATA]
      EXPORT g_oalDeviceTable[DATA]
      DCD 0xAF400000, 0x00500000, 1, 0
      DCD 0x00000000, 0x00000000, 0, 0
      DCD CE_NEW_MAPPING_TABLE, g_oalDeviceTable, 0
      DCD 0x80000000,           0x00000000,       512 
      DCD 0, 0, 0; End
      adr     r0, g_oalAddressTable
      bl      KernelStart

    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom Check my blog:
    Thursday, November 3, 2011 3:30 PM
  • I am afraid that it will be used after MMU is enabled. So it will not like to have a physical address there. Therefore I am performing a manual translation by adding 0x80000000 (beginning of RAM in the virtual address space according to g_oalAddressTable) to the physical address of g_oalDeviceTable. Of course another idea would be to try to hardcode this translation there:

    DCD CE_NEW_MAPPING_TABLE, g_oalDeviceTable+0x80000000, 0
    DCD 0x80000000, 0x00000000, 512
    DCD 0, 0, 0; End

    But I don't know if it is going to work there


    Thursday, November 3, 2011 4:09 PM
  • Well, it just hangs no matter what I try. Leaves me comletely clueless.


    DCD CE_NEW_MAPPING_TABLE, g_oalDeviceTable, 0;Tried to hardcode any reasonable addresses

    DCD 0x80000000, 0x00000000, 512 ;SDRAM 512MB

    DCD 0xAF400000, 0x50000000, 1, 0;PERIPHERIAL

    g_oalDeviceTable; Empty table     
    DCD 0x00000000, 0x00000000, 0, 0;end of table

    It also hangs with empty device table... I have run out of ideas.

    Friday, November 4, 2011 9:32 AM
  • Has anyone actually used this OEMDeviceTable before? Can it be a bug in Windows Compact 7?

    I have verified all the addresses. They are correct. There is only one page in the Internet (MSDN), which describes how to use this table.

    To use OEMDeviceTable, the first entry in the OEMAddressTablemust point to OEMDeviceTable, using the following syntax:

    CE_NEW_MAPPING_TABLE, <OEMDeviceTable>, 0

    <OEMDeviceTable> must be a pointer to OEMDeviceTable.

    I have tried everything physical address, cached & uncached virtual address pointers. It points exactly to the beginning of OEMDeviceTable. It doesn't matter if this table is empty or has some entries. Is there anything else not mentioned in this page?

    Can it just treat CE_NEW_MAPPING_TABLE as a virtual address instead of special case? So in this case it is obviously a bug in Windows Compact 7. No source code, no answer. It seems that nothing can be done about it.


    Friday, November 4, 2011 4:45 PM
  • I think you are going about it wrong. It looks like you are doing this to use the full 512mb RAM.

    A better way is map 256mb RAM and your peripherals in the OEMAddressTable then add the additional 256mb RAM by using the OEMRAMTable feature.

    The additional RAM will be added dynamically at start up ..similar to the old CE6 OEMEnumExtension method.

    Friday, November 4, 2011 8:24 PM
  • Note that once you opt in the new address table format (CE_NEW_MAPPING_TABLE in first entry of OEMAddressTable), regardless using device table or not, the uncached memory aliasing will no longer exist. ie. all of the entries in OEMAddressTable only create cached static mapping, any periperal mapping need to be listed in OEMDeviceTable or use CreateStaticMapping.
    If your BSP makes any assumption of cached/non-cached alias mapping, it needs to be rewritten.
    Friday, November 4, 2011 11:01 PM
  • I have also tried the following:

    DCD CE_NEW_MAPPING_TABLE, 0x00000000, 0; latter we need to fill the second parameter with a virtual address of OEMDEVICETABLE by adding 0x80000000 to g_oalDeviceTable

    DCD 0x80000000, 0x00000000, 256 ;SDRAM

    DCD 0x90000000, 0x50000000,1 ;Peripheral

    DCD 0,0,0

    g_oalDeviceTable; Empty table     
    DCD 0x00000000, 0x00000000, 0, 0;end of table

    But it hanged somewhere in kernelstart before reaching OEMInitDebugSerial

    No clue here.

    config.bib was also changed to support a new memory model.

    in startup.s it doesn't do anything special. It just fills the second parameter in g_oalAddressTable with g_oalDeviceTable+0x80000000, then clears caches and jumps to KernelStart with the address of g_oalAddressTable in r0 and dies there. Without the first entry in g_oalAddressTable it works completely fine.

    Yes, I just wanted to move all peripheral to OEMDEVICETABLE but first I wanted to be sure that I can add OEMDEVICETABLE without any problems therefore I made a temporary placement for peripheral in g_oalAddressTable.

    • Edited by Jker Saturday, November 5, 2011 2:21 PM
    Friday, November 4, 2011 11:14 PM
  • Which platform you are using? ARM or x86?
    As CEPC already enable new address table, I assume you are using ARM?

    Most of the kernel source code is available if you installed the share source.
    The KernelStart is in private\winceos\COREOS\nk\ldr\arm\armstart.s, it initial the basic VM context and transfer to kernel, kernel.dll.
    Kernel's entry point at NKStartup in private\winceos\COREOS\nk\kernel\arm\mdarm.c
    Since it hanged before OEMInitDebugSerial, so if the address table is correct (at least switch to VM correctly), it probably dead in on of the step in NKStartup before invoking OEMInitDebugSerial.
    If it is somethnig wrong about memory size setup, perhaps you can trace into CalcMaxDeviceMapping (private\winceos\COREOS\nk\kernel\vm.c)
    As OAL and the kernel is fixed up in virtaul address, the kernel also reference OEMDeviceTable with MMU enabled context, the g_oalDeviceTable should not need the 2GB offset.

    Saturday, November 5, 2011 12:44 AM
  • Yes, it's ARM.

    Where can I get the share source that you mentioned? Is it publicly available?

    Well, and about your last sentence what do you mean by saying that g_oalDeviceTable shouldn't need 2GB offset? I am providing a pointer to g_oalDeviceTable in startup.s before calling KernelStart:

    adr r1, g_oalDeviceTable; physical address of the device table

    adr r0, g_oalAddressTable; physical address of the address table

    ldr  r2, =0x80000000; RAM offset from address 0x0 where virtual RAM space begins

    ldr r3, =0x87654321; CE_NEW_MAPPING_TABLE, could be ldr r3, =CE_NEW_MAPPING_TABLE

    str r3, [r0],#4

    add r1, r1, r2; adding offset for virtual RAM

    str r1,[r0],#4

    Did you mean that the kernel would do this translation for me so the physical address was needed instead of a virtual one? BTW is there a way how it can be achieved in a different way?

    Will the kernel ignore g_oalDeviceTable till I call OALPAtoVA(phys_addr,0) so it will use g_oalDeviceTable for OALPAtoVA(phys_addr,0) and g_oalAddressTable for OALPAtoVA(phys_addr,1)?

    Another question is why should the physical address be right-shifted by 8 bits in g_oalDeviceTable and why is the same not done for g_oalAddressTable?


    Saturday, November 5, 2011 11:25 AM
  • Yes there is another way that is much simpler. See my above suggestion.

    I have used the above method to map 512mb RAM and all my peripheral space on an ARM platform and it works just fine. Unless you really need device space in excess of 512Mb you really don't need to use the DeviceTable.

    Saturday, November 5, 2011 12:08 PM
  • Firstly, you should really get the private tree (shared source) installed, the answer of your questions are all there.
    The Shared source is part of CE7 installation, perhaps you didn't include it during your setup.
    If I remembered correctly, only official release of CE7 includes share source but evaluation version.

    Than back to your questions.
    You may want to try others suggestion first, try to hardcode thing first.
    As ROMIMAGE (MAKEIMG) will fixup address for you, so no neeed to add PA to VA offset in the table.
    And how do you determine it hang before OEMInitDebugSerial? Do you use hardware debugger?
    Since the device table only cover 1 MB, is your UART (assume debug port using UART) covered by this range?
    Since OAL's OEMInitDebugSerial also depends on the mapping listed in device table, so if you didn't configure the table correctly, OEMInitDebugSerial may not find the proper mapping and fail the initialization.

    For the shifted 8 bits part, once you have share source installed, just take a look at MapDeviceTable in private\winceos\COREOS\nk\kernel\vm.c.
    It is just by design in that way.

    And for ARMv7 processors, even you don't have more than 512mb, it is still better to use device table to avoid conflict mapping.

    Monday, November 7, 2011 8:00 PM
  • Hi Dave,

    I am using CE7 and OMAP3730 BSP from Adeneo.  I am trying to follow your suggestion to map 512MB RAM and all peripheral space on my custom board having 512MB DDR.  However, the board hangs after displaying "Jumping to bootloader" on the hyperterminal.

    I added the following code in init.c:

    #define DEVICE_RAM_512_PA    0x90000000    // upper 256mb of 512mb RAM boundry

    // Global Variables
    RAMTableEntry g_RamTableEntry[2] =
        // add another 256meg (512 total) at 0x90000000 physical
        //physical memory start address >> 8, memory size, attribute must be 0
        {(DEVICE_RAM_512_PA) >> 8, 256 * 1024 * 1024, 0},   
        {(0xA0000000) >> 8, 0, 0}    

    RamTable g_RAMTable = {MAKELONG(CE_MINOR_VER, CE_MAJOR_VER), sizeof(g_RamTableEntry) / sizeof(g_RamTableEntry[0]), g_RamTableEntry};

    // Function: OEMGetRamTable
    //      This function is implemented by the OEM to return the OEMRamTable structure,
    //      which allows your platform to support more than 512 MB of physical memory.
    // Parameters:
    // Returns:
    //      Returns an OEMRamTable structure, as defined in %_WINCEROOT%\Public\Common\Oak\Inc\OEMGlobal.h.
    PCRamTable OEMGetRamTable(void)
        return &g_RAMTable;



    #if (_WINCEOSVER >= 700)
            VfpOemInit(g_pOemGlobal, VFP_AUTO_DETECT_FPSID);

        // Adding the following code to initialize 512 RAM
        g_pOemGlobal->pfnGetOEMRamTable = OEMGetRamTable;


    In, I change OEMRamTable from

        DCD     0x80000000, 0x80000000, 256     ; SDRAM
        DCD     0x95000000, 0x15000000,  16     ; CS5, LAN9115
        DCD     0x96000000, 0x48000000,  16     ; L4 Core/Wakeup registers
        DCD     0x97000000, 0x49000000,   1     ; L4 Peripheral
        DCD     0x97100000, 0x68000000,  16     ; L3 registers
        DCD     0x98100000, 0x6C000000,  16     ; SMS registers
        DCD     0x99100000, 0x6D000000,  16     ; SDRC registers
        DCD     0x9a100000, 0x6E000000,  16     ; GPMC registers
        DCD     0x9b100000, 0x40200000,   1     ; 64KB SRAM
        DCD     0x9b200000, 0x5C000000,  16     ; IPSS interconnect
        DCD     0x9C200000, 0x00000000,   1     ; ROM
        DCD     0x9C300000, 0x08000000,   1     ; NAND Registers (FIFO)
        DCD     0x00000000, 0x00000000,   0     ; end of table


        DCD     0x80000000, 0x80000000, 256     ; SDRAM
        DCD     0xA5000000, 0x15000000,  16     ; CS5, LAN9115
        DCD     0xA6000000, 0x48000000,  16     ; L4 Core/Wakeup registers
        DCD     0xA7000000, 0x49000000,   1     ; L4 Peripheral
        DCD     0xA7100000, 0x68000000,  16     ; L3 registers
        DCD     0xA8100000, 0x6C000000,  16     ; SMS registers
        DCD     0xA9100000, 0x6D000000,  16     ; SDRC registers
        DCD     0xAa100000, 0x6E000000,  16     ; GPMC registers
        DCD     0xAb100000, 0x40200000,   1     ; 64KB SRAM
        DCD     0xAb200000, 0x5C000000,  16     ; IPSS interconnect
        DCD     0xAC200000, 0x00000000,   1     ; ROM
        DCD     0xAC300000, 0x08000000,   1     ; NAND Registers (FIFO)
        DCD     0x00000000, 0x00000000,   0     ; end of table

    I basically change the virtual addresses for all devices from 0x9XX00000 to 0xAXX00000 but keep the RAM address the same.

    Would you please show me what I did wrong?  I appreciate your help in expanding your suggestion to detail the changes required to get 512MB of RAM.


    Luan Le

    Tuesday, February 12, 2013 11:01 PM