Browse Source

Added PnP BIOS scanning code, separated out from the UNDI driver

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
477a70697a
2 changed files with 122 additions and 0 deletions
  1. 107
    0
      src/arch/i386/firmware/pcbios/pnpbios.c
  2. 15
    0
      src/arch/i386/include/pnpbios.h

+ 107
- 0
src/arch/i386/firmware/pcbios/pnpbios.c View File

@@ -0,0 +1,107 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <string.h>
21
+#include <errno.h>
22
+#include <realmode.h>
23
+#include <pnpbios.h>
24
+
25
+/** @file
26
+ *
27
+ * PnP BIOS
28
+ *
29
+ */
30
+
31
+/** PnP BIOS structure */
32
+struct pnp_bios {
33
+	/** Signature
34
+	 *
35
+	 * Must be equal to @c PNP_BIOS_SIGNATURE
36
+	 */
37
+	uint32_t signature;
38
+	/** Version as BCD (e.g. 1.0 is 0x10) */
39
+	uint8_t version;
40
+	/** Length of this structure */
41
+	uint8_t length;
42
+	/** System capabilities */
43
+	uint16_t control;
44
+	/** Checksum */
45
+	uint8_t checksum;
46
+} __attribute__ (( packed ));
47
+
48
+/** Signature for a PnP BIOS structure */
49
+#define PNP_BIOS_SIGNATURE \
50
+	( ( '$' << 0 ) + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
51
+
52
+/**
53
+ * Test address for PnP BIOS structure
54
+ *
55
+ * @v offset		Offset within BIOS segment to test
56
+ * @ret rc		Return status code
57
+ */
58
+static int is_pnp_bios ( unsigned int offset ) {
59
+	union {
60
+		struct pnp_bios pnp_bios;
61
+		uint8_t bytes[256]; /* 256 is maximum length possible */
62
+	} u;
63
+	size_t len;
64
+	unsigned int i;
65
+	uint8_t sum = 0;
66
+
67
+	/* Read start of header and verify signature */
68
+	copy_from_real ( &u.pnp_bios, BIOS_SEG, offset, sizeof ( u.pnp_bios ));
69
+	if ( u.pnp_bios.signature != PNP_BIOS_SIGNATURE )
70
+		return -EINVAL;
71
+
72
+	/* Read whole header and verify checksum */
73
+	len = u.pnp_bios.length;
74
+	copy_from_real ( &u.bytes, BIOS_SEG, offset, len );
75
+	for ( i = 0 ; i < len ; i++ ) {
76
+		sum += u.bytes[i];
77
+	}
78
+	if ( sum != 0 )
79
+		return -EINVAL;
80
+
81
+	DBG ( "Found PnP BIOS at %04x:%04x\n", BIOS_SEG, offset );
82
+
83
+	return 0;
84
+}
85
+
86
+/**
87
+ * Locate Plug-and-Play BIOS
88
+ *
89
+ * @ret pnp_offset	Offset of PnP BIOS structure within BIOS segment
90
+ *
91
+ * The PnP BIOS structure will be at BIOS_SEG:pnp_offset.  If no PnP
92
+ * BIOS is found, -1 is returned.
93
+ */
94
+int find_pnp_bios ( void ) {
95
+	static int pnp_offset = 0;
96
+
97
+	if ( pnp_offset )
98
+		return pnp_offset;
99
+
100
+	for ( pnp_offset = 0 ; pnp_offset < 0x10000 ; pnp_offset += 0x10 ) {
101
+		if ( is_pnp_bios ( pnp_offset ) == 0 )
102
+			return pnp_offset;
103
+	}
104
+
105
+	pnp_offset = -1;
106
+	return pnp_offset;
107
+}

+ 15
- 0
src/arch/i386/include/pnpbios.h View File

@@ -0,0 +1,15 @@
1
+#ifndef _PNPBIOS_H
2
+#define _PNPBIOS_H
3
+
4
+/** @file
5
+ *
6
+ * PnP BIOS
7
+ *
8
+ */
9
+
10
+/* BIOS segment address */
11
+#define BIOS_SEG 0xf000
12
+
13
+extern int find_pnp_bios ( void );
14
+
15
+#endif /* _PNPBIOS_H */

Loading…
Cancel
Save