Exemple #1
0
status_t
get_irq_routing_table(acpi_handle busDeviceHandle, acpi_data *retBuffer)
{
    ACPI_STATUS status;

    status = AcpiGetIrqRoutingTable(busDeviceHandle, (ACPI_BUFFER*)retBuffer);
    if (status == AE_BUFFER_OVERFLOW)
        dprintf("evaluate_method: the passed buffer is too small!\n");

    return status == AE_OK ? B_OK : B_ERROR;
}
Exemple #2
0
void enumerateSystemBusses() {
	auto sb = getChild(ACPI_ROOT_OBJECT, "_SB_");
	for(auto child : getChildren(sb)) {
		auto id = getHardwareId(child);
		if(id != "PNP0A03" && id != "PNP0A08")
			continue;
		
		frigg::infoLogger() << "thor: Found PCI host bridge" << frigg::endLog;

		pci::RoutingInfo routing{*kernelAlloc};

		acpi::ScopedBuffer buffer;
		ACPICA_CHECK(AcpiGetIrqRoutingTable(child, buffer.get()));

		size_t offset = 0;
		while(true) {
			auto route = (ACPI_PCI_ROUTING_TABLE *)((char *)buffer.data() + offset);
			if(!route->Length)
				break;
			
			auto slot = route->Address >> 16;
			auto function = route->Address & 0xFFFF;
			assert(function == 0xFFFF);
			auto index = static_cast<pci::IrqIndex>(route->Pin + 1);
			if(!*route->Source) {
				frigg::infoLogger() << "    Route for slot " << slot
						<< ", " << nameOf(index) << ": "
						<< "GSI " << route->SourceIndex << frigg::endLog;

				configureIrq(route->SourceIndex, {TriggerMode::level, Polarity::low});
				auto pin = getGlobalSystemIrq(route->SourceIndex);
				routing.push({slot, index, pin});
			}else{
				frigg::infoLogger() << "    Route for slot " << slot
						<< ", " << nameOf(index) << ": " << (const char *)route->Source
						<< "[" << route->SourceIndex << "]" << frigg::endLog;

				assert(!route->SourceIndex);
				auto pin = configureRoute(const_cast<const char *>(route->Source));
				routing.push({slot, index, pin});
			}

			offset += route->Length;
		}

		pci::pciDiscover(routing);
	}
}
Exemple #3
0
int
acpi_pcib_attach(device_t dev, ACPI_BUFFER *prt, int busno)
{
    ACPI_STATUS status;
    int error;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    /*
     * Don't attach if we're not really there.
     *
     * XXX: This isn't entirely correct since we may be a PCI bus
     * on a hot-plug docking station, etc.
     */
    if (!acpi_DeviceIsPresent(dev))
	return_VALUE(ENXIO);

    /*
     * Get the PCI interrupt routing table for this bus.  If we can't
     * get it, this is not an error but may reduce functionality.  There
     * are several valid bridges in the field that do not have a _PRT, so
     * only warn about missing tables if bootverbose is set.
     */
    prt->Length = ACPI_ALLOCATE_BUFFER;
    status = AcpiGetIrqRoutingTable(acpi_get_handle(dev), prt);
    if (ACPI_FAILURE(status) && (bootverbose || status != AE_NOT_FOUND))
	device_printf(dev,
	    "could not get PCI interrupt routing table for %s - %s\n",
	    acpi_name(acpi_get_handle(dev)), AcpiFormatException(status));

    /*
     * Attach the PCI bus proper.
     */
    if (device_add_child(dev, "pci", busno) == NULL) {
	device_printf(device_get_parent(dev), "couldn't attach pci bus\n");
	return_VALUE(ENXIO);
    }

    /*
     * Now go scan the bus.
     */
    prt_walk_table(prt, prt_attach_devices, dev);

    error = bus_generic_attach(dev);
    return_VALUE(error);
}
static int
acpi_get_gsiv(dev_info_t *dip, ACPI_HANDLE pciobj, int devno, int ipin,
    int *pci_irqp, iflag_t *intr_flagp, acpi_psm_lnk_t *acpipsmlnkp)
{
	ACPI_BUFFER rb;
	ACPI_PCI_ROUTING_TABLE *prtp;
	int status;
	int dev_adr;

	/*
	 * Get the IRQ routing table
	 */
	rb.Pointer = NULL;
	rb.Length = ACPI_ALLOCATE_BUFFER;
	if (AcpiGetIrqRoutingTable(pciobj, &rb) != AE_OK) {
		return (ACPI_PSM_FAILURE);
	}

	status = ACPI_PSM_FAILURE;
	dev_adr = (devno << 16 | 0xffff);
	for (prtp = rb.Pointer; prtp->Length != 0; prtp = NEXT_PRT_ITEM(prtp)) {
		/* look until a matching dev/pin is found */
		if (dev_adr != prtp->Address || ipin != prtp->Pin)
			continue;

		/* NULL Source name means index is GSIV */
		if (*prtp->Source == 0) {
			intr_flagp->intr_el = INTR_EL_LEVEL;
			intr_flagp->intr_po = INTR_PO_ACTIVE_LOW;
			ASSERT(pci_irqp != NULL);
			*pci_irqp = prtp->SourceIndex;
			status = ACPI_PSM_SUCCESS;
		} else
			status = acpi_eval_lnk(dip, prtp->Source, pci_irqp,
			    intr_flagp, acpipsmlnkp);

		break;

	}

	AcpiOsFree(rb.Pointer);
	return (status);
}
Exemple #5
0
int
acpi_pcib_attach(device_t dev, ACPI_BUFFER *prt, int busno)
{
    device_t			child;
    ACPI_STATUS			status;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    if (!acpi_DeviceIsPresent(dev)) {
    	/* Caller should already have checked it */
	panic("%s device is not present", __func__);
    }

    ACPI_SERIAL_INIT(pcib);

    /*
     * Get the PCI interrupt routing table for this bus.  If we can't
     * get it, this is not an error but may reduce functionality.  There
     * are several valid bridges in the field that do not have a _PRT, so
     * only warn about missing tables if bootverbose is set.
     */
    prt->Length = ACPI_ALLOCATE_BUFFER;
    status = AcpiGetIrqRoutingTable(acpi_get_handle(dev), prt);
    if (ACPI_FAILURE(status) && (bootverbose || status != AE_NOT_FOUND))
	device_printf(dev,
	    "could not get PCI interrupt routing table for %s - %s\n",
	    acpi_name(acpi_get_handle(dev)), AcpiFormatException(status));

    /*
     * Attach the PCI bus proper.
     */
    if ((child = device_add_child(dev, "pci", busno)) == NULL) {
	device_printf(device_get_parent(dev), "couldn't attach pci bus\n");
	return_VALUE(ENXIO);
    }

    /*
     * Now go scan the bus.
     */
    prt_walk_table(prt, prt_attach_devices, dev);

    return_VALUE (bus_generic_attach(dev));
}
Exemple #6
0
static ACPI_STATUS
AcpiDbDeviceResources (
    ACPI_HANDLE             ObjHandle,
    UINT32                  NestingLevel,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_NAMESPACE_NODE     *PrtNode = NULL;
    ACPI_NAMESPACE_NODE     *CrsNode = NULL;
    ACPI_NAMESPACE_NODE     *PrsNode = NULL;
    ACPI_NAMESPACE_NODE     *AeiNode = NULL;
    char                    *ParentPath;
    ACPI_BUFFER             ReturnObj;
    ACPI_STATUS             Status;


    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
    ParentPath = AcpiNsGetExternalPathname (Node);
    if (!ParentPath)
    {
        return (AE_NO_MEMORY);
    }

    /* Get handles to the resource methods for this device */

    (void) AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &PrtNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__CRS, ACPI_CAST_PTR (ACPI_HANDLE, &CrsNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__PRS, ACPI_CAST_PTR (ACPI_HANDLE, &PrsNode));
    (void) AcpiGetHandle (Node, METHOD_NAME__AEI, ACPI_CAST_PTR (ACPI_HANDLE, &AeiNode));
    if (!PrtNode && !CrsNode && !PrsNode && !AeiNode)
    {
        goto Cleanup;   /* Nothing to do */
    }

    AcpiOsPrintf ("\nDevice: %s\n", ParentPath);

    /* Prepare for a return object of arbitrary size */

    ReturnObj.Pointer = AcpiGbl_DbBuffer;
    ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;


    /* _PRT */

    if (PrtNode)
    {
        AcpiOsPrintf ("Evaluating _PRT\n");

        Status = AcpiEvaluateObject (PrtNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _PRT: %s\n",
                AcpiFormatException (Status));
            goto GetCrs;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetIrqRoutingTable (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n",
                AcpiFormatException (Status));
            goto GetCrs;
        }

        AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer));
    }


    /* _CRS */

