Support more than one I/O region per device.

This commit is contained in:
Maxim Poliakovski 2020-03-31 18:23:18 +02:00
parent ec384fb5ea
commit 695044cf0e
8 changed files with 21 additions and 17 deletions

View File

@ -70,7 +70,8 @@ AddressMapEntry last_dma_area = { 0 };
ret = OP((ENTRY).mem_ptr + ((ADDR) - (ENTRY).start)); \ ret = OP((ENTRY).mem_ptr + ((ADDR) - (ENTRY).start)); \
} \ } \
else if (entry->type & RT_MMIO) { \ else if (entry->type & RT_MMIO) { \
ret = entry->devobj->read((ADDR) - entry->start, (SIZE)); \ ret = entry->devobj->read(entry->start, (ADDR) - entry->start, \
(SIZE)); \
} \ } \
else { \ else { \
LOG_F(ERROR, "Please check your address map! \n"); \ LOG_F(ERROR, "Please check your address map! \n"); \
@ -99,10 +100,11 @@ AddressMapEntry last_dma_area = { 0 };
OP((ENTRY).mem_ptr + ((ADDR) - (ENTRY).start), (VAL)); \ OP((ENTRY).mem_ptr + ((ADDR) - (ENTRY).start), (VAL)); \
} \ } \
else if (entry->type & RT_MMIO) { \ else if (entry->type & RT_MMIO) { \
entry->devobj->write((ADDR) - entry->start, (VAL), (SIZE)); \ entry->devobj->write(entry->start, (ADDR) - entry->start, \
(VAL), (SIZE)); \
} \ } \
else { \ else { \
LOG_F(ERROR, "Please check your address map!\n"); \ LOG_F(ERROR, "Please check your address map!\n"); \
} \ } \
} \ } \
else { \ else { \

View File

@ -116,7 +116,7 @@ void HeathrowIC::dma_write(uint32_t offset, uint32_t value, int size)
} }
uint32_t HeathrowIC::read(uint32_t offset, int size) uint32_t HeathrowIC::read(uint32_t reg_start, uint32_t offset, int size)
{ {
uint32_t res = 0; uint32_t res = 0;
@ -153,7 +153,7 @@ uint32_t HeathrowIC::read(uint32_t offset, int size)
return res; return res;
} }
void HeathrowIC::write(uint32_t offset, uint32_t value, int size) void HeathrowIC::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
{ {
LOG_F(9, "%s: writing to offset %x \n", this->name.c_str(), offset); LOG_F(9, "%s: writing to offset %x \n", this->name.c_str(), offset);

View File

@ -51,10 +51,11 @@ public:
return type == HWCompType::MMIO_DEV; return type == HWCompType::MMIO_DEV;
}; };
uint32_t read(uint32_t offset, int size) { uint32_t read(uint32_t reg_start, uint32_t offset, int size) {
return ((!offset && size == 2) ? this->id : 0); }; return ((!offset && size == 2) ? this->id : 0); };
void write(uint32_t offset, uint32_t value, int size) {}; /* not writable */ void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
{}; /* not writable */
private: private:
uint16_t id; uint16_t id;

View File

@ -102,8 +102,8 @@ public:
void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size); void pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size);
/* MMIO device methods */ /* MMIO device methods */
uint32_t read(uint32_t offset, int size); uint32_t read(uint32_t reg_start, uint32_t offset, int size);
void write(uint32_t offset, uint32_t value, int size); void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
protected: protected:
uint32_t dma_read(uint32_t offset, int size); uint32_t dma_read(uint32_t offset, int size);

View File

@ -35,13 +35,14 @@ enum RangeType {
at some other address) */ at some other address) */
}; };
/** Defines the format for the address map entry. */
typedef struct AddressMapEntry { typedef struct AddressMapEntry {
uint32_t start; /* first address of the corresponding range */ uint32_t start; /* first address of the corresponding range */
uint32_t end; /* last address of the corresponding range */ uint32_t end; /* last address of the corresponding range */
uint32_t mirror; /* mirror address for RT_MIRROR */ uint32_t mirror; /* mirror address for RT_MIRROR */
uint32_t type; /* range type */ uint32_t type; /* range type */
MMIODevice *devobj; /* pointer to device object */ MMIODevice* devobj; /* pointer to device object */
unsigned char *mem_ptr; /* direct pointer to data for memory objects */ unsigned char* mem_ptr; /* direct pointer to data for memory objects */
} AddressMapEntry; } AddressMapEntry;

View File

@ -29,8 +29,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
/** Abstract class representing a simple, memory-mapped I/O device */ /** Abstract class representing a simple, memory-mapped I/O device */
class MMIODevice : public HWComponent { class MMIODevice : public HWComponent {
public: public:
virtual uint32_t read(uint32_t offset, int size) = 0; virtual uint32_t read(uint32_t reg_start, uint32_t offset, int size) = 0;
virtual void write(uint32_t offset, uint32_t value, int size) = 0; virtual void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) = 0;
virtual ~MMIODevice() = default; virtual ~MMIODevice() = default;
}; };

View File

@ -61,7 +61,7 @@ bool MPC106::supports_type(HWCompType type)
} }
} }
uint32_t MPC106::read(uint32_t offset, int size) uint32_t MPC106::read(uint32_t reg_start, uint32_t offset, int size)
{ {
if (offset >= 0x200000) { if (offset >= 0x200000) {
if (this->config_addr & 0x80) // process only if bit E (enable) is set if (this->config_addr & 0x80) // process only if bit E (enable) is set
@ -73,7 +73,7 @@ uint32_t MPC106::read(uint32_t offset, int size)
return 0; return 0;
} }
void MPC106::write(uint32_t offset, uint32_t value, int size) void MPC106::write(uint32_t reg_start, uint32_t offset, uint32_t value, int size)
{ {
if (offset < 0x200000) { if (offset < 0x200000) {
this->config_addr = value; this->config_addr = value;

View File

@ -52,8 +52,8 @@ public:
bool supports_type(HWCompType type); bool supports_type(HWCompType type);
uint32_t read(uint32_t offset, int size); uint32_t read(uint32_t reg_start, uint32_t offset, int size);
void write(uint32_t offset, uint32_t value, int size); void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size);
/* PCI host bridge API */ /* PCI host bridge API */
bool pci_register_device(int dev_num, PCIDevice *dev_instance); bool pci_register_device(int dev_num, PCIDevice *dev_instance);