EPIA-M fixup
authorRonald G. Minnich <rminnich@gmail.com>
Tue, 22 Nov 2005 00:07:02 +0000 (00:07 +0000)
committerRonald G. Minnich <rminnich@gmail.com>
Tue, 22 Nov 2005 00:07:02 +0000 (00:07 +0000)
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2090 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

27 files changed:
HOWTO/EPIA-M-howto [new file with mode: 0644]
src/arch/i386/lib/cpu.c
src/cpu/via/model_centaur/model_centaur_init.c
src/devices/cardbus_device.c
src/include/device/cardbus.h
src/mainboard/via/epia-m/Config.lb
src/mainboard/via/epia-m/Options.lb
src/mainboard/via/epia-m/auto.c
src/mainboard/via/epia-m/dsdt.asl [new file with mode: 0644]
src/mainboard/via/epia-m/dsdt.c [new file with mode: 0644]
src/mainboard/via/epia-m/fadt.c
src/mainboard/via/epia-m/failover.c
src/mainboard/via/epia-m/mainboard.c
src/mainboard/via/epia-m/vgabios.c [new file with mode: 0644]
src/mainboard/via/epia-m/vgachip.h [new file with mode: 0644]
src/northbridge/via/vt8623/northbridge.c
src/northbridge/via/vt8623/raminit.c
src/southbridge/ricoh/rl5c476/chip.h
src/southbridge/ricoh/rl5c476/rl5c476.c
src/southbridge/ricoh/rl5c476/rl5c476.h
src/southbridge/via/vt8235/vt8235.c
src/southbridge/via/vt8235/vt8235.h
src/southbridge/via/vt8235/vt8235_ide.c
src/southbridge/via/vt8235/vt8235_lpc.c
src/southbridge/via/vt8235/vt8235_usb.c
src/superio/via/vt1211/vt1211.c
targets/via/epia-m/Config.lb

diff --git a/HOWTO/EPIA-M-howto b/HOWTO/EPIA-M-howto
new file mode 100644 (file)
index 0000000..275cc91
--- /dev/null
@@ -0,0 +1,593 @@
+
+This HOWTO contains instructions for using LinuxBIOSv2 on the VIA EPIA-M and MII 
+mini-itx based motherboards.
+
+Version 1.0 initial write for LinuxBIOSv2 by Nick Barker
+
+Using materials and inspiration from
+- EPIA HOWTO for freebios/linuxbios by Mark Wilkinson
+- Based on the K7SEM HOWTO by Brenden Bixler,
+- which is based on the Sis 630 HOWTO by Ron Minnich.
+- Getting Started with freebios2 - a mail posting by Jay Miller
+
+Unfortunately, there is a step in this HOWTO that could be hazardous. The 
+hazards include (but are not limited to)
+       1) destroying your motherboard
+       2) hurting yourself
+       3) killing yourself
+
+Because of these hazards, you must take full responsibility if you
+decide to install LinuxBIOSv2 following these procedures. Neither the
+author of this HOWTO or any organisation or individual associated with
+the LinuxBIOSv2 project can be held responsible for any adverse consequences
+of your attempt to follow these procedures.
+
+WARNING: We assume you've built kernels, know how to open up your PC,
+and how to yank the flash part out while power is on and put in a
+different part. There is NO WARRANTY, express or implied, with this
+software. In fact, if you don't know what you're doing, and you get
+careless, you're going to end up with a nice paperweight instead of a
+motherboard, an emergency room bill, or a funeral service.
+
+                       YOU HAVE BEEN WARNED.
+
+Additional information available at: http://www.linuxbios.org/
+
+Linux distribution: Most modern distributions are supported. 
+                    
+Other software notes: You MUST have 'as' version 2.9.5 or later.
+                      You MUST have 'gcc' version other than 2.96.
+                      
+                         
+Pre-requisites
+--------------
+
+Before you start there are a few things which you need to arrange:
+
+Since you are going to be re-programming the flash rom on the mainboard, and
+it is likely that you first few attempts / images will not be right, then
+you need a way of restoring a known working bios onto a board which is otherwise
+dead.
+
+Recommended: you might want to get a Bios Saviour (RD1-PL) - this is
+a handy little piggy-back flash chip that saves you destroying the original
+flash image. This howto assumes that you have this device, though other methods
+and devices exist for programming flash roms.
+
+LinuxBIOSv2 sends debugging output through the first serial port. You might want
+to arrange a null modem serial cable for connecting this serial port to a
+second computer running a terminal emulation program. I use 'microcom' which
+is simple and allows all output to be captured into a file for later analysis.
+The port is set up to use 115200 baud, 8bit, No parity, 1 stop bit.
+
+Under LinuxBIOSv2 you have a choice of 'payloads'. The payload is the program
+which LinuxBIOSv2 hands over to once it has finished initialising everything
+on the mainboard at boot time. The payload is included in the flash rom along
+with LinuxBIOSv2, and usually its function is to locate and load the operating
+system. The 2 most common payloads are FILO, for booting Linux off an IDE
+disk, and Etherboot for booting a diskless workstation accross a network.
+This howto assumes the use of FILO.  
+
+A vga bios image. LinuxBIOS2v2 uses the vga bios of the original Via BIOS to 
+initialise the vga. It is not directly downloadable, but you can capture it from
+a system running with the original bios, so you might as well capture it now:
+               dd if=/dev/mem of=/video.bios.bin \
+                   bs=1 count=65536 skip=790528
+
+
+Getting Going
+-------------
+
+The steps for loading LinuxBIOSv2 are simple:
+1) Get Linux installed on your machine.
+2) Download and install LinuxBIOSv2 sources.
+3) Understand how to flash your rom.
+4) Download, Configure and build the FILO payload
+5) Configure and build LinuxBIOSv2.
+6) Burn the LinuxBIOSv2 image to the flash.
+7) Reset the machine -- did it work?
+
+Options Once it has booted
+  i) Speeding up the boot
+ ii) Enhancing ACPI support
+iii) On EPIA-MII, booting the computer from on-board compact flash 
+
+
+Step 1) 
+       Get Linux installed on your LinuxBIOSv2 machine.
+              Don't forget to note which partition is / (/dev/hda3 etc.)
+
+
+Step 2)
+       Grab the LinuxBIOSv2 source.
+       cd to the directory you want the source tree to be.
+
+       Note: this will create a sub directory called LinuxBIOSv2 which contains
+              the LinuxBIOSv2 source code
+
+       Download the latest code for LinuxBIOSv2 from the downloads page at
+               http://www.linuxbios.org
+
+
+       having expanded the tarball, cd into the LinuxBIOSv2 directory and browse around.
+       The top level directory includes:
+
+       'src' - where all of the source files for LinuxBIOSv2 are located.
+       'targets' - where all of the platform specific configuration files
+               for each platform supported by LinuxBIOSv2 are kept, and 
+                where the build files and build process occur.
+       'util' - where various utilities required for the build process 
+               and debugging are kept.
+
+
+       Hereafter, this howto refers to directory locations relative to these directories,
+       unless an absolute pathlist is given.
+
+Step 3)
+       Whilst getting LinuxBIOSv2 going on your EPIA-M, you are almost 
+       certainly going to be re-programming the flash rom several times, and
+       there is a very high probability that at one of these stages you will
+       get a flash rom that fails to boot your mainboard into Linux.
+       Before we proceed any further, it is absolutley vital that you have
+       worked out how to program the flash chip, and how you are going to
+       get back to your original bios when things go wrong. Otherwise you 
+       will end up with a very expensive paper weight as described earlier.
+
+        You can use a professional Data I/O burner, or you can be foolhardy
+       and simply re-program the flash part of a running machine. However
+       whilst getting going a BIOS SAVIOUR RD1-PL is a very inexpensive
+       but effective device for ensuring that you always have a working
+       BIOS to hand.
+
+       The bios saviour is a little device which plugs into the flash rom
+       socket of the motherboard, and the original flash rom then plugs into
+       the bios saviour. The bios saviour includes a second flash rom chip,
+       and either of these chips can be selected as the active chip by a 
+       simple supplied electrical switch mounted on flying leads. Make
+       sure that this switch is clearly visible, so that you know which
+       chip you are booting from, and which chip you are about to re-program.
+
+       Decide which chip you are going to use for LinuxBIOSv2, and which chip
+       you are going to keep the original working bios in, and mark them 
+       clearly on this switch.
+
+        In the 'util/flash_and_burn' directory is the source for the 'flash_rom'
+       utility, which is great for re-programming the flash chips on the 
+       EPIA-M / MII. Once you have built this utility:
+
+       Make sure that it can detect both flash chips on the bios saviour:
+               with switch set to chip 1 run 'flash_rom'
+               flash rom should search through a list of known flash rom
+               device types until it finds the type of the original chip
+               from your EPIA-M, and report what it has found.
+
+               with the switch set to chip 2, run 'flash_rom' again and confirm
+               that it can 'see' the second flash chip.
+
+               If your are lucky, the actual part number of the 2 chips may
+               be different, which you can use just prior to re-programming
+               a chip to make sure you are programming the right chip.
+
+       Make sure that you can read / write and verify a flash chip:
+               with switch set to 1 (original BIOS) run
+               'flash_rom -r original.rom'
+               this should read the contents of the original bios into the
+               file original.rom
+
+               confirm that the newly read file matches the original bios
+               'flash_rom -v original.rom'
+
+               set the switch to 2 
+               confirm if you can that flash_rom 'sees' the second chip
+               'flash_rom' - and look for the detected device type
+
+               write the known good bios to the second chip with
+               'flash_rom -w original.bios'
+
+               verify that it has written correctly
+               'flash_rom -v original.rom'
+
+               with switch left at position 2, reboot the machine and make
+               sure that it comes up corectly. If it does then you now have
+               a working flash programming environment. If it does not, then
+               set the switch back to 1, reboot the machine, and investigate
+               further. 
+
+Step 4)
+       Download FILO from http://felixx.tsn.or.jp/~ts1/filo, and expand
+
+       In the FILO source directory, type 'make'
+
+       The first invocation of make builds the default Config file, which
+       should be edited to meet your needs. In particular look at the line:
+
+       "AUTOBOOT_FILE ...."
+
+       and make sure that it looks sensible for your setup. The line
+       AUTOBOOT_FILE "hda1:/vmlinuz root=/dev/hda2 console=ttyS0,115200" 
+       reads as:
+               - find a linux os image on device hda partion 1 called vmlinuz,
+               - load this image
+               - execute the image passing kernel command line parameters of:
+                     "root=/dev/hda2 console=ttyS0,115200" 
+
+       after editing Config, type 'make' again, and this will build the file
+       'filo.elf' which is the payload we will be using.
+
+       Copy this file to somewhere which the LinuxBIOSv2 makefile can easily 
+       find it. I just tend to keep it in the root directory though I'm sure
+       others will condem me for that practise:
+       'cp filo.elf /'
+
+       Make sure that you have compiled a kernel bzImage, and copied it to
+       the file location you identified in the FILO Config file.
+
+
+Step 5)
+       The next step is to create the build environment for the epia-m. This
+       step creates the appropriate makefiles and build directories for the
+       epia-m.
+
+       'cd targets'
+       './buildtarget via/epia-m'
+
+       This step will create a subdirectory in the targets/via/epia-m
+       directory called epia-m, which is the build directory for LinuxBIOSv2.
+
+       The main configuration file for the epia-m is in 
+       'targets/via/epia-m/Config.lb'
+
+       If you need to make any changes to the configuration, for example you wish to
+       locate filo.elf in a place other than '/filo.elf', or during the more advanced
+       steps of this HOWTO, then these changes are made to this file.
+
+       You need to re-run the './buildtartegt via/epia-m' after any such change.
+
+       The directory 'targets/via/epia-m' contains other sample Config.lb files, any
+        of which can be copied through to Config.lb in order to become the current 
+       configuration.
+
+       Once you have your Config.lb set up to your needs, and the build environment
+       created with './buildtarget', it is time to build a rom image.
+
+       Change directory into the build directory 'targets/via/epia-m/epia-m'
+
+       The configuration as set up by the buildtarget process will create a LinuxBIOS
+        which is exactly 196608 bytes long, which is exactly 64K bytes short of what
+        needs to go into the 256K flash rom. The other 64K is for your vga bios
+       which is simply merged with the linuxbios image. The easiest way to make this 
+       happen is to edit the Makefile and change the line
+
+            cat fallback/linuxbios.rom > linuxbios.rom
+
+        to
+
+             cat /video.bios.bin fallback/linuxbios.rom >linuxbios.rom
+
+       Note: the above order of merging the files together is critical 
+       You will need to remember to make this change every time after you have run
+        the buildtarget program.
+       
+       Type 'make', and wait for the build process to complete.
+
+       If all went well, then you should find a file 'linuxbios.rom' in your
+       current directory. Check that it is 262144 bytes long - i.e. exactly the right 
+       size for the flash rom chip in your EPIA-M / MII.
+
+
+Step 6)
+       NOTE: BE ADVISED THAT THIS STEP CAN KILL YOUR MOTHERBOARD !
+       IF YOU DO NOT HAVE A MEANS OF RECOVERING FROM FLASHING YOUR BIOS,
+       YOU MAY/WILL BE LEFT WITH A DEAD MACHINE.
+
+
+       Assuming that you are using a Bios Saviour, make sure that the switch is set
+       to the position for your LinuxBIOSv2 image.
+
+       Type 'flash_rom' to make sure it can see the flash chip, and verify its type if
+       possible.
+
+       Only once you are happy that you are about to re-programme the desired chip, type
+       'flash_rom -w linuxbios.rom', and wait the few seconds it takes to program it.
+
+       Once it has finished, verify that the chip was re-rogrammed correctly - type
+       'flash_rom -v linuxbios.rom'
+
+
+Step 7) 
+       Power cycle the machine. LinuxBIOSv2 should come up in a few seconds.
+
+       With a connection to the serial port set at 115200, you should see LinuxBIOSv2
+       come up, launch FILO, and if you have a timeout set in FILO, then it may be
+       waiting for you to confirm its boot command line.
+
+       As long as you have this command line set up correctly, and an os image in the
+       right place, then FILO should proceed to boot into your Linux os.
+
+       If you do, CONGRATULATIONS ! It WORKED ! Pat yourself on the back,
+       why not try the optional steps now ?
+
+       If you don't, time to start capturing the output of the serial port
+       and talking to the linuxbios mailing list.
+
+
+Optional steps - for use only if step 7 was successfull.
+
+OK so now we have a BIOS which boots your computer fully into the operating system, and
+depending upon your needs that may be all that you want. However LinuxBIOSv2 has a few more
+tricks up its sleeve should you find yourself hungry for more.
+
+Speeding up the boot
+--------------------
+
+Linuxbios sends its debugging output to the first serial port and, depending upon the amount of debug
+output selected, can be the limiting factor in the speed with which it boots your computer - regardless 
+of whether you have anything attached to the serial port.
+
+Linuxbios uses the notion of debug levels to control what is sent to the serial port. These levels
+range from 0 to 9 with 0 being the least verbose and 9 being the most verbose.
+
+These levels are defined in the Config.lb file described earlier. To reduce the output set:
+    option  MAXIMUM_CONSOLE_LOGLEVEL=8 
+    option  DEFAULT_CONSOLE_LOGLEVEL=8
+to lower values.
+
+Next you will have to run 'buildtarget' again to propagate the effects of the config change.
+Then edit your Makefile again to include your video bios in the final merging.
+
+Then run 'make clean' followed by 'make'.
+
+Advanced ACPI
+-------------
+
+       LinuxBIOSv2 now supports ACPI on the epia-m and epia-m II. In particular the interrupt
+       processing in Linux can be done through ACPI, and crude power management support
+       is provided. This includes software power off, and power management events from the
+       power button.
+
+       It is possible to enhance this behaviour to provide the full capabilities of the 
+       original BIOS, which includes different sleep levels and wake from these levels
+       upon certain events. This is achieved by using a 'grabbed' copy of the ACPI 
+       Differentiated System Descriptor Table or DSDT from the original BIOS.
+
+       For copyright reasons this table cannot be included with the source distribution
+       of LinuxBIOSv2.
+
+
+       You MUST have 'iasl' - Intel's ACPI Asl compiler for Unix/Linux - 
+               http://developer.intel.com/technology/iapc/acpi/downloads.htm.
+
+
+       To replace the LinuxBIOSv2 DSDT with the grabbed one from the original BIOS:
+
+               - Start the computer using the original BIOS, and make sure that you
+                       have ACPI set up in the kernel that you are running
+
+               - Grab the DSDT table - 'cat /proc/acpi/dsdt >dsdt.aml'
+               - Convert to asl code - 'iasl -d dsdt.aml'          (creates dsdt.dsl)
+               - Convert it to a C hex table - 'iasl -tc dsdt.dsl' (creates dsdt.hex)
+               - Replace the file 'src/mainboard/via/epia-m/dsdt.c with dsdt.hex
+
+       Now re-build LinuxBIOSv2, re-program the flash and power cycle.
+
+       If you wish to return to the LinuxBIOSv2 DSDT, then the original file dsdt.asl can be converted
+       into a C hex file using 'iasl -tc dsdt.asl'
+
+
+
+Boot from Onboard Compact Flash (MII only)
+------------------------------------------
+
+       LinuxBIOSv2 now supports the onboard compact flash on the MII as an IDE drive,
+        and it is possible to boot directly from this drive using the following steps.
+
+       The first step is to get Filo or whatever payload you are using to recognise
+        and use this device.
+
+       In order that the pcmcia subsystem of the Linux kernel can correctly configure
+        the device later on in the boot process the CF is set up with its I/O
+       registers in a contiguous block of 16 bytes at 0x1e0 through 0x1ef. Unfortunately
+        this is not a standard IDE address which is why we need to 'fix' filo to use it.
+        (Actually it is half of the address range used by IDE4, and so we need to
+        be careful to tell the kernel not to probe that address - more on that later).
+
+       The first step is to change the filo Config file.
+       1) Comment out SUPPORT_PCI=1. This line instructs filo to search for PCI based IDE 
+           adapters only, and the CF is not attached to a PCI based IDE controller.
+       2) Add the following two lines somewhere in the Config file:
+               IDE2_CMD = 0x1e0
+               IDE2_CNTRL =0x1ec
+
+
+       The second step is to modify the file drivers/ide.c in the filo source directory.
+       Find the function 'find_ide_controller_compat' and change it to look like
+
+       static int find_ide_controller_compat(struct controller *ctrl, int index)
+       {
+               if (index >= IDE_MAX_CONTROLLERS)
+                       return -1;
+       #ifdef IDE2_CMD
+               if(index == 2){
+                       ctrl->cmd_base = IDE2_CMD;
+                       ctrl->ctrl_base = IDE2_CNTRL;
+                       return 0;
+               }
+       #endif
+               ctrl->cmd_base  = ide_base[index];
+               ctrl->ctrl_base = ide_base[index] + IDE_REG_EXTENDED_OFFSET;
+               return 0;
+       }
+       Filo will now recognise the CF as the first device on the third IDE controller 
+        (i.e. ide2), and can be referred to as 'hde'
+
+
+       The next step is to create an initrd file for your Linux kernel. What? Why?
+        The CF socket on your MII is hardwired to the PCMCIA controller and for all intents
+        and purposes it is a PCMCIA device. This means that once Linux boots it will be under
+        the control of the pcmcia manager. Now according to the pcmcia-utils documentation,
+        the pcmcia manager is intended to control and configure devices on an already
+        running system. Yet if we need the CF to be the root device, it needs to be mounted
+        very early on in the boot sequence, before the stage where pcmcia devices would normally
+        be configured. The answer is to use an initrd file to get the pcmcia manager running early
+        for the CF. If you are unfamiliar with initrd then 'man initrd' will give you more background.
+
+
+       The easiest way to create an initrd is to use the script 'mkcfinitrd' which is at the bottom
+        of this howto. This is a tailored version of the 'pcinitrd' script from the pcmcia-utils package.
+        Make sure that 'ash' is available on your system as this is the tiny shell programme used during
+        the initrd phase of booting.
+
+        It is worth mounting the initrd generated, and looking over it to make sure that
+        it contains all of the modules necessary to load and initialise the CF. It does not
+        need drivers for whatever you use in the pcmcia socket, as that can be initialised
+        later on in the boot process as before.
+
+        Finally gzip the file created, and move it alongside your kernel.
+
+       Next adjust your FILO command line to pick things up from the CF. My linux command
+       line in filo looks like:
+
+       AUTOBOOT_FILE = "hde:/vmlinuz initrd=hde:/initrd.gz root=/dev/hde console=tty0 ide4=noprobe"
+
+       The ide4=noprobe option is required to stop the kernel from probing the address used
+        by the CF. As this address is half that used as the standard address for a fifth (i.e. ide4)
+        controller, the kernel hangs whilst trying to initialise this device if this option
+        is not given.
+
+       Finally make sure that you have copied the necessary files onto your CF, and re-boot
+       your computer.
+
+
+
+******************* mkcfinitrd script **************************************
+#!/bin/sh
+#
+# Utility for constructing CF initrd for Epia-MII CF Boot
+#
+# Copyright (C) 2005 Nick Barker -- nick.barker9@btinternet.com
+#
+# Based on pcinitrd
+# Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net
+
+SIZE=2400
+MODULES="pcmcia/pcmcia_core.o pcmcia/ds.o pcmcia/yenta_socket.o"
+BLK="kernel/drivers/ide/legacy/ide-cs.o"
+KERNEL=`uname -r`
+MODDIR=/lib/modules/$KERNEL
+BIN="bin/mount bin/umount sbin/insmod sbin/cardmgr"
+LIB=`ls /lib/libc.so.? | sort | tail -1`
+ETC="/etc/ld.so.cache /etc/pcmcia/config /etc/pcmcia/config.opts"
+DEV="/dev/console /dev/null /dev/ram /dev/tty1 /dev/tty2 /dev/tty3 /dev/tty4"
+MNT=/tmp/initrd.mnt
+
+# name of the initrd file to make
+TARGET=/tmp/initrd
+
+fail()
+{
+    umount $MNT
+    rmdir $MNT
+    exit 1
+}
+trap fail SIGTERM SIGINT
+
+strip_cp()
+{
+    if [ -d $3 ] ; then
+       DEST=$3/`basename $2`
+    else
+       DEST=$3
+    fi
+    strip $1 --verbose -o $DEST $2 | sed -e 's/([^ ]*)//g' || fail
+}
+
+mkdir --verbose $MNT || exit 1
+
+echo "Creating filesystem on $TARGET"
+if [ -b $TARGET ] ; then
+    rm $TARGET || fail
+fi
+
+dd if=$ROOT/dev/zero of=$TARGET bs=1k count=$SIZE
+echo "y" | mke2fs $TARGET $SIZE >/dev/null || fail
+mount --verbose -t ext2 -o loop $TARGET $MNT || fail
+
+
+rm -rf $MNT/lost+found
+echo "Creating Directories on $TARGET"
+for DIR in bin dev etc lib proc tmp mnt ; do
+    mkdir --verbose $MNT/$DIR || fail
+done
+for DIR in block misc fs net pcmcia ; do
+    mkdir --verbose $MNT/lib/$DIR || fail
+done
+
+echo "Copying Files to $TARGET"
+for F in $DEV ; do
+    cp -a --verbose /$F $MNT/dev || fail
+done
+if [ -e /dev/systty ] ; then
+    cp -a --verbose /dev/systty $MNT/dev || fail
+fi
+
+for F in $BIN ; do
+    strip_cp --strip-all /$F $MNT/bin
+done
+strip_cp --strip-all /bin/ash $MNT/bin/sh
+
+for F in $LIB ; do
+    strip_cp --strip-debug /$F $MNT/lib
+done
+cp --verbose /lib/ld-linux.so.? $MNT/lib || fail
+
+for F in $ETC ; do
+    cp --verbose /$F $MNT/etc || fail
+done
+for F in scsi network ftl ide memory serial ; do
+    touch $MNT/etc/$F ; chmod +x $MNT/etc/$F
+done
+
+for MOD in $MODULES ; do
+    strip_cp --strip-debug $MODDIR/$MOD $MNT/lib/$MOD
+done
+
+strip_cp --strip-debug $MODDIR/$BLK $MNT/lib/block/ide-cs.o
+
+echo "Creating linuxrc startup script"
+cat > $MNT/linuxrc <<- 'EOF'
+       #!/bin/sh
+       
+       mount -t proc /proc /proc
+
+       echo ""
+       echo "==== initrd: starting PCMCIA services ===="
+       echo ""
+       PC=/lib/pcmcia
+       insmod $PC/pcmcia_core.o 
+       insmod $PC/yenta_socket.o
+       insmod $PC/ds.o
+       insmod /lib/block/ide-cs.o
+       if [ "$DEBUG" != "" ] ; then V=-v ; fi
+       cardmgr $V -q -o -c /etc -m /lib -s /tmp/stab -p /tmp/pid
+       umount /proc
+       echo ""
+       
+       if [ "$DEBUG" != "" ] ; then
+           /bin/sh < /dev/console
+       fi
+EOF
+chmod +x $MNT/linuxrc 
+
+df -P $MNT | awk '/tmp/ { printf "%dK/%dK used\n",$3,$2 }'
+umount $VERBOSE $MNT
+rmdir $MNT
+echo "Finished $TARGET"
+echo "Now gzip $TARGET to create final initrd.gz"
+exit 0
+
+*************************** end mkcfinitrd ***********************************
\ No newline at end of file
index 628bb79e91f7035e2d04bbb9eb7c214ba607412e..11ccee211fc3363822c8c0bc9fb256237f6d88a6 100644 (file)
@@ -234,11 +234,13 @@ void cpu_initialize(void)
        // Check that we haven't been passed bad information as the result of a race 
        // (i.e. BSP timed out while waiting for us to load secondary_stack)
 
