dde_ipxe: alloc DMA memory via dde_kit

This commit is contained in:
Alexander Boettcher 2013-02-21 13:45:39 +01:00 committed by Norman Feske
parent 415b50032e
commit 269efd1d6d
3 changed files with 37 additions and 29 deletions

View File

@ -14,64 +14,59 @@
#include <base/allocator_avl.h> #include <base/allocator_avl.h>
#include <base/env.h> #include <base/env.h>
#include <base/printf.h> #include <base/printf.h>
#include <dataspace/client.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#include <util/misc_math.h> #include <util/misc_math.h>
extern "C" { extern "C" {
#include <dde_kit/pgtab.h> #include <dde_kit/pci.h>
#include "dde_support.h" #include "dde_support.h"
} }
using namespace Genode; using namespace Genode;
/******************************************* /***************************************************
** Support for aligned memory allocation ** ** Support for aligned and DMA memory allocation **
*******************************************/ ***************************************************/
enum { BACKING_STORE_SIZE = 1024 * 1024 }; enum { BACKING_STORE_SIZE = 1024 * 1024 };
Allocator_avl *allocator() static Allocator_avl& allocator()
{ {
static Allocator_avl _avl(env()->heap()); static Allocator_avl _avl(env()->heap());
return &_avl; return _avl;
} }
extern "C" int dde_mem_init(int bus, int dev, int func)
void __attribute__((constructor)) init()
{ {
try { try {
Dataspace_capability ds_cap = env()->ram_session()->alloc(BACKING_STORE_SIZE); addr_t base = dde_kit_pci_alloc_dma_buffer(bus, dev, func,
addr_t base = (addr_t)env()->rm_session()->attach(ds_cap); BACKING_STORE_SIZE);
/* add to allocator */ /* add to allocator */
allocator()->add_range(base, BACKING_STORE_SIZE); allocator().add_range(base, BACKING_STORE_SIZE);
/* add to DDE-kit page tables */
addr_t phys = Dataspace_client(ds_cap).phys_addr();
dde_kit_pgtab_set_region_with_size((void *)base, phys, BACKING_STORE_SIZE);
} catch (...) { } catch (...) {
PERR("Initialization of block memory failed!"); return false;
} }
return true;
} }
extern "C" void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align,
extern "C" void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align, dde_kit_size_t offset) dde_kit_size_t offset)
{ {
void *ptr; void *ptr;
if (allocator()->alloc_aligned(size, &ptr, log2(align)).is_error()) { if (allocator().alloc_aligned(size, &ptr, log2(align)).is_error()) {
PERR("memory allocation failed in alloc_memblock (size=%zd, align=%zx, offset=%zx)", PERR("memory allocation failed in alloc_memblock (size=%zd, align=%zx,"
size, align, offset); " offset=%zx)", size, align, offset);
return 0; return 0;
}; }
return ptr; return ptr;
} }
extern "C" void dde_free_memblock(void *p, dde_kit_size_t size) extern "C" void dde_free_memblock(void *p, dde_kit_size_t size)
{ {
allocator()->free(p, size); allocator().free(p, size);
} }
@ -84,8 +79,8 @@ extern "C" void dde_timer2_udelay(unsigned long usecs)
/* /*
* This function is called only once during rdtsc calibration (usecs will be * This function is called only once during rdtsc calibration (usecs will be
* 10000, see dde.c 'udelay'. We do not use DDE timers here, since Genode's * 10000, see dde.c 'udelay'. We do not use DDE timers here, since Genode's
* timer connection is the precised one around. * timer connection is the most precise one around.
*/ */
Timer::Connection timer; Timer::Connection timer;
timer.msleep(usecs / 1000); timer.usleep(usecs);
} }

View File

@ -17,8 +17,10 @@
#include <dde_kit/types.h> #include <dde_kit/types.h>
void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align, dde_kit_size_t offset); void *dde_alloc_memblock(dde_kit_size_t size, dde_kit_size_t align,
dde_kit_size_t offset);
void dde_free_memblock(void *p, dde_kit_size_t size); void dde_free_memblock(void *p, dde_kit_size_t size);
void dde_timer2_udelay(unsigned long usecs); void dde_timer2_udelay(unsigned long usecs);
int dde_mem_init(int bus, int dev, int func);
#endif /* _DDE_SUPPORT_H_ */ #endif /* _DDE_SUPPORT_H_ */

View File

@ -27,6 +27,7 @@
#include <dde_ipxe/nic.h> #include <dde_ipxe/nic.h>
#include "local.h" #include "local.h"
#include "dde_support.h"
/** /**
* DDE iPXE mutual exclusion lock * DDE iPXE mutual exclusion lock
@ -310,8 +311,18 @@ int dde_ipxe_nic_init(void)
if (location == NO_DEVICE_FOUND) if (location == NO_DEVICE_FOUND)
return 0; return 0;
/* find and open iPXE NIC device */ /* find iPXE NIC device */
net_dev = find_netdev_by_location(BUS_TYPE_PCI, location); net_dev = find_netdev_by_location(BUS_TYPE_PCI, location);
/* initialize memory backend allocator for nic driver */
if (!dde_mem_init(PCI_BUS(net_dev->dev->desc.location),
PCI_SLOT(net_dev->dev->desc.location),
PCI_FUNC(net_dev->dev->desc.location))) {
LOG("initialization of block memory failed!");
return 0;
}
/* open iPXE NIC device */
if (netdev_open(net_dev)) { if (netdev_open(net_dev)) {
LOG("opening device " FMT_BUSDEVFN " failed", LOG("opening device " FMT_BUSDEVFN " failed",
PCI_BUS(net_dev->dev->desc.location), PCI_BUS(net_dev->dev->desc.location),