[Midnightbsd-cvs] src [11957] trunk/tools/tools/drm: add drm

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jul 22 15:26:19 EDT 2018


Revision: 11957
          http://svnweb.midnightbsd.org/src/?rev=11957
Author:   laffer1
Date:     2018-07-22 15:26:19 -0400 (Sun, 22 Jul 2018)
Log Message:
-----------
add drm

Added Paths:
-----------
    trunk/tools/tools/drm/
    trunk/tools/tools/drm/README
    trunk/tools/tools/drm/gen-drm_pciids
    trunk/tools/tools/drm/radeon/
    trunk/tools/tools/drm/radeon/README
    trunk/tools/tools/drm/radeon/firmwares/
    trunk/tools/tools/drm/radeon/firmwares/README
    trunk/tools/tools/drm/radeon/firmwares/encode-firmwares
    trunk/tools/tools/drm/radeon/mkregtable/
    trunk/tools/tools/drm/radeon/mkregtable/Makefile
    trunk/tools/tools/drm/radeon/mkregtable/README
    trunk/tools/tools/drm/radeon/mkregtable/mkregtable.c

Added: trunk/tools/tools/drm/README
===================================================================
--- trunk/tools/tools/drm/README	                        (rev 0)
+++ trunk/tools/tools/drm/README	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,5 @@
+# $MidnightBSD$
+
+gen-drm_pciids	Generate drm_pciids.h based on Linux' drm_pciids.h, FreeBSD's
+		drm_pciids.h and misc/pciids database.
+radeon		Tools specific to the Radeon device driver.