+#if CONFIG_SMP  || CONFIG_IOPIC 
        if (cpu->path.u.apic.apic_id != lapicid()) {
                printk_err("CPU #%d Initialization FAILED: APIC ID mismatch (%u != %u)\n",
                                   info->index, cpu->path.u.apic.apic_id, lapicid());
                // return without setting initialized flag
        } else {
+#endif
                /* Find what type of cpu we are dealing with */
                identify_cpu(cpu);
                printk_debug("CPU: vendor %s device %x\n",
@@ -255,8 +257,10 @@ void cpu_initialize(void)
                }
 
                printk_info("CPU #%d Initialized\n", info->index);
-       }
+#if CONFIG_SMP  || CONFIG_IOPIC 
 
+       }
+#endif
        return;
 }
 
index b76b065ebbc5c170fc99831390de49bb9c3beed1..33f10a831e8341c9bb45c528e63e8c05e84dada0 100644 (file)
@@ -15,6 +15,7 @@ static void model_centaur_init(device_t dev)
 {
        /* Turn on caching if we haven't already */
        x86_enable_cache();
+       x86_setup_mtrrs(36);
        x86_mtrr_check();
 
        /* Enable the local cpu apics */
@@ -28,6 +29,13 @@ static struct device_operations cpu_dev_ops = {
 #warning "FIXME - need correct cpu id here for VIA C3"
 static struct cpu_device_id cpu_table[] = {
        { X86_VENDOR_CENTAUR, 0x0670 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0671 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0672 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0673 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0674 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0675 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0676 },         // VIA C3 Samual 2
+       { X86_VENDOR_CENTAUR, 0x0677 },         // VIA C3 Samual 2
        { X86_VENDOR_CENTAUR, 0x0678 },         // VIA C3 Ezra
        { X86_VENDOR_CENTAUR, 0x0680 },         // VIA C3 Ezra-T
        { X86_VENDOR_CENTAUR, 0x0698 },         // VIA C3 Nehemiah
index 4c92d91735149fb0650ebc0af1e22d0ddf7898a0..5b03d2827c9de775bd2289f48c0ff2efe284bbfe 100644 (file)
@@ -74,7 +74,14 @@ void cardbus_read_resources(device_t dev)
        resource_t moving_base, moving_limit, moving;
        unsigned long type;
        uint16_t ctl;
-       
+       unsigned long index;    
+
+       /* See if needs a card control registers base address */
+
+       pci_get_resource(dev, PCI_BASE_ADDRESS_0);
+
+       compact_resources(dev);
+
        /* See which bridge I/O resources are implemented */
        moving_base  = pci_moving_config32(dev, PCI_CB_IO_BASE_0);
        moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_0);
index 38aa41cab5b64630c4f459c148f70faba98332f7..07cc46a54a7ccaa0a3d383ccb00dd24869c77270 100644 (file)
@@ -6,6 +6,7 @@ void cardbus_read_resources(device_t dev);
 unsigned int cardbus_scan_bus(struct bus *bus, 
        unsigned min_devfn, unsigned max_devfn, unsigned int max);
 unsigned int cardbus_scan_bridge(device_t dev, unsigned int max);
+void cardbus_enable_resources(device_t dev);
 
 extern struct device_operations default_cardbus_ops_bus;
 
index decbd0e3b1f2fe8ba43858950c50eb68423ab9b8..6dc4b3d79a005275133308d609edd65ed7cb34fc 100644 (file)
@@ -45,6 +45,7 @@ arch i386 end
 driver mainboard.o
 if HAVE_PIRQ_TABLE object irq_tables.o end
 #object reset.o
+object vgabios.o
 
 if HAVE_ACPI_TABLES
        object fadt.o
@@ -133,11 +134,6 @@ config chip.h
 chip northbridge/via/vt8623
        device pci_domain 0 on
                chip southbridge/via/vt8235
-                       register "enable_usb" = "0"
-                       register "enable_native_ide" = "0"
-                       register "enable_com_ports" = "1"
-                       register "enable_keyboard" = "0"
-                       register "enable_nvram" = "1"
 
                        device pci 10.0 on end # USB 1.1
                        device pci 10.1 on end # USB 1.1
@@ -151,7 +147,7 @@ chip northbridge/via/vt8623
                                                irq 0x70 = 6
                                                drq 0x74 = 2
                                        end
-                                       device pnp 2e.1 off     # Parallel Port
+                                       device pnp 2e.1 o     # Parallel Port
                                                io 0x60 = 0x378
                                                irq 0x70 = 7
                                                drq 0x74 = 3
@@ -178,10 +174,16 @@ chip northbridge/via/vt8623
                        device pci 12.0 on end  # Ethernet
                end
 #              This is on the EPIA MII, not the M.
-#              chip southbridge/ricoh/rl5c476
-#              end
+               chip southbridge/ricoh/rl5c476
+                       register "enable_cf" = "1"
+                       device pci 0a.0 on end
+                       device pci 0a.1 on end  
+               end
        end
 
-       chip cpu/via/model_centaur 
+       device apic_cluster 0 on
+               chip cpu/via/model_centaur
+                       device apic 0 on  end 
+               end
        end
 end
index 4184236c5c4cf2d3eca3867582f6963eee2486cb..6c3193e78d196b45e424d7561fd19c08e763b674 100644 (file)
@@ -36,6 +36,8 @@ uses DEFAULT_CONSOLE_LOGLEVEL
 uses MAXIMUM_CONSOLE_LOGLEVEL
 uses CONFIG_CONSOLE_SERIAL8250
 uses CONFIG_UDELAY_TSC
+uses CONFIG_PCI_ROM_RUN
+uses CONFIG_CONSOLE_VGA
 
 ## ROM_SIZE is the size of boot ROM that this board will use.
 default ROM_SIZE  = 256*1024
@@ -43,6 +45,8 @@ default ROM_SIZE  = 256*1024
 ###
 ### Build options
 ###
+default CONFIG_PCI_ROM_RUN=0
+default CONFIG_CONSOLE_VGA=0
 
 ##
 ## Build code for the fallback boot
@@ -70,6 +74,13 @@ default HAVE_HARD_RESET=1
 default HAVE_PIRQ_TABLE=1
 default IRQ_SLOT_COUNT=5
 
+
+##
+## Build code to load acpi tables
+##
+default HAVE_ACPI_TABLES=1
+
+
 ##
 ## Build code to export a CMOS option table
 ##
index 7d08de87bbb002f654df6e0e115102a73932e10c..c69b7bf1016cd5fd44cd0a5ef9b90aebcca1cbb3 100644 (file)
@@ -68,7 +68,7 @@ static void enable_mainboard_devices(void)
                die("Southbridge not found!!!\n");
        }
        pci_write_config8(dev, 0x50, 0x80);
-       pci_write_config8(dev, 0x51, 0x1F);
+       pci_write_config8(dev, 0x51, 0x1f);
 #if 0
        // This early setup switches IDE into compatibility mode before PCI gets 
        // // a chance to assign I/Os
@@ -141,14 +141,8 @@ static void main(unsigned long bist)
 
        print_debug(" Enabling shadow ram\r\n");
        enable_shadow_ram();
-       /*
-         memreset_setup();
-         this is way more generic than we need.
-         sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
-       */
-       sdram_set_registers((const struct mem_controller *) 0);
-       sdram_set_spd_registers((const struct mem_controller *) 0);
-       sdram_enable(0, (const struct mem_controller *) 0);
+
+       ddr_ram_setup((const struct mem_controller *)0);
        
        /* Check all of memory */
 #if 0
diff --git a/src/mainboard/via/epia-m/dsdt.asl b/src/mainboard/via/epia-m/dsdt.asl
new file mode 100644 (file)
index 0000000..2fcb77e
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-M / MII
+ * (C) Copyright 2004 Nick Barker <Nick.Barker9@btinternet.com>
+ *
+ * 
+ */
+
+DefinitionBlock ("DSDT.aml", "DSDT", 1, "LXBIOS", "LXB-DSDT", 1)
+{
+       /*  
+        * Define the main processor
+        */
+       Scope (\_PR)
+       {
+               Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) {}
+       }
+
+       /* For now only define 2 power states:
+        *  - S0 which is fully on
+        *  - S5 which is soft off
+        * any others would involve declaring the wake up methods
+        */
+       Name (\_S0, Package () {0x00, 0x00, 0x00, 0x00 })
+       Name (\_S5, Package () {0x02, 0x02, 0x00, 0x00 })
+
+       /* Root of the bus hierarchy */
+       Scope (\_SB)
+       {
+               /* Define how interrupt Link A is plumbed in */ 
+               Device (LNKA)
+               {
+                       Name (_HID, EisaId ("PNP0C0F"))
+                       Name (_UID, 0x01)
+                       /* Status - always return ready */
+                       Method (_STA, 0, NotSerialized)
+                       {
+                               Return (0x0B)
+                       }
+                       /* Current Resources - return irq set up in BIOS */  
+                       Method (_CRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Possible Resources - return the range of irqs
+                        * we are using for PCI - only here to keep Linux ACPI
+                        * happy 
+                        */
+                       Method (_PRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5,9,10}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+                        * assignments as long as the CRS and STA functions 
+                        * return good values
+                        */
+                       Method (_SRS, 1, NotSerialized ) {}
+                       /* Disable - dummy function to keep Linux ACPI happy */
+                       Method (_DIS, 0, NotSerialized ) {}
+               } // End of LNKA 
+
+               /* Define how interrupt Link B is plumbed in */ 
+               Device (LNKB)
+               {
+                       Name (_HID, EisaId ("PNP0C0F"))
+                       Name (_UID, 0x02)
+                       /* Status - always return ready */
+                       Method (_STA, 0, NotSerialized)
+                       {
+                               Return (0x0B)
+                       }
+                       /* Current Resources - return irq set up in BIOS */  
+                       Method (_CRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {9}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Possible Resources - return the range of irqs
+                        * we are using for PCI - only here to keep Linux ACPI
+                        * happy 
+                        */
+                       Method (_PRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5,9,10}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+                        * assignments as long as the CRS and STA functions 
+                        * return good values
+                        */
+                       Method (_SRS, 1, NotSerialized ) {}
+                       /* Disable - dummy function to keep Linux ACPI happy */
+                       Method (_DIS, 0, NotSerialized ) {}
+               } // End of LNKB
+
+               /* Define how interrupt Link C is plumbed in */ 
+               Device (LNKC)
+               {
+                       Name (_HID, EisaId ("PNP0C0F"))
+                       Name (_UID, 0x03)
+                       /* Status - always return ready */
+                       Method (_STA, 0, NotSerialized)
+                       {
+                               Return (0x0B)
+                       }
+                       /* Current Resources - return irq set up in BIOS */  
+                       Method (_CRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {9}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Possible Resources - return the range of irqs
+                        * we are using for PCI - only here to keep Linux ACPI
+                        * happy 
+                        */
+                       Method (_PRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5,9,10}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+                        * assignments as long as the CRS and STA functions 
+                        * return good values
+                        */
+                       Method (_SRS, 1, NotSerialized ) {}
+                       /* Disable - dummy function to keep Linux ACPI happy */
+                       Method (_DIS, 0, NotSerialized ) {}
+               } // End of LNKC
+
+               /* Define how interrupt Link D is plumbed in */ 
+               Device (LNKD)
+               {
+                       Name (_HID, EisaId ("PNP0C0F"))
+                       Name (_UID, 0x04)
+                       /* Status - always return ready */
+                       Method (_STA, 0, NotSerialized)
+                       {
+                               Return (0x0B)
+                       }
+                       /* Current Resources - return irq set up in BIOS */  
+                       Method (_CRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Possible Resources - return the range of irqs
+                        * we are using for PCI - only here to keep Linux ACPI
+                        * happy 
+                        */
+                       Method (_PRS, 0, NotSerialized)
+                       {
+                               Name (BUFF, ResourceTemplate ()
+                               {
+                                       IRQ (Level, ActiveLow, Shared) {5,9,10}
+                               })
+                               Return (BUFF)
+                       }
+                       /* Set Resources - dummy function to keep Linux ACPI happy
+                         * Linux is more than happy not to tinker with irq
+                        * assignments as long as the CRS and STA functions 
+                        * return good values
+                        */
+                       Method (_SRS, 1, NotSerialized ) {}
+                       /* Disable - dummy function to keep Linux ACPI happy */
+                       Method (_DIS, 0, NotSerialized ) {}
+               } // End of LNKD 
+
+               /* top PCI device */
+               Device (PCI0)
+               {
+                       Name (_HID, EisaId ("PNP0A03"))
+                       Name (_ADR, 0x00)
+                       Name (_UID, 0x00)
+                       Name (_BBN, 0x00)
+
+                       /* PCI Routing Table */
+                       Name (_PRT, Package () {
+                               Package () {0x000AFFFF, 0x00, LNKD, 0x00}, // Cardbus Link D
+                               Package () {0x000AFFFF, 0x01, LNKA, 0x00}, // Cardbus Link A 
+                               Package () {0x000AFFFF, 0x02, LNKB, 0x00}, // Cardbus Link B
+                               Package () {0x000AFFFF, 0x03, LNKC, 0x00}, // Cardbus Link C
+
+                               Package () {0x000DFFFF, 0x00, LNKB, 0x00}, // Firewire Link B
+                               Package () {0x000DFFFF, 0x01, LNKC, 0x00}, // Firewire Link C
+                               Package () {0x000DFFFF, 0x02, LNKD, 0x00}, // Firewire Linc D
+                               Package () {0x000DFFFF, 0x03, LNKA, 0x00}, // Firewire Link A
+
+                               Package () {0x0010FFFF, 0x00, LNKA, 0x00}, // USB Link A
+                               Package () {0x0010FFFF, 0x01, LNKB, 0x00}, // USB Link B
+                               Package () {0x0010FFFF, 0x02, LNKC, 0x00}, // USB Link C
+                               Package () {0x0010FFFF, 0x03, LNKD, 0x00}, // USB Link D
+
+                               Package () {0x0011FFFF, 0x00, LNKA, 0x00}, // vt8623 Link A
+                               Package () {0x0011FFFF, 0x01, LNKB, 0x00}, // vt8623 Link B
+                               Package () {0x0011FFFF, 0x02, LNKC, 0x00}, // vt8623 Link C
+                               Package () {0x0011FFFF, 0x03, LNKD, 0x00}, // vt8623 Link D
+
+                               Package () {0x0012FFFF, 0x00, LNKA, 0x00}, // LAN Link A 
+                               Package () {0x0012FFFF, 0x01, LNKB, 0x00}, // LAN Link B
+                               Package () {0x0012FFFF, 0x02, LNKC, 0x00}, // LAN Link C
+                               Package () {0x0012FFFF, 0x03, LNKD, 0x00}, // LAN Link D
+
+                               Package () {0x0013FFFF, 0x00, LNKA, 0x00}, // Riser slot LinkA 
+                               Package () {0x0013FFFF, 0x01, LNKB, 0x00}, // Riser slot LinkB
+                               Package () {0x0013FFFF, 0x02, LNKC, 0x00}, // Riser slot LinkC
+                               Package () {0x0013FFFF, 0x03, LNKD, 0x00}, // Riser slot LinkD
+
+                               Package () {0x0014FFFF, 0x00, LNKB, 0x00}, // Slot 1, Link B
+                               Package () {0x0014FFFF, 0x01, LNKC, 0x00}, // Slot 1, Link C
+                               Package () {0x0014FFFF, 0x02, LNKD, 0x00}, // Slot 1, Link D
+                               Package () {0x0014FFFF, 0x03, LNKA, 0x00}, // Slot 1, Link A
+                
+                               Package () {0x0001FFFF, 0x00, LNKA, 0x00}, // VGA Link A
+                               Package () {0x0001FFFF, 0x01, LNKB, 0x00}, // VGA Link B
+                               Package () {0x0001FFFF, 0x02, LNKC, 0x00}, // VGA Link C
+                               Package () {0x0001FFFF, 0x03, LNKD, 0x00} // VGA Link D
+
+                       })
+
+
+               } // End of PCI0
+
+       } // End of _SB
+
+} // End of Definition Block
+
diff --git a/src/mainboard/via/epia-m/dsdt.c b/src/mainboard/via/epia-m/dsdt.c
new file mode 100644 (file)
index 0000000..62b0f3d
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 
+ * Intel ACPI Component Architecture
+ * ASL Optimizing Compiler / AML Disassembler version 20040715 [Aug 16 2004]
+ * Copyright (C) 2000 - 2004 Intel Corporation
+ * Supports ACPI Specification Revision 2.0c
+ * 
+ * Compilation of "dsdt.asl" - Thu Oct 27 09:25:57 2005
+ * 
+ * C source code output
+ *
+ */
+unsigned char AmlCode[] = 
+{
+    0x44,0x53,0x44,0x54,0xF0,0x03,0x00,0x00,  /* 00000000    "DSDT...." */
+    0x01,0x11,0x4C,0x58,0x42,0x49,0x4F,0x53,  /* 00000008    "..LXBIOS" */
+    0x4C,0x58,0x42,0x2D,0x44,0x53,0x44,0x54,  /* 00000010    "LXB-DSDT" */
+    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
+    0x15,0x07,0x04,0x20,0x10,0x12,0x5F,0x50,  /* 00000020    "... .._P" */
+    0x52,0x5F,0x5B,0x83,0x0B,0x43,0x50,0x55,  /* 00000028    "R_[..CPU" */
+    0x30,0x00,0x10,0x04,0x00,0x00,0x06,0x08,  /* 00000030    "0......." */
+    0x5F,0x53,0x30,0x5F,0x12,0x06,0x04,0x00,  /* 00000038    "_S0_...." */
+    0x00,0x00,0x00,0x08,0x5F,0x53,0x35,0x5F,  /* 00000040    "...._S5_" */
+    0x12,0x08,0x04,0x0A,0x02,0x0A,0x02,0x00,  /* 00000048    "........" */
+    0x00,0x10,0x4E,0x39,0x5F,0x53,0x42,0x5F,  /* 00000050    "..N9_SB_" */
+    0x5B,0x82,0x44,0x06,0x4C,0x4E,0x4B,0x41,  /* 00000058    "[.D.LNKA" */
+    0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,  /* 00000060    "._HID.A." */
+    0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x01,  /* 00000068    "..._UID." */
+    0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,  /* 00000070    ".._STA.." */
+    0x0A,0x0B,0x14,0x1A,0x5F,0x43,0x52,0x53,  /* 00000078    "...._CRS" */
+    0x00,0x08,0x42,0x55,0x46,0x46,0x11,0x09,  /* 00000080    "..BUFF.." */
+    0x0A,0x06,0x23,0x20,0x00,0x18,0x79,0x00,  /* 00000088    "..# ..y." */
+    0xA4,0x42,0x55,0x46,0x46,0x14,0x1A,0x5F,  /* 00000090    ".BUFF.._" */
+    0x50,0x52,0x53,0x00,0x08,0x42,0x55,0x46,  /* 00000098    "PRS..BUF" */
+    0x46,0x11,0x09,0x0A,0x06,0x23,0x20,0x06,  /* 000000A0    "F....# ." */
+    0x18,0x79,0x00,0xA4,0x42,0x55,0x46,0x46,  /* 000000A8    ".y..BUFF" */
+    0x14,0x06,0x5F,0x53,0x52,0x53,0x01,0x14,  /* 000000B0    ".._SRS.." */
+    0x06,0x5F,0x44,0x49,0x53,0x00,0x5B,0x82,  /* 000000B8    "._DIS.[." */
+    0x45,0x06,0x4C,0x4E,0x4B,0x42,0x08,0x5F,  /* 000000C0    "E.LNKB._" */
+    0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,  /* 000000C8    "HID.A..." */
+    0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,  /* 000000D0    "._UID..." */
+    0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,  /* 000000D8    "._STA..." */
+    0x0B,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,  /* 000000E0    "..._CRS." */
+    0x08,0x42,0x55,0x46,0x46,0x11,0x09,0x0A,  /* 000000E8    ".BUFF..." */
+    0x06,0x23,0x00,0x02,0x18,0x79,0x00,0xA4,  /* 000000F0    ".#...y.." */
+    0x42,0x55,0x46,0x46,0x14,0x1A,0x5F,0x50,  /* 000000F8    "BUFF.._P" */
+    0x52,0x53,0x00,0x08,0x42,0x55,0x46,0x46,  /* 00000100    "RS..BUFF" */
+    0x11,0x09,0x0A,0x06,0x23,0x20,0x06,0x18,  /* 00000108    "....# .." */
+    0x79,0x00,0xA4,0x42,0x55,0x46,0x46,0x14,  /* 00000110    "y..BUFF." */
+    0x06,0x5F,0x53,0x52,0x53,0x01,0x14,0x06,  /* 00000118    "._SRS..." */
+    0x5F,0x44,0x49,0x53,0x00,0x5B,0x82,0x45,  /* 00000120    "_DIS.[.E" */
+    0x06,0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48,  /* 00000128    ".LNKC._H" */
+    0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,  /* 00000130    "ID.A...." */
+    0x5F,0x55,0x49,0x44,0x0A,0x03,0x14,0x09,  /* 00000138    "_UID...." */
+    0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0B,  /* 00000140    "_STA...." */
+    0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x08,  /* 00000148    ".._CRS.." */
+    0x42,0x55,0x46,0x46,0x11,0x09,0x0A,0x06,  /* 00000150    "BUFF...." */
+    0x23,0x00,0x02,0x18,0x79,0x00,0xA4,0x42,  /* 00000158    "#...y..B" */
+    0x55,0x46,0x46,0x14,0x1A,0x5F,0x50,0x52,  /* 00000160    "UFF.._PR" */
+    0x53,0x00,0x08,0x42,0x55,0x46,0x46,0x11,  /* 00000168    "S..BUFF." */
+    0x09,0x0A,0x06,0x23,0x20,0x06,0x18,0x79,  /* 00000170    "...# ..y" */
+    0x00,0xA4,0x42,0x55,0x46,0x46,0x14,0x06,  /* 00000178    "..BUFF.." */
+    0x5F,0x53,0x52,0x53,0x01,0x14,0x06,0x5F,  /* 00000180    "_SRS..._" */
+    0x44,0x49,0x53,0x00,0x5B,0x82,0x45,0x06,  /* 00000188    "DIS.[.E." */
+    0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,  /* 00000190    "LNKD._HI" */
+    0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,  /* 00000198    "D.A...._" */
+    0x55,0x49,0x44,0x0A,0x04,0x14,0x09,0x5F,  /* 000001A0    "UID...._" */
+    0x53,0x54,0x41,0x00,0xA4,0x0A,0x0B,0x14,  /* 000001A8    "STA....." */
+    0x1A,0x5F,0x43,0x52,0x53,0x00,0x08,0x42,  /* 000001B0    "._CRS..B" */
+    0x55,0x46,0x46,0x11,0x09,0x0A,0x06,0x23,  /* 000001B8    "UFF....#" */
+    0x20,0x00,0x18,0x79,0x00,0xA4,0x42,0x55,  /* 000001C0    " ..y..BU" */
+    0x46,0x46,0x14,0x1A,0x5F,0x50,0x52,0x53,  /* 000001C8    "FF.._PRS" */
+    0x00,0x08,0x42,0x55,0x46,0x46,0x11,0x09,  /* 000001D0    "..BUFF.." */
+    0x0A,0x06,0x23,0x20,0x06,0x18,0x79,0x00,  /* 000001D8    "..# ..y." */
+    0xA4,0x42,0x55,0x46,0x46,0x14,0x06,0x5F,  /* 000001E0    ".BUFF.._" */
+    0x53,0x52,0x53,0x01,0x14,0x06,0x5F,0x44,  /* 000001E8    "SRS..._D" */
+    0x49,0x53,0x00,0x5B,0x82,0x4B,0x1F,0x50,  /* 000001F0    "IS.[.K.P" */
+    0x43,0x49,0x30,0x08,0x5F,0x48,0x49,0x44,  /* 000001F8    "CI0._HID" */
+    0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F,0x41,  /* 00000200    ".A...._A" */
+    0x44,0x52,0x00,0x08,0x5F,0x55,0x49,0x44,  /* 00000208    "DR.._UID" */
+    0x00,0x08,0x5F,0x42,0x42,0x4E,0x00,0x08,  /* 00000210    ".._BBN.." */
+    0x5F,0x50,0x52,0x54,0x12,0x43,0x1D,0x20,  /* 00000218    "_PRT.C. " */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A,0x00,  /* 00000220    "........" */
+    0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 00000228    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x4C,  /* 00000230    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C,  /* 00000238    "NKA....." */
+    0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000240    "......LN" */
+    0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000248    "KB......" */
+    0xFF,0x0A,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000250    ".....LNK" */
+    0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000258    "C......." */
+    0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,  /* 00000260    "...LNKB." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,  /* 00000268    "........" */
+    0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,  /* 00000270    ".LNKC..." */
+    0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,  /* 00000278    "........" */
+    0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,  /* 00000280    "LNKD...." */
+    0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C,  /* 00000288    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 00000290    "NKA....." */
+    0xFF,0xFF,0x10,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000298    ".....LNK" */
+    0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 000002A0    "A......." */
+    0x10,0x00,0x01,0x4C,0x4E,0x4B,0x42,0x00,  /* 000002A8    "...LNKB." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x10,0x00,  /* 000002B0    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x43,0x00,0x12,  /* 000002B8    "..LNKC.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x10,0x00,0x0A,  /* 000002C0    "........" */
+    0x03,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D,  /* 000002C8    ".LNKD..." */
+    0x04,0x0C,0xFF,0xFF,0x11,0x00,0x00,0x4C,  /* 000002D0    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 000002D8    "NKA....." */
+    0xFF,0xFF,0x11,0x00,0x01,0x4C,0x4E,0x4B,  /* 000002E0    ".....LNK" */
+    0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000002E8    "B......." */
+    0x11,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,  /* 000002F0    "....LNKC" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x11,  /* 000002F8    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,  /* 00000300    "...LNKD." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x12,0x00,  /* 00000308    "........" */
+    0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 00000310    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x12,0x00,0x01,0x4C,  /* 00000318    ".......L" */
+    0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,  /* 00000320    "NKB....." */
+    0xFF,0xFF,0x12,0x00,0x0A,0x02,0x4C,0x4E,  /* 00000328    "......LN" */
+    0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,  /* 00000330    "KC......" */
+    0xFF,0x12,0x00,0x0A,0x03,0x4C,0x4E,0x4B,  /* 00000338    ".....LNK" */
+    0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000340    "D......." */
+    0x13,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00,  /* 00000348    "...LNKA." */
+    0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x13,0x00,  /* 00000350    "........" */
+    0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E,  /* 00000358    ".LNKB..." */
+    0x04,0x0C,0xFF,0xFF,0x13,0x00,0x0A,0x02,  /* 00000360    "........" */
+    0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04,  /* 00000368    "LNKC...." */
+    0x0C,0xFF,0xFF,0x13,0x00,0x0A,0x03,0x4C,  /* 00000370    ".......L" */
+    0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,  /* 00000378    "NKD....." */
+    0xFF,0xFF,0x14,0x00,0x00,0x4C,0x4E,0x4B,  /* 00000380    ".....LNK" */
+    0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,  /* 00000388    "B......." */
+    0x14,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00,  /* 00000390    "...LNKC." */
+    0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x14,0x00,  /* 00000398    "........" */
+    0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12,  /* 000003A0    "..LNKD.." */
+    0x0E,0x04,0x0C,0xFF,0xFF,0x14,0x00,0x0A,  /* 000003A8    "........" */
+    0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,  /* 000003B0    ".LNKA..." */
+    0x04,0x0C,0xFF,0xFF,0x01,0x00,0x00,0x4C,  /* 000003B8    ".......L" */
+    0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,  /* 000003C0    "NKA....." */
+    0xFF,0xFF,0x01,0x00,0x01,0x4C,0x4E,0x4B,  /* 000003C8    ".....LNK" */
+    0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,  /* 000003D0    "B......." */
+    0x01,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x43,  /* 000003D8    "....LNKC" */
+    0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,  /* 000003E0    "........" */
+    0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44,0x00,  /* 000003E8    "...LNKD." */
+
+};
index 3d9873e7b6eafc22b7fc00b6e573baccd4dc201e..702d55698844a2d75d23430c03f7101db514d559 100644 (file)
@@ -15,8 +15,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
 
index bdcb9eaed2475c7903d0f28526fad18b8eb453c9..35317fc7b22ee50079bb126af3491422d308dd0d 100644 (file)
@@ -8,6 +8,7 @@
 
 static unsigned long main(unsigned long bist)
 {
+#if 0
        /* This is the primary cpu how should I boot? */
        if (do_normal_boot()) {
                goto normal_image;
@@ -28,5 +29,6 @@ static unsigned long main(unsigned long bist)
                : /* clobbers */
                );
  fallback_image:
+#endif
        return bist;
 }
index 9eb7b3705ba5feed71afa955667a10b80b064efb..26e5916f0171466fd956a9bd4f2fde6fd60e5cc9 100644 (file)
@@ -25,7 +25,7 @@ static void vga_fixup(void) {
 
 }
  
-static void write_protect_vgabios(void)
+void write_protect_vgabios(void)
 {
        device_t dev;
  
diff --git a/src/mainboard/via/epia-m/vgabios.c b/src/mainboard/via/epia-m/vgabios.c
new file mode 100644 (file)
index 0000000..67620ea
--- /dev/null
@@ -0,0 +1,861 @@
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#undef __KERNEL__
+#include <arch/io.h>
+//#include <printk.h>
+#include <string.h>
+#include "vgachip.h"
+
+/* vgabios.c. Derived from: */
+
+/*------------------------------------------------------------ -*- C -*-
+ *  2 Kernel Monte a.k.a. Linux loading Linux on x86
+ *
+ *  Erik Arjan Hendriks <hendriks@lanl.gov>
+ *
+ *  This version is a derivative of the original two kernel monte
+ *  which is (C) 2000 Scyld.
+ *
+ *  Copyright (C) 2000 Scyld Computing Corporation
+ *
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Portions related to the alpha architecture are:
+ *
+ *  Copyright(C) 2001 University of California.  LA-CC Number 01-67.
+ *  This software has been authored by an employee or employees of the
+ *  University of California, operator of the Los Alamos National
+ *  Laboratory under Contract No.  W-7405-ENG-36 with the U.S.
+ *  Department of Energy.  The U.S. Government has rights to use,
+ *  reproduce, and distribute this software. If the software is
+ *  modified to produce derivative works, such modified software should
+ *  be clearly marked, so as not to confuse it with the version
+ *  available from LANL.
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by
+ *  reference to http://www.gnu.org/licenses/gpl.html.
+ *
+ *  This software is provided by the author(s) "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(s) 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.
+ *
+ *  $Id: vgabios.c,v 1.5 2004/10/06 17:33:52 rminnich Exp $
+ *--------------------------------------------------------------------*/
+
+/* Modified to be a self sufficient plug in so that it can be used 
+   without reliance on other parts of core Linuxbios 
+   (C) 2005 Nick.Barker9@btinternet.com
+
+  Used initially for epia-m where there are problems getting the bios
+  emulator to successfully run this bios.
+*/
+
+/* Declare a temporary global descriptor table - necessary because the
+   Core part of the bios no longer sets up any 16 bit segments */
+__asm__ (
+       /* pointer to original gdt */
+       "gdtarg:                        \n\t"
+       ".word  gdt_limit       \n\t"
+       ".long  gdt                     \n\t"           
+
+       /* compute the table limit */
+       "__mygdt_limit = __mygdt_end - __mygdt - 1      \n\t"
+
+       "__mygdtaddr:                   \n\t"
+       ".word  __mygdt_limit   \n\t"
+       ".long  __mygdt                 \n\t"           
+
+
+       "__mygdt:                               \n\t"
+       /* selgdt 0, unused */
+       ".word  0x0000, 0x0000  \n\t"
+       ".byte  0x00, 0x00, 0x00, 0x00  \n\t"
+
+       /* selgdt 8, unused */
+       ".word  0x0000, 0x0000                  \n\t"
+       ".byte  0x00, 0x00, 0x00, 0x00  \n\t"
+
+       /* selgdt 0x10, flat code segment */
+       ".word  0xffff, 0x0000                  \n\t"           
+       ".byte  0x00, 0x9b, 0xcf, 0x00  \n\t"   
+
+       /* selgdt 0x18, flat data segment */
+       ".word  0xffff, 0x0000                  \n\t"           
+       ".byte  0x00, 0x93, 0xcf, 0x00  \n\t"
+
+       /* selgdt 0x20, unused */
+       ".word  0x0000, 0x0000                  \n\t"
+       ".byte  0x00, 0x00, 0x00, 0x00  \n\t"
+
+        /*selgdt 0x28 16-bit 64k code at 0x00000000 */
+       ".word 0xffff, 0x0000                   \n\t"
+       ".byte 0, 0x9a, 0, 0                    \n\t"
+
+       /* selgdt 0x30 16-bit 64k data at 0x00000000 */
+       ".word 0xffff, 0x0000                   \n\t"
+       ".byte 0, 0x92, 0, 0                    \n\t"
+
+       "__mygdt_end:                                   \n\t"
+);
+
+/* Declare a pointer to where our idt is going to be i.e. at mem zero */
+__asm__ (
+       "__myidt:       \n"
+       "    .word 1023 \n"
+       "    .long 0 \n"
+       "    .word 0 \n"
+);
+
+/* The address arguments to this function are PHYSICAL ADDRESSES */ 
+static void real_mode_switch_call_vga(unsigned long devfn)
+{
+       __asm__ __volatile__ (
+               // paranoia -- does ecx get saved? not sure. This is 
+               // the easiest safe thing to do.
+               "       pushal\n"
+               /* save the stack */
+               "       mov %esp, __stack\n"
+               "       jmp 1f\n"
+               "__stack: .long 0\n"
+               "1:\n"
+               /* get devfn into %ecx */
+               "       movl    %esp, %ebp\n"
+               "       movl    8(%ebp), %ecx\n"
+               /* load 'our' gdt */
+               "   lgdt %cs:__mygdtaddr                \n\t"
+
+               /*  This configures CS properly for real mode. */
+               "       ljmp $0x28, $__rms_16bit\n"
+               "__rms_16bit:                 \n"
+               ".code16                      \n"
+               /* 16 bit code from here on... */
+
+               /* Load the segment registers w/ properly configured segment
+                * descriptors.  They will retain these configurations (limits,
+                * writability, etc.) once protected mode is turned off. */
+               "       mov  $0x30, %ax         \n"
+               "       mov  %ax, %ds          \n"
+               "       mov  %ax, %es          \n"
+               "       mov  %ax, %fs          \n"
+               "       mov  %ax, %gs          \n"
+               "       mov  %ax, %ss          \n"
+
+               /* Turn off protection (bit 0 in CR0) */
+               "       movl %cr0, %eax        \n"
+               "       andl $0xFFFFFFFE, %eax  \n"
+               "       movl %eax, %cr0        \n"
+
+               /* Now really going into real mode */
+               "       ljmp $0,  $__rms_real \n"
+               "__rms_real:                  \n"
+
+               // put the stack at the end of page zero. 
+               // that way we can easily share it between real and protected, 
+               // since the 16-bit ESP at segment 0 will work for any case. 
+               /* Setup a stack */
+               "    mov  $0x0, %ax       \n"
+               "    mov  %ax, %ss          \n"
+               "    movl  $0x1000, %eax       \n"
+               "    movl  %eax, %esp          \n"
+
+               /* Load our 16 it idt */
+               "    xor  %ax, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    lidt __myidt            \n"
+
+
+               /* Dump zeros in the other segregs */
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  $0x40, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    mov %cx, %ax       \n"
+               /* go run the code */
+               " .byte 0x9a, 0x03, 0, 0, 0xc0  \n"
+
+               /* if we got here, just about done. 
+                * Need to get back to protected mode */
+               "movl   %cr0, %eax\n"
+               "orl    $0x0000001, %eax\n" /* PE = 1 */
+               "movl   %eax, %cr0\n"
+
+               /* Now that we are in protected mode jump to a 32 bit code segment. */
+               "data32 ljmp    $0x10, $vgarestart\n"
+               "vgarestart:\n"
+               ".code32\n"
+               "    movw $0x18, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  %ax, %ss          \n"
+
+               /* restore proper gdt and idt */
+               "        lgdt %cs:gdtarg                        \n"
+               "    lidt idtarg            \n"
+               ".globl vga_exit\n"
+               "vga_exit:\n"
+               "    mov  __stack, %esp\n"
+               "    popal\n"
+               );
+}
+
+__asm__ (".text\n""real_mode_switch_end:\n");
+extern char real_mode_switch_end[];
+
+/* call vga bios int 10 function 0x4f14 to enable main console 
+   epia-m does not always autosence the main console so forcing it on is good !! */
+void vga_enable_console()
+{
+       __asm__ __volatile__ (
+               // paranoia -- does ecx get saved? not sure. This is 
+               // the easiest safe thing to do.
+               "       pushal\n"
+               /* save the stack */
+               "       mov %esp, __stack\n"
+
+               /* load 'our' gdt */
+               "   lgdt %cs:__mygdtaddr                \n\t"
+
+               /*  This configures CS properly for real mode. */
+               "       ljmp $0x28, $__vga_ec_16bit\n"
+               "__vga_ec_16bit:                 \n"
+               ".code16                      \n"
+               /* 16 bit code from here on... */
+
+               /* Load the segment registers w/ properly configured segment
+                * descriptors.  They will retain these configurations (limits,
+                * writability, etc.) once protected mode is turned off. */
+               "       mov  $0x30, %ax         \n"
+               "       mov  %ax, %ds          \n"
+               "       mov  %ax, %es          \n"
+               "       mov  %ax, %fs          \n"
+               "       mov  %ax, %gs          \n"
+               "       mov  %ax, %ss          \n"
+
+               /* Turn off protection (bit 0 in CR0) */
+               "       movl %cr0, %eax        \n"
+               "       andl $0xFFFFFFFE, %eax  \n"
+               "       movl %eax, %cr0        \n"
+
+               /* Now really going into real mode */
+               "       ljmp $0,  $__vga_ec_real \n"
+               "__vga_ec_real:                  \n"
+
+               // put the stack at the end of page zero. 
+               // that way we can easily share it between real and protected, 
+               // since the 16-bit ESP at segment 0 will work for any case. 
+               /* Setup a stack */
+               "    mov  $0x0, %ax       \n"
+               "    mov  %ax, %ss          \n"
+               "    movl  $0x1000, %eax       \n"
+               "    movl  %eax, %esp          \n"
+               /* debugging for RGM */
+               "    mov $0x11, %al     \n"
+               " outb  %al, $0x80\n"
+
+               /* Load our 16 it idt */
+               "    xor  %ax, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    lidt __myidt            \n"
+
+               /* Dump zeros in the other segregs */
+               "    mov  %ax, %ds          \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+
+               /* ask bios to enable main console */
+               /* set up for int 10 call - values found from X server bios call routines */
+               "    movw $0x4f14,%ax    \n"
+               "    movw $0x8003,%bx     \n"
+               "    movw $1, %cx          \n"
+               "    movw $0, %dx          \n"
+               "    movw $0, %di          \n"
+               "  .byte 0xcd, 0x10             \n"
+               " movb $0x55, %al\noutb %al, $0x80\n"
+
+               /* if we got here, just about done. 
+                * Need to get back to protected mode */
+               "movl   %cr0, %eax\n"
+               "orl    $0x0000001, %eax\n" /* PE = 1 */
+               "movl   %eax, %cr0\n"
+
+               /* Now that we are in protected mode jump to a 32 bit code segment. */
+               "data32 ljmp    $0x10, $vga_ec_restart\n"
+               "vga_ec_restart:\n"
+               ".code32\n"
+               "    movw $0x18, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  %ax, %ss          \n"
+
+
+               /* restore proper gdt and idt */
+               "        lgdt %cs:gdtarg                        \n"
+               "    lidt idtarg            \n"
+               ".globl vga__ec_exit\n"
+               "vga_ec_exit:\n"
+               "    mov  __stack, %esp\n"
+               "    popal\n"
+               );
+}
+
+
+void
+do_vgabios(void)
+{
+       device_t dev;
+       unsigned long busdevfn;
+       unsigned int rom = 0;
+       unsigned char *buf;
+       unsigned int size = 64*1024;
+       int i;
+       
+       /* clear vga bios data area */
+       for (i=0x400; i<0x500; i++) {
+               *(unsigned char *) i = 0;
+       }
+
+       dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0);
+
+       if (! dev) {
+               printk_debug("NO VGA FOUND\n");
+               return;
+       }
+       printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
+       
+       /* declare rom address here - keep any config data out of the way of core LXB stuff */
+
+       rom = 0xfffc0000;
+       pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
+       printk_debug("rom base, size: %x\n", rom);
+
+       buf = (unsigned char *) rom;
+       if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
+               memcpy((void *) 0xc0000, buf, size);
+
+               write_protect_vgabios();  // in northbridge
+
+               // check signature again
+               buf = (unsigned char *) 0xc0000;
+               if (buf[0]==0x55 && buf[1]==0xAA) {
+                       busdevfn = (dev->bus->secondary << 8) | dev->path.u.pci.devfn;
+                       printk_debug("bus/devfn = %#x\n", busdevfn);
+
+                       real_mode_switch_call_vga(busdevfn);
+               } else
+                       printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
+               
+       } else 
+               printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
+       
+       pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
+
+}
+
+
+// we had hoped to avoid this. 
+// this is a stub IDT only. It's main purpose is to ignore calls 
+// to the BIOS. 
+// no longer. Dammit. We have to respond to these.
+struct realidt {
+       unsigned short offset, cs;
+}; 
+
+// from a handy writeup that andrey found.
+
+// handler. 
+// There are some assumptions we can make here. 
+// First, the Top Of Stack (TOS) is located on the top of page zero. 
+// we can share this stack between real and protected mode. 
+// that simplifies a lot of things ...
+// we'll just push all the registers on the stack as longwords, 
+// and pop to protected mode. 
+// second, since this only ever runs as part of linuxbios, 
+// we know all the segment register values -- so we don't save any.
+// keep the handler that calls things small. It can do a call to 
+// more complex code in linuxbios itself. This helps a lot as we don't
+// have to do address fixup in this little stub, and calls are absolute
+// so the handler is relocatable.
+void handler(void) {
+       __asm__ __volatile__ ( 
+               ".code16\n"
+               "idthandle:\n"
+               "       pushal\n"
+               "       movb $0, %al\n"
+               "       ljmp $0, $callbiosint16\n"
+               "end_idthandle:\n"
+               ".code32\n"
+               );
+
+}
+
+void debughandler(void) {
+       __asm__ __volatile__ ( 
+               ".code16\n"
+               "debughandle:\n"
+               "   pushw %cx  \n"
+               "   movw  $250, %cx \n"
+               "dbh1:         \n"
+               "       loop dbh1  \n"
+               "   popw %cx   \n"
+               "       iret \n"
+               "end_debughandle:\n"
+               ".code32\n"
+               );
+
+}
+
+// Calling conventions. The first C function is called with this stuff
+// on the stack. They look like value parameters, but note that if you
+// modify them they will go back to the INTx function modified. 
+// the C function will call the biosint function with these as
+// REFERENCE parameters. In this way, we can easily get 
+// returns back to the INTx caller (i.e. vgabios)
+void callbiosint(void) {
+       __asm__ __volatile__ (
+               ".code16\n"
+               "callbiosint16:\n"
+               " push %ds \n"
+               " push %es \n"
+               " push %fs \n"
+               " push %gs \n"
+               // clean up the int #. To save space we put it in the lower
+               // byte. But the top 24 bits are junk. 
+               "andl $0xff, %eax\n"
+               // this push does two things:
+               // - put the INT # on the stack as a parameter
+               // - provides us with a temp for the %cr0 mods.
+               "pushl  %eax\n"
+               "movl    %cr0, %eax\n"
+               //"andl    $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
+               //"orl    $0x60000001, %eax\n" /* CD, NW, PE = 1 */
+               "orl    $0x00000001, %eax\n" /* PE = 1 */
+               "movl    %eax, %cr0\n"
+               /* Now that we are in protected mode jump to a 32 bit code segment. */
+               "data32  ljmp    $0x10, $biosprotect\n"
+               "biosprotect:\n"
+               ".code32\n"
+               "    movw $0x18, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  %ax, %ss          \n"
+               "   lidt idtarg         \n"
+               "       call    biosint \n"
+               // back to real mode ...
+               "    ljmp $0x28, $__rms_16bit2\n"
+               "__rms_16bit2:                 \n"
+               ".code16                      \n" /* 16 bit code from here on... */
+               
+               /* Load the segment registers w/ properly configured segment
+                * descriptors.  They will retain these configurations (limits,
+                * writability, etc.) once protected mode is turned off. */
+               "    mov  $0x30, %ax         \n"
+               "    mov  %ax, %ds          \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  %ax, %ss          \n"
+               
+               /* Turn off protection (bit 0 in CR0) */
+               "    movl %cr0, %eax        \n"
+               "    andl $0xFFFFFFFE, %eax  \n"
+               "    movl %eax, %cr0        \n"
+               
+               /* Now really going into real mode */
+               "    ljmp $0,  $__rms_real2 \n"
+               "__rms_real2:                  \n"
+               
+               /* Setup a stack */
+               "    mov  $0x0, %ax       \n"
+               "    mov  %ax, %ss          \n"
+               /* ebugging for RGM */
+               "    mov $0x11, %al      \n"
+               " outb  %al, $0x80\n"
+               "    xor  %ax, %ax          \n"
+               "    mov  %ax, %ds          \n"
+               "    lidt __myidt           \n"
+               "    mov  %ax, %es          \n"
+               "    mov  %ax, %fs          \n"
+               "    mov  %ax, %gs          \n"
+               "    mov  $0x40, %ax        \n"
+               "    mov  %ax, %ds          \n"
+               // pop the INT # that you pushed earlier
+               "   popl        %eax\n"
+               "   pop %gs \n"
+               "   pop %fs \n"
+               "   pop %es \n"
+               "   pop %ds \n"
+               "   popal\n"
+               "   iret\n"
+               ".code32\n"
+               );
+}
+
+
+enum {
+       PCIBIOS = 0x1a, 
+       MEMSIZE = 0x12
+};
+int
+pcibios(
+        unsigned long *pedi,
+        unsigned long *pesi,
+        unsigned long *pebp,
+        unsigned long *pesp,
+        unsigned long *pebx,
+        unsigned long *pedx,
+        unsigned long *pecx,
+        unsigned long *peax,
+        unsigned long *pflags
+        );
+int
+handleint21(
+        unsigned long *pedi,
+        unsigned long *pesi,
+        unsigned long *pebp,
+        unsigned long *pesp,
+        unsigned long *pebx,
+        unsigned long *pedx,
+        unsigned long *pecx,
+        unsigned long *peax,
+        unsigned long *pflags
+        );
+
+extern void vga_exit(void);
+
+int
+biosint(
+       unsigned long intnumber,
+       unsigned long gsfs,
+       unsigned long dses,
+       unsigned long edi, 
+       unsigned long esi,
+       unsigned long ebp, 
+       unsigned long esp, 
+       unsigned long ebx, 
+       unsigned long edx, 
+       unsigned long ecx, 
+       unsigned long eax, 
+       unsigned long cs_ip,
+       unsigned short stackflags
+       ) {
+       unsigned long ip; 
+       unsigned long cs; 
+       unsigned long flags;
+       int ret = -1;
+       
+       ip = cs_ip & 0xffff;
+       cs = cs_ip >> 16;
+       flags = stackflags;
+       
+       printk_debug("biosint: # 0x%lx, eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n", 
+                    intnumber, eax, ebx, ecx, edx);
+       printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n", ebp, esp, edi, esi);
+       printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n", ip, cs, flags);
+       // cases in a good compiler are just as good as your own tables. 
+       switch (intnumber) {
+       case 0 ... 15:
+               // These are not BIOS service, but the CPU-generated exceptions
+               printk_info("biosint: Oops, exception %u\n", intnumber);
+               if (esp < 0x1000) {
+                       printk_debug("Stack contents: ");
+                       while (esp < 0x1000) {
+                               printk_debug("0x%04x ", *(unsigned short *) esp);
+                               esp += 2;
+                       }
+                       printk_debug("\n");
+               }
+               printk_debug("biosint: Bailing out\n");
+               // "longjmp"
+               vga_exit();
+               break;
+               
+       case PCIBIOS:
+               ret = pcibios( &edi, &esi, &ebp, &esp, 
+                              &ebx, &edx, &ecx, &eax, &flags);
+               break;
+       case MEMSIZE: 
+               // who cares. 
+               eax = 64 * 1024;
+               ret = 0;
+               break;
+       case 0x15:
+               ret=handleint21( &edi, &esi, &ebp, &esp, 
+                               &ebx, &edx, &ecx, &eax, &flags);
+               break;
+       default:
+               printk_info("BIOSINT: Unsupport int #0x%x\n", 
+                           intnumber);
+               break;
+       }
+       if (ret)
+               flags |= 1; // carry flags
+       else
+               flags &= ~1;
+       stackflags = flags;
+       return ret;
+} 
+
+
+void setup_realmode_idt(void) 
+{
+       extern unsigned char idthandle, end_idthandle;
+       extern unsigned char debughandle, end_debughandle;
+
+       int i;
+       struct realidt *idts = (struct realidt *) 0;
+       int codesize = &end_idthandle - &idthandle;
+       unsigned char *intbyte, *codeptr;
+       
+       // for each int, we create a customized little handler
+       // that just pushes %ax, puts the int # in %al, 
+       // then calls the common interrupt handler. 
+       // this necessitated because intel didn't know much about 
+       // architecture when they did the 8086 (it shows)
+       // (hmm do they know anymore even now :-)
+       // obviously you can see I don't really care about memory 
+       // efficiency. If I did I would probe back through the stack
+       // and get it that way. But that's really disgusting.
+       for (i = 0; i < 256; i++) {
+               idts[i].cs = 0;
+               codeptr = (char*) 4096 + i * codesize;
+               idts[i].offset = (unsigned) codeptr;
+               memcpy(codeptr, &idthandle, codesize);
+               intbyte = codeptr + 3;
+               *intbyte = i;
+       }
+       
+       // fixed entry points
+       
+       // VGA BIOSes tend to hardcode f000:f065 as the previous handler of
+       // int10. 
+       // calling convention here is the same as INTs, we can reuse
+       // the int entry code.
+       codeptr = (char*) 0xff065;
+       memcpy(codeptr, &idthandle, codesize);
+       intbyte = codeptr + 3;
+       *intbyte = 0x42; /* int42 is the relocated int10 */
+
+       /* debug handler - useful to set a programmable delay between instructions if the TF bit is set upon
+           call to real mode */
+       idts[1].cs = 0;
+       idts[1].offset = 16384;
+       memcpy(16384, &debughandle, &end_debughandle - &debughandle);
+
+       
+}
+
+
+
+enum {
+       CHECK = 0xb001,
+       FINDDEV = 0xb102,
+       READCONFBYTE = 0xb108,
+       READCONFWORD = 0xb109,
+       READCONFDWORD = 0xb10a,
+       WRITECONFBYTE = 0xb10b,
+       WRITECONFWORD = 0xb10c,
+       WRITECONFDWORD = 0xb10d
+};
+
+// errors go in AH. Just set these up so that word assigns
+// will work. KISS. 
+enum {
+       PCIBIOS_NODEV = 0x8600,
+       PCIBIOS_BADREG = 0x8700
+};
+
+int
+pcibios(
+       unsigned long *pedi, 
+       unsigned long *pesi,
+       unsigned long *pebp, 
+       unsigned long *pesp, 
+       unsigned long *pebx, 
+       unsigned long *pedx, 
+       unsigned long *pecx, 
+       unsigned long *peax, 
+       unsigned long *pflags
+       ) {
+       unsigned long edi = *pedi;
+       unsigned long esi = *pesi;
+       unsigned long ebp = *pebp;
+       unsigned long esp = *pesp;
+       unsigned long ebx = *pebx;
+       unsigned long edx = *pedx;
+       unsigned long ecx = *pecx;
+       unsigned long eax = *peax;
+       unsigned long flags = *pflags;
+       unsigned short func = (unsigned short) eax;
+       int retval = 0;
+       unsigned short devid, vendorid, devfn;
+       short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
+       unsigned char bus;
+       device_t dev;
+       
+       switch(func) {
+       case  CHECK:
+               *pedx = 0x4350;
+               *pecx = 0x2049;
+               retval = 0;
+               break;
+       case FINDDEV:
+       {
+               devid = *pecx;
+               vendorid = *pedx;
+               devindex = *pesi;
+               dev = 0;
+               while ((dev = dev_find_device(vendorid, devid, dev))) {
+                       if (devindex <= 0)
+                               break;
+                       devindex--;
+               }
+               if (dev) {
+                       unsigned short busdevfn;
+                       *peax = 0;
+                       // busnum is an unsigned char;
+                       // devfn is an int, so we mask it off. 
+                       busdevfn = (dev->bus->secondary << 8)
+                               | (dev->path.u.pci.devfn & 0xff);
+                       printk_debug("0x%x: return 0x%x\n", func, busdevfn);
+                       *pebx = busdevfn;
+                       retval = 0;
+               } else {
+                       *peax = PCIBIOS_NODEV;
+                       retval = -1;
+               }
+       }
+       break;
+       case READCONFDWORD:
+       case READCONFWORD:
+       case READCONFBYTE:
+       case WRITECONFDWORD:
+       case WRITECONFWORD:
+       case WRITECONFBYTE:
+       {
+               unsigned long dword;
+               unsigned short word;
+               unsigned char byte;
+               unsigned char reg;
+               
+               devfn = *pebx & 0xff;
+               bus = *pebx >> 8;
+               reg = *pedi;
+               dev = dev_find_slot(bus, devfn);
+               if (! dev) {
+                       printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
+                       // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
+                       *peax = PCIBIOS_BADREG;
+                       retval = -1;
+               }
+               switch(func) {
+               case READCONFBYTE:
+                       byte = pci_read_config8(dev, reg);
+                       *pecx = byte;
+                       break;
+               case READCONFWORD:
+                       word = pci_read_config16(dev, reg);
+                       *pecx = word;
+                       break;
+               case READCONFDWORD:
+                       dword = pci_read_config32(dev, reg);
+                       *pecx = dword;
+                       break;
+               case WRITECONFBYTE:
+                       byte = *pecx;
+                       pci_write_config8(dev, reg, byte);
+                       break;
+               case WRITECONFWORD:
+                       word = *pecx;
+                       pci_write_config16(dev, reg, word);
+                       break;
+               case WRITECONFDWORD:
+                       dword = *pecx;
+                       pci_write_config32(dev, reg, dword);
+                       break;
+               }
+               
+               if (retval) 
+                       retval = PCIBIOS_BADREG;
+               printk_debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n", func, bus, devfn, reg, *pecx);
+               *peax = 0;
+               retval = 0;
+       }
+       break;
+       default:
+               printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n",  func);
+               break;
+       }
+       
+       return retval;
+} 
+
+
+
+int handleint21( unsigned long *edi, unsigned long *esi, unsigned long *ebp,
+                         unsigned long *esp, unsigned long *ebx, unsigned long *edx,
+                         unsigned long *ecx, unsigned long *eax, unsigned long *flags)
+{
+int res=-1;
+       switch(*eax&0xffff)
+       {
+       case 0x5f19:
+               break;
+       case 0x5f18:
+               *eax=0x5f;
+               *ebx=0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
+               *ecx=0x060;
+               res=0;
+               break;
+       case 0x5f00:
+               *eax = 0x8600;
+               break;
+       case 0x5f01:
+               *eax = 0x5f;
+               *ecx = (*ecx & 0xffffff00 ) | 2; // panel type =  2 = 1024 * 768
+               res = 0;
+               break;
+       case 0x5f02:
+               *eax=0x5f;
+               *ebx= (*ebx & 0xffff0000) | 2;
+               *ecx= (*ecx & 0xffff0000) | 0x401;  // PAL + crt only 
+               *edx= (*edx & 0xffff0000) | 0;  // TV Layout - default
+               res=0;
+               break;
+       case 0x5f0f:
+               *eax=0x860f;
+               break;
+       }
+       return res;
+}
diff --git a/src/mainboard/via/epia-m/vgachip.h b/src/mainboard/via/epia-m/vgachip.h
new file mode 100644 (file)
index 0000000..d43788c
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _PC80_VGABIOS
+#define _PC80_VGABIOS
+
+extern struct chip_control pc80_vgabios_control;
+
+struct pc80_vgabios_config {
+       int nothing;
+};
+
+#endif /* _PC80_VGABIOS */
index bfaaeac30f021e5a07c187e2fe49b32390579aac..7143c358da19a2dff245bbbf4387d0f769d9e3b2 100644 (file)
@@ -10,6 +10,7 @@
 #include <bitops.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
 #include "chip.h"
 #include "northbridge.h"
 
  * slower than normal, ethernet drops packets).
  * Apparently these registers govern some sort of bus master behavior.
  */
+static void dump_dev(device_t dev)
+{
+       int i,j;
+       
+       for(i = 0; i < 256; i += 16) {
+               printk_debug("0x%x: ", i);
+               for(j = 0; j < 16; j++) {
+                       printk_debug("%02x ", pci_read_config8(dev, i+j));
+               }
+               printk_debug("\n");
+       }
+}
 static void northbridge_init(device_t dev) 
 {
        device_t fb_dev;
@@ -44,21 +57,25 @@ static void northbridge_init(device_t dev)
                /* Fixup GART and framebuffer addresses properly.
                 * First setup frame buffer properly.
                 */
-               fb = pci_read_config32(dev, 0x10);       /* Base addres of framebuffer */
+               //fb = pci_read_config32(dev, 0x10);       /* Base addres of framebuffer */
+               fb = 0xd0000000;
                printk_debug("Frame buffer at %8x\n",fb);
 
                c = pci_read_config8(dev, 0xe1) & 0xf0;  /* size of vga */
                c |= fb>>28;  /* upper nibble of frame buffer address */
+               c = 0xdd;
                pci_write_config8(dev, 0xe1, c);
-               c = (fb>>20) | 1;                        /* enable framebuffer */
+               c = 0x81;                                /* enable framebuffer */
                pci_write_config8(dev, 0xe0, c);
                pci_write_config8(dev, 0xe2, 0x42);      /* 'cos award does */
        }
+       //dump_dev(dev);
 }
 
+static void nullfunc(){}
 
 static struct device_operations northbridge_operations = {
-       .read_resources   = pci_dev_read_resources,
+       .read_resources   = nullfunc,
        .set_resources    = pci_dev_set_resources,
        .enable_resources = pci_dev_enable_resources,
        .init             = northbridge_init
@@ -80,10 +97,11 @@ static void agp_init(device_t dev)
        pci_write_config8(dev, 0x43, 0x44);
        pci_write_config8(dev, 0x44, 0x34);
        pci_write_config8(dev, 0x83, 0x02);
+       //dump_dev(dev);
 }
 
 static struct device_operations agp_operations = {
-       .read_resources   = pci_bus_read_resources,
+       .read_resources   = nullfunc,
        .set_resources    = pci_dev_set_resources,
        .enable_resources = pci_bus_enable_resources,
        .init             = agp_init,
@@ -100,12 +118,64 @@ static struct pci_driver agp_driver __pci_driver = {
 static void vga_init(device_t dev)
 {
 //     unsigned long fb;
+       msr_t clocks1,clocks2,instructions,setup;
 
        printk_debug("VGA random fixup ...\n");
        pci_write_config8(dev, 0x04, 0x07);
        pci_write_config8(dev, 0x0d, 0x20);
+       pci_write_config32(dev,0x10,0xd8000008);
+       pci_write_config32(dev,0x14,0xdc000000);
+
+       //dump_dev(dev);
+       
+       // set up performnce counters for debugging vga init sequence
+       //setup.lo = 0x1c0; // count instructions
+       //wrmsr(0x187,setup);
+       //instructions.hi = 0;
+       //instructions.lo = 0;
+       //wrmsr(0xc2,instructions);
+       //clocks1 = rdmsr(0x10);
+
+       
+#if 0
+       /* code to make vga init go through the emulator - as of yet this does not workfor the epia-m */
+       dev->on_mainboard=1;
+       dev->rom_address = (void *)0xfffc0000;
+
+       pci_dev_init(dev);
+       
+       call_bios_interrupt(0x10,0x4f1f,0x8003,1,0);
+       
+       //clocks2 = rdmsr(0x10);
+       //instructions = rdmsr(0xc2);
+       
+       printk_debug("Clocks 1 = %08x:%08x\n",clocks1.hi,clocks1.lo);
+       printk_debug("Clocks 2 = %08x:%08x\n",clocks2.hi,clocks2.lo);
+       printk_debug("Instructions = %08x:%08x\n",instructions.hi,instructions.lo);
+
+#else
+
+       /* code to make vga init run in real mode - does work but against the current Linuxbios philosophy */
+       printk_debug("INSTALL REAL-MODE IDT\n");
+        setup_realmode_idt();
+        printk_debug("DO THE VGA BIOS\n");
+        do_vgabios();
+
+       //clocks2 = rdmsr(0x10);
+       //instructions = rdmsr(0xc2);
        
-       /* Set the vga mtrrs - disable for the moment */
+       //printk_debug("Clocks 1 = %08x:%08x\n",clocks1.hi,clocks1.lo);
+       //printk_debug("Clocks 2 = %08x:%08x\n",clocks2.hi,clocks2.lo);
+       //printk_debug("Instructions = %08x:%08x\n",instructions.hi,instructions.lo);
+
+        vga_enable_console();
+       
+#endif
+
+
+       pci_write_config32(dev,0x30,0);
+
+       /* Set the vga mtrrs - disable for the moment as the add_var_mtrr function has vapourised */
 #if 0
        add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
        fb = pci_read_config32(dev,0x10); // get the fb address
@@ -113,8 +183,17 @@ static void vga_init(device_t dev)
 #endif
 }
 
+static void vga_read_resources(device_t dev)
+{
+
+       dev->rom_address = (void *)0xfffc0000;
+       dev->on_mainboard=1;
+       pci_dev_read_resources(dev);
+
+}
+
 static struct device_operations vga_operations = {
-       .read_resources   = pci_dev_read_resources,
+       .read_resources   = vga_read_resources,
        .set_resources    = pci_dev_set_resources,
        .enable_resources = pci_dev_enable_resources,
        .init             = vga_init,
index 7371e09e57c0f4d7e50a902a83c00dbfbd1a3567..750193231a2a26d2c6f1fe7ab22994b04bb8061d 100644 (file)
@@ -1,91 +1,50 @@
-#include <cpu/x86/mtrr.h>
-#include "raminit.h"
-
-/*
-This software and ancillary information (herein called SOFTWARE )
-called LinuxBIOS          is made available under the terms described
-here.  The SOFTWARE has been approved for release with associated
-LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
-been authored by an employee or employees of the University of
-California, operator of the Los Alamos National Laboratory under
-Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
-U.S. Government has rights to use, reproduce, and distribute this
-SOFTWARE.  The public may copy, distribute, prepare derivative works
-and publicly display this SOFTWARE without charge, provided that this
-Notice and any statement of authorship are reproduced on all copies.
-Neither the Government nor the University makes any warranty, express 
-or implied, or assumes any liability or responsibility for the use of
-this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
-such modified SOFTWARE should be clearly marked, so as not to confuse
-it with the version available from LANL.
- */
-/* Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
- * rminnich@lanl.gov
- */
 /*
- * 11/26/02 - kevinh@ispiri.com - The existing comments implied that
- * this didn't work yet.  Therefore, I've updated it so that it works
- * correctly - at least on my VIA epia motherboard.  64MB DIMM in slot 0.
- */
-
-/* Added automatic detection of first equipped bank and its MA mapping type.
- * (Rest of configuration is done in C)
- * 5/19/03 by SONE Takeshi <ts1@tsn.or.jp>
+ * (C) Copyright 2005 Nick Barker <nick.barker9@btinternet.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; 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
  */
-/* converted to C 9/2003 Ron Minnich */
-
-/* Set to 1 if your DIMMs are PC133 Note that I'm assuming CPU's FSB
- * frequency is 133MHz. If your CPU runs at another bus speed, you
- * might need to change some of register values.
- */
-#ifndef DIMM_PC133
-#define DIMM_PC133 0
-#endif
-
-// Set to 1 if your DIMMs are CL=2
-#ifndef DIMM_CL2
-#define DIMM_CL2 0
-#endif
 
+/* 
+  Automatically detect and set up ddr dram on the CLE266 chipset.
+  Assumes DDR memory, though chipset also supports SDRAM
+  Assumes at least 266Mhz memory as no attempt is made to clock
+  the chipset down if slower memory is installed.
+  So far tested on:
+       256 Mb 266Mhz 1 Bank (i.e. single sided)
+       256 Mb 266Mhz 2 Bank (i.e. double sided)
+       512 Mb 266Mhz 2 Bank (i.e. double sided)
+*/
+/* ported and enhanced from assembler level code in Linuxbios v1 */
 
+#include <cpu/x86/mtrr.h>
+#include "raminit.h"
 
 
 
-void dimm_read(unsigned long x) 
+void dimm_read(unsigned long bank,unsigned long x) 
 {
-       unsigned long eax; 
+       //unsigned long eax; 
        volatile unsigned long y;
-       eax =  x;
-       y = * (volatile unsigned long *) eax;
-
-}
+       //eax =  x;
+       y = * (volatile unsigned long *) (x+ bank) ;
 
-void dimms_write(int x) 
-{
-       uint8_t c;
-       unsigned long eax = x;
-       for(c = 0; c < 6; c++) {
-               *(volatile unsigned long *) eax = 0;
-               eax += 0x10000000;
-       }
 }
 
 
-
-#ifdef DEBUG_SETNORTHB
-void setnorthb(device_t north, uint8_t reg, uint8_t val) 
-{
-       print_debug("setnorth: reg ");
-       print_debug_hex8(reg);
-       print_debug(" to ");
-       print_debug_hex8(val);
-       print_debug("\r\n");
-       pci_write_config8(north, reg, val);
-}
-#else
-#define setnorthb pci_write_config8
-#endif
-
 void
 dumpnorth(device_t north) 
 {
@@ -100,246 +59,527 @@ dumpnorth(device_t north)
                print_debug("\r\n");
   }
 }
+void print_val(char *str, int val)
+{
+       print_debug(str);
+       print_debug_hex8(val);
+}
 
-static void sdram_set_registers(const struct mem_controller *ctrl) 
+static void ddr_ram_setup(const struct mem_controller *ctrl) 
 {
        device_t north = (device_t) 0;
-       uint8_t c, r;
+       uint8_t b, c, bank;
+       uint16_t i,j;
+       unsigned long bank_address;
 
        print_err("vt8623 init starting\r\n");
        north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0);
        north = 0;
-       print_debug_hex32(north);
-       print_debug(" is the north\r\n");
-       print_debug_hex16(pci_read_config16(north, 0));
-       print_debug(" ");
-       print_debug_hex16(pci_read_config16(north, 2));
-       print_debug("\r\n");
        
-       /* All we are doing now is setting initial known-good values that will
-        * be revised later as we read SPD
-        */     
 
        pci_write_config8(north,0x75,0x08);
 
-       /* since we only support epia-m at the moment, only ddr is supported */
        /* setup cpu */
        pci_write_config8(north,0x50,0xc8);
        pci_write_config8(north,0x51,0xde);
        pci_write_config8(north,0x52,0xcf);
        pci_write_config8(north,0x53,0x88);
-       pci_write_config8(north,0x55,0x07);
+       pci_write_config8(north,0x55,0x04);
 
-       /* DRAM MA Map Type */
-       pci_write_config8(north,0x58,0xe0);
+/*
+    DRAM MA Map Type  Device 0  Offset 58
 
-       /* DRAM bank 0 - 3 size = 512M */
-       pci_write_config8(north,0x5a,0x10);
-       pci_write_config8(north,0x5b,0x10);
-       pci_write_config8(north,0x5c,0x10);
-       pci_write_config8(north,0x5d,0x10);
+    Determine memory addressing based on the module's memory technology and
+    arrangement.  See Table 4-9 of Intel's 82443GX datasheet for details.
 
-       /* set DRAM timing for all banks */
-       pci_write_config8(north,0x64,0xe6);
+    Bank 1/0 MA map type   58[7-5]
+    Bank 1/0 command rate  58[4]
+    Bank 3/2 MA map type   58[3-1]
+    Bank 3/2 command rate  58[0]
 
-       /* set DRAM type to DDR */
-       pci_write_config8(north,0x60,0x02);
 
+    Read SPD byte 17, Number of banks on SDRAM device.
+*/
+       c = 0;
+       b = smbus_read_byte(0xa0,17);
+       print_val("Detecting Memory\r\nNumber of Banks ",b);
 
-       /* DRAM arbitration timer */
-       pci_write_config8(north,0x65,0x32);
-       pci_write_config8(north,0x66,0x01);
-       pci_write_config8(north,0x68,0x59);
+       if( b != 2 ){            // not 16 Mb type
+       
+/*
+    Read SPD byte 3, Number of row addresses.
+*/
+               b = smbus_read_byte(0xa0,3);
+               print_val("\r\nNumber of Rows ",b);
+               if( b >= 0x0d ){        // not 64/128Mb (rows <=12)
 
+/*
+    Read SPD byte 13, Primary DRAM width.
+*/
+                       b = smbus_read_byte(0xa0,13);
+                       print_val("\r\nPriamry DRAM width",b);
+                       if( b != 4 )   // mot 64/128Mb (x4)
+                               c = 0x80;  // 256Mb
+               }
 
-       /* DRAM Frequency */
-       pci_write_config8(north,0x54,0xe0);
-       pci_write_config8(north,0x69,0x2d);
+/*
+    64/128Mb chip
 
-       /* Enable CKE */
-       pci_write_config8(north,0x6b,0x10);
+    Read SPD byte 4, Number of column addresses.
+*/             
+               b = smbus_read_byte(0xa0,4);
+               print_val("\r\nNo Columns ",b);
+               if( b == 10 || b == 11 ) c |= 0x60;   // 10/11 bit col addr
+               if( b == 9 ) c |= 0x40;           // 9 bit col addr
+               if( b == 8 ) c |= 0x20;           // 8 bit col addr
+
+       }
+       print_val("\r\nMA type ",c);
+       pci_write_config8(north,0x58,c);
+
+/*
+    DRAM bank size.  See 4.3.1 pg 35
+
+    5a->5d  set to end address for each bank.  1 bit == 16MB
+    5a = bank 0
+    5b = bank 0 + b1
+    5c = bank 0 + b1 + b2
+    5d = bank 0 + b1 + b2 + b3
+*/
+
+// Read SPD byte 31 Module bank density
+       c = 0;
+       b = smbus_read_byte(0xa0,31);
+       if( b & 0x02 ) c = 0x80;         // 2GB
+       else if( b & 0x01) c = 0x40;     // 1GB
+       else if( b & 0x80) c = 0x20;     // 512Mb
+       else if( b & 0x40) c = 0x10;     // 256Mb 
+       else if( b & 0x20) c = 0x08;     // 128Mb
+       else if( b & 0x10) c = 0x04;     // 64Mb
+       else if( b & 0x08) c = 0x02;     // 32Mb
+       else if( b & 0x04) c = 0x01;     // 16Mb / 4Gb
+       else c = 0x01;                   // Error, use default
+
+
+       print_val("\r\nBank 0 (*16 Mb) ",c);
+
+       // set bank zero size
+       pci_write_config8(north,0x5a,c);
+       // SPD byte 5  # of physical banks
+       b = smbus_read_byte(0xa0,5);
+
+       print_val("\r\nNo Physical Banks ",b);
+       if( b == 2)
+               c <<=1;
+
+       print_val("\r\nTotal Memory (*16 Mb) ",c);
+       // set banks 1,2,3
+       pci_write_config8(north,0x5b,c);
+       pci_write_config8(north,0x5c,c);
+       pci_write_config8(north,0x5d,c);
+
+
+       /* Read SPD byte 18 CAS Latency */
+       b = smbus_read_byte(0xa0,18);
+       print_debug("\r\nCAS Supported ");
+       if(b & 0x04)
+               print_debug("2 ");
+       if(b & 0x08)
+               print_debug("2.5 ");
+       if(b & 0x10)
+               print_debug("3");
+       print_val("\r\nCycle time at CL X     (nS)",smbus_read_byte(0xa0,9));
+       print_val("\r\nCycle time at CL X-0.5 (nS)",smbus_read_byte(0xa0,23));
+       print_val("\r\nCycle time at CL X-1   (nS)",smbus_read_byte(0xa0,25));
        
-       /* Disable DRAM refresh */
-       pci_write_config8(north,0x6a,0x0);
 
-       /* set heavy drive */
-       pci_write_config8(north,0x6d,0x44);
+       if( b & 0x10 ){             // DDR offering optional CAS 3
+               print_debug("\r\nStarting at CAS 3");
+               c = 0x30;
+               /* see if we can better it */
+               if( b & 0x08 ){     // DDR mandatory CAS 2.5
+                       if( smbus_read_byte(0xa0,23) <= 0x75 ){ // we can manage 133Mhz at CAS 2.5
+                               print_debug("\r\nWe can do CAS 2.5");
+                               c = 0x20;
+                       }
+               }
+               if( b & 0x04 ){     // DDR mandatory CAS 2
+                       if( smbus_read_byte(0xa0,25) <= 0x75 ){ // we can manage 133Mhz at CAS 2
+                               print_debug("\r\nWe can do CAS 2");
+                               c = 0x10;
+                       }
+               }
+       }else{                     // no optional CAS values just 2 & 2.5
+               print_debug("\r\nStarting at CAS 2.5");
+               c = 0x20;          // assume CAS 2.5
+               if( b & 0x04){      // Should always happen
+                       if( smbus_read_byte(0xa0,23) <= 0x75){ // we can manage 133Mhz at CAS 2
+                               print_debug("\r\nWe can do CAS 2");
+                               c = 0x10;
+                       }
+               }
+       }
 
 
-       pci_write_config8(north,0x61,0xff);
 
+/*
+    DRAM Timing  Device 0  Offset 64
 
+    Row pre-charge  64[7]
+    RAS Pulse width 64[6]
+    CAS Latency     64[5,4]
 
-}
+         SDR  DDR
+      00  1T   -
+      01  2T   2T
+      10  3T   2.5T
+      11  -    3T
 
-/* slot is the dram slot. Return size of side0 in lower 16-bit,
- * side1 in upper 16-bit, in units of 8MB */
-static unsigned long 
-spd_module_size(unsigned char slot) 
-{ 
-       /* for all the DRAMS, see if they are there and get the size of each
-        * module. This is just a very early first cut at sizing.
-        */
-       /* we may run out of registers ... */
-       unsigned int banks, rows, cols, reg;
-       unsigned int value = 0;
-       unsigned int module = ((0x50 + slot) << 1) + 1;
-       /* is the module there? if byte 2 is not 4, then we'll assume it 
-        * is useless. 
-        */
-       print_info("Slot "); 
-       print_info_hex8(slot); 
-       if (smbus_read_byte(module, 2) != 4) {
-               print_info(" is empty\r\n");
-               return 0;
-       }
-       print_info(" is SDRAM ");
-       
-       banks = smbus_read_byte(module, 17);
-       /* we're going to assume symmetric banks. Sorry. */
-       cols = smbus_read_byte(module, 4)  & 0xf;
-       rows = smbus_read_byte(module, 3)  & 0xf;
-       /* grand total. You have rows+cols addressing, * times of banks, times
-        * width of data in bytes */
-       /* Width is assumed to be 64 bits == 8 bytes */
-       value = (1 << (cols + rows)) * banks * 8;
-       print_info_hex32(value);
-       print_info(" bytes ");
-       /* Return in 8MB units */
-       value >>= 23;
-
-       /* We should have single or double side */
-       if (smbus_read_byte(module, 5) == 2) {
-               print_info("x2");
-               value = (value << 16) | value;
-       }
-       print_info("\r\n");
-       return value;
+    RAS/CAS delay   64[2]
+    Bank Interleave 64[1,0]
 
-}
 
-static int
-spd_num_chips(unsigned char slot) 
-{ 
-       unsigned int module = ((0x50 + slot) << 1) + 1;
-       unsigned int width;
+    Determine row pre-charge time (tRP)
 
-       width = smbus_read_byte(module, 13);
-       if (width == 0)
-               width = 8;
-       return 64 / width;
-}
+    T    nS    SPD*4   SPD
+    1T   7.5   0x1e
+    2T   15    0x3c
+    3T   22.5  0x5a
+    4T   30            0x1e
+    5T   37.5          0x25 .5?
+    6T   45            0x2d
 
-static void sdram_set_spd_registers(const struct mem_controller *ctrl)
-{
-#define T133 7
-       unsigned char Trp = 1, Tras = 1, casl = 2, val;
-       unsigned char timing = 0xe4;
-       /* read Trp */
-       val = smbus_read_byte(0xa0, 27);
-       if (val < 2*T133)
-               Trp = 1;
-       val = smbus_read_byte(0xa0, 30);
-       if (val < 5*T133)
-               Tras = 0;
-       val = smbus_read_byte(0xa0, 18);
-       if (val < 8)
-               casl = 1;
-       if (val < 4)
-               casl = 0;
-       
-       val = (Trp << 7) | (Tras << 6) | (casl << 4) | 4;
-       
-       print_debug_hex8(val); print_debug(" is the computed timing\r\n");
-       /* don't set it. Experience shows that this screwy chipset should just
-        * be run with the most conservative timing.
-        * pci_write_config8(0, 0x64, val);
-        */
-}
 
-static void set_ma_mapping(device_t north, int slot, int type)
-{
-    unsigned char reg, val;
-    int shift;
-
-    reg = 0x58 + slot/2;
-    if (slot%2 >= 1)
-        shift = 0;
-    else
-        shift = 4;
-
-    val = pci_read_config8(north, reg);
-    val &= ~(0xf << shift);
-    val |= type << shift;
-    pci_write_config8(north, reg, val);
-}
+    Read SPD byte 27, min row pre-charge time.
+*/
 
+       b = smbus_read_byte(0xa0,27);
+       print_val("\r\ntRP ",b);
+       if( b > 0x3c )           // set tRP = 3T
+               c |= 0x80;
 
-static void sdram_enable(int controllers, const struct mem_controller *ctrl) 
-{
-       unsigned char i;
-       static const uint8_t ramregs[] = {
-               0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57
-       };
-       device_t north = 0;
-       uint32_t size, base, slot, ma;
-       
 
-       /* NOP command enable */
-       pci_write_config8(north,0x6b,0x01);
+/*
+    Determine RAS to CAS delay (tRCD)
+
+    Read SPD byte 29, min row pre-charge time.
+*/
+
+       b = smbus_read_byte(0xa0,29);
+       print_val("\r\ntRCD ",b);
+       if( b > 0x3c )           // set tRCD = 3T
+               c |= 0x04;
+
+/*
+    Determine RAS pulse width (tRAS)
+
+
+    Read SPD byte 30, device min active to pre-charge time.
+*/
+
+       b = smbus_read_byte(0xa0,30);
+       print_val("\r\ntRAS ",b);
+       if( b > 0x25 )           // set tRAS = 6T
+               c |= 0x40;
+
+
+/*
+    Determine bank interleave
+
+    Read SPD byte 17, Number of banks on SDRAM device.
+*/
+       b = smbus_read_byte(0xa0,17);
+       if( b == 4) c |= 0x02;
+       else if (b == 2) c |= 0x01;
+
+
+       /* set DRAM timing for all banks */
+       pci_write_config8(north,0x64,c);
+
+       /* set DRAM type to DDR */
+       pci_write_config8(north,0x60,0x02);
+
+
+       /* DRAM arbitration timer */
+       pci_write_config8(north,0x65,0x32);
+
+
+/*
+    CPU Frequency  Device 0 Offset 54
+
+    CPU Frequency          54[7,6]  bootstraps at 0xc0 (133Mhz)
+    DRAM burst length = 8  54[5]
+*/
+       pci_write_config8(north,0x54,0xe0);
+
 
-       /* read a double word from any addree of the dimm */
-       dimm_read(0x1f000);
+/*
+    DRAM Clock  Device 0 Offset 69
+
+    DRAM/CPU speed      69[7,6]  (leave at default 00 == CPU)
+    Controller que > 2  69[5]
+    Controller que != 4 69[4]
+    DRAM 8k page size   69[3]
+    DRAM 4k page size   69[2]
+    Multiple page mode  69[0]
+*/
+
+       pci_write_config8(north,0x69,0x2d);
+
+       /* Delay >= 100ns after DRAM Frequency adjust, See 4.1.1.3 pg 15 */
+       udelay(200);
+
+
+       /* Enable CKE */
+       pci_write_config8(north,0x6b,0x10);
        udelay(200);
 
-       /* All bank precharge Command Enable */
-       pci_write_config8(north,0x6b,0x02);
-       dimm_read(0x1f000);
+       /* Disable DRAM refresh */
+       pci_write_config8(north,0x6a,0x0);
+
+
+       /* Set drive for 1 bank DDR  (Table 4.4.2, pg 40) */
+       pci_write_config8(north,0x6d,0x044);
+       pci_write_config8(north,0x67,0x3a);
+
+       b = smbus_read_byte(0xa0,5); // SPD byte 5  # of physical banks
+       if( b > 1) {
+                // Increase drive control when there is more than 1 physical bank
+               pci_write_config8(north,0x6c,0x84);   // Drive control: MA, DQS, MD/CKE
+               pci_write_config8(north,0x6d,0x55);   // DC: Early clock select, DQM, CS#, MD
+       }
+       /* place frame buffer on last bank */
+       if( !b) b++;     // make sure at least 1 bank reported
+       pci_write_config8(north,0xe3,b-1);
+
+       for( bank = 0 , bank_address=0; bank < b ; bank++){
+/*
+    DDR init described in Via BIOS Porting Guide.  Pg 28 (4.2.3.1)
+*/
+
+
+               /* NOP command enable */
+               pci_write_config8(north,0x6b,0x11);
+
+               /* read a double word from any address of the dimm */
+               dimm_read(bank_address,0x1f000);
+               //udelay(200);
+
+               /* All bank precharge Command Enable */
+               pci_write_config8(north,0x6b,0x12);
+               dimm_read(bank_address,0x1f000);
+
+
+               /* MSR Enable */
+               pci_write_config8(north,0x6b,0x13);
+               dimm_read(bank_address,0x2000);
+               udelay(1);
+               dimm_read(bank_address,0x800);
+               udelay(1);
+
+               /* All banks precharge Command Enable */
+               pci_write_config8(north,0x6b,0x12);
+               dimm_read(bank_address,0x1f200);
+
+               /* CBR Cycle Enable */
+               pci_write_config8(north,0x6b,0x14);
+
+               /* Read 8 times */
+               dimm_read(bank_address,0x1f300);
+               udelay(100);
+               dimm_read(bank_address,0x1f400);
+               udelay(100);
+               dimm_read(bank_address,0x1f500);
+               udelay(100);
+               dimm_read(bank_address,0x1f600);
+               udelay(100);
+               dimm_read(bank_address,0x1f700);
+               udelay(100);
+               dimm_read(bank_address,0x1f800);
+               udelay(100);
+               dimm_read(bank_address,0x1f900);
+               udelay(100);
+               dimm_read(bank_address,0x1fa00);
+               udelay(100);
+
+               /* MSR Enable */
+               pci_write_config8(north,0x6b,0x13);
+
+/* 
+    Mode Register Definition
+    with adjustement so that address calculation is correct - 64 bit technology, therefore
+    a0-a2 refer to byte within a 64 bit long word, and a3 is the first address line presented
+    to DIMM as a row or column address.
+
+    MR[9-7]   CAS Latency
+    MR[6]     Burst Type 0 = sequential, 1 = interleaved
+    MR[5-3]   burst length 001 = 2, 010 = 4, 011 = 8, others reserved
+    MR[0-2]   dont care 
+
+    CAS Latency 
+    000       reserved
+    001       reserved
+    010       2
+    011       3
+    100       reserved
+    101       1.5
+    110       2.5
+    111       reserved
+
+    CAS 2     0101011000 = 0x158
+    CAS 2.5   1101011000 = 0x358
+    CAS 3     0111011000 = 0x1d8
+
+*/
+               c = pci_read_config8(north,0x64);
+               if( (c & 0x30) == 0x10 )
+                       dimm_read(bank_address,0x150);
+               else if((c & 0x30) == 0x20 )
+                       dimm_read(bank_address,0x350);
+               else
+                       dimm_read(bank_address,0x1d0);
+
+               //dimm_read(bank_address,0x350);
+
+               /* Normal SDRAM Mode */
+               pci_write_config8(north,0x6b,0x58 );
+
+
+               bank_address = pci_read_config8(north,0x5a+bank) * 0x1000000;
+       } // end of for each bank
+
+       /* Adjust DQS (data strobe output delay). See 4.2.3.2 pg 29 */
+       pci_write_config8(north,0x66,0x41);
+
+       /* determine low bond */
+       if( b == 2)
+               bank_address = pci_read_config8(north,0x5a) * 0x1000000;
+       else
+               bank_address = 0;
+
+       for(i = 0 ; i < 0x0ff; i++){
+               c = i ^ (i>>1);                 // convert to gray code
+               pci_write_config8(north,0x68,c);
+               // clear
+               *(volatile unsigned long*)(0x4000) = 0;
+               *(volatile unsigned long*)(0x4100+bank_address) = 0;
+               *(volatile unsigned long*)(0x4200) = 0;
+               *(volatile unsigned long*)(0x4300+bank_address) = 0;
+               *(volatile unsigned long*)(0x4400) = 0;
+               *(volatile unsigned long*)(0x4500+bank_address) = 0;
+
+
+               // fill
+               *(volatile unsigned long*)(0x4000) = 0x12345678;
+               *(volatile unsigned long*)(0x4100+bank_address) = 0x81234567;
+               *(volatile unsigned long*)(0x4200) = 0x78123456;
+               *(volatile unsigned long*)(0x4300+bank_address) = 0x67812345;
+               *(volatile unsigned long*)(0x4400) = 0x56781234;
+               *(volatile unsigned long*)(0x4500+bank_address) = 0x45678123;
+
+                       // verify
+               if( *(volatile unsigned long*)(0x4000) != 0x12345678)
+                       continue;
+
+               if( *(volatile unsigned long*)(0x4100+bank_address) != 0x81234567)
+                       continue;
+
+               if( *(volatile unsigned long*)(0x4200) != 0x78123456)
+                       continue;
+
+               if( *(volatile unsigned long*)(0x4300+bank_address) != 0x67812345)
+                       continue;
+
+               if( *(volatile unsigned long*)(0x4400) != 0x56781234)
+                       continue;
+
+               if( *(volatile unsigned long*)(0x4500+bank_address) != 0x45678123)
+                       continue;
+
+               // if everything verified then found low bond
+               break;
+               
+       }
+       print_val("\r\nLow Bond ",i);   
+       if( i < 0xff ){ 
+               c = i++;
+               for(  ; i <0xff ; i++){
+                       pci_write_config8(north,0x68,i ^ (i>>1) );
+
+                       // clear
+                       *(volatile unsigned long*)(0x8000) = 0;
+                       *(volatile unsigned long*)(0x8100+bank_address) = 0;
+                       *(volatile unsigned long*)(0x8200) = 0x0;
+                       *(volatile unsigned long*)(0x8300+bank_address) = 0;
+                       *(volatile unsigned long*)(0x8400) = 0x0;
+                       *(volatile unsigned long*)(0x8500+bank_address) = 0;
+
+                       // fill
+                       *(volatile unsigned long*)(0x8000) = 0x12345678;
+                       *(volatile unsigned long*)(0x8100+bank_address) = 0x81234567;
+                       *(volatile unsigned long*)(0x8200) = 0x78123456;
+                       *(volatile unsigned long*)(0x8300+bank_address) = 0x67812345;
+                       *(volatile unsigned long*)(0x8400) = 0x56781234;
+                       *(volatile unsigned long*)(0x8500+bank_address) = 0x45678123;
+
+                       // verify
+                       if( *(volatile unsigned long*)(0x8000) != 0x12345678)
+                               break;
+
+                       if( *(volatile unsigned long*)(0x8100+bank_address) != 0x81234567)
+                               break;
+
+                       if( *(volatile unsigned long*)(0x8200) != 0x78123456)
+                               break;
+
+                       if( *(volatile unsigned long*)(0x8300+bank_address) != 0x67812345)
+                               break;
+
+                       if( *(volatile unsigned long*)(0x8400) != 0x56781234)
+                               break;
+
+                       if( *(volatile unsigned long*)(0x8500+bank_address) != 0x45678123)
+                               break;
+
+               }
+               print_val("  High Bond",i);
+               c = ((i - c)<<1)/3 +c;
+               print_val("  Setting DQS delay",c);
+               c = c ^ (c>>1);         // convert to gray code
+               pci_write_config8(north,0x68,c);
+               pci_write_config8(north,0x68,0x42);
+       }else{
+               print_debug("Unable to determine low bond - Setting default\r\n");
+               pci_write_config8(north,0x68,0x59);
+       }
 
-       /* MSR Enable */
-       pci_write_config8(north,0x6b,0x03);
-       dimm_read(0x2000);
 
-       dimm_read(0x800);
+       pci_write_config8(north,0x66,0x01);
+       pci_write_config8(north,0x55,0x07);
 
-       /* All banks precharge Command Enable */
-       pci_write_config8(north,0x6b,0x02);
-       dimm_read(0x1f200);
 
-       /* CBR Cycle Enable */
-       pci_write_config8(north,0x6b,0x04);
 
-       /* Read 8 times */
-       dimm_read(0x1f300);
-       udelay(100);
-       dimm_read(0x1f400);
-       udelay(100);
-       dimm_read(0x1f500);
-       udelay(100);
-       dimm_read(0x1f600);
-       udelay(100);
-       dimm_read(0x1f700);
-       udelay(100);
-       dimm_read(0x1f800);
-       udelay(100);
-       dimm_read(0x1f900);
-       udelay(100);
-       dimm_read(0x1fa00);
-       udelay(100);
+/*
+    DRAM refresh rate  Device 0 Offset 6a
 
-       /* MSR Enable */
-       pci_write_config8(north,0x6b,0x03);
+    Units of 16 DRAM clock cycles.  (See 4.4.1 pg 39)
 
-       /* 0x150 if CAS Latency 2 or 0x350 CAS Latency 2.5 */
-       dimm_read(0x350);
+    Rx69 (DRAM freq)  Rx58 (chip tech)  Rx6a
 
-       /* Normal SDRAM Mode */
-       pci_write_config8(north,0x6b,0x58 );
+    133Mhz            64/128Mb          0x86
+    133Mhz            256/512Mb         0x43
+    100Mhz            64/128Mb          0x65
+    100Mhz            256/512Mb         0x32
+*/
 
+       b = pci_read_config8(north,0x58);
+       if( b < 0x80 )   // 256 tech
+               pci_write_config8(north,0x6a,0x86);
+       else
+               pci_write_config8(north,0x6a,0x43);
 
-       /* Set the refresh rate */
-       pci_write_config8(north,0x6a,0x43);
-       pci_write_config8(north,0x67,0x22);
+       pci_write_config8(north,0x61,0xff);
+       //pci_write_config8(north,0x67,0x22);
 
        /* pci */
        pci_write_config8(north,0x70,0x82);
@@ -351,14 +591,18 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
        
 
        /* graphics aperture base */
+
        pci_write_config8(north,0x13,0xd0);
 
-       //pci_write_config8(north,0x56,0x10);
-       //pci_write_config8(north,0x57,0x10);
+       //pci_write_config8(north,0xe1,0xdf);
+       //pci_write_config8(north,0xe2,0x42);
+       pci_write_config8(north,0xe0,0x00);
+
+       pci_write_config8(north,0x84,0x80);
+       pci_write_config16(north,0x80,0x610f);
+       pci_write_config32(north,0x88,0x00000002);
+
 
-       pci_write_config8(north,0xe0,0x80);
-       pci_write_config8(north,0xe1,0xdf);
-       pci_write_config8(north,0xe2,0x42);
 
        pci_write_config8(north,0xa8,0x04);
        pci_write_config8(north,0xac,0x2f);
@@ -366,4 +610,18 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
 
         print_err("vt8623 done\r\n");
        dumpnorth(north);
+
+       print_err("AGP\r\n");
+       north = pci_locate_device(PCI_ID(0x1106, 0xb091), 0);
+       pci_write_config32(north,0x20,0xddf0dc00);
+       pci_write_config32(north,0x24,0xdbf0d800);
+       pci_write_config8(north,0x3e,0x0c);
+       //dumpnorth(north);
+
+       //print_err("VGA\n");
+       //north = pci_locate_device(PCI_ID(0x1106, 0x3122), 0);
+       //pci_write_config32(north,0x10,0xd8000008);
+       //pci_write_config32(north,0x14,0xdc000000);
+       //dumpnorth(north);
+
 }
index 5d7a2e3ab64f545b4cc09a263b4ea8076a1a3dde..c4cd9d7997bc3d905ea5c40d9859f6c633148f3d 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef _SOUTHBRIDGE_RICOH_RL5C476
 #define _SOUTHBRIDGE_RICOH_RL5C476
 
-extern struct chip_operations southbridge_ricoh_rl5c476_control;
+extern struct chip_operations southbridge_ricoh_rl5c476_ops;
 
 struct southbridge_ricoh_rl5c476_config {
-       int num;
+       int enable_cf;
+       
 };
 
 #endif /* _SOUTHBRIDGE_RL5C476 */
index ede34b61f59f3250558011bb69e6f9ab679d9def..8495c3f94168400b7844acefc0bb4af881462653 100644 (file)
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
-
+/* (C) Copyright 2005 Nick Barker <nick.barker@btinternet.com
+   brought into line with the current architecture of LinuxBios */ 
 
 
 #include <arch/io.h>
 #include <device/pci_ops.h>
 #include <device/pci_ids.h>
 #include <console/console.h>
+#include <device/cardbus.h>
 #include "rl5c476.h"
 #include "chip.h"
 
+static int enable_cf_boot = 0;
+static unsigned int cf_base;
+
 static void udelay(int i){
        for(; i > 0 ; i--)
                inb(0x80);
 
 }
 
-static void
-dump_south(void)
-{
-       device_t dev0;
-       dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
-       dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev0);
-       int i,j;
-       
-       for(i = 0; i < 256; i += 16) {
-               printk_debug("0x%x: ", i);
-               for(j = 0; j < 16; j++) {
-                       printk_debug("%02x ", pci_read_config8(dev0, i+j));
-               }
-               printk_debug("\n");
-       }
-       printk_debug("Card32\n");
-       for(i = 0 ; i < 256 ; i+=16){
-               printk_debug("0x%x: ",i);
-               for(j = 0 ; j < 16 ; j++){
-                       printk_debug(" %02x",*(unsigned char *)(0x80000000+i+j));
-               }
-               printk_debug("\n");
-       }
-       printk_debug("Card16\n");
-       for(i = 0; i < 256; i += 16) {
-               printk_debug("0x%x: ", i);
-               for(j = 0; j < 16; j++) {
-                       printk_debug("%02x ", *(unsigned char *)(0x80000800+ i+j));
-               }
-               printk_debug("\n");
-       }
-       printk_debug("CF Config\n");
-       for(i = 0 ; i < 256 ; i+=16){
-               printk_debug("0x%x: ",i);
-               for(j=0 ; j < 16 ; j++){
-                       printk_debug("%02x ",*(unsigned char *)(0x81000200 + i + j));
-               }
-               printk_debug("\n");
-       }
-}
-
-
 static void rl5c476_init(device_t dev)
 {
        //unsigned char enables;
        pc16reg_t *pc16;
-       int i;
 
-#error "FIXME implement carbus bridge support"
-#error "FIXME this code is close to a but the conversion needs more work"
+       unsigned char *base;
+
        /* cardbus controller function 1 for CF Socket */
        printk_debug("rl5c476 init\n");
 
-       /* setup pci header manually because 'pci_device.c' doesn't know how to handle
-         * pci to cardbus bridges - (header type 2 I think)
-        */
+       printk_debug("CF Base = %0x\n",cf_base);
 
+       /* misc control register */
+       pci_write_config16(dev,0x82,0x00a0);
 
-       /* initialize function zero - pcmcia socket so it behaves itself */
-       /* FIXME - statically put control memory at 0xe0000000 for now
-        * one day the pci_device allocator might do this */
-       pci_write_config32(dev,0x10,0xe0000000);
-       pci_write_config8(dev,0x0d,0x20);
-       pci_write_config8(dev,0x19,0x02);
-       pci_write_config8(dev,0x1a,0x02);
-       pci_write_config8(dev,0x1b,0x20);
-       //pci_write_config8(dev,0x3c,0);
-       pci_write_config8(dev,0x82,0x00a0);
-       pci_write_config16(dev,0x04,0x07);
+       /* set up second slot as compact flash port if asked to do so */
+       if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){ 
 
-       
-       /* get second function - i.e. compact flash socket */
-       dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev);
+               /* make sure isa interrupts are enabled */
+               pci_write_config16(dev,0x3e,0x0780);
 
+               /* pick up where 16 bit card control structure is (0x800 bytes into config structure) */
+               base = (unsigned char *)pci_read_config32(dev,0x10);
+               pc16 = (pc16reg_t *)(base + 0x800);
 
-       /* FIXME - control structure statically declared at 0xe0008000 for now */
-       pci_write_config32(dev,0x10,0xe0008000);
-       pci_write_config8(dev,0x0d,0x20);
-       pci_write_config8(dev,0x19,0x03);
-       pci_write_config8(dev,0x1a,0x03);
-       pci_write_config8(dev,0x1b,0x20);
+               /* disable memory and io windows and turn off socket power */
+               pc16->pwctrl = 0;
 
-       //pci_write_config8(dev,0x3c,0x0);
-       pci_write_config16(dev,0x3e,0x0780);
-       pci_write_config16(dev,0x82,0x00a0);
+               /* disable irq lines */
+               pc16->igctrl = 0;
 
-       pci_write_config16(dev,0x04,0x07);
+               /* disable memory and I/O windows */
+               pc16->awinen = 0;
 
+               /* reset card, configure for I/O and set IRQ line */
+               pc16->igctrl = 0x69;
 
-       /* pick up where 16 bit card control structure is */
-       pc16 = (pc16reg_t *)(0xe0008800);
+               // set io window 0 for 1e0 - 1ef
+               /* note this now sets CF up on a contiguous I/O window of 16 bytes, 0x1e0 to 0x1ef
+                   Be warned that this is not a standard IDE address as automatically detected by the likes
+                   of Filo, and would need patching to recognise these addresses as an IDE drive */
+               /* an earlier version of this driver set up 2 io windows to emulate the expected addresses
+                   for IDE2, however the pcmcia package within Linux then could not re-initiailse the
+                   device as it tried to take control of it. So I belive it is easier to patch Filo or the like
+                   to pick up this drive rather than playing silly games as the kernel tries to boot.
+               */
+               pc16->iostl0 = 0xe0;
+               pc16->iosth0 = 1;
 
-       /* disable memory and io windows and turn off socket power */
-       pc16->pwctrl = 0;
+               pc16->iospl0 = 0xef;
+               pc16->iosph0 = 1;
 
-       /* disable irq lines */
-       pc16->igctrl = 0;
+               pc16->ioffl0 = 0;
+               pc16->ioffh0 = 0;
 
-       /* disable memory and I/O windows */
-       pc16->awinen = 0;
+               // clear window 1
+               pc16->iostl1 = 0;
+               pc16->iosth1 = 0;
 
-       /* reset card, configure for I/O and set IRQ line */
-       pc16->igctrl = 0x69;
+               pc16->iospl1 = 0;
+               pc16->iosph1 = 0;
 
+               pc16->ioffl1 = 0x0;
+               pc16->ioffh1 = 0;
 
-       // set io window 0 for 1e8 - 1ef
-       pc16->iostl0 = 0xe8;
-       pc16->iosth0 = 1;
 
-       pc16->iospl0 = 0xef;
-       pc16->iosph0 = 1;
 
-       // add io offset of 8 so that CF card will decode 0x1e8 as 0x1f0 i.e. the first byte of
-       // a 16 byte aligned, 16 byte window etc
-       pc16->ioffl0 = 0x8;
-       pc16->ioffh0 = 0;
+               // set up CF config window
+               pc16->smpga0 = cf_base>>24;
+               pc16->smsth0 = (cf_base>>20)&0x0f;
+               pc16->smstl0 = (cf_base>>12)&0xff;
+               pc16->smsph0 = ((cf_base>>20)&0x0f) | 0x80;
+               pc16->smspl0 = (cf_base>>12)&0xff;
+               pc16->moffl0 = 0;
+               pc16->moffh0 = 0x40;
 
-       // set io window 1 for 3ed - 3ee
-       pc16->iostl1 = 0xed;
-       pc16->iosth1 = 3;
 
-       pc16->iospl1 = 0xee;
-       pc16->iosph1 = 3;
+               // set I/O width for Auto Data width
+               pc16->ioctrl = 0x22;
 
-       pc16->ioffl1 = 0x0;
-       pc16->ioffh1 = 0;
 
+               // enable I/O window 0 and 1
+               pc16->awinen = 0xc1;
 
-       // FIXME statically declare CF config window at 0xe1000000
-       pc16->smstl0 = 0;
-       pc16->smsth0 = 0;
-       pc16->smspl0 = 0;
-       pc16->smsph0 = 0x80;
-       pc16->moffl0 = 0;
-       pc16->moffh0 = 0x40;
-       pc16->smpga0 = 0xe1;
 
-       // set I/O width for Auto Data width
-       pc16->ioctrl = 0x22;
+               pc16->miscc1 = 1;
 
+               // apply power and enable outputs
+               pc16->pwctrl = 0xb0;
+       
 
-       // enable I/O window 0 and 1
-       pc16->awinen = 0xc1;
+               // delay could be optimised, but this works
+               udelay(100000);
+       
+               pc16->igctrl = 0x69;
 
 
-       pc16->miscc1 = 1;
+               // 16 bit CF always have first config byte at 0x200 into Config structure,
+               // but CF+ May Not according to spec - should locate through reading tuple data,
+               // but this will do for now !!!
+               unsigned char *cptr;
+               cptr = (unsigned char *)(cf_base + 0x200);
+               printk_debug("CF Config = %x\n",*cptr);
 
-       // apply power and enable outputs
-       pc16->pwctrl = 0xb0;
-       
+               // set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
+               // windows of the bridge set up above to map those bytes into the 
+               // addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
+               *cptr = 0x41;
+       }
 
-       // delay could be optimised, but this works
-       udelay(100000);
-       
-       pc16->igctrl = 0x69;
+}
 
