write to apic must be 16-byte aligned
This commit is contained in:
parent
8b608fe045
commit
7d5e058dfe
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: apic.cc,v 1.115 2009-02-03 19:25:37 sshwarts Exp $
|
||||
// $Id: apic.cc,v 1.116 2009-02-03 20:42:15 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2002 Zwane Mwaikambo, Stanislav Shwartsman
|
||||
@ -221,33 +221,17 @@ void bx_generic_apic_c::read(bx_phy_address addr, void *data, unsigned len)
|
||||
|
||||
void bx_generic_apic_c::write(bx_phy_address addr, void *data, unsigned len)
|
||||
{
|
||||
if((addr & ~0x3) != ((addr+len-1) & ~0x3)) {
|
||||
BX_PANIC(("APIC write at address 0x" FMT_PHY_ADDRX " spans 32-bit boundary !", addr));
|
||||
if (len != 4) {
|
||||
BX_PANIC(("APIC write with len=%d (should be 4)", len));
|
||||
return;
|
||||
}
|
||||
bx_phy_address addr_aligned = addr & ~0x3;
|
||||
if(len == 4) { // must be 32-bit aligned
|
||||
write_aligned(addr_aligned, (Bit32u*) data);
|
||||
|
||||
if(addr & 0xf) {
|
||||
BX_PANIC(("APIC write at unaligned address 0x" FMT_PHY_ADDRX, addr));
|
||||
return;
|
||||
}
|
||||
// partial write to the apic register, need to update some bytes
|
||||
// and do not touch the others, i.e. to do RMW operation
|
||||
Bit32u value;
|
||||
read_aligned(addr_aligned, &value); // apic read has no side effects
|
||||
// handle partial write, independent of endian-ness
|
||||
unsigned shift = (addr&3)*8;
|
||||
if (len == 1) {
|
||||
value &= ~(0xff << shift);
|
||||
value |= (*((Bit8u *) data) << shift);
|
||||
}
|
||||
else if (len == 2) {
|
||||
value &= ~(0xffff << shift);
|
||||
value |= (*((Bit16u *)data) << shift);
|
||||
}
|
||||
else {
|
||||
BX_PANIC(("Unsupported APIC write at address 0x" FMT_PHY_ADDRX ", len=%d", addr, len));
|
||||
}
|
||||
write_aligned(addr_aligned, &value);
|
||||
|
||||
write_aligned(addr, (Bit32u*) data);
|
||||
}
|
||||
|
||||
bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu)
|
||||
@ -325,10 +309,8 @@ void bx_local_apic_c::set_id(Bit8u newid)
|
||||
} else {
|
||||
BX_INFO(("naming convention for apics requires id=0-%d only", APIC_MAX_ID));
|
||||
}
|
||||
if(BX_CPU_LEVEL<2)
|
||||
BX_INFO(("8086"));
|
||||
else
|
||||
BX_INFO(("80%d86", BX_CPU_LEVEL));
|
||||
|
||||
BX_INFO(("80%d86", BX_CPU_LEVEL));
|
||||
}
|
||||
|
||||
// APIC write: 4 byte write to 16-byte aligned APIC address
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: apic.h,v 1.39 2009-01-16 18:18:58 sshwarts Exp $
|
||||
// $Id: apic.h,v 1.40 2009-02-03 20:42:15 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2002 Zwane Mwaikambo, Stanislav Shwartsman
|
||||
@ -48,10 +48,10 @@ public:
|
||||
void set_id(Bit8u newid);
|
||||
Bit8u get_id() const { return id; }
|
||||
bx_bool is_selected(bx_phy_address addr, unsigned len);
|
||||
void read(bx_phy_address addr, void *data, unsigned len);
|
||||
virtual void read_aligned(bx_phy_address address, Bit32u *data) = 0;
|
||||
void write(bx_phy_address address, void *value, unsigned len);
|
||||
void read(bx_phy_address addr, void *data, unsigned len);
|
||||
virtual void write_aligned(bx_phy_address address, Bit32u *data) = 0;
|
||||
void write(bx_phy_address addr, void *data, unsigned len);
|
||||
};
|
||||
|
||||
#ifdef BX_INCLUDE_LOCAL_APIC
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ioapic.cc,v 1.42 2009-02-03 19:12:00 sshwarts Exp $
|
||||
// $Id: ioapic.cc,v 1.43 2009-02-03 20:42:15 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -46,7 +46,7 @@ static bx_bool ioapic_write(bx_phy_address a20addr, unsigned len, void *data, vo
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(a20addr & 3) {
|
||||
if(a20addr & 0xf) {
|
||||
BX_PANIC(("I/O apic write at unaligned address 0x" FMT_PHY_ADDRX, a20addr));
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ioapic.h,v 1.26 2008-11-17 20:06:16 sshwarts Exp $
|
||||
// $Id: ioapic.h,v 1.27 2009-02-03 20:42:15 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -82,8 +82,9 @@ class bx_ioapic_c : public bx_generic_apic_c
|
||||
// It's not clear if this is how the real device works.
|
||||
Bit32u irr;
|
||||
|
||||
public:
|
||||
bx_io_redirect_entry_t ioredtbl[BX_IOAPIC_NUM_PINS]; // table of redirections
|
||||
|
||||
public:
|
||||
bx_ioapic_c();
|
||||
virtual ~bx_ioapic_c() {}
|
||||
virtual void init();
|
||||
@ -93,7 +94,7 @@ public:
|
||||
void set_irq_level(Bit8u int_in, bx_bool level);
|
||||
void receive_eoi(Bit8u vector);
|
||||
void service_ioapic(void);
|
||||
virtual void register_state(void);
|
||||
void register_state(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user