From 33a6b1fa243c311f95dd3bf1a9c1fb2904e0cc3f Mon Sep 17 00:00:00 2001 From: yajin Date: Tue, 16 Jun 2009 19:44:53 +0800 Subject: [PATCH] 1. fix the bug of sm502 pci configuration r/w 2. do not map the sm502 to loongson pci memory space if sm502_mmio_base_addr(reg 0x10)>256M --- hw/sm502.c | 125 ++++++++++++++++++++++++++++++++++++++++--------------------- hw/sm502.h | 9 +---- 2 files changed, 83 insertions(+), 51 deletions(-) diff --git a/hw/sm502.c b/hw/sm502.c index d88d1155a1..d1587516ad 100755 --- a/hw/sm502.c +++ b/hw/sm502.c @@ -40,7 +40,7 @@ #define DEBUG_MMIO (1<<0x3) #define DEBUG_ALL (0xffffffff) -#define DEBUG_FLAG DEBUG_ALL +#define DEBUG_FLAG DEBUG_MMIO #ifdef DEBUG #define debug_out(flag,out) {\ @@ -49,6 +49,9 @@ #else #define debug_out(flag,out) #endif + +//#define PRINT_WARNNING + #if 0 static uint32_t sm502_badwidth_read8(void *opaque, target_phys_addr_t addr) { @@ -59,7 +62,7 @@ static uint32_t sm502_badwidth_read8(void *opaque, target_phys_addr_t addr) } static void sm502_badwidth_write8(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint32_t value) { SM502_8B_REG(addr); exit(-1); @@ -73,7 +76,7 @@ static uint32_t sm502_badwidth_read16(void *opaque, target_phys_addr_t addr) return 0; } static void sm502_badwidth_write16(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint32_t value) { SM502_16B_REG(addr); exit(-1); @@ -87,7 +90,7 @@ static uint32_t sm502_badwidth_read32(void *opaque, target_phys_addr_t addr) return 0; } static void sm502_badwidth_write32(void *opaque, target_phys_addr_t addr, - uint32_t value) + uint32_t value) { SM502_32B_REG(addr); exit(-1); @@ -412,7 +415,7 @@ static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val, int can_write, i; uint32_t addr; uint32_t new_sm502_mm_io; - int iomemtype; + uint8_t write_mask; struct sm502_s *s = (struct sm502_s *) d; @@ -422,6 +425,8 @@ static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val, /* not efficient, but simple */ addr = address; + can_write = 1; + write_mask = 0xff; for (i = 0; i < len; i++) { /* default read/write accesses */ @@ -451,31 +456,52 @@ static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val, case 0x43: can_write = 0; break; - case 0x04: + case 0x05: case 0x06: case 0x07: case 0x10: case 0x11: - case 0x12: - case 0x13: + case 0x12: /*[23:21] of reg10 -> 0x0? */ case 0x14: case 0x15: + case 0x31: + case 0x3d: + case 0x3e: + case 0x3f: + case 0x46: + case 0x47: + write_mask = 0; + break; + case 0x04: + write_mask = 0x36; + break; + case 0x13: + write_mask = 0xfe; + break; case 0x16: + write_mask = 0xe0; + break; case 0x17: + write_mask = 0xff; + break; case 0x30: - case 0x31: + if (d->config[4] & 0x2) + write_mask = 0x1; + else + write_mask = 0x0; + break; case 0x32: case 0x33: + if (d->config[4] & 0x2) + write_mask = 0xff; + else + write_mask = 0x0; + break; case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: case 0x44: case 0x45: - case 0x46: - case 0x47: - can_write = 1; + write_mask = 0xff; break; default: /*reserved */ @@ -484,41 +510,49 @@ static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val, } if (can_write == 1) { - d->config[addr] = (val & 0xff); + d->config[addr] = (val & write_mask); if (addr == (0x14 + len - 1)) { /*write the last byte of mmio */ new_sm502_mm_io = le32_to_cpu(*(uint32_t *) (d->config + 0x14)); - if (s->sm502_mm_io != new_sm502_mm_io) + if ((s->sm502_mm_io != new_sm502_mm_io) + && ((pci_mem_base + new_sm502_mm_io) < 0xffffffff)) { + if (s->mmio_index != 0) + { + cpu_register_physical_memory(pci_mem_base + + s->sm502_mm_io, 0x200000, + IO_MEM_UNASSIGNED); + cpu_unregister_io_memory(s->mmio_index); + } /*remapped the Control register to CPU memory space */ - iomemtype = + s->mmio_index = cpu_register_io_memory(0, sm502_readfn, sm502_writefn, s); - cpu_register_physical_memory(new_sm502_mm_io + - s->pci_mem_base, 0x200000, - iomemtype); - debug_out(DEBUG_MMIO,("new_sm502_mm_io %x pci_mem _base %llx\n", - new_sm502_mm_io, s->pci_mem_base)); - if (s->sm502_mm_io != 0) - cpu_register_physical_memory(s->sm502_mm_io + - pci_mem_base, 0x200000, - IO_MEM_UNASSIGNED); - s->sm502_mm_io = new_sm502_mm_io; + cpu_register_physical_memory(pci_mem_base + + new_sm502_mm_io, 0x200000, + s->mmio_index); + debug_out(DEBUG_MMIO, + ("new_sm502_mm_io %x pci_mem _base %llx\n", + new_sm502_mm_io, pci_mem_base)); } } } else if (can_write == 0) { +#ifdef PRINT_WARNNING fprintf(stderr, "warnning. %s :write to read only pci conf register addr %x\n", __FUNCTION__, addr); +#endif } else if (can_write == 2) { +#ifdef PRINT_WARNNING fprintf(stderr, "warnning. %s :write to reserved pci conf register addr %x\n", __FUNCTION__, addr); +#endif } if (++addr > 0xff) break; @@ -528,18 +562,24 @@ static void sm502_write_config(PCIDevice * d, uint32_t address, uint32_t val, static void sm502_reset(struct sm502_s *s) { - s->config[0] = 0x6F; - s->config[1] = 0x12; - s->config[2] = 0x01; - s->config[3] = 0x05; - s->config[6] = 0x30; - s->config[7] = 0x02; - s->config[10] = 0x30; - s->config[11] = 0x02; - s->config[0x34] = 0x40; - s->config[0x40] = 0x01; - s->config[0x42] = 0x01; - s->config[0x43] = 0x06; + uint8_t *pci_conf; + + pci_conf = s->dev.config; + memset(pci_conf, 0, 256); + + pci_conf[0] = 0x6F; + pci_conf[1] = 0x12; + pci_conf[2] = 0x01; + pci_conf[3] = 0x05; + pci_conf[6] = 0x30; + pci_conf[7] = 0x02; + pci_conf[8] = 0xc0; + pci_conf[10] = 0x80; + pci_conf[11] = 0x03; + pci_conf[0x34] = 0x40; + pci_conf[0x40] = 0x01; + pci_conf[0x42] = 0x01; + pci_conf[0x43] = 0x06; s->arb_control = 0x05146732; s->current_gate = 0x00021807; @@ -556,8 +596,7 @@ static void sm502_reset(struct sm502_s *s) } -struct sm502_s *sm502_init(PCIBus * bus, int devfn, - target_phys_addr_t pci_mem_base) +struct sm502_s *sm502_init(PCIBus * bus, int devfn, target_phys_addr_t pci_base) { struct sm502_s *s = (struct sm502_s *) qemu_mallocz(sizeof(*s)); @@ -565,7 +604,7 @@ struct sm502_s *sm502_init(PCIBus * bus, int devfn, sizeof(struct sm502_s), devfn, sm502_read_config, sm502_write_config); - s->pci_mem_base = pci_mem_base; + pci_mem_base = pci_base; sm502_gpio_init(s); diff --git a/hw/sm502.h b/hw/sm502.h index eacc9c2143..1b491eca9d 100755 --- a/hw/sm502.h +++ b/hw/sm502.h @@ -61,9 +61,6 @@ struct sm502_s PCIDevice dev; DisplayState *ds; - /*PCI configuration */ - uint8 config[256]; - /*SM502 System Configuration Register */ uint32_t system_control; /*0x00 */ uint32_t misc_control; /*0x04 */ @@ -103,12 +100,8 @@ struct sm502_s uint32_t gpio_int_setup; /*0x010010 */ uint32_t gpio_int_status; /*0x01001c */ - - - - uint32_t sm502_mm_io; /*MMIO base address */ - target_phys_addr_t pci_mem_base; + int mmio_index; }; -- 2.11.4.GIT