diff --git a/bochs/cpu/apic.cc b/bochs/cpu/apic.cc index 0015bc0eb..b2dafa37f 100644 --- a/bochs/cpu/apic.cc +++ b/bochs/cpu/apic.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: apic.cc,v 1.11 2002-03-23 00:54:37 bdenney Exp $ +// $Id: apic.cc,v 1.12 2002-03-25 01:58:34 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // #define NEED_CPU_REG_SHORTCUTS 1 @@ -22,6 +22,13 @@ bx_generic_apic_c::~bx_generic_apic_c () { } +void +bx_generic_apic_c::set_arb_id (int new_arb_id) +{ + // politely ignore it. This gets sent to every APIC, regardless of its + // type. +} + // init is called during RESET and when an INIT message is delivered. void bx_generic_apic_c::init () { @@ -160,8 +167,7 @@ bx_generic_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bi Bit32u deliver_bitmask = get_delivery_bitmask (dest, dest_mode); // mask must include ONLY local APICs, or we will have problems. if (!deliver_bitmask) { - if (bx_dbg.apic) - BX_INFO(("deliver failed: no APICs in destination bitmask")); + BX_PANIC(("deliver failed for vector %02x: no APICs in destination bitmask", vector)); return false; } switch (delivery_mode) { @@ -185,6 +191,10 @@ bx_generic_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bi break; case 5: // INIT { + // NOTE: special behavior of local apics is handled in + // bx_local_apic_c::deliver. + + // normal INIT. initialize the local apics in the delivery mask. for (int bit=0; bitinit (); @@ -221,6 +231,33 @@ bx_generic_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bi return true; } +Boolean +bx_local_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode) +{ + // In this function, implement only the behavior that is specific to + // the local apic. For general behavior of all apics, just send it to + // the base class. + if (delivery_mode == 5) + { + int trig_mode = (icr_low >> 15) & 1; + int level = (icr_low >> 14) & 1; + if (level == 0 && trig_mode == 1) { + // special mode in local apic. See "INIT Level Deassert" in the + // Intel Soft. Devel. Guide Vol 3, page 7-34. This magic code + // causes all APICs (regardless of dest address) to set their + // arbitration ID to their APIC ID. + BX_INFO (("INIT with Level&Deassert: synchronize arbitration IDs")); + for (int bit=0; bitset_arb_id (apic_index[bit]->get_id ()); + } + return true; + } + } + // not any special case behavior, just use generic apic code. + return bx_generic_apic_c::deliver (dest, dest_mode, delivery_mode, vector, polarity, trig_mode); +} + bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu) : bx_generic_apic_c () { @@ -229,6 +266,13 @@ bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu) hwreset (); } +void +bx_local_apic_c::set_arb_id (int new_arb_id) +{ + BX_DEBUG (("set arbitration ID to %d", new_arb_id)); + arb_id = new_arb_id; +} + void bx_local_apic_c::hwreset () { @@ -334,9 +378,11 @@ void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len) break; case 0xd0: // logical destination log_dest = (*data >> 24) & 0xff; + BX_DEBUG (("set logical destiation to %02x", log_dest)); break; case 0xe0: // destination format dest_format = (*data >> 28) & 0xf; + BX_DEBUG (("set destination format to %02x", dest_format)); break; case 0xf0: // spurious interrupt vector spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0); @@ -645,12 +691,9 @@ Bit8u bx_local_apic_c::get_ppr () Bit8u bx_local_apic_c::get_apr () { - BX_ERROR (("WARNING: Local APIC Arbitration Priority not implemented, returning 0")); - // should look at TPR, vector of highest priority isr, etc. - return 0; + return arb_id; } - void bx_local_apic_c::periodic (Bit32u usec_delta) { diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index ff901c050..549f081c7 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.15 2001-10-03 19:53:48 instinc Exp $ +// $Id: cpu.h,v 1.16 2002-03-25 01:58:34 bdenney Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -548,9 +548,10 @@ public: virtual void trigger_irq (unsigned num, unsigned from); virtual void untrigger_irq (unsigned num, unsigned from); virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode); - Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); + virtual Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); virtual Boolean match_logical_addr (Bit8u address); virtual bx_apic_type_t get_type (); + virtual void set_arb_id (int newid); // only implemented on local apics }; class bx_local_apic_c : public bx_generic_apic_c { @@ -612,10 +613,12 @@ public: virtual Boolean is_local_apic () { return true; } virtual bx_apic_type_t get_type () { return APIC_TYPE_LOCAL_APIC; } virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode); + virtual Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); Bit8u get_ppr (); Bit8u get_apr (); void periodic (Bit32u usec_delta); void set_divide_configuration (Bit32u value); + virtual void set_arb_id (int newid); }; #define APIC_MAX_ID 16 diff --git a/bochs/patches/patch.smp-sync-arb-ids b/bochs/patches/patch.smp-sync-arb-ids deleted file mode 100644 index 8a6cb7294..000000000 --- a/bochs/patches/patch.smp-sync-arb-ids +++ /dev/null @@ -1,151 +0,0 @@ -? cpu/Makefile -? cpu/stSVOcJq -? cpu/apic-works.cc -Index: cpu/apic.cc -=================================================================== -RCS file: /cvsroot/bochs/bochs/cpu/apic.cc,v -retrieving revision 1.8 -diff -u -r1.8 apic.cc ---- cpu/apic.cc 3 Oct 2001 13:10:37 -0000 1.8 -+++ cpu/apic.cc 24 Mar 2002 01:14:58 -0000 -@@ -22,6 +22,13 @@ - { - } - -+void -+bx_generic_apic_c::set_arb_id (int new_arb_id) -+{ -+ // politely ignore it. This gets sent to every APIC, regardless of its -+ // type. -+} -+ - // init is called during RESET and when an INIT message is delivered. - void bx_generic_apic_c::init () - { -@@ -160,8 +167,7 @@ - Bit32u deliver_bitmask = get_delivery_bitmask (dest, dest_mode); - // mask must include ONLY local APICs, or we will have problems. - if (!deliver_bitmask) { -- if (bx_dbg.apic) -- BX_INFO(("deliver failed: no APICs in destination bitmask")); -+ BX_PANIC(("deliver failed for vector %02x: no APICs in destination bitmask", vector)); - return false; - } - switch (delivery_mode) { -@@ -185,6 +191,10 @@ - break; - case 5: // INIT - { -+ // NOTE: special behavior of local apics is handled in -+ // bx_local_apic_c::deliver. -+ -+ // normal INIT. initialize the local apics in the delivery mask. - for (int bit=0; bitinit (); -@@ -221,6 +231,33 @@ - return true; - } - -+Boolean -+bx_local_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode) -+{ -+ // In this function, implement only the behavior that is specific to -+ // the local apic. For general behavior of all apics, just send it to -+ // the base class. -+ if (delivery_mode == 5) -+ { -+ int trig_mode = (icr_low >> 15) & 1; -+ int level = (icr_low >> 14) & 1; -+ if (level == 0 && trig_mode == 1) { -+ // special mode in local apic. See "INIT Level Deassert" in the -+ // Intel Soft. Devel. Guide Vol 3, page 7-34. This magic code -+ // causes all APICs (regardless of dest address) to set their -+ // arbitration ID to their APIC ID. -+ BX_INFO (("INIT with Level&Deassert: synchronize arbitration IDs")); -+ for (int bit=0; bitset_arb_id (apic_index[bit]->get_id ()); -+ } -+ return true; -+ } -+ } -+ // not any special case behavior, just use generic apic code. -+ return bx_generic_apic_c::deliver (dest, dest_mode, delivery_mode, vector, polarity, trig_mode); -+} -+ - bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu) - : bx_generic_apic_c () - { -@@ -230,6 +267,13 @@ - } - - void -+bx_local_apic_c::set_arb_id (int new_arb_id) -+{ -+ BX_DEBUG (("set arbitration ID to %d", new_arb_id)); -+ arb_id = new_arb_id; -+} -+ -+void - bx_local_apic_c::hwreset () - { - /* same as INIT but also sets arbitration ID and APIC ID */ -@@ -338,9 +382,11 @@ - break; - case 0xd0: // logical destination - log_dest = (*data >> 24) & 0xff; -+ BX_DEBUG (("set logical destiation to %02x", log_dest)); - break; - case 0xe0: // destination format - dest_format = (*data >> 28) & 0xf; -+ BX_DEBUG (("set destination format to %02x", dest_format)); - break; - case 0xf0: // spurious interrupt vector - spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0); -@@ -653,11 +698,9 @@ - - Bit8u bx_local_apic_c::get_apr () - { -- if (bx_dbg.apic) -- BX_INFO(("WARNING: Local APIC Arbitration Priority not implemented, returning 0")); -- // should look at TPR, vector of highest priority isr, etc. -- return 0; -+ return arb_id; - } -+ - - - void -Index: cpu/cpu.h -=================================================================== -RCS file: /cvsroot/bochs/bochs/cpu/cpu.h,v -retrieving revision 1.15 -diff -u -r1.15 cpu.h ---- cpu/cpu.h 3 Oct 2001 19:53:48 -0000 1.15 -+++ cpu/cpu.h 24 Mar 2002 01:15:01 -0000 -@@ -548,9 +548,10 @@ - virtual void trigger_irq (unsigned num, unsigned from); - virtual void untrigger_irq (unsigned num, unsigned from); - virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode); -- Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); -+ virtual Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); - virtual Boolean match_logical_addr (Bit8u address); - virtual bx_apic_type_t get_type (); -+ virtual void set_arb_id (int newid); // only implemented on local apics - }; - - class bx_local_apic_c : public bx_generic_apic_c { -@@ -612,10 +613,12 @@ - virtual Boolean is_local_apic () { return true; } - virtual bx_apic_type_t get_type () { return APIC_TYPE_LOCAL_APIC; } - virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode); -+ virtual Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode); - Bit8u get_ppr (); - Bit8u get_apr (); - void periodic (Bit32u usec_delta); - void set_divide_configuration (Bit32u value); -+ virtual void set_arb_id (int newid); - }; - - #define APIC_MAX_ID 16