Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/smp.c

1/*
2 * smp.c
3 * Chameleon
4 *
5 * Created by cparm on 17/06/11.
6 * Copyright 2011 __MyCompanyName__. All rights reserved.
7 *
8 */
9
10#include "smp.h"
11#include "libsaio.h"
12
13#define ACPI_RANGE_START (0x0E0000)
14#define ACPI_RANGE_END (0x0FFFFF)
15
16static struct mp_t *
17bios_search_mp(char *base, int length);
18static struct mp_t* getAddressOfMPSTable();
19
20static int lapic_dummy = 0;
21unsigned imps_lapic_addr = ((unsigned)(&lapic_dummy)) - LAPIC_ID;
22
23struct mp_t {
24uint8_t sig[4];
25uint32_t config_ptr;
26uint8_t len;
27uint8_t ver;
28uint8_t checksum;
29uint8_t f1;
30uint8_t f2;
31uint8_t fr[3];
32}__attribute__((packed)) mp_t;
33
34static struct mp_t* getAddressOfMPSTable()
35{
36struct mp_t *mp;
37 uint16_t*addr;
38
39 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
40 addr = (uint16_t *)ptov(EBDA_SEG_ADDR);
41 if ((mp = bios_search_mp((char *)(*addr << 4), EBDA_SEG_LEN)) != NULL)
42return (mp);
43
44unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
45 | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10;
46
47if ((mp = bios_search_mp((char *)mem_lower, EBDA_SEG_LEN)) != NULL)
48return (mp);
49
50 if ((mp = bios_search_mp((char *)0x00F0000, ACPI_RANGE_END)) != NULL)
51return (mp);
52
53 return (NULL);
54
55}
56
57static struct mp_t *
58bios_search_mp(char *base, int length)
59{
60struct mp_t *mp;
61 intofs;
62
63 /* search on 16-byte boundaries */
64 for (ofs = 0; ofs < length; ofs += 16) {
65
66mp = (struct mp_t*)ptov(base + ofs);
67
68/* compare signature, validate checksum */
69if (!strncmp((char*)mp->sig, MP_SIGSTR, strlen(MP_SIGSTR))) {
70uint8_t csum = checksum8(mp, sizeof(struct mp_t));
71if(csum == 0) {
72return mp;
73}
74
75}
76}
77 return NULL;
78}
79
80void * getMPSTable()
81{
82struct mp_t *mps_p = getAddressOfMPSTable() ;
83
84 if (mps_p)
85 {
86 if (mps_p->config_ptr) {
87
88 struct imps_cth *local_cth_ptr
89 = (struct imps_cth *)ptov(mps_p->config_ptr);
90
91 imps_lapic_addr = local_cth_ptr->lapic_addr;
92
93 } else {
94 imps_lapic_addr = LAPIC_ADDR_DEFAULT;
95 }
96}
97
98return (void *)mps_p;
99}

Archive Download this file

Revision: 1119