From a8c813cb4b489315350654083d00c55761eb3cf6 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 8 Sep 2020 21:43:54 -0300 Subject: [PATCH] Initial implementation of ALi M6117D --- src/chipset/ali6117.c | 350 ++++++++++++++++++++++++++++++++++++ src/include/86box/chipset.h | 3 + src/win/Makefile.mingw | 4 +- 3 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 src/chipset/ali6117.c diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c new file mode 100644 index 000000000..14967e4f9 --- /dev/null +++ b/src/chipset/ali6117.c @@ -0,0 +1,350 @@ +/* + * 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 the ALi M6117D SoC. + * + * + * + * Authors: RichardG, + * + * Copyright 2020 RichardG. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/mem.h> +#include <86box/io.h> +#include <86box/rom.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/port_92.h> +#include <86box/usb.h> +#include <86box/hdc.h> +#include <86box/chipset.h> + + +typedef struct ali6117_t +{ + uint32_t local; + + /* Main registers (port 22h/23h) */ + uint8_t unlocked; + uint8_t reg_offset; + uint8_t regs[256]; +} ali6117_t; + + +#ifdef ENABLE_ALI6117_LOG +int ali6117_do_log = ENABLE_ALI6117_LOG; + +static void +ali6117_log(const char *fmt, ...) +{ + va_list ap; + + if (ali6117_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define ali6117_log(fmt, ...) +#endif + + +static void +ali6117_recalcmapping(ali6117_t *dev) +{ + uint8_t reg, bitpair; + uint32_t base, size; + int state; + + shadowbios = 0; + shadowbios_write = 0; + + ali6117_log("M6117: Shadowing for 0xa0000-0xbffff (reg %02X) = %s\n", (dev->regs[0x12] & 0x02) ? "on" : "off"); + mem_set_mem_state(0xa0000, 0x20000, (dev->regs[0x12] & 0x02) ? (MEM_WRITE_INTERNAL | MEM_READ_INTERNAL) : (MEM_WRITE_EXTANY | MEM_READ_EXTANY)); + + for (reg = 0; reg <= 1; reg++) { + for (bitpair = 0; bitpair <= 3; bitpair++) { + size = 0x8000; + base = 0xc0000 + (size * ((reg * 4) + bitpair)); + ali6117_log("M6117: Shadowing for %05x-%05x (reg %02X bp %d wmask %02X rmask %02X) =", base, base + size - 1, 0x14 + reg, bitpair, 1 << ((bitpair * 2) + 1), 1 << (bitpair * 2)); + + state = 0; + if (dev->regs[0x14 + reg] & (1 << ((bitpair * 2) + 1))) { + ali6117_log(" w on"); + state |= MEM_WRITE_INTERNAL; + if (base >= 0xe0000) + shadowbios_write |= 1; + } else { + ali6117_log(" w off"); + state |= MEM_WRITE_EXTANY; + } + if (dev->regs[0x14 + reg] & (1 << (bitpair * 2))) { + ali6117_log("; r on\n"); + state |= MEM_READ_INTERNAL; + if (base >= 0xe0000) + shadowbios |= 1; + } else { + ali6117_log("; r off\n"); + state |= MEM_READ_EXTANY; + } + + mem_set_mem_state(base, size, state); + } + } + + flushmmucache(); +} + + +static void +ali6117_smram_map(int smm, uint32_t addr, uint32_t size, int is_smram) +{ + mem_set_mem_state_smram(smm, addr, size, is_smram); +} + + +static void +ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) +{ + ali6117_t *dev = (ali6117_t *) priv; + + ali6117_log("ALI6117: reg_write(%04X, %02X)\n", addr, val); + + if (addr == 0x22) + dev->reg_offset = val; + else if (dev->reg_offset == 0x13) + dev->unlocked = (val == 0xc5); + else if (dev->unlocked) { + ali6117_log("ALI6117: regs[%02X] = %02X\n", dev->reg_offset, val); + + switch (dev->reg_offset) { + case 0x30: case 0x34: case 0x35: case 0x3e: + case 0x3f: case 0x46: case 0x4c: case 0x6a: + case 0x73: + return; /* read-only registers */ + + case 0x12: + val &= 0xf7; + /* FALL-THROUGH */ + + case 0x14: case 0x15: + dev->regs[dev->reg_offset] = val; + ali6117_recalcmapping(dev); + break; + + case 0x1e: + val &= 0x07; + break; + + case 0x20: + val &= 0xbf; + refresh_at_enable = (val & 0x02); + break; + + case 0x31: + /* TODO: fast gate A20 (bit 0) */ + val &= 0x21; + break; + + case 0x32: + val &= 0xc1; + break; + + case 0x33: + val &= 0xfd; + break; + + case 0x36: + val &= 0xf0; + val |= dev->regs[dev->reg_offset]; + break; + + case 0x37: + val &= 0xf5; + break; + + case 0x3c: + /* TODO: IDE channel selection (bit 0, secondary if set) */ + val &= 0x8f; + break; + + case 0x44: case 0x45: + val &= 0x3f; + break; + + case 0x4a: + val &= 0xfe; + break; + + case 0x55: + val &= 0x03; + break; + + case 0x56: + val &= 0xc7; + break; + + case 0x58: + val &= 0xc3; + break; + + case 0x59: + val &= 0x60; + break; + + case 0x5b: + val &= 0x1f; + break; + + case 0x64: + val &= 0xf7; + break; + + case 0x66: + val &= 0xe3; + break; + + case 0x67: + val &= 0xdf; + break; + + case 0x69: + val &= 0x50; + break; + + case 0x6b: + val &= 0x7f; + break; + + case 0x6e: case 0x6f: + val &= 0x03; + break; + + case 0x71: + val &= 0x1f; + break; + } + + dev->regs[dev->reg_offset] = val; + } +} + + +static uint8_t +ali6117_reg_read(uint16_t addr, void *priv) +{ + ali6117_t *dev = (ali6117_t *) priv; + uint8_t ret; + + if (addr == 0x22) + ret = dev->reg_offset; + else + ret = dev->regs[dev->reg_offset]; + + ali6117_log("ALI6117: reg_read(%04X) = %02X\n", dev->reg_offset, ret); + return ret; +} + + +static void +ali6117_reset(void *priv) +{ + ali6117_t *dev = (ali6117_t *) priv; + + ali6117_log("ALI6117: reset()\n"); + + memset(dev->regs, 0, sizeof(dev->regs)); + dev->regs[0x11] = 0xf8; + dev->regs[0x12] = 0x20; + dev->regs[0x17] = 0xff; + dev->regs[0x18] = 0xf0; + dev->regs[0x1a] = 0xff; + dev->regs[0x1b] = 0xf0; + dev->regs[0x1d] = 0xff; + dev->regs[0x20] = 0x80; + dev->regs[0x30] = 0x08; + dev->regs[0x31] = 0x01; + dev->regs[0x34] = 0x04; /* enable internal RTC */ + dev->regs[0x35] = 0x20; /* enable internal KBC */ + dev->regs[0x36] = (dev->local & 0x4); /* M6117D ID */ +} + + +static void +ali6117_setup(ali6117_t *dev) +{ + ali6117_log("ALI6117: setup()\n"); + + /* Main register interface */ + io_sethandler(0x22, 2, + ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev); +} + + +static void +ali6117_close(void *priv) +{ + ali6117_t *dev = (ali6117_t *) priv; + + ali6117_log("ALI6117: close()\n"); + + io_removehandler(0x22, 2, + ali6117_reg_read, NULL, NULL, ali6117_reg_write, NULL, NULL, dev); + + free(dev); +} + + +static void * +ali6117_init(const device_t *info) +{ + ali6117_log("ALI6117: init()\n"); + + ali6117_t *dev = (ali6117_t *) malloc(sizeof(ali6117_t)); + memset(dev, 0, sizeof(ali6117_t)); + + dev->local = info->local; + + device_add(&ide_isa_device); + + ali6117_setup(dev); + ali6117_reset(dev); + + pci_elcr_io_disable(); + refresh_at_enable = 0; + + return dev; +} + + +const device_t ali6117d_device = +{ + "ALi M6117D", + DEVICE_AT, + 0x2, + ali6117_init, + ali6117_close, + ali6117_reset, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 36be94044..683491c85 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -26,6 +26,9 @@ extern const device_t ali1429_device; #if defined(DEV_BRANCH) && defined(USE_M1489) extern const device_t ali1489_device; #endif +#if defined(DEV_BRANCH) && defined(USE_STPC) +extern const device_t ali6117d_device; +#endif /* AMD */ extern const device_t amd640_device; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 2abce2836..a1fa60d51 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -560,7 +560,7 @@ endif ifeq ($(STPC), y) OPTS += -DUSE_STPC -DEVBROBJ += stpc.o +DEVBROBJ += ali6117.o stpc.o endif ifeq ($(M1489), y) @@ -601,7 +601,7 @@ endif # Final versions of the toolchain flags. CFLAGS := $(WX_FLAGS) $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) \ - $(AFLAGS) -fomit-frame-pointer -mstackrealign -Wall \ + $(AFLAGS) -mstackrealign -Wall \ -fno-strict-aliasing # Add freetyp2 references through pkgconfig