Fix Xbox SuperIO code

This commit is contained in:
Matt Borgerson 2018-06-26 14:46:54 -07:00
parent 5e1deea596
commit a87f67f143
1 changed files with 36 additions and 34 deletions

View File

@ -17,11 +17,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw/isa/isa.h"
#include "qemu/osdep.h"
#include "hw/char/serial.h"
#include "sysemu/sysemu.h"
#include "sysemu/char.h"
#include "qapi/qmp/qerror.h"
#include "hw/isa/isa.h"
#include "qapi/error.h"
#define MAX_DEVICE 0xC
#define DEVICE_FDD 0x0
@ -73,13 +72,13 @@ typedef struct LPC47M157State {
static void update_devices(LPC47M157State *s)
{
ISADevice *isadev = ISA_DEVICE(s);
/* init serial devices */
int i;
for (i=0; i<2; i++) {
for (i = 0; i < 2; i++) {
uint8_t *dev = s->device_regs[DEVICE_SERIAL_PORT_1 + i];
if (dev[CONFIG_DEVICE_ACTIVATE] && !s->serial[i].active) {
uint32_t iobase = (dev[CONFIG_DEVICE_BASE_ADDRESS_HIGH] << 8)
| dev[CONFIG_DEVICE_BASE_ADDRESS_LOW];
uint32_t irq = dev[CONFIG_DEVICE_INETRRUPT];
@ -101,10 +100,11 @@ static void lpc47m157_io_write(void *opaque, hwaddr addr, uint64_t val,
LPC47M157State *s = opaque;
#ifdef DEBUG_LPC47M157
printf("lpc47m157 io write 0x%llx = 0x%llx\n", addr, val);
printf("lpc47m157 io write 0x%"HWADDR_PRIx" = 0x%"PRIx64"\n", addr, val);
#endif
if (addr == 0) { //INDEX_PORT
if (addr == 0) {
/* INDEX_PORT */
if (val == ENTER_CONFIG_KEY) {
assert(!s->configuration_mode);
s->configuration_mode = true;
@ -116,17 +116,20 @@ static void lpc47m157_io_write(void *opaque, hwaddr addr, uint64_t val,
} else {
s->selected_reg = val;
}
} else if (addr == 1) { //DATA_PORT
} else if (addr == 1) {
/* DATA_PORT */
if (s->selected_reg < MAX_CONFIG_REG) {
/* global configuration register */
s->config_regs[s->selected_reg] = val;
} else {
/* device register */
assert(s->config_regs[CONFIG_DEVICE_NUMBER] < MAX_DEVICE);
uint8_t* dev = s->device_regs[s->config_regs[CONFIG_DEVICE_NUMBER]];
uint8_t *dev = s->device_regs[s->config_regs[CONFIG_DEVICE_NUMBER]];
dev[s->selected_reg] = val;
#ifdef DEBUG_LPC47M157
printf("lpc47m157 dev %x . %x = %llx\n", s->config_regs[CONFIG_DEVICE_NUMBER], s->selected_reg, val);
printf("lpc47m157 dev %x . %x = %"PRIx64"\n",
s->config_regs[CONFIG_DEVICE_NUMBER],
s->selected_reg, val);
#endif
}
} else {
@ -139,14 +142,15 @@ static uint64_t lpc47m157_io_read(void *opaque, hwaddr addr, unsigned int size)
LPC47M157State *s = opaque;
uint32_t val = 0;
if (addr == 0) { //INDEX_PORT
} else if (addr == 1) { //DATA_PORT
if (addr == 0) {
/* INDEX_PORT */
} else if (addr == 1) {
/* DATA_PORT */
if (s->selected_reg < MAX_CONFIG_REG) {
val = s->config_regs[s->selected_reg];
} else {
assert(s->config_regs[CONFIG_DEVICE_NUMBER] < MAX_DEVICE);
uint8_t* dev = s->device_regs[s->config_regs[CONFIG_DEVICE_NUMBER]];
uint8_t *dev = s->device_regs[s->config_regs[CONFIG_DEVICE_NUMBER]];
val = dev[s->selected_reg];
}
} else {
@ -154,7 +158,7 @@ static uint64_t lpc47m157_io_read(void *opaque, hwaddr addr, unsigned int size)
}
#ifdef DEBUG_LPC47M157
printf("lpc47m157 io read 0x%llx -> 0x%x\n", addr, val);
printf("lpc47m157 io read 0x%"HWADDR_PRIx" -> 0x%x\n", addr, val);
#endif
return val;
@ -169,12 +173,18 @@ static const MemoryRegionOps lpc47m157_io_ops = {
},
};
static Property lpc47m157_properties[] = {
DEFINE_PROP_CHR("chardev0", LPC47M157State, serial[0].state.chr),
DEFINE_PROP_CHR("chardev1", LPC47M157State, serial[1].state.chr),
DEFINE_PROP_END_OF_LIST(),
};
static void lpc47m157_realize(DeviceState *dev, Error **errp)
{
LPC47M157State *s = LPC47M157_DEVICE(dev);
ISADevice *isa = ISA_DEVICE(dev);
const uint32_t iobase = 0x2e; //0x4e if SYSOPT pin, make it a property
const uint32_t iobase = 0x2e; //0x4e if SYSOPT pin, make it a property
s->config_regs[CONFIG_PORT_LOW] = iobase & 0xFF;
s->config_regs[CONFIG_PORT_HIGH] = iobase >> 8;
@ -184,32 +194,24 @@ static void lpc47m157_realize(DeviceState *dev, Error **errp)
/* init serial cores */
int i;
for (i=0; i<2; i++) {
CharDriverState *chr = serial_hds[i];
for (i = 0; i < 2; i++) {
Chardev *chr = serial_hds[i];
if (chr == NULL) {
char name[5];
snprintf(name, sizeof(name), "ser%d", i);
chr = qemu_chr_new(name, "null", NULL);
chr = qemu_chr_new(name, "null");
}
SerialState *ss = &s->serial[i].state;
ss->chr = chr;
ss->baudbase = 115200;
Error *err = NULL;
serial_realize_core(ss, &err);
if (err != NULL) {
qerror_report_err(err);
error_free(err);
exit(1);
}
qdev_prop_set_chr(dev, i == 0 ? "chardev0" : "chardev1", chr);
serial_realize_core(ss, errp);
memory_region_init_io(&ss->io, OBJECT(s),
&serial_io_ops, ss, "serial", 8);
}
}
static const VMStateDescription vmstate_lpc47m157= {
static const VMStateDescription vmstate_lpc47m157 = {
.name = "lpc47m157",
.version_id = 1,
.minimum_version_id = 1,
@ -229,7 +231,7 @@ static void lpc47m157_class_init(ObjectClass *klass, void *data)
dc->realize = lpc47m157_realize;
dc->vmsd = &vmstate_lpc47m157;
//dc->reset = pc87312_reset;
//dc->props = pc87312_properties;
dc->props = lpc47m157_properties;
}
static const TypeInfo lpc47m157_type_info = {
@ -244,4 +246,4 @@ static void lpc47m157_register_types(void)
type_register_static(&lpc47m157_type_info);
}
type_init(lpc47m157_register_types)
type_init(lpc47m157_register_types)