aslmapenter.c revision 306536
1/******************************************************************************
2 *
3 * Module Name: aslmapenter - Build resource descriptor/device maps
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acapps.h>
47#include <contrib/dev/acpica/compiler/aslcompiler.h>
48
49/* This module used for application-level code only */
50
51#define _COMPONENT          ACPI_COMPILER
52        ACPI_MODULE_NAME    ("aslmapenter")
53
54/* Local prototypes */
55
56static ACPI_GPIO_INFO *
57MpCreateGpioInfo (
58    UINT16                  PinNumber,
59    char                    *DeviceName);
60
61static ACPI_SERIAL_INFO *
62MpCreateSerialInfo (
63    char                    *DeviceName,
64    UINT16                  Address);
65
66
67/*******************************************************************************
68 *
69 * FUNCTION:    MpSaveGpioInfo
70 *
71 * PARAMETERS:  Resource                - GPIO resource descriptor
72 *              PinCount                - From GPIO descriptor
73 *              PinList                 - From GPIO descriptor
74 *              DeviceName              - The "ResourceSource" name
75 *
76 * RETURN:      None
77 *
78 * DESCRIPTION: External Interface.
79 *              Save GPIO resource descriptor information.
80 *              Creates new GPIO info blocks, one for each pin defined by the
81 *              GPIO descriptor.
82 *
83 ******************************************************************************/
84
85void
86MpSaveGpioInfo (
87    ACPI_PARSE_OBJECT       *Op,
88    AML_RESOURCE            *Resource,
89    UINT32                  PinCount,
90    UINT16                  *PinList,
91    char                    *DeviceName)
92{
93    ACPI_GPIO_INFO          *Info;
94    UINT32                  i;
95
96
97    /* Mapfile option enabled? */
98
99    if (!Gbl_MapfileFlag)
100    {
101        return;
102    }
103
104    /* Create an info block for each pin defined in the descriptor */
105
106    for (i = 0; i < PinCount; i++)
107    {
108        Info = MpCreateGpioInfo (PinList[i], DeviceName);
109
110        Info->Op = Op;
111        Info->DeviceName = DeviceName;
112        Info->PinCount = PinCount;
113        Info->PinIndex = i;
114        Info->PinNumber = PinList[i];
115        Info->Type = Resource->Gpio.ConnectionType;
116        Info->Direction = (UINT8) (Resource->Gpio.IntFlags & 0x0003);       /* _IOR, for IO descriptor */
117        Info->Polarity = (UINT8) ((Resource->Gpio.IntFlags >> 1) & 0x0003); /* _POL, for INT descriptor */
118    }
119}
120
121
122/*******************************************************************************
123 *
124 * FUNCTION:    MpSaveSerialInfo
125 *
126 * PARAMETERS:  Resource                - A Serial resource descriptor
127 *              DeviceName              - The "ResourceSource" name.
128 *
129 * RETURN:      None
130 *
131 * DESCRIPTION: External Interface.
132 *              Save serial resource descriptor information.
133 *              Creates a new serial info block.
134 *
135 ******************************************************************************/
136
137void
138MpSaveSerialInfo (
139    ACPI_PARSE_OBJECT       *Op,
140    AML_RESOURCE            *Resource,
141    char                    *DeviceName)
142{
143    ACPI_SERIAL_INFO        *Info;
144    UINT16                  Address;
145    UINT32                  Speed;
146
147
148    /* Mapfile option enabled? */
149
150    if (!Gbl_MapfileFlag)
151    {
152        return;
153    }
154
155    if (Resource->DescriptorType != ACPI_RESOURCE_NAME_SERIAL_BUS)
156    {
157        return;
158    }
159
160    /* Extract address and speed from the resource descriptor */
161
162    switch (Resource->CommonSerialBus.Type)
163    {
164    case AML_RESOURCE_I2C_SERIALBUSTYPE:
165
166        Address = Resource->I2cSerialBus.SlaveAddress;
167        Speed = Resource->I2cSerialBus.ConnectionSpeed;
168        break;
169
170    case AML_RESOURCE_SPI_SERIALBUSTYPE:
171
172        Address = Resource->SpiSerialBus.DeviceSelection;
173        Speed = Resource->SpiSerialBus.ConnectionSpeed;
174        break;
175
176    case AML_RESOURCE_UART_SERIALBUSTYPE:
177
178        Address = 0;
179        Speed = Resource->UartSerialBus.DefaultBaudRate;
180        break;
181
182    default:    /* Invalid bus subtype */
183        return;
184    }
185
186    Info = MpCreateSerialInfo (DeviceName, Address);
187
188    Info->Op = Op;
189    Info->DeviceName = DeviceName;
190    Info->Resource = Resource;
191    Info->Address = Address;
192    Info->Speed = Speed;
193}
194
195
196/*******************************************************************************
197 *
198 * FUNCTION:    MpCreateGpioInfo
199 *
200 * PARAMETERS:  PinNumber               - GPIO pin number
201 *              DeviceName              - The "ResourceSource" name
202 *
203 * RETURN:      New GPIO info block.
204 *
205 * DESCRIPTION: Create a new GPIO info block and place it on the global list.
206 *              The list is sorted by GPIO device names first, and pin numbers
207 *              secondarily.
208 *
209 ******************************************************************************/
210
211static ACPI_GPIO_INFO *
212MpCreateGpioInfo (
213    UINT16                  PinNumber,
214    char                    *DeviceName)
215{
216    ACPI_GPIO_INFO          *Info;
217    ACPI_GPIO_INFO          *NextGpio;
218    ACPI_GPIO_INFO          *PrevGpio;
219    char                    *Buffer;
220
221
222    /*
223     * Allocate a new info block and insert it into the global GPIO list
224     * sorted by both source device name and then the pin number. There is
225     * one block per pin.
226     */
227    Buffer = UtStringCacheCalloc (sizeof (ACPI_GPIO_INFO));
228    Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Buffer);
229
230    NextGpio = Gbl_GpioList;
231    PrevGpio = NULL;
232    if (!Gbl_GpioList)
233    {
234        Gbl_GpioList = Info;
235        Info->Next = NULL;
236        return (Info);
237    }
238
239    /* Sort on source DeviceName first */
240
241    while (NextGpio &&
242        (strcmp (DeviceName, NextGpio->DeviceName) > 0))
243    {
244        PrevGpio = NextGpio;
245        NextGpio = NextGpio->Next;
246    }
247
248    /* Now sort on the PinNumber */
249
250    while (NextGpio &&
251        (NextGpio->PinNumber < PinNumber) &&
252        !strcmp (DeviceName, NextGpio->DeviceName))
253    {
254        PrevGpio = NextGpio;
255        NextGpio = NextGpio->Next;
256    }
257
258    /* Finish the list insertion */
259
260    if (PrevGpio)
261    {
262        PrevGpio->Next = Info;
263    }
264    else
265    {
266        Gbl_GpioList = Info;
267    }
268
269    Info->Next = NextGpio;
270    return (Info);
271}
272
273
274/*******************************************************************************
275 *
276 * FUNCTION:    MpCreateSerialInfo
277 *
278 * PARAMETERS:  DeviceName              - The "ResourceSource" name.
279 *              Address                 - Physical address for the device
280 *
281 * RETURN:      New Serial info block.
282 *
283 * DESCRIPTION: Create a new Serial info block and place it on the global list.
284 *              The list is sorted by Serial device names first, and addresses
285 *              secondarily.
286 *
287 ******************************************************************************/
288
289static ACPI_SERIAL_INFO *
290MpCreateSerialInfo (
291    char                    *DeviceName,
292    UINT16                  Address)
293{
294    ACPI_SERIAL_INFO        *Info;
295    ACPI_SERIAL_INFO        *NextSerial;
296    ACPI_SERIAL_INFO        *PrevSerial;
297    char                    *Buffer;
298
299
300    /*
301     * Allocate a new info block and insert it into the global Serial list
302     * sorted by both source device name and then the address.
303     */
304    Buffer = UtStringCacheCalloc (sizeof (ACPI_SERIAL_INFO));
305    Info = ACPI_CAST_PTR (ACPI_SERIAL_INFO, Buffer);
306
307    NextSerial = Gbl_SerialList;
308    PrevSerial = NULL;
309    if (!Gbl_SerialList)
310    {
311        Gbl_SerialList = Info;
312        Info->Next = NULL;
313        return (Info);
314    }
315
316    /* Sort on source DeviceName */
317
318    while (NextSerial &&
319        (strcmp (DeviceName, NextSerial->DeviceName) > 0))
320    {
321        PrevSerial = NextSerial;
322        NextSerial = NextSerial->Next;
323    }
324
325    /* Now sort on the Address */
326
327    while (NextSerial &&
328        (NextSerial->Address < Address) &&
329        !strcmp (DeviceName, NextSerial->DeviceName))
330    {
331        PrevSerial = NextSerial;
332        NextSerial = NextSerial->Next;
333    }
334
335    /* Finish the list insertion */
336
337    if (PrevSerial)
338    {
339        PrevSerial->Next = Info;
340    }
341    else
342    {
343        Gbl_SerialList = Info;
344    }
345
346    Info->Next = NextSerial;
347    return (Info);
348}
349