- within BX_MEM_C member functions, use reference to local data instead of

going out to BX_MEM to get it.
- outside of BX_CPU_C, use BX_CPU(n) instead of BX_CPU_THIS_PTR
- add memory-mapped I/O APIC and local APICs.
This commit is contained in:
Bryce Denney 2001-05-23 08:02:15 +00:00
parent af4ccaae3e
commit 564ca0a857
3 changed files with 93 additions and 62 deletions

View File

@ -34,7 +34,7 @@
#if BX_PROVIDE_CPU_MEMORY
void
BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
{
Bit8u *data_ptr;
Bit32u a20addr;
@ -45,9 +45,10 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
#if BX_DEBUGGER
// (mch) Check for physical write break points, TODO
// (bbd) Each breakpoint should have an associated CPU#, TODO
for (int i = 0; i < num_write_watchpoints; i++)
if (write_watchpoint[i] == a20addr) {
BX_CPU_THIS_PTR break_point = BREAK_POINT_WRITE;
BX_CPU(0)->break_point = BREAK_POINT_WRITE;
break;
}
#endif
@ -66,7 +67,7 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
data32 = (data32 << 24) | (data32 >> 24) |
((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
#endif
* ((Bit32u *) (&BX_MEM.vector[a20addr])) = data32;
* ((Bit32u *) (&vector[a20addr])) = data32;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
@ -75,12 +76,12 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
Bit32u data32;
data32 = * (Bit32u *) data;
* ((Bit8u *) (&BX_MEM.vector[a20addr])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[a20addr])) = data32; data32 >>= 8;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
* ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+1)])) = data32; data32 >>= 8;
* ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+2)])) = data32; data32 >>= 8;
* ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+3)])) = data32;
* ((Bit8u *) (&vector[A20ADDR(addr+1)])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[A20ADDR(addr+2)])) = data32; data32 >>= 8;
* ((Bit8u *) (&vector[A20ADDR(addr+3)])) = data32;
// worst case, last byte is in different page; possible extra dirty page
BX_DBG_DIRTY_PAGE(A20ADDR(addr+3) >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
@ -96,7 +97,7 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
#ifdef BX_BIG_ENDIAN
data16 = (data16 >> 8) | (data16 << 8);
#endif
* ((Bit16u *) (&BX_MEM.vector[a20addr])) = data16;
* ((Bit16u *) (&vector[a20addr])) = data16;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
@ -105,10 +106,10 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
Bit16u data16;
data16 = * (Bit16u *) data;
* ((Bit8u *) (&BX_MEM.vector[a20addr])) = (Bit8u) data16;
* ((Bit8u *) (&vector[a20addr])) = (Bit8u) data16;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
* ((Bit8u *) (&BX_MEM.vector[A20ADDR(a20addr+1)])) = (data16 >> 8);
* ((Bit8u *) (&vector[A20ADDR(a20addr+1)])) = (data16 >> 8);
BX_DBG_DIRTY_PAGE(A20ADDR(a20addr+1) >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
@ -118,7 +119,7 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
Bit8u data8;
data8 = * (Bit8u *) data;
* ((Bit8u *) (&BX_MEM.vector[a20addr])) = data8;
* ((Bit8u *) (&vector[a20addr])) = data8;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
return;
@ -135,7 +136,7 @@ BX_MEM_C::write_physical(Bit32u addr, unsigned len, void *data)
write_one:
if ( (a20addr & 0xfff80000) != 0x00080000 ) {
// addr *not* in range 00080000 .. 000FFFFF
BX_MEM.vector[a20addr] = *data_ptr;
vector[a20addr] = *data_ptr;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
inc_one:
@ -155,7 +156,7 @@ inc_one:
if (a20addr <= 0x0009ffff) {
// regular memory 80000 .. 9FFFF
BX_MEM.vector[a20addr] = *data_ptr;
vector[a20addr] = *data_ptr;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
goto inc_one;
@ -176,7 +177,7 @@ inc_one:
#if BX_PCI_SUPPORT == 0
#if BX_SHADOW_RAM
// Write it since its in shadow RAM
BX_MEM.vector[a20addr] = *data_ptr;
vector[a20addr] = *data_ptr;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
#else
@ -186,10 +187,10 @@ inc_one:
// Write Based on 440fx Programming
if (bx_options.i440FXSupport &&
((a20addr >= 0xC0000) && (a20addr <= 0xFFFFF))) {
switch (bx_pci.wr_memType(a20addr & 0xFC000)) {
switch (bx_devices.pci->wr_memType(a20addr & 0xFC000)) {
case 0x0: // Writes to ShadowRAM
// BX_INFO(("Writing to ShadowRAM %08x, len %u ! \n", (unsigned) a20addr, (unsigned) len));
BX_MEM.vector[a20addr] = *data_ptr;
vector[a20addr] = *data_ptr;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
goto inc_one;
@ -217,9 +218,21 @@ inc_one:
data_ptr = (Bit8u *) data + (len - 1);
#endif
#if BX_APIC_SUPPORT
bx_generic_apic_c *local_apic = &cpu->local_apic;
bx_generic_apic_c *ioapic = bx_devices.ioapic;
if (local_apic->is_selected (a20addr, len)) {
local_apic->write (a20addr, (Bit32u *)data, len);
return;
} else if (ioapic->is_selected (a20addr, len)) {
ioapic->write (a20addr, (Bit32u *)data, len);
return;
}
else
#endif
for (i = 0; i < len; i++) {
if (a20addr < BX_MEM_THIS len) {
BX_MEM.vector[a20addr] = *data_ptr;
vector[a20addr] = *data_ptr;
BX_DBG_DIRTY_PAGE(a20addr >> 12);
BX_DYN_DIRTY_PAGE(a20addr >> 12);
}
@ -238,7 +251,7 @@ inc_one:
void
BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
{
Bit8u *data_ptr;
Bit32u a20addr;
@ -249,9 +262,10 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
#if BX_DEBUGGER
// (mch) Check for physical read break points, TODO
// (bbd) Each breakpoint should have an associated CPU#, TODO
for (int i = 0; i < num_read_watchpoints; i++)
if (read_watchpoint[i] == a20addr) {
BX_CPU_THIS_PTR break_point = BREAK_POINT_READ;
BX_CPU(0)->break_point = BREAK_POINT_READ;
break;
}
#endif
@ -264,7 +278,7 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
// read 4-byte data from aligned memory location
Bit32u data32;
data32 = * ((Bit32u *) (&BX_MEM.vector[a20addr]));
data32 = * ((Bit32u *) (&vector[a20addr]));
#ifdef BX_BIG_ENDIAN
data32 = (data32 << 24) | (data32 >> 24) |
((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
@ -275,10 +289,10 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
else {
Bit32u data32;
data32 = * ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+3)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+2)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+1)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&BX_MEM.vector[a20addr]));
data32 = * ((Bit8u *) (&vector[A20ADDR(addr+3)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+2)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data32 <<= 8;
data32 |= * ((Bit8u *) (&vector[a20addr]));
* (Bit32u *) data = data32;
return;
@ -289,7 +303,7 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
// read 2-byte data from aligned memory location
Bit16u data16;
data16 = * ((Bit16u *) (&BX_MEM.vector[a20addr]));
data16 = * ((Bit16u *) (&vector[a20addr]));
#ifdef BX_BIG_ENDIAN
data16 = (data16 >> 8) | (data16 << 8);
#endif
@ -300,8 +314,8 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
else {
Bit16u data16;
data16 = * ((Bit8u *) (&BX_MEM.vector[A20ADDR(addr+1)])); data16 <<= 8;
data16 |= * ((Bit8u *) (&BX_MEM.vector[a20addr]));
data16 = * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data16 <<= 8;
data16 |= * ((Bit8u *) (&vector[a20addr]));
* (Bit16u *) data = data16;
return;
@ -310,7 +324,7 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
if (len == 1) {
Bit8u data8;
data8 = * ((Bit8u *) (&BX_MEM.vector[a20addr]));
data8 = * ((Bit8u *) (&vector[a20addr]));
* (Bit8u *) data = data8;
return;
}
@ -329,7 +343,7 @@ BX_MEM_C::read_physical(Bit32u addr, unsigned len, void *data)
read_one:
if ( (a20addr & 0xfff80000) != 0x00080000 ) {
// addr *not* in range 00080000 .. 000FFFFF
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
inc_one:
if (len == 1) return;
len--;
@ -347,7 +361,7 @@ inc_one:
#if BX_PCI_SUPPORT == 0
if ((a20addr <= 0x0009ffff) || (a20addr >= 0x000c0000) ) {
// regular memory 80000 .. 9FFFF, C0000 .. F0000
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
goto inc_one;
}
// VGA memory A0000 .. BFFFF
@ -356,7 +370,7 @@ inc_one:
goto inc_one;
#else // #if BX_PCI_SUPPORT == 0
if (a20addr <= 0x0009ffff) {
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
goto inc_one;
}
if (a20addr <= 0x000BFFFF) {
@ -368,13 +382,13 @@ inc_one:
// a20addr in C0000 .. FFFFF
if (!bx_options.i440FXSupport) {
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
goto inc_one;
}
else {
switch (bx_pci.rd_memType(a20addr & 0xFC000)) {
switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
case 0x0: // Read from ShadowRAM
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
BX_INFO(("Reading from ShadowRAM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
goto inc_one;
@ -399,21 +413,32 @@ inc_one:
data_ptr = (Bit8u *) data + (len - 1);
#endif
#if BX_APIC_SUPPORT
bx_generic_apic_c *local_apic = &cpu->local_apic;
bx_generic_apic_c *ioapic = bx_devices.ioapic;
if (local_apic->is_selected (addr, len)) {
local_apic->read (addr, data, len);
return;
} else if (ioapic->is_selected (addr, len)) {
ioapic->read (addr, data, len);
return;
}
#endif
for (i = 0; i < len; i++) {
#if BX_PCI_SUPPORT == 0
if (a20addr < BX_MEM_THIS len)
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
else
*data_ptr = 0xff;
#else // BX_PCI_SUPPORT == 0
if (a20addr < BX_MEM_THIS len) {
if ((a20addr >= 0x000C0000) && (a20addr <= 0x000FFFFF)) {
if (!bx_options.i440FXSupport)
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
else {
switch (bx_pci.rd_memType(a20addr & 0xFC000)) {
switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
case 0x0: // Read from ROM
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
//BX_INFO(("Reading from ROM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
break;
@ -427,11 +452,11 @@ inc_one:
}
}
else {
*data_ptr = BX_MEM.vector[a20addr];
*data_ptr = vector[a20addr];
BX_INFO(("Reading from Norm %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
}
}
else
else
*data_ptr = 0xff;
#endif // BX_PCI_SUPPORT == 0
addr++;

View File

@ -22,11 +22,12 @@
#define BX_USE_MEM_SMF 1
#define BX_USE_MEM_SMF 0
#if BX_USE_MEM_SMF
// if static member functions on, then there is only one memory
# define BX_MEM_SMF static
# define BX_MEM_THIS BX_MEM.
# define BX_MEM_THIS bx_mem_array[0]->
#else
# define BX_MEM_SMF
# define BX_MEM_THIS this->
@ -42,14 +43,17 @@ public:
size_t megabytes; // (len in Megabytes)
#if BX_DEBUGGER
unsigned char dbg_dirty_pages[(BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096];
Bit32u dbg_count_dirty_pages () {
return (BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096;
}
#endif
BX_MEM_C(void);
BX_MEM_C(size_t memsize);
~BX_MEM_C(void);
BX_MEM_SMF void init_memory(int memsize);
BX_MEM_SMF void read_physical(Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void write_physical(Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
BX_MEM_SMF void load_ROM(const char *path, Bit32u romaddress);
BX_MEM_SMF Bit32u get_memory_in_k(void);
BX_MEM_SMF Boolean dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf);
@ -60,11 +64,11 @@ public:
};
#if BX_PROVIDE_CPU_MEMORY==1
extern BX_MEM_C BX_MEM;
extern BX_MEM_C *bx_mem_array[BX_ADDRESS_SPACES];
#endif
#if BX_DEBUGGER
# define BX_DBG_DIRTY_PAGE(page) BX_MEM.dbg_dirty_pages[page] = 1;
# define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1;
#else
# define BX_DBG_DIRTY_PAGE(page)
#endif

View File

@ -27,7 +27,7 @@
#include "bochs.h"
#define LOG_THIS BX_MEM.
#define LOG_THIS BX_MEM(0)->
@ -51,9 +51,9 @@ BX_MEM_C::BX_MEM_C(void)
setprefix(mem);
settype(MEMLOG);
BX_MEM.vector = NULL;
BX_MEM.len = 0;
BX_MEM.megabytes = 0;
vector = NULL;
len = 0;
megabytes = 0;
}
#endif // #if BX_PROVIDE_CPU_MEMORY
@ -107,9 +107,9 @@ BX_MEM_C::init_memory(int memsize)
#if BX_DEBUGGER
// initialize dirty pages table
memset(BX_MEM.dbg_dirty_pages, 0, sizeof(BX_MEM.dbg_dirty_pages));
memset(dbg_dirty_pages, 0, sizeof(dbg_dirty_pages));
if (BX_MEM.megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
BX_INFO(("Error: memory larger than dirty page table can handle\n"));
BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS\n"));
}
@ -154,7 +154,7 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress)
while (size > 0) {
#if BX_PCI_SUPPORT
if (bx_options.i440FXSupport)
ret = read(fd, (bx_ptr_t) &bx_pci.s.i440fx.shadow[romaddress - 0xC0000 + offset],
ret = read(fd, (bx_ptr_t) &bx_devices.pci->s.i440fx.shadow[romaddress - 0xC0000 + offset],
size);
else
ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
@ -196,7 +196,9 @@ BX_MEM_C::load_ROM(const char *path, Bit32u romaddress)
Boolean
BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
{
if ( (addr + len) > BX_MEM.len ) {
if ( (addr + len) > this->len ) {
BX_INFO(("dbg_fetch_mem out of range. %p > %p\n",
addr+len, this->len));
return(0); // error, beyond limits of memory
}
for (; len>0; len--) {
@ -207,13 +209,13 @@ BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
else {
#endif
#if BX_PCI_SUPPORT == 0
*buf = BX_MEM.vector[addr];
*buf = vector[addr];
#else
if ( bx_options.i440FXSupport &&
((addr >= 0x000C0000) && (addr <= 0x000FFFFF)) ) {
switch (bx_pci.rd_memType (addr)) {
switch (bx_devices.pci->rd_memType (addr)) {
case 0x0: // Fetch from ShadowRAM
*buf = BX_MEM.vector[addr];
*buf = vector[addr];
// BX_INFO(("Fetching from ShadowRAM %08x, len %u !\n", (unsigned)addr, (unsigned)len));
break;
@ -226,7 +228,7 @@ BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
}
}
else
*buf = BX_MEM.vector[addr];
*buf = vector[addr];
#endif // #if BX_PCI_SUPPORT == 0
}
buf++;
@ -240,7 +242,7 @@ BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
Boolean
BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
{
if ( (addr + len) > BX_MEM.len ) {
if ( (addr + len) > this->len ) {
return(0); // error, beyond limits of memory
}
for (; len>0; len--) {
@ -250,7 +252,7 @@ BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
}
else
#endif
BX_MEM.vector[addr] = *buf;
vector[addr] = *buf;
buf++;
addr++;
}
@ -268,12 +270,12 @@ BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
if (addr1 > addr2)
return(0);
if (addr2 >= BX_MEM.len) {
if (addr2 >= this->len) {
return(0); // error, specified address past last phy mem addr
}
len = 1 + addr2 - addr1;
*crc = f(BX_MEM.vector + addr1, len);
*crc = f(vector + addr1, len);
return(1);
}