xref: /openbsd/sys/arch/i386/stand/libsa/smpprobe.c (revision db3296cf)
1 /*	$OpenBSD: smpprobe.c,v 1.4 2003/06/04 17:04:05 deraadt 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
51 mp_checksum(ptr, len)
52 	u_int8_t *ptr;
53 	int len;
54 {
55 	register int i, sum = 0;
56 
57 #ifdef DEBUG
58 	printf("Checksum %p for %d\n", ptr, len);
59 #endif
60 
61 	for (i = 0; i < len; i++)
62 		sum += *(ptr + i);
63 
64 	return (!(sum & 0xff));
65 }
66 
67 
68 static mp_float_t *
69 mp_probefloat(ptr, len)
70 	u_int8_t *ptr;
71 	int len;
72 {
73 	mp_float_t *mpp = NULL;
74 	int i;
75 
76 #ifdef DEBUG
77 	if (debug)
78 		printf("Checking %p for %d\n", ptr, len);
79 #endif
80 	for(i = 0; i < 1024; i++){
81 		mp_float_t *tmp = (mp_float_t*)(ptr + i);
82 		if(tmp->signature == MP_FLOAT_SIG){
83 			printf("Found possible MP signature at: %p\n", ptr);
84 
85 			mpp = tmp;
86 			break;
87 		}
88 		if((tmp->signature == MP_FLOAT_SIG) &&
89 			mp_checksum(tmp, tmp->length*16)){
90 #ifdef DEBUG
91 			if (debug)
92 				printf("Found valid MP signature at: %p\n", ptr);
93 #endif
94 			mpp = tmp;
95 			break;
96 		}
97 	}
98 
99 	return (mpp);
100 }
101 
102 
103 void
104 smpprobe()
105 {
106 	mp_float_t *mp = NULL;
107 
108 	/* Check EBDA */
109 	if (!(mp = mp_probefloat((void *)((*((u_int32_t*)0x4e)) * 16), 1024)) &&
110 		/* Check BIOS ROM 0xE0000 - 0xFFFFF */
111 	    !(mp = mp_probefloat((void *)(0xE0000), 0x1FFFF)) &&
112 		/* Check last 1K of base RAM */
113 	    !(mp = mp_probefloat((void *)(cnvmem * 1024), 1024)) &&
114 		/* Check last 1K of extended RAM XXX */
115 	    !(mp = mp_probefloat((void *)(extmem * 1024 - 1024), 1024))) {
116 		/* No valid MP signature found */
117 #if DEBUG
118 		if (debug)
119 			printf("No valid MP signature found.\n");
120 #endif
121 		return;
122 	}
123 
124 	/* Valid MP signature found */
125 	printf(" smp");
126 #if DEBUG
127 	if (debug)
128 		printf("Floating Structure:\n"
129 		"\tSignature: %x\n"
130 		"\tConfig at: %x\n"
131 		"\tLength: %d\n"
132 		"\tRev: 1.%d\n"
133 		"\tFeature: %x %x %x %x %x\n",
134 		mp->signature, mp->conf_addr, mp->length, mp->spec_rev,
135 		mp->feature[0], mp->feature[1], mp->feature[2],
136 		mp->feature[3], mp->feature[4]);
137 #endif
138 }
139 
140