Property changes on: trunk/tools/tools/drm/README
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/gen-drm_pciids
===================================================================
--- trunk/tools/tools/drm/gen-drm_pciids	                        (rev 0)
+++ trunk/tools/tools/drm/gen-drm_pciids	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,183 @@
+#!/usr/bin/perl
+# $MidnightBSD$
+
+use strict;
+use warnings;
+use utf8;
+
+use File::Basename;
+
+my $progname = basename($0);
+
+sub parse_linux_header ($)
+{
+    my ($header) = @_;
+
+    open(my $fh, '<', $header) or die "Can't open Linux header: $!\n";
+
+    my $in_list = 0;
+
+    my %pciids = ();
+
+    my $current_vendor_define;
+
+    while (my $line = <$fh>) {
+        if ($line =~ /^#define +([^ ]+) +/) {
+            $current_vendor_define = $1;
+            $pciids{$current_vendor_define} = {};
+        } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}),[^,]+,[^,]+,[^,]+,[^,]+, *([^}]+)\}/) {
+            my $vendor_id = uc($1);
+            my $device_id = uc($2);
+            my $flags     = $3;
+
+            $pciids{$current_vendor_define}{$device_id} = {
+                'vendor_id' => $vendor_id,
+                'flags'     => $flags
+            };
+        }
+    }
+
+    close($fh);
+
+    return %pciids;
+}
+
+sub parse_freebsd_header ($) {
+    my ($header) = @_;
+
+    open(my $fh, '<', $header) or die "Can't open FreeBSD header: $!\n";
+
+    my $in_list = 0;
+
+    my %pciids = ();
+
+    my $current_vendor_define;
+
+    while (my $line = <$fh>) {
+        if ($line =~ /^#define +([^ ]+) +/) {
+            $current_vendor_define = $1;
+            $pciids{$current_vendor_define} = {};
+        } elsif ($line =~ /^\t\{0x([0-9a-fA-F]{4}), *0x([0-9a-fA-F]{4}), *([^,]+), *"([^"]+)"\}/) {
+            my $vendor_id = uc($1);
+            my $device_id = uc($2);
+            my $flags     = $3;
+            my $name      = $4;
+
+            $pciids{$current_vendor_define}{$device_id} = {
+                'vendor_id' => $vendor_id,
+                'flags'     => $flags,
+                'name'      => $name
+            };
+        }
+    }
+
+    close($fh);
+
+    return %pciids;
+}
+
+sub parse_pciids_db ($) {
+    my ($header) = @_;
+
+    open(my $fh, '<', $header) or die "Can't open PCI IDs database: $!\n";
+
+    my %pciids = ();
+
+    my $current_vendor_id;
+
+    while (my $line = <$fh>) {
+        if (!$line || $line =~ /^#/) {
+            next;
+        }
+        if ($line =~ /^([0-9a-fA-F]{4})  (.+)/) {
+            # Vendor ID & name.
+            my $vendor_id   = uc($1);
+            my $vendor_name = $2;
+            $pciids{$vendor_id} = {
+                'name'    => $vendor_name,
+                'devices' => {}
+            };
+
+            $current_vendor_id = $vendor_id;
+        } elsif ($line =~ /^\t([0-9a-fA-F]{4})  (.+)/) {
+            # Device ID & name.
+            my $device_id   = uc($1);
+            my $device_name = $2;
+            $pciids{$current_vendor_id}{'devices'}{$device_id} = $device_name;
+        }
+    }
+
+    close($fh);
+
+    return %pciids;
+}
+
+if (scalar(@ARGV) != 3) {
+    print STDERR "Syntax: $progname <linux_header> <freebsd_header> <pciids_db> [<vendor_define>]\n";
+    exit 1;
+}
+
+my $linux_header   = $ARGV[0];
+my $freebsd_header = $ARGV[1];
+my $pciids_db      = $ARGV[2];
+my $only_vendor    = $ARGV[3];
+
+my %linux_pciids   = parse_linux_header($linux_header);
+my %freebsd_pciids = parse_freebsd_header($freebsd_header);
+my %pciids_db      = parse_pciids_db($pciids_db);
+
+print STDERR "Update FreeBSD's PCI IDs:\n";
+foreach my $vendor_define (sort keys(%linux_pciids)) {
+    if ($only_vendor && $vendor_define ne $only_vendor) {
+        print STDERR "(skip unwanted define: $vendor_define)\n";
+        next;
+    } elsif (!$only_vendor && !exists($freebsd_pciids{$vendor_define})) {
+        print STDERR "(skip unsupport define: $vendor_define)\n";
+        next;
+    }
+
+    foreach my $device_id (sort keys(%{$linux_pciids{$vendor_define}})) {
+        my $vendor_id = $linux_pciids{$vendor_define}{$device_id}{'vendor_id'};
+
+        if (exists($freebsd_pciids{$vendor_define}{$device_id})) {
+            print STDERR "  $vendor_define: $vendor_id:$device_id already in header\n";
+            next;
+        }
+
+        my $flags     = $linux_pciids{$vendor_define}{$device_id}{'flags'};
+        my $name      = $pciids_db{$vendor_id}{'devices'}{$device_id} || "Unknown device name";
+        print STDERR "  $vendor_define: $vendor_id:$device_id is missing ($name)\n";
+        $freebsd_pciids{$vendor_define}{$device_id} = {
+            'vendor_id' => $vendor_id,
+            'flags'     => $flags,
+            'name'      => $name
+        };
+    }
+}
+
+print STDERR "\nWrite FreeBSD header to stdout...\n";
+print <<"EOF";
+/*
+ * \$FreeBSD\$
+ */
+
+/*
+ * Generated by $progname from:
+ *   o  previous FreeBSD's drm_pciids.h
+ *   o  Linux' drm_pciids.h
+ *   o  the PCI ID repository (http://pciids.sourceforge.net/)
+ *
+ * See tools/tools/drm/$progname.
+ */
+EOF
+foreach my $vendor_define (sort keys(%freebsd_pciids)) {
+    print "\n#define $vendor_define \\\n";
+    foreach my $device_id (sort keys(%{$freebsd_pciids{$vendor_define}})) {
+        my $vendor_id = $freebsd_pciids{$vendor_define}{$device_id}{'vendor_id'};
+        my $flags     = $freebsd_pciids{$vendor_define}{$device_id}{'flags'};
+        my $name      = $freebsd_pciids{$vendor_define}{$device_id}{'name'};
+
+        print "\t{0x$vendor_id, 0x$device_id, $flags, \"$name\"}, \\\n";
+    }
+    print "\t{0, 0, 0, NULL}\n";
+}


Property changes on: trunk/tools/tools/drm/gen-drm_pciids
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/README
===================================================================
--- trunk/tools/tools/drm/radeon/README	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/README	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,5 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/tools/tools/drm/radeon/README 254885 2013-08-25 19:37:15Z dumbbell $
+
+firmwares	Tools to handle Radeon firmwares imported into the tree.
+mkregtable	Generate headers used to build the Radeon driver.


