This patch adds a proper namestring generation to our ACPIgen generator.
authorRudolf Marek <r.marek@assembler.cz>
Sun, 21 Jun 2009 20:26:13 +0000 (20:26 +0000)
committerRudolf Marek <r.marek@assembler.cz>
Sun, 21 Jun 2009 20:26:13 +0000 (20:26 +0000)
Its used for Name and Scope and Processor now. As bonus, it allows to
create a multi name paths too. Like Scope(\ALL.YOUR.BASE).

Signed-off-by: Rudolf Marek <r.marek@assembler.cz>
Acked-by: Stefan Reinauer <stepan@coresystems.de>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4368 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/arch/i386/boot/acpigen.c
src/arch/i386/include/arch/acpigen.h
src/cpu/amd/model_fxx/powernow_acpi.c
src/northbridge/amd/amdk8/amdk8_acpi.c

index 3dec6714944130048342faea75049e78e54c01b2..2ad2a92cde5d0cd1027a6196fc83c89d3cebdb9b 100644 (file)
@@ -147,22 +147,111 @@ int acpigen_emit_stream(char *data, int size)
        return size;
 }
 
+/* The NameString are bit tricky, each element can be 4 chars, if 
+   less its padded with underscore. Check 18.2.2 and 18.4 
+   and 5.3 of ACPI specs 3.0 for details
+*/
+
+static int acpigen_emit_simple_namestring(char *name) {
+       int i, len = 0;
+       char ud[] = "____";
+       for (i = 0; i < 4; i++) {
+               if ((name[i] == '\0') || (name[i] == '.')) {
+                       len += acpigen_emit_stream(ud, 4 - i);
+                       break;
+               } else {
+                       len += acpigen_emit_byte(name[i]);                              
+               }
+       }
+       return len;
+}
+
+static int acpigen_emit_double_namestring(char *name, int dotpos) {
+       int len = 0; 
+       /* mark dual name prefix */
+       len += acpigen_emit_byte(0x2e);
+       len += acpigen_emit_simple_namestring(name);
+       len += acpigen_emit_simple_namestring(&name[dotpos + 1]);
+       return len;
+}
+
+static int acpigen_emit_multi_namestring(char *name) {
+       int len = 0, count = 0;
+       unsigned char *pathlen; 
+       /* mark multi name prefix */
+       len += acpigen_emit_byte(0x2f);
+       len += acpigen_emit_byte(0x0);
+       pathlen = ((unsigned char *) acpigen_get_current()) - 1;
+
+       while (name[0] != '\0') {
+               len += acpigen_emit_simple_namestring(name);
+               /* find end or next entity */
+               while ((name[0] != '.') && (name[0] != '\0'))
+                       name++;
+               /* forward to next */
+               if (name[0] == '.')
+                       name++;
+               count++;
+       }
+
+       pathlen[0] = count;
+       return len;
+}
+
+
+int acpigen_emit_namestring(char *namepath) {
+       int dotcount = 0, i;
+       int dotpos;
+       int len = 0;
+
+       /* we can start with a \ */
+       if (namepath[0] == '\\') {
+               len += acpigen_emit_byte('\\');
+               namepath++;
+       }
+
+       /* and there can be any number of ^ */
+       while (namepath[0] == '^') {
+               len += acpigen_emit_byte('^');
+               namepath++;
+       }
+
+       ASSERT(namepath[0] != '\0');
+
+       i = 0;
+       while (namepath[i] != '\0') {
+               if (namepath[i] == '.') {
+                       dotcount++;
+                       dotpos = i;
+               }
+               i++;
+       }
+
+       if (dotcount == 0) {
+               len += acpigen_emit_simple_namestring(namepath);
+       } else if (dotcount == 1) { 
+               len += acpigen_emit_double_namestring(namepath, dotpos);
+       } else {
+               len += acpigen_emit_multi_namestring(namepath);
+       }
+       return len;
+}
+
 int acpigen_write_name(char *name)
 {
-       int len = strlen(name);
+       int len;
        /* name op */
-       acpigen_emit_byte(0x8);
-       acpigen_emit_stream(name, len);
-       return len + 1;
+       len = acpigen_emit_byte(0x8);
+       return len + acpigen_emit_namestring(name);
 }
 
 int acpigen_write_scope(char *name)
 {
        int len;
        /* scope op */
-       acpigen_emit_byte(0x10);
-       len = acpigen_write_len_f();
-       return len + acpigen_emit_stream(name, strlen(name)) + 1;
+       len = acpigen_emit_byte(0x10);
+       len += acpigen_write_len_f();
+       return len + acpigen_emit_namestring(name);
 }
 
 int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len)
@@ -178,8 +267,8 @@ int acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len)
        acpigen_emit_byte(0x83);
        len = acpigen_write_len_f();
 
-       sprintf(pscope, "\\._PR_CPU%x", (unsigned int) cpuindex);
-       len += acpigen_emit_stream(pscope, strlen(pscope));
+       sprintf(pscope, "\\_PR.CPU%x", (unsigned int) cpuindex);
+       len += acpigen_emit_namestring(pscope);
        acpigen_emit_byte(cpuindex);
        acpigen_emit_byte(pblock_addr & 0xff);
        acpigen_emit_byte((pblock_addr >> 8) & 0xff);
@@ -238,7 +327,7 @@ int acpigen_write_PPC(u8 nr)
        /* method op */
        acpigen_emit_byte(0x14);
        len = acpigen_write_len_f();
-       len += acpigen_emit_stream("_PPC", 4);
+       len += acpigen_emit_namestring("_PPC");
        /* no fnarg */
        acpigen_emit_byte(0x00);
        /* return */
index 0abeae5050bc8a58f2f7eff41544b01ba5dce6f7..63c369d6a8e353eeef1609541829885771b1194f 100644 (file)
@@ -29,6 +29,7 @@ int acpigen_write_package(int nr_el);
 int acpigen_write_byte(unsigned int data);
 int acpigen_emit_byte(unsigned char data);
 int acpigen_emit_stream(char *data, int size);
+int acpigen_emit_namestring(char *namepath);
 int acpigen_write_dword(unsigned int data);
 int acpigen_write_qword(uint64_t data);
 int acpigen_write_name(char *name);
index 1e789e3729a0c9cbe0fd1c2c27c1437d38d431ef..6ad1686dadc28a07c3e12bca8b72caf0968e3d6c 100644 (file)
@@ -376,7 +376,7 @@ write_pstates:
 
 int amd_model_fxx_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP) {
        int lens;
-       char pscope[] = "\\_PR_";
+       char pscope[] = "\\_PR";
 
        lens = acpigen_write_scope(pscope);
        lens += pstates_algorithm(pcontrol_blk, plen, onlyBSP);
index b6d4ed46f989f8357ac472df9e54eab394929e13..46b17db161fa7b4b0d53340049fbeb99eed51d9e 100644 (file)
@@ -270,7 +270,7 @@ int k8acpi_write_vars(void)
 {
        int lens;
        msr_t msr;
-       char pscope[] = "\\._SB_PCI0";
+       char pscope[] = "\\_SB.PCI0";
 
        lens = acpigen_write_scope(pscope);
        lens += k8acpi_write_pci_data(4, "BUSN", 0xe0);