Skip to content

Commit

Permalink
SMSC USB SMI implementation
Browse files Browse the repository at this point in the history
OHCI Hce* register implementation
  • Loading branch information
Cacodemon345 committed May 27, 2024
1 parent 9a85282 commit 521cb1d
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 13 deletions.
16 changes: 16 additions & 0 deletions src/chipset/intel_piix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,19 @@ piix_speed_changed(void *priv)
timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period);
}

static void
piix_smsc_usb_smi_raise(void* priv)
{
piix_t *dev = (piix_t *) priv;
if (!dev)
return;

if ((dev->acpi->regs.glben & 1)) {
dev->acpi->regs.glbsts |= 2;
acpi_raise_smi(dev->acpi, 1);
}
}

static void *
piix_init(const device_t *info)
{
Expand All @@ -1554,6 +1567,9 @@ piix_init(const device_t *info)
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
params.pci_dev = &dev->pci_slot;
params.pci_conf = &dev->regs[2][0];
params.do_smi_raise = piix_smsc_usb_smi_raise;
params.priv = dev;
params.do_pci_irq = 0;

dev->bm[0] = device_add_inst(&sff8038i_device, 1);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
Expand Down
7 changes: 6 additions & 1 deletion src/chipset/sis_5571_h2p.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv)
break;

case 0x95: /* Test mode control */
dev->sis->test_mode_reg = val & 0xfb;
pclog("SiS: USB SMI# %sabled\n", (dev->sis->test_mode_reg & 0x10) ? "en" : "dis");
break;
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
dev->pci_conf[addr] = val & 0xfb;
break;
Expand Down Expand Up @@ -309,7 +312,7 @@ sis_5571_host_to_pci_read(int addr, void *priv)
const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
uint8_t ret = 0xff;

ret = dev->pci_conf[addr];
ret = (addr == 0x95) ? dev->sis->test_mode_reg : dev->pci_conf[addr];

sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);

Expand Down Expand Up @@ -410,6 +413,8 @@ sis_5571_host_to_pci_reset(void *priv)
dev->pci_conf[0xa2] = 0xff;
dev->pci_conf[0xa3] = 0x00;

dev->sis->test_mode_reg = 0x10;

cpu_cache_ext_enabled = 0;
cpu_update_waitstates();

Expand Down
33 changes: 30 additions & 3 deletions src/chipset/sis_5572_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ sis_5572_usb_log(const char *fmt, ...)
#endif

typedef struct sis_5572_usb_t {
uint8_t rev;
uint8_t rev, irq_state;

uint8_t usb_unk_regs[256];
uint8_t pci_conf[256];
Expand All @@ -78,6 +78,30 @@ typedef struct sis_5572_usb_t {
sis_55xx_common_t *sis;
} sis_5572_usb_t;

void
sis_5572_usb_smi_raise(void* priv)
{
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;

if (dev->sis->usb_enabled && (dev->sis->test_mode_reg & 0x10)) {
dev->sis->test_mode_reg |= 0x8;
smi_raise();
}
}

void
sis_5572_usb_pci_irq(void *priv, int level)
{
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;

if (dev->sis->usb_enabled) {
if (level)
pci_set_mirq(PCI_MIRQ3, level, &dev->irq_state);
else
pci_clear_mirq(PCI_MIRQ3, level, &dev->irq_state);
}
}

/* SiS 5572 unknown I/O port (second USB PCI BAR). */
static void
sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv)
Expand Down Expand Up @@ -275,8 +299,11 @@ sis_5572_usb_init(UNUSED(const device_t *info))

/* USB */
usb_param.pci_conf = dev->pci_conf;
usb_param.pci_dev = dev->sis->sb_southbridge_slot;
dev->usb = device_add(&usb_device);
usb_param.pci_dev = dev->sis->sb_southbridge_slot;
usb_param.priv = dev;
usb_param.do_smi_raise = sis_5572_usb_smi_raise;
usb_param.do_pci_irq = sis_5572_usb_pci_irq;
dev->usb = device_add_params(&usb_device, &usb_param);
ohci_register_usb(dev->usb);

sis_5572_usb_reset(dev);
Expand Down
7 changes: 5 additions & 2 deletions src/chipset/sis_5581_h2p.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv)
break;

case 0x95:
dev->pci_conf[addr] = val & 0xfb;
dev->sis->test_mode_reg = val & 0xfb;
pclog("SiS: USB SMI# %sabled\n", (dev->sis->test_mode_reg & 0x10) ? "en" : "dis");
break;

case 0x96:
Expand Down Expand Up @@ -418,7 +419,7 @@ sis_5581_host_to_pci_read(int addr, void *priv)
const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
uint8_t ret = 0xff;

ret = dev->pci_conf[addr];
ret = (addr == 0x95) ? dev->sis->test_mode_reg : dev->pci_conf[addr];

sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);

Expand Down Expand Up @@ -478,6 +479,8 @@ sis_5581_host_to_pci_reset(void *priv)
dev->pci_conf[0xa1] = 0x00;
dev->pci_conf[0xa2] = 0xff;
dev->pci_conf[0xa3] = 0x00;

dev->sis->test_mode_reg = 0x00;

cpu_cache_ext_enabled = 0;
cpu_update_waitstates();
Expand Down
1 change: 1 addition & 0 deletions src/include/86box/sis_55xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef struct
uint8_t *sb_southbridge_slot;
uint8_t ide_bits_1_3_writable;
uint8_t usb_enabled;
uint8_t test_mode_reg; /* USB SMI control. */

uint8_t *pmu_regs;

