mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
x86/platform_drv: add Platform::Session::dma_addr
This patch adds the designated alternative to Dataspace::phys_addr to the platform-session interface. Under the hood, the platform driver still calls Dataspace::phys_addr but it should eventuelly become the only caller before we can abolish this function. Issue #2243
This commit is contained in:
parent
97a9ad114c
commit
3ed8df9089
@ -44,6 +44,9 @@ struct Platform::Client : public Genode::Rpc_client<Session>
|
||||
void free_dma_buffer(Genode::Ram_dataspace_capability cap) override {
|
||||
call<Rpc_free_dma_buffer>(cap); }
|
||||
|
||||
Genode::addr_t dma_addr(Genode::Ram_dataspace_capability cap) override {
|
||||
return call<Rpc_dma_addr>(cap); }
|
||||
|
||||
Device_capability device(String const &device) override {
|
||||
return call<Rpc_device>(device); }
|
||||
};
|
||||
|
@ -68,13 +68,13 @@ struct Platform::Session : Genode::Session
|
||||
typedef Genode::Rpc_in_buffer<8> String;
|
||||
|
||||
/**
|
||||
* Provide non-PCI device known by unique name.
|
||||
* Provide non-PCI device known by unique name
|
||||
*/
|
||||
virtual Device_capability device(String const &string) = 0;
|
||||
|
||||
/**
|
||||
* Allocate memory suitable for DMA.
|
||||
*/
|
||||
* Allocate memory suitable for DMA
|
||||
*/
|
||||
virtual Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t) = 0;
|
||||
|
||||
/**
|
||||
@ -82,6 +82,10 @@ struct Platform::Session : Genode::Session
|
||||
*/
|
||||
virtual void free_dma_buffer(Genode::Ram_dataspace_capability) = 0;
|
||||
|
||||
/**
|
||||
* Return the bus address of the previously allocated DMA memory
|
||||
*/
|
||||
virtual Genode::addr_t dma_addr(Genode::Ram_dataspace_capability) = 0;
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
@ -100,13 +104,15 @@ struct Platform::Session : Genode::Session
|
||||
Genode::size_t);
|
||||
GENODE_RPC(Rpc_free_dma_buffer, void, free_dma_buffer,
|
||||
Genode::Ram_dataspace_capability);
|
||||
GENODE_RPC(Rpc_dma_addr, Genode::addr_t, dma_addr,
|
||||
Genode::Ram_dataspace_capability);
|
||||
GENODE_RPC_THROW(Rpc_device, Device_capability, device,
|
||||
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
|
||||
String const &);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_first_device, Rpc_next_device,
|
||||
Rpc_release_device, Rpc_alloc_dma_buffer,
|
||||
Rpc_free_dma_buffer, Rpc_device);
|
||||
Rpc_free_dma_buffer, Rpc_dma_addr, Rpc_device);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__SPEC__X86__PLATFORM_SESSION__PLATFORM_SESSION_H_ */
|
||||
|
@ -20,19 +20,19 @@
|
||||
|
||||
#include "device_pd.h"
|
||||
|
||||
void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap)
|
||||
void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap,
|
||||
Genode::addr_t const dma_addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Dataspace_client ds_client(ds_cap);
|
||||
|
||||
addr_t const phys = ds_client.phys_addr();
|
||||
size_t const size = ds_client.size();
|
||||
|
||||
addr_t page = ~0UL;
|
||||
|
||||
try {
|
||||
page = _address_space.attach_at(ds_cap, phys);
|
||||
page = _address_space.attach_at(ds_cap, dma_addr);
|
||||
/* trigger eager mapping of memory */
|
||||
_pd.map(page, size);
|
||||
}
|
||||
@ -42,18 +42,19 @@ void Platform::Device_pd::attach_dma_mem(Genode::Dataspace_capability ds_cap)
|
||||
/*
|
||||
* DMA memory already attached before.
|
||||
*/
|
||||
page = phys;
|
||||
page = dma_addr;
|
||||
} catch (...) {
|
||||
error(_label, ": attach_at or map failed");
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if ((page == ~0UL) || (page != phys)) {
|
||||
if ((page == ~0UL) || (page != dma_addr)) {
|
||||
if (page != ~0UL)
|
||||
_address_space.detach(page);
|
||||
|
||||
Genode::error(_label, ": attachment of DMA memory @ ",
|
||||
Genode::Hex(phys), "+", Genode::Hex(size), " failed page=", Genode::Hex(page));
|
||||
Genode::Hex(dma_addr), "+", Genode::Hex(size), " "
|
||||
"failed page=", Genode::Hex(page));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -93,7 +94,6 @@ void Platform::Device_pd::assign_pci(Genode::Io_mem_dataspace_capability const i
|
||||
/* try to assign pci device to this protection domain */
|
||||
if (!_pd.assign_pci(page, rid))
|
||||
Genode::error(_label, ": assignment of PCI device ", Rid(rid), " failed ",
|
||||
"phys=", Genode::Hex(ds_client.phys_addr() + offset), " "
|
||||
"virt=", Genode::Hex(page));
|
||||
else
|
||||
Genode::log(_label,": assignment of PCI device ", Rid(rid), " succeeded");
|
||||
|
@ -110,7 +110,7 @@ class Platform::Device_pd
|
||||
_pd.ref_account(env.pd_session_cap());
|
||||
}
|
||||
|
||||
void attach_dma_mem(Genode::Dataspace_capability);
|
||||
void attach_dma_mem(Genode::Dataspace_capability, Genode::addr_t dma_addr);
|
||||
void assign_pci(Genode::Io_mem_dataspace_capability const,
|
||||
Genode::addr_t const, Genode::uint16_t const);
|
||||
};
|
||||
|
@ -71,9 +71,15 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
||||
|
||||
public:
|
||||
|
||||
Io_mem (Genode::Env &env, Genode::addr_t base,
|
||||
Genode::size_t size, bool wc)
|
||||
: Genode::Io_mem_connection(env, base, size, wc) { }
|
||||
Genode::addr_t const base;
|
||||
Genode::size_t const size;
|
||||
|
||||
Io_mem(Genode::Env &env, Genode::addr_t base,
|
||||
Genode::size_t size, bool wc)
|
||||
:
|
||||
Genode::Io_mem_connection(env, base, size, wc),
|
||||
base(base), size(size)
|
||||
{ }
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -309,13 +315,11 @@ class Platform::Device_component : public Genode::Rpc_object<Platform::Device>,
|
||||
|
||||
for (Io_mem * io_mem = _io_mem[i].first(); io_mem; io_mem = io_mem->next()) {
|
||||
|
||||
Dataspace_client ds_client(io_mem->dataspace());
|
||||
|
||||
if (!(ds_client.phys_addr() <= msix_table_phys &&
|
||||
msix_table_phys + msix_table_size <= ds_client.phys_addr() + ds_client.size()))
|
||||
if (!(io_mem->base <= msix_table_phys &&
|
||||
msix_table_phys + msix_table_size <= io_mem->base + io_mem->size))
|
||||
continue;
|
||||
|
||||
Genode::size_t const offset = msix_table_phys - ds_client.phys_addr();
|
||||
Genode::size_t const offset = msix_table_phys - io_mem->base;
|
||||
|
||||
Attached_dataspace mem_io(_env.rm(), io_mem->dataspace());
|
||||
|
||||
|
@ -120,6 +120,8 @@ class Platform::Rmrr : public Genode::List<Platform::Rmrr>::Element
|
||||
return Genode::Io_mem_dataspace_capability();
|
||||
}
|
||||
|
||||
addr_t start() const { return _start; }
|
||||
|
||||
void add(Bdf * bdf) { _bdf_list.insert(bdf); }
|
||||
|
||||
static Genode::List<Rmrr> *list()
|
||||
@ -208,6 +210,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
Genode::Env &_env;
|
||||
Genode::Attached_rom_dataspace &_config;
|
||||
Genode::Attached_io_mem_dataspace &_pciconf;
|
||||
Genode::addr_t const _pciconf_base;
|
||||
Genode::Ram_quota_guard _ram_guard;
|
||||
Genode::Cap_quota_guard _cap_guard;
|
||||
Genode::Constrained_ram_allocator _env_ram {
|
||||
@ -230,6 +233,15 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
void _insert(Ram_capability cap) {
|
||||
_ram_caps.insert(new (_md_alloc) Platform::Ram_dataspace(cap)); }
|
||||
|
||||
bool _owned(Ram_capability cap)
|
||||
{
|
||||
for (Ram_dataspace *ds = _ram_caps.first(); ds; ds = ds->next())
|
||||
if (ds->match(cap))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _remove(Ram_capability cap)
|
||||
{
|
||||
for (Platform::Ram_dataspace *ds = _ram_caps.first(); ds;
|
||||
@ -469,6 +481,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
Session_component(Genode::Env &env,
|
||||
Genode::Attached_rom_dataspace &config,
|
||||
Genode::Attached_io_mem_dataspace &pciconf,
|
||||
Genode::addr_t pciconf_base,
|
||||
Platform::Pci_buses &buses,
|
||||
Genode::Heap &global_heap,
|
||||
Pci::Config::Delayer &delayer,
|
||||
@ -479,6 +492,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
_env(env),
|
||||
_config(config),
|
||||
_pciconf(pciconf),
|
||||
_pciconf_base(pciconf_base),
|
||||
_ram_guard(Genode::ram_quota_from_args(args)),
|
||||
_cap_guard(Genode::cap_quota_from_args(args)),
|
||||
_md_alloc(_env_ram, env.rm()),
|
||||
@ -792,7 +806,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
return;
|
||||
|
||||
try {
|
||||
addr_t const base_ecam = Dataspace_client(_pciconf.cap()).phys_addr();
|
||||
addr_t const base_ecam = _pciconf_base;
|
||||
addr_t const base_offset = 0x1000UL * device->device_config().bdf().value();
|
||||
|
||||
if (base_ecam + base_offset != device->config_space())
|
||||
@ -801,7 +815,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
for (Rmrr *r = Rmrr::list()->first(); r; r = r->next()) {
|
||||
Io_mem_dataspace_capability rmrr_cap = r->match(_env, device->device_config());
|
||||
if (rmrr_cap.valid())
|
||||
_device_pd.attach_dma_mem(rmrr_cap);
|
||||
_device_pd.attach_dma_mem(rmrr_cap, r->start());
|
||||
}
|
||||
|
||||
_device_pd.assign_pci(_pciconf.cap(), base_offset,
|
||||
@ -819,12 +833,13 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
Ram_capability alloc_dma_buffer(Genode::size_t const size) override
|
||||
{
|
||||
Ram_capability ram_cap = _env_ram.alloc(size, Genode::UNCACHED);
|
||||
addr_t const dma_addr = Dataspace_client(ram_cap).phys_addr();
|
||||
|
||||
if (!ram_cap.valid())
|
||||
return ram_cap;
|
||||
|
||||
try {
|
||||
_device_pd.attach_dma_mem(ram_cap);
|
||||
_device_pd.attach_dma_mem(ram_cap, dma_addr);
|
||||
_insert(ram_cap);
|
||||
} catch (Out_of_ram) {
|
||||
_env_ram.free(ram_cap);
|
||||
@ -845,6 +860,14 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
|
||||
_env_ram.free(ram_cap);
|
||||
}
|
||||
|
||||
Genode::addr_t dma_addr(Ram_capability ram_cap) override
|
||||
{
|
||||
if (!ram_cap.valid() || !_owned(ram_cap))
|
||||
return 0;
|
||||
|
||||
return Dataspace_client(ram_cap).phys_addr();
|
||||
}
|
||||
|
||||
Device_capability device(String const &name) override;
|
||||
};
|
||||
|
||||
@ -857,6 +880,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
Genode::Attached_rom_dataspace &_config;
|
||||
|
||||
Genode::Constructible<Genode::Attached_io_mem_dataspace> _pci_confspace { };
|
||||
Genode::addr_t _pci_confspace_base = 0;
|
||||
|
||||
Genode::Constructible<Genode::Expanding_reporter> _pci_reporter { };
|
||||
|
||||
@ -913,6 +937,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
log("ECAM/MMCONF range ", bdf_first, "-", bdf_last, " - addr ",
|
||||
Hex_range<addr_t>(base, memory_size));
|
||||
|
||||
_pci_confspace_base = base;
|
||||
_pci_confspace.construct(env, base, memory_size);
|
||||
});
|
||||
|
||||
@ -1020,7 +1045,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
void _construct_buses()
|
||||
{
|
||||
Genode::Dataspace_client ds_pci_mmio(_pci_confspace->cap());
|
||||
uint64_t const phys_addr = ds_pci_mmio.phys_addr();
|
||||
uint64_t const phys_addr = _pci_confspace_base;
|
||||
uint64_t const phys_size = ds_pci_mmio.size();
|
||||
uint64_t mmio_size = 0x10000000UL; /* max MMCONF memory */
|
||||
|
||||
@ -1065,6 +1090,7 @@ class Platform::Root : public Genode::Root_component<Session_component>
|
||||
Genode::Registered<Session_component>(_sessions, _env,
|
||||
_config,
|
||||
*_pci_confspace,
|
||||
_pci_confspace_base,
|
||||
*_buses, _heap,
|
||||
_delayer,
|
||||
_devices_bars, args,
|
||||
|
Loading…
x
Reference in New Issue
Block a user