public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
@ 2021-10-13  9:16 Corvin Köhne
  2021-10-14  5:07 ` [edk2-devel] " Gerd Hoffmann
  2021-10-14  5:42 ` Peter Grehan
  0 siblings, 2 replies; 6+ messages in thread
From: Corvin Köhne @ 2021-10-13  9:16 UTC (permalink / raw)
  Cc: Corvin Köhne, Ard Biesheuvel, Jiewen Yao, Jordan Justen,
	Gerd Hoffmann, Rebecca Cran, Peter Grehan, devel,
	Michael D Kinney, Liming Gao, Zhiguang Liu

It's much easier to create configuration dependend ACPI tables for
bhyve than for OVMF. For this reason, don't use the statically
created ACPI tables provided by OVMF. Instead use the dynamically
created ACPI tables of bhyve. If bhyve provides no ACPI tables or
we are unable to detect those, fall back to OVMF tables.

Implementation is similar to <OvmfPkg/XenAcpiPlatformDxe/Xen.c>.

Signed-off-by: Corvin Köhne <c.koehne@beckhoff.com>
CC: Ard Biesheuvel <ardb+tianocore@kernel.org>
CC: Jiewen Yao <jiewen.yao@intel.com>
CC: Jordan Justen <jordan.l.justen@intel.com>
CC: Gerd Hoffmann <kraxel@redhat.com>
CC: Rebecca Cran <rebecca@bsdio.com>
CC: Peter Grehan <grehan@freebsd.org>
CC: devel@edk2.groups.io
CC: Michael D Kinney <michael.d.kinney@intel.com>
CC: Liming Gao <gaoliming@byosoft.com.cn>
CC: Zhiguang Liu <zhiguang.liu@intel.com>
---
 MdePkg/Include/Uefi/UefiBaseType.h           |   2 +
 OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c |  10 ++
 OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h |   6 +
 OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c        | 241 +++++++++++++++++++++++++++
 4 files changed, 259 insertions(+)

diff --git a/MdePkg/Include/Uefi/UefiBaseType.h b/MdePkg/Include/Uefi/UefiBaseType.h
index 45e2aa63bb..084c52cd0f 100644
--- a/MdePkg/Include/Uefi/UefiBaseType.h
+++ b/MdePkg/Include/Uefi/UefiBaseType.h
@@ -53,6 +53,8 @@ typedef UINT64                    EFI_PHYSICAL_ADDRESS;
 ///
 typedef UINT64                    EFI_VIRTUAL_ADDRESS;
 