-       unsigned char *cptr;
-       cptr = (unsigned char *)(0xe1000200);
-       printk_debug("CF Config = %x\n",*cptr);
+void rl5c476_read_resources(device_t dev)
+{
 
-       // FIX Me 16 bit CF always have first config byte at 0x200 into Config structure,
-        // but CF+ May Not according to spec - should locate through reading tuple data,
-        // but this will do for now !!!
+       struct resource *resource;
 
+        /* for cf socket we need an extra memory window for the control structure of the cf itself */
+       if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){ 
+               resource = new_resource(dev,1);    /* fake index as it isn't in pci config space */
+               resource->flags |= IORESOURCE_MEM ;
+               resource->size = 0x1000;
+               resource->align = resource->gran = 12;
+               resource->limit= 0xffff0000;
+               //compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
+       }
+       cardbus_read_resources(dev);
 
-       // set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
-       // windows of the bridge set up above to map those bytes into the 
-       // addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
-       *cptr = 0x41;
+}
 
+void rl5c476_set_resources(device_t dev)
+{
+
+       struct resource *resource;
+       printk_debug("%s In set resources \n",dev_path(dev));
+       if( enable_cf_boot && (PCI_FUNC(dev->path.u.pci.devfn) == 1)){
+               resource = find_resource(dev,1);
+               if( !(resource->flags & IORESOURCE_STORED) ){
+                       resource->flags |= IORESOURCE_STORED ;
+                       compute_allocate_resource(&dev->link[0],resource,resource->flags,resource->flags);
+                       printk_debug("%s 1 ==> %x\n",dev_path(dev),resource->base); 
+                       cf_base = resource->base;
+               }
+       }
+
+       pci_dev_set_resources(dev);
 
 }
 
 static struct device_operations ricoh_rl5c476_ops = {
-       .read_resources   = pci_bus_read_resources,
-       .set_resources    = pci_dev_set_resources,
-       .enable_resources = pci_bus_enable_resources,
-       .inti             = rl5c476_init,
-       .scan_bus         = pci_scan_bridge,
+       .read_resources   = rl5c476_read_resources,
+       .set_resources    = rl5c476_set_resources,
+       .enable_resources = cardbus_enable_resources,
+       .init             = rl5c476_init,
+       .scan_bus         = cardbus_scan_bridge,
 };
 
 static struct pci_driver ricoh_rl5c476_driver __pci_driver = {
@@ -222,7 +203,15 @@ static struct pci_driver ricoh_rl5c476_driver __pci_driver = {
        .device = PCI_DEVICE_ID_RICOH_RL5C476,
 };
 
-struct chip_operations southbridge_ricoh_rl5c476_control = {
+void southbridge_init(device_t dev)
+{
+
+       struct southbridge_ricoh_rl5c476_config *conf = dev->chip_info;
+       enable_cf_boot = conf->enable_cf;
+
+}
+
+struct chip_operations southbridge_ricoh_rl5c476_ops = {
        CHIP_NAME("RICOH RL5C476")
-       .enable    = southbridge_init,
+       .enable_dev    = southbridge_init,
 };
index 0ded3d5aa902d3b78039a5a37429782620185e34..c2da0de17fed2583b2082fa019e8a9fa1b7fb8d5 100644 (file)
@@ -14,8 +14,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* rl5c476 routines and defines*/
index ea649a418ce695c2cae7977915b56a01fb6c4058..e6287ece9cea38c22ebfd1f0b67e96c4a3837a48 100644 (file)
@@ -10,7 +10,7 @@
 /*
  * Base VT8235.
  */
-static device_t lpc_dev;
+static int enabled = 0;
 
 void hard_reset(void) 
 {
@@ -22,18 +22,15 @@ static void keyboard_on(struct device *dev)
        unsigned char regval;
 
        regval = pci_read_config8(dev, 0x51);
-//     regval |= 0x0f; 
-       /* !!!FIX let's try this */
-       regval |= 0x1d; 
+       regval |= 0x05; 
+       regval &= 0xfd;
        pci_write_config8(dev, 0x51, regval);
 
        init_pc_keyboard(0x60, 0x64, 0);
 }
 
-void dump_south(void)
+void dump_south(device_t dev0)
 {
-       device_t dev0;
-       dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
        int i,j;
        
        for(i = 0; i < 256; i += 16) {
@@ -45,23 +42,53 @@ void dump_south(void)
        }
 }
 
-void set_led(struct device *dev)
+void set_led()
 {
        // set power led to steady now that lxbios has virtually done its job
+       device_t dev;
+       dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
        pci_write_config8(dev, 0x94, 0xb0);
 }
 
+
 static void vt8235_enable(struct device *dev)
 {
        struct southbridge_via_vt8235_config *conf = dev->chip_info;
+       unsigned char regval;
+       unsigned short vendor,model;
+
+
+       vendor = pci_read_config16(dev,0);
+       model = pci_read_config16(dev,0x2);
+
+       printk_debug("In vt8235_enable %04x %04x.\n",vendor,model);
+       
+       /* if this is not the southbridge itself just return */
+       /* this is necessary because USB devices are slot 10, whereas this device is slot 11 
+         therefore usb devices get called first during the bus scan */
+
+       if( (vendor != PCI_VENDOR_ID_VIA) || (model != PCI_DEVICE_ID_VIA_8235))
+               return;
+
+       printk_debug("Initialising Devices\n");
+
+
+       setup_i8259();   // make sure interupt controller is configured before keyboard init 
+
+       /* enable RTC and ethernet */
+       regval = pci_read_config8(dev, 0x51);
+       regval |= 0x18; 
+       pci_write_config8(dev, 0x51, regval);
+
+       /* turn on keyboard */
+       keyboard_on(dev);
+
+       /* enable USB 1.1 & USB 2.0 -redundant really since we've already been there - see note above*/
+       regval = pci_read_config8(dev, 0x50);
+       regval &= ~(0x36);
+       pci_write_config8(dev, 0x50, regval);
+
 
-       printk_debug("In vt8235_enable.\n");
-       if (!lpc_dev) {
-               lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
-                               PCI_DEVICE_ID_VIA_8235, 0);
-               if (conf->enable_keyboard)
-                       keyboard_on(lpc_dev);
-       }
 }
 
 struct chip_operations southbridge_via_vt8235_ops = {
index c8e79fc4803a95be793cff259188a41adf1d078f..f07137193894e8f913696b5dcd8f54b9c4c33be1 100644 (file)
@@ -17,8 +17,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* winbond access routines and defines*/
index 1775203ca88b08157a0b51460de75180d74d6028..fedda9c3be08e6c07da9f3d3fe828f5685b39dcc 100644 (file)
@@ -13,7 +13,7 @@ static void ide_init(struct device *dev)
 
        printk_info("Enabling VIA IDE.\n");
 
-       if (!conf->enable_native_ide) {
+       /*if (!conf->enable_native_ide) { */
                /*
                 * Run the IDE controller in 'compatiblity mode - i.e. don't
                 * use PCI interrupts.  Using PCI ints confuses linux for some
@@ -28,7 +28,7 @@ static void ide_init(struct device *dev)
                enables = pci_read_config8(dev, 0x42);
                printk_debug("enables in reg 0x42 read back as 0x%x\n",
                                enables);
-       }
+       /* } */
        
        enables = pci_read_config8(dev, 0x40);
        printk_debug("enables in reg 0x40 0x%x\n", enables);
index 4a3c683f610b9e77ebd4cef8a561629497dbfff6..3e220940cdba8113ff3444cf793fad6de07c14ce 100644 (file)
 #include "vt8235.h"
 #include "chip.h"
 
-/*
- * Taken some liberties - changed irq structures to pins numbers so that it is
- * easier to change PCI irq assignments without having to change each PCI
- * function individually
- * 
- * pciIrqs contains the irqs assigned for PCI pins A-D
- * 
- * Setting will depend on motherboard as irqs can be quite scarce e.g on
- * EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia
- * socket may want another - for now only claim 3 interupts for PCI, leaving at
- * least one spare for CF.  On EPIA-M one could allocated all four irqs to
- * different numbers since there are no cardbus devices
- */
-
-static const unsigned char pciIrqs[4] = { 11 , 5, 10 , 12 };
+/* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
+   This is how the Award bios sets it up too.
+   epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
+   make sure that ACPI dsdt is changed to suit.
+
+       IRQ 0 = timer
+       IRQ 1 = keyboard
+       IRQ 2 = cascade
+       IRQ 3 = COM 2
+       IRQ 4 = COM 1
+       IRQ 5 = available for PCI interrupts
+       IRQ 6 = floppy or availbale for PCI if floppy controller disabled
+        IRQ 7 = LPT or available if LPT port disabled
+       IRQ 8 = rtc
+       IRQ 9 = available for PCI interrupts
+       IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
+       IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
+       IRQ 12 = PS2 mouse (hardwired to 12)
+       IRQ 13 = legacy FPU interrupt
+       IRQ 14 = IDE controller 1
+       IRQ 15 = IDE controller 2
+
+*/
+static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
 
 static const unsigned char usbPins[4] =      { 'A','B','C','D'};
 static const unsigned char enetPins[4] =     { 'A','B','C','D'};
@@ -32,14 +41,9 @@ static const unsigned char slotPins[4] =     { 'B','C','D','A'};
 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
 static const unsigned char vt8235Pins[4] =   { 'A','B','C','D'};
 static const unsigned char vgaPins[4] =      { 'A','B','C','D'};
-static const unsigned char cbPins[4] =       { 'A','B','C','D'};
+static const unsigned char cbPins[4] =       { 'D','A','B','C'};
 static const unsigned char riserPins[4] =    { 'A','B','C','D'};
 
-/*
-       Our IDSEL mappings are as follows
-       PCI slot is AD31          (device 15) (00:14.0)
-       Southbridge is AD28       (device 12) (00:11.0)
-*/
 
 static unsigned char *pin_to_irq(const unsigned char *pin)
 {
@@ -54,19 +58,12 @@ static unsigned char *pin_to_irq(const unsigned char *pin)
 static void pci_routing_fixup(struct device *dev)
 {
        printk_info("%s: dev is %p\n", __FUNCTION__, dev);
-       if (dev) {
-               /* initialize PCI interupts - these assignments depend
-                  on the PCB routing of PINTA-D 
-
-                  PINTA = IRQ11
-                  PINTB = IRQ5
-                  PINTC = IRQ10
-                  PINTD = IRQ12
-               */
-               pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
-               pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
-               pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
-       }
+
+       /* set up PCI IRQ routing */
+       pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+       pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+       pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
 
        // firewire built into southbridge
        printk_info("setting firewire\n");
@@ -201,12 +198,6 @@ static void vt8235_init(struct device *dev)
        // Set 0x58 to 0x03 to match Award
        pci_write_config8(dev, 0x58, 0x03);
        
-       // enable the ethernet/RTC
-       if (dev) {
-               enables = pci_read_config8(dev, 0x51);
-               enables |= 0x18; 
-               pci_write_config8(dev, 0x51, enables);
-       }
        
        /* enable serial irq */
        pci_write_config8(dev, 0x52, 0x9);
@@ -224,6 +215,36 @@ static void vt8235_init(struct device *dev)
        rtc_init(0);
 }
 
+/* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
+   device has a resource to set - so set a dummy one */
+void vt8235_read_resources(device_t dev)
+{
+
+       struct resource *resource;
+       pci_dev_read_resources(dev);
+       resource = new_resource(dev, 1);
+       resource->flags |= IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | IORESOURCE_STORED;
+       resource->size = 2;
+       resource->base = 0x2e;
+
+}
+void vt8235_set_resources(device_t dev)
+{
+       struct resource *resource;
+       //resource = find_resource(dev,1);
+       //resource->flags |= IORESOURCE_STORED;
+       pci_dev_set_resources(dev);
+}
+
+void vt8235_enable_resources(device_t dev)
+{
+       /* vt8235 is not a pci bridge and has no resources of its own (other than standard PC i/o addresses)
+           however it does control the isa bus and so we need to manually call enable childrens resources on that bus */
+       pci_dev_enable_resources(dev);
+       enable_childrens_resources(dev);
+
+}
+       
 static void southbridge_init(struct device *dev)
 {
        vt8235_init(dev);
@@ -231,9 +252,9 @@ static void southbridge_init(struct device *dev)
 }
 
 static struct device_operations vt8235_lpc_ops = {
-       .read_resources   = pci_dev_read_resources,
-       .set_resources    = pci_dev_set_resources,
-       .enable_resources = pci_dev_enable_resources,
+       .read_resources   = vt8235_read_resources,
+       .set_resources    = vt8235_set_resources,
+       .enable_resources = vt8235_enable_resources,
        .init             = &southbridge_init,
        .scan_bus         = scan_static_bus,
 };
index 24c6a17acb5fcf5cc622b7a745d98da2b1c040ff..8142c535daaa25e36a09f8038948e7ee3964b369 100644 (file)
@@ -5,11 +5,14 @@
 #include <device/pci_ids.h>
 #include "vt8235.h"
 
+/* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated
+   properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */
+
 static void usb_init(struct device *dev)
 {
        printk_debug("Configuring VIA USB 1.1\n");
 
-       pci_write_config8(dev, 0x04, 0x07);
+       /* pci_write_config8(dev, 0x04, 0x07); */
 
        /*
         * To disable; though do we need to do this?
@@ -25,6 +28,7 @@ static void usb_init(struct device *dev)
         */
 }
 
+/*
 static struct device_operations usb_ops = {
        .read_resources   = pci_dev_read_resources,
        .set_resources    = pci_dev_set_resources,
@@ -39,3 +43,4 @@ static struct pci_driver northbridge_driver __pci_driver = {
        .vendor = PCI_VENDOR_ID_VIA,
        .device = PCI_DEVICE_ID_VIA_82C586_2,
 };
+*/
\ No newline at end of file
index 30d9592e5c99eb5e189594ef382e4287e11b13b5..47a1ba48bb20fa416e100f71ffa15d050eed5dc6 100644 (file)
@@ -14,8 +14,8 @@
  *
  * 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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
  */
 
  /* vt1211 routines and defines*/
@@ -58,6 +58,25 @@ static void pnp_exit_ext_func_mode(device_t dev)
        outb(0xaa, dev->path.u.pnp.port);
 }
 
+static void vt1211_set_iobase(device_t dev, unsigned index, unsigned iobase)
+{
+
+       switch (dev->path.u.pnp.device) {
+               case VT1211_FDC:
+               case VT1211_PP:
+               case VT1211_SP1:
+               case VT1211_SP2:
+                       pnp_write_config(dev, index + 0, (iobase >> 2) & 0xff);
+                       break;
+               case VT1211_HWM:
+               default:
+                       pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
+                       pnp_write_config(dev, index + 1, iobase & 0xff);
+                       break;
+       }
+       
+}
+
 static void init_hwm(unsigned long base)
 {
        int i;
@@ -79,6 +98,9 @@ static void vt1211_init(struct device *dev)
        }
 
        switch (dev->path.u.pnp.device) {
+       case VT1211_FDC:
+       case VT1211_PP:
+               break;
        case VT1211_SP1:
                res0 = find_resource(dev, PNP_IDX_IO0);
                init_uart8250(res0->base, &conf->com1);
@@ -95,24 +117,12 @@ static void vt1211_init(struct device *dev)
                printk_info("vt1211 asked to initialise unknown device!\n");
        }
        
-       /* activate com2
-       start_conf_pnp(3);
-       write_pnp(0x60,0xbe);
-       write_pnp(0x70,0x3);
-       write_pnp(0xf0,0x02);
-       write_pnp(0x30,0x01);
-       end_conf_pnp();
-
-       // Activate the vt1211 hardware monitor
-       start_conf_pnp(0x0b);
-       write_pnp(0x60,0xec); 
-       write_pnp(0x30,1);
-       end_conf_pnp(); */
 
 }
 
 void vt1211_pnp_enable_resources(device_t dev)
 {
+       printk_debug("%s - enabling\n",dev_path(dev));
        pnp_enter_ext_func_mode(dev);
        pnp_enable_resources(dev);
        pnp_exit_ext_func_mode(dev);
@@ -120,8 +130,54 @@ void vt1211_pnp_enable_resources(device_t dev)
 
 void vt1211_pnp_set_resources(struct device *dev)
 {
+       int i;
+       struct resource *resource;
+
+#if CONFIG_CONSOLE_SERIAL8250 == 1
+       if( dev->path.u.pnp.device == 2 ){
+               for( i = 0 ; i < dev->resources; i++){
+                       resource = &dev->resource[i];
+                       resource->flags |= IORESOURCE_STORED;
+                       report_resource_stored(dev, resource, "");      
+               }
+               return;
+       }
+#endif
        pnp_enter_ext_func_mode(dev);
-       pnp_set_resources(dev);
+       /* Select the device */
+       pnp_set_logical_device(dev);
+
+       /* Paranoia says I should disable the device here... */
+       for(i = 0; i < dev->resources; i++) {
+               resource = &dev->resource[i];
+               if (!(resource->flags & IORESOURCE_ASSIGNED)) {
+                       printk_err("ERROR: %s %02x %s size: 0x%010Lx not assigned\n",
+                               dev_path(dev), dev->resource->index,
+                               resource_type(resource),
+                               resource->size);
+                       continue;
+               }
+
+               /* Now store the resource */
+               if (resource->flags & IORESOURCE_IO) {
+                       vt1211_set_iobase(dev, resource->index, resource->base);
+               }
+               else if (resource->flags & IORESOURCE_DRQ) {
+                       pnp_set_drq(dev, resource->index, resource->base);
+               }
+               else if (resource->flags  & IORESOURCE_IRQ) {
+                       pnp_set_irq(dev, resource->index, resource->base);
+               }
+               else {
+                       printk_err("ERROR: %s %02x unknown resource type\n",
+                               dev_path(dev), resource->index);
+                       return;
+               }
+               resource->flags |= IORESOURCE_STORED;
+
+               report_resource_stored(dev, resource, "");      
+       }
+
        pnp_exit_ext_func_mode(dev);
 }
 
@@ -148,7 +204,7 @@ static struct pnp_info pnp_dev_info[] = {
        { &ops, VT1211_PP,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
        { &ops, VT1211_SP1, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
        { &ops, VT1211_SP2, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
-       { &ops, VT1211_HWM, PNP_IO0 , { 0xfff8, 0 }, },
+       { &ops, VT1211_HWM, PNP_IO0 , { 0xff00, 0 }, },
 };
 
 static void enable_dev(struct device *dev)
index baf066eb544dc3080c192986cd8609973962da5a..1d204819e4475200e478dd23cf18372eedd51ffd 100644 (file)
@@ -18,7 +18,7 @@ option HAVE_FALLBACK_BOOT=1
 ### Compute the location and size of where this firmware image
 ### (linuxBIOS plus bootloader) will live in the boot rom chip.
 ###
-option FALLBACK_SIZE=131072
+option FALLBACK_SIZE=0x30000
 
 ## LinuxBIOS C code runs at this location in RAM
 option _RAMBASE=0x00004000
@@ -30,26 +30,32 @@ option _RAMBASE=0x00004000
 ###
 
 #
-# Via EPIA-M
+# EPIA-M
 #
-romimage "normal"
-       option USE_FALLBACK_IMAGE=0
-       option ROM_IMAGE_SIZE=0x10000
-       option LINUXBIOS_EXTRA_VERSION=".0Normal"
+#romimage "normal"
+#      option USE_FALLBACK_IMAGE=0
+#      option ROM_IMAGE_SIZE=0xc000
+#      option ROM_SECTION_OFFSET=0x10000
+#      option ROM_SECTION_SIZE=0x18000
+#      option XIP_ROM_BASE=0xfffd0000
+#      option LINUXBIOS_EXTRA_VERSION=".0Normal"
 #      payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
 #      payload ../../../../tg3--ide_disk.zelf  
 #      payload ../../../../../lnxieepro100.ebi
-       payload ../../../payloads/filo.elf
-end
+#      payload /filo.elf
+#end
 
 romimage "fallback" 
        option USE_FALLBACK_IMAGE=1
        option ROM_IMAGE_SIZE=0x10000
+       option ROM_SECTION_OFFSET=0x10000
+       option ROM_SECTION_SIZE=0x30000
+#      option XIP_ROM_BASE=0xfffe0000
        option LINUXBIOS_EXTRA_VERSION=".0Fallback"
 #      payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
 #      payload ../../../../tg3--ide_disk.zelf  
 #      payload ../../../../../lnxieepro100.ebi
-       payload ../../../payloads/filo.elf
+       payload /filo.elf
 end
 
-buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"
+buildrom ./linuxbios.rom ROM_SIZE  "fallback"