summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/conf/options.i3863
-rw-r--r--sys/i386/conf/XBOX104
-rw-r--r--sys/i386/i386/machdep.c45
-rw-r--r--sys/i386/i386/pmap.c12
-rw-r--r--sys/i386/i386/vm_machdep.c13
-rw-r--r--sys/i386/include/xbox.h45
-rw-r--r--sys/i386/isa/clock.c10
-rw-r--r--sys/i386/pci/pci_cfgreg.c39
-rw-r--r--sys/i386/xbox/pic16l.s202
-rw-r--r--sys/i386/xbox/xbox.c60
-rw-r--r--sys/i386/xbox/xboxfb.c398
-rw-r--r--sys/isa/atrtc.c10
13 files changed, 945 insertions, 0 deletions
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 4be8226..f5de557 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -462,3 +462,7 @@ pci/agp_intel.c optional agp
pci/agp_nvidia.c optional agp
pci/agp_sis.c optional agp
pci/agp_via.c optional agp
+i386/xbox/xbox.c optional xbox
+i386/xbox/xboxfb.c optional xboxfb
+dev/fb/boot_font.c optional xboxfb
+i386/xbox/pic16l.s optional xbox
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index 7dafd5e..9e7c650 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -163,3 +163,6 @@ ASR_COMPAT opt_asr.h
# Debugging
STOP_NMI opt_cpu.h
NPX_DEBUG opt_npx.h
+
+# XBOX support in the kernel
+XBOX opt_xbox.h
diff --git a/sys/i386/conf/XBOX b/sys/i386/conf/XBOX
new file mode 100644
index 0000000..e6f7bfb
--- /dev/null
+++ b/sys/i386/conf/XBOX
@@ -0,0 +1,104 @@
+#
+# XBOX -- kernel for an XBOX
+#
+# $FreeBSD$
+machine i386
+cpu I686_CPU # Celeron
+ident XBOX
+
+makeoptions MODULES_OVERRIDE=""
+
+options KDB
+options DDB
+
+options XBOX # kernel is for XBOX
+device xboxfb # frame buffer support (REQUIRED!)
+
+# no support yet for root device name fetching
+options ROOTDEVNAME=\"ufs:ad0s1a\"
+#options ROOTDEVNAME=\"cd9660:acd0\"
+
+options SCHED_4BSD # 4BSD scheduler
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options FFS # Berkeley Fast Filesystem
+options SOFTUPDATES # Enable FFS soft updates support
+#options UFS_ACL # Support for access control lists
+#options UFS_DIRHASH # Improve performance on big directories
+#options MD_ROOT # MD is a potential root device
+options NFSCLIENT # Network Filesystem Client
+#options NFSSERVER # Network Filesystem Server
+#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+#options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+#options PROCFS # Process filesystem (requires PSEUDOFS)
+#options PSEUDOFS # Pseudo-filesystem framework
+#options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
+#options COMPAT_FREEBSD4 # Compatible with FreeBSD4
+#options KTRACE # ktrace(1) support
+#options SYSVSHM # SYSV-style shared memory
+#options SYSVMSG # SYSV-style message queues
+#options SYSVSEM # SYSV-style semaphores
+#options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+#options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options ADAPTIVE_GIANT # Giant mutex is adaptive.
+
+#device apic # I/O APIC
+
+# Bus support. Do not remove isa, even if you have no isa slots
+device isa
+device pci
+
+# ATA and ATAPI devices
+device ata
+device atadisk # ATA disk drives
+device atapicd # ATAPI CDROM drives
+options ATA_STATIC_ID # Static device numbering
+
+# SCSI peripherals
+device scbus # SCSI bus (required for SCSI)
+device da # Direct Access (disks)
+
+# Floating point support - do not disable.
+device npx
+
+# Pseudo devices.
+device loop # Network loopback
+device mem # Memory and kernel memory devices
+device io # I/O device
+device random # Entropy device
+device ether # Ethernet support
+#device tun # Packet tunnel.
+device pty # Pseudo-ttys (telnet etc)
+#device md # Memory "disks"
+#device gif # IPv6 and IPv4 tunneling
+#device faith # IPv6-to-IPv4 relaying (translation)
+
+# The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter
+
+# USB support
+#device uhci # UHCI PCI->USB interface
+device ohci # OHCI PCI->USB interface
+device usb # USB Bus (required)
+device ugen # Generic
+device uhid # "Human Interface Devices"
+device ukbd # Keyboard
+device ulpt # Printer
+device umass # Disks/Mass storage - Requires scbus and da
+device ums # Mouse
+device urio # Diamond Rio 500 MP3 player
+device uscanner # Scanners
+
+device miibus
+device aue # ADMtek USB Ethernet
+device axe # ASIX Electronics USB Ethernet
+device cdce # Generic USB over Ethernet
+device cue # CATC USB Ethernet
+device kue # Kawasaki LSI USB Ethernet
+device rue # RealTek RTL8150 USB Ethernet
+
+device sound
+device snd_ich # nForce audio
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index fa29b9c..bb38901 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include "opt_msgbuf.h"
#include "opt_npx.h"
#include "opt_perfmon.h"
+#include "opt_xbox.h"
#include <sys/param.h>
#include <sys/proc.h>
@@ -133,6 +134,13 @@ __FBSDID("$FreeBSD$");
#include <i386/isa/icu.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+
+int arch_i386_is_xbox = 0;
+uint32_t arch_i386_xbox_memsize = 0;
+#endif
+
/* Sanity check for __curthread() */
CTASSERT(offsetof(struct pcpu, pc_curthread) == 0);
@@ -1625,6 +1633,21 @@ getmemsize(int first)
struct bios_smap *smap;
quad_t dcons_addr, dcons_size;
+#ifdef XBOX
+ if (arch_i386_is_xbox) {
+ /*
+ * We queried the memory size before, so chop off 4MB for
+ * the framebuffer and inform the OS of this.
+ */
+ extmem = (arch_i386_xbox_memsize - 4) * 1024;
+ basemem = 0;
+ physmap[0] = 0;
+ physmap[1] = extmem * 1024;
+ physmap_idx = 0;
+ goto physmap_done;
+ }
+#endif
+
hasbrokenint12 = 0;
TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12);
bzero(&vmf, sizeof(vmf));
@@ -2158,6 +2181,28 @@ init386(first)
r_idt.rd_base = (int) idt;
lidt(&r_idt);
+#ifdef XBOX
+ /*
+ * The following code queries the PCI ID of 0:0:0. For the XBOX,
+ * This should be 0x10de / 0x02a5.
+ *
+ * This is exactly what Linux does.
+ */
+ outl(0xcf8, 0x80000000);
+ if (inl(0xcfc) == 0x02a510de) {
+ arch_i386_is_xbox = 1;
+ pic16l_setled(XBOX_LED_GREEN);
+
+ /*
+ * We are an XBOX, but we may have either 64MB or 128MB of
+ * memory. The PCI host bridge should be programmed for this,
+ * so we just query it.
+ */
+ outl (0xcf8, 0x80000084);
+ arch_i386_xbox_memsize = (inl (0xcfc) == 0x7FFFFFF) ? 128 : 64;
+ }
+#endif /* XBOX */
+
/*
* Initialize the console before we print anything out.
*/
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 0f0f3ad..d6f6541 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -106,6 +106,7 @@ __FBSDID("$FreeBSD$");
#include "opt_cpu.h"
#include "opt_pmap.h"
#include "opt_msgbuf.h"
+#include "opt_xbox.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -144,6 +145,10 @@ __FBSDID("$FreeBSD$");
#include <machine/smp.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU)
#define CPU_ENABLE_SSE
#endif
@@ -393,6 +398,13 @@ pmap_bootstrap(firstaddr, loadaddr)
virtual_avail = va;
*CMAP1 = 0;
+
+#ifdef XBOX
+ /* FIXME: This is gross, but needed for the XBOX. Since we are in such
+ * an early stadium, we cannot yet neatly map video memory ... :-(
+ * Better fixes are very welcome! */
+ if (!arch_i386_is_xbox)
+#endif
for (i = 0; i < NKPT; i++)
PTD[i] = 0;
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index ca51b8f..217ae8b 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "opt_npx.h"
#include "opt_reset.h"
#include "opt_cpu.h"
+#include "opt_xbox.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -94,6 +95,10 @@ __FBSDID("$FreeBSD$");
#include <i386/isa/isa.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
#ifndef NSFBUFS
#define NSFBUFS (512 + maxusers * 16)
#endif
@@ -536,6 +541,14 @@ cpu_reset_proxy()
void
cpu_reset()
{
+#ifdef XBOX
+ if (arch_i386_is_xbox) {
+ /* Kick the PIC16L, it can reboot the box */
+ pic16l_reboot();
+ for (;;);
+ }
+#endif
+
#ifdef SMP
u_int cnt, map;
diff --git a/sys/i386/include/xbox.h b/sys/i386/include/xbox.h
new file mode 100644
index 0000000..06db5df
--- /dev/null
+++ b/sys/i386/include/xbox.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2005 Rink Springer
+ * All rights reserved.
+ *
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+#ifndef _MACHINE_XBOX_H_
+#define _MACHINE_XBOX_H_
+
+#define XBOX_LED_GREEN 0x0f
+#define XBOX_LED_RED 0xf0
+#define XBOX_LED_FLASHRED 0xa0
+#define XBOX_LED_FLASHGREEN 0x03
+
+extern int arch_i386_is_xbox;
+extern uint32_t arch_i386_xbox_memsize; /* Megabytes */
+
+void pic16l_setbyte(int addr, int reg, int data);
+void pic16l_setled(int val);
+void pic16l_reboot(void);
+void pic16l_poweroff(void);
+
+#endif /* !_MACHINE_XBOX_H_ */
diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c
index a4ae751..38b238f 100644
--- a/sys/i386/isa/clock.c
+++ b/sys/i386/isa/clock.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include "opt_clock.h"
#include "opt_isa.h"
#include "opt_mca.h"
+#include "opt_xbox.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,6 +91,10 @@ __FBSDID("$FreeBSD$");
#include <i386/bios/mca_machdep.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
* can use a simple formula for leap years.
@@ -522,6 +527,11 @@ calibrate_clocks(void)
return (tot_count);
fail:
+#ifdef XBOX
+ if (arch_i386_is_xbox)
+ timer_freq = 1125000; /* gives ~733.34MHz CPU clock */
+#endif
+
if (bootverbose)
printf("failed, using default i8254 clock of %u Hz\n",
timer_freq);
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index adea6dc..869649d 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -30,6 +30,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_xbox.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -49,6 +51,10 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <machine/pmap.h>
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
#define PRVERB(a) do { \
if (bootverbose) \
printf a ; \
@@ -207,6 +213,39 @@ pci_cfgenable(unsigned bus, unsigned slot, unsigned func, int reg, int bytes)
{
int dataport = 0;
+#ifdef XBOX
+ if (arch_i386_is_xbox) {
+ /*
+ * The Xbox MCPX chipset is a derivative of the nForce 1
+ * chipset. It almost has the same bus layout; some devices
+ * cannot be used, because they have been removed.
+ */
+
+ /*
+ * Devices 00:00.1 and 00:00.2 used to be memory controllers on
+ * the nForce chipset, but on the Xbox, using them will lockup
+ * the chipset.
+ */
+ if (bus == 0 && slot == 0 && (func == 1 || func == 2))
+ return dataport;
+
+ /*
+ * Bus 1 only contains a VGA controller at 01:00.0. When you try
+ * to probe beyond that device, you only get garbage, which
+ * could cause lockups.
+ */
+ if (bus == 1 && (slot != 0 || func != 0))
+ return dataport;
+
+ /*
+ * Bus 2 used to contain the AGP controller, but the Xbox MCPX
+ * doesn't have one. Probing it can cause lockups.
+ */
+ if (bus >= 2)
+ return dataport;
+ }
+#endif
+
if (bus <= PCI_BUSMAX
&& slot < devmax
&& func <= PCI_FUNCMAX
diff --git a/sys/i386/xbox/pic16l.s b/sys/i386/xbox/pic16l.s
new file mode 100644
index 0000000..612c306
--- /dev/null
+++ b/sys/i386/xbox/pic16l.s
@@ -0,0 +1,202 @@
+/*-
+ * Copyright (c) 2005 Rink Springer
+ * All rights reserved.
+ *
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+#include <machine/asmacros.h>
+
+.text
+
+/*
+ * send a command to the PIC16L
+ *
+ * void pic16l_setbyte (int addr, int reg, int data)
+ *
+ */
+ENTRY(pic16l_setbyte)
+ push %ebp
+ mov %esp,%ebp
+
+ push %ebx
+
+ movw $0xc000,%dx
+
+1: xor %eax,%eax
+ inw %dx,%ax
+ shr $0x0b,%eax
+ and $0x01,%eax
+ test %eax,%eax
+ jne 1b
+
+ mov $50,%ecx
+2: movw $0xc004,%dx
+ movl 0x8(%ebp),%eax
+ outb %al,%dx
+ movw $0xc008,%dx
+ movl 0xc(%ebp),%eax
+ outb %al,%dx
+ movw $0xc006,%dx
+ movl 0x10(%ebp),%eax
+ outw %ax,%dx
+
+ movw $0xc000,%dx
+ inw %dx,%ax
+ outw %ax,%dx
+
+ movw $0xc002,%dx
+ movb $0x1a,%al
+ outb %al,%dx
+
+ movw $0xc000,%dx
+3:
+ inb %dx,%al
+ movb %al,%bl
+ orb $0x36,%al
+ jz 3b
+
+ orb $0x10,%bl
+ jnz 5f
+
+4:
+ push %ecx
+ xor %ecx,%ecx
+l: loop l
+ pop %ecx
+
+ dec %ecx
+ jz 5f
+ jmp 2b
+5:
+
+ pop %ebx
+
+ leave
+ ret
+
+/*
+ * instructs the pic16l to reboot the xbox
+ *
+ * void pic16l_reboot();
+ *
+ */
+ENTRY(pic16l_reboot)
+ pushl $0x01
+ pushl $0x02
+ pushl $0x20
+ call pic16l_setbyte
+ addl $12,%esp
+ ret
+
+/*
+ * instructs the pic16l to power-off the xbox
+ *
+ * void pic16l_poweroff();
+ *
+ */
+ENTRY(pic16l_poweroff)
+ pushl $0x80
+ pushl $0x02
+ pushl $0x20
+ call pic16l_setbyte
+ addl $12,%esp
+ ret
+
+pic16l_ledhlp:
+ movw $0xc000,%dx
+1: xor %eax,%eax
+ inw %dx,%ax
+ shr $0x0b,%eax
+ and $0x01,%eax
+ test %eax,%eax
+ jne 1b
+
+ mov $400,%ecx
+
+2:
+ movw $0xc004,%dx
+ movb $0x20,%al
+ outb %al,%dx
+
+ movw $0xc008,%dx
+ movb %bh,%al
+ outb %al,%dx
+
+ movw $0xc006,%dx
+ movb %bl,%al
+ outb %al,%dx
+
+ movw $0xc000,%dx
+ inw %dx,%ax
+ outw %ax,%dx
+
+ movw $0xc002,%dx
+ movb $0x1a,%al
+ outb %al,%dx
+
+ movw $0xc000,%dx
+3:
+ inb %dx,%al
+ movb %al,%bl
+ orb $0x36,%al
+ jz 3b
+
+ orb $0x10,%bl
+ jz 4f
+
+ ret
+
+4:
+ push %ecx
+ xor %ecx,%ecx
+l2: loop l2
+ pop %ecx
+ dec %ecx
+ jz 5f
+ jmp 2b
+5:
+ ret
+
+/*
+ * changes the front led
+ *
+ * void pic16l_setled (int val);
+ */
+ENTRY(pic16l_setled)
+ push %ebp
+ mov %esp,%ebp
+
+ push %ebx
+
+ movl 0x8(%ebp),%ebx
+ orl $0x800,%ebx
+ call pic16l_ledhlp
+ movl $0x701,%ebx
+ call pic16l_ledhlp
+
+ pop %ebx
+
+ leave
+ ret
diff --git a/sys/i386/xbox/xbox.c b/sys/i386/xbox/xbox.c
new file mode 100644
index 0000000..b0da531
--- /dev/null
+++ b/sys/i386/xbox/xbox.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2005 Rink Springer
+ * All rights reserved.
+ *
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/eventhandler.h>
+#include <sys/reboot.h>
+#include <machine/xbox.h>
+#include "opt_global.h"
+
+#ifndef I686_CPU
+#error You must have a I686_CPU in your kernel if you want to make an XBOX-compitable kernel
+#endif
+
+static void
+xbox_poweroff(void* junk, int howto)
+{
+ if (!(howto & RB_POWEROFF))
+ return;
+
+ pic16l_poweroff();
+}
+
+static void
+xbox_init(void)
+{
+ if (!arch_i386_is_xbox)
+ return;
+
+ /* register our poweroff function */
+ EVENTHANDLER_REGISTER (shutdown_final, xbox_poweroff, NULL,
+ SHUTDOWN_PRI_LAST);
+}
+
+SYSINIT(xbox, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, xbox_init, NULL)
diff --git a/sys/i386/xbox/xboxfb.c b/sys/i386/xbox/xboxfb.c
new file mode 100644
index 0000000..6271b8a
--- /dev/null
+++ b/sys/i386/xbox/xboxfb.c
@@ -0,0 +1,398 @@
+/*-
+ * Copyright (c) 2005 Rink Springer
+ * All rights reserved.
+ *
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This will handles video output using the XBOX' frame buffer. It assumes
+ * the graphics have been set up by Cromwell. This driver uses all video memory
+ * to avoid expensive memcpy()'s.
+ *
+ * It is usuable as console (to see the initial boot) as well as for interactive
+ * use. The latter is handeled using kbd_*() functionality. Keyboard hotplug is
+ * fully supported, the console will periodically rescan if no keyboard was
+ * found.
+ *
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <vm/vm_param.h>
+#include <sys/kernel.h>
+#include <sys/cons.h>
+#include <sys/conf.h>
+#include <sys/consio.h>
+#include <sys/tty.h>
+#include <sys/kbio.h>
+#include <sys/fbio.h>
+#include <dev/kbd/kbdreg.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/bus.h>
+#include <machine/xbox.h>
+#include <dev/fb/fbreg.h>
+#include <dev/fb/gfb.h>
+
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+#define SCREEN_BPP 4
+#define SCREEN_SIZE (SCREEN_WIDTH*SCREEN_HEIGHT*SCREEN_BPP)
+
+/* FONT_xxx declares the dimensions of the charachter structure, CHAR_xxx is how
+ * they appear on-screen. Having slightly more spacing improves readability. */
+#define FONT_HEIGHT 16
+#define FONT_WIDTH 8
+
+#define CHAR_HEIGHT 16
+#define CHAR_WIDTH 10
+
+#define RAM_SIZE (arch_i386_xbox_memsize * 1024 * 1024)
+#define FB_SIZE (0x400000)
+#define FB_START (0xf0000000 | (RAM_SIZE - FB_SIZE))
+#define FB_START_PTR (0xFD600800)
+
+/* colours */
+#define CONSOLE_COL 0xFF88FF88 /* greenish */
+#define NORM_COL 0xFFAAAAAA /* grayish */
+#define BLACK_COL 0x00000000 /* black */
+
+static int xcon_x = 0;
+static int xcon_y = 0;
+static int xcon_yoffs = 0;
+
+extern struct gfb_font bold8x16;
+
+static char* xcon_map;
+static int* xcon_memstartptr;
+
+static struct tty* xboxfb_tp = NULL;
+static struct keyboard* xbfb_kbd = NULL;
+static int xbfb_keyboard = -1;
+static d_open_t xboxfb_dev_open;
+static d_close_t xboxfb_dev_close;
+static int xboxfb_kbdevent(keyboard_t* thiskbd, int event, void* arg);
+
+static struct cdevsw xboxfb_cdevsw = {
+ .d_version = D_VERSION,
+ .d_open = xboxfb_dev_open,
+ .d_close = xboxfb_dev_close,
+ .d_name = "xboxfb",
+ .d_flags = D_TTY | D_NEEDGIANT,
+};
+
+static void
+xcon_probe(struct consdev* cp)
+{
+ if (arch_i386_is_xbox)
+ cp->cn_pri = CN_REMOTE;
+ else
+ cp->cn_pri = CN_DEAD;
+}
+
+static int
+xcon_getc(struct consdev* cp)
+{
+ return 0;
+}
+
+static int
+xcon_checkc(struct consdev* cp)
+{
+ return 0;
+}
+
+static void
+xcon_real_putc(int basecol, int c)
+{
+ int i, j, ch = c, col;
+ char mask;
+ int* ptri = (int*)xcon_map;
+
+ /* special control chars */
+ switch (ch) {
+ case '\r': /* carriage return */
+ xcon_x = 0;
+ return;
+ case '\n': /* newline */
+ xcon_y += CHAR_HEIGHT;
+ goto scroll;
+ case 7: /* beep */
+ return;
+ case 8: /* backspace */
+ if (xcon_x > 0) {
+ xcon_x -= CHAR_WIDTH;
+ } else {
+ if (xcon_y > CHAR_HEIGHT) {
+ xcon_y -= CHAR_HEIGHT;
+ xcon_x = (SCREEN_WIDTH - CHAR_WIDTH);
+ }
+ }
+ return;
+ case 9: /* tab */
+ xcon_real_putc (basecol, ' ');
+ while ((xcon_x % (8 * CHAR_WIDTH)) != 0) {
+ xcon_real_putc (basecol, ' ');
+ }
+ return;
+ }
+ ptri += (xcon_y * SCREEN_WIDTH) + xcon_x;
+
+ /* we plot the font pixel-by-pixel. bit 7 is skipped as it renders the
+ * console unreadable ... */
+ for (i = 0; i < FONT_HEIGHT; i++) {
+ mask = 0x40;
+ for (j = 0; j < FONT_WIDTH; j++) {
+ col = (bold8x16.data[(ch * FONT_HEIGHT) + i] & mask) ? basecol : BLACK_COL;
+ *ptri++ = col;
+ mask >>= 1;
+ }
+ ptri += (SCREEN_WIDTH - FONT_WIDTH);
+ }
+
+ xcon_x += CHAR_WIDTH;
+ if (xcon_x >= SCREEN_WIDTH) {
+ xcon_x = 0;
+ xcon_y += CHAR_HEIGHT;
+ }
+
+scroll:
+ if (((xcon_yoffs + CHAR_HEIGHT) * SCREEN_WIDTH * SCREEN_BPP) > (FB_SIZE - SCREEN_SIZE)) {
+ /* we are about to run out of video memory, so move everything
+ * back to the beginning of the video memory */
+ memcpy ((char*)xcon_map,
+ (char*)(xcon_map + (xcon_yoffs * SCREEN_WIDTH * SCREEN_BPP)),
+ SCREEN_SIZE);
+ xcon_y -= xcon_yoffs; xcon_yoffs = 0;
+ *xcon_memstartptr = FB_START;
+ }
+
+ /* we achieve much faster scrolling by just altering the video memory
+ * address base. once all memory is used, we return to the beginning
+ * again */
+ while ((xcon_y - xcon_yoffs) >= SCREEN_HEIGHT) {
+ xcon_yoffs += CHAR_HEIGHT;
+ memset ((char*)(xcon_map + (xcon_y * SCREEN_WIDTH * SCREEN_BPP)), 0, CHAR_HEIGHT * SCREEN_WIDTH * SCREEN_BPP);
+ *xcon_memstartptr = FB_START + (xcon_yoffs * SCREEN_WIDTH * SCREEN_BPP);
+ }
+}
+
+static void
+xcon_putc(struct consdev* cp, int c)
+{
+ xcon_real_putc (CONSOLE_COL, c);
+}
+
+static void
+xcon_init(struct consdev* cp)
+{
+ int i;
+ int* iptr;
+
+ /* Don't init the framebuffer on non-XBOX-es */
+ if (!arch_i386_is_xbox)
+ return;
+
+ /*
+ * We must make a mapping from video framebuffer memory to real. This is
+ * very crude: we map the entire videomemory to PAGE_SIZE! Since our
+ * kernel lives at it's relocated address range (0xc0xxxxxx), it won't
+ * care.
+ *
+ * We use address PAGE_SIZE and up so we can still trap NULL pointers.
+ * Once xboxfb_drvinit() is called, the mapping will be done via the OS
+ * and stored in a more sensible location ... but since we're not fully
+ * initialized, this is our only way to go :-(
+ */
+ for (i = 0; i < (FB_SIZE / PAGE_SIZE); i++) {
+ pmap_kenter (((i + 1) * PAGE_SIZE), FB_START + (i * PAGE_SIZE));
+ }
+ pmap_kenter ((i + 1) * PAGE_SIZE, FB_START_PTR - FB_START_PTR % PAGE_SIZE);
+ xcon_map = (char*)PAGE_SIZE;
+ xcon_memstartptr = (int*)((i + 1) * PAGE_SIZE + FB_START_PTR % PAGE_SIZE);
+
+ /* clear the screen */
+ iptr = (int*)xcon_map;
+ for (i = 0; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++)
+ *iptr++ = BLACK_COL;
+
+ sprintf(cp->cn_name, "xboxfb");
+ cp->cn_tp = xboxfb_tp;
+}
+
+static void
+xboxfb_timer(void* arg)
+{
+ int i;
+
+ if (xbfb_kbd != NULL)
+ return;
+
+ i = kbd_allocate ("*", 0, (void*)&xbfb_keyboard, xboxfb_kbdevent, NULL);
+ if (i != -1) {
+ /* allocation was successfull; xboxfb_kbdevent() is called to
+ * feed the keystrokes to the tty driver */
+ xbfb_kbd = kbd_get_keyboard (i);
+ xbfb_keyboard = i;
+ return;
+ }
+
+ /* probe again in a few */
+ timeout (xboxfb_timer, NULL, hz / 10);
+}
+
+static int
+xboxfb_kbdevent(keyboard_t* thiskbd, int event, void* arg)
+{
+ int c;
+
+ if (event == KBDIO_UNLOADING) {
+ /* keyboard was unplugged; clean up and enable probing */
+ xbfb_kbd = NULL;
+ xbfb_keyboard = -1;
+ kbd_release (thiskbd, (void*)&xbfb_keyboard);
+ timeout (xboxfb_timer, NULL, hz / 10);
+ return 0;
+ }
+
+ for (;;) {
+ c = (kbdsw[xbfb_kbd->kb_index])->read_char (xbfb_kbd, 0);
+ if (c == NOKEY)
+ return 0;
+
+ /* only feed non-special keys to an open console */
+ if (c != ERRKEY) {
+ if ((KEYFLAGS(c)) == 0x0)
+ if (xboxfb_tp->t_state & TS_ISOPEN)
+ ttyld_rint (xboxfb_tp, KEYCHAR(c));
+ }
+ }
+
+ return 0;
+}
+
+static void
+xboxfb_drvinit (void* unused)
+{
+ struct cdev* dev;
+ int i;
+
+ /* Don't init the framebuffer on non-XBOX-es */
+ if (!arch_i386_is_xbox)
+ return;
+
+ /*
+ * When this function is called, the OS is capable of doing
+ * device-memory mappings using pmap_mapdev(). Therefore, we ditch the
+ * ugly PAGE_SIZE-based mapping and ask the OS to create a decent
+ * mapping for us.
+ */
+ dev = make_dev (&xboxfb_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "%s", "xboxfb");
+ xcon_map = pmap_mapdev (FB_START, FB_SIZE);
+ xcon_memstartptr = (int*)pmap_mapdev (FB_START_PTR, PAGE_SIZE);
+ *xcon_memstartptr = FB_START;
+
+ /* ditch all ugly previous mappings */
+ for (i = 0; i < (FB_SIZE / PAGE_SIZE); i++) {
+ pmap_kremove (((i + 1) * PAGE_SIZE));
+ }
+ pmap_kremove (PAGE_SIZE + FB_SIZE);
+
+ /* probe for a keyboard */
+ xboxfb_timer (NULL);
+}
+
+static void
+xboxfb_tty_start(struct tty* tp)
+{
+ struct clist* cl;
+ int len, i;
+ u_char buf[128];
+
+ if (tp->t_state & TS_BUSY)
+ return;
+
+ /* simply feed all outstanding tty data to real_putc() */
+ tp->t_state |= TS_BUSY;
+ cl = &tp->t_outq;
+ len = q_to_b(cl, buf, 128);
+ for (i = 0; i < len; i++)
+ xcon_real_putc(NORM_COL, buf[i]);
+ tp->t_state &= ~TS_BUSY;
+}
+
+static void
+xboxfb_tty_stop(struct tty* tp, int flag) {
+ if (tp->t_state & TS_BUSY)
+ if ((tp->t_state & TS_TTSTOP) == 0)
+ tp->t_state |= TS_FLUSH;
+}
+
+static int
+xboxfb_tty_param(struct tty* tp, struct termios* t)
+{
+ return 0;
+}
+
+static int
+xboxfb_dev_open(struct cdev* dev, int flag, int mode, struct thread* td)
+{
+ struct tty* tp;
+
+ tp = xboxfb_tp = dev->si_tty = ttymalloc (xboxfb_tp);
+
+ tp->t_oproc = xboxfb_tty_start;
+ tp->t_param = xboxfb_tty_param;
+ tp->t_stop = xboxfb_tty_stop;
+ tp->t_dev = dev;
+
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ tp->t_state |= TS_CARR_ON;
+ ttychars(tp);
+ tp->t_iflag = TTYDEF_IFLAG;
+ tp->t_oflag = TTYDEF_OFLAG;
+ tp->t_cflag = TTYDEF_CFLAG | CLOCAL;
+ tp->t_lflag = TTYDEF_LFLAG;
+ tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
+ ttsetwater(tp);
+ }
+
+ return ttyld_open (tp, dev);
+}
+
+static int
+xboxfb_dev_close(struct cdev* dev, int flag, int mode, struct thread* td)
+{
+ struct tty* tp;
+
+ tp = xboxfb_tp;
+ ttyld_close (tp, flag);
+ tty_close(tp);
+ return 0;
+}
+
+SYSINIT(xboxfbdev, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, xboxfb_drvinit, NULL)
+
+CONS_DRIVER(xcon, xcon_probe, xcon_init, NULL, xcon_getc, xcon_checkc, xcon_putc, NULL);
diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c
index a4ae751..38b238f 100644
--- a/sys/isa/atrtc.c
+++ b/sys/isa/atrtc.c
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include "opt_clock.h"
#include "opt_isa.h"
#include "opt_mca.h"
+#include "opt_xbox.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,6 +91,10 @@ __FBSDID("$FreeBSD$");
#include <i386/bios/mca_machdep.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
* can use a simple formula for leap years.
@@ -522,6 +527,11 @@ calibrate_clocks(void)
return (tot_count);
fail:
+#ifdef XBOX
+ if (arch_i386_is_xbox)
+ timer_freq = 1125000; /* gives ~733.34MHz CPU clock */
+#endif
+
if (bootverbose)
printf("failed, using default i8254 clock of %u Hz\n",
timer_freq);
OpenPOWER on IntegriCloud