direct-io.hg

changeset 1104:8870c27357dd

bitkeeper revision 1.737 (403a06aeivKFHIf1N0Wp-yJEFUDIrw)

serial.h:
new file
Many files:
Rewritten serial and console I/O for Xen. New command-line options (see the docs). ser_baud is deprecated.
Xeno-HOWTO.txt:
Rename: docs/Xeno-1.2-HOWTO.txt -> docs/Xeno-HOWTO.txt
serial.c:
Rename: xen/drivers/char/xen_serial.c -> xen/drivers/char/serial.c
author kaf24@scramble.cl.cam.ac.uk
date Mon Feb 23 13:57:02 2004 +0000 (2004-02-23)
parents 63f485891446
children 3ba8d5faadd2 a98fbec887fb 3171cfca9a50
files .rootkeys README.CD docs/Xeno-1.2-HOWTO.txt docs/Xeno-HOWTO.txt xen/arch/i386/boot/boot.S xen/arch/i386/nmi.c xen/arch/i386/pdb-stub.c xen/arch/i386/setup.c xen/common/domain.c xen/common/kernel.c xen/common/keyhandler.c xen/common/memory.c xen/drivers/char/serial.c xen/drivers/char/xen_serial.c xen/include/xeno/config.h xen/include/xeno/console.h xen/include/xeno/lib.h xen/include/xeno/serial.h
line diff
     1.1 --- a/.rootkeys	Fri Feb 20 16:13:18 2004 +0000
     1.2 +++ b/.rootkeys	Mon Feb 23 13:57:02 2004 +0000
     1.3 @@ -8,7 +8,7 @@ 3f5ef5a2l4kfBYSQTUaOyyD76WROZQ README.CD
     1.4  3f69d8abYB1vMyD_QVDvzxy5Zscf1A TODO
     1.5  3f9e7d53iC47UnlfORp9iC1vai6kWw docs/Makefile
     1.6  40083bb4LVQzRqA3ABz0__pPhGNwtA docs/VBD-HOWTO.txt
     1.7 -4021053fmeFrEyPHcT8JFiDpLNgtHQ docs/Xeno-1.2-HOWTO.txt
     1.8 +4021053fmeFrEyPHcT8JFiDpLNgtHQ docs/Xeno-HOWTO.txt
     1.9  3f9e7d60PWZJeVh5xdnk0nLUdxlqEA docs/eps/xenlogo.eps
    1.10  3f9e7d63lTwQbp2fnx7yY93epWS-eQ docs/figs/dummy
    1.11  3f9e7d564bWFB-Czjv1qdmE6o0GqNg docs/interface.tex
    1.12 @@ -167,8 +167,8 @@ 3e5d129asHNyZOjBKTkqs-9AFzxemA xen/drive
    1.13  3e9c248afxxsnAzIt2na7Ej24yNFzg xen/drivers/cdrom/Makefile
    1.14  3e9c248ajUkn2W3n4vgm72Hp2ftZ8A xen/drivers/cdrom/cdrom.c
    1.15  3e4a8cb7alzQCDKS7MlioPoHBKYkdQ xen/drivers/char/Makefile
    1.16 +3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/serial.c
    1.17  3e4a8cb7WmiYdC-ASGiCSG_CL8vsqg xen/drivers/char/xen_kbd.c
    1.18 -3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/xen_serial.c
    1.19  3ddb79bdhcqD9ebrslr0O0oHqTiiXg xen/drivers/ide/Makefile
    1.20  3e9c248aCM6Lex1Am8_NJIeesN4kKg xen/drivers/ide/ide-cd.c
    1.21  3e9c248aFfSNR_hl-WQBbv-R9CTgzg xen/drivers/ide/ide-cd.h
    1.22 @@ -479,6 +479,7 @@ 3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen/inclu
    1.23  4006e65fWMwLqcocgik6wbF0Eeh0Og xen/include/xeno/rbtree.h
    1.24  3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xeno/reboot.h
    1.25  3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen/include/xeno/sched.h
    1.26 +403a06a7H0hpHcKpAiDe5BPnaXWTlA xen/include/xeno/serial.h
    1.27  3ddb79c0VDeD-Oft5eNfMneTU3D1dQ xen/include/xeno/skbuff.h
    1.28  3ddb79c14dXIhP7C2ahnoD08K90G_w xen/include/xeno/slab.h
    1.29  3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/include/xeno/smp.h
     2.1 --- a/README.CD	Fri Feb 20 16:13:18 2004 +0000
     2.2 +++ b/README.CD	Mon Feb 23 13:57:02 2004 +0000
     2.3 @@ -76,7 +76,7 @@ sequentially for subsequent domains unle
     2.4  After selecting the kernel to boot, stand back and watch Xen boot,
     2.5  closely followed by "domain 0" running the XenoLinux kernel. The boot
     2.6  messages can also sent to the serial line by specifying the baud rate
     2.7 -on the Xen cmdline (e.g., 'ser_baud=9600'); this can be very useful
     2.8 +on the Xen cmdline (e.g., 'com1=9600,8n1'); this can be very useful
     2.9  for debugging should anything important scroll off the screen. Xen's
    2.10  startup messages will look quite familiar as much of the hardware
    2.11  initialisation (SMP boot, apic setup) and device drivers are derived
    2.12 @@ -329,7 +329,31 @@ that may be able to help diagnose proble
    2.13  
    2.14   ifname=dummy	  Don't use any network interface.
    2.15  
    2.16 - ser_baud=xxx	  Enable serial I/O and set the baud rate (COM1)
    2.17 + com1=<baud>,DPS[,<io_base>,<irq>]
    2.18 + com2=<baud>,DPS[,<io_base>,<irq>]
    2.19 +                  Xen supports up to two 16550-compatible serial ports.
    2.20 +                  For example: 'com1=9600,8n1,0x408,5' maps COM1 to a
    2.21 +                  9600-baud port, 8 data bits, no parity, 1 stop bit,
    2.22 +                  I/O port base 0x408, IRQ 5.
    2.23 +                  If the I/O base and IRQ are standard (com1:0x3f8,4;
    2.24 +                  com2:0x2f8,3) then they need not be specified.
    2.25 +
    2.26 + console=<specifier list>
    2.27 +                  Specify the destination for Xen console I/O.
    2.28 +                  This is a comma-separated list of, for example:
    2.29 +                   vga:  use VGA console and allow keyboard input
    2.30 +                   com1: use serial port com1
    2.31 +                   com2H: use serial port com2. Transmitted chars will
    2.32 +                          have the MSB set. Received chars must have
    2.33 +                          MSB set.
    2.34 +                   com2L: use serial port com2. Transmitted chars will
    2.35 +                          have the MSB cleared. Received chars must
    2.36 +                          have MSB cleared.
    2.37 +                  The latter two examples allow a single port to be
    2.38 +                  shared by two subsystems (eg. console and
    2.39 +                  debugger). Sharing is controlled by MSB of each
    2.40 +                  transmitted/received character.
    2.41 + [NB. Default for this option is 'com1,tty']
    2.42  
    2.43   dom0_mem=xxx 	  Set the initial amount of memory for domain0.
    2.44  
    2.45 @@ -405,7 +429,7 @@ config file.
    2.46  A typical Grub menu option might look like:
    2.47  
    2.48  title Xen / XenoLinux 2.4.22
    2.49 -        kernel /boot/image.gz dom0_mem=131072 ser_baud=115200 noht
    2.50 +        kernel /boot/image.gz dom0_mem=131072 com1=115200,8n1 noht
    2.51          module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
    2.52  
    2.53  The first line specifies which Xen image to use, and what command line
     3.1 --- a/docs/Xeno-1.2-HOWTO.txt	Fri Feb 20 16:13:18 2004 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,321 +0,0 @@
     3.4 -###########################################
     3.5 -Xeno HOWTO
     3.6 -
     3.7 -University of Cambridge Computer Laboratory
     3.8 -
     3.9 -http://www.cl.cam.ac.uk/netos/xen
    3.10 -#############################
    3.11 -
    3.12 -
    3.13 -Get Xeno Source Codes
    3.14 -==========================
    3.15 -
    3.16 -The public master BK repository for the 1.2 release lives at:
    3.17 -'bk://xen.bkbits.net/xeno-1.2.bk'
    3.18 -
    3.19 -To fetch a local copy, first download the BitKeeper tools at:
    3.20 -http://www.bitmover.com/download with username 'bitkeeper' and
    3.21 -password 'get bitkeeper'.
    3.22 -
    3.23 -Then install the tools and then run:
    3.24 -# bk clone bk://xen.bkbits.net/xeno-1.2.bk
    3.25 -
    3.26 -Under your current directory, a new directory named 'xeno-1.2.bk' has
    3.27 -been created, which contains all the source codes for Xen and
    3.28 -XenoLinux. 
    3.29 -
    3.30 -To get newest changes to the repository, run
    3.31 -# cd xeno-1.2.bk
    3.32 -# bk pull
    3.33 -
    3.34 -
    3.35 -Build Xen
    3.36 -=============================
    3.37 -
    3.38 -Hint: To see how to build Xen and all the control tools, inspect the
    3.39 -tools/misc/xen-clone script in the BK repository. This script can be
    3.40 -used to clone the repository and perform a full build.
    3.41 -
    3.42 -To build Xen manually:
    3.43 -
    3.44 -# cd xeno-1.2.bk/xen
    3.45 -# make clean
    3.46 -# make
    3.47 -
    3.48 -This will (should) produce a file called 'xen' in the current
    3.49 -directory.  This is the ELF 32-bit LSB executable file of Xen.  You
    3.50 -can also find a gzip version, named 'xen.gz'.
    3.51 -
    3.52 -To install the built files on your Xenoserver under /usr, type 'make
    3.53 -install' at the root of the BK repository. You will need to be root to
    3.54 -do this!
    3.55 -
    3.56 -Hint: There is also a 'make dist' rule which copies built files to an
    3.57 -install directory just outside the BK repo; if this suits your setup,
    3.58 -go for it.
    3.59 -
    3.60 -
    3.61 -Build XenoLinux
    3.62 -==============================
    3.63 -
    3.64 -This is a little more involved since the repository only contains a
    3.65 -"sparse" tree -- this is essentially an 'overlay' on a standard linux
    3.66 -kernel source tree. It contains only those files currently 'in play'
    3.67 -which are either modified versions of files in the vanilla linux tree,
    3.68 -or brand new files specific to XenoLinux.
    3.69 -
    3.70 -So, first you need a vanilla linux-2.4.24 tree, which is located at:
    3.71 -http://www.kernel.org/pub/linux/kernel/v2.4
    3.72 -
    3.73 -Then:
    3.74 -  # mv linux-2.4.24.tar.gz /xeno-1.2.bk
    3.75 -  # cd /xeno-1.2.bk
    3.76 -  # tar -zxvf linux-2.4.24.tar.gz
    3.77 -
    3.78 -You'll find a new directory 'linux-2.4.24' which contains all
    3.79 -the vanilla Linux 2.4.24 kernel source codes.
    3.80 -
    3.81 -Hint: You should choose the vanilla linux kernel tree that has the
    3.82 -same version as the "sparse" tree.
    3.83 -
    3.84 -Next, you need to 'overlay' this sparse tree on the full vanilla Linux
    3.85 -kernel tree:
    3.86 -
    3.87 -  # cd /xeno-1.2.bk/xenolinux-2.4.24-sparse
    3.88 -  # ./mkbuildtree ../linux-2.4.24
    3.89 -
    3.90 -Finally, rename the buildtree since it is now a xenolinux buildtree. 
    3.91 -
    3.92 -  # cd /xeno-1.2.bk
    3.93 -  # mv linux-2.4.24 xenolinux-2.4.24
    3.94 -
    3.95 -Now that the buildtree is there, you can build the xenolinux kernel.
    3.96 -The default configuration should work fine for most people (use 'make
    3.97 -oldconfig') but you can customise using one of the other config tools
    3.98 -if you want.
    3.99 -
   3.100 -  # cd /xeno-1.2.bk/xenolinux-2.4.24
   3.101 -  # ARCH=xeno make oldconfig   { or menuconfig, or xconfig, or config }  
   3.102 -  # ARCH=xeno make dep bzImage
   3.103 -
   3.104 -Assuming the build works, you'll end up with
   3.105 -/xeno-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz. This is the
   3.106 -gzip version of XenoLinux kernel image.
   3.107 -
   3.108 -
   3.109 -Build the Domain Control Tools
   3.110 -==============================
   3.111 -
   3.112 -Under '/xeno-1.2.bk/tools', there are three sub-directories:
   3.113 -'balloon', 'xc' and 'misc', each containing
   3.114 -a group of tools. You can enter any of the four sub-directories
   3.115 -and type 'make' to compile the corresponding group of tools.
   3.116 -Or you can type 'make' under '/xeno-1.2.bk/tools' to compile
   3.117 -all the tools.
   3.118 -
   3.119 -In order to compile the control-interface library in 'xc' you must
   3.120 -have zlib and development headers installed. Also you will need at
   3.121 -least Python v2.2. 
   3.122 -
   3.123 -'make install' in the tools directory will place executables and
   3.124 -libraries in /usr/bin and /usr/lib. You will need to be root to do this!
   3.125 -
   3.126 -As noted earlier, 'make dist' installs files to a local 'install'
   3.127 -directory just outside the BK repository. These files will then need
   3.128 -to be installed manually onto the Xenoserver.
   3.129 -
   3.130 -The Example Scripts
   3.131 -===================
   3.132 -
   3.133 -The scripts in tools/examples/ are generally useful for
   3.134 -administering a Xen-based system.  You can install them by running
   3.135 -'make install' in that directory.
   3.136 -
   3.137 -The python scripts (*.py) are the main tools for controlling
   3.138 -Xen domains.
   3.139 -
   3.140 -'defaults' and 'democd' are example configuration files for starting
   3.141 -new domains.
   3.142 -
   3.143 -'xendomains' is a Sys-V style init script for starting and stopping
   3.144 -Xen domains when the system boots / shuts down.
   3.145 -
   3.146 -These will be discussed below in more detail.
   3.147 -
   3.148 -
   3.149 -Installation
   3.150 -==============================
   3.151 -
   3.152 -First:
   3.153 -# cp /xen-1.2.bk/xen/xen.gz /boot/xen.gz
   3.154 -# cp /xen-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz /boot/xenolinux.gz
   3.155 -
   3.156 -Second, you must have 'GNU Grub' installed. Then you need to edit
   3.157 -the Grub configuration file '/boot/grub/menu.lst'.
   3.158 -
   3.159 -A typical Grub menu option might look like:
   3.160 -
   3.161 -title Xen 1.2 / XenoLinux 2.4.24
   3.162 -        kernel /boot/xen.gz dom0_mem=131072 ser_baud=115200 noht
   3.163 -        module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
   3.164 -
   3.165 -The first line specifies which Xen image to use, and what command line
   3.166 -arguments to pass to Xen. In this case we set the maximum amount of
   3.167 -memory to allocate to domain0, and enable serial I/O at 115200 baud.
   3.168 -We could also disable smp support (nosmp) or disable hyper-threading
   3.169 -support (noht). If you have multiple network interface you can use
   3.170 -ifname=ethXX to select which one to use. If your network card is
   3.171 -unsupported, use ifname=dummy
   3.172 -
   3.173 -The second line specifies which XenoLinux image to use, and the
   3.174 -standard linux command line arguments to pass to the kernel. In this
   3.175 -case, we're configuring the root partition and stating that it should
   3.176 -(initially) be mounted read-only (normal practice). 
   3.177 -
   3.178 -The following is a list of command line arguments to pass to Xen:
   3.179 -
   3.180 - ignorebiostables Disable parsing of BIOS-supplied tables. This may
   3.181 -                  help with some chipsets that aren't fully supported
   3.182 -                  by Xen. If you specify this option then ACPI tables are
   3.183 -                  also ignored, and SMP support is disabled.
   3.184 -
   3.185 - noreboot         Don't reboot the machine automatically on errors.
   3.186 -                  This is useful to catch debug output if you aren't
   3.187 -                  catching console messages via the serial line.
   3.188 -
   3.189 - nosmp            Disable SMP support.
   3.190 -                  This option is implied by 'ignorebiostables'.
   3.191 -
   3.192 - noacpi           Disable ACPI tables, which confuse Xen on some chipsets.
   3.193 -                  This option is implied by 'ignorebiostables'.
   3.194 -
   3.195 - watchdog         Enable NMI watchdog which can report certain failures.
   3.196 -
   3.197 - noht             Disable Hyperthreading.
   3.198 -
   3.199 - ifname=ethXX     Select which Ethernet interface to use.
   3.200 -
   3.201 - ifname=dummy     Don't use any network interface.
   3.202 -
   3.203 - ser_baud=xxx     Enable serial I/O and set the baud rate.
   3.204 -
   3.205 - dom0_mem=xxx     Set the maximum amount of memory for domain0.
   3.206 -
   3.207 -
   3.208 -Boot into Domain 0
   3.209 -==============================
   3.210 -
   3.211 -Reboot your computer; After selecting the kernel to boot, stand back
   3.212 -and watch Xen boot, closely followed by "domain 0" running the
   3.213 -XenoLinux kernel.  Depending on which root partition you have assigned
   3.214 -to XenoLinux kernel in Grub configuration file, you can use the
   3.215 -corresponding username / password to log in.
   3.216 -
   3.217 -Once logged in, it should look just like any regular linux box. All
   3.218 -the usual tools and commands should work as per usual.
   3.219 -
   3.220 -
   3.221 -Start New Domains
   3.222 -==============================
   3.223 -
   3.224 -You must be 'root' to start new domains.
   3.225 -
   3.226 -Make sure you have successfully configured at least one
   3.227 -physical network interface. Then:
   3.228 -
   3.229 -# xen_nat_enable
   3.230 -# xen_read_console &
   3.231 -
   3.232 -When new  domains are created and  started, they will  send output via
   3.233 -UDP packets to  the local virtual network. Those  packets are received
   3.234 -by xen_read_console running in Domain  0 and output are printed out to
   3.235 -the standard output.
   3.236 -
   3.237 -The xc_dom_create.py program is useful for starting Xen domains.
   3.238 -You can specify configuration files using the -f switch on the command
   3.239 -line.  The default configuration is in /etc/xc/defaults.  You can
   3.240 -create custom versions of this to suit your local configuration.
   3.241 -
   3.242 -You can override the settings in a configuration file using command
   3.243 -line arguments to xc_dom_create.py.  However, you may find it simplest
   3.244 -to create a separate configuration file for each domain you start.
   3.245 -
   3.246 -When you start domains, you should be able to see XenoLinux boot
   3.247 -message on standard output with each line prepended with [domain_id].
   3.248 -
   3.249 -
   3.250 -Manage Running Domains
   3.251 -==============================
   3.252 -
   3.253 -You can see a list of existing domains with:
   3.254 -# xc_dom_control.py list
   3.255 -
   3.256 -In order to stop a domain, you use:
   3.257 -# xc_dom_control.py stop <domain_id>
   3.258 -
   3.259 -To shutdown a domain cleanly use:
   3.260 -# xc_dom_control.py shutdown <domain_id>
   3.261 -
   3.262 -To destroy a domain immediately:
   3.263 -# xc_dom_control.py destroy <domain_id>
   3.264 -
   3.265 -There are other more advanced options, including pinning domains to
   3.266 -specific CPUs and saving / resuming domains to / from disk files.  To
   3.267 -get more information, run the tool without any arguments:
   3.268 -# xc_dom_control.py
   3.269 -
   3.270 -There is more information available in the Xen README files, the
   3.271 -VBD-HOWTO and the contributed FAQ / HOWTO documents on the web.
   3.272 -
   3.273 -
   3.274 -Other Control Tasks using Python
   3.275 -================================
   3.276 -
   3.277 -A Python module 'Xc' is installed as part of the tools-install
   3.278 -process. This can be imported, and an 'xc object' instantiated, to
   3.279 -provide access to privileged command operations:
   3.280 -
   3.281 -# import Xc
   3.282 -# xc = Xc.new()
   3.283 -# dir(xc)
   3.284 -# help(xc.domain_create)
   3.285 -
   3.286 -In this way you can see that the class 'xc' contains useful
   3.287 -documentation for you to consult.
   3.288 -
   3.289 -A further module of useful routines (XenoUtil) is also installed:
   3.290 -
   3.291 -# import XenoUtil
   3.292 -# help(XenoUtil)
   3.293 -
   3.294 -You can use these modules to write your own custom scripts or you can
   3.295 -customise the scripts supplied in the Xen distribution.
   3.296 -
   3.297 -
   3.298 -Automatically start / stop domains at boot / shutdown
   3.299 -=====================================================
   3.300 -
   3.301 -A Sys-V style init script for RedHat systems is provided in
   3.302 -tools/examples/xendomains.  When you run 'make install' in that
   3.303 -directory, it should be automatically copied to /etc/init.d/.  You can
   3.304 -then enable it using the chkconfig command, e.g.:
   3.305 -
   3.306 -# chkconfig --add xendomains
   3.307 -
   3.308 -By default, this will start the boot-time domains in runlevels 3, 4
   3.309 -and 5.  To specify a domain is to start at boot-time, place its
   3.310 -configuration file (or a link to it) under /etc/xc/auto/.
   3.311 -
   3.312 -The script will also stop ALL domains when the system is shut down,
   3.313 -even domains that it did not start originally.
   3.314 -
   3.315 -You can also use the "service" command (part of the RedHat standard
   3.316 -distribution) to run this script manually, e.g:
   3.317 -
   3.318 -# service xendomains start
   3.319 -
   3.320 -Starts all the domains with config files under /etc/xc/auto/.
   3.321 -
   3.322 -# service xendomains stop
   3.323 -
   3.324 -Shuts down ALL running Xen domains.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/docs/Xeno-HOWTO.txt	Mon Feb 23 13:57:02 2004 +0000
     4.3 @@ -0,0 +1,345 @@
     4.4 +###########################################
     4.5 +Xeno HOWTO
     4.6 +
     4.7 +University of Cambridge Computer Laboratory
     4.8 +
     4.9 +http://www.cl.cam.ac.uk/netos/xen
    4.10 +#############################
    4.11 +
    4.12 +
    4.13 +Get Xeno Source Codes
    4.14 +==========================
    4.15 +
    4.16 +The public master BK repository for the 1.2 release lives at:
    4.17 +'bk://xen.bkbits.net/xeno-1.2.bk'
    4.18 +
    4.19 +To fetch a local copy, first download the BitKeeper tools at:
    4.20 +http://www.bitmover.com/download with username 'bitkeeper' and
    4.21 +password 'get bitkeeper'.
    4.22 +
    4.23 +Then install the tools and then run:
    4.24 +# bk clone bk://xen.bkbits.net/xeno-1.2.bk
    4.25 +
    4.26 +Under your current directory, a new directory named 'xeno-1.2.bk' has
    4.27 +been created, which contains all the source codes for Xen and
    4.28 +XenoLinux. 
    4.29 +
    4.30 +To get newest changes to the repository, run
    4.31 +# cd xeno-1.2.bk
    4.32 +# bk pull
    4.33 +
    4.34 +
    4.35 +Build Xen
    4.36 +=============================
    4.37 +
    4.38 +Hint: To see how to build Xen and all the control tools, inspect the
    4.39 +tools/misc/xen-clone script in the BK repository. This script can be
    4.40 +used to clone the repository and perform a full build.
    4.41 +
    4.42 +To build Xen manually:
    4.43 +
    4.44 +# cd xeno-1.2.bk/xen
    4.45 +# make clean
    4.46 +# make
    4.47 +
    4.48 +This will (should) produce a file called 'xen' in the current
    4.49 +directory.  This is the ELF 32-bit LSB executable file of Xen.  You
    4.50 +can also find a gzip version, named 'xen.gz'.
    4.51 +
    4.52 +To install the built files on your Xenoserver under /usr, type 'make
    4.53 +install' at the root of the BK repository. You will need to be root to
    4.54 +do this!
    4.55 +
    4.56 +Hint: There is also a 'make dist' rule which copies built files to an
    4.57 +install directory just outside the BK repo; if this suits your setup,
    4.58 +go for it.
    4.59 +
    4.60 +
    4.61 +Build XenoLinux
    4.62 +==============================
    4.63 +
    4.64 +This is a little more involved since the repository only contains a
    4.65 +"sparse" tree -- this is essentially an 'overlay' on a standard linux
    4.66 +kernel source tree. It contains only those files currently 'in play'
    4.67 +which are either modified versions of files in the vanilla linux tree,
    4.68 +or brand new files specific to XenoLinux.
    4.69 +
    4.70 +So, first you need a vanilla linux-2.4.24 tree, which is located at:
    4.71 +http://www.kernel.org/pub/linux/kernel/v2.4
    4.72 +
    4.73 +Then:
    4.74 +  # mv linux-2.4.24.tar.gz /xeno-1.2.bk
    4.75 +  # cd /xeno-1.2.bk
    4.76 +  # tar -zxvf linux-2.4.24.tar.gz
    4.77 +
    4.78 +You'll find a new directory 'linux-2.4.24' which contains all
    4.79 +the vanilla Linux 2.4.24 kernel source codes.
    4.80 +
    4.81 +Hint: You should choose the vanilla linux kernel tree that has the
    4.82 +same version as the "sparse" tree.
    4.83 +
    4.84 +Next, you need to 'overlay' this sparse tree on the full vanilla Linux
    4.85 +kernel tree:
    4.86 +
    4.87 +  # cd /xeno-1.2.bk/xenolinux-2.4.24-sparse
    4.88 +  # ./mkbuildtree ../linux-2.4.24
    4.89 +
    4.90 +Finally, rename the buildtree since it is now a xenolinux buildtree. 
    4.91 +
    4.92 +  # cd /xeno-1.2.bk
    4.93 +  # mv linux-2.4.24 xenolinux-2.4.24
    4.94 +
    4.95 +Now that the buildtree is there, you can build the xenolinux kernel.
    4.96 +The default configuration should work fine for most people (use 'make
    4.97 +oldconfig') but you can customise using one of the other config tools
    4.98 +if you want.
    4.99 +
   4.100 +  # cd /xeno-1.2.bk/xenolinux-2.4.24
   4.101 +  # ARCH=xeno make oldconfig   { or menuconfig, or xconfig, or config }  
   4.102 +  # ARCH=xeno make dep bzImage
   4.103 +
   4.104 +Assuming the build works, you'll end up with
   4.105 +/xeno-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz. This is the
   4.106 +gzip version of XenoLinux kernel image.
   4.107 +
   4.108 +
   4.109 +Build the Domain Control Tools
   4.110 +==============================
   4.111 +
   4.112 +Under '/xeno-1.2.bk/tools', there are three sub-directories:
   4.113 +'balloon', 'xc' and 'misc', each containing
   4.114 +a group of tools. You can enter any of the four sub-directories
   4.115 +and type 'make' to compile the corresponding group of tools.
   4.116 +Or you can type 'make' under '/xeno-1.2.bk/tools' to compile
   4.117 +all the tools.
   4.118 +
   4.119 +In order to compile the control-interface library in 'xc' you must
   4.120 +have zlib and development headers installed. Also you will need at
   4.121 +least Python v2.2. 
   4.122 +
   4.123 +'make install' in the tools directory will place executables and
   4.124 +libraries in /usr/bin and /usr/lib. You will need to be root to do this!
   4.125 +
   4.126 +As noted earlier, 'make dist' installs files to a local 'install'
   4.127 +directory just outside the BK repository. These files will then need
   4.128 +to be installed manually onto the Xenoserver.
   4.129 +
   4.130 +The Example Scripts
   4.131 +===================
   4.132 +
   4.133 +The scripts in tools/examples/ are generally useful for
   4.134 +administering a Xen-based system.  You can install them by running
   4.135 +'make install' in that directory.
   4.136 +
   4.137 +The python scripts (*.py) are the main tools for controlling
   4.138 +Xen domains.
   4.139 +
   4.140 +'defaults' and 'democd' are example configuration files for starting
   4.141 +new domains.
   4.142 +
   4.143 +'xendomains' is a Sys-V style init script for starting and stopping
   4.144 +Xen domains when the system boots / shuts down.
   4.145 +
   4.146 +These will be discussed below in more detail.
   4.147 +
   4.148 +
   4.149 +Installation
   4.150 +==============================
   4.151 +
   4.152 +First:
   4.153 +# cp /xen-1.2.bk/xen/xen.gz /boot/xen.gz
   4.154 +# cp /xen-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz /boot/xenolinux.gz
   4.155 +
   4.156 +Second, you must have 'GNU Grub' installed. Then you need to edit
   4.157 +the Grub configuration file '/boot/grub/menu.lst'.
   4.158 +
   4.159 +A typical Grub menu option might look like:
   4.160 +
   4.161 +title Xen 1.2 / XenoLinux 2.4.24
   4.162 +        kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1 noht
   4.163 +        module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
   4.164 +
   4.165 +The first line specifies which Xen image to use, and what command line
   4.166 +arguments to pass to Xen. In this case we set the maximum amount of
   4.167 +memory to allocate to domain0, and enable serial I/O at 115200 baud.
   4.168 +We could also disable smp support (nosmp) or disable hyper-threading
   4.169 +support (noht). If you have multiple network interface you can use
   4.170 +ifname=ethXX to select which one to use. If your network card is
   4.171 +unsupported, use ifname=dummy
   4.172 +
   4.173 +The second line specifies which XenoLinux image to use, and the
   4.174 +standard linux command line arguments to pass to the kernel. In this
   4.175 +case, we're configuring the root partition and stating that it should
   4.176 +(initially) be mounted read-only (normal practice). 
   4.177 +
   4.178 +The following is a list of command line arguments to pass to Xen:
   4.179 +
   4.180 + ignorebiostables Disable parsing of BIOS-supplied tables. This may
   4.181 +                  help with some chipsets that aren't fully supported
   4.182 +                  by Xen. If you specify this option then ACPI tables are
   4.183 +                  also ignored, and SMP support is disabled.
   4.184 +
   4.185 + noreboot         Don't reboot the machine automatically on errors.
   4.186 +                  This is useful to catch debug output if you aren't
   4.187 +                  catching console messages via the serial line.
   4.188 +
   4.189 + nosmp            Disable SMP support.
   4.190 +                  This option is implied by 'ignorebiostables'.
   4.191 +
   4.192 + noacpi           Disable ACPI tables, which confuse Xen on some chipsets.
   4.193 +                  This option is implied by 'ignorebiostables'.
   4.194 +
   4.195 + watchdog         Enable NMI watchdog which can report certain failures.
   4.196 +
   4.197 + noht             Disable Hyperthreading.
   4.198 +
   4.199 + ifname=ethXX     Select which Ethernet interface to use.
   4.200 +
   4.201 + ifname=dummy     Don't use any network interface.
   4.202 +
   4.203 + com1=<baud>,DPS[,<io_base>,<irq>]
   4.204 + com2=<baud>,DPS[,<io_base>,<irq>]
   4.205 +                  Xen supports up to two 16550-compatible serial ports.
   4.206 +                  For example: 'com1=9600,8n1,0x408,5' maps COM1 to a
   4.207 +                  9600-baud port, 8 data bits, no parity, 1 stop bit,
   4.208 +                  I/O port base 0x408, IRQ 5.
   4.209 +                  If the I/O base and IRQ are standard (com1:0x3f8,4;
   4.210 +                  com2:0x2f8,3) then they need not be specified.
   4.211 +
   4.212 + console=<specifier list>
   4.213 +                  Specify the destination for Xen console I/O.
   4.214 +                  This is a comma-separated list of, for example:
   4.215 +                   vga:  use VGA console and allow keyboard input
   4.216 +                   com1: use serial port com1
   4.217 +                   com2H: use serial port com2. Transmitted chars will
   4.218 +                          have the MSB set. Received chars must have
   4.219 +                          MSB set.
   4.220 +                   com2L: use serial port com2. Transmitted chars will
   4.221 +                          have the MSB cleared. Received chars must
   4.222 +                          have MSB cleared.
   4.223 +                  The latter two examples allow a single port to be
   4.224 +                  shared by two subsystems (eg. console and
   4.225 +                  debugger). Sharing is controlled by MSB of each
   4.226 +                  transmitted/received character.
   4.227 + [NB. Default for this option is 'com1,tty']
   4.228 +
   4.229 + dom0_mem=xxx     Set the maximum amount of memory for domain0.
   4.230 +
   4.231 +
   4.232 +Boot into Domain 0
   4.233 +==============================
   4.234 +
   4.235 +Reboot your computer; After selecting the kernel to boot, stand back
   4.236 +and watch Xen boot, closely followed by "domain 0" running the
   4.237 +XenoLinux kernel.  Depending on which root partition you have assigned
   4.238 +to XenoLinux kernel in Grub configuration file, you can use the
   4.239 +corresponding username / password to log in.
   4.240 +
   4.241 +Once logged in, it should look just like any regular linux box. All
   4.242 +the usual tools and commands should work as per usual.
   4.243 +
   4.244 +
   4.245 +Start New Domains
   4.246 +==============================
   4.247 +
   4.248 +You must be 'root' to start new domains.
   4.249 +
   4.250 +Make sure you have successfully configured at least one
   4.251 +physical network interface. Then:
   4.252 +
   4.253 +# xen_nat_enable
   4.254 +# xen_read_console &
   4.255 +
   4.256 +When new  domains are created and  started, they will  send output via
   4.257 +UDP packets to  the local virtual network. Those  packets are received
   4.258 +by xen_read_console running in Domain  0 and output are printed out to
   4.259 +the standard output.
   4.260 +
   4.261 +The xc_dom_create.py program is useful for starting Xen domains.
   4.262 +You can specify configuration files using the -f switch on the command
   4.263 +line.  The default configuration is in /etc/xc/defaults.  You can
   4.264 +create custom versions of this to suit your local configuration.
   4.265 +
   4.266 +You can override the settings in a configuration file using command
   4.267 +line arguments to xc_dom_create.py.  However, you may find it simplest
   4.268 +to create a separate configuration file for each domain you start.
   4.269 +
   4.270 +When you start domains, you should be able to see XenoLinux boot
   4.271 +message on standard output with each line prepended with [domain_id].
   4.272 +
   4.273 +
   4.274 +Manage Running Domains
   4.275 +==============================
   4.276 +
   4.277 +You can see a list of existing domains with:
   4.278 +# xc_dom_control.py list
   4.279 +
   4.280 +In order to stop a domain, you use:
   4.281 +# xc_dom_control.py stop <domain_id>
   4.282 +
   4.283 +To shutdown a domain cleanly use:
   4.284 +# xc_dom_control.py shutdown <domain_id>
   4.285 +
   4.286 +To destroy a domain immediately:
   4.287 +# xc_dom_control.py destroy <domain_id>
   4.288 +
   4.289 +There are other more advanced options, including pinning domains to
   4.290 +specific CPUs and saving / resuming domains to / from disk files.  To
   4.291 +get more information, run the tool without any arguments:
   4.292 +# xc_dom_control.py
   4.293 +
   4.294 +There is more information available in the Xen README files, the
   4.295 +VBD-HOWTO and the contributed FAQ / HOWTO documents on the web.
   4.296 +
   4.297 +
   4.298 +Other Control Tasks using Python
   4.299 +================================
   4.300 +
   4.301 +A Python module 'Xc' is installed as part of the tools-install
   4.302 +process. This can be imported, and an 'xc object' instantiated, to
   4.303 +provide access to privileged command operations:
   4.304 +
   4.305 +# import Xc
   4.306 +# xc = Xc.new()
   4.307 +# dir(xc)
   4.308 +# help(xc.domain_create)
   4.309 +
   4.310 +In this way you can see that the class 'xc' contains useful
   4.311 +documentation for you to consult.
   4.312 +
   4.313 +A further module of useful routines (XenoUtil) is also installed:
   4.314 +
   4.315 +# import XenoUtil
   4.316 +# help(XenoUtil)
   4.317 +
   4.318 +You can use these modules to write your own custom scripts or you can
   4.319 +customise the scripts supplied in the Xen distribution.
   4.320 +
   4.321 +
   4.322 +Automatically start / stop domains at boot / shutdown
   4.323 +=====================================================
   4.324 +
   4.325 +A Sys-V style init script for RedHat systems is provided in
   4.326 +tools/examples/xendomains.  When you run 'make install' in that
   4.327 +directory, it should be automatically copied to /etc/init.d/.  You can
   4.328 +then enable it using the chkconfig command, e.g.:
   4.329 +
   4.330 +# chkconfig --add xendomains
   4.331 +
   4.332 +By default, this will start the boot-time domains in runlevels 3, 4
   4.333 +and 5.  To specify a domain is to start at boot-time, place its
   4.334 +configuration file (or a link to it) under /etc/xc/auto/.
   4.335 +
   4.336 +The script will also stop ALL domains when the system is shut down,
   4.337 +even domains that it did not start originally.
   4.338 +
   4.339 +You can also use the "service" command (part of the RedHat standard
   4.340 +distribution) to run this script manually, e.g:
   4.341 +
   4.342 +# service xendomains start
   4.343 +
   4.344 +Starts all the domains with config files under /etc/xc/auto/.
   4.345 +
   4.346 +# service xendomains stop
   4.347 +
   4.348 +Shuts down ALL running Xen domains.
     5.1 --- a/xen/arch/i386/boot/boot.S	Fri Feb 20 16:13:18 2004 +0000
     5.2 +++ b/xen/arch/i386/boot/boot.S	Mon Feb 23 13:57:02 2004 +0000
     5.3 @@ -186,30 +186,14 @@ ignore_int:
     5.4          pushl   $int_msg
     5.5          call    SYMBOL_NAME(printf)
     5.6  1:      jmp     1b
     5.7 -        pop     %eax
     5.8 -        popl    %ds
     5.9 -        popl    %es
    5.10 -        pop     %edx
    5.11 -        pop     %ecx
    5.12 -        pop     %eax
    5.13 -        iret
    5.14 -
    5.15  
    5.16  bad_cpu_msg:
    5.17          .asciz  "Bad CPU type. Need P6+."
    5.18          ALIGN
    5.19  bad_cpu:
    5.20 -/* NB. We assume the UART is set up correctly. */
    5.21 -        mov     $bad_cpu_msg,%esi
    5.22 -1:      lodsb
    5.23 -        test    %al,%al
    5.24 -        je      1f
    5.25 -        push    %eax
    5.26 -        call    putchar_serial
    5.27 -        add     $4,%esp
    5.28 -        jmp     1b
    5.29 +        pushl   $bad_cpu_msg
    5.30 +        call    SYMBOL_NAME(printf)
    5.31  1:      jmp     1b
    5.32 -                   
    5.33          
    5.34  /*** STACK LOCATION ***/
    5.35          
     6.1 --- a/xen/arch/i386/nmi.c	Fri Feb 20 16:13:18 2004 +0000
     6.2 +++ b/xen/arch/i386/nmi.c	Mon Feb 23 13:57:02 2004 +0000
     6.3 @@ -276,7 +276,6 @@ void nmi_watchdog_tick (struct pt_regs *
     6.4  {
     6.5      extern spinlock_t console_lock;
     6.6      extern void die(const char * str, struct pt_regs * regs, long err);
     6.7 -    extern void putchar_serial(unsigned char c);
     6.8  
     6.9      int sum, cpu = smp_processor_id();
    6.10  
     7.1 --- a/xen/arch/i386/pdb-stub.c	Fri Feb 20 16:13:18 2004 +0000
     7.2 +++ b/xen/arch/i386/pdb-stub.c	Mon Feb 23 13:57:02 2004 +0000
     7.3 @@ -5,6 +5,7 @@
     7.4  #include <asm/apic.h>
     7.5  #include <asm/pdb.h>
     7.6  #include <xeno/list.h>
     7.7 +#include <xeno/serial.h>
     7.8  
     7.9  #define BUFMAX 400
    7.10  
    7.11 @@ -27,8 +28,32 @@ static int pdb_info_thread = -1;
    7.12  static int pdb_stepping = 0;
    7.13  
    7.14  void pdb_put_packet (unsigned char *buffer, int ack);
    7.15 -void pdb_put_char (u_char c);
    7.16 -u_char pdb_get_char ();
    7.17 +
    7.18 +static int pdb_initialized = 0;
    7.19 +static int pdb_serhnd      = -1;
    7.20 +
    7.21 +#define RX_SIZE 32
    7.22 +#define RX_MASK(_i) ((_i)&(RX_SIZE-1))
    7.23 +static unsigned int rx_cons = 0, rx_prod = 0;
    7.24 +static unsigned char rx_ring[RX_RING_SIZE];
    7.25 +
    7.26 +static inline void pdb_put_char(unsigned char c)
    7.27 +{
    7.28 +    serial_putc(pdb_serhnd, c);
    7.29 +}
    7.30 +
    7.31 +static inline unsigned char pdb_get_char(void)
    7.32 +{
    7.33 +    while ( rx_cons == rx_prod )
    7.34 +        barrier();
    7.35 +    return rx_ring[RX_MASK(rx_cons++)];
    7.36 +}
    7.37 +
    7.38 +static void pdb_rx_char(unsigned char c, struct pt_regs *regs)
    7.39 +{
    7.40 +    if ( (rx_prod - rx_cons) != RX_SIZE )
    7.41 +        rx_ring[RX_MASK(rx_prod++)] = c;
    7.42 +}
    7.43  
    7.44  static volatile int mem_err = 0;
    7.45  void set_mem_err (void)                                   /* NOT USED YET... */
    7.46 @@ -635,23 +660,6 @@ int pdb_bkpt_remove (unsigned long addre
    7.47  
    7.48  void breakpoint(void);
    7.49  
    7.50 -int pdb_initialized = 0;
    7.51 -int pdb_high_bit = 1;
    7.52 -
    7.53 -void pdb_put_char (u_char c)
    7.54 -{
    7.55 -    extern void   debug_putchar(u_char);
    7.56 -    u_char cc = pdb_high_bit ? c | 0x80 : c;
    7.57 -    debug_putchar(cc);
    7.58 -}
    7.59 -
    7.60 -u_char pdb_get_char ()
    7.61 -{
    7.62 -    extern u_char debug_getchar();
    7.63 -    u_char cc = debug_getchar();
    7.64 -    return cc & 0x7f;
    7.65 -}
    7.66 -
    7.67  /* send the packet in buffer.  */
    7.68  void pdb_put_packet (unsigned char *buffer, int ack)
    7.69  {
    7.70 @@ -821,35 +829,28 @@ void pdb_key_pressed(u_char key, void *d
    7.71  void initialize_pdb()
    7.72  {
    7.73      extern char opt_pdb[];
    7.74 -    int pdb_com_port;
    7.75  
    7.76      /* Certain state must be initialised even when PDB will not be used. */
    7.77      breakpoints.address = 0;
    7.78      INIT_LIST_HEAD(&breakpoints.list);
    7.79      pdb_stepping = 0;
    7.80  
    7.81 -    if ( strncmp(opt_pdb, "com", 3) == 0 )
    7.82 -    {
    7.83 -        extern void debug_set_com_port(int port);
    7.84 +    if ( strcmp(opt_pdb, "none") == 0 )
    7.85 +        return;
    7.86  
    7.87 -        pdb_com_port = opt_pdb[3] - '0';                 /* error checking ? */
    7.88 -	debug_set_com_port(pdb_com_port);
    7.89 -	pdb_high_bit = opt_pdb[4] == 'H' ? 1 : 0;
    7.90 -    }
    7.91 -    else
    7.92 +    if ( (pdb_serhnd = parse_serial_handle(opt_pdb)) == -1 )
    7.93      {
    7.94 -        if ( strcmp(opt_pdb, "none") != 0 )
    7.95 -	    printk ("pdb: unknown option\n");
    7.96 +        printk("Failed to initialise PDB on port %s\n", opt_pdb);
    7.97          return;
    7.98      }
    7.99  
   7.100 -    printk("Initializing pervasive debugger (PDB) on serial port %d %s\n",
   7.101 -           pdb_com_port, pdb_high_bit ? "(high bit enabled)" : "");
   7.102 +    serial_set_rx_handler(pdb_serhnd, pdb_rx_char);
   7.103 +
   7.104 +    printk("Initialised pervasive debugger (PDB) on port %s\n", opt_pdb);
   7.105  
   7.106 -    /* ack any spurrious gdb packets */
   7.107 -    pdb_put_char ('+');
   7.108 +    /* Acknowledge any spurious GDB packets. */
   7.109 +    serial_putc(pdb_serhnd, '+');
   7.110  
   7.111 -    /* serial console */
   7.112      add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
   7.113  
   7.114      pdb_initialized = 1;
     8.1 --- a/xen/arch/i386/setup.c	Fri Feb 20 16:13:18 2004 +0000
     8.2 +++ b/xen/arch/i386/setup.c	Mon Feb 23 13:57:02 2004 +0000
     8.3 @@ -5,6 +5,7 @@
     8.4  #include <xeno/lib.h>
     8.5  #include <xeno/sched.h>
     8.6  #include <xeno/pci.h>
     8.7 +#include <xeno/serial.h>
     8.8  #include <asm/bitops.h>
     8.9  #include <asm/smp.h>
    8.10  #include <asm/processor.h>
    8.11 @@ -316,7 +317,6 @@ void __init start_of_day(void)
    8.12      extern void net_init(void);
    8.13      extern void initialize_block_io(void);
    8.14      extern void initialize_keytable(); 
    8.15 -    extern void initialize_serial(void);
    8.16      extern void initialize_keyboard(void);
    8.17      extern int opt_nosmp, opt_watchdog, opt_noacpi, opt_ignorebiostables;
    8.18      extern int do_timer_lists_from_pit;
    8.19 @@ -406,6 +406,10 @@ void __init start_of_day(void)
    8.20  
    8.21      initialize_keytable(); /* call back handling for key codes      */
    8.22  
    8.23 +    serial_init_stage2();
    8.24 +    initialize_keyboard(); /* setup keyboard (also for debugging)   */
    8.25 +    initialize_pdb();      /* pervasive debugger */
    8.26 +
    8.27      if ( !cpu_has_apic )
    8.28      {
    8.29          do_timer_lists_from_pit = 1;
    8.30 @@ -427,10 +431,6 @@ void __init start_of_day(void)
    8.31      pci_init();
    8.32  #endif
    8.33      do_initcalls();
    8.34 -    initialize_serial();   /* setup serial 'driver' (for debugging) */
    8.35 -    initialize_keyboard(); /* setup keyboard (also for debugging)   */
    8.36 -    initialize_pdb();      /* pervasive debugger */
    8.37 -
    8.38      if ( !setup_network_devices() )
    8.39          panic("Must have a network device!\n");
    8.40      net_init();            /* initializes virtual network system. */
     9.1 --- a/xen/common/domain.c	Fri Feb 20 16:13:18 2004 +0000
     9.2 +++ b/xen/common/domain.c	Mon Feb 23 13:57:02 2004 +0000
     9.3 @@ -787,9 +787,9 @@ int setup_guestos(struct task_struct *p,
     9.4      }
     9.5      *dst = '\0';
     9.6  
     9.7 -    /* If this guy's getting the console we'd better let go. */
     9.8 -    if ( CONSOLE_ISOWNER(p) )
     9.9 -        opt_console = 0;
    9.10 +    /* HACK: Give up the VGA console iff the Xenolinux DOM0 wants it. */
    9.11 +    if ( strstr(cmdline, "tty0") != NULL )
    9.12 +        vgacon_enabled = 0;
    9.13  
    9.14      /* Reinstate the caller's page tables. */
    9.15      write_cr3_counted(pagetable_val(current->mm.pagetable));
    10.1 --- a/xen/common/kernel.c	Fri Feb 20 16:13:18 2004 +0000
    10.2 +++ b/xen/common/kernel.c	Mon Feb 23 13:57:02 2004 +0000
    10.3 @@ -29,11 +29,15 @@
    10.4  #include <asm/domain_page.h>
    10.5  #include <xeno/console.h>
    10.6  #include <xeno/net_headers.h>
    10.7 +#include <xeno/serial.h>
    10.8  
    10.9  kmem_cache_t *task_struct_cachep;
   10.10  
   10.11  static int xpos, ypos;
   10.12 -static volatile unsigned char *video;
   10.13 +static unsigned char *video = __va(0xB8000);
   10.14 +
   10.15 +int sercon_handle = -1;
   10.16 +int vgacon_enabled = 0;
   10.17  
   10.18  spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
   10.19  
   10.20 @@ -43,15 +47,17 @@ struct e820entry {
   10.21      unsigned long type;                    /* type of memory segment */
   10.22  };
   10.23  
   10.24 -void init_vga(void);
   10.25 -void init_serial(void);
   10.26 +static void init_vga(void);
   10.27  void start_of_day(void);
   10.28  
   10.29 -/* opt_console: If true, Xen sends logging to the VGA console. */
   10.30 -int opt_console = 1;
   10.31 +/* opt_console: comma-separated list of console outputs. */
   10.32 +unsigned char opt_console[30] = "com1,vga";
   10.33  /* opt_ser_baud: Baud rate at which logging is sent to COM1. */
   10.34  /* NB. Default (0) means that serial I/O is disabled. */
   10.35 +/* NB2. THIS OPTION IS DEPRECATED!! */
   10.36  unsigned int opt_ser_baud = 0;
   10.37 +/* opt_com[12]: Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
   10.38 +unsigned char opt_com1[30] = "", opt_com2[30] = "";
   10.39  /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
   10.40  unsigned int opt_dom0_mem = 16000;
   10.41  /* opt_ifname: Name of physical network interface to use. */
   10.42 @@ -77,8 +83,10 @@ static struct {
   10.43      enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL } type;
   10.44      void *var;
   10.45  } opts[] = {
   10.46 -    { "console",          OPT_UINT, &opt_console },
   10.47 +    { "console",          OPT_STR,  &opt_console },
   10.48      { "ser_baud",         OPT_UINT, &opt_ser_baud },
   10.49 +    { "com1",             OPT_STR,  &opt_com1 },
   10.50 +    { "com2",             OPT_STR,  &opt_com2 },
   10.51      { "dom0_mem",         OPT_UINT, &opt_dom0_mem }, 
   10.52      { "ifname",           OPT_STR,  &opt_ifname },
   10.53      { "noht",             OPT_BOOL, &opt_noht },
   10.54 @@ -92,31 +100,16 @@ static struct {
   10.55  };
   10.56  
   10.57  
   10.58 -void cmain (unsigned long magic, multiboot_info_t *mbi)
   10.59 +void cmain(unsigned long magic, multiboot_info_t *mbi)
   10.60  {
   10.61      struct task_struct *new_dom;
   10.62      dom0_createdomain_t dom0_params;
   10.63      unsigned long max_page;
   10.64 -    unsigned char *cmdline;
   10.65 +    unsigned char *cmdline, *p;
   10.66      module_t *mod;
   10.67      int i;
   10.68  
   10.69 -    /*
   10.70 -     * Note that serial output cannot be done properly until after 
   10.71 -     * command-line arguments have been parsed, and the required baud rate is 
   10.72 -     * known. Any messages before that will be output using the settings of 
   10.73 -     * the bootloader, for example.
   10.74 -     */
   10.75 -
   10.76 -    if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
   10.77 -    {
   10.78 -        init_vga();
   10.79 -        cls();
   10.80 -        printk("Invalid magic number: 0x%x\n", (unsigned)magic);
   10.81 -        for ( ; ; ) ;
   10.82 -    }
   10.83 -
   10.84 -    /* Parse the command line. */
   10.85 +    /* Parse the command-line options. */
   10.86      cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
   10.87      if ( cmdline != NULL )
   10.88      {
   10.89 @@ -158,10 +151,28 @@ void cmain (unsigned long magic, multibo
   10.90          }
   10.91      }
   10.92  
   10.93 -    init_serial();
   10.94 +    /* Backward compatibility with deprecated 'ser_baud=' cmdline option. */
   10.95 +    if ( opt_ser_baud != 0 )
   10.96 +        sprintf(opt_com1, "%u,8n1", opt_ser_baud);
   10.97 +
   10.98 +    /* We initialise the serial devices very early so we can get debugging. */
   10.99 +    serial_init_stage1();
  10.100 +
  10.101 +    /* Where should console output go? */
  10.102 +    for ( p = opt_console; p != NULL; p = strchr(p, ',') )
  10.103 +    {
  10.104 +        if ( *p == ',' )
  10.105 +            p++;
  10.106 +        if ( strncmp(p, "com", 3) == 0 )
  10.107 +            sercon_handle = parse_serial_handle(p);
  10.108 +        else if ( strncmp(p, "vga", 3) == 0 )
  10.109 +            vgacon_enabled = 1;
  10.110 +    }
  10.111 +
  10.112 +    /* Set up VGA console output, if it was enabled. */
  10.113      init_vga();
  10.114 -    cls();
  10.115  
  10.116 +    /* HELLO WORLD --- start-of-day banner text. */
  10.117      printk(XEN_BANNER);
  10.118      printk(" http://www.cl.cam.ac.uk/netos/xen\n");
  10.119      printk(" University of Cambridge Computer Laboratory\n\n");
  10.120 @@ -170,6 +181,16 @@ void cmain (unsigned long magic, multibo
  10.121             XEN_COMPILE_BY, XEN_COMPILE_DOMAIN,
  10.122             XEN_COMPILER, XEN_COMPILE_DATE);
  10.123  
  10.124 +    if ( opt_ser_baud != 0 )
  10.125 +        printk("**WARNING**: Xen option 'ser_baud=' is deprecated! "
  10.126 +               "Use 'com1=' instead.\n");
  10.127 +
  10.128 +    if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
  10.129 +    {
  10.130 +        printk("FATAL ERROR: Invalid magic number: 0x%08lx\n", magic);
  10.131 +        for ( ; ; ) ;
  10.132 +    }
  10.133 +
  10.134      /* We require memory and module information. */
  10.135      if ( (mbi->flags & 9) != 9 )
  10.136      {
  10.137 @@ -245,60 +266,20 @@ void cmain (unsigned long magic, multibo
  10.138  }
  10.139  
  10.140  
  10.141 -#define SERIAL_BASE 0x3f8
  10.142 -#define RX_BUF      0
  10.143 -#define TX_HOLD     0
  10.144 -#define INT_ENABLE  1
  10.145 -#define INT_IDENT   2
  10.146 -#define DATA_FORMAT 3
  10.147 -#define LINE_CTL    4
  10.148 -#define LINE_STATUS 5
  10.149 -#define LINE_IN     6
  10.150 -#define DIVISOR_LO  0
  10.151 -#define DIVISOR_HI  1
  10.152 -
  10.153 -void init_serial(void)
  10.154 -{
  10.155 -    if ( !SERIAL_ENABLED )
  10.156 -        return;
  10.157 -
  10.158 -    /* 'opt_ser_baud' baud, no parity, 1 stop bit, 8 data bits. */
  10.159 -    outb(0x83, SERIAL_BASE+DATA_FORMAT);
  10.160 -    outb(115200/opt_ser_baud, SERIAL_BASE+DIVISOR_LO);
  10.161 -    outb(0, SERIAL_BASE+DIVISOR_HI);
  10.162 -    outb(0x03, SERIAL_BASE+DATA_FORMAT);
  10.163 -    
  10.164 -    /* DTR and RTS should both be high, to keep other end happy. */
  10.165 -    outb(0x02, SERIAL_BASE+LINE_CTL);
  10.166 -
  10.167 -    /* No interrupts. */
  10.168 -    outb(0x00, SERIAL_BASE+INT_ENABLE);
  10.169 -}
  10.170 -
  10.171 -
  10.172 -#ifdef CONFIG_OUTPUT_SERIAL
  10.173 -void putchar_serial(unsigned char c)
  10.174 -{
  10.175 -    if ( !SERIAL_ENABLED )
  10.176 -        return;
  10.177 -    if ( c == '\n' ) putchar_serial('\r');
  10.178 -    while ( !(inb(SERIAL_BASE+LINE_STATUS)&(1<<5)) ) barrier();
  10.179 -    outb(c, SERIAL_BASE+TX_HOLD);
  10.180 -}
  10.181 -#else
  10.182 -void putchar_serial(unsigned char c) {}
  10.183 -#endif
  10.184 -
  10.185 -
  10.186 -#ifdef CONFIG_OUTPUT_CONSOLE
  10.187 -
  10.188  /* VGA text (mode 3) definitions. */
  10.189  #define COLUMNS	    80
  10.190  #define LINES	    25
  10.191  #define ATTRIBUTE    7
  10.192 -#define VIDEO	    __va(0xB8000)
  10.193  
  10.194 -int detect_video(void *video_base)
  10.195 +/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
  10.196 +static void cls(void)
  10.197 +{
  10.198 +    memset(video, 0, COLUMNS * LINES * 2);
  10.199 +    xpos = ypos = 0;
  10.200 +    outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
  10.201 +}
  10.202 +
  10.203 +static int detect_video(void *video_base)
  10.204  {
  10.205      volatile u16 *p = (volatile u16 *)video_base;
  10.206      u16 saved1 = p[0], saved2 = p[1];
  10.207 @@ -320,7 +301,7 @@ int detect_video(void *video_base)
  10.208      return video_found;
  10.209  }
  10.210  
  10.211 -int detect_vga(void)
  10.212 +static int detect_vga(void)
  10.213  {
  10.214      /*
  10.215       * Look at a number of well-known locations. Even if video is not at
  10.216 @@ -337,7 +318,7 @@ int detect_vga(void)
  10.217  }
  10.218  
  10.219  /* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
  10.220 -void init_vga(void)
  10.221 +static void init_vga(void)
  10.222  {
  10.223      /* The following VGA state was saved from a chip in text mode 3. */
  10.224      static unsigned char regs[] = {
  10.225 @@ -357,13 +338,13 @@ void init_vga(void)
  10.226      int i, j = 0;
  10.227      volatile unsigned char tmp;
  10.228  
  10.229 -    if ( !opt_console )
  10.230 +    if ( !vgacon_enabled )
  10.231          return;
  10.232  
  10.233      if ( !detect_vga() )
  10.234      {
  10.235          printk("No VGA adaptor detected!\n");
  10.236 -        opt_console = 0;
  10.237 +        vgacon_enabled = 0;
  10.238          return;
  10.239      }
  10.240  
  10.241 @@ -391,26 +372,8 @@ void init_vga(void)
  10.242      
  10.243      tmp = inb(0x3da);
  10.244      outb(0x20, 0x3c0);
  10.245 -}
  10.246  
  10.247 -
  10.248 -/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
  10.249 -void cls(void)
  10.250 -{
  10.251 -    int i;
  10.252 -
  10.253 -    if ( !opt_console )
  10.254 -        return;
  10.255 -
  10.256 -    video = (unsigned char *) VIDEO;
  10.257 -    
  10.258 -    for (i = 0; i < COLUMNS * LINES * 2; i++)
  10.259 -        *(video + i) = 0;
  10.260 -    
  10.261 -    xpos = 0;
  10.262 -    ypos = 0;
  10.263 -    
  10.264 -    outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
  10.265 +    cls();
  10.266  }
  10.267  
  10.268  
  10.269 @@ -431,9 +394,9 @@ static void put_newline(void)
  10.270  }
  10.271  
  10.272  
  10.273 -void putchar_console(int c)
  10.274 +static void putchar_console(int c)
  10.275  {
  10.276 -    if ( !opt_console )
  10.277 +    if ( !vgacon_enabled )
  10.278          return;
  10.279  
  10.280      if ( c == '\n' )
  10.281 @@ -442,54 +405,34 @@ void putchar_console(int c)
  10.282      }
  10.283      else
  10.284      {
  10.285 -        *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
  10.286 -        *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
  10.287 -        
  10.288 -        xpos++;
  10.289 -        if (xpos >= COLUMNS)
  10.290 +        video[(xpos + ypos * COLUMNS) * 2]     = c & 0xFF;
  10.291 +        video[(xpos + ypos * COLUMNS) * 2 + 1] = ATTRIBUTE;
  10.292 +        if ( ++xpos >= COLUMNS )
  10.293              put_newline();
  10.294      }
  10.295  }
  10.296  
  10.297 -#else
  10.298 -
  10.299 -void init_vga(void) {}
  10.300 -void cls(void) {}
  10.301 -void putchar_console(int c) {}
  10.302 -
  10.303 -#endif
  10.304 -
  10.305 -#ifdef CONFIG_OUTPUT_CONSOLE_RING
  10.306  
  10.307  void putchar_console_ring(int c)
  10.308  {
  10.309 -    if (console_ring.len < CONSOLE_RING_SIZE)
  10.310 +    if ( console_ring.len < CONSOLE_RING_SIZE )
  10.311          console_ring.buf[console_ring.len++] = (char)c;
  10.312  }
  10.313  
  10.314 -#else
  10.315 -
  10.316 -void putchar_console_ring(int c) {}
  10.317 -
  10.318 -#endif
  10.319 -
  10.320 -
  10.321 -static void putchar(int c)
  10.322 -{
  10.323 -    if ( (c != '\n') && ((c < 32) || (c > 126)) ) return;
  10.324 -    putchar_serial(c);
  10.325 -    putchar_console(c);
  10.326 -    putchar_console_ring(c);
  10.327 -}
  10.328 -
  10.329  
  10.330  static inline void __putstr(const char *str)
  10.331  {
  10.332 -    while ( *str ) putchar(*str++);
  10.333 +    int c;
  10.334 +    serial_puts(sercon_handle, str);
  10.335 +    while ( (c = *str++) != '\0' )
  10.336 +    {
  10.337 +        putchar_console(c);
  10.338 +        putchar_console_ring(c);
  10.339 +    }
  10.340  }
  10.341  
  10.342  
  10.343 -void printf (const char *fmt, ...)
  10.344 +void printf(const char *fmt, ...)
  10.345  {
  10.346      va_list args;
  10.347      char buf[128];
  10.348 @@ -510,7 +453,7 @@ void printf (const char *fmt, ...)
  10.349      }
  10.350  
  10.351      spin_lock_irqsave(&console_lock, flags);
  10.352 -    while ( *p ) putchar(*p++);
  10.353 +    __putstr(p);
  10.354      spin_unlock_irqrestore(&console_lock, flags);
  10.355  }
  10.356  
  10.357 @@ -633,11 +576,12 @@ long do_console_write(char *str, unsigne
  10.358  {
  10.359  #define SIZEOF_BUF 256
  10.360      unsigned char safe_str[SIZEOF_BUF+1];
  10.361 -    unsigned char exported_str[SIZEOF_BUF+2];
  10.362 -    unsigned char dom_id[5];
  10.363 +    unsigned char single_line[SIZEOF_BUF+2];
  10.364 +    unsigned char line_header[30];
  10.365      unsigned char *p;
  10.366 +    unsigned char  c;
  10.367      unsigned long flags;
  10.368 -    int j;
  10.369 +    int            j;
  10.370      
  10.371      if ( count == 0 )
  10.372          return 0;
  10.373 @@ -649,38 +593,32 @@ long do_console_write(char *str, unsigne
  10.374          return -EFAULT;
  10.375      safe_str[count] = '\0';
  10.376      
  10.377 +    sprintf(line_header, "DOM%llu: ", current->domain);
  10.378 +    
  10.379      p = safe_str;
  10.380      while ( *p != '\0' )
  10.381      {
  10.382          j = 0;
  10.383  
  10.384 -        spin_lock_irqsave(&console_lock, flags);
  10.385 -        
  10.386 -        __putstr("DOM"); 
  10.387 -        sprintf(dom_id, "%llu", current->domain);
  10.388 -        __putstr(dom_id);
  10.389 -        __putstr(": ");
  10.390 -        
  10.391 -        while ( (*p != '\0') && (*p != '\n') )
  10.392 +        while ( (c = *p++) != '\0' )
  10.393          {
  10.394 -            exported_str[j++] = *p;
  10.395 -            putchar(*p);
  10.396 -            p++;
  10.397 +            if ( c == '\n' )
  10.398 +                break;
  10.399 +            if ( (c < 32) || (c > 126) )
  10.400 +                continue;
  10.401 +            single_line[j++] = c;
  10.402          }
  10.403  
  10.404 -        if ( *p == '\n' )
  10.405 -            p++;
  10.406 +        single_line[j++] = '\n';
  10.407 +        single_line[j++] = '\0';
  10.408  
  10.409 -        putchar('\n');
  10.410 -        
  10.411 +        spin_lock_irqsave(&console_lock, flags);
  10.412 +        __putstr(line_header);
  10.413 +        __putstr(single_line);
  10.414          spin_unlock_irqrestore(&console_lock, flags);
  10.415  
  10.416          if ( current->domain != 0 )
  10.417 -        {
  10.418 -            exported_str[j++] = '\n';
  10.419 -            exported_str[j++] = '\0';
  10.420 -            console_export(exported_str, j);
  10.421 -        }
  10.422 +            console_export(single_line, j);
  10.423      }
  10.424  
  10.425      return 0;
    11.1 --- a/xen/common/keyhandler.c	Fri Feb 20 16:13:18 2004 +0000
    11.2 +++ b/xen/common/keyhandler.c	Mon Feb 23 13:57:02 2004 +0000
    11.3 @@ -2,6 +2,8 @@
    11.4  #include <xeno/keyhandler.h> 
    11.5  #include <xeno/reboot.h>
    11.6  #include <xeno/event.h>
    11.7 +#include <xeno/console.h>
    11.8 +#include <xeno/serial.h>
    11.9  
   11.10  #define KEY_MAX 256
   11.11  #define STR_MAX  64
   11.12 @@ -18,21 +20,21 @@ void add_key_handler(u_char key, key_han
   11.13      int i; 
   11.14      char *str; 
   11.15  
   11.16 -    if(key_table[key].handler != NULL) 
   11.17 +    if ( key_table[key].handler != NULL ) 
   11.18  	printk("Warning: overwriting handler for key 0x%x\n", key); 
   11.19  
   11.20      key_table[key].handler = handler; 
   11.21  
   11.22      str = key_table[key].desc; 
   11.23 -    for(i = 0; i < STR_MAX; i++) {
   11.24 -	if(*desc) 
   11.25 +    for ( i = 0; i < STR_MAX; i++ )
   11.26 +    {
   11.27 +	if ( *desc != '\0' ) 
   11.28  	    *str++ = *desc++; 
   11.29 -	else break; 
   11.30 +	else
   11.31 +            break; 
   11.32      }
   11.33 -    if (i == STR_MAX) 
   11.34 +    if ( i == STR_MAX ) 
   11.35  	key_table[key].desc[STR_MAX-1] = '\0'; 
   11.36 -
   11.37 -    return; 
   11.38  }
   11.39  
   11.40  key_handler *get_key_handler(u_char key)
   11.41 @@ -40,42 +42,43 @@ key_handler *get_key_handler(u_char key)
   11.42      return key_table[key].handler; 
   11.43  }
   11.44  
   11.45 +static void serial_rx(unsigned char c, struct pt_regs *regs)
   11.46 +{
   11.47 +    key_handler *handler;
   11.48 +    if ( (handler = get_key_handler(c)) != NULL )
   11.49 +        (*handler)(c, NULL, regs);
   11.50 +}
   11.51  
   11.52  static void show_handlers(u_char key, void *dev_id, struct pt_regs *regs) 
   11.53  {
   11.54      int i; 
   11.55  
   11.56      printk("'%c' pressed -> showing installed handlers\n", key); 
   11.57 -    for(i=0; i < KEY_MAX; i++) 
   11.58 -	if(key_table[i].handler) 
   11.59 +    for ( i = 0; i < KEY_MAX; i++ ) 
   11.60 +	if ( key_table[i].handler != NULL ) 
   11.61  	    printk(" key '%c' (ascii '%02x') => %s\n", 
   11.62  			(i<33 || i>126)?(' '):(i),i,
   11.63  			key_table[i].desc);
   11.64 -    return; 
   11.65  }
   11.66  
   11.67  
   11.68  static void dump_registers(u_char key, void *dev_id, struct pt_regs *regs) 
   11.69  {
   11.70      extern void show_registers(struct pt_regs *regs); 
   11.71 -
   11.72      printk("'%c' pressed -> dumping registers\n", key); 
   11.73      show_registers(regs); 
   11.74 -    return; 
   11.75  }
   11.76  
   11.77  static void halt_machine(u_char key, void *dev_id, struct pt_regs *regs) 
   11.78  {
   11.79      printk("'%c' pressed -> rebooting machine\n", key); 
   11.80      machine_restart(NULL); 
   11.81 -    return; 
   11.82  }
   11.83  
   11.84  static void kill_dom0(u_char key, void *dev_id, struct pt_regs *regs) 
   11.85  {
   11.86      printk("'%c' pressed -> gracefully rebooting machine\n", key); 
   11.87      kill_other_domain(0, 0);
   11.88 -    return;
   11.89  }
   11.90  
   11.91  
   11.92 @@ -137,12 +140,12 @@ void audit_all_pages(u_char key, void *d
   11.93  #endif
   11.94  
   11.95  
   11.96 -void initialize_keytable() 
   11.97 +void initialize_keytable(void)
   11.98  {
   11.99      int i; 
  11.100  
  11.101      /* first initialize key handler table */
  11.102 -    for(i = 0; i < KEY_MAX; i++) 
  11.103 +    for ( i = 0; i < KEY_MAX; i++ ) 
  11.104  	key_table[i].handler = (key_handler *)NULL; 
  11.105  	
  11.106      /* setup own handlers */
  11.107 @@ -160,4 +163,6 @@ void initialize_keytable()
  11.108      add_key_handler('m', reaudit_pages, "re-audit pages");
  11.109      add_key_handler('M', audit_all_pages, "audit all pages");
  11.110  #endif
  11.111 +
  11.112 +    serial_set_rx_handler(sercon_handle, serial_rx);
  11.113  }
    12.1 --- a/xen/common/memory.c	Fri Feb 20 16:13:18 2004 +0000
    12.2 +++ b/xen/common/memory.c	Mon Feb 23 13:57:02 2004 +0000
    12.3 @@ -140,9 +140,9 @@
    12.4  #include <asm/domain_page.h>
    12.5  
    12.6  #ifndef NDEBUG
    12.7 -#define MEM_LOG(_f, _a...)                           \
    12.8 +#define MEM_LOG(_f, _a...)                             \
    12.9    printk("DOM%llu: (file=memory.c, line=%d) " _f "\n", \
   12.10 -         current->domain, __LINE__, ## _a )
   12.11 +         current->domain , __LINE__ , ## _a )
   12.12  #else
   12.13  #define MEM_LOG(_f, _a...) ((void)0)
   12.14  #endif
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xen/drivers/char/serial.c	Mon Feb 23 13:57:02 2004 +0000
    13.3 @@ -0,0 +1,398 @@
    13.4 +/******************************************************************************
    13.5 + * serial.c
    13.6 + * 
    13.7 + * Driver for 16550-series UARTs. This driver is to be kept within Xen as
    13.8 + * it permits debugging of seriously-toasted machines (e.g., in situations
    13.9 + * where a device driver within a guest OS would be inaccessible).
   13.10 + * 
   13.11 + * Copyright (c) 2003-2004, K A Fraser
   13.12 + */
   13.13 +
   13.14 +#include <asm-i386/io.h>
   13.15 +#include <xeno/sched.h>
   13.16 +#include <xeno/keyhandler.h> 
   13.17 +#include <xeno/reboot.h>
   13.18 +#include <xeno/irq.h>
   13.19 +#include <xeno/serial.h>
   13.20 +#include <asm/pdb.h>
   13.21 +
   13.22 +/* Register offsets */
   13.23 +#define RBR             0x00    /* receive buffer       */
   13.24 +#define THR             0x00    /* transmit holding     */
   13.25 +#define IER             0x01    /* interrupt enable     */
   13.26 +#define IIR             0x02    /* interrupt identity   */
   13.27 +#define FCR             0x02    /* FIFO control         */
   13.28 +#define LCR             0x03    /* line control         */
   13.29 +#define MCR             0x04    /* Modem control        */
   13.30 +#define LSR             0x05    /* line status          */
   13.31 +#define MSR             0x06    /* Modem status         */
   13.32 +#define DLL             0x00    /* divisor latch (ls) ( DLAB=1)	*/
   13.33 +#define DLM             0x01    /* divisor latch (ms) ( DLAB=1)	*/
   13.34 +
   13.35 +/* Interrupt Enable Register */
   13.36 +#define IER_ERDAI       0x01    /* rx data recv'd       */
   13.37 +#define IER_ETHREI      0x02    /* tx reg. empty        */
   13.38 +#define IER_ELSI        0x04    /* rx line status       */
   13.39 +#define IER_EMSI        0x08    /* MODEM status	        */
   13.40 +
   13.41 +/* FIFO control register */
   13.42 +#define FCR_ENABLE      0x01    /* enable FIFO          */
   13.43 +#define FCR_CLRX        0x02    /* clear Rx FIFO        */
   13.44 +#define FCR_CLTX        0x04    /* clear Tx FIFO        */
   13.45 +#define FCR_DMA         0x10    /* enter DMA mode       */
   13.46 +#define FCR_TRG1        0x00    /* Rx FIFO trig lev 1   */
   13.47 +#define FCR_TRG4        0x40    /* Rx FIFO trig lev 4   */
   13.48 +#define FCR_TRG8        0x80    /* Rx FIFO trig lev 8   */
   13.49 +#define FCR_TRG14       0xc0    /* Rx FIFO trig lev 14  */
   13.50 +
   13.51 +/* Line control register */
   13.52 +#define LCR_DLAB        0x80    /* Divisor Latch Access */
   13.53 +
   13.54 +/* Modem Control Register */
   13.55 +#define MCR_DTR         0x01    /* Data Terminal Ready  */
   13.56 +#define MCR_RTS         0x02    /* Request to Send      */
   13.57 +#define MCR_OUT2        0x08    /* OUT2: interrupt mask */
   13.58 +
   13.59 +/* Line Status Register */
   13.60 +#define LSR_DR          0x01    /* Data ready           */
   13.61 +#define LSR_OE          0x02    /* Overrun              */
   13.62 +#define LSR_PE          0x04    /* Parity error         */
   13.63 +#define LSR_FE          0x08    /* Framing error        */
   13.64 +#define LSR_BI          0x10    /* Break                */
   13.65 +#define LSR_THRE        0x20    /* Xmit hold reg empty  */
   13.66 +#define LSR_TEMT        0x40    /* Xmitter empty        */
   13.67 +#define LSR_ERR         0x80    /* Error                */
   13.68 +
   13.69 +/* These parity settings can be ORed directly into the LCR. */
   13.70 +#define PARITY_NONE     (0<<3)
   13.71 +#define PARITY_ODD      (1<<3)
   13.72 +#define PARITY_EVEN     (3<<3)
   13.73 +#define PARITY_MARK     (5<<3)
   13.74 +#define PARITY_SPACE    (7<<3)
   13.75 +
   13.76 +typedef struct {
   13.77 +    int          baud, data_bits, parity, stop_bits, io_base, irq;
   13.78 +    serial_rx_fn rx_lo, rx_hi, rx;
   13.79 +    spinlock_t   lock;
   13.80 +} uart_t;
   13.81 +
   13.82 +static uart_t com[2] = {
   13.83 +    { 0, 0, 0, 0, 0x3f8, 4,
   13.84 +      NULL, NULL, NULL,
   13.85 +      SPIN_LOCK_UNLOCKED },
   13.86 +    { 0, 0, 0, 0, 0x2f8, 3,
   13.87 +      NULL, NULL, NULL,
   13.88 +      SPIN_LOCK_UNLOCKED }
   13.89 +};
   13.90 +
   13.91 +#define UART_ENABLED(_u) ((_u)->baud != 0)
   13.92 +#define DISABLE_UART(_u) ((_u)->baud = 0)
   13.93 +
   13.94 +
   13.95 +/***********************
   13.96 + * PRIVATE FUNCTIONS
   13.97 + */
   13.98 +
   13.99 +static void uart_rx(uart_t *uart, struct pt_regs *regs)
  13.100 +{
  13.101 +    unsigned char c;
  13.102 +
  13.103 +    if ( !UART_ENABLED(uart) )
  13.104 +        return;
  13.105 +
  13.106 +    /*
  13.107 +     * No need for the uart spinlock here. Only the uart's own interrupt
  13.108 +     * handler will read from the RBR and the handler isn't reentrant.
  13.109 +     */
  13.110 +    while ( inb(uart->io_base + LSR) & LSR_DR )
  13.111 +    {
  13.112 +        c = inb(uart->io_base + RBR);
  13.113 +        if ( uart->rx != NULL )
  13.114 +            uart->rx(c, regs);
  13.115 +        else if ( (c & 0x80) && (uart->rx_hi != NULL) )
  13.116 +            uart->rx_hi(c&0x7f, regs);
  13.117 +        else if ( !(c & 0x80) && (uart->rx_lo != NULL) )
  13.118 +            uart->rx_lo(c&0x7f, regs);
  13.119 +    }
  13.120 +}
  13.121 +
  13.122 +static void serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  13.123 +{
  13.124 +    uart_rx((uart_t *)dev_id, regs);
  13.125 +}
  13.126 +
  13.127 +static inline void __serial_putc(uart_t *uart, int handle, unsigned char c)
  13.128 +{
  13.129 +    if ( (c == '\n') && (handle & SERHND_COOKED) )
  13.130 +        __serial_putc(uart, handle, '\r');
  13.131 +
  13.132 +    if ( handle & SERHND_HI )
  13.133 +        c |= 0x80;
  13.134 +    else if ( handle & SERHND_LO )
  13.135 +        c &= ~0x7f;
  13.136 +
  13.137 +    while ( !(inb(uart->io_base + LSR) & LSR_THRE) )
  13.138 +        barrier();
  13.139 +
  13.140 +    outb(c, uart->io_base + THR);
  13.141 +}
  13.142 +
  13.143 +#define PARSE_ERR(_f, _a...)                 \
  13.144 +    do {                                     \
  13.145 +        printk( "ERROR: " _f "\n" , ## _a ); \
  13.146 +        DISABLE_UART(uart);                  \
  13.147 +        return;                              \
  13.148 +} while ( 0 )
  13.149 +        
  13.150 +static void parse_port_config(char *conf, uart_t *uart)
  13.151 +{
  13.152 +    if ( *conf == '\0' )
  13.153 +        return;
  13.154 +
  13.155 +    uart->baud = simple_strtol(conf, &conf, 10);
  13.156 +    if ( (uart->baud < 1200) || (uart->baud > 115200) )
  13.157 +        PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
  13.158 +
  13.159 +    if ( *conf != ',' )
  13.160 +        PARSE_ERR("Missing data/parity/stop specifiers.");
  13.161 +
  13.162 +    conf++;
  13.163 +
  13.164 +    uart->data_bits = simple_strtol(conf, &conf, 10);
  13.165 +    if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
  13.166 +        PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
  13.167 +
  13.168 +    switch ( *conf )
  13.169 +    {
  13.170 +    case 'n':
  13.171 +        uart->parity = PARITY_NONE;
  13.172 +        break;
  13.173 +    case 'o': 
  13.174 +        uart->parity =  PARITY_ODD;
  13.175 +        break;
  13.176 +    case 'e': 
  13.177 +        uart->parity =  PARITY_EVEN;
  13.178 +        break;
  13.179 +    case 'm': 
  13.180 +        uart->parity =  PARITY_MARK;
  13.181 +        break;
  13.182 +    case 's': 
  13.183 +        uart->parity =  PARITY_SPACE;
  13.184 +        break;
  13.185 +
  13.186 +    default:
  13.187 +        PARSE_ERR("Invalid parity specifier '%c'.", *conf);
  13.188 +    }
  13.189 +
  13.190 +    conf++;
  13.191 +
  13.192 +    uart->stop_bits = simple_strtol(conf, &conf, 10);
  13.193 +    if ( (uart->stop_bits < 1) || (uart->stop_bits > 2) )
  13.194 +        PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
  13.195 +
  13.196 +    if ( *conf == ',' )
  13.197 +    {
  13.198 +        conf++;
  13.199 +
  13.200 +        uart->io_base = simple_strtol(conf, &conf, 0);
  13.201 +        if ( (uart->io_base <= 0x0000) || (uart->io_base > 0xfff0) )
  13.202 +            PARSE_ERR("I/O port base 0x%x is outside the supported range.",
  13.203 +                      uart->io_base);
  13.204 +
  13.205 +        if ( *conf != ',' )
  13.206 +            PARSE_ERR("Missing IRQ specifier.");
  13.207 +            
  13.208 +        conf++;
  13.209 +            
  13.210 +        uart->irq = simple_strtol(conf, &conf, 10);
  13.211 +        if ( (uart->irq <= 0) || (uart->irq >= 32) )
  13.212 +            PARSE_ERR("IRQ %d is outside the supported range.", uart->irq);
  13.213 +    }
  13.214 +}
  13.215 +
  13.216 +static void uart_config_stage1(uart_t *uart)
  13.217 +{
  13.218 +    unsigned char lcr;
  13.219 +
  13.220 +    if ( !UART_ENABLED(uart) )
  13.221 +        return;
  13.222 +
  13.223 +    lcr = (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | uart->parity;
  13.224 +
  13.225 +    /* No interrupts. */
  13.226 +    outb(0, uart->io_base + IER);
  13.227 +
  13.228 +    /* Line control and baud-rate generator. */
  13.229 +    outb(lcr | LCR_DLAB,    uart->io_base + LCR);
  13.230 +    outb(115200/uart->baud, uart->io_base + DLL); /* baud lo */
  13.231 +    outb(0,                 uart->io_base + DLM); /* baud hi */
  13.232 +    outb(lcr,               uart->io_base + LCR); /* parity, data, stop */
  13.233 +
  13.234 +    /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */
  13.235 +    outb(MCR_DTR | MCR_RTS, uart->io_base + MCR);
  13.236 +
  13.237 +    /* Enable and clear the FIFOs. Set a large trigger threshold. */
  13.238 +    outb(FCR_ENABLE | FCR_CLRX | FCR_CLTX | FCR_TRG14, uart->io_base + FCR);
  13.239 +}
  13.240 +
  13.241 +static void uart_config_stage2(uart_t *uart)
  13.242 +{
  13.243 +    int rc;
  13.244 +
  13.245 +    if ( !UART_ENABLED(uart) )
  13.246 +        return;
  13.247 +
  13.248 +    rc = request_irq(uart->irq, 
  13.249 +                     serial_interrupt, 
  13.250 +                     SA_NOPROFILE, 
  13.251 +                     "serial", 
  13.252 +                     uart);
  13.253 +    if ( rc != 0 )
  13.254 +        printk("ERROR: Failed to allocate serial IRQ %d\n", uart->irq);
  13.255 +
  13.256 +    /* For sanity, clear the receive FIFO. */
  13.257 +    outb(FCR_ENABLE | FCR_CLRX | FCR_TRG14, uart->io_base + FCR);
  13.258 +
  13.259 +    /* Master interrupt enable; also keep DTR/RTS asserted. */
  13.260 +    outb(MCR_OUT2 | MCR_DTR | MCR_RTS, uart->io_base + MCR);
  13.261 +
  13.262 +    /* Enable receive interrupts. */
  13.263 +    outb(IER_ERDAI, uart->io_base + IER);
  13.264 +}
  13.265 +
  13.266 +
  13.267 +/***********************
  13.268 + * PUBLIC FUNCTIONS
  13.269 + */
  13.270 +
  13.271 +void serial_init_stage1(void)
  13.272 +{
  13.273 +    extern unsigned char opt_com1[], opt_com2[];
  13.274 +
  13.275 +    parse_port_config(opt_com1, &com[0]);
  13.276 +    parse_port_config(opt_com2, &com[1]);
  13.277 +
  13.278 +    uart_config_stage1(&com[0]);
  13.279 +    uart_config_stage1(&com[1]);
  13.280 +}
  13.281 +
  13.282 +void serial_init_stage2(void)
  13.283 +{
  13.284 +    uart_config_stage2(&com[0]);
  13.285 +    uart_config_stage2(&com[1]);
  13.286 +}
  13.287 +
  13.288 +int parse_serial_handle(char *conf)
  13.289 +{
  13.290 +    int handle;
  13.291 +
  13.292 +    /* Silently fail if user has explicitly requested no serial I/O. */
  13.293 +    if ( strcmp(conf, "none") == 0 )
  13.294 +        return -1;
  13.295 +
  13.296 +    if ( strncmp(conf, "com", 3) != 0 )
  13.297 +        goto fail;
  13.298 +
  13.299 +    switch ( conf[3] )
  13.300 +    {
  13.301 +    case '1':
  13.302 +        handle = 0;
  13.303 +        break;
  13.304 +    case '2':
  13.305 +        handle = 1;
  13.306 +        break;
  13.307 +    default:
  13.308 +        goto fail;
  13.309 +    }
  13.310 +
  13.311 +    if ( !UART_ENABLED(&com[handle]) )
  13.312 +    {
  13.313 +        printk("ERROR: cannot use unconfigured serial port COM%d\n", handle+1);
  13.314 +        return -1;
  13.315 +    }
  13.316 +
  13.317 +    if ( conf[4] == 'H' )
  13.318 +        handle |= SERHND_HI;
  13.319 +    else if ( conf[4] == 'L' )
  13.320 +        handle |= SERHND_LO;
  13.321 +
  13.322 +    handle |= SERHND_COOKED;
  13.323 +
  13.324 +    return handle;
  13.325 +
  13.326 + fail:
  13.327 +    printk("ERROR: bad serial-interface specification '%s'\n", conf);
  13.328 +    return -1;
  13.329 +}
  13.330 +
  13.331 +void serial_set_rx_handler(int handle, serial_rx_fn fn)
  13.332 +{
  13.333 +    uart_t *uart = &com[handle & SERHND_IDX];
  13.334 +    unsigned long flags;
  13.335 +
  13.336 +    if ( handle == -1 )
  13.337 +        return;
  13.338 +
  13.339 +    spin_lock_irqsave(&uart->lock, flags);
  13.340 +
  13.341 +    if ( uart->rx != NULL )
  13.342 +        goto fail;
  13.343 +
  13.344 +    if ( handle & SERHND_LO )
  13.345 +    {
  13.346 +        if ( uart->rx_lo != NULL )
  13.347 +            goto fail;
  13.348 +        uart->rx_lo = fn;        
  13.349 +    }
  13.350 +    else if ( handle & SERHND_HI )
  13.351 +    {
  13.352 +        if ( uart->rx_hi != NULL )
  13.353 +            goto fail;
  13.354 +        uart->rx_hi = fn;
  13.355 +    }
  13.356 +    else
  13.357 +    {
  13.358 +        if ( (uart->rx_hi != NULL) || (uart->rx_lo != NULL) )
  13.359 +            goto fail;
  13.360 +        uart->rx = fn;
  13.361 +    }
  13.362 +
  13.363 +    spin_unlock_irqrestore(&uart->lock, flags);
  13.364 +    return;
  13.365 +
  13.366 + fail:
  13.367 +    spin_unlock_irqrestore(&uart->lock, flags);
  13.368 +    printk("ERROR: Conflicting receive handlers for COM%d\n", 
  13.369 +           handle & SERHND_IDX);
  13.370 +}
  13.371 +
  13.372 +void serial_putc(int handle, unsigned char c)
  13.373 +{
  13.374 +    uart_t *uart = &com[handle & SERHND_IDX];
  13.375 +    unsigned long flags;
  13.376 +
  13.377 +    if ( handle == -1 )
  13.378 +        return;
  13.379 +
  13.380 +    spin_lock_irqsave(&uart->lock, flags);
  13.381 +
  13.382 +    __serial_putc(uart, handle, c);
  13.383 +
  13.384 +    spin_unlock_irqrestore(&uart->lock, flags);
  13.385 +}
  13.386 +
  13.387 +void serial_puts(int handle, const unsigned char *s)
  13.388 +{
  13.389 +    uart_t *uart = &com[handle & SERHND_IDX];
  13.390 +    unsigned long flags;
  13.391 +
  13.392 +    if ( handle == -1 )
  13.393 +        return;
  13.394 +
  13.395 +    spin_lock_irqsave(&uart->lock, flags);
  13.396 +
  13.397 +    while ( *s != '\0' )
  13.398 +        __serial_putc(uart, handle, *s++);
  13.399 +
  13.400 +    spin_unlock_irqrestore(&uart->lock, flags);
  13.401 +}
    14.1 --- a/xen/drivers/char/xen_serial.c	Fri Feb 20 16:13:18 2004 +0000
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,206 +0,0 @@
    14.4 -#include <asm-i386/io.h>
    14.5 -#include <xeno/sched.h>    /* this has request_irq() proto for some reason */
    14.6 -#include <xeno/keyhandler.h> 
    14.7 -#include <xeno/reboot.h>
    14.8 -#include <xeno/irq.h>
    14.9 -#include <asm/pdb.h>
   14.10 -
   14.11 -/* Register offsets */
   14.12 -#define NS16550_RBR	0x00	/* receive buffer	*/
   14.13 -#define NS16550_THR	0x00	/* transmit holding	*/
   14.14 -#define NS16550_IER	0x01	/* interrupt enable	*/
   14.15 -#define NS16550_IIR	0x02	/* interrupt identity	*/
   14.16 -#define NS16550_FCR     0x02    /* FIFO control         */
   14.17 -#define NS16550_LCR	0x03	/* line control		*/
   14.18 -#define NS16550_MCR	0x04	/* MODEM control	*/
   14.19 -#define NS16550_LSR	0x05	/* line status		*/
   14.20 -#define NS16550_MSR	0x06	/* MODEM status		*/
   14.21 -#define NS16550_SCR	0x07	/* scratch		*/
   14.22 -#define NS16550_DDL	0x00	/* divisor latch (ls) ( DLAB=1)	*/
   14.23 -#define NS16550_DLM	0x01	/* divisor latch (ms) ( DLAB=1)	*/
   14.24 -
   14.25 -/* Interrupt enable register */
   14.26 -#define NS16550_IER_ERDAI	0x01	/* rx data recv'd	*/
   14.27 -#define NS16550_IER_ETHREI	0x02	/* tx reg. empty	*/
   14.28 -#define NS16550_IER_ELSI	0x04	/* rx line status	*/
   14.29 -#define NS16550_IER_EMSI	0x08	/* MODEM status		*/
   14.30 -
   14.31 -/* FIFO control register */
   14.32 -#define NS16550_FCR_ENABLE      0x01    /* enable FIFO          */
   14.33 -#define NS16550_FCR_CLRX        0x02    /* clear Rx FIFO        */
   14.34 -#define NS16550_FCR_CLTX        0x04    /* clear Tx FIFO        */
   14.35 -#define NS16550_FCR_DMA         0x10    /* enter DMA mode       */
   14.36 -#define NS16550_FCR_TRG1        0x00    /* Rx FIFO trig lev 1   */
   14.37 -#define NS16550_FCR_TRG4        0x40    /* Rx FIFO trig lev 4   */
   14.38 -#define NS16550_FCR_TRG8        0x80    /* Rx FIFO trig lev 8   */
   14.39 -#define NS16550_FCR_TRG14       0xc0    /* Rx FIFO trig lev 14  */
   14.40 -
   14.41 -/* MODEM control register */
   14.42 -#define NS16550_MCR_DTR 	0x01	/* Data Terminal Ready	*/
   14.43 -#define NS16550_MCR_RTS 	0x02	/* Request to Send	*/
   14.44 -#define NS16550_MCR_OUT1        0x04    /* OUT1: unused         */
   14.45 -#define NS16550_MCR_OUT2        0x08    /* OUT2: interrupt mask */
   14.46 -#define NS16550_MCR_LOOP	0x10	/* Loop			*/
   14.47 -
   14.48 -#define LSR_DR   0x01  /* Data ready */
   14.49 -#define LSR_OE   0x02  /* Overrun */
   14.50 -#define LSR_PE   0x04  /* Parity error */
   14.51 -#define LSR_FE   0x08  /* Framing error */
   14.52 -#define LSR_BI   0x10  /* Break */
   14.53 -#define LSR_THRE 0x20  /* Xmit holding register empty */
   14.54 -#define LSR_TEMT 0x40  /* Xmitter empty */
   14.55 -#define LSR_ERR  0x80  /* Error */
   14.56 -
   14.57 -#define SERIAL_COM1 0x3f8
   14.58 -#define SERIAL_COM2 0x2f8
   14.59 -
   14.60 -void initialize_serial_port(int base);
   14.61 -
   14.62 -int serial_com_base = SERIAL_COM1;
   14.63 -int debug_com_base  = SERIAL_COM1;
   14.64 -
   14.65 -static int serial_echo = 0;       /* default is not to echo; change with '~' */
   14.66 -
   14.67 -void toggle_echo(u_char key, void *dev_id, struct pt_regs *regs) 
   14.68 -{
   14.69 -    serial_echo = !serial_echo; 
   14.70 -}
   14.71 -
   14.72 -void debug_set_com_port(int port)
   14.73 -{
   14.74 -    debug_com_base = port == 1 ? SERIAL_COM1 : SERIAL_COM2;
   14.75 -    if (port == 2) initialize_serial_port(SERIAL_COM2);
   14.76 -}
   14.77 -
   14.78 -int debug_testchar()                                /* character available? */
   14.79 -{
   14.80 -    return (inb(debug_com_base + NS16550_LSR) & LSR_DR);
   14.81 -}
   14.82 -
   14.83 -u_char debug_getchar()
   14.84 -{
   14.85 -    while (! (inb(debug_com_base + NS16550_LSR) & LSR_DR));/* wait for char */
   14.86 -    return inb(debug_com_base + NS16550_RBR);
   14.87 -}
   14.88 -
   14.89 -void debug_putch(u_char c)
   14.90 -{
   14.91 -    while (! (inb(debug_com_base + NS16550_LSR) & LSR_THRE));
   14.92 -                                                            /* wait for idle */
   14.93 -    outb(c, debug_com_base + NS16550_RBR);
   14.94 -}
   14.95 -
   14.96 -void debug_putchar(u_char c)
   14.97 -{
   14.98 -    debug_putch(c);
   14.99 -    if (c == '\n') debug_putch('\r');
  14.100 -}
  14.101 -
  14.102 -
  14.103 -
  14.104 -int serial_testchar()                                /* character available? */
  14.105 -{
  14.106 -    return (inb(serial_com_base + NS16550_LSR) & LSR_DR);
  14.107 -}
  14.108 -
  14.109 -u_char serial_getchar()
  14.110 -{
  14.111 -    while (! (inb(serial_com_base + NS16550_LSR) & LSR_DR));/* wait for char */
  14.112 -    return inb(serial_com_base + NS16550_RBR);
  14.113 -}
  14.114 -
  14.115 -void serial_putch(u_char c)
  14.116 -{
  14.117 -    while (! (inb(serial_com_base + NS16550_LSR) & LSR_THRE));
  14.118 -                                                            /* wait for idle */
  14.119 -    outb(c, serial_com_base + NS16550_RBR);
  14.120 -}
  14.121 -
  14.122 -void serial_putchar(u_char c)
  14.123 -{
  14.124 -    serial_putch(c);
  14.125 -    if ( c == '\n' )
  14.126 -        serial_putch('\r');
  14.127 -}
  14.128 -
  14.129 -static spinlock_t serial_lock;
  14.130 -
  14.131 -static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
  14.132 -{
  14.133 -    u_char c; 
  14.134 -    key_handler *handler; 
  14.135 -    unsigned long flags;
  14.136 -
  14.137 -    spin_lock_irqsave(&serial_lock, flags);
  14.138 -
  14.139 -    while ( serial_testchar() )
  14.140 -    {
  14.141 -        c = serial_getchar();
  14.142 -
  14.143 -	if ( c & 0x80 )
  14.144 -	{
  14.145 -	    pdb_serial_input(c & 0x7f, regs);
  14.146 -	}
  14.147 -	else
  14.148 -	{
  14.149 -	    if ( (handler = get_key_handler(c)) != NULL ) 
  14.150 -  	        (*handler)(c, dev_id, regs); 
  14.151 -
  14.152 -	    if ( serial_echo ) 
  14.153 -	        serial_putch(c);
  14.154 -	}
  14.155 -    }
  14.156 -
  14.157 -    spin_unlock_irqrestore(&serial_lock, flags);
  14.158 -}
  14.159 -
  14.160 -void initialize_serial() 
  14.161 -{
  14.162 -    if ( !SERIAL_ENABLED )
  14.163 -        return;
  14.164 -
  14.165 -    spin_lock_init(&serial_lock);
  14.166 -    
  14.167 -    /* setup key handler */
  14.168 -    add_key_handler('~', toggle_echo, "toggle serial echo");
  14.169 -
  14.170 -    initialize_serial_port(SERIAL_COM1);
  14.171 -}
  14.172 -
  14.173 -/* warning: no protection against duplicate initialization */
  14.174 -void initialize_serial_port(int base)
  14.175 -{    
  14.176 -    int rc; 
  14.177 -
  14.178 -    /* This assumes we have a 16550. It's pretty darned likely really! */
  14.179 -    /* Clear FIFOs, enable, trigger at 1 byte */
  14.180 -    outb(NS16550_FCR_TRG1 | NS16550_FCR_ENABLE |
  14.181 -         NS16550_FCR_CLRX  | NS16550_FCR_CLTX, 
  14.182 -         base + NS16550_FCR);
  14.183 -
  14.184 -    /* Enable receive interrupts. Also remember to keep DTR/RTS asserted. */
  14.185 -    outb(NS16550_MCR_OUT2|NS16550_MCR_DTR|NS16550_MCR_RTS, 
  14.186 -         base + NS16550_MCR);
  14.187 -    outb(NS16550_IER_ERDAI, 
  14.188 -         base + NS16550_IER );
  14.189 -
  14.190 -    switch(base)
  14.191 -    {
  14.192 -    case SERIAL_COM1 :
  14.193 -    {
  14.194 -        if( (rc = request_irq(4, serial_rx_int, SA_NOPROFILE, "serial 1", 0)) )
  14.195 -	  printk("initialize_serial: failed to get IRQ4, rc=%d\n", rc); 
  14.196 -	break;
  14.197 -    }
  14.198 -    case SERIAL_COM2 :
  14.199 -    {
  14.200 -        if( (rc = request_irq(3, serial_rx_int, SA_NOPROFILE, "serial 2", 0)) )
  14.201 -	  printk("initialize_serial: failed to get IRQ3, rc=%d\n", rc); 
  14.202 -	break;
  14.203 -    }
  14.204 -    default :
  14.205 -    {
  14.206 -	  printk("initialize_serial: unknown serial base: 0x%d\n", base); 
  14.207 -    }
  14.208 -    }
  14.209 -}
    15.1 --- a/xen/include/xeno/config.h	Fri Feb 20 16:13:18 2004 +0000
    15.2 +++ b/xen/include/xeno/config.h	Mon Feb 23 13:57:02 2004 +0000
    15.3 @@ -147,7 +147,7 @@
    15.4  
    15.5  #ifndef NDEBUG
    15.6  #define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
    15.7 -                           __FILE__, __LINE__, ## _a)
    15.8 +                           __FILE__ , __LINE__ , ## _a )
    15.9  #define STACK_GUARD
   15.10  #else
   15.11  #define DPRINTK(_f, _a...) ((void)0)
    16.1 --- a/xen/include/xeno/console.h	Fri Feb 20 16:13:18 2004 +0000
    16.2 +++ b/xen/include/xeno/console.h	Mon Feb 23 13:57:02 2004 +0000
    16.3 @@ -14,38 +14,12 @@
    16.4   * who gets the PS/2 keyboard/mouse events
    16.5   */
    16.6  
    16.7 +extern int sercon_handle;
    16.8 +extern int vgacon_enabled;
    16.9 +
   16.10  #define CONSOLE_ISOWNER(p) (p->domain == 0) 
   16.11  #define CONSOLE_OWNER      (find_domain_by_id(0))
   16.12  
   16.13 -
   16.14 -/*
   16.15 - * Xen output redirection (in common/kernel.c)
   16.16 - *
   16.17 - * This is coarsely done right now - 
   16.18 - *  - a boot-time option for console output
   16.19 - *  - a compile-time option for serial output and console output
   16.20 - *
   16.21 - * Really, when starting up a guest os with console privilege, we should:
   16.22 - *  - reset the video to a known state
   16.23 - *  - stop sending characters (clear 'opt_console')
   16.24 - *  - allow the guest os access to the video RAM area and keyboard
   16.25 - * Similarly, when stopping that guest os, we should:
   16.26 - *  - stop allowing the guest os access to video RAM
   16.27 - *  - reset the video to a known state
   16.28 - *  - start sending it console output again (if we so desire)
   16.29 - *
   16.30 - * Resetting the video to a known state has not been explored yet, although
   16.31 - * Xen resets to a VGA text mode at start of day. Also, the notion of
   16.32 - * privileges for guest os's (e.g. console privilege) has not been explored
   16.33 - * yet, so this will do for now.
   16.34 - */
   16.35 -
   16.36 -#define CONFIG_OUTPUT_SERIAL  1
   16.37 -#define CONFIG_OUTPUT_CONSOLE 1
   16.38 -#define CONFIG_OUTPUT_CONSOLE_RING 1
   16.39 -
   16.40 -extern int opt_console;
   16.41 -
   16.42  #define CONSOLE_RING_SIZE	16392
   16.43  #define CONSOLE_RING_CLEAR	1
   16.44  
    17.1 --- a/xen/include/xeno/lib.h	Fri Feb 20 16:13:18 2004 +0000
    17.2 +++ b/xen/include/xeno/lib.h	Mon Feb 23 13:57:02 2004 +0000
    17.3 @@ -36,7 +36,6 @@ unsigned char *quad_to_str(unsigned long
    17.4  /* kernel.c */
    17.5  #define printk printf
    17.6  void printf (const char *format, ...);
    17.7 -void cls(void);
    17.8  void panic(const char *format, ...);
    17.9  
   17.10  /* vsprintf.c */
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/xen/include/xeno/serial.h	Mon Feb 23 13:57:02 2004 +0000
    18.3 @@ -0,0 +1,39 @@
    18.4 +/******************************************************************************
    18.5 + * serial.h
    18.6 + * 
    18.7 + * Driver for 16550-series UARTs. This driver is to be kept within Xen as
    18.8 + * it permits debugging of seriously-toasted machines (e.g., in situations
    18.9 + * where a device driver within a guest OS would be inaccessible).
   18.10 + * 
   18.11 + * Copyright (c) 2003-2004, K A Fraser
   18.12 + */
   18.13 +
   18.14 +#ifndef __XEN_SERIAL_H__
   18.15 +#define __XEN_SERIAL_H__
   18.16 +
   18.17 +#include <asm/ptrace.h>
   18.18 +
   18.19 +/* 'Serial handles' are comprise the following fields. */
   18.20 +#define SERHND_IDX      (1<<0) /* COM1 or COM2?                           */
   18.21 +#define SERHND_HI       (1<<1) /* Mux/demux each transferred char by MSB. */
   18.22 +#define SERHND_LO       (1<<2) /* Ditto, except that the MSB is cleared.  */
   18.23 +#define SERHND_COOKED   (1<<3) /* Newline/carriage-return translation?    */
   18.24 +
   18.25 +/* Two-stage initialisation (before/after IRQ-subsystem initialisation). */
   18.26 +void serial_init_stage1(void);
   18.27 +void serial_init_stage2(void);
   18.28 +
   18.29 +/* Takes a config string and creates a numeric handle on the COM port. */
   18.30 +int parse_serial_handle(char *conf);
   18.31 +
   18.32 +/* Register a character-receive hook on the specified COM port. */
   18.33 +typedef void (*serial_rx_fn)(unsigned char, struct pt_regs *);
   18.34 +void serial_set_rx_handler(int handle, serial_rx_fn fn);
   18.35 +
   18.36 +/* Transmit a single character via the specified COM port. */
   18.37 +void serial_putc(int handle, unsigned char c);
   18.38 +
   18.39 +/* Transmit a NULL-terminated string via the specified COM port. */
   18.40 +void serial_puts(int handle, const unsigned char *s);
   18.41 +
   18.42 +#endif /* __XEN_SERIAL_H__ */