1 /* $OpenBSD: smpprobe.c,v 1.6 2004/03/09 19:12:13 tom Exp $ */
2
3 /*
4 * Copyright (c) 1997 Tobias Weingartner
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29
30 #include <sys/param.h>
31 #include <machine/biosvar.h>
32 #include "libsa.h"
33
34 extern int debug;
35
36 extern u_int cnvmem, extmem;
37 #define MP_FLOAT_SIG 0x5F504D5F /* _MP_ */
38 #define MP_CONF_SIG 0x504D4350 /* PCMP */
39
40 typedef struct _mp_float {
41 u_int32_t signature;
42 u_int32_t conf_addr;
43 u_int8_t length;
44 u_int8_t spec_rev;
45 u_int8_t checksum;
46 u_int8_t feature[5];
47 } mp_float_t;
48
49
50 static __inline int
mp_checksum(u_int8_t * ptr,int len)51 mp_checksum(u_int8_t *ptr, int len)
52 {
53 register int i, sum = 0;
54
55 #ifdef DEBUG
56 printf("Checksum %p for %d\n", ptr, len);
57 #endif
58
59 for (i = 0; i < len; i++)
60 sum += *(ptr + i);
61
62 return (!(sum & 0xff));
63 }
64
65
66 static mp_float_t *
mp_probefloat(u_int8_t * ptr,int len)67 mp_probefloat(u_int8_t *ptr, int len)
68 {
69 mp_float_t *mpp = NULL;
70 int i;
71
72 #ifdef DEBUG
73 if (debug)
74 printf("Checking %p for %d\n", ptr, len);
75 #endif
76 for (i = 0; i < 1024; i++) {
77 mp_float_t *tmp = (mp_float_t*)(ptr + i);
78
79 if (tmp->signature == MP_FLOAT_SIG) {
80 printf("Found possible MP signature at: %p\n", ptr);
81
82 mpp = tmp;
83 break;
84 }
85 if ((tmp->signature == MP_FLOAT_SIG) &&
86 mp_checksum((u_int8_t *)tmp, tmp->length*16)) {
87 #ifdef DEBUG
88 if (debug)
89 printf("Found valid MP signature at: %p\n",
90 ptr);
91 #endif
92 mpp = tmp;
93 break;
94 }
95 }
96
97 return mpp;
98 }
99
100
101 void
smpprobe(void)102 smpprobe(void)
103 {
104 mp_float_t *mp = NULL;
105
106 /* Check EBDA */
107 if (!(mp = mp_probefloat((void *)((*((u_int32_t*)0x4e)) * 16), 1024)) &&
108 /* Check BIOS ROM 0xE0000 - 0xFFFFF */
109 !(mp = mp_probefloat((void *)(0xE0000), 0x1FFFF)) &&
110 /* Check last 1K of base RAM */
111 !(mp = mp_probefloat((void *)(cnvmem * 1024), 1024)) &&
112 /* Check last 1K of extended RAM XXX */
113 !(mp = mp_probefloat((void *)(extmem * 1024 - 1024), 1024))) {
114 /* No valid MP signature found */
115 #if DEBUG
116 if (debug)
117 printf("No valid MP signature found.\n");
118 #endif
119 return;
120 }
121
122 /* Valid MP signature found */
123 printf(" smp");
124
125 #if DEBUG
126 if (debug)
127 printf("Floating Structure:\n"
128 "\tSignature: %x\n"
129 "\tConfig at: %x\n"
130 "\tLength: %d\n"
131 "\tRev: 1.%d\n"
132 "\tFeature: %x %x %x %x %x\n",
133 mp->signature, mp->conf_addr, mp->length, mp->spec_rev,
134 mp->feature[0], mp->feature[1], mp->feature[2],
135 mp->feature[3], mp->feature[4]);
136 #endif
137 }
138