pnpbios.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <string.h>
00023 #include <errno.h>
00024 #include <realmode.h>
00025 #include <pnpbios.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034 struct pnp_bios {
00035
00036
00037
00038
00039 uint32_t signature;
00040
00041 uint8_t version;
00042
00043 uint8_t length;
00044
00045 uint16_t control;
00046
00047 uint8_t checksum;
00048 } __attribute__ (( packed ));
00049
00050
00051 #define PNP_BIOS_SIGNATURE \
00052 ( ( '$' << 0 ) + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
00053
00054
00055
00056
00057
00058
00059
00060 static int is_pnp_bios ( unsigned int offset ) {
00061 union {
00062 struct pnp_bios pnp_bios;
00063 uint8_t bytes[256];
00064 } u;
00065 size_t len;
00066 unsigned int i;
00067 uint8_t sum = 0;
00068
00069
00070 copy_from_real ( &u.pnp_bios, BIOS_SEG, offset, sizeof ( u.pnp_bios ));
00071 if ( u.pnp_bios.signature != PNP_BIOS_SIGNATURE )
00072 return -EINVAL;
00073
00074
00075 len = u.pnp_bios.length;
00076 copy_from_real ( &u.bytes, BIOS_SEG, offset, len );
00077 for ( i = 0 ; i < len ; i++ ) {
00078 sum += u.bytes[i];
00079 }
00080 if ( sum != 0 )
00081 return -EINVAL;
00082
00083 DBG ( "Found PnP BIOS at %04x:%04x\n", BIOS_SEG, offset );
00084
00085 return 0;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 int find_pnp_bios ( void ) {
00097 static int pnp_offset = 0;
00098
00099 if ( pnp_offset )
00100 return pnp_offset;
00101
00102 for ( pnp_offset = 0 ; pnp_offset < 0x10000 ; pnp_offset += 0x10 ) {
00103 if ( is_pnp_bios ( pnp_offset ) == 0 )
00104 return pnp_offset;
00105 }
00106
00107 pnp_offset = -1;
00108 return pnp_offset;
00109 }