123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "io.h"
- #include "mp.h"
- _MP_ *_mp_;
- static void
- mpresetothers(void)
- {
- /*
- * INIT all excluding self.
- */
- lapicicrw(0, 0x000C0000|ApicINIT);
- }
- static int identify(void);
- PCArch archmp = {
- .id= "_MP_",
- .ident= identify,
- .reset= mpshutdown,
- .intrinit= mpinit,
- .intrenable= mpintrenable,
- .intron= lapicintron,
- .introff= lapicintroff,
- .fastclock= i8253read,
- .timerset= lapictimerset,
- .resetothers= mpresetothers,
- };
- static int
- identify(void)
- {
- char *cp;
- PCMP *pcmp;
- uchar *p, sum;
- ulong length;
- if((cp = getconf("*nomp")) != nil && strtol(cp, 0, 0) != 0)
- return 1;
- /*
- * 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.
- */
- if((_mp_ = sigsearch("_MP_")) == 0 || _mp_->physaddr == 0) {
- /*
- * we can easily get processor info from acpi, but
- * interrupt routing, etc. would require interpreting aml.
- */
- print("archmp: no mp table found, assuming uniprocessor\n");
- return 1;
- }
- if (0)
- iprint("mp physaddr %#lux\n", _mp_->physaddr);
- pcmp = KADDR(_mp_->physaddr);
- if(memcmp(pcmp, "PCMP", 4) != 0) {
- print("archmp: mp table has bad magic");
- return 1;
- }
- length = pcmp->length;
- sum = 0;
- for(p = (uchar*)pcmp; length; length--)
- sum += *p++;
- if(sum || (pcmp->version != 1 && pcmp->version != 4))
- return 1;
- if(cpuserver && m->havetsc)
- archmp.fastclock = tscticks;
- return 0;
- }
- Lock mpsynclock;
- void
- syncclock(void)
- {
- uvlong x;
- if(arch->fastclock != tscticks)
- return;
- if(m->machno == 0){
- wrmsr(0x10, 0);
- m->tscticks = 0;
- } else {
- x = MACHP(0)->tscticks;
- while(x == MACHP(0)->tscticks)
- ;
- wrmsr(0x10, MACHP(0)->tscticks);
- cycles(&m->tscticks);
- }
- }
- uvlong
- tscticks(uvlong *hz)
- {
- if(hz != nil)
- *hz = m->cpuhz;
- cycles(&m->tscticks); /* Uses the rdtsc instruction */
- return m->tscticks;
- }
|