+//\r
+// The PL061 is a strange beast. The 8-bit data register is aliased across a\r
+// region 0x400 bytes in size, with bits [9:2] of the address operating as a\r
+// mask for both read and write operations:\r
+// For reads:\r
+// - All bits where their corresponding mask bit is 1 return the current\r
+// value of that bit in the GPIO_DATA register.\r
+// - All bits where their corresponding mask bit is 0 return 0.\r
+// For writes:\r
+// - All bits where their corresponding mask bit is 1 set the bit in the\r
+// GPIO_DATA register to the written value.\r
+// - All bits where their corresponding mask bit is 0 are left untouched\r
+// in the GPIO_DATA register.\r
+//\r
+// To keep this driver intelligible, PL061EffectiveAddress, PL061GetPins and\r
+// Pl061SetPins provide an internal abstraction from this interface.\r
+\r
+STATIC\r
+UINTN\r
+EFIAPI\r
+PL061EffectiveAddress (\r
+ IN UINTN Address,\r
+ IN UINTN Mask\r
+ )\r
+{\r
+ return ((Address + PL061_GPIO_DATA_REG_OFFSET) + (Mask << 2));\r
+}\r
+\r
+STATIC\r
+UINTN\r
+EFIAPI\r
+PL061GetPins (\r
+ IN UINTN Address,\r
+ IN UINTN Mask\r
+ )\r
+{\r
+ return MmioRead8 (PL061EffectiveAddress (Address, Mask));\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+PL061SetPins (\r
+ IN UINTN Address,\r
+ IN UINTN Mask,\r
+ IN UINTN Value\r
+ )\r
+{\r
+ MmioWrite8 (PL061EffectiveAddress (Address, Mask), Value);\r
+}\r