[install] Add reg_set_sz() function
[sanbootconf.git] / driver / acpi.c
1 /*
2  * Copyright (C) 2008 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 <ntddk.h>
20 #include "sanbootconf.h"
21 #include "acpi.h"
22
23 /** Start of region to scan in base memory */
24 #define BASEMEM_START 0x0
25
26 /** End of region to scan in base memory */
27 #define BASEMEM_END 0xa0000
28
29 /** Length of region to scan in base memory */
30 #define BASEMEM_LEN ( BASEMEM_END - BASEMEM_START )
31
32 /**
33  * Calculate byte checksum
34  *
35  * @v data              Region to checksum
36  * @v len               Length of region
37  * @ret checksum        Byte checksum
38  */
39 static UCHAR byte_sum ( PUCHAR data, ULONG len ) {
40         UCHAR checksum = 0;
41         ULONG offset;
42
43         for ( offset = 0 ; offset < len ; offset++ )
44                 checksum = ( ( UCHAR ) ( checksum + data[offset] ) );
45
46         return checksum;
47 }
48
49 /**
50  * Search for ACPI table in base memory
51  *
52  * @v signature         Table signature
53  * @ret table_copy      Copy of table, or NULL
54  *
55  * The returned table is allocated using ExAllocatePool().
56  */
57 NTSTATUS find_acpi_table ( PCHAR signature,
58                            PACPI_DESCRIPTION_HEADER *table_copy ) {
59         PHYSICAL_ADDRESS basemem_phy;
60         PUCHAR basemem;
61         ULONG offset;
62         PACPI_DESCRIPTION_HEADER table;
63         NTSTATUS status;
64
65         /* Map base memory */
66         basemem_phy.QuadPart = BASEMEM_START;
67         basemem = MmMapIoSpace ( basemem_phy, BASEMEM_LEN, MmNonCached );
68         if ( ! basemem ) {
69                 DbgPrint ( "Could not map base memory\n" );
70                 status = STATUS_UNSUCCESSFUL;
71                 goto err_mmmapiospace;
72         }
73
74         /* Scan for table */
75         status = STATUS_NO_SUCH_FILE;
76         for ( offset = 0 ; offset < BASEMEM_LEN ; offset += 16 ) {
77                 table = ( ( PACPI_DESCRIPTION_HEADER ) ( basemem + offset ) );
78                 if ( memcmp ( table->signature, signature,
79                               sizeof ( table->signature ) ) != 0 )
80                         continue;
81                 if ( ( offset + table->length ) > BASEMEM_LEN )
82                         continue;
83                 if ( byte_sum ( ( ( PUCHAR ) table ), table->length ) != 0 )
84                         continue;
85                 DbgPrint ( "Found ACPI table \"%.4s\" at %05x OEM ID "
86                            "\"%.6s\" OEM table ID \"%.8s\"\n", signature,
87                            ( BASEMEM_START + offset ), table->oem_id,
88                            table->oem_table_id );
89                 /* Create copy of table */
90                 *table_copy = ExAllocatePoolWithTag ( NonPagedPool,
91                                                       table->length,
92                                                       SANBOOTCONF_POOL_TAG );
93                 if ( ! *table_copy ) {
94                         DbgPrint ( "Could not allocate table copy\n" );
95                         status = STATUS_NO_MEMORY;
96                         goto err_exallocatepoolwithtag;
97                 }
98                 RtlCopyMemory ( *table_copy, table, table->length );
99                 status = STATUS_SUCCESS;
100                 break;
101         }
102
103  err_exallocatepoolwithtag:
104         MmUnmapIoSpace ( basemem, BASEMEM_LEN );
105  err_mmmapiospace:
106         return status;
107 }