1272286Sjkim/******************************************************************************
2272286Sjkim *
3272286Sjkim * Module Name: aslmapenter - Build resource descriptor/device maps
4272286Sjkim *
5272286Sjkim *****************************************************************************/
6272286Sjkim
7272286Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9272286Sjkim * All rights reserved.
10272286Sjkim *
11272286Sjkim * Redistribution and use in source and binary forms, with or without
12272286Sjkim * modification, are permitted provided that the following conditions
13272286Sjkim * are met:
14272286Sjkim * 1. Redistributions of source code must retain the above copyright
15272286Sjkim *    notice, this list of conditions, and the following disclaimer,
16272286Sjkim *    without modification.
17272286Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18272286Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19272286Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20272286Sjkim *    including a substantially similar Disclaimer requirement for further
21272286Sjkim *    binary redistribution.
22272286Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23272286Sjkim *    of any contributors may be used to endorse or promote products derived
24272286Sjkim *    from this software without specific prior written permission.
25272286Sjkim *
26272286Sjkim * Alternatively, this software may be distributed under the terms of the
27272286Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28272286Sjkim * Software Foundation.
29272286Sjkim *
30272286Sjkim * NO WARRANTY
31272286Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32272286Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33272286Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34272286Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35272286Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36272286Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37272286Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38272286Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39272286Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40272286Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41272286Sjkim * POSSIBILITY OF SUCH DAMAGES.
42272286Sjkim */
43272286Sjkim
44272444Sjkim#include <contrib/dev/acpica/include/acpi.h>
45272444Sjkim#include <contrib/dev/acpica/include/accommon.h>
46272444Sjkim#include <contrib/dev/acpica/include/acapps.h>
47272444Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
48272286Sjkim
49272286Sjkim/* This module used for application-level code only */
50272286Sjkim
51272286Sjkim#define _COMPONENT          ACPI_COMPILER
52272286Sjkim        ACPI_MODULE_NAME    ("aslmapenter")
53272286Sjkim
54272286Sjkim/* Local prototypes */
55272286Sjkim
56272286Sjkimstatic ACPI_GPIO_INFO *
57272286SjkimMpCreateGpioInfo (
58272286Sjkim    UINT16                  PinNumber,
59272286Sjkim    char                    *DeviceName);
60272286Sjkim
61272286Sjkimstatic ACPI_SERIAL_INFO *
62272286SjkimMpCreateSerialInfo (
63272286Sjkim    char                    *DeviceName,
64272286Sjkim    UINT16                  Address);
65272286Sjkim
66272286Sjkim
67272286Sjkim/*******************************************************************************
68272286Sjkim *
69272286Sjkim * FUNCTION:    MpSaveGpioInfo
70272286Sjkim *
71272286Sjkim * PARAMETERS:  Resource                - GPIO resource descriptor
72272286Sjkim *              PinCount                - From GPIO descriptor
73272286Sjkim *              PinList                 - From GPIO descriptor
74272286Sjkim *              DeviceName              - The "ResourceSource" name
75272286Sjkim *
76272286Sjkim * RETURN:      None
77272286Sjkim *
78272286Sjkim * DESCRIPTION: External Interface.
79272286Sjkim *              Save GPIO resource descriptor information.
80272286Sjkim *              Creates new GPIO info blocks, one for each pin defined by the
81272286Sjkim *              GPIO descriptor.
82272286Sjkim *
83272286Sjkim ******************************************************************************/
84272286Sjkim
85272286Sjkimvoid
86272286SjkimMpSaveGpioInfo (
87272286Sjkim    ACPI_PARSE_OBJECT       *Op,
88272286Sjkim    AML_RESOURCE            *Resource,
89272286Sjkim    UINT32                  PinCount,
90272286Sjkim    UINT16                  *PinList,
91272286Sjkim    char                    *DeviceName)
92272286Sjkim{
93272286Sjkim    ACPI_GPIO_INFO          *Info;
94272286Sjkim    UINT32                  i;
95272286Sjkim
96272286Sjkim
97272286Sjkim    /* Mapfile option enabled? */
98272286Sjkim
99272286Sjkim    if (!Gbl_MapfileFlag)
100272286Sjkim    {
101272286Sjkim        return;
102272286Sjkim    }
103272286Sjkim
104272286Sjkim    /* Create an info block for each pin defined in the descriptor */
105272286Sjkim
106272286Sjkim    for (i = 0; i < PinCount; i++)
107272286Sjkim    {
108272286Sjkim        Info = MpCreateGpioInfo (PinList[i], DeviceName);
109272286Sjkim
110272286Sjkim        Info->Op = Op;
111272286Sjkim        Info->DeviceName = DeviceName;
112272286Sjkim        Info->PinCount = PinCount;
113272286Sjkim        Info->PinIndex = i;
114272286Sjkim        Info->PinNumber = PinList[i];
115272286Sjkim        Info->Type = Resource->Gpio.ConnectionType;
116272286Sjkim        Info->Direction = (UINT8) (Resource->Gpio.IntFlags & 0x0003);       /* _IOR, for IO descriptor */
117272286Sjkim        Info->Polarity = (UINT8) ((Resource->Gpio.IntFlags >> 1) & 0x0003); /* _POL, for INT descriptor */
118272286Sjkim    }
119272286Sjkim}
120272286Sjkim
121272286Sjkim
122272286Sjkim/*******************************************************************************
123272286Sjkim *
124272286Sjkim * FUNCTION:    MpSaveSerialInfo
125272286Sjkim *
126272286Sjkim * PARAMETERS:  Resource                - A Serial resource descriptor
127272286Sjkim *              DeviceName              - The "ResourceSource" name.
128272286Sjkim *
129272286Sjkim * RETURN:      None
130272286Sjkim *
131272286Sjkim * DESCRIPTION: External Interface.
132272286Sjkim *              Save serial resource descriptor information.
133272286Sjkim *              Creates a new serial info block.
134272286Sjkim *
135272286Sjkim ******************************************************************************/
136272286Sjkim
137272286Sjkimvoid
138272286SjkimMpSaveSerialInfo (
139272286Sjkim    ACPI_PARSE_OBJECT       *Op,
140272286Sjkim    AML_RESOURCE            *Resource,
141272286Sjkim    char                    *DeviceName)
142272286Sjkim{
143272286Sjkim    ACPI_SERIAL_INFO        *Info;
144272286Sjkim    UINT16                  Address;
145272286Sjkim    UINT32                  Speed;
146272286Sjkim
147272286Sjkim
148272286Sjkim    /* Mapfile option enabled? */
149272286Sjkim
150272286Sjkim    if (!Gbl_MapfileFlag)
151272286Sjkim    {
152272286Sjkim        return;
153272286Sjkim    }
154272286Sjkim
155272286Sjkim    if (Resource->DescriptorType != ACPI_RESOURCE_NAME_SERIAL_BUS)
156272286Sjkim    {
157272286Sjkim        return;
158272286Sjkim    }
159272286Sjkim
160272286Sjkim    /* Extract address and speed from the resource descriptor */
161272286Sjkim
162272286Sjkim    switch (Resource->CommonSerialBus.Type)
163272286Sjkim    {
164272286Sjkim    case AML_RESOURCE_I2C_SERIALBUSTYPE:
165272286Sjkim
166272286Sjkim        Address = Resource->I2cSerialBus.SlaveAddress;
167272286Sjkim        Speed = Resource->I2cSerialBus.ConnectionSpeed;
168272286Sjkim        break;
169272286Sjkim
170272286Sjkim    case AML_RESOURCE_SPI_SERIALBUSTYPE:
171272286Sjkim
172272286Sjkim        Address = Resource->SpiSerialBus.DeviceSelection;
173272286Sjkim        Speed = Resource->SpiSerialBus.ConnectionSpeed;
174272286Sjkim        break;
175272286Sjkim
176272286Sjkim    case AML_RESOURCE_UART_SERIALBUSTYPE:
177272286Sjkim
178272286Sjkim        Address = 0;
179272286Sjkim        Speed = Resource->UartSerialBus.DefaultBaudRate;
180272286Sjkim        break;
181272286Sjkim
182272286Sjkim    default:    /* Invalid bus subtype */
183272286Sjkim        return;
184272286Sjkim    }
185272286Sjkim
186272286Sjkim    Info = MpCreateSerialInfo (DeviceName, Address);
187272286Sjkim
188272286Sjkim    Info->Op = Op;
189272286Sjkim    Info->DeviceName = DeviceName;
190272286Sjkim    Info->Resource = Resource;
191272286Sjkim    Info->Address = Address;
192272286Sjkim    Info->Speed = Speed;
193272286Sjkim}
194272286Sjkim
195272286Sjkim
196272286Sjkim/*******************************************************************************
197272286Sjkim *
198272286Sjkim * FUNCTION:    MpCreateGpioInfo
199272286Sjkim *
200272286Sjkim * PARAMETERS:  PinNumber               - GPIO pin number
201272286Sjkim *              DeviceName              - The "ResourceSource" name
202272286Sjkim *
203272286Sjkim * RETURN:      New GPIO info block.
204272286Sjkim *
205272286Sjkim * DESCRIPTION: Create a new GPIO info block and place it on the global list.
206272286Sjkim *              The list is sorted by GPIO device names first, and pin numbers
207272286Sjkim *              secondarily.
208272286Sjkim *
209272286Sjkim ******************************************************************************/
210272286Sjkim
211272286Sjkimstatic ACPI_GPIO_INFO *
212272286SjkimMpCreateGpioInfo (
213272286Sjkim    UINT16                  PinNumber,
214272286Sjkim    char                    *DeviceName)
215272286Sjkim{
216272286Sjkim    ACPI_GPIO_INFO          *Info;
217272286Sjkim    ACPI_GPIO_INFO          *NextGpio;
218272286Sjkim    ACPI_GPIO_INFO          *PrevGpio;
219281687Sjkim    char                    *Buffer;
220272286Sjkim
221272286Sjkim
222272286Sjkim    /*
223272286Sjkim     * Allocate a new info block and insert it into the global GPIO list
224272286Sjkim     * sorted by both source device name and then the pin number. There is
225272286Sjkim     * one block per pin.
226272286Sjkim     */
227281687Sjkim    Buffer = UtStringCacheCalloc (sizeof (ACPI_GPIO_INFO));
228281687Sjkim    Info = ACPI_CAST_PTR (ACPI_GPIO_INFO, Buffer);
229272286Sjkim
230272286Sjkim    NextGpio = Gbl_GpioList;
231272286Sjkim    PrevGpio = NULL;
232272286Sjkim    if (!Gbl_GpioList)
233272286Sjkim    {
234272286Sjkim        Gbl_GpioList = Info;
235272286Sjkim        Info->Next = NULL;
236272286Sjkim        return (Info);
237272286Sjkim    }
238272286Sjkim
239272286Sjkim    /* Sort on source DeviceName first */
240272286Sjkim
241272286Sjkim    while (NextGpio &&
242306536Sjkim        (strcmp (DeviceName, NextGpio->DeviceName) > 0))
243272286Sjkim    {
244272286Sjkim        PrevGpio = NextGpio;
245272286Sjkim        NextGpio = NextGpio->Next;
246272286Sjkim    }
247272286Sjkim
248272286Sjkim    /* Now sort on the PinNumber */
249272286Sjkim
250272286Sjkim    while (NextGpio &&
251306536Sjkim        (NextGpio->PinNumber < PinNumber) &&
252306536Sjkim        !strcmp (DeviceName, NextGpio->DeviceName))
253272286Sjkim    {
254272286Sjkim        PrevGpio = NextGpio;
255272286Sjkim        NextGpio = NextGpio->Next;
256272286Sjkim    }
257272286Sjkim
258272286Sjkim    /* Finish the list insertion */
259272286Sjkim
260272286Sjkim    if (PrevGpio)
261272286Sjkim    {
262272286Sjkim        PrevGpio->Next = Info;
263272286Sjkim    }
264272286Sjkim    else
265272286Sjkim    {
266272286Sjkim        Gbl_GpioList = Info;
267272286Sjkim    }
268272286Sjkim
269272286Sjkim    Info->Next = NextGpio;
270272286Sjkim    return (Info);
271272286Sjkim}
272272286Sjkim
273272286Sjkim
274272286Sjkim/*******************************************************************************
275272286Sjkim *
276272286Sjkim * FUNCTION:    MpCreateSerialInfo
277272286Sjkim *
278272286Sjkim * PARAMETERS:  DeviceName              - The "ResourceSource" name.
279272286Sjkim *              Address                 - Physical address for the device
280272286Sjkim *
281272286Sjkim * RETURN:      New Serial info block.
282272286Sjkim *
283272286Sjkim * DESCRIPTION: Create a new Serial info block and place it on the global list.
284272286Sjkim *              The list is sorted by Serial device names first, and addresses
285272286Sjkim *              secondarily.
286272286Sjkim *
287272286Sjkim ******************************************************************************/
288272286Sjkim
289272286Sjkimstatic ACPI_SERIAL_INFO *
290272286SjkimMpCreateSerialInfo (
291272286Sjkim    char                    *DeviceName,
292272286Sjkim    UINT16                  Address)
293272286Sjkim{
294272286Sjkim    ACPI_SERIAL_INFO        *Info;
295272286Sjkim    ACPI_SERIAL_INFO        *NextSerial;
296272286Sjkim    ACPI_SERIAL_INFO        *PrevSerial;
297281687Sjkim    char                    *Buffer;
298272286Sjkim
299272286Sjkim
300272286Sjkim    /*
301272286Sjkim     * Allocate a new info block and insert it into the global Serial list
302272286Sjkim     * sorted by both source device name and then the address.
303272286Sjkim     */
304281687Sjkim    Buffer = UtStringCacheCalloc (sizeof (ACPI_SERIAL_INFO));
305281687Sjkim    Info = ACPI_CAST_PTR (ACPI_SERIAL_INFO, Buffer);
306272286Sjkim
307272286Sjkim    NextSerial = Gbl_SerialList;
308272286Sjkim    PrevSerial = NULL;
309272286Sjkim    if (!Gbl_SerialList)
310272286Sjkim    {
311272286Sjkim        Gbl_SerialList = Info;
312272286Sjkim        Info->Next = NULL;
313272286Sjkim        return (Info);
314272286Sjkim    }
315272286Sjkim
316272286Sjkim    /* Sort on source DeviceName */
317272286Sjkim
318272286Sjkim    while (NextSerial &&
319306536Sjkim        (strcmp (DeviceName, NextSerial->DeviceName) > 0))
320272286Sjkim    {
321272286Sjkim        PrevSerial = NextSerial;
322272286Sjkim        NextSerial = NextSerial->Next;
323272286Sjkim    }
324272286Sjkim
325272286Sjkim    /* Now sort on the Address */
326272286Sjkim
327272286Sjkim    while (NextSerial &&
328272286Sjkim        (NextSerial->Address < Address) &&
329306536Sjkim        !strcmp (DeviceName, NextSerial->DeviceName))
330272286Sjkim    {
331272286Sjkim        PrevSerial = NextSerial;
332272286Sjkim        NextSerial = NextSerial->Next;
333272286Sjkim    }
334272286Sjkim
335272286Sjkim    /* Finish the list insertion */
336272286Sjkim
337272286Sjkim    if (PrevSerial)
338272286Sjkim    {
339272286Sjkim        PrevSerial->Next = Info;
340272286Sjkim    }
341272286Sjkim    else
342272286Sjkim    {
343272286Sjkim        Gbl_SerialList = Info;
344272286Sjkim    }
345272286Sjkim
346272286Sjkim    Info->Next = NextSerial;
347272286Sjkim    return (Info);
348272286Sjkim}
349