Commit 84631fd79cd9c1c5ed21b9a574dd6bb9309de64c

Authored by bellard
1 parent 4f3baa4b

implement i440 instead of i450 ISA memory mappings to be compatible with Bochs


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2177 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 41 additions and 54 deletions
hw/piix_pci.c
@@ -55,63 +55,50 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) @@ -55,63 +55,50 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
55 static uint32_t isa_page_descs[384 / 4]; 55 static uint32_t isa_page_descs[384 / 4];
56 static uint8_t smm_enabled; 56 static uint8_t smm_enabled;
57 57
58 -static const uint32_t mar_addresses[15] = {  
59 - 0xa0000,  
60 - 0xc0000,  
61 - 0xc4000,  
62 - 0xc8000,  
63 - 0xcc000,  
64 - 0xd0000,  
65 - 0xd4000,  
66 - 0xd8000,  
67 - 0xdc000,  
68 - 0xe0000,  
69 - 0xe4000,  
70 - 0xe8000,  
71 - 0xec000,  
72 - 0xf0000,  
73 - 0x100000,  
74 -}; 58 +static void update_pam(PCIDevice *d, uint32_t start, uint32_t end, int r)
  59 +{
  60 + uint32_t addr;
  61 +
  62 + // printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
  63 + switch(r) {
  64 + case 3:
  65 + /* RAM */
  66 + cpu_register_physical_memory(start, end - start,
  67 + start);
  68 + break;
  69 + case 1:
  70 + /* ROM (XXX: not quite correct) */
  71 + cpu_register_physical_memory(start, end - start,
  72 + start | IO_MEM_ROM);
  73 + break;
  74 + case 2:
  75 + case 0:
  76 + /* XXX: should distinguish read/write cases */
  77 + for(addr = start; addr < end; addr += 4096) {
  78 + cpu_register_physical_memory(addr, 4096,
  79 + isa_page_descs[(addr - 0xa0000) >> 12]);
  80 + }
  81 + break;
  82 + }
  83 +}
75 84
76 static void i440fx_update_memory_mappings(PCIDevice *d) 85 static void i440fx_update_memory_mappings(PCIDevice *d)
77 { 86 {
78 int i, r; 87 int i, r;
79 - uint32_t start, end, addr;  
80 - uint32_t smram, smbase, smsize;  
81 -  
82 - for(i = 0; i < 14; i++) {  
83 - r = (d->config[(i >> 1) + 0x61] >> ((i & 1) * 4)) & 3;  
84 - start = mar_addresses[i];  
85 - end = mar_addresses[i + 1];  
86 - // printf("ISA mapping %08x: %d\n", start, r);  
87 - switch(r) {  
88 - case 3:  
89 - /* RAM */  
90 - cpu_register_physical_memory(start, end - start,  
91 - start);  
92 - break;  
93 - case 2:  
94 - /* ROM (XXX: not quite correct) */  
95 - cpu_register_physical_memory(start, end - start,  
96 - start | IO_MEM_ROM);  
97 - break;  
98 - case 1:  
99 - case 0:  
100 - /* XXX: should distinguish read/write cases */  
101 - for(addr = start; addr < end; addr += 4096) {  
102 - cpu_register_physical_memory(addr, 4096,  
103 - isa_page_descs[(addr - 0xa0000) >> 12]);  
104 - }  
105 - break;  
106 - } 88 + uint32_t smram, addr;
  89 +
  90 + update_pam(d, 0xf0000, 0x100000, (d->config[0x59] >> 4) & 3);
  91 + for(i = 0; i < 12; i++) {
  92 + r = (d->config[(i >> 1) + 0x5a] >> ((i & 1) * 4)) & 3;
  93 + update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
107 } 94 }
108 - smram = le32_to_cpu(*(uint32_t *)(d->config + 0x6c));  
109 - if ((smm_enabled && (smram & 0x80000000)) || (smram & (1 << 26))) {  
110 - /* Note: we assume the SMM area is in the 0xa0000-0x100000 range */  
111 - smbase = (smram & 0xffff) << 16;  
112 - smsize = (((smram >> 20) & 0xf) + 1) << 16;  
113 - if (smbase >= 0xa0000 && (smbase + smsize) <= 0x100000) {  
114 - cpu_register_physical_memory(smbase, smsize, smbase); 95 + smram = d->config[0x72];
  96 + if ((smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
  97 + cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
  98 + } else {
  99 + for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
  100 + cpu_register_physical_memory(addr, 4096,
  101 + isa_page_descs[(addr - 0xa0000) >> 12]);
115 } 102 }
116 } 103 }
117 } 104 }
@@ -142,7 +129,7 @@ static void i440fx_write_config(PCIDevice *d, @@ -142,7 +129,7 @@ static void i440fx_write_config(PCIDevice *d,
142 { 129 {
143 /* XXX: implement SMRAM.D_LOCK */ 130 /* XXX: implement SMRAM.D_LOCK */
144 pci_default_write_config(d, address, val, len); 131 pci_default_write_config(d, address, val, len);
145 - if ((address >= 0x61 && address <= 0x67) || address == 0x6c) 132 + if ((address >= 0x59 && address <= 0x5f) || address == 0x72)
146 i440fx_update_memory_mappings(d); 133 i440fx_update_memory_mappings(d);
147 } 134 }
148 135
@@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state) @@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state)
200 d->config[0x0b] = 0x06; // class_base = PCI_bridge 187 d->config[0x0b] = 0x06; // class_base = PCI_bridge
201 d->config[0x0e] = 0x00; // header_type 188 d->config[0x0e] = 0x00; // header_type
202 189
203 - d->config[0x6c] = 0x0a; /* SMRAM */ 190 + d->config[0x72] = 0x02; /* SMRAM */
204 191
205 register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d); 192 register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
206 *pi440fx_state = d; 193 *pi440fx_state = d;