|
@@ -569,8 +569,10 @@ static const char * const table_sigs[] = {
|
|
|
|
|
|
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
|
|
|
|
|
|
-/* Must not increase 10 or needs code modification below */
|
|
|
-#define ACPI_OVERRIDE_TABLES 10
|
|
|
+#define ACPI_OVERRIDE_TABLES 64
|
|
|
+static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES];
|
|
|
+
|
|
|
+#define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
|
|
|
|
|
|
void __init acpi_initrd_override(void *data, size_t size)
|
|
|
{
|
|
@@ -579,8 +581,6 @@ void __init acpi_initrd_override(void *data, size_t size)
|
|
|
struct acpi_table_header *table;
|
|
|
char cpio_path[32] = "kernel/firmware/acpi/";
|
|
|
struct cpio_data file;
|
|
|
- struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES];
|
|
|
- char *p;
|
|
|
|
|
|
if (data == NULL || size == 0)
|
|
|
return;
|
|
@@ -625,8 +625,8 @@ void __init acpi_initrd_override(void *data, size_t size)
|
|
|
table->signature, cpio_path, file.name, table->length);
|
|
|
|
|
|
all_tables_size += table->length;
|
|
|
- early_initrd_files[table_nr].data = file.data;
|
|
|
- early_initrd_files[table_nr].size = file.size;
|
|
|
+ acpi_initrd_files[table_nr].data = file.data;
|
|
|
+ acpi_initrd_files[table_nr].size = file.size;
|
|
|
table_nr++;
|
|
|
}
|
|
|
if (table_nr == 0)
|
|
@@ -652,14 +652,34 @@ void __init acpi_initrd_override(void *data, size_t size)
|
|
|
memblock_reserve(acpi_tables_addr, all_tables_size);
|
|
|
arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
|
|
|
|
|
|
- p = early_ioremap(acpi_tables_addr, all_tables_size);
|
|
|
-
|
|
|
+ /*
|
|
|
+ * early_ioremap only can remap 256k one time. If we map all
|
|
|
+ * tables one time, we will hit the limit. Need to map chunks
|
|
|
+ * one by one during copying the same as that in relocate_initrd().
|
|
|
+ */
|
|
|
for (no = 0; no < table_nr; no++) {
|
|
|
- memcpy(p + total_offset, early_initrd_files[no].data,
|
|
|
- early_initrd_files[no].size);
|
|
|
- total_offset += early_initrd_files[no].size;
|
|
|
+ unsigned char *src_p = acpi_initrd_files[no].data;
|
|
|
+ phys_addr_t size = acpi_initrd_files[no].size;
|
|
|
+ phys_addr_t dest_addr = acpi_tables_addr + total_offset;
|
|
|
+ phys_addr_t slop, clen;
|
|
|
+ char *dest_p;
|
|
|
+
|
|
|
+ total_offset += size;
|
|
|
+
|
|
|
+ while (size) {
|
|
|
+ slop = dest_addr & ~PAGE_MASK;
|
|
|
+ clen = size;
|
|
|
+ if (clen > MAP_CHUNK_SIZE - slop)
|
|
|
+ clen = MAP_CHUNK_SIZE - slop;
|
|
|
+ dest_p = early_ioremap(dest_addr & PAGE_MASK,
|
|
|
+ clen + slop);
|
|
|
+ memcpy(dest_p + slop, src_p, clen);
|
|
|
+ early_iounmap(dest_p, clen + slop);
|
|
|
+ src_p += clen;
|
|
|
+ dest_addr += clen;
|
|
|
+ size -= clen;
|
|
|
+ }
|
|
|
}
|
|
|
- early_iounmap(p, all_tables_size);
|
|
|
}
|
|
|
#endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */
|
|
|
|