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 int is_device(EFI_PCI_IO
*pciio
, uint16_t vendor_id
, uint16_t device_id
)
48 rc
= uefi_call_wrapper(pciio
->Pci
.Read
, 5, pciio
, EfiPciIoWidthUint16
, 0, 2, &lpcif
);
52 if (vendor_id
== lpcif
.vendor_id
&& device_id
== lpcif
.device_id
)
57 static EFI_STATUS
find_pci_device(uint16_t vendor_id
, uint16_t device_id
,
65 return EFI_INVALID_PARAMETER
;
67 rc
= LibLocateHandle(ByProtocol
, &PciIoProtocol
, NULL
, &NoHandles
,
72 for (i
= 0; i
< NoHandles
; i
++) {
73 void *pciio_tmp
= NULL
;
74 rc
= uefi_call_wrapper(BS
->OpenProtocol
, 6, Handles
[i
],
75 &PciIoProtocol
, &pciio_tmp
, ImageHandle
,
76 NULL
, EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
80 if (!is_device(*pciio
, vendor_id
, device_id
)) {
91 efi_main (EFI_HANDLE image_handle
, EFI_SYSTEM_TABLE
*systab
)
93 InitializeLib(image_handle
, systab
);
94 EFI_PCI_IO
*pciio
= NULL
;
96 EFI_STATUS rc
= EFI_SUCCESS
;
101 { VENDOR_ID_INTEL
, DEVICE_ID_LPCIF
},
102 { VENDOR_ID_INTEL
, DEVICE_ID_COUGARPOINT_LPCIF
},
107 ImageHandle
= image_handle
;
108 for (i
= 0; devices
[i
].vendor
!= 0; i
++) {
109 rc
= find_pci_device(devices
[i
].vendor
, devices
[i
].device
, &pciio
);
114 if (rc
== EFI_NOT_FOUND
) {
115 Print(L
"Device not found.\n");
117 } else if (EFI_ERROR(rc
)) {
121 rc
= uefi_call_wrapper(pciio
->Pci
.Read
, 5, pciio
, EfiPciIoWidthUint32
,
122 EFI_FIELD_OFFSET(lpcif_t
, rcba
), 1, &lpcif
.rcba
);
125 if (!(lpcif
.rcba
& 1)) {
126 Print(L
"rcrb is not mapped, cannot route port 80h\n");
127 return EFI_UNSUPPORTED
;
131 Print(L
"rcba: 0x%8x\n", lpcif
.rcba
, lpcif
.rcba
);
132 set_bit((uint32_t *)(intptr_t)(lpcif
.rcba
+ GCS_OFFSET_ADDR
),
133 GCS_RPR_SHIFT
, GCS_RPR_PCI
);