Revision af8f3f514d193eb353f9b6cea503c55d074e6153 authored by Hanjun Guo on 04 January 2015, 10:55:02 UTC, committed by Rafael J. Wysocki on 05 January 2015, 22:32:42 UTC
apic_id in MADT table is the CPU hardware id which identify
it self in the system for x86 and ia64, OSPM will use it for
SMP init to map APIC ID to logical cpu number in the early
boot, when the DSDT/SSDT (ACPI namespace) is scanned later, the
ACPI processor driver is probed and the driver will use acpi_id
in DSDT to get the apic_id, then map to the logical cpu number
which is needed by the processor driver.

Before ACPI 5.0, only x86 and ia64 were supported in ACPI spec,
so apic_id is used both in arch code and ACPI core which is
pretty fine. Since ACPI 5.0, ARM is supported by ACPI and
APIC is not available on ARM, this will confuse people when
apic_id is both used by x86 and ARM in one function.

So convert apic_id to phys_id (which is the original meaning)
in ACPI processor dirver to make it arch agnostic, but leave the
arch dependent code unchanged, no functional change.

Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent b7392d2
Raw File
build_OID_registry
#!/usr/bin/perl -w
#
# Build a static ASN.1 Object Identified (OID) registry
#
# Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public Licence
# as published by the Free Software Foundation; either version
# 2 of the Licence, or (at your option) any later version.
#

use strict;

my @names = ();
my @oids = ();

if ($#ARGV != 1) {
    print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
    exit(2);
}

#
# Open the file to read from
#
open IN_FILE, "<$ARGV[0]" || die;
while (<IN_FILE>) {
    chomp;
    if (m!\s+OID_([a-zA-z][a-zA-Z0-9_]+),\s+/[*]\s+([012][.0-9]*)\s+[*]/!) {
	push @names, $1;
	push @oids, $2;
    }
}
close IN_FILE || die;

#
# Open the files to write into
#
open C_FILE, ">$ARGV[1]" or die;
print C_FILE "/*\n";
print C_FILE " * Automatically generated by ", $0, ".  Do not edit\n";
print C_FILE " */\n";

#
# Split the data up into separate lists and also determine the lengths of the
# encoded data arrays.
#
my @indices = ();
my @lengths = ();
my $total_length = 0;

for (my $i = 0; $i <= $#names; $i++) {
    my $name = $names[$i];
    my $oid = $oids[$i];

    my @components = split(/[.]/, $oid);

    # Determine the encoded length of this OID
    my $size = $#components;
    for (my $loop = 2; $loop <= $#components; $loop++) {
	my $c = $components[$loop];

	# We will base128 encode the number
	my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
	$tmp = int($tmp / 7);
	$size += $tmp;
    }
    push @lengths, $size;
    push @indices, $total_length;
    $total_length += $size;
}

#
# Emit the look-up-by-OID index table
#
print C_FILE "\n";
if ($total_length <= 255) {
    print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n";
} else {
    print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n";
}
for (my $i = 0; $i <= $#names; $i++) {
    print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n"
}
print C_FILE "\t[OID__NR] = ", $total_length, "\n";
print C_FILE "};\n";

#
# Encode the OIDs
#
my @encoded_oids = ();

for (my $i = 0; $i <= $#names; $i++) {
    my @octets = ();

    my @components = split(/[.]/, $oids[$i]);

    push @octets, $components[0] * 40 + $components[1];

    for (my $loop = 2; $loop <= $#components; $loop++) {
	my $c = $components[$loop];

	# Base128 encode the number
	my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
	$tmp = int($tmp / 7);

	for (; $tmp > 0; $tmp--) {
	    push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
	}
	push @octets, $c & 0x7f;
    }

    push @encoded_oids, \@octets;
}

#
# Create a hash value for each OID
#
my @hash_values = ();
for (my $i = 0; $i <= $#names; $i++) {
    my @octets = @{$encoded_oids[$i]};

    my $hash = $#octets;
    foreach (@octets) {
	$hash += $_ * 33;
    }

    $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash);

    push @hash_values, $hash & 0xff;
}

#
# Emit the OID data
#
print C_FILE "\n";
print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n";
for (my $i = 0; $i <= $#names; $i++) {
    my @octets = @{$encoded_oids[$i]};
    print C_FILE "\t";
    print C_FILE $_, ", " foreach (@octets);
    print C_FILE "\t// ", $names[$i];
    print C_FILE "\n";
}
print C_FILE "};\n";

#
# Build the search index table (ordered by length then hash then content)
#
my @index_table = ( 0 .. $#names );

@index_table = sort {
    my @octets_a = @{$encoded_oids[$a]};
    my @octets_b = @{$encoded_oids[$b]};

    return $hash_values[$a] <=> $hash_values[$b]
	if ($hash_values[$a] != $hash_values[$b]);
    return $#octets_a <=> $#octets_b
	if ($#octets_a != $#octets_b);
    for (my $i = $#octets_a; $i >= 0; $i--) {
	return $octets_a[$i] <=> $octets_b[$i]
	    if ($octets_a[$i] != $octets_b[$i]);
    }
    return 0;

} @index_table;

#
# Emit the search index and hash value table
#
print C_FILE "\n";
print C_FILE "static const struct {\n";
print C_FILE "\tunsigned char hash;\n";
if ($#names <= 255) {
    print C_FILE "\tenum OID oid : 8;\n";
} else {
    print C_FILE "\tenum OID oid : 16;\n";
}
print C_FILE "} oid_search_table[OID__NR] = {\n";
for (my $i = 0; $i <= $#names; $i++) {
    my @octets = @{$encoded_oids[$index_table[$i]]};
    printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ",
	   $i,
	   $hash_values[$index_table[$i]],
	   $names[$index_table[$i]]);
    printf C_FILE "%02x", $_ foreach (@octets);
    print C_FILE "\n";
}
print C_FILE "};\n";

#
# Emit the OID debugging name table
#
#print C_FILE "\n";
#print C_FILE "const char *const oid_name_table[OID__NR + 1] = {\n";
#
#for (my $i = 0; $i <= $#names; $i++) {
#    print C_FILE "\t\"", $names[$i], "\",\n"
#}
#print C_FILE "\t\"Unknown-OID\"\n";
#print C_FILE "};\n";

#
# Polish off
#
close C_FILE or die;
back to top