diff --git a/repos/os/run/ahci_block.run b/repos/os/run/ahci_block.run
index 43d6895f63..6fdb74bd8e 100644
--- a/repos/os/run/ahci_block.run
+++ b/repos/os/run/ahci_block.run
@@ -1,35 +1,25 @@
assert_spec x86
-set mke2fs [installed_command mke2fs]
-set dd [installed_command dd]
-
-#
-# Build
-#
-set build_components {
+create_boot_directory
+build {
core init timer
+ drivers/platform
+ drivers/acpi
drivers/ahci
+ app/pci_decode
server/report_rom
app/block_tester
}
-source ${genode_dir}/repos/base/run/platform_drv.inc
-append_platform_drv_build_components
-
-build $build_components
-
#
# Build EXT2-file-system image
#
+set mke2fs [installed_command mke2fs]
+set dd [installed_command dd]
catch { exec $dd if=/dev/zero of=bin/ext2.raw bs=1M count=16 }
catch { exec $mke2fs -F bin/ext2.raw }
-create_boot_directory
-
-#
-# Generate config
-#
-set config {
+install_config {
@@ -45,20 +35,78 @@ set config {
+
- }
+
-append_platform_drv_config
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-append config {
+
@@ -72,6 +120,7 @@ append config {
+
@@ -86,6 +135,7 @@ append config {
+
@@ -101,16 +151,13 @@ append config {
}
-install_config $config
-
#
# Boot modules
#
-set boot_modules { core ld.lib.so init timer ahci_drv report_rom block_tester }
-
-append_platform_drv_boot_modules
-
-build_boot_image $boot_modules
+build_boot_image {
+ core ld.lib.so init timer
+ pci_decode platform_drv report_rom acpi_drv
+ ahci_drv report_rom block_tester }
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 "
diff --git a/repos/os/src/drivers/ahci/ahci.h b/repos/os/src/drivers/ahci/ahci.h
index b0478ffdd9..8a11e51923 100644
--- a/repos/os/src/drivers/ahci/ahci.h
+++ b/repos/os/src/drivers/ahci/ahci.h
@@ -16,19 +16,18 @@
#define _AHCI__AHCI_H_
#include
-#include
+#include
#include
#include
#include
-#include
-
static bool constexpr verbose = false;
namespace Ahci {
+ using namespace Genode;
+
struct Missing_controller : Exception { };
- class Platform;
struct Protocol;
struct Port;
struct Port_base;
@@ -39,47 +38,70 @@ namespace Ahci {
using block_count_t = Block::block_count_t;
}
-class Ahci::Platform
-{
- private :
-
- Data _data;
-
- protected:
-
- /**
- * Return base address and size of HBA device registers
- */
- addr_t _mmio_base() const;
-
- public:
-
- Platform(Env &env) : _data(env) { };
-
- /**
- * Register interrupt signal context
- */
- void sigh_irq(Signal_context_capability sigh);
- void ack_irq();
-
- /**
- * DMA
- */
- Ram_dataspace_capability alloc_dma_buffer(size_t size);
- void free_dma_buffer(Ram_dataspace_capability ds);
- addr_t dma_addr(Ram_dataspace_capability);
-};
-
/**
* HBA definitions
*/
-struct Ahci::Hba : Ahci::Platform,
- Mmio
+struct Ahci::Hba : private Platform::Device::Mmio
{
- Mmio::Delayer &_delayer;
+ using Platform::Device::Mmio::base;
+ using Index = Platform::Device::Mmio::Index;
- Hba(Env &env, Mmio::Delayer &delayer)
- : Platform(env), Mmio(_mmio_base()), _delayer(delayer) { }
+ Platform::Device::Irq _irq;
+
+ /*
+ * mmio region of AHCI controller is always in BAR 5
+ */
+ class No_bar : Genode::Exception { };
+
+ Index _mmio_index(Platform::Connection &platform)
+ {
+ unsigned index = 0;
+ unsigned bar5 = ~0u;
+
+ platform.update();
+
+ platform.with_xml([&] (Xml_node & xml) {
+ xml.with_optional_sub_node("device", [&] (Xml_node xml) {
+ xml.for_each_sub_node("io_mem", [&] (Xml_node node) {
+ unsigned bar = node.attribute_value("pci_bar", ~0u);
+ if (bar == 5) bar5 = index;
+ index++;
+ });
+ });
+ });
+
+ if (bar5 == ~0u) {
+ error("MMIO region of HBA (BAR 5) not found. Try adding\n"
+ "\n"
+ "to platform driver configuration.");
+ throw No_bar();
+ }
+
+ return { bar5 };
+ }
+
+ Hba(Platform::Device & dev,
+ Signal_context_capability cap,
+ Platform::Connection & platform)
+ :
+ Platform::Device::Mmio(dev, _mmio_index(platform)),
+ _irq(dev)
+ {
+ log("version: "
+ "major=", Hex(read()), " "
+ "minor=", Hex(read()));
+ log("command slots: ", command_slots());
+ log("native command queuing: ", ncq() ? "yes" : "no");
+ log("64-bit support: ", supports_64bit() ? "yes" : "no");
+
+ _irq.sigh(cap);
+
+ /* enable AHCI */
+ write(1);
+
+ /* enable interrupts */
+ write(1);
+ }
/**
* Host capabilites
@@ -116,7 +138,7 @@ struct Ahci::Hba : Ahci::Platform,
void ack_irq()
{
write(read());
- Platform::ack_irq();
+ _irq.ack();
}
/**
@@ -135,16 +157,24 @@ struct Ahci::Hba : Ahci::Platform,
struct Cap2 : Register<0x24, 32> { };
- void init()
+ bool port_implemented(unsigned port) const
{
- /* enable AHCI */
- write(1);
-
- /* enable interrupts */
- write(1);
+ return read() & (1u << port);
}
- Mmio::Delayer &delayer() { return _delayer; }
+ template
+ void handle_irq(FN const & fn)
+ {
+ unsigned port_list = read();
+ while (port_list) {
+ unsigned port = log2(port_list);
+ port_list &= ~(1U << port);
+ fn(port);
+ }
+
+ /* clear status register */
+ ack_irq();
+ }
};
@@ -434,8 +464,10 @@ struct Ahci::Port_base : Mmio
ATAPI_SIG_QEMU = 0xeb140000, /* will be fixed in Qemu */
};
- unsigned index { };
- Hba &hba;
+ unsigned index { };
+ Platform::Connection &plat;
+ Hba &hba;
+ Mmio::Delayer &delayer;
/**
* Port signature
@@ -445,13 +477,14 @@ struct Ahci::Port_base : Mmio
static constexpr addr_t offset() { return 0x100; }
static constexpr size_t size() { return 0x80; }
- Port_base(unsigned index, Hba &hba)
+ Port_base(unsigned index, Platform::Connection &plat, Hba &hba,
+ Mmio::Delayer &delayer)
: Mmio(hba.base() + offset() + (index * size())),
- index(index), hba(hba) { }
+ index(index), plat(plat), hba(hba), delayer(delayer) { }
bool implemented() const
{
- return hba.read() & (1u << index);
+ return hba.port_implemented(index);
}
bool ata() const { return read() == ATA_SIG; }
@@ -488,6 +521,7 @@ struct Ahci::Port : private Port_base
using Port_base::Register_set::Polling_timeout;
using Port_base::index;
using Port_base::hba;
+ using Port_base::delayer;
struct Not_ready : Exception { };
@@ -507,10 +541,10 @@ struct Ahci::Port : private Port_base
addr_t device_info = 0;
addr_t dma_base = 0; /* physical address of DMA memory */
- Port(Protocol &protocol, Region_map &rm, Hba &hba,
- unsigned index)
+ Port(Protocol &protocol, Region_map &rm, Platform::Connection & plat,
+ Hba &hba, Mmio::Delayer &delayer, unsigned index)
:
- Port_base(index, hba),
+ Port_base(index, plat, hba, delayer),
protocol(protocol), rm(rm)
{
reset();
@@ -519,7 +553,7 @@ struct Ahci::Port : private Port_base
stop();
- wait_for(hba.delayer(), Cmd::Cr::Equal(0));
+ wait_for(delayer, Cmd::Cr::Equal(0));
init();
@@ -540,17 +574,17 @@ struct Ahci::Port : private Port_base
{
if (device_ds.valid()) {
rm.detach((void *)cmd_list);
- hba.free_dma_buffer(device_ds);
+ plat.free_dma_buffer(device_ds);
}
if (cmd_ds.valid()) {
rm.detach((void *)cmd_table);
- hba.free_dma_buffer(cmd_ds);
+ plat.free_dma_buffer(cmd_ds);
}
if (device_info_ds.valid()) {
rm.detach((void*)device_info);
- hba.free_dma_buffer(device_info_ds);
+ plat.free_dma_buffer(device_info_ds);
}
}
@@ -679,14 +713,14 @@ struct Ahci::Port : private Port_base
return;
try {
- wait_for(hba.delayer(), Tfd::Sts_bsy::Equal(0));
+ wait_for(delayer, Tfd::Sts_bsy::Equal(0));
} catch (Polling_timeout) {
error("HBA busy unable to start command processing.");
return;
}
try {
- wait_for(hba.delayer(), Tfd::Sts_drq::Equal(0));
+ wait_for(delayer, Tfd::Sts_drq::Equal(0));
} catch (Polling_timeout) {
error("HBA in DRQ unable to start command processing.");
return;
@@ -758,7 +792,7 @@ struct Ahci::Port : private Port_base
throw Not_ready();
},
[&] {
- hba.delayer().usleep(1000);
+ delayer.usleep(1000);
status = read();
}, 10);
}
@@ -782,11 +816,11 @@ struct Ahci::Port : private Port_base
warning("CMD.ST bit set during device reset --> unknown behavior");
write(1);
- hba.delayer().usleep(1000);
+ delayer.usleep(1000);
write(0);
try {
- wait_for(hba.delayer(), Ssts::Dec::Equal(Ssts::Dec::ESTABLISHED));
+ wait_for(delayer, Ssts::Dec::Equal(Ssts::Dec::ESTABLISHED));
} catch (Polling_timeout) {
warning("Port reset failed");
}
@@ -846,10 +880,10 @@ struct Ahci::Port : private Port_base
void setup_memory()
{
- device_ds = hba.alloc_dma_buffer(0x1000);
+ device_ds = plat.alloc_dma_buffer(0x1000, CACHED);
/* command list 1K */
- addr_t phys = hba.dma_addr(device_ds);
+ addr_t phys = plat.dma_addr(device_ds);
cmd_list = (addr_t)rm.attach(device_ds);
command_list_base(phys);
@@ -861,14 +895,14 @@ struct Ahci::Port : private Port_base
* (FIS receive running) to clear
*/
write(0);
- wait_for(hba.delayer(), Cmd::Fr::Equal(0));
+ wait_for(delayer, Cmd::Fr::Equal(0));
fis_rcv_base(phys + 1024);
/* command table */
size_t cmd_size = align_addr(cmd_slots * Command_table::size(), 12);
- cmd_ds = hba.alloc_dma_buffer(cmd_size);
+ cmd_ds = plat.alloc_dma_buffer(cmd_size, CACHED);
cmd_table = (addr_t)rm.attach(cmd_ds);
- phys = hba.dma_addr(cmd_ds);
+ phys = plat.dma_addr(cmd_ds);
/* set command table addresses in command list */
for (unsigned i = 0; i < cmd_slots; i++) {
@@ -877,8 +911,8 @@ struct Ahci::Port : private Port_base
}
/* dataspace for device info */
- device_info_ds = hba.alloc_dma_buffer(0x1000);
- device_info_dma_addr = hba.dma_addr(device_info_ds);
+ device_info_ds = plat.alloc_dma_buffer(0x1000, CACHED);
+ device_info_dma_addr = plat.dma_addr(device_info_ds);
device_info = rm.attach(device_info_ds);
}
@@ -921,15 +955,15 @@ struct Ahci::Port : private Port_base
{
if (dma_base) return Ram_dataspace_capability();
- Ram_dataspace_capability dma = hba.alloc_dma_buffer(size);
- dma_base = hba.dma_addr(dma);
+ Ram_dataspace_capability dma = plat.alloc_dma_buffer(size, CACHED);
+ dma_base = plat.dma_addr(dma);
return dma;
}
void free_buffer(Ram_dataspace_capability ds)
{
dma_base = 0;
- hba.free_dma_buffer(ds);
+ plat.free_dma_buffer(ds);
}
/**********************
diff --git a/repos/os/src/drivers/ahci/ata_protocol.h b/repos/os/src/drivers/ahci/ata_protocol.h
index cfd9ebc41f..88fb85424c 100644
--- a/repos/os/src/drivers/ahci/ata_protocol.h
+++ b/repos/os/src/drivers/ahci/ata_protocol.h
@@ -227,9 +227,9 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
table.fis.identify_device();
port.execute(0);
- port.wait_for_any(port.hba.delayer(), Port::Is::Dss::Equal(1),
- Port::Is::Pss::Equal(1),
- Port::Is::Dhrs::Equal(1));
+ port.wait_for_any(port.delayer, Port::Is::Dss::Equal(1),
+ Port::Is::Pss::Equal(1),
+ Port::Is::Dhrs::Equal(1));
_identity.construct(port.device_info);
serial.construct(*_identity);
diff --git a/repos/os/src/drivers/ahci/atapi_protocol.h b/repos/os/src/drivers/ahci/atapi_protocol.h
index 4b0a2cbb58..e1cb346da1 100644
--- a/repos/os/src/drivers/ahci/atapi_protocol.h
+++ b/repos/os/src/drivers/ahci/atapi_protocol.h
@@ -93,21 +93,21 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
[&] {
_start_unit(port);
- port.wait_for_any(port.hba.delayer(),
+ port.wait_for_any(port.delayer,
Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1),
Port::Is::Dhrs::Equal(1));
port.ack_irq();
/* read sense */
_read_sense(port);
- port.wait_for_any(port.hba.delayer(),
+ port.wait_for_any(port.delayer,
Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1),
Port::Is::Dhrs::Equal(1));
port.ack_irq();
/* test unit ready */
_test_unit_ready(port);
- port.wait_for(port.hba.delayer(), Port::Is::Dhrs::Equal(1));
+ port.wait_for(port.delayer, Port::Is::Dhrs::Equal(1));
port.ack_irq();
Device_fis f(port.fis_base);
@@ -116,7 +116,7 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
throw Port::Polling_timeout();
_read_capacity(port);
- port.wait_for_any(port.hba.delayer(),
+ port.wait_for_any(port.delayer,
Port::Is::Dss::Equal(1), Port::Is::Pss::Equal(1),
Port::Is::Dhrs::Equal(1));
port.ack_irq();
diff --git a/repos/os/src/drivers/ahci/main.cc b/repos/os/src/drivers/ahci/main.cc
index 2b050b1939..b535e384a1 100644
--- a/repos/os/src/drivers/ahci/main.cc
+++ b/repos/os/src/drivers/ahci/main.cc
@@ -55,39 +55,30 @@ class Ahci::Driver : Noncopyable
struct Timer_delayer : Mmio::Delayer, Timer::Connection
{
- Timer_delayer(Env &env)
- : Timer::Connection(env) { }
+ using Timer::Connection::Connection;
void usleep(uint64_t us) override { Timer::Connection::usleep(us); }
} _delayer { _env };
- Hba _hba { _env, _delayer };
+ Signal_handler _handler { _env.ep(), *this, &Driver::handle_irq };
+
+ Platform::Connection _plat { _env };
+ Platform::Device _device { _plat };
+ Hba _hba { _device, _handler, _plat };
Constructible _ata[MAX_PORTS];
Constructible _atapi[MAX_PORTS];
Constructible _ports[MAX_PORTS];
- Signal_handler _irq { _env.ep(), *this, &Driver::handle_irq };
- bool _enable_atapi;
-
- void _info()
- {
- log("version: "
- "major=", Hex(_hba.read()), " "
- "minor=", Hex(_hba.read()));
- log("command slots: ", _hba.command_slots());
- log("native command queuing: ", _hba.ncq() ? "yes" : "no");
- log("64-bit support: ", _hba.supports_64bit() ? "yes" : "no");
- }
+ bool _enable_atapi;
void _scan_ports(Region_map &rm)
{
- log("number of ports: ", _hba.port_count(), " pi: ",
- Hex(_hba.read()));
+ log("number of ports: ", _hba.port_count());
for (unsigned index = 0; index < MAX_PORTS; index++) {
- Port_base port(index, _hba);
+ Port_base port(index, _plat, _hba, _delayer);
if (port.implemented() == false)
continue;
@@ -96,7 +87,8 @@ class Ahci::Driver : Noncopyable
if (port.ata()) {
try {
_ata[index].construct();
- _ports[index].construct(*_ata[index], rm, _hba, index);
+ _ports[index].construct(*_ata[index], rm, _plat,
+ _hba, _delayer, index);
enabled = true;
} catch (...) { }
@@ -104,7 +96,8 @@ class Ahci::Driver : Noncopyable
} else if (port.atapi() && _enable_atapi) {
try {
_atapi[index].construct();
- _ports[index].construct(*_atapi[index], rm, _hba, index);
+ _ports[index].construct(*_atapi[index], rm, _plat,
+ _hba, _delayer, index);
enabled = true;
} catch (...) { }
@@ -121,14 +114,6 @@ class Ahci::Driver : Noncopyable
Driver(Env &env, Dispatch &dispatch, bool support_atapi)
: _env(env), _dispatch(dispatch), _enable_atapi(support_atapi)
{
- _info();
-
- /* register irq handler */
- _hba.sigh_irq(_irq);
-
- /* initialize HBA (IRQs, memory) */
- _hba.init();
-
/* search for devices */
_scan_ports(env.rm());
}
@@ -138,22 +123,15 @@ class Ahci::Driver : Noncopyable
*/
void handle_irq()
{
- unsigned port_list = _hba.read();
- while (port_list) {
- unsigned port = log2(port_list);
- port_list &= ~(1U << port);
-
- /* ack irq */
+ _hba.handle_irq([&] (unsigned port) {
if (_ports[port].constructed())
_ports[port]->handle_irq();
/* handle (pending) requests */
_dispatch.session(port);
- }
-
- /* clear status register */
- _hba.ack_irq();
+ });
}
+
Port &port(Session_label const &label, Session_policy const &policy)
{
/* try read device port number attribute */
diff --git a/repos/os/src/drivers/ahci/spec/x86/platform.cc b/repos/os/src/drivers/ahci/spec/x86/platform.cc
deleted file mode 100644
index bc12cb560d..0000000000
--- a/repos/os/src/drivers/ahci/spec/x86/platform.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * \brief Driver for PCI-bus platforms
- * \author Sebastian Sumpf
- * \date 2020-01-20
- */
-
-/*
- * Copyright (C) 2020 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-
-Ahci::Data::Data(Env &env)
- : env(env)
-{
- pci_device_cap = pci.with_upgrade(
- [&] () { return pci.next_device(pci_device_cap, AHCI_DEVICE,
- CLASS_MASK); });
-
- if (!pci_device_cap.valid()) {
- throw Missing_controller();
- }
-
- /* construct pci client */
- pci_device.construct(pci_device_cap);
- log("AHCI found ("
- "vendor: ", Hex(pci_device->vendor_id()), " "
- "device: ", Hex(pci_device->device_id()), " "
- "class: ", Hex(pci_device->class_code()), ")");
-
- /* map base address of controller */
- Io_mem_session_capability iomem_cap = pci_device->io_mem(pci_device->phys_bar_to_virt(AHCI_BASE_ID));
- iomem.construct(env.rm(), Io_mem_session_client(iomem_cap).dataspace());
-
- uint16_t cmd = (uint16_t)pci_device->config_read(PCI_CMD, ::Platform::Device::ACCESS_16BIT);
- cmd |= 0x2; /* respond to memory space accesses */
- cmd |= 0x4; /* enable bus master */
- _config_write(PCI_CMD, cmd, ::Platform::Device::ACCESS_16BIT);
-
- irq.construct(pci_device->irq(0));
-}
-
-
-/************************
- ** Platform interface **
- ************************/
-
-Genode::addr_t Ahci::Platform::_mmio_base() const
-{
- return addr_t(_data.iomem->local_addr());
-}
-
-
-void Ahci::Platform::sigh_irq(Signal_context_capability sigh)
-{
- _data.irq->sigh(sigh);
- ack_irq();
-}
-
-
-void Ahci::Platform::ack_irq() { _data.irq->ack_irq(); }
-
-
-Genode::Ram_dataspace_capability Ahci::Platform::alloc_dma_buffer(size_t size)
-{
- size_t donate = size;
-
- return retry(
- [&] () {
- return retry(
- [&] () { return _data.pci.alloc_dma_buffer(size, Genode::UNCACHED); },
- [&] () { _data.pci.upgrade_caps(2); });
- },
- [&] () {
- _data.pci.upgrade_ram(donate);
- donate = donate * 2 > size ? 4096 : donate * 2;
- });
-}
-
-
-void Ahci::Platform::free_dma_buffer(Genode::Ram_dataspace_capability ds)
-{
- _data.pci.free_dma_buffer(ds);
-}
-
-
-Genode::addr_t Ahci::Platform::dma_addr(Genode::Ram_dataspace_capability ds)
-{
- return _data.pci.dma_addr(ds);
-}
diff --git a/repos/os/src/drivers/ahci/spec/x86/platform.h b/repos/os/src/drivers/ahci/spec/x86/platform.h
deleted file mode 100644
index fc5c53b110..0000000000
--- a/repos/os/src/drivers/ahci/spec/x86/platform.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _AHCI__SPEC__X86__PLATFORM_H_
-#define _AHCI__SPEC__X86__PLATFORM_H_
-/*
- * \brief Driver for PCI-bus platforms
- * \author Sebastian Sumpf
- * \date 2020-01-20
- */
-
-/*
- * Copyright (C) 2020 Genode Labs GmbH
- *
- * This file is part of the Genode OS framework, which is distributed
- * under the terms of the GNU Affero General Public License version 3.
- */
-
-#include
-#include
-#include
-#include
-
-namespace Ahci {
- struct Data;
- using namespace Genode;
-}
-
-struct Ahci::Data
-{
- enum Pci_config {
- CLASS_MASS_STORAGE = 0x10000u,
- SUBCLASS_AHCI = 0x600u,
- CLASS_MASK = 0xffff00u,
- AHCI_DEVICE = CLASS_MASS_STORAGE | SUBCLASS_AHCI,
- AHCI_BASE_ID = 0x5, /* resource id of ahci base addr */
- PCI_CMD = 0x4,
- };
-
- Genode::Env &env;
-
- Platform::Connection pci { env };
- Platform::Device_capability pci_device_cap { };
- Constructible pci_device { };
- Constructible irq { };
- Constructible iomem { };
-
- Data(Env &env);
-
- void _config_write(uint8_t op, uint16_t cmd,
- Platform::Device::Access_size width)
- {
- size_t donate = 4096;
- retry(
- [&] () {
- retry(
- [&] () { pci_device->config_write(op, cmd, width); },
- [&] () { pci.upgrade_caps(2); });
- },
- [&] () {
- pci.upgrade_ram(donate);
- donate *= 2;
- });
- }
-};
-
-
-#endif /* _AHCI__SPEC__X86__PLATFORM_H_ */
diff --git a/repos/os/src/drivers/ahci/spec/x86/target.mk b/repos/os/src/drivers/ahci/spec/x86/target.mk
deleted file mode 100644
index fe44856e5b..0000000000
--- a/repos/os/src/drivers/ahci/spec/x86/target.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-TARGET = ahci_drv
-REQUIRES = x86
-
-INC_DIR += $(REP_DIR)/src/drivers/ahci/spec/x86
-
-include $(REP_DIR)/src/drivers/ahci/target.inc
-
diff --git a/repos/os/src/drivers/ahci/target.inc b/repos/os/src/drivers/ahci/target.inc
deleted file mode 100644
index dee2052fcc..0000000000
--- a/repos/os/src/drivers/ahci/target.inc
+++ /dev/null
@@ -1,8 +0,0 @@
-SRC_CC += main.cc platform.cc
-INC_DIR += $(REP_DIR)/src/drivers/ahci
-LIBS += base
-
-CC_CXX_WARN_STRICT_CONVERSION =
-
-vpath platform.cc $(PRG_DIR)
-vpath %.cc $(REP_DIR)/src/drivers/ahci
diff --git a/repos/os/src/drivers/ahci/target.mk b/repos/os/src/drivers/ahci/target.mk
new file mode 100644
index 0000000000..7d22e9a0dd
--- /dev/null
+++ b/repos/os/src/drivers/ahci/target.mk
@@ -0,0 +1,8 @@
+TARGET = ahci_drv
+SRC_CC += main.cc
+INC_DIR += $(PRG_DIR)
+LIBS += base
+
+CC_CXX_WARN_STRICT_CONVERSION =
+
+vpath %.cc $(PRG_DIR)