ahci: transition to the new base API

Issue #1987
This commit is contained in:
Josef Söntgen 2016-05-29 09:50:14 +02:00 committed by Christian Helmuth
parent c77f146e72
commit 0d8d8de42c
7 changed files with 105 additions and 71 deletions

View File

@ -31,6 +31,9 @@ Mmio::Delayer &Hba::delayer()
struct Ahci
{
Genode::Env &env;
Genode::Allocator &alloc;
/* read device signature */
enum Signature {
ATA_SIG = 0x101,
@ -39,7 +42,7 @@ struct Ahci
};
Ahci_root &root;
Platform::Hba &platform_hba = Platform::init(Hba::delayer());
Platform::Hba &platform_hba = Platform::init(env, Hba::delayer());
Hba hba = { platform_hba };
enum { MAX_PORTS = 32 };
@ -51,10 +54,13 @@ struct Ahci
unsigned ready_count = 0;
bool enable_atapi;
Ahci(Ahci_root &root, bool support_atapi)
: root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
device_ready(root.entrypoint(), *this, &Ahci::ready),
enable_atapi(support_atapi)
Ahci(Genode::Env &env, Genode::Allocator &alloc,
Ahci_root &root, bool support_atapi)
:
env(env), alloc(alloc),
root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
device_ready(root.entrypoint(), *this, &Ahci::ready),
enable_atapi(support_atapi)
{
info();
@ -65,7 +71,7 @@ struct Ahci
hba.init();
/* search for devices */
scan_ports();
scan_ports(env.rm());
}
bool atapi(unsigned sig)
@ -118,7 +124,7 @@ struct Ahci
PINF("\t64 bit support: %s", hba.supports_64bit() ? "yes" : "no");
}
void scan_ports()
void scan_ports(Genode::Region_map &rm)
{
PINF("\tnumber of ports: %u pi: %x", hba.port_count(), hba.read<Hba::Pi>());
unsigned available = hba.read<Hba::Pi>();
@ -128,7 +134,7 @@ struct Ahci
if (!(available & (1U << i)))
continue;
Port port(hba, platform_hba, i);
Port port(rm, hba, platform_hba, i);
/* check for ATA/ATAPI devices */
unsigned sig = port.read<Port::Sig>();
@ -152,13 +158,13 @@ struct Ahci
switch (sig) {
case ATA_SIG:
ports[i] = new (Genode::env()->heap()) Ata_driver(port, device_ready);
ports[i] = new (&alloc) Ata_driver(alloc, port, device_ready);
ready_count++;
break;
case ATAPI_SIG:
case ATAPI_SIG_QEMU:
ports[i] = new (Genode::env()->heap()) Atapi_driver(port, device_ready);
ports[i] = new (&alloc) Atapi_driver(port, device_ready);
ready_count++;
break;
@ -210,9 +216,10 @@ static Ahci *sata_ahci(Ahci *ahci = 0)
}
void Ahci_driver::init(Ahci_root &root, bool support_atapi)
void Ahci_driver::init(Genode::Env &env, Genode::Allocator &alloc,
Ahci_root &root, bool support_atapi)
{
static Ahci ahci(root, support_atapi);
static Ahci ahci(env, alloc, root, support_atapi);
sata_ahci(&ahci);
}

View File

@ -23,7 +23,7 @@ static bool constexpr verbose = false;
namespace Platform {
struct Hba;
Hba &init(Genode::Mmio::Delayer &delayer);
Hba &init(Genode::Env &env, Genode::Mmio::Delayer &delayer);
};
@ -36,7 +36,7 @@ struct Ahci_root
namespace Ahci_driver {
void init(Ahci_root &ep, bool support_atapi);
void init(Genode::Env &env, Genode::Allocator &alloc, Ahci_root &ep, bool support_atapi);
bool avail(long device_num);
long device_number(char const *model_num, char const *serial_num);
@ -393,6 +393,7 @@ struct Port : Genode::Mmio
{
struct Not_ready : Genode::Exception { };
Genode::Region_map &rm;
Hba &hba;
Platform::Hba &platform_hba;
@ -417,9 +418,11 @@ struct Port : Genode::Mmio
State state = NONE;
Port(Hba &hba, Platform::Hba &platform_hba, unsigned number)
: Mmio(hba.base + offset() + (number * size())), hba(hba),
platform_hba(platform_hba)
Port(Genode::Region_map &rm, Hba &hba, Platform::Hba &platform_hba,
unsigned number)
:
Mmio(hba.base + offset() + (number * size())),
rm(rm), hba(hba), platform_hba(platform_hba)
{
stop();
if (!wait_for<Cmd::Cr>(0, Hba::delayer(), 500, 1000))
@ -429,17 +432,17 @@ struct Port : Genode::Mmio
virtual ~Port()
{
if (device_ds.valid()) {
Genode::env()->rm_session()->detach((void *)cmd_list);
rm.detach((void *)cmd_list);
platform_hba.free_dma_buffer(device_ds);
}
if (cmd_ds.valid()) {
Genode::env()->rm_session()->detach((void *)cmd_table);
rm.detach((void *)cmd_table);
platform_hba.free_dma_buffer(cmd_ds);
}
if (device_info_ds.valid()) {
Genode::env()->rm_session()->detach((void*)device_info);
rm.detach((void*)device_info);
platform_hba.free_dma_buffer(device_info_ds);
}
}
@ -743,7 +746,7 @@ struct Port : Genode::Mmio
/* command list 1K */
addr_t phys = Genode::Dataspace_client(device_ds).phys_addr();
cmd_list = (addr_t)Genode::env()->rm_session()->attach(device_ds);
cmd_list = (addr_t)rm.attach(device_ds);
command_list_base(phys);
/* receive FIS base 256 byte */
@ -753,7 +756,7 @@ struct Port : Genode::Mmio
/* command table */
size_t cmd_size = Genode::align_addr(cmd_slots * Command_table::size(), 12);
cmd_ds = platform_hba.alloc_dma_buffer(cmd_size);
cmd_table = (addr_t)Genode::env()->rm_session()->attach(cmd_ds);
cmd_table = (addr_t)rm.attach(cmd_ds);
phys = (addr_t)Genode::Dataspace_client(cmd_ds).phys_addr();
/* set command table addresses in command list */
@ -764,7 +767,7 @@ struct Port : Genode::Mmio
/* dataspace for device info */
device_info_ds = platform_hba.alloc_dma_buffer(0x1000);
device_info = Genode::env()->rm_session()->attach(device_info_ds);
device_info = rm.attach(device_info_ds);
}
Genode::addr_t command_table_addr(unsigned slot)

View File

@ -172,6 +172,8 @@ struct Dma_ext_command : Io_command
*/
struct Ata_driver : Port_driver
{
Genode::Allocator &alloc;
typedef ::String<Identity::Serial_number> Serial_string;
typedef ::String<Identity::Model_number> Model_string;
@ -182,8 +184,9 @@ struct Ata_driver : Port_driver
Io_command *io_cmd = nullptr;
Block::Packet_descriptor pending[32];
Ata_driver(Port &port, Signal_context_capability state_change)
: Port_driver(port, state_change)
Ata_driver(Genode::Allocator &alloc,
Port &port, Signal_context_capability state_change)
: Port_driver(port, state_change), alloc(alloc)
{
Port::init();
identify_device();
@ -192,7 +195,7 @@ struct Ata_driver : Port_driver
~Ata_driver()
{
if (io_cmd)
destroy (Genode::env()->heap(), io_cmd);
destroy(&alloc, io_cmd);
}
unsigned find_free_cmd_slot()
@ -296,9 +299,9 @@ struct Ata_driver : Port_driver
check_device();
if (ncq_support())
io_cmd = new (Genode::env()->heap()) Ncq_command();
io_cmd = new (&alloc) Ncq_command();
else
io_cmd = new (Genode::env()->heap()) Dma_ext_command();
io_cmd = new (&alloc) Dma_ext_command();
ack_irq();
}

View File

@ -5,22 +5,27 @@
*/
/*
* Copyright (C) 2015 Genode Labs GmbH
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/log.h>
#include <block/component.h>
#include <os/config.h>
#include <os/server.h>
#include <util/xml_node.h>
#include "ahci.h"
/* local includes */
#include <ahci.h>
namespace Block {
class Factory;
class Root_multiple_clients;
class Main;
}
@ -59,13 +64,15 @@ class Block::Root_multiple_clients : public Root_component< ::Session_component>
{
private:
Server::Entrypoint &_ep;
Genode::Env &_env;
Genode::Allocator &_alloc;
Genode::Xml_node _config;
long _device_num(const char *session_label, char *model, char *sn, size_t bufs_len)
{
long num = -1;
Xml_node policy = config()->xml_node().sub_node("policy");
Xml_node policy = _config.sub_node("policy");
for (;; policy = policy.next("policy")) {
char label_buf[64];
@ -121,48 +128,56 @@ class Block::Root_multiple_clients : public Root_component< ::Session_component>
throw Root::Unavailable();
}
Factory *factory = new (Genode::env()->heap()) Factory(num);
return new (md_alloc()) ::Session_component(*factory,
_ep, tx_buf_size);
Factory *factory = new (&_alloc) Factory(num);
return new (&_alloc) ::Session_component(*factory,
_env.ep(), tx_buf_size);
}
void _destroy_session(::Session_component *session)
{
Driver_factory &factory = session->factory();
destroy(env()->heap(), session);
destroy(env()->heap(), &factory);
destroy(&_alloc, session);
destroy(&_alloc, &factory);
}
public:
Root_multiple_clients(Server::Entrypoint &ep, Allocator *md_alloc)
: Root_component(&ep.rpc_ep(), md_alloc), _ep(ep) { }
Root_multiple_clients(Genode::Env &env, Genode::Allocator &alloc,
Genode::Xml_node config)
:
Root_component(&env.ep().rpc_ep(), &alloc),
_env(env), _alloc(alloc), _config(config)
{ }
Server::Entrypoint &entrypoint() override { return _ep; }
Genode::Entrypoint &entrypoint() override { return _env.ep(); }
void announce() override
{
Genode::env()->parent()->announce(_ep.manage(*this));
_env.parent().announce(_env.ep().manage(*this));
}
};
struct Main
struct Block::Main
{
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
Genode::Attached_rom_dataspace config { env, "config" };
Block::Root_multiple_clients root;
Main(Server::Entrypoint &ep)
: root(ep, Genode::env()->heap())
Main(Genode::Env &env)
: env(env), root(env, heap, config.xml())
{
PINF("--- Starting AHCI driver -> done right .-) --\n");
bool support_atapi = Genode::config()->xml_node().attribute_value("atapi", false);
Ahci_driver::init(root, support_atapi);
Genode::log("--- Starting AHCI driver ---");
bool support_atapi = config.xml().attribute_value("atapi", false);
Ahci_driver::init(env, heap, root, support_atapi);
}
};
namespace Server {
char const *name() { return "ahci_ep"; }
size_t stack_size() { return 2 * 1024 * sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
namespace Component {
Genode::size_t stack_size() { return 2 * 1024 * sizeof(long); }
void construct(Genode::Env &env) { static Block::Main server(env); }
}

View File

@ -315,11 +315,14 @@ struct Sata_phy_ctrl : Attached_mmio
struct Exynos5_hba : Platform::Hba
{
Irq_connection irq { Board_base::SATA_IRQ };
Regulator::Connection clock_src { Regulator::CLK_SATA };
Regulator::Connection power_src { Regulator::PWR_SATA };
Genode::Env &env;
Exynos5_hba(Mmio::Delayer &delayer)
Irq_connection irq { Board_base::SATA_IRQ };
Regulator::Connection clock_src { env, Regulator::CLK_SATA };
Regulator::Connection power_src { env, Regulator::PWR_SATA };
Exynos5_hba(Genode::Env &env, Mmio::Delayer &delayer)
: env(env)
{
clock_src.state(true);
power_src.state(true);
@ -368,18 +371,18 @@ struct Exynos5_hba : Platform::Hba
Ram_dataspace_capability
alloc_dma_buffer(size_t size) override
{
return env()->ram_session()->alloc(size, UNCACHED);
return env.ram().alloc(size, UNCACHED);
}
void free_dma_buffer(Ram_dataspace_capability ds)
{
env()->ram_session()->free(ds);
env.ram().free(ds);
}
};
Platform::Hba &Platform::init(Mmio::Delayer &delayer)
Platform::Hba &Platform::init(Genode::Env &env, Mmio::Delayer &delayer)
{
static Exynos5_hba h(delayer);
static Exynos5_hba h(env, delayer);
return h;
}

View File

@ -32,19 +32,21 @@ struct X86_hba : Platform::Hba
PCI_CMD = 0x4,
};
Platform::Connection pci;
Genode::Env &env;
Platform::Connection pci { env };
Platform::Device_capability pci_device_cap;
Lazy_volatile_object<Platform::Device_client> pci_device;
Lazy_volatile_object<Irq_session_client> irq;
addr_t res_base;
size_t res_size;
X86_hba()
X86_hba(Genode::Env &env) : env(env)
{
pci_device_cap = retry<Platform::Session::Out_of_metadata>(
[&] () { return pci.next_device(pci_device_cap, AHCI_DEVICE,
CLASS_MASK); },
[&] () { env()->parent()->upgrade(pci.cap(), "ram_quota=4096"); });
[&] () { env.parent().upgrade(pci.cap(), "ram_quota=4096"); });
if (!pci_device_cap.valid()) {
PERR("No AHCI controller found");
@ -105,7 +107,7 @@ struct X86_hba : Platform::Hba
char quota[32];
Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd",
donate);
Genode::env()->parent()->upgrade(pci.cap(), quota);
env.parent().upgrade(pci.cap(), quota);
donate *= 2;
});
}
@ -136,7 +138,7 @@ struct X86_hba : Platform::Hba
[&] () {
char quota[32];
snprintf(quota, sizeof(quota), "ram_quota=%zd", donate);
env()->parent()->upgrade(pci.cap(), quota);
env.parent().upgrade(pci.cap(), quota);
donate = donate * 2 > size ? 4096 : donate * 2;
});
}
@ -148,8 +150,8 @@ struct X86_hba : Platform::Hba
};
Platform::Hba &Platform::init(Mmio::Delayer &)
Platform::Hba &Platform::init(Genode::Env &env, Mmio::Delayer &)
{
static X86_hba h;
static X86_hba h(env);
return h;
}

View File

@ -1,3 +1,4 @@
TARGET = ahci_drv
SRC_CC = main.cc ahci.cc
LIBS += server base config ahci_platform
TARGET = ahci_drv
SRC_CC = main.cc ahci.cc
INC_DIR += $(PRG_DIR)
LIBS += base ahci_platform