aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/i386
diff options
context:
space:
mode:
authorJordan Crouse <jordan.crouse@amd.com>2008-03-19 23:56:58 +0000
committerJordan Crouse <jordan.crouse@amd.com>2008-03-19 23:56:58 +0000
commitf6145c3c15789123f6b4a9ce64a517048e753762 (patch)
tree0d56f31bd3f7051766c03f00d46f40511446aa96 /payloads/libpayload/i386
parentc221349746299537de9e01a0bcfb28485b15ef84 (diff)
libpayload: The initial chunk of code writen by AMD
This is the initial chunk of code written by me and copyrighted by AMD. Includes everything but a few files that we pulled from outside sources. Signed-off-by: Jordan Crouse <jordan.crouse@amd.com> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3170 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'payloads/libpayload/i386')
-rw-r--r--payloads/libpayload/i386/Makefile.inc31
-rw-r--r--payloads/libpayload/i386/coreboot.c147
-rw-r--r--payloads/libpayload/i386/head.S85
-rw-r--r--payloads/libpayload/i386/main.c79
-rw-r--r--payloads/libpayload/i386/sysinfo.c70
-rw-r--r--payloads/libpayload/i386/timer.c92
-rw-r--r--payloads/libpayload/i386/util.S38
7 files changed, 542 insertions, 0 deletions
diff --git a/payloads/libpayload/i386/Makefile.inc b/payloads/libpayload/i386/Makefile.inc
new file mode 100644
index 0000000000..75b0749973
--- /dev/null
+++ b/payloads/libpayload/i386/Makefile.inc
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+TARGETS-y += i386/head.o i386/main.o i386/sysinfo.o
+TARGETS-y += i386/timer.o i386/coreboot.o i386/util.o
diff --git a/payloads/libpayload/i386/coreboot.c b/payloads/libpayload/i386/coreboot.c
new file mode 100644
index 0000000000..6d310d0325
--- /dev/null
+++ b/payloads/libpayload/i386/coreboot.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <libpayload.h>
+#include <sysinfo.h>
+#include <ipchecksum.h>
+#include <coreboot_tables.h>
+
+/* Some of this is x86 specific, and the rest of it
+ is generic. Right now, since we only support x86,
+ we'll avoid trying to make lots of infrastructure
+ we don't need. If in the future, we want to use
+ coreboot on some other architecture, then take out
+ the generic parsing code and move it elsewhere
+*/
+
+/* === Parsing code === */
+/* This is the generic parsing code */
+
+static void cb_parse_memory(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_memory *mem = (struct cb_memory *) ptr;
+ int count = MEM_RANGE_COUNT(mem);
+ int i;
+
+ if (count > SYSINFO_MAX_MEM_RANGES)
+ count = SYSINFO_MAX_MEM_RANGES;
+
+ info->n_memranges = 0;
+
+ for(i = 0; i < count; i++) {
+ struct cb_memory_range *range =
+ (struct cb_memory_range *) MEM_RANGE_PTR(mem, i);
+
+ if (range->type != CB_MEM_RAM)
+ continue;
+
+ info->memrange[info->n_memranges].base =
+ UNPACK_CB64(range->start);
+
+ info->memrange[info->n_memranges].size =
+ UNPACK_CB64(range->size);
+
+ info->n_memranges++;
+ }
+}
+
+static void cb_parse_serial(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_serial *ser = (struct cb_serial *) ptr;
+ info->ser_ioport = ser->ioport;
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+ struct cb_header *header;
+ unsigned char *ptr = (unsigned char *) addr;
+ int i;
+
+ for (i = 0; i < len; i += 16, ptr += 16) {
+ header = (struct cb_header *) ptr;
+
+ if (!strncmp(header->signature, "LBIO", 4))
+ break;
+ }
+
+ /* We walked the entire space and didn't find anything */
+
+ if (i >= len)
+ return -1;
+
+ if (!header->table_bytes)
+ return 0;
+
+ /* Make sure the checksums match */
+
+ if (ipchksum((uint16_t *) header, sizeof(*header)) != 0)
+ return -1;
+
+ if (ipchksum((uint16_t *) (ptr + sizeof(*header)),
+ header->table_bytes) != header->table_checksum)
+ return -1;
+
+ /* Now, walk the tables */
+ ptr += header->header_bytes;
+
+ for(i = 0; i < header->table_entries; i++) {
+ struct cb_record *rec = (struct cb_record *) ptr;
+
+ /* We only care about a few tags here - maybe
+ more will be interesting later
+ */
+
+ switch(rec->tag) {
+ case CB_TAG_MEMORY:
+ cb_parse_memory(ptr, info);
+ break;
+
+ case CB_TAG_SERIAL:
+ cb_parse_serial(ptr, info);
+ break;
+ }
+
+ ptr += rec->size;
+ }
+
+ return 1;
+}
+
+/* == Architecture specific ==*/
+/* This is the x86 specific stuff */
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ int ret = cb_parse_header((void *) 0x0, 0x1000, info);
+
+ if (ret != 1)
+ ret = cb_parse_header((void *) 0xf0000, 0x1000, info);
+
+ return (ret == 1) ? 0 : -1;
+}
diff --git a/payloads/libpayload/i386/head.S b/payloads/libpayload/i386/head.S
new file mode 100644
index 0000000000..1278bdf4ed
--- /dev/null
+++ b/payloads/libpayload/i386/head.S
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+ .global _entry, _leave
+ .text
+ .align 4
+
+/* Our entry point - assume that the CPU is in
+ * 32 bit protected mode and all segments are in a
+ * flat model. Thats our operating mode, so we won't
+ * change anything
+ */
+
+_entry:
+ call _init
+
+ /* We're back - go back to the bootloader */
+ ret
+
+/* This function saves off the previous stack and
+ switches us to our own execution enviornment
+*/
+
+_init:
+ /* No interrupts, please */
+ cli
+
+ /* Get the current stack pointer */
+ movl %esp, %esi
+
+ movl _istack, %ebx
+
+ /* lret needs %cs in the stack, so copy it over */
+ movw %cs, 4(%ebx)
+
+ /* Exchange the current stack pointer for the one in
+ the initial stack (which happens to be the new
+ stack pointer) */
+
+ xchgl %esi, 16(%ebx)
+
+ /* Set the new stack pointer */
+ movl %esi, %esp
+
+ /* Return into the main entry function
+ and go
+ */
+
+ lret
+
+_leave:
+ movl _istack, %ebx
+
+ /* Restore the stack pointer from the storage area */
+ movl 16(%ebx), %esp
+
+ /* Return to the original context */
+ lret
+
diff --git a/payloads/libpayload/i386/main.c b/payloads/libpayload/i386/main.c
new file mode 100644
index 0000000000..846d46a426
--- /dev/null
+++ b/payloads/libpayload/i386/main.c
@@ -0,0 +1,79 @@
+/*
+ * 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 <arch/types.h>
+
+/* This structure seeds the stack. We provide
+ the return address of our main function, and
+ further down, the address of the function
+ that we call when we leave and try to restore
+ the original stack. At the very bottom of the
+ stack we store the orignal stack pointer
+ from the calling application
+*/
+
+static void start_main(void);
+extern void _leave(void);
+
+static struct {
+ uint32_t eip[2];
+ uint32_t raddr[2];
+ uint32_t esp;
+} initial_stack __attribute__((section (".istack"))) = {
+ { (uint32_t) start_main, 0 },
+ { (uint32_t) _leave, 0 },
+ (uint32_t) &initial_stack,
+};
+
+void * _istack = &initial_stack;
+
+/* This is our C entry function - set up the system
+ and jump into the payload entry point */
+
+static void start_main(void)
+{
+ extern int main(void);
+
+ /* Set up the consoles */
+ console_init();
+
+ /* Gather system information */
+ lib_get_sysinfo();
+
+ /* Any other system init that has to happen before the
+ user gets control goes here. */
+
+ /* Go to the entry point */
+
+ /* in the future we may care about the return value */
+ (void) main();
+
+ /* Returning here will go to the _leave function to return
+ us to the original context */
+}
diff --git a/payloads/libpayload/i386/sysinfo.c b/payloads/libpayload/i386/sysinfo.c
new file mode 100644
index 0000000000..1fdf3fc419
--- /dev/null
+++ b/payloads/libpayload/i386/sysinfo.c
@@ -0,0 +1,70 @@
+/*
+ * 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 <libpayload.h>
+#include <sysinfo.h>
+
+/* This is a global structure that is used through the
+ library - we set it up initially with some dummy
+ values - hopefully they will be overridden
+*/
+
+struct sysinfo_t lib_sysinfo = {
+ . cpu_khz = 200,
+ . ser_ioport = CONFIG_SERIAL_IOBASE,
+};
+
+void lib_get_sysinfo(void)
+{
+ /* Get the CPU speed (for delays) */
+ lib_sysinfo.cpu_khz = get_cpu_speed();
+
+ /* Get the memory information */
+
+ get_coreboot_info(&lib_sysinfo);
+
+ if (!lib_sysinfo.n_memranges) {
+
+ /* If we couldn't get a good memory range,
+ then use a hard coded default */
+
+ lib_sysinfo.n_memranges = 2;
+
+ lib_sysinfo.memrange[0].base = 0;
+ lib_sysinfo.memrange[0].size = 640 * 1024;
+ lib_sysinfo.memrange[1].base = 1024 * 1024;
+ lib_sysinfo.memrange[1].size = 31 * 1024 * 1024;
+ }
+}
+
+
+
+
+
+
diff --git a/payloads/libpayload/i386/timer.c b/payloads/libpayload/i386/timer.c
new file mode 100644
index 0000000000..72a3ee8f48
--- /dev/null
+++ b/payloads/libpayload/i386/timer.c
@@ -0,0 +1,92 @@
+/*
+ * 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 <libpayload.h>
+#include <arch/rdtsc.h>
+
+static unsigned int cpu_khz;
+
+/* Calculate the speed of the processor for use in delays */
+
+void 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 miliseconds 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));
+}
+
+/* Global delay functions */
+
+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);
+}
diff --git a/payloads/libpayload/i386/util.S b/payloads/libpayload/i386/util.S
new file mode 100644
index 0000000000..a0b1b0980d
--- /dev/null
+++ b/payloads/libpayload/i386/util.S
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+ .global halt
+ .text
+ .align 4
+
+/* This function puts the system into a halt. */
+
+halt:
+ cli
+ hlt
+ jmp halt