GetCrs:
    if (CrsNode)
    {
        AcpiOsPrintf ("Evaluating _CRS\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (CrsNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _CRS: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* This code is here to exercise the AcpiWalkResources interface */

        Status = AcpiWalkResources (Node, METHOD_NAME__CRS,
            AcpiDbResourceCallback, NULL);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiWalkResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* Get the _CRS resource list */

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetCurrentResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }

        /* Dump the _CRS resource list */

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE,
            ReturnObj.Pointer));

        /*
         * Perform comparison of original AML to newly created AML. This tests both
         * the AML->Resource conversion and the Resource->Aml conversion.
         */
        Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS);

        /* Execute _SRS with the resource list */

        Status = AcpiSetCurrentResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetPrs;
        }
    }


    /* _PRS */

GetPrs:
    if (PrsNode)
    {
        AcpiOsPrintf ("Evaluating _PRS\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (PrsNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _PRS: %s\n",
                AcpiFormatException (Status));
            goto GetAei;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetPossibleResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n",
                AcpiFormatException (Status));
            goto GetAei;
        }

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
    }


    /* _AEI */

GetAei:
    if (AeiNode)
    {
        AcpiOsPrintf ("Evaluating _AEI\n");

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiEvaluateObject (AeiNode, NULL, NULL, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("Could not evaluate _AEI: %s\n",
                AcpiFormatException (Status));
            goto Cleanup;
        }

        ReturnObj.Pointer = AcpiGbl_DbBuffer;
        ReturnObj.Length  = ACPI_DEBUG_BUFFER_SIZE;

        Status = AcpiGetEventResources (Node, &ReturnObj);
        if (ACPI_FAILURE (Status))
        {
            AcpiOsPrintf ("AcpiGetEventResources failed: %s\n",
                AcpiFormatException (Status));
            goto Cleanup;
        }

        AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer));
    }


