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