Hello,

The namestring handling in ACPIgen was a big trickery. We were pasing the strings as it was a bytestream already. This was a reason for instead of
_PR one had to write _PR_

Or \_SB.PCI0 was in fact \_SB_PCI0.

This patch adds a proper namestring generation to our ACPIgen generator.
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 <[email protected]>

I have no board now, so I cannot test it on real HW. I did some tests which a ACPIgen testbench which I'm attaching for future reference.

I dont know what happen to fam10 code, but I think it will need similar change.

Rudolf

Index: src/cpu/amd/model_fxx/powernow_acpi.c
===================================================================
--- src/cpu/amd/model_fxx/powernow_acpi.c	(revision 4367)
+++ src/cpu/amd/model_fxx/powernow_acpi.c	(working copy)
@@ -376,7 +376,7 @@
 
 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: src/northbridge/amd/amdk8/amdk8_acpi.c
===================================================================
--- src/northbridge/amd/amdk8/amdk8_acpi.c	(revision 4367)
+++ src/northbridge/amd/amdk8/amdk8_acpi.c	(working copy)
@@ -270,7 +270,7 @@
 {
 	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);
Index: src/arch/i386/boot/acpigen.c
===================================================================
--- src/arch/i386/boot/acpigen.c	(revision 4367)
+++ src/arch/i386/boot/acpigen.c	(working copy)
@@ -147,22 +147,111 @@
 	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 @@
 	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 @@
 	/* 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: src/arch/i386/include/arch/acpigen.h
===================================================================
--- src/arch/i386/include/arch/acpigen.h	(revision 4367)
+++ src/arch/i386/include/arch/acpigen.h	(working copy)
@@ -29,6 +29,7 @@
 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);
#include "acpigen.h"

static int k8acpi_write_TOM1(void)
{
	int len;
	len = acpigen_write_name("TOM1");
	len += acpigen_write_dword(0x12345678);
	return len;
}

static int k8acpi_write_SBLK(void)
{
	int len;
	len = acpigen_write_name("SBLK");
	len += acpigen_write_byte(42);
	return len;
}


static int k8acpi_write_BUSN(void)
{
int len, lenp;

	len = acpigen_write_name("BUSN");
	lenp = acpigen_write_package(4);
	lenp += acpigen_write_dword(0x11111111);
	lenp += acpigen_write_dword(0x22222222);
	lenp += acpigen_write_dword(0x33333333);
	lenp += acpigen_write_dword(0x44444444);
// minus the opcode
	acpigen_patch_len(lenp - 1);
	return len + lenp;
}

int k8acpi_write_data(void)
{
	int lens;
	int ltot = 0;
//	char pscope[] = "\\._SB_PCI0";
	char pscope[] = "\\_SB.PCI0";
	char pscope1[] = "\\_SB";

	lens = acpigen_write_scope(pscope);
	lens += k8acpi_write_BUSN();
//      lens += acpigen_write_MMIO();
//      lens += acpigen_write_PCIO();
	lens += k8acpi_write_SBLK();
//      lens += acpigen_write_SBDN();
//      lens += acpigen_write_HCLK();
//      lens += acpigen_write_HCDN();
//      lens += acpigen_write_CBST();

	//minus opcode
	acpigen_patch_len(lens - 1);

	lens = acpigen_write_scope(pscope1);
	lens += k8acpi_write_TOM1();
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("TEST");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("TES");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("TE");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("T");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("\\Q");
	acpigen_patch_len(lens - 1);
	ltot += lens;
/*
	lens = acpigen_write_scope("^A");
	acpigen_patch_len(lens - 1);
	ltot += lens;
*/
	lens = acpigen_write_scope("\\QRTY");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("T.ASDF");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("T.ASD");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("T.AS");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("T.A");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("TEST.QWER.TYUI");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	lens = acpigen_write_scope("ALL.YOUR.BASE.ARE.BELO.NG.TO.US");
	acpigen_patch_len(lens - 1);
	ltot += lens;

	return ltot;
}


#include "assert.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>



//int pnow_gen_for_core(int core);
int k8acpi_write_data(void);


typedef unsigned char u8;
typedef unsigned int u32;

typedef struct acpi_table_header {	/* ACPI common table header */
	char signature[4];	/* ACPI signature (4 ASCII characters) */
	u32 length;		/* Length of table, in bytes, including header */
	u8 revision;		/* ACPI Specification minor version # */
	u8 checksum;		/* To make sum of entire table == 0 */
	char oem_id[6];		/* OEM identification */
	char oem_table_id[8];	/* OEM table identification */
	u32 oem_revision;	/* OEM revision number */
	char asl_compiler_id[4];	/* ASL compiler vendor ID */
	u32 asl_compiler_revision;	/* ASL compiler revision number */
} __attribute__ ((packed)) acpi_header_t;

//("SSDT.aml", "SSDT", 1, "AMD-K8", "AMD-ACPI", 100925440)
acpi_header_t *ssdt;
// = (acpi_header_t *) buffer;

char buffer[10000];

int main(void)
{
	int fd = open("test", O_RDWR|O_CREAT);
	ssdt = (acpi_header_t *) buffer;
	memcpy(&ssdt->signature, "SSDT", 4);
	ssdt->revision = 1;
	memcpy(&ssdt->oem_id, "COREBO", 6);
	memcpy(&ssdt->oem_table_id, "K8-ACPI ", 8);
	ssdt->oem_revision = 42;
	memcpy(&ssdt->asl_compiler_id, "GENAML", 4);
	ssdt->asl_compiler_revision = 42;

	acpigen_set_current(buffer+36);
	
	//pnow_gen();
	k8acpi_write_data();
	ssdt->length = (int) ((char *)acpigen_get_current() - &buffer[0]);
	write(fd, buffer, ssdt->length);
	close(fd);


	return 0;
}
-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to