Hi,I am trying to write an 64bit os,so I try to transplant my 32bit code to 64bit.However,I can't boot multiprocessors on my 64bit machine.Even,I cannot find an MP Floating Pointer Structer on my 64bit machine,I don't know what's wrong?The code I use to bootstrap multiprocessors is as follows:
// Multiprocessor support
// Search memory for MP description structures.
// http://developer.intel.com/design/penti ... 201606.pdf
#include "types.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "mp.h"
#include "x86.h"
#include "mmu.h"
#include "proc.h"
struct cpu cpus[NCPU];
static struct cpu *bcpu;
int ismp;
int ncpu;
uchar ioapicid;
int
mpbcpu(void)
{
return bcpu-cpus;
}
static uchar
sum(uchar *addr, int len)
{
int i, sum;
sum = 0;
for(i=0; i<len; i++)
sum += addr;
return sum;
}
// Look for an MP structure in the len bytes at addr.
static struct mp*
mpsearch1(uint a, int len)
{
uchar *e, *p, *addr;
addr = p2v(a);
e = addr+len;
for(p = addr; p < e; p += sizeof(struct mp))
if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
return (struct mp*)p;
return 0;
}
// Search for the MP Floating Pointer Structure, which according to the
// spec is in one of the following three locations:
// 1) in the first KB of the EBDA;
// 2) in the last KB of system base memory;
// 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
static struct mp*
mpsearch(void)
{
uchar *bda;
uint p;
struct mp *mp;
bda = (uchar *) P2V(0x400);
if((p = ((bda[0x0F]<<8)| bda[0x0E]) << 4)){
if((mp = mpsearch1(p, 1024)))
return mp;
} else {
p = ((bda[0x14]<<8)|bda[0x13])*1024;
if((mp = mpsearch1(p-1024, 1024)))
return mp;
}
return mpsearch1(0xF0000, 0x10000);
}
// Search for an MP configuration table. For now,
// don't accept the default configurations (physaddr == 0).
// Check for correct signature, calculate the checksum and,
// if correct, check the version.
// To do: check extended table checksum.
static struct mpconf*
mpconfig(struct mp **pmp)
{
struct mpconf *conf;
struct mp *mp;
if((mp = mpsearch()) == 0 || mp->physaddr == 0)
return 0;
conf = (struct mpconf*) p2v((uint) mp->physaddr);
if(memcmp(conf, "PCMP", 4) != 0)
return 0;
if(conf->version != 1 && conf->version != 4)
return 0;
if(sum((uchar*)conf, conf->length) != 0)
return 0;
*pmp = mp;
return conf;
}
void
mpinit(void)
{
uchar *p, *e;
struct mp *mp;
struct mpconf *conf;
struct mpproc *proc;
struct mpioapic *ioapic;
bcpu = &cpus[0];
if((conf = mpconfig(&mp)) == 0)
return;
ismp = 1;
lapic = (uint*)conf->lapicaddr;
for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
switch(*p){
case MPPROC:
proc = (struct mpproc*)p;
if(ncpu != proc->apicid){
cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu, proc->apicid);
ismp = 0;
}
if(proc->flags & MPBOOT)
bcpu = &cpus[ncpu];
cpus[ncpu].id = ncpu;
ncpu++;
p += sizeof(struct mpproc);
continue;
case MPIOAPIC:
ioapic = (struct mpioapic*)p;
ioapicid = ioapic->apicno;
p += sizeof(struct mpioapic);
continue;
case MPBUS:
case MPIOINTR:
case MPLINTR:
p += 8;
continue;
default:
cprintf("mpinit: unknown config type %x\n", *p);
ismp = 0;
}
}
if(!ismp){
// Didn't like what we found; fall back to no MP.
ncpu = 1;
lapic = 0;
ioapicid = 0;
return;
}
if(mp->imcrp){
// Bochs doesn't support IMCR, so this doesn't run on Bochs.
// But it would on real hardware.
outb(0x22, 0x70); // Select IMCR
outb(0x23, inb(0x23) | 1); // Mask external interrupts.
}
}
can anyone tells me why?and the differences between 32bit and 64bit,Thanks in advance~
MP fl
- xenos
- Member
- Posts: 1118
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: MP fl
Have you tested your code on a virtual machine with 64 bit and multiprocessor support? Bochs, QEMU, AMD SimNow! should all report an MP table and its much easier to debug your code than on real hardware.
Another thing you may encounter on real hardware is that there is no MP table, even though it's a multiprocessor. In this case it will be necessary to use ACPI instead. It's not more difficult than using the MP table, you just need to find and parse a different table (called the MADT - multiple APIC description table).
Another thing you may encounter on real hardware is that there is no MP table, even though it's a multiprocessor. In this case it will be necessary to use ACPI instead. It's not more difficult than using the MP table, you just need to find and parse a different table (called the MADT - multiple APIC description table).
Re: MP fl
This post is piss poor and as such has been locked.
a) Post to correct subforum. This is OS Development.
b) Write a proper thread title. "MP fl" does not cut it.
c) Use [ code ] tags.
d) Do not code dump.
a) Post to correct subforum. This is OS Development.
b) Write a proper thread title. "MP fl" does not cut it.
c) Use [ code ] tags.
d) Do not code dump.