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)); \
} \
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 { \
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)); \
} \
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 { \
LOG_F(ERROR, "Please check your address map!\n"); \
LOG_F(ERROR, "Please check your address map!\n"); \
} \
} \
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;
@ -153,7 +153,7 @@ uint32_t HeathrowIC::read(uint32_t offset, int size)
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);

View File

@ -51,10 +51,11 @@ public:
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); };
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:
uint16_t id;

View File

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

View File

@ -35,13 +35,14 @@ enum RangeType {
at some other address) */
};
/** Defines the format for the address map entry. */
typedef struct AddressMapEntry {
uint32_t start; /* first address of the corresponding range */
uint32_t end; /* last address of the corresponding range */
uint32_t mirror; /* mirror address for RT_MIRROR */
uint32_t type; /* range type */
MMIODevice *devobj; /* pointer to device object */
unsigned char *mem_ptr; /* direct pointer to data for memory objects */
MMIODevice* devobj; /* pointer to device object */
unsigned char* mem_ptr; /* direct pointer to data for memory objects */
} 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 */
class MMIODevice : public HWComponent {
public:
virtual uint32_t read(uint32_t offset, int size) = 0;
virtual void write(uint32_t offset, uint32_t value, int size) = 0;
virtual uint32_t read(uint32_t reg_start, uint32_t offset, int size) = 0;
virtual void write(uint32_t reg_start, uint32_t offset, uint32_t value, int size) = 0;
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 (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;
}
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) {
this->config_addr = value;

View File

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