mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-29 07:19:45 +00:00
parent
3eed3ad329
commit
2ceecd44f9
@ -121,15 +121,6 @@ class Pci_driver : public Bsd::Bus_driver
|
|||||||
Genode::Ram_dataspace_capability _alloc_dma_memory(Genode::size_t size)
|
Genode::Ram_dataspace_capability _alloc_dma_memory(Genode::size_t size)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
/* trigger that the device gets assigned to this driver (needed by IOMMUs) */
|
|
||||||
for (unsigned i = 0; i < 2; i++)
|
|
||||||
try {
|
|
||||||
_pci.config_extended(_cap);
|
|
||||||
break;
|
|
||||||
} catch (Pci::Device::Quota_exceeded) {
|
|
||||||
Genode::env()->parent()->upgrade(_pci.cap(), "ram_quota=4096");
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu", size);
|
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zu", size);
|
||||||
Genode::env()->parent()->upgrade(_pci.cap(), buf);
|
Genode::env()->parent()->upgrade(_pci.cap(), buf);
|
||||||
|
@ -200,16 +200,6 @@ struct Pci_driver
|
|||||||
try {
|
try {
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
/* trigger that the device gets assigned to this driver */
|
|
||||||
for (unsigned i = 0; i < 2; i++) {
|
|
||||||
try {
|
|
||||||
_pci.config_extended(_cap);
|
|
||||||
break;
|
|
||||||
} catch (Pci::Device::Quota_exceeded) {
|
|
||||||
Genode::env()->parent()->upgrade(_pci.cap(), "ram_quota=4096");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* transfer quota to pci driver, otherwise it will give us a exception */
|
/* transfer quota to pci driver, otherwise it will give us a exception */
|
||||||
char buf[32];
|
char buf[32];
|
||||||
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zd", size);
|
Genode::snprintf(buf, sizeof(buf), "ram_quota=%zd", size);
|
||||||
|
@ -313,9 +313,6 @@ int pci_register_driver(struct pci_driver *drv)
|
|||||||
|
|
||||||
Pci_driver *pci_drv = 0;
|
Pci_driver *pci_drv = 0;
|
||||||
try {
|
try {
|
||||||
/* trigger that the device get be assigned to the usb driver */
|
|
||||||
pci.config_extended(cap);
|
|
||||||
|
|
||||||
/* probe device */
|
/* probe device */
|
||||||
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
|
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
|
||||||
pci.on_destruction(Pci::Connection::KEEP_OPEN);
|
pci.on_destruction(Pci::Connection::KEEP_OPEN);
|
||||||
|
@ -295,9 +295,6 @@ extern "C" int pci_register_driver(struct pci_driver *drv)
|
|||||||
try {
|
try {
|
||||||
pci_device_cap = cap;
|
pci_device_cap = cap;
|
||||||
|
|
||||||
/* trigger that the device get be assigned to the wifi driver */
|
|
||||||
pci()->config_extended(cap);
|
|
||||||
|
|
||||||
/* probe device */
|
/* probe device */
|
||||||
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
|
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
|
||||||
pci()->on_destruction(Pci::Connection::KEEP_OPEN);
|
pci()->on_destruction(Pci::Connection::KEEP_OPEN);
|
||||||
|
@ -36,6 +36,7 @@ class Ahci_device : public Ahci_device_base
|
|||||||
CLASS_MASK = 0xffff00U,
|
CLASS_MASK = 0xffff00U,
|
||||||
AHCI_BASE_ID = 0x5, /* resource id of AHCI base addr <BAR 5> */
|
AHCI_BASE_ID = 0x5, /* resource id of AHCI base addr <BAR 5> */
|
||||||
AHCI_INTR_OFF = 0x3c, /* offset of interrupt information in config space */
|
AHCI_INTR_OFF = 0x3c, /* offset of interrupt information in config space */
|
||||||
|
PCI_CFG_CMD_REG = 0x4,
|
||||||
};
|
};
|
||||||
|
|
||||||
::Pci::Connection &_pci;
|
::Pci::Connection &_pci;
|
||||||
@ -137,6 +138,10 @@ class Ahci_device : public Ahci_device_base
|
|||||||
" %08x)\n", pci_device->vendor_id(),
|
" %08x)\n", pci_device->vendor_id(),
|
||||||
pci_device->device_id(), pci_device->class_code());
|
pci_device->device_id(), pci_device->class_code());
|
||||||
|
|
||||||
|
/* enable Bus Master, Memory Space, I/O Space access by dev */
|
||||||
|
pci_device->config_write(PCI_CFG_CMD_REG, 0x7,
|
||||||
|
::Pci::Device::ACCESS_16BIT);
|
||||||
|
|
||||||
/* read and map base address of AHCI controller */
|
/* read and map base address of AHCI controller */
|
||||||
Pci::Device::Resource resource = pci_device->resource(AHCI_BASE_ID);
|
Pci::Device::Resource resource = pci_device->resource(AHCI_BASE_ID);
|
||||||
|
|
||||||
@ -173,14 +178,6 @@ class Ahci_device : public Ahci_device_base
|
|||||||
device->_irq->ack_irq();
|
device->_irq->ack_irq();
|
||||||
|
|
||||||
device->_pci_device = pci_device;
|
device->_pci_device = pci_device;
|
||||||
/* trigger assignment of pci device to the ahci driver */
|
|
||||||
try {
|
|
||||||
pci.config_extended(device_cap);
|
|
||||||
} catch (Pci::Device::Quota_exceeded) {
|
|
||||||
Genode::env()->parent()->upgrade(pci.cap(), "ram_quota=4096");
|
|
||||||
pci.config_extended(device_cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get device ready */
|
/* get device ready */
|
||||||
device->_init(pci_device);
|
device->_init(pci_device);
|
||||||
|
|
||||||
|
@ -60,3 +60,39 @@ Genode::Io_mem_session_capability Pci::Device_component::io_mem(Genode::uint8_t
|
|||||||
|
|
||||||
return Genode::Io_mem_session_capability();
|
return Genode::Io_mem_session_capability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pci::Device_component::config_write(unsigned char address, unsigned value,
|
||||||
|
Access_size size)
|
||||||
|
{
|
||||||
|
/* white list of ports which we permit to write */
|
||||||
|
switch (address) {
|
||||||
|
case 0x40 ... 0xff: /* allow access to device-specific registers */
|
||||||
|
break;
|
||||||
|
case PCI_CMD_REG: /* COMMAND register - first byte */
|
||||||
|
if (size == Access_size::ACCESS_16BIT)
|
||||||
|
break;
|
||||||
|
case PCI_CMD_REG + 1: /* COMMAND register - second byte */
|
||||||
|
case 0xd: /* Latency timer */
|
||||||
|
if (size == Access_size::ACCESS_8BIT)
|
||||||
|
break;
|
||||||
|
case PCI_IRQ_LINE:
|
||||||
|
/* permitted up to now solely for acpi driver */
|
||||||
|
if (address == PCI_IRQ_LINE && _rewrite_irq_line &&
|
||||||
|
size == Access_size::ACCESS_8BIT)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PWRN("%x:%x:%x write access to address=%x value=0x%x "
|
||||||
|
" size=0x%x got dropped", _device_config.bus_number(),
|
||||||
|
_device_config.device_number(),
|
||||||
|
_device_config.function_number(),
|
||||||
|
address, value, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assign device to device_pd */
|
||||||
|
if (address == PCI_CMD_REG && value & PCI_CMD_DMA && _session)
|
||||||
|
_session->assign_device(this);
|
||||||
|
|
||||||
|
_device_config.write(&_config_access, address, value, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -543,16 +543,32 @@ namespace Pci {
|
|||||||
_device_list.remove(device);
|
_device_list.remove(device);
|
||||||
_ep->dissolve(device);
|
_ep->dissolve(device);
|
||||||
|
|
||||||
Genode::Io_mem_connection * io_mem = device->get_config_space();
|
|
||||||
if (io_mem)
|
|
||||||
destroy(_md_alloc, io_mem);
|
|
||||||
|
|
||||||
if (device->config().valid())
|
if (device->config().valid())
|
||||||
destroy(_device_slab, device);
|
destroy(_device_slab, device);
|
||||||
else
|
else
|
||||||
destroy(_md_alloc, device);
|
destroy(_md_alloc, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Genode::Io_mem_dataspace_capability assign_device(Device_component * device)
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
if (!device || !device->get_config_space().valid())
|
||||||
|
return Io_mem_dataspace_capability();
|
||||||
|
|
||||||
|
Io_mem_dataspace_capability io_mem = device->get_config_space();
|
||||||
|
|
||||||
|
if (_child)
|
||||||
|
_child->assign_pci(io_mem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* By now forbid usage of extended pci config space dataspace,
|
||||||
|
* - until required.
|
||||||
|
*/
|
||||||
|
// return io_mem;
|
||||||
|
return Io_mem_dataspace_capability();
|
||||||
|
}
|
||||||
|
|
||||||
Genode::Io_mem_dataspace_capability config_extended(Device_capability device_cap)
|
Genode::Io_mem_dataspace_capability config_extended(Device_capability device_cap)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
@ -560,33 +576,7 @@ namespace Pci {
|
|||||||
Object_pool<Device_component>::Guard
|
Object_pool<Device_component>::Guard
|
||||||
device(_ep->lookup_and_lock(device_cap));
|
device(_ep->lookup_and_lock(device_cap));
|
||||||
|
|
||||||
if (!device || device->config_space() == ~0UL)
|
return assign_device(device);
|
||||||
return Io_mem_dataspace_capability();
|
|
||||||
|
|
||||||
Io_mem_connection * io_mem = device->get_config_space();
|
|
||||||
if (io_mem)
|
|
||||||
return io_mem->dataspace();
|
|
||||||
|
|
||||||
try {
|
|
||||||
io_mem = new (_md_alloc) Io_mem_connection(device->config_space(),
|
|
||||||
0x1000);
|
|
||||||
} catch (Genode::Allocator::Out_of_memory) {
|
|
||||||
throw Device::Quota_exceeded();
|
|
||||||
} catch (Parent::Service_denied) {
|
|
||||||
return Io_mem_dataspace_capability();
|
|
||||||
}
|
|
||||||
|
|
||||||
device->set_config_space(io_mem);
|
|
||||||
|
|
||||||
if (_child)
|
|
||||||
_child->assign_pci(io_mem->dataspace());
|
|
||||||
|
|
||||||
/*
|
|
||||||
* By now forbid usage of extended pci config space dataspace,
|
|
||||||
* - until required.
|
|
||||||
*/
|
|
||||||
// return io_mem->dataspace();
|
|
||||||
return Io_mem_dataspace_capability();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,18 +126,6 @@ namespace Dde_kit {
|
|||||||
Ram_dataspace_capability alloc_dma_buffer(Pci::Connection &pci_drv,
|
Ram_dataspace_capability alloc_dma_buffer(Pci::Connection &pci_drv,
|
||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
/* trigger that the device gets assigned to this driver */
|
|
||||||
for (unsigned i = 0; i < 2; i++) {
|
|
||||||
try {
|
|
||||||
pci_drv.config_extended(_device);
|
|
||||||
break;
|
|
||||||
} catch (Pci::Device::Quota_exceeded) {
|
|
||||||
if (i == 1)
|
|
||||||
return Ram_dataspace_capability();
|
|
||||||
Genode::env()->parent()->upgrade(pci_drv.cap(), "ram_quota=4096");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 2; i++) {
|
for (unsigned i = 0; i < 2; i++) {
|
||||||
try {
|
try {
|
||||||
return pci_drv.alloc_dma_buffer(size);
|
return pci_drv.alloc_dma_buffer(size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user