- create SMP specific tables dynamicly ("backported" from qemu - already mentioned

in our TODO list items 9.1 and 9.2)
This commit is contained in:
Volker Ruppert 2005-12-25 19:30:48 +00:00
parent 682895ca77
commit 81dd23c68f

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: misc_mem.cc,v 1.68 2005-12-19 20:48:51 vruppert Exp $
// $Id: misc_mem.cc,v 1.69 2005-12-25 19:30:48 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -95,7 +95,7 @@ void BX_MEM_C::init_memory(int memsize)
{
int idx;
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.68 2005-12-19 20:48:51 vruppert Exp $"));
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.69 2005-12-25 19:30:48 vruppert Exp $"));
// you can pass 0 if memory has been allocated already through
// the constructor, or the desired size of memory if it hasn't
// BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
@ -126,6 +126,49 @@ void BX_MEM_C::init_memory(int memsize)
}
#if BX_SMP_PROCESSORS > 1
void put_8bit(Bit8u **pp, Bit8u value)
{
Bit8u *p = *pp;
*p++ = value;
*pp = p;
}
void put_16bit(Bit8u **pp, Bit16u value)
{
Bit8u *p = *pp;
*p++ = value & 0xff;
*p++ = (value >> 8) & 0xff;
*pp = p;
}
void put_32bit(Bit8u **pp, Bit32u value)
{
Bit8u *p = *pp;
*p++ = value & 0xff;
*p++ = (value >> 8) & 0xff;
*p++ = (value >> 16) & 0xff;
*p++ = (value >> 24) & 0xff;
*pp = p;
}
void put_string(Bit8u **pp, const char *str)
{
Bit8u *p = *pp;
while (*str)
*p++ = *str++;
*pp = p;
}
Bit8u mp_checksum(const Bit8u *p, int len)
{
Bit8u sum = 0;
for (int i = 0; i < len; i++)
sum += p[i];
return (Bit8u)(-sum);
}
#endif
//
// Values for type:
// 0 : System Bios
@ -260,7 +303,73 @@ void BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
}
#if BX_SMP_PROCESSORS > 1
if (is_bochs_bios) {
// TODO: dynamicly create SMP tables at F000:B000
Bit8u* pcmp_ptr = &BX_MEM_THIS rom[0xFB000 & BIOS_MASK];
Bit8u* p = pcmp_ptr;
put_string(&p, "PCMP"); // signature
put_16bit(&p, 0); // table length
put_8bit(&p, 4); // version
put_8bit(&p, 0); // checksum
put_string(&p, "BOCHSCPU"); // OEM ID
put_string(&p, "0.1 "); // vendor ID
put_32bit(&p, 0); // OEM table pointer
put_16bit(&p, 0); // OEM table size
put_16bit(&p, 20); // entry count
put_32bit(&p, 0xfee00000); // local APIC addr
put_16bit(&p, 0); // ext table length
put_8bit(&p, 0); // ext table checksum
put_8bit(&p, 0); // reserved
for (i = 0; i < BX_SMP_PROCESSORS; i++) {
put_8bit(&p, 0); // entry type = processor
put_8bit(&p, (Bit8u)i); // APIC id
put_8bit(&p, 0x11); // local APIC version number
put_8bit(&p, (i==0)?3:1); // cpu flags: enabled, cpu0 = bootstrap cpu
put_8bit(&p, 0); // cpu signature
put_8bit(&p, 0);
put_8bit(&p, 0);
put_8bit(&p, 0);
put_16bit(&p, 0x201); // feature flags
put_16bit(&p, 0);
put_16bit(&p, 0); // reserved
put_16bit(&p, 0);
put_16bit(&p, 0);
put_16bit(&p, 0);
}
put_8bit(&p, 1); // entry type = bus
put_8bit(&p, 0); // bus ID
put_string(&p, "ISA ");
Bit8u ioapic_id = BX_SMP_PROCESSORS;
put_8bit(&p, 2); // entry type = I/O APIC
put_8bit(&p, ioapic_id); // apic id
put_8bit(&p, 0x11); // I/O APIC version number
put_8bit(&p, 1); // enabled
put_32bit(&p, 0xfec00000); // I/O APIC addr
for (i = 0; i < 16; i++) {
put_8bit(&p, 3); // entry type = I/O interrupt
put_8bit(&p, 0); // interrupt type = vectored interrupt
put_8bit(&p, 0); // flags: po=0, el=0
put_8bit(&p, 0);
put_8bit(&p, 0); // source bus ID = ISA
put_8bit(&p, i); // source bus IRQ
put_8bit(&p, ioapic_id); // dest I/O APIC ID
put_8bit(&p, i); // dest I/O APIC interrupt in
}
Bit16u len = (Bit16u)(p - pcmp_ptr);
pcmp_ptr[4] = (Bit8u)len;
pcmp_ptr[5] = (Bit8u)(len >> 8);
pcmp_ptr[7] = mp_checksum(pcmp_ptr, len);
Bit8u *fl_mp_ptr = &BX_MEM_THIS rom[0xFB000 & BIOS_MASK] + ((len + 15) & ~15);
p = fl_mp_ptr;
put_string(&p, "_MP_");
put_32bit(&p, 0xFB000); // pointer to MP config table
put_8bit(&p, 1); // length in 16 byte units
put_8bit(&p, 4); // MP spec revision
put_8bit(&p, 0); // checksum
put_8bit(&p, 0); // MP feature bytes 1-5
put_8bit(&p, 0);
put_8bit(&p, 0);
put_8bit(&p, 0);
put_8bit(&p, 0);
fl_mp_ptr[10] = mp_checksum(fl_mp_ptr, (int)(p - fl_mp_ptr));
}
#endif
BX_INFO(("rom at 0x%05x/%u ('%s')",