4 /* this example program changes the Reserved Page Route (RPR) bit on ICH10's General
5 * Control And Status Register (GCS) from LPC to PCI. In practical terms, it routes
6 * outb to port 80h to the PCI bus. */
8 #define GCS_OFFSET_ADDR 0x3410
9 #define GCS_RPR_SHIFT 2
13 #define VENDOR_ID_INTEL 0x8086
14 #define DEVICE_ID_LPCIF 0x3a16
15 #define DEVICE_ID_COUGARPOINT_LPCIF 0x1c56
17 static EFI_HANDLE ImageHandle;
20 uint16_t vendor_id; /* 00-01 */
21 uint16_t device_id; /* 02-03 */
22 char pad[0xEB]; /* 04-EF */
23 uint32_t rcba; /* F0-F3 */
24 uint32_t reserved[3]; /* F4-FF */
27 static inline void set_bit(volatile uint32_t *flag, int bit, int value)
30 Print(L"current value is 0x%2x\n", val);
37 Print(L"setting value to 0x%2x\n", val);
40 Print(L"new value is 0x%2x\n", val);
43 static inline int configspace_matches_ids(void *config, uint32_t vendor_id,
46 uint32_t *cfg = config;
47 if (cfg[0] == vendor_id && cfg[1] == device_id)
52 static int is_device(EFI_PCI_IO *pciio, uint16_t vendor_id, uint16_t device_id)
57 rc = uefi_call_wrapper(pciio->Pci.Read, 5, pciio, EfiPciIoWidthUint16, 0, 2, &lpcif);
61 if (vendor_id == lpcif.vendor_id && device_id == lpcif.device_id)
66 static EFI_STATUS find_pci_device(uint16_t vendor_id, uint16_t device_id,
75 return EFI_INVALID_PARAMETER;
77 rc = LibLocateHandle(ByProtocol, &PciIoProtocol, NULL, &NoHandles,
82 for (i = 0; i < NoHandles; i++) {
83 void *pciio_tmp = NULL;
84 rc = uefi_call_wrapper(BS->OpenProtocol, 6, Handles[i],
85 &PciIoProtocol, &pciio_tmp, ImageHandle,
86 NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
90 if (!is_device(*pciio, vendor_id, device_id)) {
101 efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
103 InitializeLib(image_handle, systab);
104 EFI_PCI_IO *pciio = NULL;
111 { VENDOR_ID_INTEL, DEVICE_ID_LPCIF },
112 { VENDOR_ID_INTEL, DEVICE_ID_COUGARPOINT_LPCIF },
117 ImageHandle = image_handle;
118 for (i = 0; devices[i].vendor != 0; i++) {
119 rc = find_pci_device(devices[i].vendor, devices[i].device, &pciio);
124 if (rc == EFI_NOT_FOUND) {
125 Print(L"Device not found.\n");
127 } else if (EFI_ERROR(rc)) {
131 rc = uefi_call_wrapper(pciio->Pci.Read, 5, pciio, EfiPciIoWidthUint32,
132 EFI_FIELD_OFFSET(lpcif_t, rcba), 1, &lpcif.rcba);
135 if (!(lpcif.rcba & 1)) {
136 Print(L"rcrb is not mapped, cannot route port 80h\n");
137 return EFI_UNSUPPORTED;
141 Print(L"rcba: 0x%8x\n", lpcif.rcba, lpcif.rcba);
142 set_bit((uint32_t *)(uint64_t)(lpcif.rcba + GCS_OFFSET_ADDR),
143 GCS_RPR_SHIFT, GCS_RPR_PCI);