Merge pull request #658 from richardg867/master
Move the PIIX4 SMBus interface to its own file
This commit is contained in:
43
src/include/86box/smbus_piix4.h
Normal file
43
src/include/86box/smbus_piix4.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* Definitions for the generic PIIX4-compatible SMBus host controller.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors: RichardG, <richardg867@gmail.com>
|
||||||
|
*
|
||||||
|
* Copyright 2020 RichardG.
|
||||||
|
*/
|
||||||
|
#ifndef EMU_SMBUS_PIIX4_H
|
||||||
|
# define EMU_SMBUS_PIIX4_H
|
||||||
|
|
||||||
|
|
||||||
|
#define SMBUS_PIIX4_BLOCK_DATA_SIZE 32
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t io_base;
|
||||||
|
uint8_t stat, next_stat, ctl, cmd, addr,
|
||||||
|
data0, data1,
|
||||||
|
index,
|
||||||
|
data[SMBUS_PIIX4_BLOCK_DATA_SIZE];
|
||||||
|
pc_timer_t response_timer;
|
||||||
|
} smbus_piix4_t;
|
||||||
|
|
||||||
|
|
||||||
|
extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef EMU_DEVICE_H
|
||||||
|
extern const device_t piix4_smbus_device;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*EMU_SMBUS_PIIX4_H*/
|
182
src/intel_piix.c
182
src/intel_piix.c
@@ -47,7 +47,7 @@
|
|||||||
#include <86box/hdc_ide_sff8038i.h>
|
#include <86box/hdc_ide_sff8038i.h>
|
||||||
#include <86box/zip.h>
|
#include <86box/zip.h>
|
||||||
#include <86box/machine.h>
|
#include <86box/machine.h>
|
||||||
#include <86box/smbus.h>
|
#include <86box/smbus_piix4.h>
|
||||||
#include <86box/piix.h>
|
#include <86box/piix.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -87,16 +87,6 @@ typedef struct
|
|||||||
} power_t;
|
} power_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t stat, next_stat, ctl, cmd, addr,
|
|
||||||
data0, data1,
|
|
||||||
index,
|
|
||||||
data[32];
|
|
||||||
pc_timer_t command_timer;
|
|
||||||
} piix_smbus_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t cur_readout_reg, rev,
|
uint8_t cur_readout_reg, rev,
|
||||||
@@ -105,12 +95,11 @@ typedef struct
|
|||||||
regs[4][256],
|
regs[4][256],
|
||||||
readout_regs[256], board_config[2];
|
readout_regs[256], board_config[2];
|
||||||
uint16_t func0_id,
|
uint16_t func0_id,
|
||||||
usb_io_base, power_io_base,
|
usb_io_base, power_io_base;
|
||||||
smbus_io_base;
|
|
||||||
sff8038i_t *bm[2];
|
sff8038i_t *bm[2];
|
||||||
ddma_t ddma[2];
|
ddma_t ddma[2];
|
||||||
power_t power;
|
power_t power;
|
||||||
piix_smbus_t smbus;
|
smbus_piix4_t * smbus;
|
||||||
apm_t * apm;
|
apm_t * apm;
|
||||||
nvr_t * nvr;
|
nvr_t * nvr;
|
||||||
} piix_t;
|
} piix_t;
|
||||||
@@ -466,159 +455,10 @@ power_update_io_mapping(piix_t *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
|
||||||
smbus_reg_read(uint16_t addr, void *priv)
|
|
||||||
{
|
|
||||||
piix_t *dev = (piix_t *) priv;
|
|
||||||
uint8_t ret = 0x00;
|
|
||||||
|
|
||||||
switch (addr - dev->smbus_io_base) {
|
|
||||||
case 0x00:
|
|
||||||
ret = dev->smbus.stat;
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
dev->smbus.index = 0;
|
|
||||||
ret = dev->smbus.ctl;
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
ret = dev->smbus.cmd;
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
ret = dev->smbus.addr;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
ret = dev->smbus.data0;
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
ret = dev->smbus.data1;
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
ret = dev->smbus.data[dev->smbus.index++];
|
|
||||||
if (dev->smbus.index > 31)
|
|
||||||
dev->smbus.index = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
piix_log("smbus_reg_read %02x %02x\n", addr - dev->smbus_io_base, ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
smbus_reg_write(uint16_t addr, uint8_t val, void *priv)
|
|
||||||
{
|
|
||||||
piix_t *dev = (piix_t *) priv;
|
|
||||||
uint8_t smbus_addr;
|
|
||||||
uint8_t smbus_read;
|
|
||||||
uint16_t temp;
|
|
||||||
|
|
||||||
piix_log("smbus_reg_write %02x %02x\n", addr - dev->smbus_io_base, val);
|
|
||||||
|
|
||||||
dev->smbus.next_stat = 0;
|
|
||||||
switch (addr - dev->smbus_io_base) {
|
|
||||||
case 0x00:
|
|
||||||
/* some status bits are reset by writing 1 to them */
|
|
||||||
for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr = smbus_addr << 1) {
|
|
||||||
if (val & smbus_addr)
|
|
||||||
dev->smbus.stat = dev->smbus.stat & ~smbus_addr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
dev->smbus.ctl = val & ~(0x40); /* START always reads 0 */
|
|
||||||
if (val & 0x40) { /* dispatch command if START is set */
|
|
||||||
smbus_addr = (dev->smbus.addr >> 1);
|
|
||||||
if (!smbus_has_device(smbus_addr)) {
|
|
||||||
/* raise DEV_ERR if no device is at this address */
|
|
||||||
dev->smbus.next_stat = 0x4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
smbus_read = (dev->smbus.addr & 0x01);
|
|
||||||
|
|
||||||
switch ((val >> 2) & 0x7) {
|
|
||||||
case 0x0: /* quick R/W */
|
|
||||||
dev->smbus.next_stat = 0x2;
|
|
||||||
break;
|
|
||||||
case 0x1: /* byte R/W */
|
|
||||||
if (smbus_read)
|
|
||||||
dev->smbus.data0 = smbus_read_byte(smbus_addr);
|
|
||||||
else
|
|
||||||
smbus_write_byte(smbus_addr, dev->smbus.data0);
|
|
||||||
dev->smbus.next_stat = 0x2;
|
|
||||||
break;
|
|
||||||
case 0x2: /* byte data R/W */
|
|
||||||
if (smbus_read)
|
|
||||||
dev->smbus.data0 = smbus_read_byte_cmd(smbus_addr, dev->smbus.cmd);
|
|
||||||
else
|
|
||||||
smbus_write_byte_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data0);
|
|
||||||
dev->smbus.next_stat = 0x2;
|
|
||||||
break;
|
|
||||||
case 0x3: /* word data R/W */
|
|
||||||
if (smbus_read) {
|
|
||||||
temp = smbus_read_word_cmd(smbus_addr, dev->smbus.cmd);
|
|
||||||
dev->smbus.data0 = (temp & 0xFF);
|
|
||||||
dev->smbus.data1 = (temp >> 8);
|
|
||||||
} else {
|
|
||||||
temp = (dev->smbus.data1 << 8) | dev->smbus.data0;
|
|
||||||
smbus_write_word_cmd(smbus_addr, dev->smbus.cmd, temp);
|
|
||||||
}
|
|
||||||
dev->smbus.next_stat = 0x2;
|
|
||||||
break;
|
|
||||||
case 0x5: /* block R/W */
|
|
||||||
if (smbus_read)
|
|
||||||
dev->smbus.data0 = smbus_read_block_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data);
|
|
||||||
else
|
|
||||||
smbus_write_block_cmd(smbus_addr, dev->smbus.cmd, dev->smbus.data, dev->smbus.data0);
|
|
||||||
dev->smbus.next_stat = 0x2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
dev->smbus.cmd = val;
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
dev->smbus.addr = val;
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
dev->smbus.data0 = val;
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
dev->smbus.data1 = val;
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
dev->smbus.data[dev->smbus.index++] = val;
|
|
||||||
if (dev->smbus.index > 31)
|
|
||||||
dev->smbus.index = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->smbus.next_stat) {
|
|
||||||
dev->smbus.stat = 0x1;
|
|
||||||
timer_disable(&dev->smbus.command_timer);
|
|
||||||
timer_set_delay_u64(&dev->smbus.command_timer, 10 * TIMER_USEC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
smbus_inter(void *priv)
|
|
||||||
{
|
|
||||||
piix_t *dev = (piix_t *) priv;
|
|
||||||
dev->smbus.stat = dev->smbus.next_stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
smbus_update_io_mapping(piix_t *dev)
|
smbus_update_io_mapping(piix_t *dev)
|
||||||
{
|
{
|
||||||
if (dev->smbus_io_base != 0x0000)
|
smbus_piix4_remap(dev->smbus, (dev->regs[3][0x91] << 8) | (dev->regs[3][0x90] & 0xf0), (dev->regs[3][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->regs[3][0xd2] & 0x01));
|
||||||
io_removehandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev);
|
|
||||||
|
|
||||||
dev->smbus_io_base = (dev->regs[3][0x91] << 8) | (dev->regs[3][0x90] & 0xf0);
|
|
||||||
|
|
||||||
if ((dev->regs[3][PCI_REG_COMMAND] & PCI_COMMAND_IO) && (dev->regs[3][0xd2] & 0x01) && (dev->smbus_io_base != 0x0000))
|
|
||||||
io_sethandler(dev->smbus_io_base, 0x10, smbus_reg_read, NULL, NULL, smbus_reg_write, NULL, NULL, dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1259,6 +1099,8 @@ static void
|
|||||||
|
|
||||||
piix_reset_hard(dev);
|
piix_reset_hard(dev);
|
||||||
|
|
||||||
|
dev->smbus = device_add(&piix4_smbus_device);
|
||||||
|
|
||||||
dev->apm = device_add(&apm_device);
|
dev->apm = device_add(&apm_device);
|
||||||
device_add(&port_92_pci_device);
|
device_add(&port_92_pci_device);
|
||||||
|
|
||||||
@@ -1331,18 +1173,6 @@ static void
|
|||||||
else
|
else
|
||||||
dev->board_config[1] |= 0x10; /* TODO: how are the overdrive processors configured? */
|
dev->board_config[1] |= 0x10; /* TODO: how are the overdrive processors configured? */
|
||||||
|
|
||||||
smbus_init();
|
|
||||||
dev->smbus.stat = 0;
|
|
||||||
dev->smbus.ctl = 0;
|
|
||||||
dev->smbus.cmd = 0;
|
|
||||||
dev->smbus.addr = 0;
|
|
||||||
dev->smbus.data0 = 0;
|
|
||||||
dev->smbus.data1 = 0;
|
|
||||||
dev->smbus.index = 0;
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
dev->smbus.data[i] = 0;
|
|
||||||
timer_add(&dev->smbus.command_timer, smbus_inter, dev, 0);
|
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
253
src/smbus_piix4.c
Normal file
253
src/smbus_piix4.c
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* Implementation of a generic PIIX4-compatible SMBus host controller.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors: RichardG, <richardg867@gmail.com>
|
||||||
|
*
|
||||||
|
* Copyright 2020 RichardG.
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#define HAVE_STDARG_H
|
||||||
|
#include <86box/86box.h>
|
||||||
|
#include <86box/io.h>
|
||||||
|
#include <86box/device.h>
|
||||||
|
#include <86box/timer.h>
|
||||||
|
#include <86box/smbus.h>
|
||||||
|
#include <86box/smbus_piix4.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_SMBUS_PIIX4_LOG
|
||||||
|
int smbus_piix4_do_log = ENABLE_SMBUS_PIIX4_LOG;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
smbus_piix4_log(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (smbus_piix4_do_log) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
pclog_ex(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define smbus_piix4_log(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
smbus_piix4_read(uint16_t addr, void *priv)
|
||||||
|
{
|
||||||
|
smbus_piix4_t *dev = (smbus_piix4_t *) priv;
|
||||||
|
uint8_t ret = 0x00;
|
||||||
|
|
||||||
|
switch (addr - dev->io_base) {
|
||||||
|
case 0x00:
|
||||||
|
ret = dev->stat;
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
dev->index = 0; /* reading from this resets the block data index */
|
||||||
|
ret = dev->ctl;
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
ret = dev->cmd;
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
ret = dev->addr;
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
ret = dev->data0;
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
ret = dev->data1;
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
ret = dev->data[dev->index++];
|
||||||
|
if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE)
|
||||||
|
dev->index = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
smbus_piix4_log("SMBus PIIX4: read(%02x) = %02x\n", addr, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
smbus_piix4_write(uint16_t addr, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
smbus_piix4_t *dev = (smbus_piix4_t *) priv;
|
||||||
|
uint8_t smbus_addr, smbus_read, prev_stat;
|
||||||
|
uint16_t temp;
|
||||||
|
|
||||||
|
smbus_piix4_log("SMBus PIIX4: write(%02x, %02x)\n", addr, val);
|
||||||
|
|
||||||
|
prev_stat = dev->next_stat;
|
||||||
|
dev->next_stat = 0;
|
||||||
|
switch (addr - dev->io_base) {
|
||||||
|
case 0x00:
|
||||||
|
/* some status bits are reset by writing 1 to them */
|
||||||
|
for (smbus_addr = 0x02; smbus_addr <= 0x10; smbus_addr = smbus_addr << 1) {
|
||||||
|
if (val & smbus_addr)
|
||||||
|
dev->stat = dev->stat & ~smbus_addr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
dev->ctl = val & ~(0x40); /* START always reads 0 */
|
||||||
|
if (val & 0x02) { /* cancel an in-progress command if KILL is set */
|
||||||
|
/* cancel only if a command is in progress */
|
||||||
|
if (prev_stat) {
|
||||||
|
dev->stat = 0x10; /* raise FAILED */
|
||||||
|
timer_disable(&dev->response_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val & 0x40) { /* dispatch command if START is set */
|
||||||
|
smbus_addr = (dev->addr >> 1);
|
||||||
|
if (!smbus_has_device(smbus_addr)) {
|
||||||
|
/* raise DEV_ERR if no device is at this address */
|
||||||
|
dev->next_stat = 0x4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
smbus_read = (dev->addr & 0x01);
|
||||||
|
|
||||||
|
/* decode the 3-bit command protocol */
|
||||||
|
switch ((val >> 2) & 0x7) {
|
||||||
|
case 0x0: /* quick R/W */
|
||||||
|
dev->next_stat = 0x2;
|
||||||
|
break;
|
||||||
|
case 0x1: /* byte R/W */
|
||||||
|
if (smbus_read)
|
||||||
|
dev->data0 = smbus_read_byte(smbus_addr);
|
||||||
|
else
|
||||||
|
smbus_write_byte(smbus_addr, dev->data0);
|
||||||
|
dev->next_stat = 0x2;
|
||||||
|
break;
|
||||||
|
case 0x2: /* byte data R/W */
|
||||||
|
if (smbus_read)
|
||||||
|
dev->data0 = smbus_read_byte_cmd(smbus_addr, dev->cmd);
|
||||||
|
else
|
||||||
|
smbus_write_byte_cmd(smbus_addr, dev->cmd, dev->data0);
|
||||||
|
dev->next_stat = 0x2;
|
||||||
|
break;
|
||||||
|
case 0x3: /* word data R/W */
|
||||||
|
if (smbus_read) {
|
||||||
|
temp = smbus_read_word_cmd(smbus_addr, dev->cmd);
|
||||||
|
dev->data0 = (temp & 0xFF);
|
||||||
|
dev->data1 = (temp >> 8);
|
||||||
|
} else {
|
||||||
|
temp = (dev->data1 << 8) | dev->data0;
|
||||||
|
smbus_write_word_cmd(smbus_addr, dev->cmd, temp);
|
||||||
|
}
|
||||||
|
dev->next_stat = 0x2;
|
||||||
|
break;
|
||||||
|
case 0x5: /* block R/W */
|
||||||
|
if (smbus_read)
|
||||||
|
dev->data0 = smbus_read_block_cmd(smbus_addr, dev->cmd, dev->data);
|
||||||
|
else
|
||||||
|
smbus_write_block_cmd(smbus_addr, dev->cmd, dev->data, dev->data0);
|
||||||
|
dev->next_stat = 0x2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* other command protocols have undefined behavior, but raise DEV_ERR to be safe */
|
||||||
|
dev->next_stat = 0x4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
dev->cmd = val;
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
dev->addr = val;
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
dev->data0 = val;
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
dev->data1 = val;
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
dev->data[dev->index++] = val;
|
||||||
|
if (dev->index >= SMBUS_PIIX4_BLOCK_DATA_SIZE)
|
||||||
|
dev->index = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if a status register update was given, dispatch it after 10ms to ensure nothing breaks */
|
||||||
|
if (dev->next_stat) {
|
||||||
|
dev->stat = 0x1; /* raise HOST_BUSY while waiting */
|
||||||
|
timer_disable(&dev->response_timer);
|
||||||
|
timer_set_delay_u64(&dev->response_timer, 10 * TIMER_USEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
smbus_piix4_response(void *priv)
|
||||||
|
{
|
||||||
|
smbus_piix4_t *dev = (smbus_piix4_t *) priv;
|
||||||
|
|
||||||
|
/* dispatch the status register update */
|
||||||
|
dev->stat = dev->next_stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable)
|
||||||
|
{
|
||||||
|
if (dev->io_base != 0x0000)
|
||||||
|
io_removehandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev);
|
||||||
|
|
||||||
|
dev->io_base = new_io_base;
|
||||||
|
smbus_piix4_log("SMBus PIIX4: remap to %04Xh\n", dev->io_base);
|
||||||
|
|
||||||
|
if (enable && (dev->io_base != 0x0000))
|
||||||
|
io_sethandler(dev->io_base, 0x10, smbus_piix4_read, NULL, NULL, smbus_piix4_write, NULL, NULL, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
smbus_piix4_init(const device_t *info)
|
||||||
|
{
|
||||||
|
smbus_piix4_t *dev = (smbus_piix4_t *) malloc(sizeof(smbus_piix4_t));
|
||||||
|
memset(dev, 0, sizeof(smbus_piix4_t));
|
||||||
|
|
||||||
|
smbus_init();
|
||||||
|
timer_add(&dev->response_timer, smbus_piix4_response, dev, 0);
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
smbus_piix4_close(void *priv)
|
||||||
|
{
|
||||||
|
smbus_piix4_t *dev = (smbus_piix4_t *) priv;
|
||||||
|
|
||||||
|
free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const device_t piix4_smbus_device = {
|
||||||
|
"PIIX4-compatible SMBus Host Controller",
|
||||||
|
DEVICE_AT,
|
||||||
|
0,
|
||||||
|
smbus_piix4_init, smbus_piix4_close, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL
|
||||||
|
};
|
@@ -593,7 +593,7 @@ DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postc
|
|||||||
sio_w83787f.o \
|
sio_w83787f.o \
|
||||||
sio_w83877f.o sio_w83977f.o \
|
sio_w83877f.o sio_w83977f.o \
|
||||||
sio_um8669f.o \
|
sio_um8669f.o \
|
||||||
smbus.o spd.o \
|
smbus.o smbus_piix4.o spd.o \
|
||||||
keyboard.o \
|
keyboard.o \
|
||||||
keyboard_xt.o keyboard_at.o \
|
keyboard_xt.o keyboard_at.o \
|
||||||
gameport.o \
|
gameport.o \
|
||||||
|
@@ -598,7 +598,7 @@ DEVOBJ := bugger.o hwm.o hwm_w83781d.o ibm_5161.o isamem.o isartc.o lpt.o postc
|
|||||||
sio_w83787f.o \
|
sio_w83787f.o \
|
||||||
sio_w83877f.o sio_w83977f.o \
|
sio_w83877f.o sio_w83977f.o \
|
||||||
sio_um8669f.o \
|
sio_um8669f.o \
|
||||||
smbus.o spd.o \
|
smbus.o smbus_piix4.o spd.o \
|
||||||
keyboard.o \
|
keyboard.o \
|
||||||
keyboard_xt.o keyboard_at.o \
|
keyboard_xt.o keyboard_at.o \
|
||||||
gameport.o \
|
gameport.o \
|
||||||
|
Reference in New Issue
Block a user