@@ -840,7 +840,7 @@ struct acpi_table_header
} __attribute__((packed));
char *acpi_tables;
-size_t acpi_tables_len;
+size_t acpi_tables_len, acpi_tables_prev_len;
static int acpi_checksum(const uint8_t *data, int len)
{
@@ -851,13 +851,44 @@ static int acpi_checksum(const uint8_t *data, int len)
return (-sum) & 0xff;
}
-int acpi_table_add(const char *t)
+void *acpi_alloc_table(size_t size)
+{
+ void *ptr;
+
+ if (!acpi_tables) {
+ acpi_tables_len = sizeof(uint16_t);
+ acpi_tables = qemu_mallocz(acpi_tables_len);
+ }
+ acpi_tables_prev_len = acpi_tables_len;
+ acpi_tables_len += sizeof(uint16_t) + size;
+ acpi_tables = qemu_realloc(acpi_tables, acpi_tables_len);
+ ptr = acpi_tables + acpi_tables_prev_len;
+
+ *(uint16_t *) ptr = size;
+
+ return ptr + sizeof(uint16_t);
+}
+
+void acpi_commit_table(void *buf)
+{
+ struct acpi_table_header *acpi_hdr = buf;
+ size_t size = acpi_tables_len - acpi_tables_prev_len - sizeof(uint16_t);
+
+ acpi_hdr->length = cpu_to_le32(size);
+ acpi_hdr->checksum = acpi_checksum(buf, size);
+
+ /* increase number of tables */
+ (*(uint16_t *) acpi_tables) =
+ cpu_to_le32(le32_to_cpu(*(uint16_t *) acpi_tables) + 1);
+}
+
+int acpi_table_cmdline_add(const char *t)
{
static const char *dfl_id = "QEMUQEMU";
char buf[1024], *p, *f;
struct acpi_table_header acpi_hdr;
unsigned long val;
- size_t newlen, off;
+ size_t size, off;
memset(&acpi_hdr, 0, sizeof(acpi_hdr));
@@ -915,7 +946,7 @@ int acpi_table_add(const char *t)
buf[0] = '\0';
}
- acpi_hdr.length = sizeof(acpi_hdr);
+ size = sizeof(acpi_hdr);
f = buf;
while (buf[0]) {
@@ -927,27 +958,17 @@ int acpi_table_add(const char *t)
fprintf(stderr, "Can't stat file '%s': %s\n", f, strerror(errno));
goto out;
}
- acpi_hdr.length += s.st_size;
+ size += s.st_size;
if (!n)
break;
*n = ':';
f = n + 1;
}
- if (!acpi_tables) {
- acpi_tables_len = sizeof(uint16_t);
- acpi_tables = qemu_mallocz(acpi_tables_len);
- }
- newlen = acpi_tables_len + sizeof(uint16_t) + acpi_hdr.length;
- acpi_tables = qemu_realloc(acpi_tables, newlen);
- p = acpi_tables + acpi_tables_len;
- acpi_tables_len = newlen;
+ p = acpi_alloc_table(size);
+ off = sizeof(struct acpi_table_header);
- acpi_hdr.length = cpu_to_le32(acpi_hdr.length);
- *(uint16_t*)p = acpi_hdr.length;
- p += sizeof(uint16_t);
- memcpy(p, &acpi_hdr, sizeof(acpi_hdr));
- off = sizeof(acpi_hdr);
+ memcpy(p, &acpi_hdr, off);
f = buf;
while (buf[0]) {
@@ -983,10 +1004,8 @@ int acpi_table_add(const char *t)
f = n + 1;
}
- ((struct acpi_table_header*)p)->checksum = acpi_checksum((uint8_t*)p, off);
- /* increase number of tables */
- (*(uint16_t*)acpi_tables) =
- cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1);
+ acpi_commit_table(p);
+
return 0;
out:
if (acpi_tables) {
@@ -995,3 +1014,4 @@ out:
}
return -1;
}
+
@@ -108,7 +108,9 @@ extern char *acpi_tables;
extern size_t acpi_tables_len;
void acpi_bios_init(void);
-int acpi_table_add(const char *table_desc);
+void *acpi_alloc_table(size_t size);
+void acpi_commit_table(void *buf);
+int acpi_table_cmdline_add(const char *table_desc);
/* acpi_piix.c */
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
@@ -5492,7 +5492,7 @@ int main(int argc, char **argv, char **envp)
rtc_td_hack = 1;
break;
case QEMU_OPTION_acpitable:
- if(acpi_table_add(optarg) < 0) {
+ if(acpi_table_cmdline_add(optarg) < 0) {
fprintf(stderr, "Wrong acpi table provided\n");
exit(1);
}