mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
250fd42368
commit
b37f411c3f
@ -44,6 +44,7 @@ set config {
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
|
@ -9,6 +9,7 @@ set build_components {
|
||||
core init
|
||||
drivers/timer
|
||||
drivers/ahci
|
||||
server/report_rom
|
||||
test/blk/cli
|
||||
}
|
||||
|
||||
@ -44,6 +45,7 @@ set config {
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
@ -52,12 +54,23 @@ set config {
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
<start name="ahci_report_rom">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="yes"/>
|
||||
</start>
|
||||
<start name="ahci_drv">
|
||||
<resource name="RAM" quantum="10M" />
|
||||
<provides><service name="Block" /></provides>
|
||||
<config>
|
||||
<config atapi="yes">
|
||||
<report ports="yes"/>
|
||||
<policy label_prefix="test-ahci" device="0" />
|
||||
</config>
|
||||
<route>
|
||||
<service name="Report"> <child name="ahci_report_rom"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-ahci">
|
||||
<binary name="test-blk-cli" />
|
||||
@ -75,15 +88,16 @@ install_config $config
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
set boot_modules { core ld.lib.so init timer ahci_drv test-blk-cli }
|
||||
set boot_modules { core ld.lib.so init timer ahci_drv report_rom test-blk-cli }
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -nographic "
|
||||
append qemu_args " -drive id=disk,file=bin/ext2.raw,format=raw,if=none -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -boot d"
|
||||
append qemu_args " -drive id=cd,file=[run_dir]/../ahci_blk.iso,if=none,media=cdrom -device ide-cd,drive=cd,bus=ahci.1"
|
||||
append qemu_args " -nographic -device ahci,id=ahci -boot d "
|
||||
append qemu_args " -drive id=disk,file=bin/ext2.raw,format=raw,if=none -device ide-hd,drive=disk,bus=ahci.0 "
|
||||
append qemu_args " -drive id=cd,file=[run_dir]/../ahci_blk.iso,if=none,media=cdrom -device ide-cd,drive=cd,bus=ahci.1 "
|
||||
append qemu_args " -drive id=disk2,file=bin/ext2.raw,format=raw,if=none -device ide-hd,drive=disk2,bus=ahci.2 "
|
||||
|
||||
run_genode_until "Tests finished successfully!" 100
|
||||
|
||||
|
@ -29,3 +29,18 @@ In the example above, a session request labeled with "test-ahci" gains access to
|
||||
a device with certain model and serial numbers, while "bench" gains access to
|
||||
device at port 1. ATAPI support is by default disabled and can be enabled by
|
||||
setting the config attribute "atapi" to "yes".
|
||||
|
||||
ahci_drv supports reporting of active ports, which can be enabled via
|
||||
configuration sub-node like follows.
|
||||
|
||||
!<report ports="yes"/>
|
||||
|
||||
The report structure is depicted by the following example.
|
||||
|
||||
! <ports>
|
||||
! <port num="0" type="ATA" block_count="32768" block_size="512"
|
||||
! model="QEMU HARDDISK" serial="QM00005"/>
|
||||
! <port num="1" type="ATAPI"/>
|
||||
! <port num="2" type="ATA" block_count="32768" block_size="512"
|
||||
! model="QEMU HARDDISK" serial="QM00009"/>
|
||||
! </ports>
|
||||
|
@ -52,12 +52,16 @@ struct Ahci
|
||||
unsigned ready_count = 0;
|
||||
bool enable_atapi;
|
||||
|
||||
Signal_context_capability device_identified;
|
||||
|
||||
Ahci(Genode::Env &env, Genode::Allocator &alloc,
|
||||
Ahci_root &root, bool support_atapi)
|
||||
Ahci_root &root, bool support_atapi,
|
||||
Genode::Signal_context_capability device_identified)
|
||||
:
|
||||
env(env), alloc(alloc),
|
||||
root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
|
||||
enable_atapi(support_atapi)
|
||||
enable_atapi(support_atapi),
|
||||
device_identified(device_identified)
|
||||
{
|
||||
info();
|
||||
|
||||
@ -122,7 +126,7 @@ struct Ahci
|
||||
try {
|
||||
ports[i] = new (&alloc)
|
||||
Ata_driver(alloc, ram, root, ready_count, rm, hba,
|
||||
platform_hba, i);
|
||||
platform_hba, i, device_identified);
|
||||
enabled = true;
|
||||
} catch (...) { }
|
||||
|
||||
@ -168,6 +172,11 @@ struct Ahci
|
||||
ports[port_num]->ready();
|
||||
}
|
||||
|
||||
Port_driver * port(unsigned num)
|
||||
{
|
||||
return num < MAX_PORTS ? ports[num] : nullptr;
|
||||
}
|
||||
|
||||
long device_number(const char *model_num, const char *serial_num)
|
||||
{
|
||||
for (long port_num = 0; port_num < MAX_PORTS; port_num++) {
|
||||
@ -191,9 +200,10 @@ static Ahci *sata_ahci(Ahci *ahci = 0)
|
||||
|
||||
|
||||
void Ahci_driver::init(Genode::Env &env, Genode::Allocator &alloc,
|
||||
Ahci_root &root, bool support_atapi)
|
||||
Ahci_root &root, bool support_atapi,
|
||||
Genode::Signal_context_capability device_identified)
|
||||
{
|
||||
static Ahci ahci(env, alloc, root, support_atapi);
|
||||
static Ahci ahci(env, alloc, root, support_atapi, device_identified);
|
||||
sata_ahci(&ahci);
|
||||
}
|
||||
|
||||
@ -220,3 +230,27 @@ long Ahci_driver::device_number(char const *model_num, char const *serial_num)
|
||||
{
|
||||
return sata_ahci()->device_number(model_num, serial_num);
|
||||
}
|
||||
|
||||
|
||||
void Ahci_driver::report_ports(Genode::Reporter &reporter)
|
||||
{
|
||||
Genode::Reporter::Xml_generator xml(reporter, [&] () {
|
||||
for (unsigned i = 0; i < Ahci::MAX_PORTS; ++i) {
|
||||
Port_driver *port = sata_ahci()->port(i);
|
||||
if (!port || !port->ready()) continue;
|
||||
|
||||
Ata_driver *ata = dynamic_cast<Ata_driver *>(port);
|
||||
|
||||
xml.node("port", [&] () {
|
||||
xml.attribute("num", i);
|
||||
xml.attribute("type", ata ? "ATA" : "ATAPI");
|
||||
if (ata) {
|
||||
xml.attribute("block_count", ata->block_count());
|
||||
xml.attribute("block_size", ata->block_size());
|
||||
xml.attribute("model", ata->model->cstring());
|
||||
xml.attribute("serial", ata->serial->cstring());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <block/component.h>
|
||||
#include <os/attached_mmio.h>
|
||||
#include <os/reporter.h>
|
||||
#include <util/retry.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
@ -36,13 +37,15 @@ struct Ahci_root
|
||||
|
||||
namespace Ahci_driver {
|
||||
|
||||
void init(Genode::Env &env, Genode::Allocator &alloc, Ahci_root &ep, bool support_atapi);
|
||||
void init(Genode::Env &env, Genode::Allocator &alloc, Ahci_root &ep,
|
||||
bool support_atapi, Genode::Signal_context_capability device_identified);
|
||||
|
||||
bool avail(long device_num);
|
||||
long device_number(char const *model_num, char const *serial_num);
|
||||
|
||||
Block::Driver *claim_port(long device_num);
|
||||
void free_port(long device_num);
|
||||
void report_ports(Genode::Reporter &reporter);
|
||||
|
||||
struct Missing_controller { };
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ struct String
|
||||
}
|
||||
|
||||
void print(Genode::Output &out) const { Genode::print(out, (char const *)buf); }
|
||||
char const *cstring() { return buf; }
|
||||
};
|
||||
|
||||
|
||||
@ -188,6 +189,8 @@ struct Ata_driver : Port_driver
|
||||
Io_command *io_cmd = nullptr;
|
||||
Block::Packet_descriptor pending[32];
|
||||
|
||||
Signal_context_capability device_identified;
|
||||
|
||||
Ata_driver(Genode::Allocator &alloc,
|
||||
Genode::Ram_session &ram,
|
||||
Ahci_root &root,
|
||||
@ -195,9 +198,10 @@ struct Ata_driver : Port_driver
|
||||
Genode::Region_map &rm,
|
||||
Hba &hba,
|
||||
Platform::Hba &platform_hba,
|
||||
unsigned number)
|
||||
unsigned number,
|
||||
Genode::Signal_context_capability device_identified)
|
||||
: Port_driver(ram, root, sem, rm, hba, platform_hba, number),
|
||||
alloc(alloc)
|
||||
alloc(alloc), device_identified(device_identified)
|
||||
{
|
||||
Port::init();
|
||||
identify_device();
|
||||
@ -317,6 +321,8 @@ struct Ata_driver : Port_driver
|
||||
io_cmd = new (&alloc) Dma_ext_command();
|
||||
|
||||
ack_irq();
|
||||
|
||||
Genode::Signal_transmitter(device_identified).submit();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <block/component.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <os/reporter.h>
|
||||
|
||||
/* local includes */
|
||||
#include <ahci.h>
|
||||
@ -175,24 +176,40 @@ struct Block::Main
|
||||
|
||||
Genode::Attached_rom_dataspace config { env, "config" };
|
||||
|
||||
Genode::Constructible<Genode::Reporter> reporter;
|
||||
|
||||
Block::Root_multiple_clients root;
|
||||
|
||||
Signal_handler<Main> device_identified {
|
||||
env.ep(), *this, &Main::handle_device_identified };
|
||||
|
||||
Main(Genode::Env &env)
|
||||
: env(env), root(env, heap, config.xml())
|
||||
{
|
||||
Genode::log("--- Starting AHCI driver ---");
|
||||
bool support_atapi = config.xml().attribute_value("atapi", false);
|
||||
try { Ahci_driver::init(env, heap, root, support_atapi); }
|
||||
|
||||
catch (Ahci_driver::Missing_controller) {
|
||||
bool support_atapi = config.xml().attribute_value("atapi", false);
|
||||
try {
|
||||
Ahci_driver::init(env, heap, root, support_atapi, device_identified);
|
||||
} catch (Ahci_driver::Missing_controller) {
|
||||
Genode::error("no AHCI controller found");
|
||||
env.parent().exit(~0);
|
||||
}
|
||||
catch (Genode::Service_denied) {
|
||||
} catch (Genode::Service_denied) {
|
||||
Genode::error("hardware access denied");
|
||||
env.parent().exit(~0);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_device_identified()
|
||||
{
|
||||
try {
|
||||
Xml_node report = config.xml().sub_node("report");
|
||||
if (report.attribute_value("ports", false)) {
|
||||
reporter.construct(env, "ports");
|
||||
reporter->enabled(true);
|
||||
Ahci_driver::report_ports(*reporter);
|
||||
}
|
||||
} catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user