mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-24 15:56:41 +00:00
parent
c77f146e72
commit
0d8d8de42c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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); }
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user