[LinuxBIOS] r418 - in LinuxBIOSv3: arch/x86 device include include/arch/x86 include/arch/x86/arch include/device lib util/dtc
svn at openbios.org
svn at openbios.org
Fri Jun 29 18:57:23 CEST 2007
Author: stepan
Date: 2007-06-29 18:57:23 +0200 (Fri, 29 Jun 2007)
New Revision: 418
Added:
LinuxBIOSv3/include/arch/x86/arch/elf.h
LinuxBIOSv3/include/arch/x86/arch/spinlock.h
Removed:
LinuxBIOSv3/include/arch/x86/archelf.h
LinuxBIOSv3/include/stdlib.h
LinuxBIOSv3/lib/malloc.c
Modified:
LinuxBIOSv3/arch/x86/Kconfig
LinuxBIOSv3/arch/x86/Makefile
LinuxBIOSv3/arch/x86/stage1.c
LinuxBIOSv3/device/device.c
LinuxBIOSv3/include/device/device.h
LinuxBIOSv3/include/elf.h
LinuxBIOSv3/lib/console.c
LinuxBIOSv3/util/dtc/dtc-parser.y
Log:
* start using arch/foo.h again instead of archfoo.h (trivial)
* make constructor an initializer.
* fix memory leak/code flow error in current code
* add spinlocking
* drop malloc and use new_device for device allocation instead.
* add CONFIG_SMP as it is needed by spinlocks and soon other stuff.
Signed-off-by: Stefan Reinauer <stepan at coresystems.de>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>
Modified: LinuxBIOSv3/arch/x86/Kconfig
===================================================================
--- LinuxBIOSv3/arch/x86/Kconfig 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/arch/x86/Kconfig 2007-06-29 16:57:23 UTC (rev 418)
@@ -55,3 +55,11 @@
a battery backed up real time clock with CMOS NVRAM.
It is usually set in mainboard/*/Kconfig.
+config SMP
+ boolean
+ help
+ This option is used to enable certain functions to make
+ LinuxBIOS work correctly on symmetric multi processor
+ systems.
+ It is usually set in mainboard/*/Kconfig.
+
Modified: LinuxBIOSv3/arch/x86/Makefile
===================================================================
--- LinuxBIOSv3/arch/x86/Makefile 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/arch/x86/Makefile 2007-06-29 16:57:23 UTC (rev 418)
@@ -123,8 +123,7 @@
# TODO: This should be compressed with the default compressor.
#
-STAGE2_LIB_OBJ = stage2.o clog2.o mem.o malloc.o tables.o delay.o \
- compute_ip_checksum.o
+STAGE2_LIB_OBJ = stage2.o clog2.o mem.o tables.o delay.o compute_ip_checksum.o
STAGE2_ARCH_X86_OBJ = archtables.o linuxbios_table.o udelay_io.o
STAGE2_ARCH_X86_OBJ += pci_ops_auto.o pci_ops_conf1.o pci_ops_conf2.o
Modified: LinuxBIOSv3/arch/x86/stage1.c
===================================================================
--- LinuxBIOSv3/arch/x86/stage1.c 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/arch/x86/stage1.c 2007-06-29 16:57:23 UTC (rev 418)
@@ -119,12 +119,15 @@
if (ret)
die("Failed RAM init code\n");
- printk(BIOS_INFO, "Done RAM init code\n");
- /* this is nasty. And, it has to be done this way. Sorry! */
- /* we have to turn off CAR, and do some other things, and it has to be done
- * inline -- you can't call a function
- */
+ printk(BIOS_DEBUG, "Done RAM init code\n");
+
+ /* Turn off Cache-As-Ram, and do some other things.
+ *
+ * This has to be done inline -- You can't call a function because the
+ * return stack does not survive.
+ */
+
__asm__ volatile (
/*
FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
Modified: LinuxBIOSv3/device/device.c
===================================================================
--- LinuxBIOSv3/device/device.c 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/device/device.c 2007-06-29 16:57:23 UTC (rev 418)
@@ -10,8 +10,9 @@
* Copyright (C) 2003 Ronald G. Minnich <rminnich at gmail.com>
* Copyright (C) 2004-2005 Li-Ta Lo <ollie at lanl.gov>
* Copyright (C) 2005-2006 Tyan
- * (Written by Yinghai Lu <yhlu at tyan.com> for Tyan)
+ * (Written by Yinghai Lu for Tyan)
* Copyright (C) 2005-2006 Stefan Reinauer <stepan at openbios.org>
+ * Copyright (C) 2007 coresystems GmbH
*/
/*
@@ -34,10 +35,8 @@
#include <device/pci.h>
#include <device/pci_ids.h>
#include <string.h>
-#include <stdlib.h>
#include <lib.h>
-#warning Do we need spinlocks in device/device.c?
-//#include <smp/spinlock.h>
+#include <spinlock.h>
/** Linked list of all devices. */
struct device *all_devices = &dev_root;
@@ -61,6 +60,34 @@
#define DEVICE_IO_START 0x1000
/**
+ * device memory. All the device tree wil live here
+ */
+
+#define MAX_DEVICES 256
+static struct device devs[MAX_DEVICES];
+
+/**
+ * The device creator.
+ *
+ * reserves a piece of memory for a device in the tree
+ *
+ * @return Pointer to the newly created device structure.
+ */
+
+static struct device *new_device(void)
+{
+ static int devcnt=0;
+ devcnt++;
+
+ /* Should we really die here? */
+ if (devcnt>=MAX_DEVICES) {
+ die("Too many devices. Increase MAX_DEVICES\n");
+ }
+
+ return &devs[devcnt];
+}
+
+/**
* Initialization tasks for the device tree code.
*
* At present, merely sets up last_dev_p, which used to be done by
@@ -76,27 +103,17 @@
}
/**
- * The default constructor, which simply allocates and sets the ops pointer.
+ * The default constructor, which simply sets the ops pointer.
*
- * Allocate a new device structure and initialize device->ops.
+ * Initialize device->ops of a newly allocated device structure.
*
+ * @param dev Pointer to the newly created device structure.
* @param constructor A pointer to a struct constructor.
- * @return Pointer to the newly created device structure.
*/
-struct device *default_device_constructor(struct constructor *constructor)
+void default_device_constructor(struct device *dev, struct constructor *constructor)
{
- struct device *dev;
- dev = malloc(sizeof(*dev));
-
- // FIXME: This is overkill. Our malloc() will never return with
- // a return value of NULL. So this is dead code (and thus would
- // drop code coverage and usability in safety critical environments.
- if (dev == NULL) {
- die("DEV: out of memory.\n");
- }
- memset(dev, 0, sizeof(dev));
+ printk(BIOS_DEBUG, "default device constructor called\n");
dev->ops = constructor->ops;
- return dev;
}
/**
@@ -119,9 +136,6 @@
printk(BIOS_SPEW, "%s: cons 0x%lx, cons id %s\n",
__func__, c, dev_id_string(&c->id));
if ((!c->ops) || (!c->ops->constructor)) {
- printk(BIOS_INFO,
- "Constructor for %s with missing ops or ops->constructor!\n",
- dev_id_string(&c->id));
continue;
}
if (id_eq(&c->id, id)) {
@@ -131,7 +145,7 @@
}
}
- return 0;
+ return NULL;
}
/**
@@ -141,23 +155,22 @@
* Call that constructor via constructor->ops->constructor, with itself as
* a parameter; return the result.
*
+ * @param dev Pointer to the newly created device structure.
* @param path Path to the device to be created.
- * @return Pointer to the newly created device structure.
* @see device_path
*/
-struct device *constructor(struct device_id *id)
+void constructor(struct device *dev, struct device_id *id)
{
struct constructor *c;
- struct device *dev = 0;
c = find_constructor(id);
- printk(BIOS_DEBUG, "%s constructor is 0x%lx\n", __func__, c);
- if (!c)
- return 0;
-
- dev = c->ops->constructor(c);
- printk(BIOS_DEBUG, "%s returns 0x%lx\n", __func__, dev);
- return dev;
+ printk(BIOS_SPEW, "%s: constructor is 0x%lx\n", __func__, c);
+
+ if(c && c->ops && c->ops->constructor)
+ c->ops->constructor(dev, c);
+ else
+ printk(BIOS_INFO, "No constructor called for %s.\n",
+ dev_id_string(&c->id));
}
/**
@@ -177,24 +190,18 @@
struct device *dev, *child;
int link;
-// spin_lock(&dev_lock);
+ spin_lock(&dev_lock);
/* Find the last child of our parent. */
for (child = parent->children; child && child->sibling; /* */) {
child = child->sibling;
}
- dev = constructor(devid);
- if (!dev)
- printk(BIOS_DEBUG, "%s: No constructor, going with empty dev",
- dev_id_string(devid));
+ dev = new_device();
+ if (!dev) /* Please don't do this at home */
+ goto out;
- dev = malloc(sizeof(*dev));
- if (dev == NULL) {
- die("DEV: out of memory.\n");
- }
memset(dev, 0, sizeof(*dev));
-
memcpy(&dev->path, path, sizeof(*path));
/* Initialize the back pointers in the link fields. */
@@ -223,7 +230,14 @@
/* Give the device a name. */
sprintf(dev->dtsname, "dynamic %s", dev_path(dev));
- // spin_unlock(&dev_lock);
+ /* Run the device specific constructor as last part of the chain
+ * so it gets the chance to overwrite the "inherited" values above
+ */
+
+ constructor(dev, devid);
+
+out:
+ spin_unlock(&dev_lock);
return dev;
}
Copied: LinuxBIOSv3/include/arch/x86/arch/elf.h (from rev 417, LinuxBIOSv3/include/arch/x86/archelf.h)
===================================================================
--- LinuxBIOSv3/include/arch/x86/arch/elf.h (rev 0)
+++ LinuxBIOSv3/include/arch/x86/arch/elf.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -0,0 +1,8 @@
+#ifndef ARCH_ELF_H
+#define ARCH_ELF_H
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_386
+
+#endif /* ARCH_ELF_H */
Added: LinuxBIOSv3/include/arch/x86/arch/spinlock.h
===================================================================
--- LinuxBIOSv3/include/arch/x86/arch/spinlock.h (rev 0)
+++ LinuxBIOSv3/include/arch/x86/arch/spinlock.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2001 Linux Networx
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef ARCH_SPINLOCK_H
+#define ARCH_SPINLOCK_H
+
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ */
+
+typedef struct {
+ volatile unsigned int lock;
+} spinlock_t;
+
+
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+
+/*
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+#define barrier() __asm__ __volatile__("": : :"memory")
+#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0)
+#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+
+#define spin_lock_string \
+ "\n1:\t" \
+ "lock ; decb %0\n\t" \
+ "js 2f\n" \
+ ".section .text.lock,\"ax\"\n" \
+ "2:\t" \
+ "cmpb $0,%0\n\t" \
+ "rep;nop\n\t" \
+ "jle 2b\n\t" \
+ "jmp 1b\n" \
+ ".previous"
+
+/*
+ * This works. Despite all the confusion.
+ */
+#define spin_unlock_string \
+ "movb $1,%0"
+
+static inline __attribute__((always_inline)) void spin_lock(spinlock_t *lock)
+{
+ __asm__ __volatile__(
+ spin_lock_string
+ :"=m" (lock->lock) : : "memory");
+}
+
+static inline __attribute__((always_inline)) void spin_unlock(spinlock_t *lock)
+{
+ __asm__ __volatile__(
+ spin_unlock_string
+ :"=m" (lock->lock) : : "memory");
+}
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static inline __attribute__((always_inline)) void cpu_relax(void)
+{
+ __asm__ __volatile__("rep;nop": : :"memory");
+}
+
+#endif /* ARCH_SPINLOCK_H */
Deleted: LinuxBIOSv3/include/arch/x86/archelf.h
===================================================================
--- LinuxBIOSv3/include/arch/x86/archelf.h 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/include/arch/x86/archelf.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -1,8 +0,0 @@
-#ifndef ARCH_X86_ARCHELF_H
-#define ARCH_X86_ARCHELF_H
-
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2LSB
-#define ELF_ARCH EM_386
-
-#endif /* ARCH_X86_ARCHELF_H */
Modified: LinuxBIOSv3/include/device/device.h
===================================================================
--- LinuxBIOSv3/include/device/device.h 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/include/device/device.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -112,18 +112,21 @@
void (*set_link)(struct device * dev, unsigned int link);
void (*reset_bus)(struct bus *bus);
- /* a constructor. The constructor for a given device is defined in the device source file.
- * When is this called? Not for the static tree. When the scan bus code finds a new device, it must
- * create it and insert it into the device tree. To do this, it calls a device constructor.
- * The set of all device constructors is concatenated into the constructors array of structures via the usual
- * gcc hack of naming a segment.
- * The dev_constructor code in device.c iterates over the constructors array.
- * A match consists of a path type, a vendor (which may be ignored if the constructo vendor value is 0),
- * and a device id.
- * When it finds a match, the dev_constructor calls the
- * function constructors->constructor(constructors->constructor) and a new device is created.
+ /* A constructor. The constructor for a given device is defined in the
+ * device source file. When is this called? Not for the static tree.
+ * When the scan bus code finds a new device, it must create it and
+ * insert it into the device tree. To initialize it, it calls a device
+ * constructor. The set of all device constructors is concatenated
+ * into the constructors array of structures.
+ *
+ * The dev_constructor code in device.c iterates over the constructors
+ * array. A match consists of a path type, a vendor (which may be
+ * ignored if the constructor vendor value is 0), and a device id.
+ * When it finds a match, the dev_constructor calls the function
+ * constructors->constructor(constructors->constructor) and a new
+ * device is created.
*/
- struct device *(*constructor)(struct constructor *);
+ void (*constructor)(struct device *, struct constructor *);
/* set device ops */
void (*phase1_set_device_operations)(struct device *dev);
@@ -245,7 +248,7 @@
struct device * dev_find_class (unsigned int class, struct device * from);
struct device * dev_find_slot (unsigned int bus, unsigned int devfn);
struct device * dev_find_slot_on_smbus (unsigned int bus, unsigned int addr);
-struct device *default_device_constructor(struct constructor *constructor);
+void default_device_constructor(struct device *dev, struct constructor *constructor);
/* Rounding for boundaries.
Modified: LinuxBIOSv3/include/elf.h
===================================================================
--- LinuxBIOSv3/include/elf.h 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/include/elf.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -31,7 +31,7 @@
#define ELF_H
#include <types.h>
-#include <archelf.h>
+#include <arch/elf.h>
/* Standard ELF types. */
Deleted: LinuxBIOSv3/include/stdlib.h
===================================================================
--- LinuxBIOSv3/include/stdlib.h 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/include/stdlib.h 2007-06-29 16:57:23 UTC (rev 418)
@@ -1,22 +0,0 @@
-/*
- * This file is part of the LinuxBIOS project.
- *
- * Copyright (C) 2007 coresystems GmbH
- * (Written by Stefan Reinauer <stepan at coresystems.de> for coresystems GmbH)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
- */
-
-void *malloc(size_t size);
-
Modified: LinuxBIOSv3/lib/console.c
===================================================================
--- LinuxBIOSv3/lib/console.c 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/lib/console.c 2007-06-29 16:57:23 UTC (rev 418)
@@ -2,7 +2,6 @@
#include <hlt.h>
#include <console.h>
#include <uart8250.h>
-// FIXME: we need this for varargs
#include <stdarg.h>
int vtxprintf(void (*)(unsigned char, void *arg),
Deleted: LinuxBIOSv3/lib/malloc.c
===================================================================
--- LinuxBIOSv3/lib/malloc.c 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/lib/malloc.c 2007-06-29 16:57:23 UTC (rev 418)
@@ -1,92 +0,0 @@
-/*
- * This file is part of the LinuxBIOS project.
- *
- * Copyright (C) 2007 Ronald G. Minnich <rminnich at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
- */
-
-/*
- * Simple non-freeing malloc. There have been about a million versions of
- * this but we need one with a known author. Almost every OS and bootloader
- * has had this at some time or other.
- */
-
-#include <types.h>
-#include <stdlib.h>
-#include <console.h>
-
-#if 0
-#define MALLOCDBG(x...)
-#else
-#define MALLOCDBG(x...) printk(BIOS_SPEW, x)
-#endif
-
-/*
- * Instead of ldscript magic, just declare an array. The array will consume
- * no bytes in the image, and it won't run into trouble the way the v2
- * allocator could. We do not provide zero'd memory.
- *
- * Note that the execute-in-place (XIP) code in top of flash is not allowed
- * to call malloc(), since we can't link this in to it. The flash-based code
- * should always be dead simple (in fact, it's not clear we need malloc() at
- * all any more -- we're doing our best to remove all usage of it -- the
- * only real users were elfboot and lzma, and we have removed its usage in
- * elfboot, and will try to remove its usage in lzma).
- */
-
-#define HEAPSIZE (256 * 1024)
-static unsigned char heap[HEAPSIZE];
-static unsigned char *free_mem_ptr = heap;
-static unsigned long freebytes = HEAPSIZE;
-
-/**
- * Allocate 'size' bytes of memory. The memory is not zero'd.
- * If not enough memory is available, just die.
- *
- * @param size The number of bytes to allocate.
- * @return A pointer to the allocated memory.
- */
-void *malloc(size_t size)
-{
- void *p;
-
- MALLOCDBG("%s Enter, size %d, free_mem_ptr %p\n",
- __FUNCTION__, size, free_mem_ptr);
-
- if (size > freebytes) {
- die("Out of memory.\n");
- }
-
- size = (size + 3) & (~3); /* Align */
-
- p = free_mem_ptr;
- free_mem_ptr += size;
- freebytes -= size;
-
- MALLOCDBG("malloc 0x%08lx\n", (unsigned long)p);
-
- return p;
-}
-
-/**
- * Free the specified memory area.
- * This is a no-op, we don't care about freeing memory.
- *
- * @param where A pointer to the memory area to free.
- */
-void free(void *where)
-{
- /* Don't care. */
-}
Modified: LinuxBIOSv3/util/dtc/dtc-parser.y
===================================================================
--- LinuxBIOSv3/util/dtc/dtc-parser.y 2007-06-29 15:32:19 UTC (rev 417)
+++ LinuxBIOSv3/util/dtc/dtc-parser.y 2007-06-29 16:57:23 UTC (rev 418)
@@ -142,7 +142,7 @@
}
')' ';' {
/* convention: first property is labeled with path */
- $6->label = strdup($3.val);
+ $6->label = strdup((char *)$3.val);
$$ = $6
}
|
More information about the coreboot
mailing list