ASL_RESOURCE_NODE * RsDoFixedDmaDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_DMA)); Descriptor = Rnode->Buffer; Descriptor->FixedDma.DescriptorType = ACPI_RESOURCE_NAME_FIXED_DMA | ASL_RDESC_FIXED_DMA_SIZE; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* DMA Request Lines [WORD] (_DMA) */ Descriptor->FixedDma.RequestLines = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_DMA, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.RequestLines)); break; case 1: /* DMA Channel [WORD] (_TYP) */ Descriptor->FixedDma.Channels = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_DMATYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Channels)); break; case 2: /* Transfer Width [BYTE] (_SIZ) */ Descriptor->FixedDma.Width = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_XFERTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedDma.Width)); break; case 3: /* Descriptor Name (optional) */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: /* Ignore any extra nodes */ break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } return (Rnode); }
static void OpnAttachNameToNode ( ACPI_PARSE_OBJECT *Op) { ACPI_PARSE_OBJECT *Child = NULL; switch (Op->Asl.AmlOpcode) { case AML_DATA_REGION_OP: case AML_DEVICE_OP: case AML_EVENT_OP: case AML_EXTERNAL_OP: case AML_METHOD_OP: case AML_MUTEX_OP: case AML_REGION_OP: case AML_POWER_RESOURCE_OP: case AML_PROCESSOR_OP: case AML_THERMAL_ZONE_OP: case AML_NAME_OP: case AML_SCOPE_OP: Child = UtGetArg (Op, 0); break; case AML_ALIAS_OP: Child = UtGetArg (Op, 1); break; case AML_CREATE_BIT_FIELD_OP: case AML_CREATE_BYTE_FIELD_OP: case AML_CREATE_WORD_FIELD_OP: case AML_CREATE_DWORD_FIELD_OP: case AML_CREATE_QWORD_FIELD_OP: Child = UtGetArg (Op, 2); break; case AML_CREATE_FIELD_OP: Child = UtGetArg (Op, 3); break; case AML_BANK_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_FIELD_OP: return; default: return; } if (Child) { UtAttachNamepathToOwner (Op, Child); } }
ASL_RESOURCE_NODE * RsDoFixedIoDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_IO)); Descriptor = Rnode->Buffer; Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_FIXED_IO | ASL_RDESC_FIXED_IO_SIZE; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Base Address */ Descriptor->FixedIo.Address = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_BASEADDRESS, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.Address)); break; case 1: /* Length */ Descriptor->FixedIo.AddressLength = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedIo.AddressLength)); break; case 2: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } return (Rnode); }
ASL_RESOURCE_NODE * RsDoInterruptDescriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; AML_RESOURCE *Rover = NULL; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT16 StringLength = 0; UINT32 OptionIndex = 0; UINT32 CurrentByteOffset; UINT32 i; BOOLEAN HasResSourceIndex = FALSE; UINT8 ResSourceIndex = 0; UINT8 *ResSourceString = NULL; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; StringLength = RsGetStringDataLength (InitializerOp); /* Count the interrupt numbers */ for (i = 0; InitializerOp; i++) { InitializerOp = ASL_GET_PEER_NODE (InitializerOp); if (i <= 6) { if (i == 3 && InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { /* * ResourceSourceIndex was specified, always make room for * it, even if the ResourceSource was omitted. */ OptionIndex++; } continue; } OptionIndex += 4; } InitializerOp = Info->DescriptorTypeOp->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_EXTENDED_IRQ) + 1 + OptionIndex + StringLength); Descriptor = Rnode->Buffer; Descriptor->ExtendedIrq.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_IRQ; /* * Initial descriptor length -- may be enlarged if there are * optional fields present */ Descriptor->ExtendedIrq.ResourceLength = 2; /* Flags and table length byte */ Descriptor->ExtendedIrq.InterruptCount = 0; Rover = ACPI_CAST_PTR (AML_RESOURCE, (&(Descriptor->ExtendedIrq.Interrupts[0]))); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Resource Usage (Default: consumer (1) */ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 0, 1); break; case 1: /* Interrupt Type (or Mode - edge/level) */ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 1, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 1); break; case 2: /* Interrupt Level (or Polarity - Active high/low) */ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 2, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 2); break; case 3: /* Share Type - Default: exclusive (0) */ RsSetFlagBits (&Descriptor->ExtendedIrq.Flags, InitializerOp, 3, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Flags), 3); break; case 4: /* ResSourceIndex [Optional Field - BYTE] */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { HasResSourceIndex = TRUE; ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; } break; case 5: /* ResSource [Optional Field - STRING] */ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && (InitializerOp->Asl.Value.String)) { if (StringLength) { ResSourceString = (UINT8 *) InitializerOp->Asl.Value.String; } /* ResourceSourceIndex must also be valid */ if (!HasResSourceIndex) { AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, InitializerOp, NULL); } } #if 0 /* * Not a valid ResourceSource, ResourceSourceIndex must also * be invalid */ else if (HasResSourceIndex) { AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, InitializerOp, NULL); } #endif break; case 6: /* ResourceTag */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; default: /* * Interrupt Numbers come through here, repeatedly */ /* Maximum 255 interrupts allowed for this descriptor */ if (Descriptor->ExtendedIrq.InterruptCount == 255) { AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST, InitializerOp, NULL); return (Rnode); } /* Each interrupt number must be a 32-bit value */ if (InitializerOp->Asl.Value.Integer > ACPI_UINT32_MAX) { AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_NUMBER, InitializerOp, NULL); } /* Save the integer and move pointer to the next one */ Rover->DwordItem = (UINT32) InitializerOp->Asl.Value.Integer; Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->DwordItem), 4); Descriptor->ExtendedIrq.InterruptCount++; Descriptor->ExtendedIrq.ResourceLength += 4; /* Case 7: First interrupt number in list */ if (i == 7) { if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) { /* Must be at least one interrupt */ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, InitializerOp, NULL); } /* Check now for duplicates in list */ RsCheckListForDuplicates (InitializerOp); /* Create a named field at the start of the list */ RsCreateDwordField (InitializerOp, ACPI_RESTAG_INTERRUPT, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0])); } } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Add optional ResSourceIndex if present */ if (HasResSourceIndex) { Rover->ByteItem = ResSourceIndex; Rover = ACPI_ADD_PTR (AML_RESOURCE, &(Rover->ByteItem), 1); Descriptor->ExtendedIrq.ResourceLength += 1; } /* Add optional ResSource string if present */ if (StringLength && ResSourceString) { strcpy ((char *) Rover, (char *) ResSourceString); Rover = ACPI_ADD_PTR ( AML_RESOURCE, &(Rover->ByteItem), StringLength); Descriptor->ExtendedIrq.ResourceLength = (UINT16) (Descriptor->ExtendedIrq.ResourceLength + StringLength); } Rnode->BufferLength = (ASL_RESDESC_OFFSET (ExtendedIrq.Interrupts[0]) - ASL_RESDESC_OFFSET (ExtendedIrq.DescriptorType)) + OptionIndex + StringLength; return (Rnode); }
ASL_RESOURCE_NODE * RsDoGeneralRegisterDescriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 CurrentByteOffset; UINT32 i; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_GENERIC_REGISTER)); Descriptor = Rnode->Buffer; Descriptor->GenericReg.DescriptorType = ACPI_RESOURCE_NAME_GENERIC_REGISTER; Descriptor->GenericReg.ResourceLength = 12; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Address space */ Descriptor->GenericReg.AddressSpaceId = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_ADDRESSSPACE, CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AddressSpaceId)); break; case 1: /* Register Bit Width */ Descriptor->GenericReg.BitWidth = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITWIDTH, CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitWidth)); break; case 2: /* Register Bit Offset */ Descriptor->GenericReg.BitOffset = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_REGISTERBITOFFSET, CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.BitOffset)); break; case 3: /* Register Address */ Descriptor->GenericReg.Address = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_ADDRESS, CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.Address)); break; case 4: /* Access Size (ACPI 3.0) */ Descriptor->GenericReg.AccessSize = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_ACCESSSIZE, CurrentByteOffset + ASL_RESDESC_OFFSET (GenericReg.AccessSize)); if (Descriptor->GenericReg.AddressSpaceId == ACPI_ADR_SPACE_PLATFORM_COMM) { break; } if (Descriptor->GenericReg.AccessSize > AML_FIELD_ACCESS_QWORD) { AslError (ASL_ERROR, ASL_MSG_INVALID_ACCESS_SIZE, InitializerOp, NULL); } break; case 5: /* ResourceTag (ACPI 3.0b) */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } return (Rnode); }
ASL_RESOURCE_NODE * RsDoQwordSpaceDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ACPI_PARSE_OBJECT *MinOp = NULL; ACPI_PARSE_OBJECT *MaxOp = NULL; ACPI_PARSE_OBJECT *LengthOp = NULL; ACPI_PARSE_OBJECT *GranOp = NULL; ASL_RESOURCE_NODE *Rnode; UINT8 *OptionalFields; UINT16 StringLength = 0; UINT32 OptionIndex = 0; UINT32 i; BOOLEAN ResSourceIndex = FALSE; InitializerOp = Op->Asl.Child; StringLength = RsGetStringDataLength (InitializerOp); Rnode = RsAllocateResourceNode ( sizeof (AML_RESOURCE_ADDRESS64) + 1 + StringLength); Descriptor = Rnode->Buffer; Descriptor->Address64.DescriptorType = ACPI_RESOURCE_NAME_ADDRESS64; /* * Initial descriptor length -- may be enlarged if there are * optional fields present */ OptionalFields = ((UINT8 *) Descriptor) + sizeof (AML_RESOURCE_ADDRESS64); Descriptor->Address64.ResourceLength = (UINT16) (sizeof (AML_RESOURCE_ADDRESS64) - sizeof (AML_RESOURCE_LARGE_HEADER)); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Resource Type */ Descriptor->Address64.ResourceType = (UINT8) InitializerOp->Asl.Value.Integer; break; case 1: /* Resource Usage */ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 0, 1); break; case 2: /* DecodeType */ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 1, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 1); break; case 3: /* MinType */ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 2, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 2); break; case 4: /* MaxType */ RsSetFlagBits (&Descriptor->Address64.Flags, InitializerOp, 3, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Flags), 3); break; case 5: /* Type-Specific flags */ Descriptor->Address64.SpecificFlags = (UINT8) InitializerOp->Asl.Value.Integer; break; case 6: /* Address Granularity */ Descriptor->Address64.Granularity = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Granularity)); GranOp = InitializerOp; break; case 7: /* Min Address */ Descriptor->Address64.Minimum = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Minimum)); MinOp = InitializerOp; break; case 8: /* Max Address */ Descriptor->Address64.Maximum = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.Maximum)); MaxOp = InitializerOp; break; case 9: /* Translation Offset */ Descriptor->Address64.TranslationOffset = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.TranslationOffset)); break; case 10: /* Address Length */ Descriptor->Address64.AddressLength = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (Address64.AddressLength)); LengthOp = InitializerOp; break; case 11: /* ResSourceIndex [Optional Field - BYTE] */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { OptionalFields[0] = (UINT8) InitializerOp->Asl.Value.Integer; OptionIndex++; Descriptor->Address64.ResourceLength++; ResSourceIndex = TRUE; } break; case 12: /* ResSource [Optional Field - STRING] */ if ((InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && (InitializerOp->Asl.Value.String)) { if (StringLength) { Descriptor->Address64.ResourceLength = (UINT16) (Descriptor->Address64.ResourceLength + StringLength); strcpy ((char *) &OptionalFields[OptionIndex], InitializerOp->Asl.Value.String); /* ResourceSourceIndex must also be valid */ if (!ResSourceIndex) { AslError (ASL_ERROR, ASL_MSG_RESOURCE_INDEX, InitializerOp, NULL); } } } #if 0 /* * Not a valid ResourceSource, ResourceSourceIndex must also * be invalid */ else if (ResSourceIndex) { AslError (ASL_ERROR, ASL_MSG_RESOURCE_SOURCE, InitializerOp, NULL); } #endif break; case 13: /* ResourceTag */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Validate the Min/Max/Len/Gran values */ RsLargeAddressCheck ( Descriptor->Address64.Minimum, Descriptor->Address64.Maximum, Descriptor->Address64.AddressLength, Descriptor->Address64.Granularity, Descriptor->Address64.Flags, MinOp, MaxOp, LengthOp, GranOp, Op); Rnode->BufferLength = sizeof (AML_RESOURCE_ADDRESS64) + OptionIndex + StringLength; return (Rnode); }
ASL_RESOURCE_NODE * RsDoDmaDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 i; UINT8 DmaChannelMask = 0; UINT8 DmaChannels = 0; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_DMA)); Descriptor = Rnode->Buffer; Descriptor->Dma.DescriptorType = ACPI_RESOURCE_NAME_DMA | ASL_RDESC_DMA_SIZE; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* DMA type */ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 5, 0); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_DMATYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 5, 2); break; case 1: /* Bus Master */ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 2, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_BUSMASTER, CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 2); break; case 2: /* Xfer Type (transfer width) */ RsSetFlagBits (&Descriptor->Dma.Flags, InitializerOp, 0, 0); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_XFERTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.Flags), 0, 2); break; case 3: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: /* All DMA channel bytes are handled here, after flags and name */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { /* Up to 8 channels can be specified in the list */ DmaChannels++; if (DmaChannels > 8) { AslError (ASL_ERROR, ASL_MSG_DMA_LIST, InitializerOp, NULL); return (Rnode); } /* Only DMA channels 0-7 are allowed (mask is 8 bits) */ if (InitializerOp->Asl.Value.Integer > 7) { AslError (ASL_ERROR, ASL_MSG_DMA_CHANNEL, InitializerOp, NULL); } /* Build the mask */ DmaChannelMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer)); } if (i == 4) /* case 4: First DMA byte */ { /* Check now for duplicates in list */ RsCheckListForDuplicates (InitializerOp); /* Create a named field at the start of the list */ RsCreateByteField (InitializerOp, ACPI_RESTAG_DMA, CurrentByteOffset + ASL_RESDESC_OFFSET (Dma.DmaChannelMask)); } break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Now we can set the channel mask */ Descriptor->Dma.DmaChannelMask = DmaChannelMask; return (Rnode); }
ASL_RESOURCE_NODE * RsDoIrqNoFlagsDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT16 IrqMask = 0; UINT32 Interrupts = 0; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ_NOFLAGS)); Descriptor = Rnode->Buffer; Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ | ASL_RDESC_IRQ_SIZE; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: /* IRQ bytes are handled here, after the flags and name */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { /* Up to 16 interrupts can be specified in the list */ Interrupts++; if (Interrupts > 16) { AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST, InitializerOp, NULL); return (Rnode); } /* Only interrupts 0-15 are allowed (mask is 16 bits) */ if (InitializerOp->Asl.Value.Integer > 15) { AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER, InitializerOp, NULL); } else { IrqMask |= (1 << ((UINT8) InitializerOp->Asl.Value.Integer)); } } /* Case 1: First IRQ value in list */ if (i == 1) { /* Check now for duplicates in list */ RsCheckListForDuplicates (InitializerOp); /* Create a named field at the start of the list */ RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT, CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask)); } break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Now we can set the interrupt mask */ Descriptor->Irq.IrqMask = IrqMask; return (Rnode); }
ASL_RESOURCE_NODE * RsDoIrqDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 Interrupts = 0; UINT16 IrqMask = 0; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IRQ)); /* Length = 3 (with flag byte) */ Descriptor = Rnode->Buffer; Descriptor->Irq.DescriptorType = ACPI_RESOURCE_NAME_IRQ | (ASL_RDESC_IRQ_SIZE + 0x01); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Interrupt Type (or Mode - edge/level) */ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 0, 1); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 0); break; case 1: /* Interrupt Level (or Polarity - Active high/low) */ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 3, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTLEVEL, CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 3); break; case 2: /* Share Type - Default: exclusive (0) */ RsSetFlagBits (&Descriptor->Irq.Flags, InitializerOp, 4, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.Flags), 4); break; case 3: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: /* All IRQ bytes are handled here, after the flags and name */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { /* Up to 16 interrupts can be specified in the list */ Interrupts++; if (Interrupts > 16) { AslError (ASL_ERROR, ASL_MSG_INTERRUPT_LIST, InitializerOp, NULL); return (Rnode); } /* Only interrupts 0-15 are allowed (mask is 16 bits) */ if (InitializerOp->Asl.Value.Integer > 15) { AslError (ASL_ERROR, ASL_MSG_INTERRUPT_NUMBER, InitializerOp, NULL); } else { IrqMask |= (1 << (UINT8) InitializerOp->Asl.Value.Integer); } } /* Case 4: First IRQ value in list */ if (i == 4) { /* Check now for duplicates in list */ RsCheckListForDuplicates (InitializerOp); /* Create a named field at the start of the list */ RsCreateWordField (InitializerOp, ACPI_RESTAG_INTERRUPT, CurrentByteOffset + ASL_RESDESC_OFFSET (Irq.IrqMask)); } break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Now we can set the channel mask */ Descriptor->Irq.IrqMask = IrqMask; return (Rnode); }
ASL_RESOURCE_NODE * RsDoIoDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ACPI_PARSE_OBJECT *MinOp = NULL; ACPI_PARSE_OBJECT *MaxOp = NULL; ACPI_PARSE_OBJECT *LengthOp = NULL; ACPI_PARSE_OBJECT *AlignOp = NULL; ASL_RESOURCE_NODE *Rnode; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_IO)); Descriptor = Rnode->Buffer; Descriptor->Io.DescriptorType = ACPI_RESOURCE_NAME_IO | ASL_RDESC_IO_SIZE; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Decode size */ RsSetFlagBits (&Descriptor->Io.Flags, InitializerOp, 0, 1); RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE, CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Flags), 0); break; case 1: /* Min Address */ Descriptor->Io.Minimum = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_MINADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Minimum)); MinOp = InitializerOp; break; case 2: /* Max Address */ Descriptor->Io.Maximum = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_MAXADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Maximum)); MaxOp = InitializerOp; break; case 3: /* Alignment */ Descriptor->Io.Alignment = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_ALIGNMENT, CurrentByteOffset + ASL_RESDESC_OFFSET (Io.Alignment)); AlignOp = InitializerOp; break; case 4: /* Length */ Descriptor->Io.AddressLength = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (Io.AddressLength)); LengthOp = InitializerOp; break; case 5: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Validate the Min/Max/Len/Align values */ RsSmallAddressCheck (ACPI_RESOURCE_NAME_IO, Descriptor->Io.Minimum, Descriptor->Io.Maximum, Descriptor->Io.AddressLength, Descriptor->Io.Alignment, MinOp, MaxOp, LengthOp, AlignOp, Op); return (Rnode); }
ASL_RESOURCE_NODE * RsDoExtendedSpaceDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ACPI_PARSE_OBJECT *MinOp = NULL; ACPI_PARSE_OBJECT *MaxOp = NULL; ACPI_PARSE_OBJECT *LengthOp = NULL; ACPI_PARSE_OBJECT *GranOp = NULL; ASL_RESOURCE_NODE *Rnode; UINT16 StringLength = 0; UINT32 i; InitializerOp = Op->Asl.Child; StringLength = RsGetStringDataLength (InitializerOp); Rnode = RsAllocateResourceNode ( sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) + 1 + StringLength); Descriptor = Rnode->Buffer; Descriptor->ExtAddress64.DescriptorType = ACPI_RESOURCE_NAME_EXTENDED_ADDRESS64; Descriptor->ExtAddress64.RevisionID = AML_RESOURCE_EXTENDED_ADDRESS_REVISION; Descriptor->ExtAddress64.ResourceLength = (UINT16) (sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) - sizeof (AML_RESOURCE_LARGE_HEADER)); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Resource Type */ Descriptor->ExtAddress64.ResourceType = (UINT8) InitializerOp->Asl.Value.Integer; break; case 1: /* Resource Usage */ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 0, 1); break; case 2: /* DecodeType */ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 1, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_DECODE, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 1); break; case 3: /* MinType */ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 2, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_MINTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 2); break; case 4: /* MaxType */ RsSetFlagBits (&Descriptor->ExtAddress64.Flags, InitializerOp, 3, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_MAXTYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Flags), 3); break; case 5: /* Type-Specific flags */ Descriptor->ExtAddress64.SpecificFlags = (UINT8) InitializerOp->Asl.Value.Integer; break; case 6: /* Address Granularity */ Descriptor->ExtAddress64.Granularity = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_GRANULARITY, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Granularity)); GranOp = InitializerOp; break; case 7: /* Min Address */ Descriptor->ExtAddress64.Minimum = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_MINADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Minimum)); MinOp = InitializerOp; break; case 8: /* Max Address */ Descriptor->ExtAddress64.Maximum = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_MAXADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.Maximum)); MaxOp = InitializerOp; break; case 9: /* Translation Offset */ Descriptor->ExtAddress64.TranslationOffset = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_TRANSLATION, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TranslationOffset)); break; case 10: /* Address Length */ Descriptor->ExtAddress64.AddressLength = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.AddressLength)); LengthOp = InitializerOp; break; case 11: /* Type-Specific Attributes */ Descriptor->ExtAddress64.TypeSpecific = InitializerOp->Asl.Value.Integer; RsCreateQwordField (InitializerOp, ACPI_RESTAG_TYPESPECIFICATTRIBUTES, CurrentByteOffset + ASL_RESDESC_OFFSET (ExtAddress64.TypeSpecific)); break; case 12: /* ResourceTag */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Validate the Min/Max/Len/Gran values */ RsLargeAddressCheck ( Descriptor->ExtAddress64.Minimum, Descriptor->ExtAddress64.Maximum, Descriptor->ExtAddress64.AddressLength, Descriptor->ExtAddress64.Granularity, Descriptor->ExtAddress64.Flags, MinOp, MaxOp, LengthOp, GranOp, Op); Rnode->BufferLength = sizeof (AML_RESOURCE_EXTENDED_ADDRESS64) + StringLength; return (Rnode); }
ASL_RESOURCE_NODE * RsDoSpiSerialBusDescriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; char *ResourceSource = NULL; UINT8 *VendorData = NULL; UINT16 ResSourceLength; UINT16 VendorLength; UINT16 DescriptorSize; UINT32 CurrentByteOffset; UINT32 i; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; /* * Calculate lengths for fields that have variable length: * 1) Resource Source string * 2) Vendor Data buffer */ ResSourceLength = RsGetStringDataLength (InitializerOp); VendorLength = RsGetBufferDataLength (InitializerOp); DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_SPI_SERIALBUS) + ResSourceLength + VendorLength; /* Allocate the local resource node and initialize */ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER)); Descriptor = Rnode->Buffer; Descriptor->SpiSerialBus.ResourceLength = DescriptorSize; Descriptor->SpiSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; Descriptor->SpiSerialBus.RevisionId = AML_RESOURCE_SPI_REVISION; Descriptor->SpiSerialBus.TypeRevisionId = AML_RESOURCE_SPI_TYPE_REVISION; Descriptor->SpiSerialBus.Type = AML_RESOURCE_SPI_SERIALBUSTYPE; Descriptor->SpiSerialBus.TypeDataLength = AML_RESOURCE_SPI_MIN_DATA_LEN + VendorLength; /* Build pointers to optional areas */ VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_SPI_SERIALBUS)); ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); DbgPrint (ASL_DEBUG_OUTPUT, "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, TypLen: %.2X\n", "SpiSerialBus", Descriptor->SpiSerialBus.ResourceLength, (UINT16) sizeof (AML_RESOURCE_SPI_SERIALBUS), ResSourceLength, VendorLength, Descriptor->SpiSerialBus.TypeDataLength); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Device Selection [WORD] (_ADR) */ Descriptor->SpiSerialBus.DeviceSelection = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_ADDRESS, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DeviceSelection)); break; case 1: /* Device Polarity [Flag] (_DPL) */ RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 1, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_DEVICEPOLARITY, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 1); break; case 2: /* Wire Mode [Flag] (_MOD) */ RsSetFlagBits16 (&Descriptor->SpiSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_MODE, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.TypeSpecificFlags), 0); break; case 3: /* Device Bit Length [BYTE] (_LEN) */ Descriptor->SpiSerialBus.DataBitLength = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.DataBitLength)); break; case 4: /* Slave Mode [Flag] (_SLV) */ RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 0, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.Flags), 0); break; case 5: /* Connection Speed [DWORD] (_SPE) */ Descriptor->SpiSerialBus.ConnectionSpeed = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ConnectionSpeed)); break; case 6: /* Clock Polarity [BYTE] (_POL) */ Descriptor->SpiSerialBus.ClockPolarity = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_POLARITY, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPolarity)); break; case 7: /* Clock Phase [BYTE] (_PHA) */ Descriptor->SpiSerialBus.ClockPhase = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_PHASE, CurrentByteOffset + ASL_RESDESC_OFFSET (SpiSerialBus.ClockPhase)); break; case 8: /* ResSource [Optional Field - STRING] */ if (ResSourceLength) { /* Copy string to the descriptor */ strcpy (ResourceSource, InitializerOp->Asl.Value.String); } break; case 9: /* Resource Index */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { Descriptor->SpiSerialBus.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; } break; case 10: /* Resource Usage (consumer/producer) */ RsSetFlagBits (&Descriptor->SpiSerialBus.Flags, InitializerOp, 1, 1); break; case 11: /* Resource Tag (Descriptor Name) */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; case 12: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ RsGetVendorData (InitializerOp, VendorData, CurrentByteOffset + sizeof (AML_RESOURCE_SPI_SERIALBUS)); break; default: /* Ignore any extra nodes */ break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); return (Rnode); }
ASL_RESOURCE_NODE * RsDoGpioIoDescriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; char *ResourceSource = NULL; UINT8 *VendorData = NULL; UINT16 *InterruptList = NULL; UINT16 *PinList = NULL; UINT16 ResSourceLength; UINT16 VendorLength; UINT16 InterruptLength; UINT16 DescriptorSize; UINT32 CurrentByteOffset; UINT32 PinCount = 0; UINT32 i; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; /* * Calculate lengths for fields that have variable length: * 1) Resource Source string * 2) Vendor Data buffer * 3) PIN (interrupt) list */ ResSourceLength = RsGetStringDataLength (InitializerOp); VendorLength = RsGetBufferDataLength (InitializerOp); InterruptLength = RsGetInterruptDataLength (InitializerOp); PinList = InterruptList; DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_GPIO) + ResSourceLength + VendorLength + InterruptLength; /* Allocate the local resource node and initialize */ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER)); Descriptor = Rnode->Buffer; Descriptor->Gpio.ResourceLength = DescriptorSize; Descriptor->Gpio.DescriptorType = ACPI_RESOURCE_NAME_GPIO; Descriptor->Gpio.RevisionId = AML_RESOURCE_GPIO_REVISION; Descriptor->Gpio.ConnectionType = AML_RESOURCE_GPIO_TYPE_IO; /* Build pointers to optional areas */ InterruptList = ACPI_ADD_PTR (UINT16, Descriptor, sizeof (AML_RESOURCE_GPIO)); PinList = InterruptList; ResourceSource = ACPI_ADD_PTR (char, InterruptList, InterruptLength); VendorData = ACPI_ADD_PTR (UINT8, ResourceSource, ResSourceLength); /* Setup offsets within the descriptor */ Descriptor->Gpio.PinTableOffset = (UINT16) ACPI_PTR_DIFF (InterruptList, Descriptor); Descriptor->Gpio.ResSourceOffset = (UINT16) ACPI_PTR_DIFF (ResourceSource, Descriptor); DbgPrint (ASL_DEBUG_OUTPUT, "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, IntLen: %.2X\n", "GpioIo", Descriptor->Gpio.ResourceLength, (UINT16) sizeof (AML_RESOURCE_GPIO), ResSourceLength, VendorLength, InterruptLength); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Share Type [Flags] (_SHR) */ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 3, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_INTERRUPTSHARE, CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 3); break; case 1: /* Pin Config [BYTE] (_PPI) */ Descriptor->Gpio.PinConfig = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_PINCONFIG, CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.PinConfig)); break; case 2: /* Debounce Timeout [WORD] (_DBT) */ Descriptor->Gpio.DebounceTimeout = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_DEBOUNCETIME, CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DebounceTimeout)); break; case 3: /* Drive Strength [WORD] (_DRS) */ Descriptor->Gpio.DriveStrength = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_DRIVESTRENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.DriveStrength)); break; case 4: /* I/O Restriction [Flag] (_IOR) */ RsSetFlagBits16 (&Descriptor->Gpio.IntFlags, InitializerOp, 0, 0); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_IORESTRICTION, CurrentByteOffset + ASL_RESDESC_OFFSET (Gpio.IntFlags), 0, 2); break; case 5: /* ResSource [Optional Field - STRING] */ if (ResSourceLength) { /* Copy string to the descriptor */ strcpy (ResourceSource, InitializerOp->Asl.Value.String); } break; case 6: /* Resource Index */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { Descriptor->Gpio.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; } break; case 7: /* Resource Usage (consumer/producer) */ RsSetFlagBits16 (&Descriptor->Gpio.Flags, InitializerOp, 0, 1); break; case 8: /* Resource Tag (Descriptor Name) */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; case 9: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ /* * Always set the VendorOffset even if there is no Vendor Data. * This field is required in order to calculate the length * of the ResourceSource at runtime. */ Descriptor->Gpio.VendorOffset = (UINT16) ACPI_PTR_DIFF (VendorData, Descriptor); if (RsGetVendorData (InitializerOp, VendorData, (CurrentByteOffset + Descriptor->Gpio.VendorOffset))) { Descriptor->Gpio.VendorLength = VendorLength; } break; default: /* * PINs come through here, repeatedly. Each PIN must be a DWORD. * NOTE: there is no "length" field for this, so from ACPI spec: * The number of pins in the table can be calculated from: * PinCount = (Resource Source Name Offset - Pin Table Offset) / 2 * (implies resource source must immediately follow the pin list.) * Name: _PIN */ *InterruptList = (UINT16) InitializerOp->Asl.Value.Integer; InterruptList++; PinCount++; /* Case 10: First interrupt number in list */ if (i == 10) { if (InitializerOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) { /* Must be at least one interrupt */ AslError (ASL_ERROR, ASL_MSG_EX_INTERRUPT_LIST_MIN, InitializerOp, NULL); } /* Check now for duplicates in list */ RsCheckListForDuplicates (InitializerOp); /* Create a named field at the start of the list */ RsCreateDwordField (InitializerOp, ACPI_RESTAG_PIN, CurrentByteOffset + Descriptor->Gpio.PinTableOffset); } break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } MpSaveGpioInfo (Info->MappingOp, Descriptor, PinCount, PinList, ResourceSource); return (Rnode); }
ASL_RESOURCE_NODE * RsDoUartSerialBusDescriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; char *ResourceSource = NULL; UINT8 *VendorData = NULL; UINT16 ResSourceLength; UINT16 VendorLength; UINT16 DescriptorSize; UINT32 CurrentByteOffset; UINT32 i; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; /* * Calculate lengths for fields that have variable length: * 1) Resource Source string * 2) Vendor Data buffer */ ResSourceLength = RsGetStringDataLength (InitializerOp); VendorLength = RsGetBufferDataLength (InitializerOp); DescriptorSize = ACPI_AML_SIZE_LARGE (AML_RESOURCE_UART_SERIALBUS) + ResSourceLength + VendorLength; /* Allocate the local resource node and initialize */ Rnode = RsAllocateResourceNode (DescriptorSize + sizeof (AML_RESOURCE_LARGE_HEADER)); Descriptor = Rnode->Buffer; Descriptor->UartSerialBus.ResourceLength = DescriptorSize; Descriptor->UartSerialBus.DescriptorType = ACPI_RESOURCE_NAME_SERIAL_BUS; Descriptor->UartSerialBus.RevisionId = AML_RESOURCE_UART_REVISION; Descriptor->UartSerialBus.TypeRevisionId = AML_RESOURCE_UART_TYPE_REVISION; Descriptor->UartSerialBus.Type = AML_RESOURCE_UART_SERIALBUSTYPE; Descriptor->UartSerialBus.TypeDataLength = AML_RESOURCE_UART_MIN_DATA_LEN + VendorLength; /* Build pointers to optional areas */ VendorData = ACPI_ADD_PTR (UINT8, Descriptor, sizeof (AML_RESOURCE_UART_SERIALBUS)); ResourceSource = ACPI_ADD_PTR (char, VendorData, VendorLength); DbgPrint (ASL_DEBUG_OUTPUT, "%16s - Actual: %.2X, Base: %.2X, ResLen: %.2X, VendLen: %.2X, TypLen: %.2X\n", "UartSerialBus", Descriptor->UartSerialBus.ResourceLength, (UINT16) sizeof (AML_RESOURCE_UART_SERIALBUS), ResSourceLength, VendorLength, Descriptor->UartSerialBus.TypeDataLength); /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Connection Speed (Baud Rate) [DWORD] (_SPE) */ Descriptor->UartSerialBus.DefaultBaudRate = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_SPEED, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.DefaultBaudRate)); break; case 1: /* Bits Per Byte [Flags] (_LEN) */ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 4, 3); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 4, 3); break; case 2: /* Stop Bits [Flags] (_STB) */ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 2, 1); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_STOPBITS, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 2, 2); break; case 3: /* Lines In Use [BYTE] (_LIN) */ Descriptor->UartSerialBus.LinesEnabled = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_LINE, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.LinesEnabled)); break; case 4: /* Endianness [Flag] (_END) */ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 7, 0); RsCreateBitField (InitializerOp, ACPI_RESTAG_ENDIANNESS, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 7); break; case 5: /* Parity [BYTE] (_PAR) */ Descriptor->UartSerialBus.Parity = (UINT8) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_PARITY, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Parity)); break; case 6: /* Flow Control [Flags] (_FLC) */ RsSetFlagBits16 (&Descriptor->UartSerialBus.TypeSpecificFlags, InitializerOp, 0, 0); RsCreateMultiBitField (InitializerOp, ACPI_RESTAG_FLOWCONTROL, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TypeSpecificFlags), 0, 2); break; case 7: /* Rx Buffer Size [WORD] (_RXL) */ Descriptor->UartSerialBus.RxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_RX, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.RxFifoSize)); break; case 8: /* Tx Buffer Size [WORD] (_TXL) */ Descriptor->UartSerialBus.TxFifoSize = (UINT16) InitializerOp->Asl.Value.Integer; RsCreateWordField (InitializerOp, ACPI_RESTAG_LENGTH_TX, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.TxFifoSize)); break; case 9: /* ResSource [Optional Field - STRING] */ if (ResSourceLength) { /* Copy string to the descriptor */ strcpy (ResourceSource, InitializerOp->Asl.Value.String); } break; case 10: /* Resource Index */ if (InitializerOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { Descriptor->UartSerialBus.ResSourceIndex = (UINT8) InitializerOp->Asl.Value.Integer; } break; case 11: /* Resource Usage (consumer/producer) */ RsSetFlagBits (&Descriptor->UartSerialBus.Flags, InitializerOp, 1, 1); /* * Slave Mode [Flag] (_SLV) * * Note: There is no SlaveMode argument to the UartSerialBus macro, but * we add this name anyway to allow the flag to be set by ASL in the * rare case where there is a slave mode associated with the UART. */ RsCreateBitField (InitializerOp, ACPI_RESTAG_SLAVEMODE, CurrentByteOffset + ASL_RESDESC_OFFSET (UartSerialBus.Flags), 0); break; case 12: /* Resource Tag (Descriptor Name) */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; case 13: /* Vendor Data (Optional - Buffer of BYTEs) (_VEN) */ RsGetVendorData (InitializerOp, VendorData, CurrentByteOffset + sizeof (AML_RESOURCE_UART_SERIALBUS)); break; default: /* Ignore any extra nodes */ break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } MpSaveSerialInfo (Info->MappingOp, Descriptor, ResourceSource); return (Rnode); }
ASL_RESOURCE_NODE * RsDoMemory32FixedDescriptor ( ACPI_PARSE_OBJECT *Op, UINT32 CurrentByteOffset) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ASL_RESOURCE_NODE *Rnode; UINT32 i; InitializerOp = Op->Asl.Child; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_FIXED_MEMORY32)); Descriptor = Rnode->Buffer; Descriptor->FixedMemory32.DescriptorType = ACPI_RESOURCE_NAME_FIXED_MEMORY32; Descriptor->FixedMemory32.ResourceLength = 9; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Read/Write type */ RsSetFlagBits (&Descriptor->FixedMemory32.Flags, InitializerOp, 0, 1); RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Flags), 0); break; case 1: /* Address */ Descriptor->FixedMemory32.Address = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_BASEADDRESS, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.Address)); break; case 2: /* Length */ Descriptor->FixedMemory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateByteField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (FixedMemory32.AddressLength)); break; case 3: /* Name */ UtAttachNamepathToOwner (Op, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } return (Rnode); }
ASL_RESOURCE_NODE * RsDoMemory32Descriptor ( ASL_RESOURCE_INFO *Info) { AML_RESOURCE *Descriptor; ACPI_PARSE_OBJECT *InitializerOp; ACPI_PARSE_OBJECT *MinOp = NULL; ACPI_PARSE_OBJECT *MaxOp = NULL; ACPI_PARSE_OBJECT *LengthOp = NULL; ACPI_PARSE_OBJECT *AlignOp = NULL; ASL_RESOURCE_NODE *Rnode; UINT32 CurrentByteOffset; UINT32 i; InitializerOp = Info->DescriptorTypeOp->Asl.Child; CurrentByteOffset = Info->CurrentByteOffset; Rnode = RsAllocateResourceNode (sizeof (AML_RESOURCE_MEMORY32)); Descriptor = Rnode->Buffer; Descriptor->Memory32.DescriptorType = ACPI_RESOURCE_NAME_MEMORY32; Descriptor->Memory32.ResourceLength = 17; /* Process all child initialization nodes */ for (i = 0; InitializerOp; i++) { switch (i) { case 0: /* Read/Write type */ RsSetFlagBits (&Descriptor->Memory32.Flags, InitializerOp, 0, 1); RsCreateBitField (InitializerOp, ACPI_RESTAG_READWRITETYPE, CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Flags), 0); break; case 1: /* Min Address */ Descriptor->Memory32.Minimum = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_MINADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Minimum)); MinOp = InitializerOp; break; case 2: /* Max Address */ Descriptor->Memory32.Maximum = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_MAXADDR, CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Maximum)); MaxOp = InitializerOp; break; case 3: /* Alignment */ Descriptor->Memory32.Alignment = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_ALIGNMENT, CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.Alignment)); AlignOp = InitializerOp; break; case 4: /* Length */ Descriptor->Memory32.AddressLength = (UINT32) InitializerOp->Asl.Value.Integer; RsCreateDwordField (InitializerOp, ACPI_RESTAG_LENGTH, CurrentByteOffset + ASL_RESDESC_OFFSET (Memory32.AddressLength)); LengthOp = InitializerOp; break; case 5: /* Name */ UtAttachNamepathToOwner (Info->DescriptorTypeOp, InitializerOp); break; default: AslError (ASL_ERROR, ASL_MSG_RESOURCE_LIST, InitializerOp, NULL); break; } InitializerOp = RsCompleteNodeAndGetNext (InitializerOp); } /* Validate the Min/Max/Len/Align values */ RsSmallAddressCheck (ACPI_RESOURCE_NAME_MEMORY32, Descriptor->Memory32.Minimum, Descriptor->Memory32.Maximum, Descriptor->Memory32.AddressLength, Descriptor->Memory32.Alignment, MinOp, MaxOp, LengthOp, AlignOp, Info->DescriptorTypeOp); return (Rnode); }