Attached is an updated patch for SVN (I used revision 9092). I blindly
adapted it to the new release, all credits go to Hans Holzer.
Since in the SVN version the DMI parameters can now be set using
VBoxManage, they have been removed from this patch. The patch still uses
environment variables for the ACPI parameters: I tried to convert to
extradata parameters but got stuck, so I preferred to publish the patch
as is in case someone found it useful. The patch compiles fine, but
please note it is currently untested.
The available parameters are:
> set VBOX_BIOS_RSDT_OEMID="ABCD "
> set VBOX_BIOS_RSDT_OEMTABLEID="B8K "
> set VBOX_BIOS_XSDT_OEMID="ABCD "
> set VBOX_BIOS_XSDT_OEMTABLEID="B8K "
> set VBOX_BIOS_SLIC_FILENAME=c:\temp\slic.bin
As in the original patch
> if VBOX_BIOS_XSDT_OEMTABLEID or VBOX_BIOS_XSDT_OEMID are not set then
> the value of VBOX_BIOS_RSDT_OEMTABLEID or VBOX_BIOS_RSDT_OEMID is
> used.
> If a variable is not set the hard coded default is used. So the
> default behavior remains unchanged.
The original patch by Hans Holzer was under the MIT license; this
update is under the same license.
Best regards,
Davide Cavalca
davide125(at)tiscali.it
Index: src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- src/VBox/Devices/PC/DevACPI.cpp (revisione 9092)
+++ src/VBox/Devices/PC/DevACPI.cpp (copia locale)
@@ -28,6 +28,8 @@
#ifdef IN_RING3
#include <iprt/alloc.h>
#include <iprt/string.h>
+#include <iprt/file.h>
+#include <stdlib.h>
#endif /* IN_RING3 */
#include "Builtins.h"
@@ -439,6 +441,80 @@
#ifdef IN_RING3
+/* overwrite a string with a value from the environment variable */
+static void overwriteHeaderString(char* newVal, char* dst, uint32_t maxLen)
+{
+ uint32_t len;
+ char* tmp = (char*)0;
+
+ if (newVal) {
+ // overwrite default settings:
+ len = strlen(newVal);
+ // check for double quotes and remove them:
+ if (newVal[0]=='"' && newVal[len-1]=='"') {
+ tmp = (char*)RTMemAllocZ (len+1);
+ memcpy(tmp, newVal, len+1);
+ newVal = tmp;
+
+ newVal++;
+ len-=2;
+ newVal[len] = '\0';
+ }
+ if (len >= maxLen)
+ memcpy(dst, newVal, maxLen);
+ else {
+ memcpy(dst, newVal, len);
+ memset(dst+len, 0, maxLen-len);
+ }
+ if (tmp)
+ RTMemFree(tmp);
+ }
+}
+
+static int copySlicFromFile(const char* fileName, char** pDest, uint32_t* len)
+{
+ RTFILE fileSlic = NIL_RTFILE;
+ int rc = RTFileOpen(&fileSlic, fileName,
+ RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
+ *len = 0;
+ if (VBOX_SUCCESS(rc))
+ {
+ uint64_t cbFile;
+ rc = RTFileGetSize(fileSlic, &cbFile);
+ if (VBOX_SUCCESS(rc))
+ {
+ *len = (uint32_t) cbFile;
+ }
+ }
+ if (VBOX_FAILURE(rc))
+ {
+ /*
+ * Ignore failure and do not add slic.
+ */
+ LogRel(("copySlicFromFile: Failed to open file with SLIC data '%s', rc=%Vrc!\n", fileName, rc));
+ return rc;
+ }
+
+ *pDest = (char*)RTMemAlloc (*len);
+ if (*pDest == NULL)
+ {
+ LogRel(("copySlicFromFile: Failed to allocate memory for reading file '%s'\n", fileName));
+ RTFileClose(fileSlic);
+ return VERR_NO_MEMORY;
+ }
+
+ rc = RTFileRead(fileSlic, *pDest, *len, NULL);
+ if (VBOX_FAILURE(rc))
+ {
+ AssertMsgFailed(("RTFileRead() for slic file failed -> %Vrc\n", rc));
+ return rc;
+ }
+
+ if (fileSlic != NIL_RTFILE)
+ RTFileClose(fileSlic);
+ return rc;
+}
+
/* Simple acpiChecksum: all the bytes must add up to 0. */
static uint8_t acpiChecksum (const uint8_t * const data, uint32_t len)
{
@@ -580,6 +656,12 @@
return PDMDEV_SET_ERROR(s->pDevIns, VERR_NO_TMP_MEMORY, N_("Cannot allocate RSDT"));
acpiPrepareHeader (&rsdt->header, "RSDT", size, 1);
+
+ char* oemId = getenv("VBOX_BIOS_RSDT_OEMID");
+ char* oemTableId = getenv("VBOX_BIOS_RSDT_OEMTABLEID");
+ overwriteHeaderString(oemId, (char*)&(rsdt->header.au8OemId), 6);
+ overwriteHeaderString(oemTableId, (char*)&(rsdt->header.au8OemTabId), 8);
+
for (unsigned int i = 0; i < nb_entries; ++i)
{
rsdt->u32Entry[i] = RT_H2LE_U32(addrs[i]);
@@ -602,6 +684,16 @@
return VERR_NO_TMP_MEMORY;
acpiPrepareHeader (&xsdt->header, "XSDT", size, 1 /* according to ACPI 3.0 specs */);
+
+ char* oemId = getenv("VBOX_BIOS_XSDT_OEMID");
+ if (oemId==NULL)
+ oemId = getenv("VBOX_BIOS_RSDT_OEMID");
+ char* oemTableId = getenv("VBOX_BIOS_XSDT_OEMTABLEID");
+ if (oemTableId==NULL)
+ oemTableId = getenv("VBOX_BIOS_RSDT_OEMTABLEID");
+ overwriteHeaderString(oemId, (char*)&(xsdt->header.au8OemId), 6);
+ overwriteHeaderString(oemTableId, (char*)&(xsdt->header.au8OemTabId), 8);
+
for (unsigned int i = 0; i < nb_entries; ++i)
{
xsdt->u64Entry[i] = RT_H2LE_U64((uint64_t)addrs[i]);
@@ -664,6 +756,12 @@
acpiPhyscpy (s, addr, &madt, sizeof(madt));
}
+/* SLIC table */
+static void acpiSetupSLIC (ACPIState *s, RTGCPHYS addr, char* buffer, uint32_t len)
+{
+ acpiPhyscpy (s, addr, (const uint8_t*)buffer, len);
+}
+
/* SCI IRQ */
DECLINLINE(void) acpiSetIrq (ACPIState *s, int level)
{
@@ -1461,15 +1559,32 @@
{
int rc;
RTGCPHYS32 rsdt_addr, xsdt_addr, fadt_addr, facs_addr, dsdt_addr, last_addr, apic_addr = 0;
+ uint32_t slic_addr = 0;
uint32_t addend = 0;
RTGCPHYS32 rsdt_addrs[4];
uint32_t cAddr;
size_t rsdt_tbl_len = sizeof(ACPITBLHEADER);
size_t xsdt_tbl_len = sizeof(ACPITBLHEADER);
+ /* copy SLIC table if a suitable file is present */
+ char* slicFileName = getenv("VBOX_BIOS_SLIC_FILENAME");
+ char* slicBuffer = NULL;
+ uint32_t slicLen = 0;
+ if (slicFileName)
+ {
+ rc = copySlicFromFile(slicFileName, &slicBuffer, &slicLen);
+ if (VBOX_FAILURE(rc))
+ {
+ slicBuffer = NULL;
+ slicLen = 0;
+ }
+ }
+
cAddr = 1; /* FADT */
if (s->u8UseIOApic)
cAddr++; /* MADT */
+ if (slicBuffer && slicLen > 0)
+ cAddr++; /* SLIC */
rsdt_tbl_len += cAddr*4; /* each entry: 32 bits phys. address. */
xsdt_tbl_len += cAddr*8; /* each entry: 64 bits phys. address. */
@@ -1499,7 +1614,16 @@
dsdt_addr = RT_ALIGN_32 (facs_addr + sizeof(ACPITBLFACS), 16);
}
- last_addr = RT_ALIGN_32 (dsdt_addr + sizeof(AmlCode), 16);
+ if (slicBuffer && slicLen > 0)
+ {
+ slic_addr = RT_ALIGN_32 (dsdt_addr + sizeof(AmlCode), 16);
+ last_addr = RT_ALIGN_32 (slic_addr + slicLen, 16);
+ }
+ else
+ {
+ last_addr = RT_ALIGN_32 (dsdt_addr + sizeof(AmlCode), 16);
+ }
+
if (last_addr > 0x10000)
return PDMDEV_SET_ERROR(s->pDevIns, VERR_TOO_MUCH_DATA,
N_("Error: ACPI tables > 64KB"));
@@ -1509,17 +1633,36 @@
Log(("RSDT 0x%08X XSDT 0x%08X\n", rsdt_addr + addend, xsdt_addr + addend));
Log(("FACS 0x%08X FADT 0x%08X\n", facs_addr + addend, fadt_addr + addend));
Log(("DSDT 0x%08X\n", dsdt_addr + addend));
+ Log(("SLIC 0x%08X\n", slic_addr + addend));
acpiSetupRSDP ((ACPITBLRSDP*)s->au8RSDPPage, rsdt_addr + addend, xsdt_addr + addend);
acpiSetupDSDT (s, dsdt_addr + addend);
acpiSetupFACS (s, facs_addr + addend);
acpiSetupFADT (s, fadt_addr + addend, facs_addr + addend, dsdt_addr + addend);
rsdt_addrs[0] = fadt_addr + addend;
- if (s->u8UseIOApic)
+ if (s->u8UseIOApic && slicBuffer && slicLen > 0)
{
acpiSetupMADT (s, apic_addr + addend);
rsdt_addrs[1] = apic_addr + addend;
+ rsdt_addrs[2] = slic_addr + addend;
}
+ else if (slicBuffer && slicLen > 0)
+ {
+ rsdt_addrs[1] = slic_addr + addend;
+ }
+ else if (s->u8UseIOApic)
+ {
+ acpiSetupMADT (s, apic_addr + addend);
+ rsdt_addrs[1] = apic_addr + addend;
+ }
+
+ /* copy SLIC table if a suitable file is present */
+ if (slicBuffer && slicLen > 0)
+ {
+ rc = copySlicFromFile(slicFileName, &slicBuffer, &slicLen);
+ if (VBOX_SUCCESS(rc))
+ acpiSetupSLIC(s, slic_addr + addend, slicBuffer, slicLen);
+ }
rc = acpiSetupRSDT (s, rsdt_addr + addend, cAddr, rsdt_addrs);
if (VBOX_FAILURE(rc))
_______________________________________________
vbox-dev mailing list
[email protected]
http://vbox.innotek.de/mailman/listinfo/vbox-dev