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 55 static uint32_t isa_page_descs[384 / 4];
56 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 85 static void i440fx_update_memory_mappings(PCIDevice *d)
77 86 {
78 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 129 {
143 130 /* XXX: implement SMRAM.D_LOCK */
144 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 133 i440fx_update_memory_mappings(d);
147 134 }
148 135  
... ... @@ -200,7 +187,7 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_state)
200 187 d->config[0x0b] = 0x06; // class_base = PCI_bridge
201 188 d->config[0x0e] = 0x00; // header_type
202 189  
203   - d->config[0x6c] = 0x0a; /* SMRAM */
  190 + d->config[0x72] = 0x02; /* SMRAM */
204 191  
205 192 register_savevm("I440FX", 0, 1, i440fx_save, i440fx_load, d);
206 193 *pi440fx_state = d;
... ...