2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2005-10-28 04:12:27 +04:00
|
|
|
// $Id: memory.h,v 1.26 2005-10-28 00:12:27 kevinlawton Exp $
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2001-04-10 06:20:02 +04:00
|
|
|
// Copyright (C) 2001 MandrakeSoft S.A.
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// MandrakeSoft S.A.
|
|
|
|
// 43, rue d'Aboukir
|
|
|
|
// 75002 Paris - France
|
|
|
|
// http://www.linux-mandrake.com/
|
|
|
|
// http://www.mandrakesoft.com/
|
|
|
|
//
|
2004-01-15 05:08:37 +03:00
|
|
|
// I/O memory handlers API Copyright (C) 2003 by Frank Cornelis
|
|
|
|
//
|
2001-04-10 05:04:59 +04:00
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
2004-10-30 01:15:48 +04:00
|
|
|
#ifndef BX_MEM_H
|
|
|
|
# define BX_MEM_H 1
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2001-05-23 12:02:15 +04:00
|
|
|
#define BX_USE_MEM_SMF 0
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#if BX_USE_MEM_SMF
|
2001-05-23 12:02:15 +04:00
|
|
|
// if static member functions on, then there is only one memory
|
2001-04-10 05:04:59 +04:00
|
|
|
# define BX_MEM_SMF static
|
2001-06-05 21:35:08 +04:00
|
|
|
# define BX_MEM_THIS BX_MEM(0)->
|
2001-04-10 05:04:59 +04:00
|
|
|
#else
|
|
|
|
# define BX_MEM_SMF
|
|
|
|
# define BX_MEM_THIS this->
|
|
|
|
#endif
|
|
|
|
|
2002-09-04 06:11:33 +04:00
|
|
|
// alignment of memory vector, must be a power of 2
|
|
|
|
#define BX_MEM_VECTOR_ALIGN 4096
|
2005-10-12 21:11:44 +04:00
|
|
|
#define BIOSROMSZ (1 << 19) // 512KB BIOS ROM @0xfff80000, must be a power of 2
|
|
|
|
#define EXROMSIZE 0x20000 // ROMs 0xc0000-0xdffff (area 0xe0000-0xfffff=bios mapped)
|
|
|
|
#define BIOS_MASK (BIOSROMSZ-1)
|
|
|
|
#define EXROM_MASK (EXROMSIZE-1)
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2004-06-06 21:01:19 +04:00
|
|
|
typedef bx_bool (*memory_handler_t)(unsigned long addr, unsigned long len, void *data, void *param);
|
2004-01-15 05:08:37 +03:00
|
|
|
|
|
|
|
struct memory_handler_struct {
|
|
|
|
struct memory_handler_struct *next;
|
|
|
|
unsigned long begin;
|
|
|
|
unsigned long end;
|
|
|
|
memory_handler_t read_handler;
|
|
|
|
memory_handler_t write_handler;
|
|
|
|
void *read_param;
|
|
|
|
void *write_param;
|
|
|
|
};
|
|
|
|
|
2002-10-25 01:07:56 +04:00
|
|
|
class BOCHSAPI BX_MEM_C : public logfunctions {
|
2004-01-15 05:08:37 +03:00
|
|
|
private:
|
|
|
|
struct memory_handler_struct **memory_handlers;
|
2004-09-01 22:12:23 +04:00
|
|
|
bx_bool rom_present[65];
|
2004-01-15 05:08:37 +03:00
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
public:
|
2002-09-04 06:11:33 +04:00
|
|
|
Bit8u *actual_vector;
|
2004-11-11 23:55:29 +03:00
|
|
|
Bit8u *vector; // aligned correctly
|
2001-04-10 05:04:59 +04:00
|
|
|
size_t len;
|
2004-11-11 23:55:29 +03:00
|
|
|
size_t megabytes; // (len in Megabytes)
|
2005-10-12 21:11:44 +04:00
|
|
|
Bit8u *rom; // 512k BIOS rom space + 128k expansion rom space
|
2004-11-16 21:50:21 +03:00
|
|
|
Bit8u *bogus; // 4k for unexisting memory
|
2001-04-10 05:04:59 +04:00
|
|
|
#if BX_DEBUGGER
|
|
|
|
unsigned char dbg_dirty_pages[(BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096];
|
2001-05-23 12:02:15 +04:00
|
|
|
Bit32u dbg_count_dirty_pages () {
|
|
|
|
return (BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096;
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
BX_MEM_C(void);
|
|
|
|
~BX_MEM_C(void);
|
2003-03-03 02:59:12 +03:00
|
|
|
BX_MEM_SMF void alloc_vector_aligned (size_t bytes, size_t alignment) BX_CPP_AttrRegparmN(2);
|
2001-04-10 05:04:59 +04:00
|
|
|
BX_MEM_SMF void init_memory(int memsize);
|
Now, when you compile with --enable-guest2host-tlb, non-paged
mode uses the notion of the guest-to-host TLB. This has the
benefit of allowing more uniform and streamlined acceleration
code in access.cc which does not have to check if CR0.PG
is set, eliminating a few instructions per guest access.
Shaved just a little off execution time, as expected.
Also, access_linear now breaks accesses which span two pages,
into two calls the the physical memory routines, when paging
is off, just like it always has for paging on. Besides
being more uniform, this allows the physical memory access
routines to known the complete data item is contained
within a single physical page, and stop reapplying the
A20ADDR() macro to pointers as it increments them.
Perhaps things can be optimized a little more now there too...
I renamed the routines to {read,write}PhysicalPage() as
a reminder that these routines now operate on data
solely within one page.
I also added a little code so that the paging module is
notified when the A20 line is tweaked, so it can dump
whatever mappings it wants to.
2002-09-05 06:31:24 +04:00
|
|
|
BX_MEM_SMF void readPhysicalPage(BX_CPU_C *cpu, Bit32u addr,
|
2003-03-03 02:59:12 +03:00
|
|
|
unsigned len, void *data) BX_CPP_AttrRegparmN(3);
|
Now, when you compile with --enable-guest2host-tlb, non-paged
mode uses the notion of the guest-to-host TLB. This has the
benefit of allowing more uniform and streamlined acceleration
code in access.cc which does not have to check if CR0.PG
is set, eliminating a few instructions per guest access.
Shaved just a little off execution time, as expected.
Also, access_linear now breaks accesses which span two pages,
into two calls the the physical memory routines, when paging
is off, just like it always has for paging on. Besides
being more uniform, this allows the physical memory access
routines to known the complete data item is contained
within a single physical page, and stop reapplying the
A20ADDR() macro to pointers as it increments them.
Perhaps things can be optimized a little more now there too...
I renamed the routines to {read,write}PhysicalPage() as
a reminder that these routines now operate on data
solely within one page.
I also added a little code so that the paging module is
notified when the A20 line is tweaked, so it can dump
whatever mappings it wants to.
2002-09-05 06:31:24 +04:00
|
|
|
BX_MEM_SMF void writePhysicalPage(BX_CPU_C *cpu, Bit32u addr,
|
2003-03-03 02:59:12 +03:00
|
|
|
unsigned len, void *data) BX_CPP_AttrRegparmN(3);
|
2003-04-02 21:03:34 +04:00
|
|
|
BX_MEM_SMF void load_ROM(const char *path, Bit32u romaddress, Bit8u type);
|
2005-10-28 04:12:27 +04:00
|
|
|
BX_MEM_SMF void load_RAM(const char *path, Bit32u romaddress, Bit8u type);
|
2001-04-10 05:04:59 +04:00
|
|
|
BX_MEM_SMF Bit32u get_memory_in_k(void);
|
2002-10-25 15:44:41 +04:00
|
|
|
BX_MEM_SMF bx_bool dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf);
|
|
|
|
BX_MEM_SMF bx_bool dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf);
|
|
|
|
BX_MEM_SMF bx_bool dbg_crc32(
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned long (*f)(unsigned char *buf, int len),
|
|
|
|
Bit32u addr1, Bit32u addr2, Bit32u *crc);
|
2004-10-30 01:15:48 +04:00
|
|
|
BX_MEM_SMF Bit8u* getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op) BX_CPP_AttrRegparmN(3);
|
2004-01-15 05:08:37 +03:00
|
|
|
BX_MEM_SMF bx_bool registerMemoryHandlers(memory_handler_t read_handler, void *read_param,
|
|
|
|
memory_handler_t write_handler, void *write_param,
|
|
|
|
unsigned long begin_addr, unsigned long end_addr);
|
|
|
|
BX_MEM_SMF bx_bool unregisterMemoryHandlers(memory_handler_t read_handler, memory_handler_t write_handler,
|
|
|
|
unsigned long begin_addr, unsigned long end_addr);
|
2001-04-10 05:04:59 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#if BX_PROVIDE_CPU_MEMORY==1
|
2001-06-05 21:35:08 +04:00
|
|
|
|
|
|
|
#if BX_SMP_PROCESSORS==1
|
2002-10-25 01:07:56 +04:00
|
|
|
BOCHSAPI extern BX_MEM_C bx_mem;
|
2001-06-05 21:35:08 +04:00
|
|
|
#else
|
2002-10-25 01:07:56 +04:00
|
|
|
BOCHSAPI extern BX_MEM_C *bx_mem_array[BX_ADDRESS_SPACES];
|
2001-06-05 21:35:08 +04:00
|
|
|
#endif /* BX_SMP_PROCESSORS */
|
|
|
|
|
|
|
|
#endif /* BX_PROVIDE_CPU_MEMORY==1 */
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#if BX_DEBUGGER
|
2001-05-23 12:02:15 +04:00
|
|
|
# define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1;
|
2001-04-10 05:04:59 +04:00
|
|
|
#else
|
|
|
|
# define BX_DBG_DIRTY_PAGE(page)
|
|
|
|
#endif
|
2004-10-30 01:15:48 +04:00
|
|
|
|
|
|
|
#endif
|