OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:29 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Qemu fw_cfg DMA aarch64
PostPosted: Wed May 01, 2019 1:10 pm 
Offline

Joined: Sat Apr 13, 2019 10:55 pm
Posts: 4
I'm attempting DMA access of a fw_cfg file. I have accessed the directory, compared file names and found the file i want. I have compared the reported size to make sure it is correct for what I was expecting. All of these things are true and then I enter fwcfg_dma_access via

Code:
    #define FWCFG_DMA_READ    2
    fwcfg_dma_access(file.select << 16 | FWCFG_DMA_READ, ramfb_file.size, (vaddr_t) &cfg);


Code:
#if __ORDER_LITTLE_ENDIAN__
#define HTOBE(x)  __builtin_bswap32(x)
#define HTOBE64(x) __builtin_bswap64(x)
#else
#define HTOBE(x) x
#define HTOBE64(x) x
#endif

#define FW_CFG_BASE       0x09020000

#define FW_CFG_CTL_OFF       0x08
#define FW_CFG_DATA_OFF    0x00
#define FW_CFG_DMA_OFF       0x10

struct fwcfg_dma_access {
   uint32_t control;
   uint32_t length;
   uint64_t address;
};

static vaddr_t _addr(vaddr_t base, vaddr_t offset)
{
   return (vaddr_t) phys_to_virt(base, MEM_AREA_IO_SEC) + offset;
}

int fwcfg_dma_access(uint32_t ctrl, uint32_t len, vaddr_t addr)
{
   volatile struct fwcfg_dma_access access;
   
   access.control = HTOBE(ctrl);
   access.length = HTOBE(len);
   access.address = HTOBE64(addr);
   
   vaddr_t access_addr = (vaddr_t) virt_to_phys((void*) &access);
   uint32_t access_addr_lo = (uint32_t) (access_addr & 0xFFFFFFFFU);
   uint32_t access_addr_hi = (uint32_t) (access_addr >> 32);
   
   io_write32(_addr(FW_CFG_BASE, FW_CFG_DMA_OFF), HTOBE(access_addr_hi));
   io_write32(_addr(FW_CFG_BASE, FW_CFG_DMA_OFF + 4), HTOBE(access_addr_lo));
   
   DMSG("Waiting on DMA Access");
   while ((HTOBE(access.control) & ~FWCFG_DMA_ERROR) != 0) {}
   DMSG("DMA Access Done");
   
   return FWCFG_OK;
}


The execution gets to "waiting on DMA acess" but never reaches "DMA access done". I pulled the check from Linux kernel. I have also tried:

Code:
   DMSG("Waiting on DMA Access");
   while (io_read32(_addr(FW_CFG_BASE, FW_CFG_DMA_OFF)) != 0) {}
   DMSG("DMA Access Done");


with no success. Anyone have any hints?


Top
 Profile  
 
 Post subject: Re: Qemu fw_cfg DMA aarch64
PostPosted: Mon May 13, 2019 10:20 am 
Offline

Joined: Sat Apr 13, 2019 10:55 pm
Posts: 4
For the posterity of future internet explorers this ended up being an issue in Qemu aarch64. Non-secure devices (FW_CFG at the time of this writing) cannot DMA secure memory (ie Secure ram). Make sure the devices are the same memory security levels.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 85 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group