MP fl

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Locked
hfcao
Posts: 11
Joined: Sun Aug 19, 2012 11:37 pm

MP fl

Post by hfcao »

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~
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: MP fl

Post by xenos »

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).
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
hfcao
Posts: 11
Joined: Sun Aug 19, 2012 11:37 pm

Re: MP fl

Post by hfcao »

thankyou very much for your prompt reply~ :D ,I have run it on qemu to test the code,but I haven't find any MP Floating pointer structer.So I don't know the reason why? Does there have any bugs in my code?
Best~
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: MP fl

Post by JamesM »

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.
Locked