+#define NUMERIC_VALUE_AS_POINTER(Type, Value)   ((Type *) ((UINTN)(Value)))
+
 ///
 /// EFI Time Abstraction:
 ///  Year:       1900 - 9999
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
index 9ccdb4d91c..e7de6937da 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
@@ -245,6 +245,16 @@ InstallAcpiTables (
 {
   EFI_STATUS Status;
 
+  Status = InstallBhyveTables (AcpiTable);
+  if (!EFI_ERROR (Status)) {
+    return EFI_SUCCESS;
+  }
+  if (Status != EFI_NOT_FOUND) {
+    DEBUG ((DEBUG_INFO, "%a: unable to install bhyve's ACPI tables (%r)\n",
+      __FUNCTION__, Status));
+    return Status;
+  }
+
   Status = InstallOvmfFvTables (AcpiTable);
 
   return Status;
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
index 994ee2c7cd..1a99838e8e 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
@@ -48,6 +48,12 @@ BhyveInstallAcpiTable(
 
 EFI_STATUS
 EFIAPI
+InstallBhyveTables (
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
+  );
+
+EFI_STATUS
+EFIAPI
 InstallXenTables (
   IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
   );
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
index 01ee894746..2f5dd87995 100644
--- a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
+++ b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
@@ -12,6 +12,19 @@
 #include <Library/BhyveFwCtlLib.h>
 #include <Library/MemoryAllocationLib.h>
 
+#define BHYVE_ACPI_PHYSICAL_ADDRESS   ((UINTN)0x000F2400)
+#define BHYVE_BIOS_PHYSICAL_END       ((UINTN)0x00100000)
+
+#pragma pack (1)
+
+typedef struct
+{
+  EFI_ACPI_DESCRIPTION_HEADER   Header;
+  UINT64                        Tables[0];
+} EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE;
+
+#pragma pack ()
+
 STATIC
 EFI_STATUS
 EFIAPI
@@ -130,3 +143,231 @@ BhyveInstallAcpiTable (
            TableKey
            );
 }
+
+/**
+  Get the address of bhyve's ACPI Root System Description Pointer (RSDP).
+
+  @param  RsdpPtr             Return pointer to RSDP.
+
+  @return EFI_SUCCESS         Bhyve's RSDP successfully found.
+  @return EFI_NOT_FOUND       Couldn't find bhyve's RSDP.
+  @return EFI_UNSUPPORTED     Revision is lower than 2.
+  @return EFI_PROTOCOL_ERROR  Invalid RSDP found.
+
+**/
+EFI_STATUS
+EFIAPI
+BhyveGetAcpiRsdp (
+  OUT   EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER   **RsdpPtr
+  )
+{
+  UINTN                                         RsdpAddress;
+  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER  *Rsdp;
+
+  if (RsdpPtr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Detect the RSDP
+  //
+  for (RsdpAddress = BHYVE_ACPI_PHYSICAL_ADDRESS;
+       RsdpAddress < BHYVE_BIOS_PHYSICAL_END;
+       RsdpAddress += 0x10) {
+    Rsdp = NUMERIC_VALUE_AS_POINTER (
+             EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
+             RsdpAddress
+             );
+    if (Rsdp->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {
+      continue;
+    }
+    if (Rsdp->Revision < 2) {
+      DEBUG ((DEBUG_INFO, "%a: unsupported RSDP found\n", __FUNCTION__));
+      return EFI_UNSUPPORTED;
+    }
+
+    //
+    // For ACPI 1.0/2.0/3.0 the checksum of first 20 bytes should be 0.
+    // For ACPI 2.0/3.0 the checksum of the entire table should be 0.
+    //
+    UINT8 Sum = CalculateCheckSum8 (
+            (CONST UINT8 *)Rsdp,
+            sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
+            );
+    if (Sum != 0) {
+      DEBUG ((DEBUG_INFO, "%a: RSDP header checksum not valid: 0x%02x\n",
+        __FUNCTION__, Sum));
+      return EFI_PROTOCOL_ERROR;
+    }
+    Sum = CalculateCheckSum8 (
+            (CONST UINT8 *)Rsdp,
+            sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
+            );
+    if (Sum != 0) {
+      DEBUG ((DEBUG_INFO, "%a: RSDP table checksum not valid: 0x%02x\n",
+        __FUNCTION__, Sum));
+      return EFI_PROTOCOL_ERROR;
+    }
+
+    //
+    // RSDP was found and is valid
+    //
+    *RsdpPtr = Rsdp;
+
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((DEBUG_INFO, "%a: RSDP not found\n", __FUNCTION__));
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Get bhyve's ACPI tables from the RSDP. And install bhyve's ACPI tables
+  into the RSDT/XSDT using InstallAcpiTable.
+
+  @param  AcpiProtocol        Protocol instance pointer.
+
+  @return EFI_SUCCESS         All tables were successfully inserted.
+  @return EFI_UNSUPPORTED     Bhyve's ACPI tables doesn't include a XSDT.
+  @return EFI_PROTOCOL_ERROR  Invalid XSDT found.
+
+  @return                     Error codes propagated from underlying functions.
+**/
+EFI_STATUS
+EFIAPI
+InstallBhyveTables (
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol
+  )
+{
+  EFI_STATUS                                      Status;
+  UINTN                                           TableHandle;
+  EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER    *Rsdp;
+  EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE    *Facs;
+  EFI_ACPI_DESCRIPTION_HEADER                     *Dsdt;
+
+  Rsdp = NULL;
+  Facs = NULL;
+  Dsdt = NULL;
+
+  //
+  // Try to find bhyve ACPI tables
+  //
+  Status = BhyveGetAcpiRsdp (&Rsdp);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "%a: can't get RSDP (%r)\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  //
+  // Bhyve should always provide a XSDT
+  //
+  EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE * CONST Xsdt =
+    NUMERIC_VALUE_AS_POINTER (
+      EFI_ACPI_2_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE,
+      Rsdp->XsdtAddress
+      );
+  if (Xsdt == NULL) {
+    DEBUG ((DEBUG_INFO, "%a: XSDT not found\n", __FUNCTION__));
+    return EFI_UNSUPPORTED;
+  }
+  if (Xsdt->Header.Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
+    DEBUG ((DEBUG_INFO, "%a: invalid XSDT length\n", __FUNCTION__));
+    return EFI_PROTOCOL_ERROR;
+  }
+
+  //
+  // Install ACPI tables
+  //
+  CONST UINTN NumberOfTableEntries =
+    (Xsdt->Header.Length - sizeof (Xsdt->Header)) / sizeof (UINT64);
+  for (UINTN Index = 0; Index < NumberOfTableEntries; Index++) {
+    EFI_ACPI_DESCRIPTION_HEADER * CONST CurrentTable =
+      NUMERIC_VALUE_AS_POINTER (
+        EFI_ACPI_DESCRIPTION_HEADER,
+        Xsdt->Tables[Index]
+        );
+    Status = AcpiProtocol->InstallAcpiTable (
+                             AcpiProtocol,
+                             CurrentTable,
+                             CurrentTable->Length,
+                             &TableHandle
+                             );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "%a: failed to install ACPI table %c%c%c%c (%r)\n",
+        __FUNCTION__,
+        NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[0],
+        NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[1],
+        NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[2],
+        NUMERIC_VALUE_AS_POINTER (UINT8, CurrentTable->Signature)[3],
+        Status));
+      return Status;
+    }
+
+    if (CurrentTable->Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
+      EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * CONST Fadt =
+        (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE * CONST)CurrentTable;
+      if (Fadt->XFirmwareCtrl) {
+        Facs = NUMERIC_VALUE_AS_POINTER (
+                 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE,
+                 Fadt->XFirmwareCtrl
+                 );
+      } else {
+        Facs = NUMERIC_VALUE_AS_POINTER (
+                 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE,
+                 Fadt->FirmwareCtrl
+                 );
+      }
+      if (Fadt->XDsdt) {
+        Dsdt = NUMERIC_VALUE_AS_POINTER (
+                 EFI_ACPI_DESCRIPTION_HEADER,
+                 Fadt->XDsdt
+                 );
+      } else {
+        Dsdt = NUMERIC_VALUE_AS_POINTER (
+                 EFI_ACPI_DESCRIPTION_HEADER,
+                 Fadt->Dsdt
+                 );
+      }
+    }
+  }
+
+  //
+  // Install FACS
+  //
+  if (Facs != NULL) {
+    Status = AcpiProtocol->InstallAcpiTable (
+                             AcpiProtocol,
+                             Facs,
+                             Facs->Length,
+                             &TableHandle
+                             );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "%a: failed to install FACS (%r)\n", __FUNCTION__,
+        Status));
+      return Status;
+    }
+  }
+
+  //
+  // Install DSDT
+  // If it's not found, something bad happened. Don't continue execution.
+  //
+  if (Dsdt == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: failed to find DSDT\n", __FUNCTION__));
+    CpuDeadLoop ();
+  }
+
+  Status = AcpiProtocol->InstallAcpiTable (
+                           AcpiProtocol,
+                           Dsdt,
+                           Dsdt->Length,
+                           &TableHandle
+                           );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "%a: failed to install DSDT (%r)\n", __FUNCTION__,
+      Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.11.0

Beckhoff Automation GmbH & Co. KG | Managing Director: Dipl. Phys. Hans Beckhoff
Registered office: Verl, Germany | Register court: Guetersloh HRA 7075




^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [edk2-devel] [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
  2021-10-13  9:16 [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables Corvin Köhne
@ 2021-10-14  5:07 ` Gerd Hoffmann
  2021-10-14  5:42 ` Peter Grehan
  1 sibling, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2021-10-14  5:07 UTC (permalink / raw)
  To: devel, c.koehne
  Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Rebecca Cran,
	Peter Grehan, Michael D Kinney, Liming Gao, Zhiguang Liu

  Hi,

> +#define BHYVE_ACPI_PHYSICAL_ADDRESS   ((UINTN)0x000F2400)
> +#define BHYVE_BIOS_PHYSICAL_END       ((UINTN)0x00100000)

> +  //
> +  // Detect the RSDP
> +  //
> +  for (RsdpAddress = BHYVE_ACPI_PHYSICAL_ADDRESS;
> +       RsdpAddress < BHYVE_BIOS_PHYSICAL_END;
> +       RsdpAddress += 0x10) {
> +    Rsdp = NUMERIC_VALUE_AS_POINTER (
> +             EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
> +             RsdpAddress
> +             );
> +    if (Rsdp->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {
> +      continue;
> +    }

So bhyve copies the tables to guest memory and ovmf searches for them,
correct?

The commit message should (briefly) describe how the tables are passed
from the host to the guest.

The code looks sane to me, so with a more verbose commit message:
Acked-by: Gerd Hoffmann <kraxel@redhat.com>

take care,
  Gerd


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
  2021-10-13  9:16 [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables Corvin Köhne
  2021-10-14  5:07 ` [edk2-devel] " Gerd Hoffmann
@ 2021-10-14  5:42 ` Peter Grehan
  2021-10-14  5:51   ` [edk2-devel] " Gerd Hoffmann
  2021-10-14  9:41   ` Yao, Jiewen
  1 sibling, 2 replies; 6+ messages in thread
From: Peter Grehan @ 2021-10-14  5:42 UTC (permalink / raw)
  To: Corvin Köhne
  Cc: Ard Biesheuvel, Jiewen Yao, Jordan Justen, Gerd Hoffmann,
	Rebecca Cran, devel, Michael D Kinney, Liming Gao, Zhiguang Liu

> It's much easier to create configuration dependend ACPI tables for > bhyve than for OVMF. For this reason, don't use the statically> 
created ACPI tables provided by OVMF. Instead use the dynamically> 
created ACPI tables of bhyve. If bhyve provides no ACPI tables or> we 
are unable to detect those, fall back to OVMF tables.
  This looks fine though bhyve will need to generate MCFG to get to full 
parity.

  I've requested in the past that you do this so I'll request again: 
please discuss these changes on the freebsd-virtualization list before 
sending patches outside of the project.

Acked-by: Peter Grehan <grehan@freebsd.org>

later,

Peter.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-devel] [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
  2021-10-14  5:42 ` Peter Grehan
@ 2021-10-14  5:51   ` Gerd Hoffmann
  2021-10-14  5:53     ` Peter Grehan
  2021-10-14  9:41   ` Yao, Jiewen
  1 sibling, 1 reply; 6+ messages in thread
From: Gerd Hoffmann @ 2021-10-14  5:51 UTC (permalink / raw)
  To: devel, grehan
  Cc: Corvin Köhne, Ard Biesheuvel, Jiewen Yao, Jordan Justen,
	Rebecca Cran, Michael D Kinney, Liming Gao, Zhiguang Liu

  Hi,

>  I've requested in the past that you do this so I'll request again: please
> discuss these changes on the freebsd-virtualization list before sending
> patches outside of the project.

I'd suggest to add the list to the bhyve section of Maintainers.txt
then.

take care,
  Gerd


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-devel] [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
  2021-10-14  5:51   ` [edk2-devel] " Gerd Hoffmann
@ 2021-10-14  5:53     ` Peter Grehan
  0 siblings, 0 replies; 6+ messages in thread
From: Peter Grehan @ 2021-10-14  5:53 UTC (permalink / raw)
  To: Gerd Hoffmann, devel
  Cc: Corvin Köhne, Ard Biesheuvel, Jiewen Yao, Jordan Justen,
	Rebecca Cran, Michael D Kinney, Liming Gao, Zhiguang Liu

>>   I've requested in the past that you do this so I'll request again: please
>> discuss these changes on the freebsd-virtualization list before sending
>> patches outside of the project.
> 
> I'd suggest to add the list to the bhyve section of Maintainers.txt
> then.

  Yep, that's fair enough.

later,

Peter.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-devel] [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables
  2021-10-14  5:42 ` Peter Grehan
  2021-10-14  5:51   ` [edk2-devel] " Gerd Hoffmann
@ 2021-10-14  9:41   ` Yao, Jiewen
  1 sibling, 0 replies; 6+ messages in thread
From: Yao, Jiewen @ 2021-10-14  9:41 UTC (permalink / raw)
  To: devel@edk2.groups.io, grehan@freebsd.org, Köhne, Corvin
  Cc: Ard Biesheuvel, Justen, Jordan L, Gerd Hoffmann, Rebecca Cran,
	Kinney, Michael D, Liming Gao, Liu, Zhiguang

Acked-by: Jiewen Yao <Jiewen.yao@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Peter
> Grehan
> Sent: Thursday, October 14, 2021 1:42 PM
> To: Köhne, Corvin <c.koehne@beckhoff.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>; Yao, Jiewen
> <jiewen.yao@intel.com>; Justen, Jordan L <jordan.l.justen@intel.com>; Gerd
> Hoffmann <kraxel@redhat.com>; Rebecca Cran <rebecca@bsdio.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>;
> Liming Gao <gaoliming@byosoft.com.cn>; Liu, Zhiguang
> <zhiguang.liu@intel.com>
> Subject: Re: [edk2-devel] [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI
> tables
> 
> > It's much easier to create configuration dependend ACPI tables for > bhyve
> than for OVMF. For this reason, don't use the statically>
> created ACPI tables provided by OVMF. Instead use the dynamically>
> created ACPI tables of bhyve. If bhyve provides no ACPI tables or> we
> are unable to detect those, fall back to OVMF tables.
>   This looks fine though bhyve will need to generate MCFG to get to full
> parity.
> 
>   I've requested in the past that you do this so I'll request again:
> please discuss these changes on the freebsd-virtualization list before
> sending patches outside of the project.
> 
> Acked-by: Peter Grehan <grehan@freebsd.org>
> 
> later,
> 
> Peter.
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-10-14  9:41 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-13  9:16 [PATCH] OvmfPkg/BhyveBhfPkg: install bhyve's ACPI tables Corvin Köhne
2021-10-14  5:07 ` [edk2-devel] " Gerd Hoffmann
2021-10-14  5:42 ` Peter Grehan
2021-10-14  5:51   ` [edk2-devel] " Gerd Hoffmann
2021-10-14  5:53     ` Peter Grehan
2021-10-14  9:41   ` Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox