All pastes #993011 Raw Edit

Stuff

public text v1 · immutable
#993011 ·published 2008-04-22 08:42 UTC
rendered paste body
#
#
# add_file "kern/i386/linuxbios/rdtsc.h"
#  content [5832e2e7e54082d9dab45ea69f17e39843d032f0]
# 
# add_file "kern/i386/linuxbios/timer.c"
#  content [9f2d6a01c2189f368072bbd2fa984caaf34e678d]
# 
# patch "conf/i386-linuxbios.rmk"
#  from [cfe28b0d50c0dbccaace29be109288013500eff1]
#    to [d42ea1a8c5301eef52069f406fbdee26d8e13365]
# 
# patch "kern/i386/linuxbios/init.c"
#  from [8433bc623ac7bcff3641e4ff9c5605c7346f7544]
#    to [d7e5bc0d6af8c62ddbbdf6a8d9df9040bd3b3572]
#
============================================================
--- kern/i386/linuxbios/rdtsc.h	5832e2e7e54082d9dab45ea69f17e39843d032f0
+++ kern/i386/linuxbios/rdtsc.h	5832e2e7e54082d9dab45ea69f17e39843d032f0
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RDTSC_H_
+#define _RDTSC_H_
+
+static inline unsigned long long rdtsc(void)
+{
+	unsigned long long val;
+	__asm__ __volatile__ ("rdtsc" : "=A" (val));
+	return val;
+}
+
+#endif
============================================================
--- kern/i386/linuxbios/timer.c	9f2d6a01c2189f368072bbd2fa984caaf34e678d
+++ kern/i386/linuxbios/timer.c	9f2d6a01c2189f368072bbd2fa984caaf34e678d
@@ -0,0 +1,91 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <grub/cpu/io.h>
+#include "rdtsc.h"
+
+#define outb grub_outb
+#define inb grub_inb
+
+static unsigned int cpu_khz;
+
+/**
+ * Calculate the speed of the processor for use in delays.
+ *
+ * @return The CPU speed in kHz.
+ */
+unsigned int get_cpu_speed(void)
+{
+	unsigned long long start, end;
+
+	/* Set up the PPC port - disable the speaker, enable the T2 gate. */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/* Set the PIT to Mode 0, counter 2, word access. */
+	outb(0xB0, 0x43);
+
+	/* Load the counter with 0xffff. */
+	outb(0xff, 0x42);
+	outb(0xff, 0x42);
+
+	/* Read the number of ticks during the period. */
+	start = rdtsc();
+	while (!(inb(0x61) & 0x20)) ;
+	end = rdtsc();
+
+	/*
+	 * The clock rate is 1193180 Hz, the number of milliseconds for a
+	 * period of 0xffff is 1193180 / (0xFFFF * 1000) or .0182.
+	 * Multiply that by the number of measured clocks to get the kHz value.
+	 */
+	cpu_khz = (unsigned int)((end - start) * 1193180U / (1000 * 0xffff));
+
+	return cpu_khz;
+}
+
+static inline void _delay(unsigned int delta)
+{
+	unsigned long long timeout = rdtsc() + delta;
+	while (rdtsc() < timeout) ;
+}
+
+void ndelay(unsigned int n)
+{
+	_delay(n * cpu_khz / 1000000);
+}
+
+void mdelay(unsigned int m)
+{
+	_delay(m * cpu_khz);
+}
+
+void delay(unsigned int s)
+{
+	_delay(s * cpu_khz * 1000);
+}
============================================================
--- conf/i386-linuxbios.rmk	cfe28b0d50c0dbccaace29be109288013500eff1
+++ conf/i386-linuxbios.rmk	d42ea1a8c5301eef52069f406fbdee26d8e13365
@@ -16,6 +16,7 @@ kernel_elf_SOURCES = kern/i386/linuxbios
 # For kernel.elf.
 kernel_elf_SOURCES = kern/i386/linuxbios/startup.S kern/i386/linuxbios/init.c \
 	kern/i386/linuxbios/table.c \
+	kern/i386/linuxbios/timer.c \
 	kern/main.c kern/device.c \
 	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
 	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
============================================================
--- kern/i386/linuxbios/init.c	8433bc623ac7bcff3641e4ff9c5605c7346f7544
+++ kern/i386/linuxbios/init.c	d7e5bc0d6af8c62ddbbdf6a8d9df9040bd3b3572
@@ -52,7 +52,7 @@ grub_get_rtc (void)
 grub_uint32_t
 grub_get_rtc (void)
 {
-  return grub_time_tics;
+  return grub_time_tics++;
 }
 
 /* Stop the floppy drive from spinning, so that other software is
@@ -63,9 +63,13 @@ grub_stop_floppy (void)
   grub_outb (0, GRUB_FLOPPY_REG_DIGITAL_OUTPUT);
 }
 
+extern unsigned int get_cpu_speed(void);
+extern void mdelay(unsigned int m);
+
 void
-grub_millisleep (grub_uint32_t ms __attribute__ ((unused)))
+grub_millisleep (grub_uint32_t ms)
 {
+ mdelay(ms);
 }
 
 void
@@ -96,6 +100,8 @@ grub_machine_init (void)
   grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
   grub_upper_mem = 0;
 
+  get_cpu_speed();
+
   // assume 256kb image, v3 style
   // TODO: check for LAR presence and be more clever in general
   *memdisk_addr = 0xc0000;