Expand Down
4 changes: 4 additions & 0 deletions src/include/86box/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ typedef struct usb_device_c usb_device_c;
typedef struct usb_params_t {
uint8_t* pci_dev;
uint8_t* pci_conf;

void* priv; /* Implementation-specific behaviour. */
void (*do_smi_raise)(void* priv);
void (*do_pci_irq)(void* priv, int level);
} usb_params_t;

typedef struct usb_t {
Expand Down
4 changes: 2 additions & 2 deletions src/usb/usb_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ usb_hid_poll_wrapper(void *priv)

mouse_subtract_coords(&delta_x, &delta_y, &overflow_x, &overflow_y,
-128, 127, 1, 0);
mouse_subtract_z(&delta_z, -8, 7, 1);
mouse_subtract_z(&delta_z, -8, 7, 0);
mouse_enq(hid, delta_x, delta_y, delta_z, b, 0);
return 1;
}
Expand Down Expand Up @@ -1505,7 +1505,7 @@ usb_device_hid_handle_data(usb_device_c *device, USBPacket *p)
case USB_TOKEN_IN:
if (p->devep == 1) {
if ((device->type == USB_HID_TYPE_MOUSE) || (device->type == USB_HID_TYPE_TABLET)) {
pclog("USB MOUSE POLLING\n");
//pclog("USB MOUSE POLLING\n");
ret = usb_mouse_poll((usb_device_hid *) device, p->data, 0);
} else {
goto fail;
Expand Down
67 changes: 62 additions & 5 deletions src/usb/usb_ohci_bochs.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ typedef struct {
bool oci; // 1 bit OverCurrentIndicator = 0b R RW
bool lps; // 1 bit LocalPowerStatus(r) = 0b RW R
} HcRhStatus; // = 0x00000000

uint32_t HceInput, HceOutput, HceControl, HceStatus;
} op_regs;

struct {
Expand Down Expand Up @@ -235,6 +237,10 @@ typedef struct {

bool ohci_enable;
uint32_t ohci_mem_base;

void (*do_smi_raise)(void *priv);
void (*do_pci_irq)(void *priv, int level);
void* card_priv;
} bx_ohci_core_t;

const char *usb_ohci_port_name[] = {
Expand Down Expand Up @@ -301,13 +307,19 @@ void usb_ohci_update_irq(bx_ohci_core_t* hub)
(hub->op_regs.HcInterruptStatus & hub->op_regs.HcInterruptEnable)) {
level = 1;
}
if (hub->op_regs.HcControl.ir && level)
smi_raise();
if (hub->op_regs.HcControl.ir && level) {
if (hub->do_smi_raise && hub->card_priv)
hub->do_smi_raise(hub->card_priv);
else
smi_raise();
}
else if (!hub->op_regs.HcControl.ir) {
if (level)
if (hub->do_pci_irq)
hub->do_pci_irq(hub->card_priv, level);
else if (level)
pci_set_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state);
else
pci_set_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state);
pci_clear_irq(*hub->devfunc, hub->pci_conf[0x3d], &hub->irq_state);
}
}

Expand Down Expand Up @@ -767,6 +779,26 @@ uint32_t usb_ohci_mem_read(uint32_t addr, void *priv)
| (hub->usb_port[p].HcRhPortStatus.ccs ? (1 << 0) : 0);
break;

case 0x100: {
val = (hub->op_regs.HceControl & 0xFF) | ((!!mem_a20_key) << 8);
break;
}

case 0x104: {
val = hub->op_regs.HceInput;
break;
}

case 0x108: {
val = hub->op_regs.HceOutput;
break;
}

case 0x10C: {
val = hub->op_regs.HceStatus;
break;
}

default:
BX_ERROR(("unsupported read from address=0x%08X!", (Bit32u)addr));
break;
Expand Down Expand Up @@ -836,7 +868,10 @@ void usb_ohci_mem_write(uint32_t addr, uint32_t value, void* priv)
hub->op_regs.HcInterruptStatus |= 0x40000000;
if ((hub->op_regs.HcInterruptEnable & 0xC0000000) == 0xC0000000) {
pclog("Assert SMI#\n");
smi_raise();
if (hub->do_smi_raise && hub->card_priv)
hub->do_smi_raise(hub->card_priv);
else
smi_raise();
}
}
if (value & (1<< 2)) hub->op_regs.HcCommandStatus.blf = 1;
Expand Down Expand Up @@ -1094,6 +1129,25 @@ void usb_ohci_mem_write(uint32_t addr, uint32_t value, void* priv)
break;
}

case 0x100: {
hub->op_regs.HceControl = value;
break;
}

case 0x104: {
hub->op_regs.HceInput = value;
break;
}

case 0x108: {
hub->op_regs.HceOutput = value;
break;
}

case 0x10C: {
hub->op_regs.HceStatus = value;
break;
}

default:
BX_ERROR(("unsupported write to address=0x%08X, val = 0x%08X!", (Bit32u)addr, value));
Expand Down Expand Up @@ -1593,6 +1647,9 @@ usb_ohci_init(UNUSED(const device_t *info))
if (usb_params) {
hub->devfunc = usb_params->pci_dev;
hub->pci_conf = usb_params->pci_conf;
hub->do_smi_raise = usb_params->do_smi_raise;
hub->card_priv = usb_params->priv;
hub->do_pci_irq = usb_params->do_pci_irq;
}
timer_add(&hub->timer, usb_ohci_timer, hub, 0);
timer_on_auto(&hub->timer, 1000);
Expand Down

0 comments on commit 521cb1d

Please sign in to comment.