summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/boot/acpigen.c143
-rw-r--r--src/arch/i386/include/arch/acpigen.h6
-rw-r--r--src/mainboard/asus/m2v-mx_se/acpi_tables.c2
-rw-r--r--src/mainboard/asus/m2v-mx_se/dsdt.asl6
-rw-r--r--src/mainboard/asus/m2v/acpi_tables.c2
-rw-r--r--src/mainboard/asus/m2v/dsdt.asl7
6 files changed, 166 insertions, 0 deletions
diff --git a/src/arch/i386/boot/acpigen.c b/src/arch/i386/boot/acpigen.c
index 2bd2ab5630..e8cd724e23 100644
--- a/src/arch/i386/boot/acpigen.c
+++ b/src/arch/i386/boot/acpigen.c
@@ -28,6 +28,7 @@
#include <string.h>
#include <arch/acpigen.h>
#include <console/console.h>
+#include <device/device.h>
static char *gencurrent;
@@ -372,3 +373,145 @@ int acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype)
acpigen_patch_len(len - 1);
return len + lenh;
}
+
+int acpigen_write_mem32fixed(int readwrite, u32 base, u32 size)
+{
+ /*
+ * acpi 4.0 section 6.4.3.4: 32-Bit Fixed Memory Range Descriptor
+ * Byte 0:
+ * Bit7 : 1 => big item
+ * Bit6-0: 0000110 (0x6) => 32-bit fixed memory
+ */
+ acpigen_emit_byte(0x86);
+ /* Byte 1+2: length (0x0009) */
+ acpigen_emit_byte(0x09);
+ acpigen_emit_byte(0x00);
+ /* bit1-7 are ignored */
+ acpigen_emit_byte(readwrite ? 0x01 : 0x00);
+ acpigen_emit_byte(base & 0xff);
+ acpigen_emit_byte((base >> 8) & 0xff);
+ acpigen_emit_byte((base >> 16) & 0xff);
+ acpigen_emit_byte((base >> 24) & 0xff);
+ acpigen_emit_byte(size & 0xff);
+ acpigen_emit_byte((size >> 8) & 0xff);
+ acpigen_emit_byte((size >> 16) & 0xff);
+ acpigen_emit_byte((size >> 24) & 0xff);
+ return 12;
+}
+
+int acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16)
+{
+ /*
+ * acpi 4.0 section 6.4.2.6: I/O Port Descriptor
+ * Byte 0:
+ * Bit7 : 0 => small item
+ * Bit6-3: 1000 (0x8) => I/O port descriptor
+ * Bit2-0: 111 (0x7) => 7 Bytes long
+ */
+ acpigen_emit_byte(0x47);
+ /* does the device decode all 16 or just 10 bits? */
+ /* bit1-7 are ignored */
+ acpigen_emit_byte(decode16 ? 0x01 : 0x00);
+ /* minimum base address the device may be configured for */
+ acpigen_emit_byte(min & 0xff);
+ acpigen_emit_byte((min >> 8) & 0xff);
+ /* maximum base address the device may be configured for */
+ acpigen_emit_byte(max & 0xff);
+ acpigen_emit_byte((max >> 8) & 0xff);
+ /* alignment for min base */
+ acpigen_emit_byte(align & 0xff);
+ acpigen_emit_byte(len & 0xff);
+ return 8;
+}
+
+int acpigen_write_resourcetemplate_header(void)
+{
+ int len;
+ /*
+ * A ResourceTemplate() is a Buffer() with a
+ * (Byte|Word|DWord) containing the length, followed by one or more
+ * resource items, terminated by the end tag
+ * (small item 0xf, len 1)
+ */
+ len = acpigen_emit_byte(0x11); /* Buffer opcode */
+ len += acpigen_write_len_f();
+ len += acpigen_emit_byte(0x0b); /* Word opcode */
+ len_stack[ltop++] = acpigen_get_current();
+ len += acpigen_emit_byte(0x00);
+ len += acpigen_emit_byte(0x00);
+ return len;
+}
+
+int acpigen_write_resourcetemplate_footer(int len)
+{
+ char *p = len_stack[--ltop];
+ /*
+ * end tag (acpi 4.0 Section 6.4.2.8)
+ * 0x79 <checksum>
+ * 0x00 is treated as a good checksum according to the spec
+ * and is what iasl generates.
+ */
+ len += acpigen_emit_byte(0x79);
+ len += acpigen_emit_byte(0x00);
+ /* patch len word */
+ p[0] = (len-6) & 0xff;
+ p[1] = ((len-6) >> 8) & 0xff;
+ /* patch len field */
+ acpigen_patch_len(len-1);
+ return 2;
+}
+
+static void acpigen_add_mainboard_rsvd_mem32(void *gp, struct device *dev,
+ struct resource *res)
+{
+ acpigen_write_mem32fixed(0, res->base, res->size);
+}
+
+static void acpigen_add_mainboard_rsvd_io(void *gp, struct device *dev,
+ struct resource *res)
+{
+ resource_t base = res->base;
+ resource_t size = res->size;
+ while (size > 0) {
+ resource_t sz = size > 255 ? 255 : size;
+ acpigen_write_io16(base, base, 0, sz, 1);
+ size -= sz;
+ base += sz;
+ }
+}
+
+int acpigen_write_mainboard_resource_template(void)
+{
+ int len;
+ char *start;
+ char *end;
+ len = acpigen_write_resourcetemplate_header();
+ start = acpigen_get_current();
+
+ /* Add reserved memory ranges */
+ search_global_resources(
+ IORESOURCE_MEM | IORESOURCE_RESERVE,
+ IORESOURCE_MEM | IORESOURCE_RESERVE,
+ acpigen_add_mainboard_rsvd_mem32, 0);
+
+ /* Add reserved io ranges */
+ search_global_resources(
+ IORESOURCE_IO | IORESOURCE_RESERVE,
+ IORESOURCE_IO | IORESOURCE_RESERVE,
+ acpigen_add_mainboard_rsvd_io, 0);
+
+ end = acpigen_get_current();
+ len += end-start;
+ len += acpigen_write_resourcetemplate_footer(len);
+ return len;
+}
+
+int acpigen_write_mainboard_resources(const char *scope, const char *name)
+{
+ int len;
+ len = acpigen_write_scope(scope);
+ len += acpigen_write_name(name);
+ len += acpigen_write_mainboard_resource_template();
+ acpigen_patch_len(len - 1);
+ return len;
+}
diff --git a/src/arch/i386/include/arch/acpigen.h b/src/arch/i386/include/arch/acpigen.h
index 52a48e417c..6f13a7ae1f 100644
--- a/src/arch/i386/include/arch/acpigen.h
+++ b/src/arch/i386/include/arch/acpigen.h
@@ -46,5 +46,11 @@ int acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat, u32 busmLat
typedef enum { SW_ALL=0xfc, SW_ANY=0xfd, HW_ALL=0xfe } PSD_coord;
int acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype);
int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len);
+int acpigen_write_mem32fixed(int readwrite, u32 base, u32 size);
+int acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16);
+int acpigen_write_resourcetemplate_header(void);
+int acpigen_write_resourcetemplate_footer(int len);
+int acpigen_write_mainboard_resource_template(void);
+int acpigen_write_mainboard_resources(const char *scope, const char *name);
#endif
diff --git a/src/mainboard/asus/m2v-mx_se/acpi_tables.c b/src/mainboard/asus/m2v-mx_se/acpi_tables.c
index 43cd3291fd..bce295dc45 100644
--- a/src/mainboard/asus/m2v-mx_se/acpi_tables.c
+++ b/src/mainboard/asus/m2v-mx_se/acpi_tables.c
@@ -25,6 +25,7 @@
#include <console/console.h>
#include <string.h>
#include <arch/acpi.h>
+#include <arch/acpigen.h>
#include <arch/smp/mpspec.h>
#include <arch/ioapic.h>
#include <device/device.h>
@@ -87,6 +88,7 @@ unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_ta
{
k8acpi_write_vars();
amd_model_fxx_generate_powernow(0, 0, 0);
+ acpigen_write_mainboard_resources("\\_SB.PCI0.MBRS", "_CRS");
return (unsigned long) (acpigen_get_current());
}
diff --git a/src/mainboard/asus/m2v-mx_se/dsdt.asl b/src/mainboard/asus/m2v-mx_se/dsdt.asl
index 493f1d6c8f..b1c2d38707 100644
--- a/src/mainboard/asus/m2v-mx_se/dsdt.asl
+++ b/src/mainboard/asus/m2v-mx_se/dsdt.asl
@@ -242,6 +242,12 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "LXBIOS", "LXB-DSDT", 1)
}
}
}
+ /* Dummy device to hold auto generated reserved resources */
+ Device(MBRS) {
+ Name (_HID, EisaId ("PNP0C02"))
+ Name (_UID, 0x01)
+ External(_CRS) /* Resource Template in SSDT */
+ }
}
}
}
diff --git a/src/mainboard/asus/m2v/acpi_tables.c b/src/mainboard/asus/m2v/acpi_tables.c
index 17101fc3b6..2919517ddb 100644
--- a/src/mainboard/asus/m2v/acpi_tables.c
+++ b/src/mainboard/asus/m2v/acpi_tables.c
@@ -25,6 +25,7 @@
#include <console/console.h>
#include <string.h>
#include <arch/acpi.h>
+#include <arch/acpigen.h>
#include <arch/smp/mpspec.h>
#include <arch/ioapic.h>
#include <device/device.h>
@@ -88,6 +89,7 @@ unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_ta
{
k8acpi_write_vars();
amd_model_fxx_generate_powernow(0, 0, 0);
+ acpigen_write_mainboard_resources("\\_SB.PCI0.MBRS", "_CRS");
return (unsigned long) (acpigen_get_current());
}
diff --git a/src/mainboard/asus/m2v/dsdt.asl b/src/mainboard/asus/m2v/dsdt.asl
index 55243db331..959e5a7990 100644
--- a/src/mainboard/asus/m2v/dsdt.asl
+++ b/src/mainboard/asus/m2v/dsdt.asl
@@ -399,6 +399,13 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "CORE ", "COREBOOT", 1)
}
}
+ Device(MBRS) {
+ Name (_HID, EisaId ("PNP0C02"))
+ Name (_UID, 0x01)
+
+ External(_CRS) /* Resource Template in SSDT */
+ }
+
External(TOM1) /* top of memory below 4GB */
Method(_CRS, 0) {