Cleanup:
    ACPI_FREE (ParentPath);
    return (AE_OK);
}
Exemple #7
0
ACPI_STATUS
DisplayOneDevice (ACPI_HANDLE ObjHandle, UINT32 Level, void *Context,
                  void **RetVal)
{
  ACPI_STATUS Status;
  ACPI_DEVICE_INFO *Info;
  ACPI_BUFFER Path;
  ACPI_BUFFER Result;
  ACPI_OBJECT Obj;
  char Buffer[256];
  uint8 prt_buf[1024];
  ACPI_BUFFER Prt = { .Length = sizeof (prt_buf), .Pointer = prt_buf };
  ACPI_PCI_ROUTING_TABLE *prtd;
  uint32 addr=0;
  uint32 fun = 0;
  bool pcibus=FALSE;
  u8 busnum;

  Path.Length = sizeof (Buffer);
  Path.Pointer = Buffer;

  Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &Path);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 ("%s: \n", Path.Pointer);
  }
  Status = AcpiGetObjectInfo (ObjHandle, &Info);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 ("    ");
    if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) {
      DLOG_COM1 (" PCI_ROOT");
      busnum = 0;
      pcibus = TRUE;
    }
    if (Info->Valid & ACPI_VALID_STA)
      DLOG_COM1 (" STA %.8X", Info->CurrentStatus);
    if (Info->Valid & ACPI_VALID_ADR) {
      DLOG_COM1 (" ADR %.8X", Info->Address);
      addr = Info->Address >> 16;
      fun = Info->Address & 0x7;
    }
    if (Info->Valid & ACPI_VALID_HID)
      DLOG_COM1 (" HID %s", Info->HardwareId.String);
    if (Info->Valid & ACPI_VALID_UID)
      DLOG_COM1 (" UID %s", Info->UniqueId.String);
    if (Info->Valid & ACPI_VALID_CID)
      DLOG_COM1 (" CID");

    ACPI_FREE (Info);
  }

  Result.Length = sizeof (Obj);
  Result.Pointer = &Obj;
  Status =
    AcpiEvaluateObjectTyped (ObjHandle, "_DDN", NULL, &Result,
                             ACPI_TYPE_STRING);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 (" DDN=%s", Obj.String.Pointer);
  }

  Result.Length = sizeof (Obj);
  Result.Pointer = &Obj;
  Status =
    AcpiEvaluateObjectTyped (ObjHandle, "_STR", NULL, &Result,
                             ACPI_TYPE_STRING);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 (" STR=%s", Obj.String.Pointer);
  }

  Result.Length = sizeof (Obj);
  Result.Pointer = &Obj;
  Status =
    AcpiEvaluateObjectTyped (ObjHandle, "_MLS", NULL, &Result,
                             ACPI_TYPE_STRING);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 (" MLS=%s", Obj.String.Pointer);
  }

  Status =
    AcpiEvaluateObjectTyped (ObjHandle, "_BBN", NULL, &Result,
                             ACPI_TYPE_INTEGER);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 (" BBN=%d", Obj.Integer.Value);
  } else if (Status != AE_NOT_FOUND)
    DLOG_COM1 (" bbnERR=%d", Status);

  Status =
    AcpiEvaluateObjectTyped (ObjHandle, "_PXM", NULL, &Result,
                             ACPI_TYPE_INTEGER);
  if (ACPI_SUCCESS (Status)) {
    DLOG_COM1 (" PXM=%d", Obj.Integer.Value);
  } else if (Status != AE_NOT_FOUND)
    DLOG_COM1 (" pxmERR=%d", Status);


  DLOG_COM1 ("\n");

  for (;;) {
    Status = AcpiGetIrqRoutingTable (ObjHandle, &Prt);
    if (ACPI_FAILURE (Status)) {
      if (Status == AE_BUFFER_OVERFLOW) {
        DLOG_COM1 ("AcpiGetIrqRoutingTable failed: BUFFER OVERFLOW\n");
      }
      break;
    } else break;
  }
  if (ACPI_SUCCESS (Status)) {
    int i;

    /* Check if ObjHandle refers to a non-root PCI bus */
    if (READ (0, addr, fun, 0, dword) != 0xFFFFFFFF) {
      u8 hdrtype = READ (0, addr, fun, 0x0E, byte);
      if ((hdrtype & 0x7F) == 1) {
        /* PCI-to-PCI bridge headerType == 1 */
        busnum = READ (0, addr, fun, 0x19, byte);
        //busnum = READ (0, addr, fun, 0x1A, byte);
        DLOG_COM1 ("  bus=0x%.02X\n", busnum);
        pcibus = TRUE;
      }
    }

    for (i=0;i<sizeof(prt_buf);) {
      pci_irq_t irq;
      prtd = (ACPI_PCI_ROUTING_TABLE *)(&prt_buf[i]);
      if (prtd->Length == 0) break;

      if (pcibus) {
        irq.pin = prtd->Pin + 1; /* ACPI numbers pins from 0 */
        irq.gsi = 0;
      }

      if (prtd->Source[0]) {
        DLOG_COM1 ("  PRT entry: len=%d pin=%d addr=%p srcidx=0x%x src=%s\n",
                     prtd->Length,
                     prtd->Pin,
                     (uint32)prtd->Address,
                     prtd->SourceIndex,
                     &prtd->Source[0]);
        GetLnkInfo (&prtd->Source[0], &irq);
      } else {
        DLOG_COM1 ("  PRT entry: len=%d pin=%d addr=%p fixed IRQ=0x%x\n",
                     prtd->Length,
                     prtd->Pin,
                     (uint32)prtd->Address,
                     prtd->SourceIndex);
        irq.gsi = prtd->SourceIndex;
        irq.polarity = POLARITY_DEFAULT;
        irq.trigger = TRIGGER_DEFAULT;
      }

      if (pcibus && irq.gsi != 0)
        pci_irq_register (&irq);

      i+=prtd->Length;
    }
  }

#if 0
  ACPI_STATUS DisplayResource (ACPI_RESOURCE *Resource, void *Context);
  DLOG_COM1 ("  _PRS:\n");
  AcpiWalkResources (ObjHandle, "_PRS", DisplayResource, NULL);
  DLOG_COM1 ("  _CRS:\n");
  AcpiWalkResources (ObjHandle, "_CRS", DisplayResource, NULL);
#endif
  return AE_OK;
}