Property changes on: trunk/tools/tools/drm/radeon/README
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/firmwares/README
===================================================================
--- trunk/tools/tools/drm/radeon/firmwares/README	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/firmwares/README	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,10 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/tools/tools/drm/radeon/firmwares/README 254885 2013-08-25 19:37:15Z dumbbell $
+
+To update firmwares:
+
+    1. Clone the following Git repository:
+       git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
+
+    2. Run this script as:
+       ./encode-firmwares /path/to/linux-firmwares/radeon


Property changes on: trunk/tools/tools/drm/radeon/firmwares/README
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/firmwares/encode-firmwares
===================================================================
--- trunk/tools/tools/drm/radeon/firmwares/encode-firmwares	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/firmwares/encode-firmwares	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $MidnightBSD$
+
+set -e
+
+scriptdir=$(cd $(dirname $0) && pwd)
+fwdir="$scriptdir/../../../../../sys/contrib/dev/drm2/radeonkmsfw"
+srcdir=$1
+
+if [ -z "$srcdir" -o ! -d "$srcdir" ]; then
+	echo "Syntax: $(basename $0) <path to original firmwares>" 1>&2
+	exit
+fi
+
+for file in "$srcdir"/*.bin; do
+	uuencode -o "$fwdir"/$(basename $file).uu $file $(basename $file)
+done


Property changes on: trunk/tools/tools/drm/radeon/firmwares/encode-firmwares
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/mkregtable/Makefile
===================================================================
--- trunk/tools/tools/drm/radeon/mkregtable/Makefile	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/mkregtable/Makefile	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,59 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/tools/tools/drm/radeon/mkregtable/Makefile 276486 2014-12-31 23:25:37Z ngie $
+
+all: regtables
+
+PROG=	mkregtable
+
+SRCS=	mkregtable.c
+
+MAN=
+
+MKREGTABLE=	${PROG}
+KERNSRCDIR=	${.CURDIR}/../../../../../sys
+REG_SRCS_DIR=	${KERNSRCDIR}/dev/drm2/radeon/reg_srcs
+REG_DEST_DIR=	${KERNSRCDIR}/dev/drm2/radeon
+
+regtables:					\
+	${REG_DEST_DIR}/rn50_reg_safe.h		\
+	${REG_DEST_DIR}/r100_reg_safe.h		\
+	${REG_DEST_DIR}/r200_reg_safe.h		\
+	${REG_DEST_DIR}/rv515_reg_safe.h	\
+	${REG_DEST_DIR}/r300_reg_safe.h		\
+	${REG_DEST_DIR}/r420_reg_safe.h		\
+	${REG_DEST_DIR}/rs600_reg_safe.h	\
+	${REG_DEST_DIR}/r600_reg_safe.h		\
+	${REG_DEST_DIR}/evergreen_reg_safe.h	\
+	${REG_DEST_DIR}/cayman_reg_safe.h
+
+${REG_DEST_DIR}/rn50_reg_safe.h: ${REG_SRCS_DIR}/rn50 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/rn50 > $@
+
+${REG_DEST_DIR}/r100_reg_safe.h: ${REG_SRCS_DIR}/r100 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/r100 > $@
+
+${REG_DEST_DIR}/r200_reg_safe.h: ${REG_SRCS_DIR}/r200 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/r200 > $@
+
+${REG_DEST_DIR}/rv515_reg_safe.h: ${REG_SRCS_DIR}/rv515 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/rv515 > $@
+
+${REG_DEST_DIR}/r300_reg_safe.h: ${REG_SRCS_DIR}/r300 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/r300 > $@
+
+${REG_DEST_DIR}/r420_reg_safe.h: ${REG_SRCS_DIR}/r420 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/r420 > $@
+
+${REG_DEST_DIR}/rs600_reg_safe.h: ${REG_SRCS_DIR}/rs600 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/rs600 > $@
+
+${REG_DEST_DIR}/r600_reg_safe.h: ${REG_SRCS_DIR}/r600 ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/r600 > $@
+
+${REG_DEST_DIR}/evergreen_reg_safe.h: ${REG_SRCS_DIR}/evergreen ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/evergreen > $@
+
+${REG_DEST_DIR}/cayman_reg_safe.h: ${REG_SRCS_DIR}/cayman ${MKREGTABLE}
+	./${MKREGTABLE} ${REG_SRCS_DIR}/cayman > $@
+
+.include <bsd.prog.mk>


Property changes on: trunk/tools/tools/drm/radeon/mkregtable/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/mkregtable/README
===================================================================
--- trunk/tools/tools/drm/radeon/mkregtable/README	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/mkregtable/README	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,7 @@
+# $MidnightBSD$
+
+"mkregtable" is a tool used to generate headers for the radeonkms
+driver. Headers are regenerated by running "make" in this directory.
+
+Header source files are in sys/dev/drm2/radeon/reg_srcs.
+Generated headers are placed in sys/dev/drm2/radeon.


Property changes on: trunk/tools/tools/drm/radeon/mkregtable/README
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: trunk/tools/tools/drm/radeon/mkregtable/mkregtable.c
===================================================================
--- trunk/tools/tools/drm/radeon/mkregtable/mkregtable.c	                        (rev 0)
+++ trunk/tools/tools/drm/radeon/mkregtable/mkregtable.c	2018-07-22 19:26:19 UTC (rev 11957)
@@ -0,0 +1,734 @@
+/* $MidnightBSD$ */
+/* utility to create the register check tables
+ * this includes inlined list.h safe for userspace.
+ *
+ * Copyright 2009 Jerome Glisse
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Authors:
+ * 	Jerome Glisse
+ * 	Dave Airlie
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/tools/tools/drm/radeon/mkregtable/mkregtable.c 254885 2013-08-25 19:37:15Z dumbbell $");
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <regex.h>
+#include <libgen.h>
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({          \
+	const typeof(((type *)0)->member)*__mptr = (ptr);    \
+		     (type *)((char *)__mptr - offsetof(type, member)); })
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *new,
+			      struct list_head *prev, struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+#else
+extern void __list_add(struct list_head *new,
+		       struct list_head *prev, struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head *prev, struct list_head *next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = (void *)0xDEADBEEF;
+	entry->prev = (void *)0xBEEFDEAD;
+}
+#else
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old, struct list_head *new)
+{
+	new->next = old->next;
+	new->next->prev = new;
+	new->prev = old->prev;
+	new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+				     struct list_head *new)
+{
+	list_replace(old, new);
+	INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+				  struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+			       const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+	return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+				       struct list_head *head,
+				       struct list_head *entry)
+{
+	struct list_head *new_first = entry->next;
+	list->next = head->next;
+	list->next->prev = list;
+	list->prev = entry;
+	entry->next = list;
+	head->next = new_first;
+	new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ *	and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+				     struct list_head *head,
+				     struct list_head *entry)
+{
+	if (list_empty(head))
+		return;
+	if (list_is_singular(head) && (head->next != entry && head != entry))
+		return;
+	if (entry == head)
+		INIT_LIST_HEAD(list);
+	else
+		__list_cut_position(list, head, entry);
+}
+
+static inline void __list_splice(const struct list_head *list,
+				 struct list_head *prev, struct list_head *next)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+
+	first->prev = prev;
+	prev->next = first;
+
+	last->next = next;
+	next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+			       struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head, head->next);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+					 struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head->prev, head);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+		pos = pos->next)
+
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev	-	iterate over a list backwards
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+		pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+	for (pos = (head)->prev, n = pos->prev; \
+	     prefetch(pos->prev), pos != (head); \
+	     pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head); 	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:	the type * to use as a start point
+ * @head:	the head of the list
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+	((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member)		\
+	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head);	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) 			\
+	for (; prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
+		n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) 			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		n = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+struct offset {
+	struct list_head list;
+	unsigned offset;
+};
+
+struct table {
+	struct list_head offsets;
+	unsigned offset_max;
+	unsigned nentry;
+	unsigned *table;
+	char *gpu_prefix;
+};
+
+static struct offset *offset_new(unsigned o)
+{
+	struct offset *offset;
+
+	offset = (struct offset *)malloc(sizeof(struct offset));
+	if (offset) {
+		INIT_LIST_HEAD(&offset->list);
+		offset->offset = o;
+	}
+	return offset;
+}
+
+static void table_offset_add(struct table *t, struct offset *offset)
+{
+	list_add_tail(&offset->list, &t->offsets);
+}
+
+static void table_init(struct table *t)
+{
+	INIT_LIST_HEAD(&t->offsets);
+	t->offset_max = 0;
+	t->nentry = 0;
+	t->table = NULL;
+}
+
+static void table_print(struct table *t)
+{
+	unsigned nlloop, i, j, n, c, id;
+
+	nlloop = (t->nentry + 3) / 4;
+	c = t->nentry;
+	printf(
+	    "#include <sys/cdefs.h>\n"
+	    "__FBSDID(\"$" "FreeBSD" "$\");\n"
+	    "\n"
+	    );
+	printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
+	       t->nentry);
+	for (i = 0, id = 0; i < nlloop; i++) {
+		n = 4;
+		if (n > c)
+			n = c;
+		c -= n;
+		for (j = 0; j < n; j++) {
+			if (j == 0)
+				printf("\t");
+			else
+				printf(" ");
+			printf("0x%08X,", t->table[id++]);
+		}
+		printf("\n");
+	}
+	printf("};\n");
+}
+
+static int table_build(struct table *t)
+{
+	struct offset *offset;
+	unsigned i, m;
+
+	t->nentry = ((t->offset_max >> 2) + 31) / 32;
+	t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
+	if (t->table == NULL)
+		return -1;
+	memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
+	list_for_each_entry(offset, &t->offsets, list) {
+		i = (offset->offset >> 2) / 32;
+		m = (offset->offset >> 2) & 31;
+		m = 1 << m;
+		t->table[i] ^= m;
+	}
+	return 0;
+}
+
+static char gpu_name[10];
+static int parser_auth(struct table *t, const char *filename)
+{
+	FILE *file;
+	regex_t mask_rex;
+	regmatch_t match[4];
+	char buf[1024];
+	size_t end;
+	int len;
+	int done = 0;
+	int r;
+	unsigned o;
+	struct offset *offset;
+	char last_reg_s[10];
+	int last_reg;
+
+	if (regcomp
+	    (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
+		fprintf(stderr, "Failed to compile regular expression\n");
+		return -1;
+	}
+	file = fopen(filename, "r");
+	if (file == NULL) {
+		fprintf(stderr, "Failed to open: %s\n", filename);
+		return -1;
+	}
+	fseek(file, 0, SEEK_END);
+	end = ftell(file);
+	fseek(file, 0, SEEK_SET);
+
+	/* get header */
+	if (fgets(buf, 1024, file) == NULL) {
+		fclose(file);
+		return -1;
+	}
+
+	/* first line will contain the last register
+	 * and gpu name */
+	sscanf(buf, "%s %s", gpu_name, last_reg_s);
+	t->gpu_prefix = gpu_name;
+	last_reg = strtol(last_reg_s, NULL, 16);
+
+	do {
+		if (fgets(buf, 1024, file) == NULL) {
+			fclose(file);
+			return -1;
+		}
+		len = strlen(buf);
+		if (ftell(file) == end)
+			done = 1;
+		if (len) {
+			r = regexec(&mask_rex, buf, 4, match, 0);
+			if (r == REG_NOMATCH) {
+			} else if (r) {
+				fprintf(stderr,
+					"Error matching regular expression %d in %s\n",
+					r, filename);
+				fclose(file);
+				return -1;
+			} else {
+				buf[match[0].rm_eo] = 0;
+				buf[match[1].rm_eo] = 0;
+				buf[match[2].rm_eo] = 0;
+				o = strtol(&buf[match[1].rm_so], NULL, 16);
+				offset = offset_new(o);
+				table_offset_add(t, offset);
+				if (o > t->offset_max)
+					t->offset_max = o;
+			}
+		}
+	} while (!done);
+	fclose(file);
+	if (t->offset_max < last_reg)
+		t->offset_max = last_reg;
+	return table_build(t);
+}
+
+int main(int argc, char *argv[])
+{
+	struct table t;
+
+	if (argc != 2) {
+		fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
+		exit(1);
+	}
+	table_init(&t);
+	if (parser_auth(&t, argv[1])) {
+		fprintf(stderr, "Failed to parse file %s\n", argv[1]);
+		return -1;
+	}
+	table_print(&t);
+	return 0;
+}


Property changes on: trunk/tools/tools/drm/radeon/mkregtable/mkregtable.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list