Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "io.h"
7
 
8
#include "mp.h"
9
 
10
_MP_ *_mp_;
11
 
12
static void
13
mpresetothers(void)
14
{
15
	/*
16
	 * INIT all excluding self.
17
	 */
18
	lapicicrw(0, 0x000C0000|ApicINIT);
19
}
20
 
21
static int identify(void);
22
 
23
PCArch archmp = {
24
.id=		"_MP_",	
25
.ident=		identify,
26
.reset=		mpshutdown,
27
.intrinit=	mpinit,
28
.intrenable=	mpintrenable,
29
.intron=	lapicintron,
30
.introff=	lapicintroff,
31
.fastclock=	i8253read,
32
.timerset=	lapictimerset,
33
.resetothers=	mpresetothers,
34
};
35
 
36
static int
37
identify(void)
38
{
39
	char *cp;
40
	PCMP *pcmp;
41
	uchar *p, sum;
42
	ulong length;
43
 
44
	if((cp = getconf("*nomp")) != nil && strtol(cp, 0, 0) != 0)
45
		return 1;
46
 
47
	/*
48
	 * Search for an MP configuration table. For now,
49
	 * don't accept the default configurations (physaddr == 0).
50
	 * Check for correct signature, calculate the checksum and,
51
	 * if correct, check the version.
52
	 * To do: check extended table checksum.
53
	 */
54
	if((_mp_ = sigsearch("_MP_")) == 0 || _mp_->physaddr == 0) {
55
		/*
56
		 * we can easily get processor info from acpi, but
57
		 * interrupt routing, etc. would require interpreting aml.
58
		 */
59
		print("archmp: no mp table found, assuming uniprocessor\n");
60
		return 1;
61
	}
62
 
63
	if (0)
64
		iprint("mp physaddr %#lux\n", _mp_->physaddr);
65
	pcmp = KADDR(_mp_->physaddr);
66
	if(memcmp(pcmp, "PCMP", 4) != 0) {
67
		print("archmp: mp table has bad magic");
68
		return 1;
69
	}
70
 
71
	length = pcmp->length;
72
	sum = 0;
73
	for(p = (uchar*)pcmp; length; length--)
74
		sum += *p++;
75
 
76
	if(sum || (pcmp->version != 1 && pcmp->version != 4))
77
		return 1;
78
 
79
	if(cpuserver && m->havetsc)
80
		archmp.fastclock = tscticks;
81
	return 0;
82
}
83
 
84
Lock mpsynclock;
85
 
86
void
87
syncclock(void)
88
{
89
	uvlong x;
90
 
91
	if(arch->fastclock != tscticks)
92
		return;
93
 
94
	if(m->machno == 0){
95
		wrmsr(0x10, 0);
96
		m->tscticks = 0;
97
	} else {
98
		x = MACHP(0)->tscticks;
99
		while(x == MACHP(0)->tscticks)
100
			;
101
		wrmsr(0x10, MACHP(0)->tscticks);
102
		cycles(&m->tscticks);
103
	}
104
}
105
 
106
uvlong
107
tscticks(uvlong *hz)
108
{
109
	if(hz != nil)
110
		*hz = m->cpuhz;
111
 
112
	cycles(&m->tscticks);	/* Uses the rdtsc instruction */
113
	return m->tscticks;
114
}