2001-10-03 17:10:38 +04:00
/////////////////////////////////////////////////////////////////////////
2001-11-19 17:41:03 +03:00
// $Id: pic.cc,v 1.15 2001-11-19 14:41:03 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_pic.
2001-04-10 05:04:59 +04:00
bx_pic_c bx_pic ;
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_PIC_SMF
2001-04-10 05:04:59 +04:00
# define this (&bx_pic)
# endif
bx_pic_c : : bx_pic_c ( void )
{
2001-06-27 23:16:01 +04:00
put ( " PIC " ) ;
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
settype ( PICLOG ) ;
2001-04-10 05:04:59 +04:00
}
bx_pic_c : : ~ bx_pic_c ( void )
{
// nothing for now
}
void
bx_pic_c : : init ( bx_devices_c * d )
{
BX_PIC_THIS devices = d ;
/* 8259 PIC (Programmable Interrupt Controller) */
BX_PIC_THIS devices - > register_io_read_handler ( this , read_handler , 0x0020 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_read_handler ( this , read_handler , 0x0021 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_read_handler ( this , read_handler , 0x00A0 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_read_handler ( this , read_handler , 0x00A1 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_write_handler ( this , write_handler , 0x0020 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_write_handler ( this , write_handler , 0x0021 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_write_handler ( this , write_handler , 0x00A0 , " 8259 PIC " ) ;
BX_PIC_THIS devices - > register_io_write_handler ( this , write_handler , 0x00A1 , " 8259 PIC " ) ;
BX_PIC_THIS s . master_pic . single_PIC = 0 ;
BX_PIC_THIS s . master_pic . interrupt_offset = 0x08 ; /* IRQ0 = INT 0x08 */
/* slave PIC connected to IRQ2 of master */
BX_PIC_THIS s . master_pic . u . slave_connect_mask = 0x04 ;
BX_PIC_THIS s . master_pic . sfnm = 0 ; /* normal nested mode */
BX_PIC_THIS s . master_pic . buffered_mode = 0 ; /* unbuffered mode */
BX_PIC_THIS s . master_pic . master_slave = 0 ; /* no meaning, buffered_mode=0 */
BX_PIC_THIS s . master_pic . auto_eoi = 0 ; /* manual EOI from CPU */
BX_PIC_THIS s . master_pic . imr = 0xFF ; /* all IRQ's initially masked */
BX_PIC_THIS s . master_pic . isr = 0x00 ; /* no IRQ's in service */
BX_PIC_THIS s . master_pic . irr = 0x00 ; /* no IRQ's requested */
BX_PIC_THIS s . master_pic . read_reg_select = 0 ; /* IRR */
BX_PIC_THIS s . master_pic . irq = 0 ;
BX_PIC_THIS s . master_pic . INT = 0 ;
BX_PIC_THIS s . master_pic . init . in_init = 0 ;
BX_PIC_THIS s . master_pic . init . requires_4 = 0 ;
BX_PIC_THIS s . master_pic . init . byte_expected = 0 ;
BX_PIC_THIS s . master_pic . special_mask = 0 ;
BX_PIC_THIS s . slave_pic . single_PIC = 0 ;
BX_PIC_THIS s . slave_pic . interrupt_offset = 0x70 ; /* IRQ8 = INT 0x70 */
BX_PIC_THIS s . slave_pic . u . slave_id = 0x02 ; /* slave PIC connected to IRQ2 of master */
BX_PIC_THIS s . slave_pic . sfnm = 0 ; /* normal nested mode */
BX_PIC_THIS s . slave_pic . buffered_mode = 0 ; /* unbuffered mode */
BX_PIC_THIS s . slave_pic . master_slave = 0 ; /* no meaning, buffered_mode=0 */
BX_PIC_THIS s . slave_pic . auto_eoi = 0 ; /* manual EOI from CPU */
BX_PIC_THIS s . slave_pic . imr = 0xFF ; /* all IRQ's initially masked */
BX_PIC_THIS s . slave_pic . isr = 0x00 ; /* no IRQ's in service */
BX_PIC_THIS s . slave_pic . irr = 0x00 ; /* no IRQ's requested */
BX_PIC_THIS s . slave_pic . read_reg_select = 0 ; /* IRR */
BX_PIC_THIS s . slave_pic . irq = 0 ;
BX_PIC_THIS s . slave_pic . INT = 0 ;
BX_PIC_THIS s . slave_pic . init . in_init = 0 ;
BX_PIC_THIS s . slave_pic . init . requires_4 = 0 ;
BX_PIC_THIS s . slave_pic . init . byte_expected = 0 ;
BX_PIC_THIS s . slave_pic . special_mask = 0 ;
}
// static IO port read callback handler
// redirects to non-static class handler to avoid virtual functions
Bit32u
bx_pic_c : : read_handler ( void * this_ptr , Bit32u address , unsigned io_len )
{
# if !BX_USE_PIC_SMF
bx_pic_c * class_ptr = ( bx_pic_c * ) this_ptr ;
return ( class_ptr - > read ( address , io_len ) ) ;
}
Bit32u
bx_pic_c : : read ( Bit32u address , unsigned io_len )
{
# else
UNUSED ( this_ptr ) ;
# endif // !BX_USE_PIC_SMF
if ( io_len > 1 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " io read from port %04x, len=%u " , ( unsigned ) address ,
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
( unsigned ) io_len ) ) ;
2001-04-10 05:04:59 +04:00
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " IO read from %04x " , ( unsigned ) address ) ) ;
2001-04-10 05:04:59 +04:00
/*
8259 A PIC
*/
switch ( address ) {
case 0x20 :
if ( BX_PIC_THIS s . master_pic . read_reg_select ) { /* ISR */
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read master ISR = %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
( unsigned ) BX_PIC_THIS s . master_pic . isr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . master_pic . isr ) ;
}
else { /* IRR */
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read master IRR = %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
( unsigned ) BX_PIC_THIS s . master_pic . irr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . master_pic . irr ) ;
}
break ;
case 0x21 :
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read master IMR = %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
( unsigned ) BX_PIC_THIS s . master_pic . imr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . master_pic . imr ) ;
break ;
case 0xA0 :
if ( BX_PIC_THIS s . slave_pic . read_reg_select ) { /* ISR */
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read slave ISR = %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
( unsigned ) BX_PIC_THIS s . slave_pic . isr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . slave_pic . isr ) ;
}
else { /* IRR */
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read slave IRR = %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
( unsigned ) BX_PIC_THIS s . slave_pic . irr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . slave_pic . irr ) ;
}
break ;
case 0xA1 :
2001-05-30 22:56:02 +04:00
if ( bx_dbg . pic ) BX_INFO ( ( " read slave IMR = %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
( unsigned ) BX_PIC_THIS s . slave_pic . imr ) ) ;
2001-04-10 05:04:59 +04:00
return ( BX_PIC_THIS s . slave_pic . imr ) ;
break ;
}
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " io read to address %04x " , ( unsigned ) address ) ) ;
2001-04-10 05:04:59 +04:00
return ( 0 ) ; /* default if not found above */
}
// static IO port write callback handler
// redirects to non-static class handler to avoid virtual functions
void
bx_pic_c : : write_handler ( void * this_ptr , Bit32u address , Bit32u value , unsigned io_len )
{
# if !BX_USE_PIC_SMF
bx_pic_c * class_ptr = ( bx_pic_c * ) this_ptr ;
class_ptr - > write ( address , value , io_len ) ;
}
void
bx_pic_c : : write ( Bit32u address , Bit32u value , unsigned io_len )
{
# else
UNUSED ( this_ptr ) ;
# endif // !BX_USE_PIC_SMF
int irq ;
if ( io_len > 1 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " io write to port %04x, len=%u " , ( unsigned ) address ,
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
( unsigned ) io_len ) ) ;
2001-04-10 05:04:59 +04:00
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " IO write to %04x = %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
( unsigned ) address , ( unsigned ) value ) ) ;
2001-04-10 05:04:59 +04:00
/*
8259 A PIC
*/
switch ( address ) {
case 0x20 :
if ( value & 0x10 ) { /* initialization command 1 */
// (mch) Ignore...
2001-05-30 22:56:02 +04:00
// BX_INFO(("pic:master: init command 1 found %02x", (unsigned) value));
2001-04-10 05:04:59 +04:00
if ( bx_dbg . pic ) {
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " pic:master: init command 1 found " ) ) ;
BX_INFO ( ( " requires 4 = %u " ,
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
( unsigned ) ( value & 0x01 ) ) ) ;
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " cascade mode: [0=cascade,1=single] %u " ,
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
( unsigned ) ( ( value & 0x02 ) > > 1 ) ) ) ;
2001-04-10 05:04:59 +04:00
}
BX_PIC_THIS s . master_pic . init . in_init = 1 ;
BX_PIC_THIS s . master_pic . init . requires_4 = ( value & 0x01 ) ;
BX_PIC_THIS s . master_pic . init . byte_expected = 2 ; /* operation command 2 */
BX_PIC_THIS s . master_pic . imr = 0xFF ; /* all IRQ's initially masked */
BX_PIC_THIS s . master_pic . isr = 0x00 ; /* no IRQ's in service */
BX_PIC_THIS s . master_pic . irr = 0x00 ; /* no IRQ's requested */
BX_PIC_THIS s . master_pic . INT = 0 ; /* reprogramming clears previous INTR request */
if ( ( value & 0x02 ) = = 1 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " pic:master: init command: single mode " ) ) ;
2001-04-10 05:04:59 +04:00
BX_SET_INTR ( 0 ) ;
return ;
}
if ( ( value & 0x18 ) = = 0x08 ) { /* OCW3 */
Bit8u special_mask , poll , read_op ;
special_mask = ( value & 0x60 ) > > 5 ;
poll = ( value & 0x04 ) > > 2 ;
read_op = ( value & 0x03 ) ;
if ( poll )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " pic:master:OCW3: poll bit set " ) ) ;
2001-04-10 05:04:59 +04:00
if ( read_op = = 0x02 ) /* read IRR */
BX_PIC_THIS s . master_pic . read_reg_select = 0 ;
else if ( read_op = = 0x03 ) /* read ISR */
BX_PIC_THIS s . master_pic . read_reg_select = 1 ;
if ( special_mask = = 0x02 ) { /* cancel special mask */
BX_PIC_THIS s . master_pic . special_mask = 0 ;
}
else if ( special_mask = = 0x03 ) { /* set specific mask */
BX_PIC_THIS s . master_pic . special_mask = 1 ;
service_master_pic ( ) ;
}
return ;
}
/* OCW2 */
switch ( value ) {
case 0x00 : // Rotate in Auto-EOI mode
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " PIC: Rotate in Auto-EOI mode command received. " ) ) ;
2001-04-10 05:04:59 +04:00
case 0x0A : /* select read interrupt request register */
BX_PIC_THIS s . master_pic . read_reg_select = 0 ;
break ;
case 0x0B : /* select read interrupt in-service register */
BX_PIC_THIS s . master_pic . read_reg_select = 1 ;
break ;
case 0x20 : /* end of interrupt command */
/* clear highest current in service bit */
for ( irq = 0 ; irq < = 7 ; irq + + ) {
if ( BX_PIC_THIS s . master_pic . isr & ( 1 < < irq ) ) {
BX_PIC_THIS s . master_pic . isr & = ~ ( 1 < < irq ) ;
break ; /* out of for loop */
}
}
service_master_pic ( ) ;
break ;
case 0x60 : /* specific EOI 0 */
case 0x61 : /* specific EOI 1 */
case 0x62 : /* specific EOI 2 */
case 0x63 : /* specific EOI 3 */
case 0x64 : /* specific EOI 4 */
case 0x65 : /* specific EOI 5 */
case 0x66 : /* specific EOI 6 */
case 0x67 : /* specific EOI 7 */
BX_PIC_THIS s . master_pic . isr & = ~ ( 1 < < ( value - 0x60 ) ) ;
2001-06-27 01:55:25 +04:00
BX_PIC_THIS s . master_pic . irr & = ~ ( 1 < < ( value - 0x60 ) ) ;
2001-04-10 05:04:59 +04:00
service_master_pic ( ) ;
break ;
// IRQ lowest priority commands
case 0xC0 : // 0 7 6 5 4 3 2 1
case 0xC1 : // 1 0 7 6 5 4 3 2
case 0xC2 : // 2 1 0 7 6 5 4 3
case 0xC3 : // 3 2 1 0 7 6 5 4
case 0xC4 : // 4 3 2 1 0 7 6 5
case 0xC5 : // 5 4 3 2 1 0 7 6
case 0xC6 : // 6 5 4 3 2 1 0 7
case 0xC7 : // 7 6 5 4 3 2 1 0
// ignore for now
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " IRQ lowest command 0x%x " , value ) ) ;
2001-04-10 05:04:59 +04:00
break ;
default :
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " PIC: write to port 20h = %02x " , value ) ) ;
2001-04-10 05:04:59 +04:00
} /* switch (value) */
break ;
case 0x21 :
/* initialization mode operation */
if ( BX_PIC_THIS s . master_pic . init . in_init ) {
switch ( BX_PIC_THIS s . master_pic . init . byte_expected ) {
case 2 :
BX_PIC_THIS s . master_pic . interrupt_offset = value & 0xf8 ;
BX_PIC_THIS s . master_pic . init . byte_expected = 3 ;
if ( bx_dbg . pic ) {
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " pic:master: init command 2 = %02x " , ( unsigned ) value ) ) ;
BX_INFO ( ( " offset = INT %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
BX_PIC_THIS s . master_pic . interrupt_offset ) ) ;
2001-04-10 05:04:59 +04:00
}
return ;
break ;
case 3 :
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " pic:master: init command 3 = %02x " , ( unsigned ) value ) ) ;
2001-04-10 05:04:59 +04:00
if ( BX_PIC_THIS s . master_pic . init . requires_4 ) {
BX_PIC_THIS s . master_pic . init . byte_expected = 4 ;
}
else {
BX_PIC_THIS s . master_pic . init . in_init = 0 ;
}
return ;
break ;
case 4 :
if ( bx_dbg . pic ) {
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " pic:master: init command 4 = %02x " , ( unsigned ) value ) ) ;
if ( value & 0x02 ) BX_INFO ( ( " auto EOI " ) ) ;
else BX_INFO ( ( " normal EOI interrupt " ) ) ;
2001-04-10 05:04:59 +04:00
}
if ( value & 0x01 ) {
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " 80x86 mode " ) ) ;
2001-04-10 05:04:59 +04:00
} else
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " not 80x86 mode " ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . master_pic . init . in_init = 0 ;
return ;
break ;
default :
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " pic:master expecting bad init command " ) ) ;
2001-04-10 05:04:59 +04:00
}
}
/* normal operation */
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " setting master pic IMR to %02x " , value ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . master_pic . imr = value ;
service_master_pic ( ) ;
return ;
break ;
case 0xA0 :
if ( value & 0x10 ) { /* initialization command 1 */
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " slave: init command 1 found " ) ) ;
BX_DEBUG ( ( " requires 4 = %u " ,
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
( unsigned ) ( value & 0x01 ) ) ) ;
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " cascade mode: [0=cascade,1=single] %u " ,
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
( unsigned ) ( ( value & 0x02 ) > > 1 ) ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . slave_pic . init . in_init = 1 ;
BX_PIC_THIS s . slave_pic . init . requires_4 = ( value & 0x01 ) ;
BX_PIC_THIS s . slave_pic . init . byte_expected = 2 ; /* operation command 2 */
BX_PIC_THIS s . slave_pic . imr = 0xFF ; /* all IRQ's initially masked */
BX_PIC_THIS s . slave_pic . isr = 0x00 ; /* no IRQ's in service */
BX_PIC_THIS s . slave_pic . irr = 0x00 ; /* no IRQ's requested */
BX_PIC_THIS s . slave_pic . INT = 0 ; /* reprogramming clears previous INTR request */
if ( ( value & 0x02 ) = = 1 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " slave: init command: single mode " ) ) ;
2001-04-10 05:04:59 +04:00
return ;
}
if ( ( value & 0x18 ) = = 0x08 ) { /* OCW3 */
Bit8u special_mask , poll , read_op ;
special_mask = ( value & 0x60 ) > > 5 ;
poll = ( value & 0x04 ) > > 2 ;
read_op = ( value & 0x03 ) ;
if ( poll )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " slave:OCW3: poll bit set " ) ) ;
2001-04-10 05:04:59 +04:00
if ( read_op = = 0x02 ) /* read IRR */
BX_PIC_THIS s . slave_pic . read_reg_select = 0 ;
else if ( read_op = = 0x03 ) /* read ISR */
BX_PIC_THIS s . slave_pic . read_reg_select = 1 ;
if ( special_mask = = 0x02 ) { /* cancel special mask */
BX_PIC_THIS s . slave_pic . special_mask = 0 ;
}
else if ( special_mask = = 0x03 ) { /* set specific mask */
BX_PIC_THIS s . slave_pic . special_mask = 1 ;
service_slave_pic ( ) ;
2001-11-11 03:45:42 +03:00
BX_ERROR ( ( " Congratulations, you found a test case for bug [ #468340 ] pic:slave: OCW3 not implemented. The bug has been fixed, but Bryce needs a way to test it. Please report exactly how you got to this point. It is perfectly safe to continue. " ) ) ;
2001-04-10 05:04:59 +04:00
}
return ;
}
switch ( value ) {
case 0x0A : /* select read interrupt request register */
BX_PIC_THIS s . slave_pic . read_reg_select = 0 ;
break ;
case 0x0B : /* select read interrupt in-service register */
BX_PIC_THIS s . slave_pic . read_reg_select = 1 ;
break ;
case 0x20 : /* end of interrupt command */
/* clear highest current in service bit */
for ( irq = 0 ; irq < = 7 ; irq + + ) {
if ( BX_PIC_THIS s . slave_pic . isr & ( 1 < < irq ) ) {
BX_PIC_THIS s . slave_pic . isr & = ~ ( 1 < < irq ) ;
break ; /* out of for loop */
}
}
service_slave_pic ( ) ;
break ;
case 0x60 : /* specific EOI 0 */
case 0x61 : /* specific EOI 1 */
case 0x62 : /* specific EOI 2 */
case 0x63 : /* specific EOI 3 */
case 0x64 : /* specific EOI 4 */
case 0x65 : /* specific EOI 5 */
case 0x66 : /* specific EOI 6 */
case 0x67 : /* specific EOI 7 */
BX_PIC_THIS s . slave_pic . isr & = ~ ( 1 < < ( value - 0x60 ) ) ;
2001-06-27 01:55:25 +04:00
BX_PIC_THIS s . slave_pic . irr & = ~ ( 1 < < ( value - 0x60 ) ) ;
2001-04-10 05:04:59 +04:00
service_slave_pic ( ) ;
break ;
2001-11-19 17:41:03 +03:00
// IRQ lowest priority commands
case 0xC0 : // 0 7 6 5 4 3 2 1
case 0xC1 : // 1 0 7 6 5 4 3 2
case 0xC2 : // 2 1 0 7 6 5 4 3
case 0xC3 : // 3 2 1 0 7 6 5 4
case 0xC4 : // 4 3 2 1 0 7 6 5
case 0xC5 : // 5 4 3 2 1 0 7 6
case 0xC6 : // 6 5 4 3 2 1 0 7
case 0xC7 : // 7 6 5 4 3 2 1 0
// ignore for now
BX_INFO ( ( " IRQ lowest command 0x%x " , value ) ) ;
break ;
2001-04-10 05:04:59 +04:00
default :
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " PIC: write to port A0h = %02x " , value ) ) ;
2001-04-10 05:04:59 +04:00
} /* switch (value) */
break ;
case 0xA1 :
/* initialization mode operation */
if ( BX_PIC_THIS s . slave_pic . init . in_init ) {
switch ( BX_PIC_THIS s . slave_pic . init . byte_expected ) {
case 2 :
BX_PIC_THIS s . slave_pic . interrupt_offset = value & 0xf8 ;
BX_PIC_THIS s . slave_pic . init . byte_expected = 3 ;
if ( bx_dbg . pic ) {
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " slave: init command 2 = %02x " , ( unsigned ) value ) ) ;
BX_DEBUG ( ( " offset = INT %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
BX_PIC_THIS s . slave_pic . interrupt_offset ) ) ;
2001-04-10 05:04:59 +04:00
}
return ;
break ;
case 3 :
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " slave: init command 3 = %02x " , ( unsigned ) value ) ) ;
2001-04-10 05:04:59 +04:00
if ( BX_PIC_THIS s . slave_pic . init . requires_4 ) {
BX_PIC_THIS s . slave_pic . init . byte_expected = 4 ;
2001-05-24 18:08:54 +04:00
} else {
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . slave_pic . init . in_init = 0 ;
}
return ;
break ;
case 4 :
if ( bx_dbg . pic ) {
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " slave: init command 4 = %02x " , ( unsigned ) value ) ) ;
if ( value & 0x02 ) BX_INFO ( ( " auto EOI " ) ) ;
else BX_DEBUG ( ( " normal EOI interrupt " ) ) ;
2001-04-10 05:04:59 +04:00
}
if ( value & 0x01 ) {
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " 80x86 mode " ) ) ;
} else BX_PANIC ( ( " not 80x86 mode " ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . slave_pic . init . in_init = 0 ;
return ;
break ;
default :
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " slave: expecting bad init command " ) ) ;
2001-04-10 05:04:59 +04:00
}
}
/* normal operation */
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " setting slave pic IMR to %02x " , value ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . slave_pic . imr = value ;
service_slave_pic ( ) ;
return ;
break ;
} /* switch (address) */
return ;
}
void
bx_pic_c : : trigger_irq ( unsigned irq_no )
{
2001-06-12 17:07:43 +04:00
# if BX_SUPPORT_APIC
2001-05-23 11:48:11 +04:00
// forward this function call to the ioapic too
BX_PIC_THIS devices - > ioapic - > trigger_irq ( irq_no , - 1 ) ;
# endif
2001-04-10 05:04:59 +04:00
int irq_no_bitmask ;
if ( irq_no > 15 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " trigger_irq: irq out of range " ) ) ;
2001-04-10 05:04:59 +04:00
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " trigger_irq(%d decimal) " , ( unsigned ) irq_no ) ) ;
2001-04-10 05:04:59 +04:00
if ( irq_no < = 7 ) {
irq_no_bitmask = 1 < < irq_no ;
BX_PIC_THIS s . master_pic . irr | = irq_no_bitmask ;
service_master_pic ( ) ;
}
else { // irq = 8..15
irq_no_bitmask = 1 < < ( irq_no - 8 ) ;
BX_PIC_THIS s . slave_pic . irr | = irq_no_bitmask ;
service_slave_pic ( ) ;
}
}
void
bx_pic_c : : untrigger_irq ( unsigned irq_no )
{
2001-06-12 17:07:43 +04:00
# if BX_SUPPORT_APIC
2001-05-23 11:48:11 +04:00
// forward this function call to the ioapic too
BX_PIC_THIS devices - > ioapic - > untrigger_irq ( irq_no , - 1 ) ;
# endif
2001-04-10 05:04:59 +04:00
int irq_no_bitmask ;
if ( irq_no > 15 )
2001-05-30 22:56:02 +04:00
BX_PANIC ( ( " untrigger_irq: irq out of range " ) ) ;
2001-04-10 05:04:59 +04:00
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " untrigger_irq(%d decimal) " , ( unsigned ) irq_no ) ) ;
2001-04-10 05:04:59 +04:00
if ( irq_no < = 7 ) {
irq_no_bitmask = 1 < < irq_no ;
if ( BX_PIC_THIS s . master_pic . imr & irq_no_bitmask ) {
BX_PIC_THIS s . master_pic . irr & = ~ irq_no_bitmask ;
}
}
else { // irq = 8..15
irq_no_bitmask = 1 < < ( irq_no - 8 ) ;
if ( BX_PIC_THIS s . slave_pic . imr & irq_no_bitmask ) {
BX_PIC_THIS s . slave_pic . irr & = ~ irq_no_bitmask ;
}
}
}
/* */
void
bx_pic_c : : service_master_pic ( void )
{
Bit8u unmasked_requests ;
int irq ;
Bit8u isr , max_irq ;
if ( BX_PIC_THIS s . master_pic . INT ) { /* last interrupt still not acknowleged */
return ;
}
if ( BX_PIC_THIS s . master_pic . special_mask ) {
/* all priorities may be enabled. check all IRR bits except ones
* which have corresponding ISR bits set
*/
max_irq = 7 ;
}
else { /* normal mode */
/* Find the highest priority IRQ that is enabled due to current ISR */
isr = BX_PIC_THIS s . master_pic . isr ;
if ( isr ) {
max_irq = 0 ;
while ( ( isr & 0x01 ) = = 0 ) {
isr > > = 1 ;
max_irq + + ;
}
if ( max_irq = = 0 ) return ; /* IRQ0 in-service, no other priorities allowed */
2001-05-30 22:56:02 +04:00
if ( max_irq > 7 ) BX_PANIC ( ( " error in service_master_pic() " ) ) ;
2001-04-10 05:04:59 +04:00
}
else
max_irq = 7 ; /* 0..7 bits in ISR are cleared */
}
/* now, see if there are any higher priority requests */
if ( ( unmasked_requests = ( BX_PIC_THIS s . master_pic . irr & ~ BX_PIC_THIS s . master_pic . imr ) ) ) {
for ( irq = 0 ; irq < = max_irq ; irq + + ) {
/* for special mode, since we're looking at all IRQ's, skip if
* current IRQ is already in - service
*/
if ( BX_PIC_THIS s . master_pic . special_mask & & ( ( BX_PIC_THIS s . master_pic . isr > > irq ) & 0x01 ) )
continue ;
if ( unmasked_requests & ( 1 < < irq ) ) {
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " signalling IRQ(%u) " , ( unsigned ) irq ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . master_pic . irr & = ~ ( 1 < < irq ) ;
/*??? do for slave too: BX_PIC_THIS s.master_pic.isr |= (1 << irq);*/
BX_PIC_THIS s . master_pic . INT = 1 ;
BX_SET_INTR ( 1 ) ;
BX_PIC_THIS s . master_pic . irq = irq ;
return ;
} /* if (unmasked_requests & ... */
} /* for (irq=7 ... */
} /* if (unmasked_requests = ... */
}
void
bx_pic_c : : service_slave_pic ( void )
{
Bit8u unmasked_requests ;
int irq ;
Bit8u isr , lowest_priority_irq ;
if ( BX_PIC_THIS s . slave_pic . INT ) { /* last interrupt still not acknowleged */
return ;
}
2001-11-11 03:45:42 +03:00
if ( BX_PIC_THIS s . master_pic . special_mask ) {
/* all priorities may be enabled. check all IRR bits except ones
* which have corresponding ISR bits set
*/
lowest_priority_irq = 8 ;
}
else {
2001-04-10 05:04:59 +04:00
/* Find the highest priority IRQ that is enabled due to current ISR */
isr = BX_PIC_THIS s . slave_pic . isr ;
if ( isr ) {
lowest_priority_irq = 0 ;
while ( ! ( isr & 0x01 ) ) {
isr > > = 1 ;
lowest_priority_irq + + ;
}
2001-05-30 22:56:02 +04:00
if ( lowest_priority_irq > 7 ) BX_PANIC ( ( " error in service_slave_pic() " ) ) ;
2001-04-10 05:04:59 +04:00
}
else
lowest_priority_irq = 8 ;
2001-11-11 03:45:42 +03:00
}
2001-04-10 05:04:59 +04:00
/* now, see if there are any higher priority requests */
if ( ( unmasked_requests = ( BX_PIC_THIS s . slave_pic . irr & ~ BX_PIC_THIS s . slave_pic . imr ) ) ) {
for ( irq = 0 ; irq < lowest_priority_irq ; irq + + ) {
2001-11-11 03:45:42 +03:00
/* for special mode, since we're looking at all IRQ's, skip if
* current IRQ is already in - service
*/
if ( BX_PIC_THIS s . slave_pic . special_mask & & ( ( BX_PIC_THIS s . slave_pic . isr > > irq ) & 0x01 ) )
continue ;
2001-04-10 05:04:59 +04:00
if ( unmasked_requests & ( 1 < < irq ) ) {
if ( bx_dbg . pic )
2001-05-30 22:56:02 +04:00
BX_DEBUG ( ( " slave: signalling IRQ(%u) " ,
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
( unsigned ) 8 + irq ) ) ;
2001-04-10 05:04:59 +04:00
BX_PIC_THIS s . slave_pic . irr & = ~ ( 1 < < irq ) ;
BX_PIC_THIS s . slave_pic . INT = 1 ;
BX_PIC_THIS s . master_pic . irr | = 0x04 ; /* request IRQ 2 on master pic */
BX_PIC_THIS s . slave_pic . irq = irq ;
service_master_pic ( ) ;
return ;
} /* if (unmasked_requests & ... */
} /* for (irq=7 ... */
} /* if (unmasked_requests = ... */
}
/* CPU handshakes with PIC after acknowledging interrupt */
Bit8u
bx_pic_c : : IAC ( void )
{
Bit8u vector ;
Bit8u irq ;
BX_SET_INTR ( 0 ) ;
BX_PIC_THIS s . master_pic . INT = 0 ;
BX_PIC_THIS s . master_pic . isr | = ( 1 < < BX_PIC_THIS s . master_pic . irq ) ;
BX_PIC_THIS s . master_pic . irr & = ~ ( 1 < < BX_PIC_THIS s . master_pic . irq ) ;
if ( BX_PIC_THIS s . master_pic . irq ! = 2 ) {
irq = BX_PIC_THIS s . master_pic . irq ;
vector = irq + BX_PIC_THIS s . master_pic . interrupt_offset ;
}
else { /* IRQ2 = slave pic IRQ8..15 */
BX_PIC_THIS s . slave_pic . INT = 0 ;
irq = BX_PIC_THIS s . slave_pic . irq ;
vector = irq + BX_PIC_THIS s . slave_pic . interrupt_offset ;
BX_PIC_THIS s . slave_pic . isr | = ( 1 < < BX_PIC_THIS s . slave_pic . irq ) ;
BX_PIC_THIS s . slave_pic . irr & = ~ ( 1 < < BX_PIC_THIS s . slave_pic . irq ) ;
service_slave_pic ( ) ;
irq + = 8 ; // for debug printing purposes
}
service_master_pic ( ) ;
BX_DBG_IAC_REPORT ( vector , irq ) ;
return ( vector ) ;
}
void
bx_pic_c : : show_pic_state ( void )
{
2001-05-30 22:56:02 +04:00
BX_INFO ( ( " s.master_pic.imr = %02x " , BX_PIC_THIS s . master_pic . imr ) ) ;
BX_INFO ( ( " s.master_pic.isr = %02x " , BX_PIC_THIS s . master_pic . isr ) ) ;
BX_INFO ( ( " s.master_pic.irr = %02x " , BX_PIC_THIS s . master_pic . irr ) ) ;
BX_INFO ( ( " s.master_pic.irq = %02x " , BX_PIC_THIS s . master_pic . irq ) ) ;
2001-04-10 05:04:59 +04:00
}