idechannel: support devices registration and interrupts.

This commit is contained in:
Maxim Poliakovski 2023-06-18 23:24:19 +02:00
parent cb347434d3
commit ac267b3daa
2 changed files with 44 additions and 8 deletions

View File

@ -1,6 +1,6 @@
/*
DingusPPC - The Experimental PowerPC Macintosh emulator
Copyright (C) 2018-22 divingkatae and maximum
Copyright (C) 2018-23 divingkatae and maximum
(theweirdo) spatium
(Contact divingkatae#1017 or powermax#2286 on Discord for more info)
@ -26,10 +26,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
from and to the host.
*/
#include <devices/common/ata/atabasedevice.h>
#include <devices/common/ata/atadefs.h>
#include <devices/common/ata/idechannel.h>
#include <devices/common/hwcomponent.h>
#include <devices/deviceregistry.h>
#include <machines/machinebase.h>
#include <cinttypes>
#include <memory>
@ -42,8 +44,28 @@ IdeChannel::IdeChannel(const std::string name)
this->set_name(name);
this->supports_types(HWCompType::IDE_BUS);
this->devices[0] = std::unique_ptr<AtaNullDevice>(new AtaNullDevice());
this->devices[1] = std::unique_ptr<AtaNullDevice>(new AtaNullDevice());
this->device_stub = std::unique_ptr<AtaNullDevice>(new AtaNullDevice());
this->devices[0] = this->device_stub.get();
this->devices[1] = this->device_stub.get();
}
int IdeChannel::device_postinit() {
this->int_ctrl = dynamic_cast<InterruptCtrl*>(
gMachineObj->get_comp_by_type(HWCompType::INT_CTRL));
this->irq_id = this->int_ctrl->register_dev_int(
this->name == "IDE0" ? IntSrc::IDE0 : IntSrc::IDE1);
return 0;
}
void IdeChannel::register_device(int id, AtaInterface* dev_obj) {
if (id < 0 || id >= 2)
ABORT_F("%s: invalid device ID", this->name.c_str());
this->devices[id] = dev_obj;
((AtaBaseDevice*)dev_obj)->set_host(this);
}
uint32_t IdeChannel::read(const uint8_t reg_addr, const int size)

View File

@ -26,6 +26,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/ata/atadefs.h>
#include <devices/common/hwcomponent.h>
#include <devices/common/hwinterrupt.h>
#include <cinttypes>
#include <memory>
@ -38,13 +39,17 @@ public:
~IdeChannel() = default;
static std::unique_ptr<HWComponent> create_first() {
return std::unique_ptr<IdeChannel>(new IdeChannel("IDEO"));
return std::unique_ptr<IdeChannel>(new IdeChannel("IDE0"));
}
static std::unique_ptr<HWComponent> create_second() {
return std::unique_ptr<IdeChannel>(new IdeChannel("IDE1"));
}
int device_postinit() override;
void register_device(int id, AtaInterface* dev_obj);
uint32_t read(const uint8_t reg_addr, const int size);
void write(const uint8_t reg_addr, const uint32_t val, const int size);
@ -56,11 +61,20 @@ public:
return this->devices[1]->get_device_id() != ata_interface::DEVICE_ID_INVALID;
}
private:
int cur_dev = 0;
uint32_t ch_config = 0; // timing configuration for this channel
void report_intrq(uint8_t intrq_state) {
this->int_ctrl->ack_int(this->irq_id, intrq_state);
}
std::unique_ptr<AtaInterface> devices[2];
private:
int cur_dev = 0;
uint32_t ch_config = 0; // timing configuration for this channel
AtaInterface* devices[2];
// interrupt related stuff
InterruptCtrl* int_ctrl = nullptr;
uint32_t irq_id = 0;
std::unique_ptr<AtaInterface> device_stub;
};
#endif // IDE_CHANNEL_H