/*
* QEMU GT64120 PCI host
*
- * Copyright (c) 2006 Aurelien Jarno
+ * Copyright (c) 2006,2007 Aurelien Jarno
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
typedef struct GT64120State {
GT64120PCIState *pci;
uint32_t regs[GT_REGS];
+ target_phys_addr_t PCI0IO_start;
+ target_phys_addr_t PCI0IO_length;
} GT64120State;
static void gt64120_pci_mapping(GT64120State *s)
{
- target_phys_addr_t start, length;
-
/* Update IO mapping */
- start = s->regs[GT_PCI0IOLD] << 21;
- length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
- isa_mmio_init(start, length);
+ if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD])
+ {
+ /* Unmap old IO address */
+ if (s->PCI0IO_length)
+ {
+ cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED);
+ }
+ /* Map new IO address */
+ s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
+ s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
+ isa_mem_base = s->PCI0IO_start;
+ isa_mmio_init(s->PCI0IO_start, s->PCI0IO_length);
+ }
}
static void gt64120_writel (void *opaque, target_phys_addr_t addr,
GT64120State *s = opaque;
uint32_t saddr;
+#ifdef TARGET_WORDS_BIGENDIAN
+ val = bswap32(val);
+#endif
+
saddr = (addr & 0xfff) >> 2;
switch (saddr) {
- /* CPU Configuration Register */
+
+ /* CPU Configuration */
case GT_CPU:
s->regs[GT_CPU] = val;
- gt64120_pci_mapping(s);
break;
case GT_MULTI:
+ /* Read-only register as only one GT64xxx is present on the CPU bus */
break;
/* CPU Address Decode */
case GT_CPUERR_DATALO:
case GT_CPUERR_DATAHI:
case GT_CPUERR_PARITY:
+ /* Read-only registers, do nothing */
+ break;
+
+ /* CPU Sync Barrier */
+ case GT_PCI0SYNC:
+ case GT_PCI1SYNC:
+ /* Read-only registers, do nothing */
break;
/* ECC */
case GT_ECC_MEM:
case GT_ECC_CALC:
case GT_ECC_ERRADDR:
+ /* Read-only registers, do nothing */
break;
/* PCI Internal */
pci_host_data_writel(s->pci, 0, val);
break;
+ /* SDRAM Parameters */
+ case GT_SDRAM_B0:
+ case GT_SDRAM_B1:
+ case GT_SDRAM_B2:
+ case GT_SDRAM_B3:
+ /* We don't simulate electrical parameters of the SDRAM.
+ Accept, but ignore the values. */
+ s->regs[saddr] = val;
+ break;
+
default:
#if 0
printf ("gt64120_writel: Bad register offset 0x%x\n", (int)addr);
switch (saddr) {
+ /* CPU Configuration */
+ case GT_MULTI:
+ /* Only one GT64xxx is present on the CPU bus, return
+ the initial value */
+ val = s->regs[saddr];
+ break;
+
/* CPU Error Report */
case GT_CPUERR_ADDRLO:
case GT_CPUERR_ADDRHI:
case GT_CPUERR_DATALO:
case GT_CPUERR_DATAHI:
case GT_CPUERR_PARITY:
- return 0;
+ /* Emulated memory has no error, always return the initial
+ values */
+ val = s->regs[saddr];
+ break;
+
+ /* CPU Sync Barrier */
+ case GT_PCI0SYNC:
+ case GT_PCI1SYNC:
+ /* Reading those register should empty all FIFO on the PCI
+ bus, which are not emulated. The return value should be
+ a random value that should be ignored. */
+ val = 0xc000ffee;
break;
/* ECC */
case GT_ECC_MEM:
case GT_ECC_CALC:
case GT_ECC_ERRADDR:
- return 0;
+ /* Emulated memory has no error, always return the initial
+ values */
+ val = s->regs[saddr];
break;
case GT_CPU:
- case GT_MULTI:
case GT_PCI0IOLD:
case GT_PCI0M0LD:
case GT_PCI0M1LD:
val = s->regs[saddr];
break;
case GT_PCI0_IACK:
- val = pic_intack_read(isa_pic);
+ /* Read the IRQ number */
+ val = pic_read_irq(isa_pic);
+ break;
+
+ /* SDRAM Parameters */
+ case GT_SDRAM_B0:
+ case GT_SDRAM_B1:
+ case GT_SDRAM_B2:
+ case GT_SDRAM_B3:
+ /* We don't simulate electrical parameters of the SDRAM.
+ Just return the last written value. */
+ val = s->regs[saddr];
break;
/* PCI Internal */
break;
}
+#ifdef TARGET_WORDS_BIGENDIAN
+ return bswap32(val);
+#else
return val;
+#endif
}
static CPUWriteMemoryFunc *gt64120_write[] = {
s->regs[GT_ECC_CALC] = 0x00000000;
s->regs[GT_ECC_ERRADDR] = 0x00000000;
+ /* SDRAM Parameters */
+ s->regs[GT_SDRAM_B0] = 0x00000005;
+ s->regs[GT_SDRAM_B1] = 0x00000005;
+ s->regs[GT_SDRAM_B2] = 0x00000005;
+ s->regs[GT_SDRAM_B3] = 0x00000005;
+
/* PCI Internal FIXME: not complete*/
#ifdef TARGET_WORDS_BIGENDIAN
s->regs[GT_PCI0_CMD] = 0x00000000;