2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2002-08-27 23:54:46 +04:00
|
|
|
// $Id: unmapped.cc,v 1.18 2002-08-27 19:54:46 bdenney 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/
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "bochs.h"
|
merge in BRANCH-io-cleanup.
To see the commit logs for this use either cvsweb or
cvs update -r BRANCH-io-cleanup and then 'cvs log' the various files.
In general this provides a generic interface for logging.
logfunctions:: is a class that is inherited by some classes, and also
. allocated as a standalone global called 'genlog'. All logging uses
. one of the ::info(), ::error(), ::ldebug(), ::panic() methods of this
. class through 'BX_INFO(), BX_ERROR(), BX_DEBUG(), BX_PANIC()' macros
. respectively.
.
. An example usage:
. BX_INFO(("Hello, World!\n"));
iofunctions:: is a class that is allocated once by default, and assigned
as the iofunction of each logfunctions instance. It is this class that
maintains the file descriptor and other output related code, at this
point using vfprintf(). At some future point, someone may choose to
write a gui 'console' for bochs to which messages would be redirected
simply by assigning a different iofunction class to the various logfunctions
objects.
More cleanup is coming, but this works for now. If you want to see alot
of debugging output, in main.cc, change onoff[LOGLEV_DEBUG]=0 to =1.
Comments, bugs, flames, to me: todd@fries.net
2001-05-15 18:49:57 +04:00
|
|
|
#define LOG_THIS bx_unmapped.
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
|
|
|
|
bx_unmapped_c bx_unmapped;
|
merge in BRANCH-io-cleanup.
To see the commit logs for this use either cvsweb or
cvs update -r BRANCH-io-cleanup and then 'cvs log' the various files.
In general this provides a generic interface for logging.
logfunctions:: is a class that is inherited by some classes, and also
. allocated as a standalone global called 'genlog'. All logging uses
. one of the ::info(), ::error(), ::ldebug(), ::panic() methods of this
. class through 'BX_INFO(), BX_ERROR(), BX_DEBUG(), BX_PANIC()' macros
. respectively.
.
. An example usage:
. BX_INFO(("Hello, World!\n"));
iofunctions:: is a class that is allocated once by default, and assigned
as the iofunction of each logfunctions instance. It is this class that
maintains the file descriptor and other output related code, at this
point using vfprintf(). At some future point, someone may choose to
write a gui 'console' for bochs to which messages would be redirected
simply by assigning a different iofunction class to the various logfunctions
objects.
More cleanup is coming, but this works for now. If you want to see alot
of debugging output, in main.cc, change onoff[LOGLEV_DEBUG]=0 to =1.
Comments, bugs, flames, to me: todd@fries.net
2001-05-15 18:49:57 +04:00
|
|
|
#if BX_USE_UM_SMF
|
2001-04-10 05:04:59 +04:00
|
|
|
#define this (&bx_unmapped)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bx_unmapped_c::bx_unmapped_c(void)
|
|
|
|
{
|
2001-06-27 23:16:01 +04:00
|
|
|
put("UNMP");
|
2001-06-13 05:46:08 +04:00
|
|
|
settype(UNMAPLOG);
|
2001-04-10 05:04:59 +04:00
|
|
|
s.port80 = 0x00;
|
|
|
|
s.port8e = 0x00;
|
2002-07-30 12:48:03 +04:00
|
|
|
s.shutdown = 0;
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bx_unmapped_c::~bx_unmapped_c(void)
|
|
|
|
{
|
2002-04-02 01:53:23 +04:00
|
|
|
// Nothing yet
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_unmapped_c::init(bx_devices_c *d)
|
|
|
|
{
|
|
|
|
BX_UM_THIS devices = d;
|
|
|
|
|
|
|
|
for (Bit32u addr=0; addr<0x10000; addr++) {
|
|
|
|
BX_UM_THIS devices->register_io_read_handler(this, read_handler,
|
|
|
|
addr, "Unmapped");
|
|
|
|
BX_UM_THIS devices->register_io_write_handler(this, write_handler,
|
|
|
|
addr, "Unmapped");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-27 23:54:46 +04:00
|
|
|
void
|
|
|
|
bx_unmapped_c::reset(unsigned type)
|
|
|
|
{
|
|
|
|
}
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
// static IO port read callback handler
|
|
|
|
// redirects to non-static class handler to avoid virtual functions
|
|
|
|
|
|
|
|
Bit32u
|
|
|
|
bx_unmapped_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
|
|
|
{
|
|
|
|
#if !BX_USE_UM_SMF
|
|
|
|
bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
|
|
|
|
|
|
|
|
return( class_ptr->read(address, io_len) );
|
|
|
|
}
|
|
|
|
|
|
|
|
Bit32u
|
|
|
|
bx_unmapped_c::read(Bit32u address, unsigned io_len)
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
UNUSED(this_ptr);
|
|
|
|
#endif // !BX_USE_UM_SMF
|
|
|
|
UNUSED(io_len);
|
|
|
|
|
|
|
|
Bit32u retval;
|
|
|
|
|
|
|
|
// This function gets called for access to any IO ports which
|
|
|
|
// are not mapped to any device handler. Reads return 0
|
|
|
|
|
|
|
|
if (address >= 0x02e0 && address <= 0x02ef) {
|
|
|
|
retval = 0;
|
|
|
|
goto return_from_read;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (address) {
|
|
|
|
case 0x80:
|
|
|
|
retval = BX_UM_THIS s.port80;
|
|
|
|
break;
|
|
|
|
case 0x8e:
|
|
|
|
retval = BX_UM_THIS s.port8e;
|
|
|
|
break;
|
|
|
|
#if BX_PORT_E9_HACK
|
|
|
|
// Unused port on ISA - this can be used by the emulated code
|
|
|
|
// to detect it is running inside Bochs and that the debugging
|
|
|
|
// features are available (write 0xFF or something on unused
|
|
|
|
// port 0x80, then read from 0xe9, if value is 0xe9, debug
|
|
|
|
// output is available) (see write() for that) -- Andreas and Emmanuel
|
|
|
|
case 0xe9:
|
|
|
|
retval = 0xe9;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 0x03df:
|
|
|
|
retval = 0xffffffff;
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unsupported IO read from port %04x (CGA)", address));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case 0x023a:
|
|
|
|
case 0x02f8: /* UART */
|
|
|
|
case 0x02f9: /* UART */
|
|
|
|
case 0x02fb: /* UART */
|
|
|
|
case 0x02fc: /* UART */
|
|
|
|
case 0x02fd: /* UART */
|
|
|
|
case 0x02ea:
|
|
|
|
case 0x02eb:
|
|
|
|
case 0x03e8:
|
|
|
|
case 0x03e9:
|
|
|
|
case 0x03ea:
|
|
|
|
case 0x03eb:
|
|
|
|
case 0x03ec:
|
|
|
|
case 0x03ed:
|
|
|
|
case 0x03f8: /* UART */
|
|
|
|
case 0x03f9: /* UART */
|
|
|
|
case 0x03fb: /* UART */
|
|
|
|
case 0x03fc: /* UART */
|
|
|
|
case 0x03fd: /* UART */
|
|
|
|
case 0x17c6:
|
|
|
|
retval = 0xffffffff;
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unsupported IO read from port %04x", address));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
retval = 0xffffffff;
|
|
|
|
}
|
|
|
|
|
|
|
|
return_from_read:
|
|
|
|
if (bx_dbg.unsupported_io)
|
|
|
|
switch (io_len) {
|
|
|
|
case 1:
|
|
|
|
retval = (Bit8u)retval;
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unmapped: 8-bit read from %04x = %02x", address, retval));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
retval = (Bit16u)retval;
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unmapped: 16-bit read from %04x = %04x", address, retval));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case 4:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unmapped: 32-bit read from %04x = %08x", address, retval));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
default:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(("unmapped: ??-bit read from %04x = %x", address, retval));
|
2001-04-10 05:04:59 +04:00
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// static IO port write callback handler
|
|
|
|
// redirects to non-static class handler to avoid virtual functions
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_unmapped_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
|
|
|
|
{
|
|
|
|
#if !BX_USE_UM_SMF
|
|
|
|
bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
|
|
|
|
|
|
|
|
class_ptr->write(address, value, io_len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
bx_unmapped_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
UNUSED(this_ptr);
|
|
|
|
#endif // !BX_USE_UM_SMF
|
|
|
|
UNUSED(io_len);
|
|
|
|
|
|
|
|
|
|
|
|
// This function gets called for access to any IO ports which
|
|
|
|
// are not mapped to any device handler. Writes to an unmapped
|
|
|
|
// IO port are ignored.
|
|
|
|
|
|
|
|
// ???
|
|
|
|
|
|
|
|
|
|
|
|
if (address >= 0x02e0 && address <= 0x02ef)
|
|
|
|
goto return_from_write;
|
|
|
|
|
|
|
|
switch (address) {
|
|
|
|
case 0x80: // diagnostic test port to display progress of POST
|
2001-05-30 22:56:02 +04:00
|
|
|
//BX_DEBUG(("Diagnostic port 80h: write = %02xh", (unsigned) value));
|
2001-04-10 05:04:59 +04:00
|
|
|
BX_UM_THIS s.port80 = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x8e: // ???
|
|
|
|
BX_UM_THIS s.port8e = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
#if BX_PORT_E9_HACK
|
|
|
|
// This port doesn't exist on normal ISA architecture. However,
|
|
|
|
// we define a convention here, to display on the console of the
|
|
|
|
// system running Bochs, anything that is written to it. The
|
|
|
|
// idea is to provide debug output very early when writing
|
|
|
|
// BIOS or OS code for example, without having to bother with
|
|
|
|
// properly setting up a serial port or anything.
|
|
|
|
//
|
|
|
|
// Idea by Andreas Beck (andreas.beck@ggi-project.org)
|
|
|
|
|
|
|
|
case 0xe9:
|
|
|
|
putchar(value);
|
|
|
|
fflush(stdout);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case 0xed: // Dummy port used as I/O delay
|
|
|
|
break;
|
|
|
|
case 0xee: // ???
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0x2f2:
|
|
|
|
case 0x2f3:
|
|
|
|
case 0x2f4:
|
|
|
|
case 0x2f5:
|
|
|
|
case 0x2f6:
|
|
|
|
case 0x2f7:
|
|
|
|
case 0x3e8:
|
|
|
|
case 0x3e9:
|
|
|
|
case 0x3eb:
|
|
|
|
case 0x3ec:
|
|
|
|
case 0x3ed:
|
2001-05-30 22:56:02 +04:00
|
|
|
// BX_DEBUG(("unsupported IO write to port %04x of %02x",
|
merge in BRANCH-io-cleanup.
To see the commit logs for this use either cvsweb or
cvs update -r BRANCH-io-cleanup and then 'cvs log' the various files.
In general this provides a generic interface for logging.
logfunctions:: is a class that is inherited by some classes, and also
. allocated as a standalone global called 'genlog'. All logging uses
. one of the ::info(), ::error(), ::ldebug(), ::panic() methods of this
. class through 'BX_INFO(), BX_ERROR(), BX_DEBUG(), BX_PANIC()' macros
. respectively.
.
. An example usage:
. BX_INFO(("Hello, World!\n"));
iofunctions:: is a class that is allocated once by default, and assigned
as the iofunction of each logfunctions instance. It is this class that
maintains the file descriptor and other output related code, at this
point using vfprintf(). At some future point, someone may choose to
write a gui 'console' for bochs to which messages would be redirected
simply by assigning a different iofunction class to the various logfunctions
objects.
More cleanup is coming, but this works for now. If you want to see alot
of debugging output, in main.cc, change onoff[LOGLEV_DEBUG]=0 to =1.
Comments, bugs, flames, to me: todd@fries.net
2001-05-15 18:49:57 +04:00
|
|
|
// address, value));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
2002-04-02 01:53:23 +04:00
|
|
|
|
2002-07-29 16:44:47 +04:00
|
|
|
case 0x8900: // Shutdown port, could be moved in a PM device
|
|
|
|
// or a host <-> guest communication device
|
|
|
|
switch (value) {
|
|
|
|
case 'S': if (BX_UM_THIS s.shutdown == 0) BX_UM_THIS s.shutdown = 1; break;
|
|
|
|
case 'h': if (BX_UM_THIS s.shutdown == 1) BX_UM_THIS s.shutdown = 2; break;
|
|
|
|
case 'u': if (BX_UM_THIS s.shutdown == 2) BX_UM_THIS s.shutdown = 3; break;
|
|
|
|
case 't': if (BX_UM_THIS s.shutdown == 3) BX_UM_THIS s.shutdown = 4; break;
|
|
|
|
case 'd': if (BX_UM_THIS s.shutdown == 4) BX_UM_THIS s.shutdown = 5; break;
|
|
|
|
case 'o': if (BX_UM_THIS s.shutdown == 5) BX_UM_THIS s.shutdown = 6; break;
|
|
|
|
case 'w': if (BX_UM_THIS s.shutdown == 6) BX_UM_THIS s.shutdown = 7; break;
|
|
|
|
case 'n': if (BX_UM_THIS s.shutdown == 7) BX_UM_THIS s.shutdown = 8; break;
|
|
|
|
default : BX_UM_THIS s.shutdown = 0; break;
|
|
|
|
}
|
|
|
|
if (BX_UM_THIS s.shutdown == 8) {
|
|
|
|
BX_INFO(("Shutdown port: shutdown requested"));
|
|
|
|
BX_CPU(0)->kill_bochs_request = 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
case 0xfedc:
|
|
|
|
bx_dbg.debugger = (value > 0);
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_DEBUG(( "DEBUGGER = %u", (unsigned) bx_dbg.debugger));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return_from_write:
|
|
|
|
if (bx_dbg.unsupported_io)
|
|
|
|
switch (io_len) {
|
|
|
|
case 1:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_INFO(("unmapped: 8-bit write to %04x = %02x", address, value));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case 2:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_INFO(("unmapped: 16-bit write to %04x = %04x", address, value));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
case 4:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_INFO(("unmapped: 32-bit write to %04x = %08x", address, value));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
default:
|
2001-05-30 22:56:02 +04:00
|
|
|
BX_INFO(("unmapped: ??-bit write to %04x = %x", address, value));
|
2001-04-10 05:04:59 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|