Show inlined functions with bt-akaros.sh (kernel)
[akaros.git] / kern / arch / x86 / mpacpi.c
1 /* This file is part of the UCB release of Plan 9. It is subject to the license
2  * terms in the LICENSE file found in the top-level directory of this
3  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
4  * part of the UCB release of Plan 9, including this file, may be copied,
5  * modified, propagated, or distributed except according to the terms contained
6  * in the LICENSE file. */
7
8 #include <slab.h>
9 #include <kmalloc.h>
10 #include <kref.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #include <error.h>
15 #include <cpio.h>
16 #include <pmap.h>
17 #include <smp.h>
18 #include <net/ip.h>
19 #include <acpi.h>
20 #include <arch/ioapic.h>
21 #include <arch/topology.h>
22
23 int mpacpi(int ncleft)
24 {
25         char *already;
26         int np, bp;
27         struct apic *apic;
28         struct Apicst *st;
29         struct Madt *mt;
30
31         /* If we don't have an mpisabusno yet, it's because the MP tables failed
32          * to parse.  So we'll just take the last one available.  I think we're
33          * supposed to parse the ACPI shit with the AML to figure out the buses
34          * and find a clear one, but fuck that.  Note this busno is just for our
35          * own RDT/Rbus bookkeeping. */
36         if (mpisabusno == -1)
37                 mpisabusno = Nbus - 1;
38
39         if (apics == NULL)
40                 return ncleft;
41         mt = apics->tbl;
42         if (mt == NULL)
43                 return ncleft;
44
45         printd("APIC lapic paddr %#.8llux, flags %#.8ux\n",
46                    mt->lapicpa, mt->pcat);
47         np = 0;
48         printd("apics->st %p\n", apics->st);
49         for (int i = 0; i < apics->nchildren; i++) {
50                 st = apics->children[i]->tbl;
51                 already = "";
52                 switch (st->type) {
53                 case ASlapic:
54                         printd("ASlapic %d\n", st->lapic.id);
55                         /* this table is supposed to have all of them if it
56                          * exists */
57                         if (st->lapic.id > MaxAPICNO)
58                                 break;
59                         apic = xlapic + st->lapic.id;
60                         bp = (np++ == 0);
61                         if (apic->useable) {
62                                 already = "(mp)";
63                         } else if (ncleft != 0) {
64                                 ncleft--;
65                                 apicinit(st->lapic.id, mt->lapicpa, bp);
66                         } else
67                                 already = "(off)";
68
69                         printd("apic proc %d/%d apicid %d %s\n", np - 1,
70                                apic->machno, st->lapic.id, already);
71                         break;
72                 case ASioapic:
73                         printd("ASioapic %d\n", st->ioapic.id);
74                         if (st->ioapic.id > Napic)
75                                 break;
76                         apic = xioapic + st->ioapic.id;
77                         if (apic->useable) {
78                                 apic->ibase = st->ioapic.ibase; /* gnarly */
79                                 already = "(mp)";
80                                 goto pr1;
81                         }
82                         ioapicinit(st->ioapic.id, st->ioapic.ibase,
83                                    st->ioapic.addr);
84 pr1:
85                         printd("ioapic %d ", st->ioapic.id);
86                         printd("addr %p base %d %s\n", apic->paddr, apic->ibase,
87                                    already);
88                         break;
89                 }
90         }
91         return ncleft;
92 }