ia64/xen-unstable

changeset 9312:25003dd43a92

merge
author awilliam@xenbuild.aw
date Fri Mar 17 15:37:28 2006 -0700 (2006-03-17)
parents e04978011d2d 3377e445aa5e
children 815758308556 78b8b0d9acc8
files xen/arch/ia64/xen/xentime.c
line diff
     1.1 --- a/docs/src/interface.tex	Fri Mar 17 14:26:24 2006 -0700
     1.2 +++ b/docs/src/interface.tex	Fri Mar 17 15:37:28 2006 -0700
     1.3 @@ -128,7 +128,7 @@ A list of all hypercalls is given in App
     1.4  \section{Exceptions}
     1.5  
     1.6  A virtual IDT is provided --- a domain can submit a table of trap
     1.7 -handlers to Xen via the {\tt set\_trap\_table()} hypercall.  The
     1.8 +handlers to Xen via the {\bf set\_trap\_table} hypercall.  The
     1.9  exception stack frame presented to a virtual trap handler is identical
    1.10  to its native equivalent.
    1.11  
    1.12 @@ -137,7 +137,7 @@ to its native equivalent.
    1.13  
    1.14  Interrupts are virtualized by mapping them to \emph{event channels},
    1.15  which are delivered asynchronously to the target domain using a callback
    1.16 -supplied via the {\tt set\_callbacks()} hypercall.  A guest OS can map
    1.17 +supplied via the {\bf set\_callbacks} hypercall.  A guest OS can map
    1.18  these events onto its standard interrupt dispatch mechanisms.  Xen is
    1.19  responsible for determining the target domain that will handle each
    1.20  physical interrupt source. For more details on the binding of event
    1.21 @@ -167,7 +167,7 @@ is used for scheduling. The following no
    1.22  
    1.23  \item[Wall clock time.]
    1.24  
    1.25 -  This is the time of day in a Unix-style {\tt struct timeval}
    1.26 +  This is the time of day in a Unix-style {\bf struct timeval}
    1.27    (seconds and microseconds since 1 January 1970, adjusted by leap
    1.28    seconds).  An NTP client hosted by {\it domain 0} can keep this
    1.29    value accurate.
    1.30 @@ -200,8 +200,8 @@ currently executing domain every 10ms.  
    1.31  timer event whenever a domain is scheduled; this allows the guest OS
    1.32  to adjust for the time that has passed while it has been inactive.  In
    1.33  addition, Xen allows each domain to request that they receive a timer
    1.34 -event sent at a specified system time by using the {\tt
    1.35 -  set\_timer\_op()} hypercall.  Guest OSes may use this timer to
    1.36 +event sent at a specified system time by using the {\bf
    1.37 +  set\_timer\_op} hypercall.  Guest OSes may use this timer to
    1.38  implement timeout values when they block.
    1.39  
    1.40  
    1.41 @@ -232,7 +232,7 @@ load-balancing between CPUs.
    1.42  
    1.43  
    1.44  %% More information on the characteristics and use of these schedulers
    1.45 -%% is available in {\tt Sched-HOWTO.txt}.
    1.46 +%% is available in {\bf Sched-HOWTO.txt}.
    1.47  
    1.48  
    1.49  \section{Privileged operations}
    1.50 @@ -354,7 +354,7 @@ page-table page, when the domain is pree
    1.51  uses Xen's explicit page-table update interfaces.
    1.52  
    1.53  Writable pagetable functionality is enabled when the guest requests
    1.54 -it, using a {\tt vm\_assist} hypercall.  Writable pagetables do {\em
    1.55 +it, using a {\bf vm\_assist} hypercall.  Writable pagetables do {\em
    1.56  not} provide full virtualisation of the MMU, so the memory management
    1.57  code of the guest still needs to be aware that it is running on Xen.
    1.58  Since the guest's page tables are used directly, it must translate
    1.59 @@ -400,7 +400,7 @@ The following hypercall is used to speci
    1.60  \end{quote}
    1.61  
    1.62  The LDT is updated via the generic MMU update mechanism (i.e., via the
    1.63 -{\tt mmu\_update()} hypercall.
    1.64 +{\bf mmu\_update} hypercall.
    1.65  
    1.66  \section{Start of Day}
    1.67  
    1.68 @@ -423,8 +423,8 @@ extra functionality to a guest.
    1.69  
    1.70  \hypercall{vm\_assist(unsigned int cmd, unsigned int type)}
    1.71  
    1.72 -The {\tt cmd} parameter describes the action to be taken, whilst the
    1.73 -{\tt type} parameter describes the kind of assist that is being
    1.74 +The {\bf cmd} parameter describes the action to be taken, whilst the
    1.75 +{\bf type} parameter describes the kind of assist that is being
    1.76  referred to.  Available commands are as follows:
    1.77  
    1.78  \begin{description}
    1.79 @@ -453,18 +453,18 @@ between the guest OS and the hypervisor.
    1.80  status, time information and event channel (virtual interrupt) state.
    1.81  The {\bf Start info page} is used to pass build-time information to
    1.82  the guest when it boots and when it is resumed from a suspended state.
    1.83 -This chapter documents the fields included in the {\tt
    1.84 -shared\_info\_t} and {\tt start\_info\_t} structures for use by the
    1.85 +This chapter documents the fields included in the {\bf
    1.86 +shared\_info\_t} and {\bf start\_info\_t} structures for use by the
    1.87  guest OS.
    1.88  
    1.89  \section{Shared info page}
    1.90  
    1.91 -The {\tt shared\_info\_t} is accessed at run time by both Xen and the
    1.92 +The {\bf shared\_info\_t} is accessed at run time by both Xen and the
    1.93  guest OS.  It is used to pass information relating to the
    1.94  virtual CPU and virtual machine state between the OS and the
    1.95  hypervisor.
    1.96  
    1.97 -The structure is declared in {\tt xen/include/public/xen.h}:
    1.98 +The structure is declared in {\bf xen/include/public/xen.h}:
    1.99  
   1.100  \scriptsize
   1.101  \begin{verbatim}
   1.102 @@ -520,7 +520,7 @@ typedef struct shared_info {
   1.103  \normalsize
   1.104  
   1.105  \begin{description}
   1.106 -\item[vcpu\_info] An array of {\tt vcpu\_info\_t} structures, each of
   1.107 +\item[vcpu\_info] An array of {\bf vcpu\_info\_t} structures, each of
   1.108    which holds either runtime information about a virtual CPU, or is
   1.109    ``empty'' if the corresponding VCPU does not exist.
   1.110  \item[evtchn\_pending] Guest-global array, with one bit per event
   1.111 @@ -579,11 +579,11 @@ typedef struct vcpu_info {
   1.112    that there are pending events to be received.
   1.113  \item[evtchn\_upcall\_mask] This is set non-zero to disable all
   1.114    interrupts for this CPU for short periods of time.  If individual
   1.115 -  event channels need to be masked, the {\tt evtchn\_mask} in the {\tt
   1.116 +  event channels need to be masked, the {\bf evtchn\_mask} in the {\bf
   1.117    shared\_info\_t} is used instead.
   1.118  \item[evtchn\_pending\_sel] When an event is delivered to this VCPU, a
   1.119 -  bit is set in this selector to indicate which word of the {\tt
   1.120 -  evtchn\_pending} array in the {\tt shared\_info\_t} contains the
   1.121 +  bit is set in this selector to indicate which word of the {\bf
   1.122 +  evtchn\_pending} array in the {\bf shared\_info\_t} contains the
   1.123    event in question.
   1.124  \item[arch] Architecture-specific VCPU info. On x86 this contains the
   1.125    virtualized CR2 register (page fault linear address) for this VCPU.
   1.126 @@ -634,7 +634,7 @@ extrapolating current time).
   1.127  
   1.128  \subsection{arch\_shared\_info\_t}
   1.129  
   1.130 -On x86, the {\tt arch\_shared\_info\_t} is defined as follows (from
   1.131 +On x86, the {\bf arch\_shared\_info\_t} is defined as follows (from
   1.132  xen/public/arch-x86\_32.h):
   1.133  
   1.134  \scriptsize
   1.135 @@ -656,7 +656,7 @@ typedef struct arch_shared_info {
   1.136  
   1.137  \section{Start info page}
   1.138  
   1.139 -The start info structure is declared as the following (in {\tt
   1.140 +The start info structure is declared as the following (in {\bf
   1.141  xen/include/public/xen.h}):
   1.142  
   1.143  \scriptsize
   1.144 @@ -745,7 +745,7 @@ of certain operations in the guest kerne
   1.145  
   1.146  The event channel operation hypercall is used for all operations on
   1.147  event channels / ports.  Operations are distinguished by the value of
   1.148 -the {\tt cmd} field of the {\tt op} structure.  The possible commands
   1.149 +the {\bf cmd} field of the {\bf op} structure.  The possible commands
   1.150  are described below:
   1.151  
   1.152  \begin{description}
   1.153 @@ -880,12 +880,12 @@ table op hypercall takes three arguments
   1.154  
   1.155  \hypercall{grant\_table\_op(unsigned int cmd, void *uop, unsigned int count)}
   1.156  
   1.157 -{\tt cmd} indicates the grant table operation of interest.  {\tt uop}
   1.158 +{\bf cmd} indicates the grant table operation of interest.  {\bf uop}
   1.159  is a pointer to a structure (or an array of structures) describing the
   1.160 -operation to be performed.  The {\tt count} field describes how many
   1.161 +operation to be performed.  The {\bf count} field describes how many
   1.162  grant table operations are being batched together.
   1.163  
   1.164 -The core logic is situated in {\tt xen/common/grant\_table.c}.  The
   1.165 +The core logic is situated in {\bf xen/common/grant\_table.c}.  The
   1.166  grant table operation hypercall can be used to perform the following
   1.167  actions:
   1.168  
   1.169 @@ -957,9 +957,9 @@ There are three main paths in XenStore:
   1.170  \item[/tool] stores information for the various tools
   1.171  \end{description}
   1.172  
   1.173 -The {\tt /vm} path stores configuration information for a domain.
   1.174 +The {\bf /vm} path stores configuration information for a domain.
   1.175  This information doesn't change and is indexed by the domain's UUID.
   1.176 -A {\tt /vm} entry contains the following information:
   1.177 +A {\bf /vm} entry contains the following information:
   1.178  
   1.179  \begin{description}
   1.180  \item[ssidref] ssid reference for domain
   1.181 @@ -974,7 +974,7 @@ A {\tt /vm} entry contains the following
   1.182  \end{description}
   1.183  
   1.184  
   1.185 -{\tt /vm/$<$uuid$>$/image/}
   1.186 +{\bf /vm/$<$uuid$>$/image/}
   1.187  
   1.188  The image path is only available for Domain-Us and contains:
   1.189  \begin{description}
   1.190 @@ -984,7 +984,7 @@ The image path is only available for Dom
   1.191  \item[ramdisk] path to ramdisk on domain-0
   1.192  \end{description}
   1.193  
   1.194 -{\tt /local}
   1.195 +{\bf /local}
   1.196  
   1.197  The {\tt /local} path currently only contains one directory, {\tt
   1.198  /local/domain} that is indexed by domain id.  It contains the running
   1.199 @@ -993,7 +993,7 @@ during migration, the uuid doesn't chang
   1.200  {\tt /local/domain} directory can be created and populated before
   1.201  finalizing the migration enabling localhost to localhost migration.
   1.202  
   1.203 -{\tt /local/domain/$<$domid$>$}
   1.204 +{\bf /local/domain/$<$domid$>$}
   1.205  
   1.206  This path contains:
   1.207  
   1.208 @@ -1663,10 +1663,10 @@ Register the normal (``event'') and fail
   1.209  event processing. In each case the code segment selector and 
   1.210  address within that segment are provided. The selectors must
   1.211  have RPL 1; in XenLinux we simply use the kernel's CS for both 
   1.212 -{\tt event\_selector} and {\tt failsafe\_selector}.
   1.213 -
   1.214 -The value {\tt event\_address} specifies the address of the guest OSes
   1.215 -event handling and dispatch routine; the {\tt failsafe\_address}
   1.216 +{\bf event\_selector} and {\bf failsafe\_selector}.
   1.217 +
   1.218 +The value {\bf event\_address} specifies the address of the guest OSes
   1.219 +event handling and dispatch routine; the {\bf failsafe\_address}
   1.220  specifies a separate entry point which is used only if a fault occurs
   1.221  when Xen attempts to use the normal callback. 
   1.222  
   1.223 @@ -1692,7 +1692,7 @@ install a `virtual IDT' by using the fol
   1.224  
   1.225  Install one or more entries into the per-domain 
   1.226  trap handler table (essentially a software version of the IDT). 
   1.227 -Each entry in the array pointed to by {\tt table} includes the 
   1.228 +Each entry in the array pointed to by {\bf table} includes the 
   1.229  exception vector number with the corresponding segment selector 
   1.230  and entry point. Most guest OSes can use the same handlers on 
   1.231  Xen as when running on the real hardware.
   1.232 @@ -1718,18 +1718,45 @@ In addition, however, a domain may choos
   1.233  control certain behavior with the following hypercall: 
   1.234  
   1.235  \begin{quote} 
   1.236 -\hypercall{sched\_op(unsigned long op)} 
   1.237 -
   1.238 -Request scheduling operation from hypervisor. The options are: {\it
   1.239 -SCHEDOP\_yield}, {\it SCHEDOP\_block}, and {\it SCHEDOP\_shutdown}.
   1.240 -{\it yield} keeps the calling domain runnable but may cause a
   1.241 -reschedule if other domains are runnable.  {\it block} removes the
   1.242 -calling domain from the run queue and cause is to sleeps until an
   1.243 -event is delivered to it.  {\it shutdown} is used to end the domain's
   1.244 -execution; the caller can additionally specify whether the domain
   1.245 -should reboot, halt or suspend.
   1.246 +\hypercall{sched\_op\_new(int cmd, void *extra\_args)}
   1.247 +
   1.248 +Request scheduling operation from hypervisor. The following
   1.249 +sub-commands are available:
   1.250 +
   1.251 +\begin{description}
   1.252 +\item[SCHEDOP\_yield] voluntarily yields the CPU, but leaves the
   1.253 +caller marked as runnable. No extra arguments are passed to this
   1.254 +command. 
   1.255 +\item[SCHEDOP\_block] removes the calling domain from the run queue
   1.256 +and causes it to sleep until an event is delivered to it. No extra 
   1.257 +arguments are passed to this command. 
   1.258 +\item[SCHEDOP\_shutdown] is used to end the calling domain's
   1.259 +execution. The extra argument is a {\bf sched\_shutdown} structure
   1.260 +which indicates the reason why the domain suspended (e.g., for reboot,
   1.261 +halt, power-off).
   1.262 +\item[SCHEDOP\_poll] allows a VCPU to wait on a set of event channels
   1.263 +with an optional timeout (all of which are specified in the {\bf
   1.264 +sched\_poll} extra argument). The semantics are similar to the UNIX
   1.265 +{\bf poll} system call. The caller must have event-channel upcalls
   1.266 +masked when executing this command.
   1.267 +\end{description}
   1.268  \end{quote} 
   1.269  
   1.270 +{\bf sched\_op\_new}  was not available prior to Xen 3.0.2. Older versions
   1.271 +provide only the following hypercall:
   1.272 +
   1.273 +\begin{quote} 
   1.274 +\hypercall{sched\_op(int cmd, unsigned long extra\_arg)}
   1.275 +
   1.276 +This hypercall supports the following subset of {\bf sched\_op\_new} commands:
   1.277 +
   1.278 +\begin{description}
   1.279 +\item[SCHEDOP\_yield] (extra argument is 0).
   1.280 +\item[SCHEDOP\_block] (extra argument is 0).
   1.281 +\item[SCHEDOP\_shutdown] (extra argument is numeric reason code).
   1.282 +\end{description}
   1.283 +\end{quote}
   1.284 +
   1.285  To aid the implementation of a process scheduler within a guest OS,
   1.286  Xen provides a virtual programmable timer:
   1.287  
   1.288 @@ -1737,12 +1764,11 @@ Xen provides a virtual programmable time
   1.289  \hypercall{set\_timer\_op(uint64\_t timeout)} 
   1.290  
   1.291  Request a timer event to be sent at the specified system time (time 
   1.292 -in nanoseconds since system boot). The hypercall actually passes the 
   1.293 -64-bit timeout value as a pair of 32-bit values. 
   1.294 +in nanoseconds since system boot).
   1.295  
   1.296  \end{quote} 
   1.297  
   1.298 -Note that calling {\tt set\_timer\_op()} prior to {\tt sched\_op} 
   1.299 +Note that calling {\bf set\_timer\_op} prior to {\bf sched\_op} 
   1.300  allows block-with-timeout semantics. 
   1.301  
   1.302  
   1.303 @@ -1757,20 +1783,20 @@ a new page-table base pointer, and more.
   1.304  \begin{quote} 
   1.305  \hypercall{mmu\_update(mmu\_update\_t *req, int count, int *success\_count)} 
   1.306  
   1.307 -Update the page table for the domain; a set of {\tt count} updates are
   1.308 -submitted for processing in a batch, with {\tt success\_count} being 
   1.309 +Update the page table for the domain; a set of {\bf count} updates are
   1.310 +submitted for processing in a batch, with {\bf success\_count} being 
   1.311  updated to report the number of successful updates.  
   1.312  
   1.313 -Each element of {\tt req[]} contains a pointer (address) and value; 
   1.314 +Each element of {\bf req[]} contains a pointer (address) and value; 
   1.315  the least significant 2-bits of the pointer are used to distinguish 
   1.316  the type of update requested as follows:
   1.317  \begin{description} 
   1.318  
   1.319 -\item[\it MMU\_NORMAL\_PT\_UPDATE:] update a page directory entry or
   1.320 +\item[MMU\_NORMAL\_PT\_UPDATE:] update a page directory entry or
   1.321  page table entry to the associated value; Xen will check that the
   1.322  update is safe, as described in Chapter~\ref{c:memory}.
   1.323  
   1.324 -\item[\it MMU\_MACHPHYS\_UPDATE:] update an entry in the
   1.325 +\item[MMU\_MACHPHYS\_UPDATE:] update an entry in the
   1.326    machine-to-physical table. The calling domain must own the machine
   1.327    page in question (or be privileged).
   1.328  \end{description}
   1.329 @@ -1792,9 +1818,9 @@ This is catered for by the following:
   1.330  \hypercall{update\_va\_mapping(unsigned long va, uint64\_t val,
   1.331                           unsigned long flags)}
   1.332  
   1.333 -Update the currently installed PTE that maps virtual address {\tt va}
   1.334 -to new value {\tt val}. As with {\tt mmu\_update()}, Xen checks the
   1.335 -modification  is safe before applying it. The {\tt flags} determine
   1.336 +Update the currently installed PTE that maps virtual address {\bf va}
   1.337 +to new value {\bf val}. As with {\bf mmu\_update}, Xen checks the
   1.338 +modification  is safe before applying it. The {\bf flags} determine
   1.339  which kind of TLB flush, if any, should follow the update. 
   1.340  
   1.341  \end{quote} 
   1.342 @@ -1806,8 +1832,8 @@ the pages of others:
   1.343  \hypercall{update\_va\_mapping(unsigned long va, uint64\_t val,
   1.344                           unsigned long flags, domid\_t domid)}
   1.345  
   1.346 -Identical to {\tt update\_va\_mapping()} save that the pages being
   1.347 -mapped must belong to the domain {\tt domid}. 
   1.348 +Identical to {\bf update\_va\_mapping} save that the pages being
   1.349 +mapped must belong to the domain {\bf domid}. 
   1.350  
   1.351  \end{quote}
   1.352  
   1.353 @@ -1854,17 +1880,17 @@ this is context switched transparently w
   1.354  \begin{quote}
   1.355  \hypercall{set\_gdt(unsigned long *frame\_list, int entries)} 
   1.356  
   1.357 -Install a global descriptor table for a domain; {\tt frame\_list} is
   1.358 +Install a global descriptor table for a domain; {\bf frame\_list} is
   1.359  an array of up to 16 machine page frames within which the GDT resides,
   1.360 -with {\tt entries} being the actual number of descriptor-entry
   1.361 +with {\bf entries} being the actual number of descriptor-entry
   1.362  slots. All page frames must be mapped read-only within the guest's
   1.363  address space, and the table must be large enough to contain Xen's
   1.364 -reserved entries (see {\tt xen/include/public/arch-x86\_32.h}).
   1.365 +reserved entries (see {\bf xen/include/public/arch-x86\_32.h}).
   1.366  
   1.367  \end{quote}
   1.368  
   1.369  Many guest OSes will also wish to install LDTs; this is achieved by
   1.370 -using {\tt mmu\_update()} with an extended command, passing the
   1.371 +using {\bf mmu\_update} with an extended command, passing the
   1.372  linear address of the LDT base along with the number of entries. No
   1.373  special safety checks are required; Xen needs to perform this task
   1.374  simply since {\tt lldt} requires CPL 0.
   1.375 @@ -1876,8 +1902,8 @@ individual segment descriptor in the GDT
   1.376  \begin{quote}
   1.377  \hypercall{update\_descriptor(uint64\_t ma, uint64\_t desc)}
   1.378  
   1.379 -Update the GDT/LDT entry at machine address {\tt ma}; the new
   1.380 -8-byte descriptor is stored in {\tt desc}.
   1.381 +Update the GDT/LDT entry at machine address {\bf ma}; the new
   1.382 +8-byte descriptor is stored in {\bf desc}.
   1.383  Xen performs a number of checks to ensure the descriptor is 
   1.384  valid. 
   1.385  
   1.386 @@ -1897,8 +1923,8 @@ stack pointer:
   1.387  \begin{quote} 
   1.388  \hypercall{stack\_switch(unsigned long ss, unsigned long esp)} 
   1.389  
   1.390 -Request kernel stack switch from hypervisor; {\tt ss} is the new 
   1.391 -stack segment, which {\tt esp} is the new stack pointer. 
   1.392 +Request kernel stack switch from hypervisor; {\bf ss} is the new 
   1.393 +stack segment, which {\bf esp} is the new stack pointer. 
   1.394  
   1.395  \end{quote} 
   1.396  
   1.397 @@ -1939,18 +1965,18 @@ following call:
   1.398  \hypercall{memory\_op(unsigned int op, void *arg)}
   1.399  
   1.400  Increase or decrease current memory allocation (as determined by 
   1.401 -the value of {\tt op}).  The available operations are:
   1.402 +the value of {\bf op}).  The available operations are:
   1.403  
   1.404  \begin{description}
   1.405  \item[XENMEM\_increase\_reservation] Request an increase in machine
   1.406 -  memory allocation; {\tt arg} must point to a {\tt
   1.407 +  memory allocation; {\bf arg} must point to a {\bf
   1.408    xen\_memory\_reservation} structure.
   1.409  \item[XENMEM\_decrease\_reservation] Request a decrease in machine
   1.410 -  memory allocation; {\tt arg} must point to a {\tt
   1.411 +  memory allocation; {\bf arg} must point to a {\bf
   1.412    xen\_memory\_reservation} structure.
   1.413  \item[XENMEM\_maximum\_ram\_page] Request the frame number of the
   1.414 -  highest-addressed frame of machine memory in the system.  {\tt arg}
   1.415 -  must point to an {\tt unsigned long} where this value will be
   1.416 +  highest-addressed frame of machine memory in the system.  {\bf arg}
   1.417 +  must point to an {\bf unsigned long} where this value will be
   1.418    stored.
   1.419  \item[XENMEM\_current\_reservation] Returns current memory reservation
   1.420    of the specified domain.
   1.421 @@ -1982,31 +2008,31 @@ The control and use of event channels in
   1.422  \begin{quote}
   1.423  \hypercall{event\_channel\_op(evtchn\_op\_t *op)} 
   1.424  
   1.425 -Inter-domain event-channel management; {\tt op} is a discriminated 
   1.426 +Inter-domain event-channel management; {\bf op} is a discriminated 
   1.427  union which allows the following 7 operations: 
   1.428  
   1.429  \begin{description} 
   1.430  
   1.431 -\item[\it alloc\_unbound:] allocate a free (unbound) local
   1.432 +\item[alloc\_unbound:] allocate a free (unbound) local
   1.433    port and prepare for connection from a specified domain. 
   1.434 -\item[\it bind\_virq:] bind a local port to a virtual 
   1.435 +\item[bind\_virq:] bind a local port to a virtual 
   1.436  IRQ; any particular VIRQ can be bound to at most one port per domain. 
   1.437 -\item[\it bind\_pirq:] bind a local port to a physical IRQ;
   1.438 +\item[bind\_pirq:] bind a local port to a physical IRQ;
   1.439  once more, a given pIRQ can be bound to at most one port per
   1.440  domain. Furthermore the calling domain must be sufficiently
   1.441  privileged.
   1.442 -\item[\it bind\_interdomain:] construct an interdomain event 
   1.443 +\item[bind\_interdomain:] construct an interdomain event 
   1.444  channel; in general, the target domain must have previously allocated 
   1.445  an unbound port for this channel, although this can be bypassed by 
   1.446  privileged domains during domain setup. 
   1.447 -\item[\it close:] close an interdomain event channel. 
   1.448 -\item[\it send:] send an event to the remote end of a 
   1.449 +\item[close:] close an interdomain event channel. 
   1.450 +\item[send:] send an event to the remote end of a 
   1.451  interdomain event channel. 
   1.452 -\item[\it status:] determine the current status of a local port. 
   1.453 +\item[status:] determine the current status of a local port. 
   1.454  \end{description} 
   1.455  
   1.456  For more details see
   1.457 -{\tt xen/include/public/event\_channel.h}. 
   1.458 +{\bf xen/include/public/event\_channel.h}. 
   1.459  
   1.460  \end{quote} 
   1.461  
   1.462 @@ -2018,7 +2044,7 @@ high-performance inter-domain communicat
   1.463  
   1.464  Safe sharing of memory pages between guest OSes is carried out by
   1.465  granting access on a per page basis to individual domains. This is
   1.466 -achieved by using the {\tt grant\_table\_op()} hypercall.
   1.467 +achieved by using the {\tt grant\_table\_op} hypercall.
   1.468  
   1.469  \begin{quote}
   1.470  \hypercall{grant\_table\_op(unsigned int cmd, void *uop, unsigned int count)}
   1.471 @@ -2047,7 +2073,7 @@ TSS IO bitmap.
   1.472  \end{quote} 
   1.473  
   1.474  
   1.475 -For examples of using {\tt physdev\_op()}, see the 
   1.476 +For examples of using {\tt physdev\_op}, see the 
   1.477  Xen-specific PCI code in the linux sparse tree. 
   1.478  
   1.479  \section{Administrative Operations}
   1.480 @@ -2066,81 +2092,81 @@ below: for more details on any or all of
   1.481  Administrative domain operations for domain management. The options are:
   1.482  
   1.483  \begin{description} 
   1.484 -\item [\it DOM0\_GETMEMLIST:] get list of pages used by the domain
   1.485 -
   1.486 -\item [\it DOM0\_SCHEDCTL:]
   1.487 -
   1.488 -\item [\it DOM0\_ADJUSTDOM:] adjust scheduling priorities for domain
   1.489 -
   1.490 -\item [\it DOM0\_CREATEDOMAIN:] create a new domain
   1.491 -
   1.492 -\item [\it DOM0\_DESTROYDOMAIN:] deallocate all resources associated
   1.493 +\item [DOM0\_GETMEMLIST:] get list of pages used by the domain
   1.494 +
   1.495 +\item [DOM0\_SCHEDCTL:]
   1.496 +
   1.497 +\item [DOM0\_ADJUSTDOM:] adjust scheduling priorities for domain
   1.498 +
   1.499 +\item [DOM0\_CREATEDOMAIN:] create a new domain
   1.500 +
   1.501 +\item [DOM0\_DESTROYDOMAIN:] deallocate all resources associated
   1.502  with a domain
   1.503  
   1.504 -\item [\it DOM0\_PAUSEDOMAIN:] remove a domain from the scheduler run 
   1.505 +\item [DOM0\_PAUSEDOMAIN:] remove a domain from the scheduler run 
   1.506  queue. 
   1.507  
   1.508 -\item [\it DOM0\_UNPAUSEDOMAIN:] mark a paused domain as schedulable
   1.509 +\item [DOM0\_UNPAUSEDOMAIN:] mark a paused domain as schedulable
   1.510    once again. 
   1.511  
   1.512 -\item [\it DOM0\_GETDOMAININFO:] get statistics about the domain
   1.513 -
   1.514 -\item [\it DOM0\_SETDOMAININFO:] set VCPU-related attributes
   1.515 -
   1.516 -\item [\it DOM0\_MSR:] read or write model specific registers
   1.517 -
   1.518 -\item [\it DOM0\_DEBUG:] interactively invoke the debugger
   1.519 -
   1.520 -\item [\it DOM0\_SETTIME:] set system time
   1.521 -
   1.522 -\item [\it DOM0\_GETPAGEFRAMEINFO:] 
   1.523 -
   1.524 -\item [\it DOM0\_READCONSOLE:] read console content from hypervisor buffer ring
   1.525 -
   1.526 -\item [\it DOM0\_PINCPUDOMAIN:] pin domain to a particular CPU
   1.527 -
   1.528 -\item [\it DOM0\_TBUFCONTROL:] get and set trace buffer attributes
   1.529 -
   1.530 -\item [\it DOM0\_PHYSINFO:] get information about the host machine
   1.531 -
   1.532 -\item [\it DOM0\_SCHED\_ID:] get the ID of the current Xen scheduler
   1.533 -
   1.534 -\item [\it DOM0\_SHADOW\_CONTROL:] switch between shadow page-table modes
   1.535 -
   1.536 -\item [\it DOM0\_SETDOMAINMAXMEM:] set maximum memory allocation of a domain
   1.537 -
   1.538 -\item [\it DOM0\_GETPAGEFRAMEINFO2:] batched interface for getting
   1.539 +\item [DOM0\_GETDOMAININFO:] get statistics about the domain
   1.540 +
   1.541 +\item [DOM0\_SETDOMAININFO:] set VCPU-related attributes
   1.542 +
   1.543 +\item [DOM0\_MSR:] read or write model specific registers
   1.544 +
   1.545 +\item [DOM0\_DEBUG:] interactively invoke the debugger
   1.546 +
   1.547 +\item [DOM0\_SETTIME:] set system time
   1.548 +
   1.549 +\item [DOM0\_GETPAGEFRAMEINFO:] 
   1.550 +
   1.551 +\item [DOM0\_READCONSOLE:] read console content from hypervisor buffer ring
   1.552 +
   1.553 +\item [DOM0\_PINCPUDOMAIN:] pin domain to a particular CPU
   1.554 +
   1.555 +\item [DOM0\_TBUFCONTROL:] get and set trace buffer attributes
   1.556 +
   1.557 +\item [DOM0\_PHYSINFO:] get information about the host machine
   1.558 +
   1.559 +\item [DOM0\_SCHED\_ID:] get the ID of the current Xen scheduler
   1.560 +
   1.561 +\item [DOM0\_SHADOW\_CONTROL:] switch between shadow page-table modes
   1.562 +
   1.563 +\item [DOM0\_SETDOMAINMAXMEM:] set maximum memory allocation of a domain
   1.564 +
   1.565 +\item [DOM0\_GETPAGEFRAMEINFO2:] batched interface for getting
   1.566  page frame info
   1.567  
   1.568 -\item [\it DOM0\_ADD\_MEMTYPE:] set MTRRs
   1.569 -
   1.570 -\item [\it DOM0\_DEL\_MEMTYPE:] remove a memory type range
   1.571 -
   1.572 -\item [\it DOM0\_READ\_MEMTYPE:] read MTRR
   1.573 -
   1.574 -\item [\it DOM0\_PERFCCONTROL:] control Xen's software performance
   1.575 +\item [DOM0\_ADD\_MEMTYPE:] set MTRRs
   1.576 +
   1.577 +\item [DOM0\_DEL\_MEMTYPE:] remove a memory type range
   1.578 +
   1.579 +\item [DOM0\_READ\_MEMTYPE:] read MTRR
   1.580 +
   1.581 +\item [DOM0\_PERFCCONTROL:] control Xen's software performance
   1.582  counters
   1.583  
   1.584 -\item [\it DOM0\_MICROCODE:] update CPU microcode
   1.585 -
   1.586 -\item [\it DOM0\_IOPORT\_PERMISSION:] modify domain permissions for an
   1.587 +\item [DOM0\_MICROCODE:] update CPU microcode
   1.588 +
   1.589 +\item [DOM0\_IOPORT\_PERMISSION:] modify domain permissions for an
   1.590  IO port range (enable / disable a range for a particular domain)
   1.591  
   1.592 -\item [\it DOM0\_GETVCPUCONTEXT:] get context from a VCPU
   1.593 -
   1.594 -\item [\it DOM0\_GETVCPUINFO:] get current state for a VCPU
   1.595 -\item [\it DOM0\_GETDOMAININFOLIST:] batched interface to get domain
   1.596 +\item [DOM0\_GETVCPUCONTEXT:] get context from a VCPU
   1.597 +
   1.598 +\item [DOM0\_GETVCPUINFO:] get current state for a VCPU
   1.599 +\item [DOM0\_GETDOMAININFOLIST:] batched interface to get domain
   1.600  info
   1.601  
   1.602 -\item [\it DOM0\_PLATFORM\_QUIRK:] inform Xen of a platform quirk it
   1.603 +\item [DOM0\_PLATFORM\_QUIRK:] inform Xen of a platform quirk it
   1.604  needs to handle (e.g. noirqbalance)
   1.605  
   1.606 -\item [\it DOM0\_PHYSICAL\_MEMORY\_MAP:] get info about dom0's memory
   1.607 +\item [DOM0\_PHYSICAL\_MEMORY\_MAP:] get info about dom0's memory
   1.608  map
   1.609  
   1.610 -\item [\it DOM0\_MAX\_VCPUS:] change max number of VCPUs for a domain
   1.611 -
   1.612 -\item [\it DOM0\_SETDOMAINHANDLE:] set the handle for a domain
   1.613 +\item [DOM0\_MAX\_VCPUS:] change max number of VCPUs for a domain
   1.614 +
   1.615 +\item [DOM0\_SETDOMAINHANDLE:] set the handle for a domain
   1.616  
   1.617  \end{description} 
   1.618  \end{quote} 
   1.619 @@ -2172,20 +2198,20 @@ A few additional hypercalls are mainly u
   1.620  
   1.621  Use Xen to interact with the console; operations are:
   1.622  
   1.623 -{\it CONSOLEIO\_write}: Output count characters from buffer str.
   1.624 -
   1.625 -{\it CONSOLEIO\_read}: Input at most count characters into buffer str.
   1.626 +{CONSOLEIO\_write}: Output count characters from buffer str.
   1.627 +
   1.628 +{CONSOLEIO\_read}: Input at most count characters into buffer str.
   1.629  \end{quote} 
   1.630  
   1.631  A pair of hypercalls allows access to the underlying debug registers: 
   1.632  \begin{quote}
   1.633  \hypercall{set\_debugreg(int reg, unsigned long value)}
   1.634  
   1.635 -Set debug register {\tt reg} to {\tt value} 
   1.636 +Set debug register {\bf reg} to {\bf value} 
   1.637  
   1.638  \hypercall{get\_debugreg(int reg)}
   1.639  
   1.640 -Return the contents of the debug register {\tt reg}
   1.641 +Return the contents of the debug register {\bf reg}
   1.642  \end{quote}
   1.643  
   1.644  And finally: 
     2.1 --- a/extras/mini-os/Makefile	Fri Mar 17 14:26:24 2006 -0700
     2.2 +++ b/extras/mini-os/Makefile	Fri Mar 17 15:37:28 2006 -0700
     2.3 @@ -32,7 +32,7 @@ OBJS := $(TARGET_ARCH).o
     2.4  OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
     2.5  OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
     2.6  OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
     2.7 -#OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
     2.8 +OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
     2.9  										   
    2.10  HDRS := $(wildcard include/*.h)
    2.11  HDRS += $(wildcard include/xen/*.h)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/mini-os/console/console.c	Fri Mar 17 15:37:28 2006 -0700
     3.3 @@ -0,0 +1,149 @@
     3.4 +/* 
     3.5 + ****************************************************************************
     3.6 + * (C) 2006 - Grzegorz Milos - Cambridge University
     3.7 + ****************************************************************************
     3.8 + *
     3.9 + *        File: console.h
    3.10 + *      Author: Grzegorz Milos
    3.11 + *     Changes: 
    3.12 + *              
    3.13 + *        Date: Mar 2006
    3.14 + * 
    3.15 + * Environment: Xen Minimal OS
    3.16 + * Description: Console interface.
    3.17 + *
    3.18 + * Handles console I/O. Defines printk.
    3.19 + *
    3.20 + ****************************************************************************
    3.21 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    3.22 + * of this software and associated documentation files (the "Software"), to
    3.23 + * deal in the Software without restriction, including without limitation the
    3.24 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    3.25 + * sell copies of the Software, and to permit persons to whom the Software is
    3.26 + * furnished to do so, subject to the following conditions:
    3.27 + * 
    3.28 + * The above copyright notice and this permission notice shall be included in
    3.29 + * all copies or substantial portions of the Software.
    3.30 + * 
    3.31 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    3.32 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    3.33 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    3.34 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    3.35 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    3.36 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    3.37 + * DEALINGS IN THE SOFTWARE.
    3.38 + */
    3.39 + 
    3.40 +#include <types.h>
    3.41 +#include <wait.h>
    3.42 +#include <mm.h>
    3.43 +#include <hypervisor.h>
    3.44 +#include <events.h>
    3.45 +#include <os.h>
    3.46 +#include <lib.h>
    3.47 +#include <xenbus.h>
    3.48 +#include <xen/io/console.h>
    3.49 +
    3.50 +
    3.51 +/* Low level functions defined in xencons_ring.c */
    3.52 +extern int xencons_ring_init(void);
    3.53 +extern int xencons_ring_send(const char *data, unsigned len);
    3.54 +extern int xencons_ring_send_no_notify(const char *data, unsigned len);
    3.55 +
    3.56 +
    3.57 +/* If console not initialised the printk will be sent to xen serial line 
    3.58 +   NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
    3.59 +static int console_initialised = 0;
    3.60 +
    3.61 +
    3.62 +void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
    3.63 +{
    3.64 +    if(len > 0)
    3.65 +    {
    3.66 +        /* Just repeat what's written */
    3.67 +        buf[len] = '\0';
    3.68 +        printk("%s", buf);
    3.69 +        
    3.70 +        if(buf[len-1] == '\r')
    3.71 +            printk("\nNo console input handler.\n");
    3.72 +    }
    3.73 +}
    3.74 +
    3.75 +void xencons_tx(void)
    3.76 +{
    3.77 +    /* Do nothing, handled by _rx */
    3.78 +}
    3.79 +
    3.80 +
    3.81 +void console_print(char *data, int length)
    3.82 +{
    3.83 +    char *curr_char, saved_char;
    3.84 +    int part_len;
    3.85 +    int (*ring_send_fn)(const char *data, unsigned length);
    3.86 +
    3.87 +    if(!console_initialised)
    3.88 +        ring_send_fn = xencons_ring_send_no_notify;
    3.89 +    else
    3.90 +        ring_send_fn = xencons_ring_send;
    3.91 +        
    3.92 +    for(curr_char = data; curr_char < data+length-1; curr_char++)
    3.93 +    {
    3.94 +        if(*curr_char == '\n')
    3.95 +        {
    3.96 +            saved_char = *(curr_char+1);
    3.97 +            *(curr_char+1) = '\r';
    3.98 +            part_len = curr_char - data + 2;
    3.99 +            ring_send_fn(data, part_len);
   3.100 +            *(curr_char+1) = saved_char;
   3.101 +            data = curr_char+1;
   3.102 +            length -= part_len - 1;
   3.103 +        }
   3.104 +    }
   3.105 +    
   3.106 +    ring_send_fn(data, length);
   3.107 +    
   3.108 +    if(data[length-1] == '\n')
   3.109 +        ring_send_fn("\r", 1);
   3.110 +}
   3.111 +
   3.112 +void print(int direct, const char *fmt, va_list args)
   3.113 +{
   3.114 +    static char   buf[1024];
   3.115 +    
   3.116 +    (void)vsnprintf(buf, sizeof(buf), fmt, args);
   3.117 + 
   3.118 +    if(direct)
   3.119 +    {
   3.120 +        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
   3.121 +        return;
   3.122 +    }
   3.123 +    
   3.124 +    if(!console_initialised)
   3.125 +        (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
   3.126 +        
   3.127 +    console_print(buf, strlen(buf));
   3.128 +}
   3.129 +
   3.130 +void printk(const char *fmt, ...)
   3.131 +{
   3.132 +    va_list       args;
   3.133 +    va_start(args, fmt);
   3.134 +    print(0, fmt, args);
   3.135 +    va_end(args);        
   3.136 +}
   3.137 +
   3.138 +void xprintk(const char *fmt, ...)
   3.139 +{
   3.140 +    va_list       args;
   3.141 +    va_start(args, fmt);
   3.142 +    print(1, fmt, args);
   3.143 +    va_end(args);        
   3.144 +}
   3.145 +void init_console(void)
   3.146 +{   
   3.147 +    printk("Initialising console ... ");
   3.148 +    xencons_ring_init();    
   3.149 +    console_initialised = 1;
   3.150 +    /* This is also required to notify the daemon */
   3.151 +    printk("done.\n");
   3.152 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/extras/mini-os/console/xencons_ring.c	Fri Mar 17 15:37:28 2006 -0700
     4.3 @@ -0,0 +1,104 @@
     4.4 +#include <types.h>
     4.5 +#include <wait.h>
     4.6 +#include <mm.h>
     4.7 +#include <hypervisor.h>
     4.8 +#include <events.h>
     4.9 +#include <os.h>
    4.10 +#include <lib.h>
    4.11 +#include <xenbus.h>
    4.12 +#include <xen/io/console.h>
    4.13 +
    4.14 +
    4.15 +/* TODO - need to define BUG_ON for whole mini-os, need crash-dump as well */
    4.16 +extern void do_exit(void);
    4.17 +#define BUG_ON(_cond)   do{if(_cond) do_exit();} while(0);
    4.18 +
    4.19 +static inline struct xencons_interface *xencons_interface(void)
    4.20 +{
    4.21 +    return mfn_to_virt(start_info.console_mfn);
    4.22 +}
    4.23 +
    4.24 +static inline void notify_daemon(void)
    4.25 +{
    4.26 +    /* Use evtchn: this is called early, before irq is set up. */
    4.27 +    notify_remote_via_evtchn(start_info.console_evtchn);
    4.28 +}
    4.29 +
    4.30 +int xencons_ring_send_no_notify(const char *data, unsigned len)
    4.31 +{	
    4.32 +    int sent = 0;
    4.33 +	struct xencons_interface *intf = xencons_interface();
    4.34 +	XENCONS_RING_IDX cons, prod;
    4.35 +
    4.36 +	cons = intf->out_cons;
    4.37 +	prod = intf->out_prod;
    4.38 +	mb();
    4.39 +	BUG_ON((prod - cons) > sizeof(intf->out));
    4.40 +
    4.41 +	while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
    4.42 +		intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
    4.43 +
    4.44 +	wmb();
    4.45 +	intf->out_prod = prod;
    4.46 +    
    4.47 +    return sent;
    4.48 +}
    4.49 +
    4.50 +int xencons_ring_send(const char *data, unsigned len)
    4.51 +{
    4.52 +    int sent;
    4.53 +    sent = xencons_ring_send_no_notify(data, len);
    4.54 +	notify_daemon();
    4.55 +
    4.56 +	return sent;
    4.57 +}	
    4.58 +
    4.59 +
    4.60 +
    4.61 +static void handle_input(int port, struct pt_regs *regs)
    4.62 +{
    4.63 +	struct xencons_interface *intf = xencons_interface();
    4.64 +	XENCONS_RING_IDX cons, prod;
    4.65 +
    4.66 +	cons = intf->in_cons;
    4.67 +	prod = intf->in_prod;
    4.68 +	mb();
    4.69 +	BUG_ON((prod - cons) > sizeof(intf->in));
    4.70 +
    4.71 +	while (cons != prod) {
    4.72 +		xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
    4.73 +		cons++;
    4.74 +	}
    4.75 +
    4.76 +	mb();
    4.77 +	intf->in_cons = cons;
    4.78 +
    4.79 +	notify_daemon();
    4.80 +
    4.81 +	xencons_tx();
    4.82 +}
    4.83 +
    4.84 +int xencons_ring_init(void)
    4.85 +{
    4.86 +	int err;
    4.87 +
    4.88 +	if (!start_info.console_evtchn)
    4.89 +		return 0;
    4.90 +
    4.91 +	err = bind_evtchn(start_info.console_evtchn, handle_input);
    4.92 +	if (err <= 0) {
    4.93 +		printk("XEN console request chn bind failed %i\n", err);
    4.94 +		return err;
    4.95 +	}
    4.96 +
    4.97 +	/* In case we have in-flight data after save/restore... */
    4.98 +	notify_daemon();
    4.99 +
   4.100 +	return 0;
   4.101 +}
   4.102 +
   4.103 +void xencons_resume(void)
   4.104 +{
   4.105 +	(void)xencons_ring_init();
   4.106 +}
   4.107 +
     5.1 --- a/extras/mini-os/events.c	Fri Mar 17 14:26:24 2006 -0700
     5.2 +++ b/extras/mini-os/events.c	Fri Mar 17 15:37:28 2006 -0700
     5.3 @@ -22,6 +22,7 @@
     5.4  #include <events.h>
     5.5  #include <lib.h>
     5.6  
     5.7 +
     5.8  static ev_action_t ev_actions[NR_EVS];
     5.9  void default_handler(int port, struct pt_regs *regs);
    5.10  
    5.11 @@ -58,7 +59,7 @@ int do_event(u32 port, struct pt_regs *r
    5.12  
    5.13  int bind_evtchn( u32 port, void (*handler)(int, struct pt_regs *) )
    5.14  {
    5.15 - 	if(ev_actions[port].handler)
    5.16 + 	if(ev_actions[port].handler != default_handler)
    5.17          printk("WARN: Handler for port %d already registered, replacing\n",
    5.18  				port);
    5.19  
    5.20 @@ -73,7 +74,7 @@ int bind_evtchn( u32 port, void (*handle
    5.21  
    5.22  void unbind_evtchn( u32 port )
    5.23  {
    5.24 -	if (!ev_actions[port].handler)
    5.25 +	if (ev_actions[port].handler)
    5.26  		printk("WARN: No handler for port %d when unbinding\n", port);
    5.27  	ev_actions[port].handler = NULL;
    5.28  	ev_actions[port].status |= EVS_DISABLED;
     6.1 --- a/extras/mini-os/include/lib.h	Fri Mar 17 14:26:24 2006 -0700
     6.2 +++ b/extras/mini-os/include/lib.h	Fri Mar 17 15:37:28 2006 -0700
     6.3 @@ -56,13 +56,10 @@
     6.4  #define _LIB_H_
     6.5  
     6.6  #include <stdarg.h>
     6.7 -
     6.8 +#include <console.h>
     6.9  
    6.10  /* printing */
    6.11 -#define printk  printf
    6.12 -#define kprintf printf
    6.13  #define _p(_x) ((void *)(unsigned long)(_x))
    6.14 -void printf(const char *fmt, ...);
    6.15  int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
    6.16  int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
    6.17  int snprintf(char * buf, size_t size, const char *fmt, ...);
     7.1 --- a/extras/mini-os/kernel.c	Fri Mar 17 14:26:24 2006 -0700
     7.2 +++ b/extras/mini-os/kernel.c	Fri Mar 17 15:37:28 2006 -0700
     7.3 @@ -76,6 +76,8 @@ static shared_info_t *map_shared_info(un
     7.4  }
     7.5  
     7.6  
     7.7 +extern void init_console(void);
     7.8 +
     7.9  /*
    7.10   * INITIAL C ENTRY POINT.
    7.11   */
    7.12 @@ -127,15 +129,19 @@ void start_kernel(start_info_t *si)
    7.13  
    7.14      /* set up events */
    7.15      init_events();
    7.16 +    
    7.17      /* init time and timers */
    7.18      init_time();
    7.19 -    
    7.20 +
    7.21 +    /* init the console driver */
    7.22 +    init_console();
    7.23 +
    7.24      /* init scheduler */
    7.25      init_sched();
    7.26  
    7.27      /* init xenbus */
    7.28      xs_init();
    7.29 -    
    7.30 +   
    7.31      /* Everything initialised, start idle thread */
    7.32      run_idle_thread();
    7.33  }
     8.1 --- a/extras/mini-os/lib/printf.c	Fri Mar 17 14:26:24 2006 -0700
     8.2 +++ b/extras/mini-os/lib/printf.c	Fri Mar 17 15:37:28 2006 -0700
     8.3 @@ -556,19 +556,6 @@ int sprintf(char * buf, const char *fmt,
     8.4      return i;
     8.5  }
     8.6  
     8.7 -
     8.8 -void printf(const char *fmt, ...)
     8.9 -{
    8.10 -    static char   buf[1024];
    8.11 -    va_list       args;
    8.12 -    
    8.13 -    va_start(args, fmt);
    8.14 -    (void)vsnprintf(buf, sizeof(buf), fmt, args);
    8.15 -    va_end(args);        
    8.16 -   
    8.17 -    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
    8.18 -}
    8.19 -
    8.20  /**
    8.21   * vsscanf - Unformat a buffer into a list of arguments
    8.22   * @buf:	input buffer
     9.1 --- a/extras/mini-os/mm.c	Fri Mar 17 14:26:24 2006 -0700
     9.2 +++ b/extras/mini-os/mm.c	Fri Mar 17 15:37:28 2006 -0700
     9.3 @@ -380,6 +380,10 @@ void new_pt_frame(unsigned long *pt_pfn,
     9.4             "prev_l_mfn=%lx, offset=%lx\n", 
     9.5             level, *pt_pfn, prev_l_mfn, offset);
     9.6  
     9.7 +    /* We need to clear the page, otherwise we might fail to map it
     9.8 +       as a page table page */
     9.9 +    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
    9.10 + 
    9.11      if (level == L1_FRAME)
    9.12      {
    9.13           prot_e = L1_PROT;
    10.1 --- a/extras/mini-os/sched.c	Fri Mar 17 14:26:24 2006 -0700
    10.2 +++ b/extras/mini-os/sched.c	Fri Mar 17 15:37:28 2006 -0700
    10.3 @@ -46,6 +46,7 @@
    10.4  #include <sched.h>
    10.5  #include <semaphore.h>
    10.6  
    10.7 +
    10.8  #ifdef SCHED_DEBUG
    10.9  #define DEBUG(_f, _a...) \
   10.10      printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
   10.11 @@ -61,7 +62,7 @@
   10.12  #define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
   10.13  
   10.14  
   10.15 -struct thread *idle_thread;
   10.16 +struct thread *idle_thread = NULL;
   10.17  LIST_HEAD(exited_threads);
   10.18  
   10.19  void dump_stack(struct thread *thread)
   10.20 @@ -225,7 +226,6 @@ void idle_thread_fn(void *unused)
   10.21      for(;;)
   10.22      {
   10.23          schedule();
   10.24 -        printk("Blocking the domain\n"); 
   10.25          block_domain(10000);
   10.26      }
   10.27  }
    11.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Fri Mar 17 14:26:24 2006 -0700
    11.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c	Fri Mar 17 15:37:28 2006 -0700
    11.3 @@ -587,6 +587,8 @@ static void pgd_test_and_unpin(pgd_t *pg
    11.4  
    11.5  void mm_pin(struct mm_struct *mm)
    11.6  {
    11.7 +	if (xen_feature(XENFEAT_writable_page_tables))
    11.8 +	    return;
    11.9  	spin_lock(&mm->page_table_lock);
   11.10  	__pgd_pin(mm->pgd);
   11.11  	spin_unlock(&mm->page_table_lock);
   11.12 @@ -594,6 +596,8 @@ void mm_pin(struct mm_struct *mm)
   11.13  
   11.14  void mm_unpin(struct mm_struct *mm)
   11.15  {
   11.16 +	if (xen_feature(XENFEAT_writable_page_tables))
   11.17 +	    return;
   11.18  	spin_lock(&mm->page_table_lock);
   11.19  	__pgd_unpin(mm->pgd);
   11.20  	spin_unlock(&mm->page_table_lock);
   11.21 @@ -602,6 +606,8 @@ void mm_unpin(struct mm_struct *mm)
   11.22  void mm_pin_all(void)
   11.23  {
   11.24  	struct page *page;
   11.25 +	if (xen_feature(XENFEAT_writable_page_tables))
   11.26 +	    return;
   11.27  	for (page = pgd_list; page; page = (struct page *)page->index) {
   11.28  		if (!test_bit(PG_pinned, &page->flags))
   11.29  			__pgd_pin((pgd_t *)page_address(page));
    12.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Fri Mar 17 14:26:24 2006 -0700
    12.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c	Fri Mar 17 15:37:28 2006 -0700
    12.3 @@ -71,6 +71,9 @@ static void mm_walk(struct mm_struct *mm
    12.4  
    12.5  void mm_pin(struct mm_struct *mm)
    12.6  {
    12.7 +	if (xen_feature(XENFEAT_writable_page_tables))
    12.8 +		return;
    12.9 +
   12.10  	spin_lock(&mm->page_table_lock);
   12.11  
   12.12  	mm_walk(mm, PAGE_KERNEL_RO);
   12.13 @@ -94,6 +97,9 @@ void mm_pin(struct mm_struct *mm)
   12.14  
   12.15  void mm_unpin(struct mm_struct *mm)
   12.16  {
   12.17 +	if (xen_feature(XENFEAT_writable_page_tables))
   12.18 +		return;
   12.19 +
   12.20  	spin_lock(&mm->page_table_lock);
   12.21  
   12.22  	xen_pgd_unpin(__pa(mm->pgd));
   12.23 @@ -116,6 +122,9 @@ void mm_unpin(struct mm_struct *mm)
   12.24  
   12.25  void mm_pin_all(void)
   12.26  {
   12.27 +	if (xen_feature(XENFEAT_writable_page_tables))
   12.28 +		return;
   12.29 +
   12.30  	while (!list_empty(&mm_unpinned))	
   12.31  		mm_pin(list_entry(mm_unpinned.next, struct mm_struct,
   12.32  				  context.unpinned));
    13.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Mar 17 14:26:24 2006 -0700
    13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c	Fri Mar 17 15:37:28 2006 -0700
    13.3 @@ -116,15 +116,13 @@ static int blkback_probe(struct xenbus_d
    13.4  			 const struct xenbus_device_id *id)
    13.5  {
    13.6  	int err;
    13.7 -	struct backend_info *be = kmalloc(sizeof(struct backend_info),
    13.8 +	struct backend_info *be = kzalloc(sizeof(struct backend_info),
    13.9  					  GFP_KERNEL);
   13.10  	if (!be) {
   13.11  		xenbus_dev_fatal(dev, -ENOMEM,
   13.12  				 "allocating backend structure");
   13.13  		return -ENOMEM;
   13.14  	}
   13.15 -	memset(be, 0, sizeof(*be));
   13.16 -
   13.17  	be->dev = dev;
   13.18  	dev->data = be;
   13.19  
    14.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Mar 17 14:26:24 2006 -0700
    14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Fri Mar 17 15:37:28 2006 -0700
    14.3 @@ -90,13 +90,12 @@ static int blkfront_probe(struct xenbus_
    14.4  		return err;
    14.5  	}
    14.6  
    14.7 -	info = kmalloc(sizeof(*info), GFP_KERNEL);
    14.8 +	info = kzalloc(sizeof(*info), GFP_KERNEL);
    14.9  	if (!info) {
   14.10  		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
   14.11  		return -ENOMEM;
   14.12  	}
   14.13  
   14.14 -	memset(info, 0, sizeof(*info));
   14.15  	info->xbdev = dev;
   14.16  	info->vdevice = vdevice;
   14.17  	info->connected = BLKIF_STATE_DISCONNECTED;
    15.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Mar 17 14:26:24 2006 -0700
    15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/vbd.c	Fri Mar 17 15:37:28 2006 -0700
    15.3 @@ -97,12 +97,10 @@ xlbd_alloc_major_info(int major, int min
    15.4  {
    15.5  	struct xlbd_major_info *ptr;
    15.6  
    15.7 -	ptr = kmalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
    15.8 +	ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
    15.9  	if (ptr == NULL)
   15.10  		return NULL;
   15.11  
   15.12 -	memset(ptr, 0, sizeof(struct xlbd_major_info));
   15.13 -
   15.14  	ptr->major = major;
   15.15  
   15.16  	switch (index) {
    16.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Fri Mar 17 14:26:24 2006 -0700
    16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c	Fri Mar 17 15:37:28 2006 -0700
    16.3 @@ -141,12 +141,11 @@ static int blkback_probe(struct xenbus_d
    16.4  	char *frontend;
    16.5  	int err;
    16.6  
    16.7 -	be = kmalloc(sizeof(*be), GFP_KERNEL);
    16.8 +	be = kzalloc(sizeof(*be), GFP_KERNEL);
    16.9  	if (!be) {
   16.10  		xenbus_dev_error(dev, -ENOMEM, "allocating backend structure");
   16.11  		return -ENOMEM;
   16.12  	}
   16.13 -	memset(be, 0, sizeof(*be));
   16.14  
   16.15  	frontend = NULL;
   16.16  	err = xenbus_gather(dev->nodename,
    17.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Fri Mar 17 14:26:24 2006 -0700
    17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c	Fri Mar 17 15:37:28 2006 -0700
    17.3 @@ -76,14 +76,13 @@ static int netback_probe(struct xenbus_d
    17.4  			 const struct xenbus_device_id *id)
    17.5  {
    17.6  	int err;
    17.7 -	struct backend_info *be = kmalloc(sizeof(struct backend_info),
    17.8 +	struct backend_info *be = kzalloc(sizeof(struct backend_info),
    17.9  					  GFP_KERNEL);
   17.10  	if (!be) {
   17.11  		xenbus_dev_fatal(dev, -ENOMEM,
   17.12  				 "allocating backend structure");
   17.13  		return -ENOMEM;
   17.14  	}
   17.15 -	memset(be, 0, sizeof(*be));
   17.16  
   17.17  	be->dev = dev;
   17.18  	dev->data = be;
    18.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Mar 17 14:26:24 2006 -0700
    18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Fri Mar 17 15:37:28 2006 -0700
    18.3 @@ -845,11 +845,11 @@ static int netif_poll(struct net_device 
    18.4  	}
    18.5  
    18.6  	while ((skb = __skb_dequeue(&rxq)) != NULL) {
    18.7 -		if (skb->len > (dev->mtu + ETH_HLEN)) {
    18.8 +		if (skb->len > (dev->mtu + ETH_HLEN + 4)) {
    18.9  			if (net_ratelimit())
   18.10  				printk(KERN_INFO "Received packet too big for "
   18.11  				       "MTU (%d > %d)\n",
   18.12 -				       skb->len - ETH_HLEN, dev->mtu);
   18.13 +				       skb->len - ETH_HLEN - 4, dev->mtu);
   18.14  			skb->len  = 0;
   18.15  			skb->tail = skb->data;
   18.16  			init_skb_shinfo(skb);
    19.1 --- a/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c	Fri Mar 17 14:26:24 2006 -0700
    19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/pcifront/pci_op.c	Fri Mar 17 15:37:28 2006 -0700
    19.3 @@ -8,6 +8,7 @@
    19.4  #include <linux/init.h>
    19.5  #include <linux/pci.h>
    19.6  #include <linux/spinlock.h>
    19.7 +#include <linux/time.h>
    19.8  #include <xen/evtchn.h>
    19.9  #include "pcifront.h"
   19.10  
   19.11 @@ -40,8 +41,10 @@ static int do_pci_op(struct pcifront_dev
   19.12  {
   19.13  	int err = 0;
   19.14  	struct xen_pci_op *active_op = &pdev->sh_info->op;
   19.15 -	unsigned long irq_flags, poll_end;
   19.16 +	unsigned long irq_flags;
   19.17  	evtchn_port_t port = pdev->evtchn;
   19.18 +	nsec_t ns, ns_timeout;
   19.19 +	struct timeval tv;
   19.20  
   19.21  	spin_lock_irqsave(&pdev->sh_info_lock, irq_flags);
   19.22  
   19.23 @@ -52,15 +55,25 @@ static int do_pci_op(struct pcifront_dev
   19.24  	set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
   19.25  	notify_remote_via_evtchn(port);
   19.26  
   19.27 -	poll_end = jiffies + 5*HZ;
   19.28 +	/*
   19.29 +	 * We set a poll timeout of 5 seconds but give up on return after
   19.30 +	 * 4 seconds. It is better to time out too late rather than too early
   19.31 +	 * (in the latter case we end up continually re-executing poll() with a
   19.32 +	 * timeout in the past). 1s difference gives plenty of slack for error.
   19.33 +	 */
   19.34 +	do_gettimeofday(&tv);
   19.35 +	ns_timeout = timeval_to_ns(&tv) + 4 * (nsec_t)NSEC_PER_SEC;
   19.36 +
   19.37  	clear_evtchn(port);
   19.38  
   19.39  	while (test_bit(_XEN_PCIF_active,
   19.40  			(unsigned long *)&pdev->sh_info->flags)) {
   19.41 -		if (HYPERVISOR_poll(&port, 1, poll_end))
   19.42 +		if (HYPERVISOR_poll(&port, 1, jiffies + 5*HZ))
   19.43  			BUG();
   19.44  		clear_evtchn(port);
   19.45 -		if (time_after(jiffies, poll_end)) {
   19.46 +		do_gettimeofday(&tv);
   19.47 +		ns = timeval_to_ns(&tv);
   19.48 +		if (ns > ns_timeout) {
   19.49  			dev_err(&pdev->xdev->dev,
   19.50  				"pciback not responding!!!\n");
   19.51  			clear_bit(_XEN_PCIF_active,
    20.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Fri Mar 17 14:26:24 2006 -0700
    20.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/xenbus.c	Fri Mar 17 15:37:28 2006 -0700
    20.3 @@ -67,7 +67,7 @@ static int tpmback_probe(struct xenbus_d
    20.4                           const struct xenbus_device_id *id)
    20.5  {
    20.6  	int err;
    20.7 -	struct backend_info *be = kmalloc(sizeof(struct backend_info),
    20.8 +	struct backend_info *be = kzalloc(sizeof(struct backend_info),
    20.9  	                                  GFP_KERNEL);
   20.10  
   20.11  	if (!be) {
   20.12 @@ -76,8 +76,6 @@ static int tpmback_probe(struct xenbus_d
   20.13  		return -ENOMEM;
   20.14  	}
   20.15  
   20.16 -	memset(be, 0, sizeof(*be));
   20.17 -
   20.18  	be->is_instance_set = 0;
   20.19  	be->dev = dev;
   20.20  	dev->data = be;
    21.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Fri Mar 17 14:26:24 2006 -0700
    21.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c	Fri Mar 17 15:37:28 2006 -0700
    21.3 @@ -106,8 +106,10 @@ int xb_write(const void *data, unsigned 
    21.4  		cons = intf->req_cons;
    21.5  		prod = intf->req_prod;
    21.6  		mb();
    21.7 -		if (!check_indexes(cons, prod))
    21.8 +		if (!check_indexes(cons, prod)) {
    21.9 +			intf->req_cons = intf->req_prod = 0;
   21.10  			return -EIO;
   21.11 +		}
   21.12  
   21.13  		dst = get_output_chunk(cons, prod, intf->req, &avail);
   21.14  		if (avail == 0)
   21.15 @@ -150,8 +152,10 @@ int xb_read(void *data, unsigned len)
   21.16  		cons = intf->rsp_cons;
   21.17  		prod = intf->rsp_prod;
   21.18  		mb();
   21.19 -		if (!check_indexes(cons, prod))
   21.20 +		if (!check_indexes(cons, prod)) {
   21.21 +			intf->rsp_cons = intf->rsp_prod = 0;
   21.22  			return -EIO;
   21.23 +		}
   21.24  
   21.25  		src = get_input_chunk(cons, prod, intf->rsp, &avail);
   21.26  		if (avail == 0)
    22.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Fri Mar 17 14:26:24 2006 -0700
    22.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c	Fri Mar 17 15:37:28 2006 -0700
    22.3 @@ -179,11 +179,10 @@ static int xenbus_dev_open(struct inode 
    22.4  
    22.5  	nonseekable_open(inode, filp);
    22.6  
    22.7 -	u = kmalloc(sizeof(*u), GFP_KERNEL);
    22.8 +	u = kzalloc(sizeof(*u), GFP_KERNEL);
    22.9  	if (u == NULL)
   22.10  		return -ENOMEM;
   22.11  
   22.12 -	memset(u, 0, sizeof(*u));
   22.13  	INIT_LIST_HEAD(&u->transactions);
   22.14  	init_waitqueue_head(&u->read_waitq);
   22.15  
    23.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Mar 17 14:26:24 2006 -0700
    23.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Fri Mar 17 15:37:28 2006 -0700
    23.3 @@ -552,10 +552,9 @@ static int xenbus_probe_node(struct xen_
    23.4  	}
    23.5  
    23.6  	stringlen = strlen(nodename) + 1 + strlen(type) + 1;
    23.7 -	xendev = kmalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
    23.8 +	xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL);
    23.9  	if (!xendev)
   23.10  		return -ENOMEM;
   23.11 -	memset(xendev, 0, sizeof(*xendev));
   23.12  
   23.13  	/* Copy the strings into the extra space. */
   23.14  
    24.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Mar 17 14:26:24 2006 -0700
    24.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c	Fri Mar 17 15:37:28 2006 -0700
    24.3 @@ -237,7 +237,14 @@ static void *xs_talkv(xenbus_transaction
    24.4  		return ERR_PTR(-err);
    24.5  	}
    24.6  
    24.7 -	BUG_ON(msg.type != type);
    24.8 +	if (msg.type != type) {
    24.9 +		if (printk_ratelimit())
   24.10 +			printk(KERN_WARNING
   24.11 +			       "XENBUS unexpected type [%d], expected [%d]\n",
   24.12 +			       msg.type, type);
   24.13 +		kfree(ret);
   24.14 +		return ERR_PTR(-EINVAL);
   24.15 +	}
   24.16  	return ret;
   24.17  }
   24.18  
    25.1 --- a/tools/ioemu/configure	Fri Mar 17 14:26:24 2006 -0700
    25.2 +++ b/tools/ioemu/configure	Fri Mar 17 15:37:28 2006 -0700
    25.3 @@ -238,6 +238,29 @@ fi
    25.4  
    25.5  fi
    25.6  
    25.7 +if test "$vnc" = "yes" ; then
    25.8 +
    25.9 +# check for eager event handling
   25.10 +cat > $TMPC <<EOF
   25.11 +#include "rfb/rfb.h"
   25.12 +int main(void) {
   25.13 +	rfbScreenInfoPtr screen;
   25.14 +
   25.15 +	screen->handleEventsEagerly = 1;
   25.16 +}
   25.17 +EOF
   25.18 +
   25.19 +if $cc `libvncserver-config --cflags` -o $TMPO $TMPC 2> /dev/null ; then
   25.20 +   have_eager_events="yes"
   25.21 +else
   25.22 +   echo "!!"
   25.23 +   echo "!! Slow VNC mouse, LibVNCServer doesn't support eager events"
   25.24 +   echo "!!"
   25.25 +   have_eager_events="no"
   25.26 +fi
   25.27 +
   25.28 +fi
   25.29 +
   25.30  ##########################################
   25.31  # SDL probe
   25.32  
   25.33 @@ -472,6 +495,9 @@ if test "$vnc" = "yes"; then
   25.34      vnc_cflags="/usr/include"
   25.35    fi
   25.36    echo "VNC_CFLAGS=$vnc_cflags" >> $config_mak
   25.37 +  if test "$have_eager_events" = "yes" ; then
   25.38 +    echo "#define VNC_EAGER_EVENTS 1" >> $config_h
   25.39 +  fi
   25.40  fi
   25.41  
   25.42  if test "$sdl" = "yes"; then
    26.1 --- a/tools/ioemu/hw/pckbd.c	Fri Mar 17 14:26:24 2006 -0700
    26.2 +++ b/tools/ioemu/hw/pckbd.c	Fri Mar 17 15:37:28 2006 -0700
    26.3 @@ -29,9 +29,6 @@
    26.4  /* debug PC keyboard : only mouse */
    26.5  //#define DEBUG_MOUSE
    26.6  
    26.7 -/* enable synapatic touchpad device model */
    26.8 -//#define SYNAPTIC
    26.9 -
   26.10  /*	Keyboard Controller Commands */
   26.11  #define KBD_CCMD_READ_MODE	0x20	/* Read mode bits */
   26.12  #define KBD_CCMD_WRITE_MODE	0x60	/* Write mode bits */
   26.13 @@ -114,18 +111,27 @@
   26.14  
   26.15  #define KBD_QUEUE_SIZE 256
   26.16  
   26.17 +/*
   26.18 + * Summagraphics tablet defines
   26.19 + */
   26.20 +#define SUMMA_BORDER	100
   26.21 +#define SUMMA_MAXX	(16000 - 1)
   26.22 +#define SUMMA_MAXY	(16000 - 1)
   26.23 +
   26.24  typedef struct {
   26.25      uint8_t aux[KBD_QUEUE_SIZE];
   26.26      uint8_t data[KBD_QUEUE_SIZE];
   26.27      int rptr, wptr, count;
   26.28  } KBDQueue;
   26.29  
   26.30 -#ifdef SYNAPTIC
   26.31 -typedef struct {
   26.32 -    int absolute;
   26.33 -    int high;
   26.34 -} TouchPad;
   26.35 -#endif
   26.36 +/*
   26.37 + *  Mouse types
   26.38 + */
   26.39 +#define PS2	0
   26.40 +#define IMPS2	3
   26.41 +#define IMEX	4
   26.42 +#define PAD	10
   26.43 +#define TABLET	11
   26.44  
   26.45  typedef struct KBDState {
   26.46      KBDQueue queue;
   26.47 @@ -143,17 +149,20 @@ typedef struct KBDState {
   26.48      uint8_t mouse_wrap;
   26.49      uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
   26.50      uint8_t mouse_detect_state;
   26.51 +    int mouse_x;  /* absolute coordinates (for mousepad) */
   26.52 +    int mouse_y;
   26.53      int mouse_dx; /* current values, needed for 'poll' mode */
   26.54      int mouse_dy;
   26.55      int mouse_dz;
   26.56      uint8_t mouse_buttons;
   26.57 -#ifdef SYNAPTIC
   26.58 -    TouchPad touchpad;
   26.59 -#endif
   26.60 +    CharDriverState *chr;
   26.61 +    void *cookie;
   26.62  } KBDState;
   26.63  
   26.64  KBDState kbd_state;
   26.65  
   26.66 +int summa_ok;		/* Allow Summagraphics emulation if true */
   26.67 +
   26.68  /* update irq and KBD_STAT_[MOUSE_]OBF */
   26.69  /* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
   26.70     incorrect, but it avoids having to simulate exact delays */
   26.71 @@ -398,7 +407,9 @@ static void kbd_write_keyboard(KBDState 
   26.72      }
   26.73  }
   26.74  
   26.75 -static void kbd_mouse_send_packet(KBDState *s)
   26.76 +int mouse_maxx, mouse_maxy;
   26.77 +
   26.78 +static int kbd_mouse_send_packet(KBDState *s)
   26.79  {
   26.80      unsigned int b;
   26.81      int dx1, dy1, dz1;
   26.82 @@ -406,95 +417,73 @@ static void kbd_mouse_send_packet(KBDSta
   26.83      dx1 = s->mouse_dx;
   26.84      dy1 = s->mouse_dy;
   26.85      dz1 = s->mouse_dz;
   26.86 -#ifdef SYNAPTIC
   26.87 -    if (s->touchpad.absolute)
   26.88 -    {
   26.89 -	int dz2, dleftnright, dg, df;
   26.90 -	if (dx1 > 6143)
   26.91 -	    dx1 = 6143;
   26.92 -	else if (dx1 < 0)
   26.93 -	    dx1 = 0;
   26.94 -	if (dy1 > 6143)
   26.95 -	    dy1 = 6143;
   26.96 -	else if (dy1 < 0)
   26.97 -	    dy1 = 0;
   26.98 -	dz2 = 80; /* normal finger pressure */
   26.99 -	dg = 0; /* guesture not supported */
  26.100 -	df = 0; /* finger not supported */
  26.101 -	dleftnright = (s->mouse_buttons & 0x07);
  26.102 -	/*
  26.103 -	X: 13 bits --return absolute x ord
  26.104 -	Y: 13 bits --return absolute y ord
  26.105 -	Z: 8 bits --return constant 80 since we don't know how hard the user
  26.106 -		is pressing on the mouse button ;) 80 is the default for pen
  26.107 -		pressure, as touchpads cant sense what pressure a pen makes.
  26.108 -	W: 4 bits --return 0, we don't support finger width (should we?)
  26.109 -	left: 1 bit --is left button pressed
  26.110 -	right: 1 bit --is right button pressed
  26.111 -	guesture: 1 bit --we dont support, return 0
  26.112 -	finger: 1 bit --ditto
  26.113 -	total: 42 bits in 6 bytes
  26.114 -	note that Synaptics drivers ignore the finger and guesture bits and
  26.115 -	consider them redundant
  26.116 -	*/
  26.117 -	/*
  26.118 -	note: the packet setup is different when Wmode = 1, but
  26.119 -	    this doesn't apply since we don't support Wmode capability
  26.120 -	format of packet is as follows:
  26.121 -	*/
  26.122 -	// 1 0 finger reserved 0 gesture right left
  26.123 -	kbd_queue(s, (0x80 | (df ? 0x20 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
  26.124 -	kbd_queue(s, ((dy1 & 0xF) * 256) + (dx1 & 0xF), 1);
  26.125 -	kbd_queue(s, 80, 1); //byte 3
  26.126 -	// 1 1 y-12 x-12 0 gesture right left
  26.127 -	kbd_queue(s, (0xC0 | ((dy1 & 1000) ? 0x20 : 0) | ((dx1 & 1000) ? 0x10 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
  26.128 -	kbd_queue(s, dx1 & 0xFF, 1);
  26.129 -	kbd_queue(s, dy1 & 0xFF, 1);
  26.130 -	return;
  26.131 +    switch(s->mouse_type) {
  26.132 +  
  26.133 +    case TABLET:        /* Summagraphics pen tablet */
  26.134 +	dx1 = s->mouse_x;
  26.135 +	dy1 = s->mouse_y;
  26.136 +	dx1 = ((dx1 * SUMMA_MAXX) / mouse_maxx) + SUMMA_BORDER;
  26.137 +	dy1 = ((dy1 * SUMMA_MAXY) / mouse_maxy) + SUMMA_BORDER;
  26.138 +	ser_queue(s->cookie, 0x80 | (s->mouse_buttons & 7));
  26.139 +	ser_queue(s->cookie, dx1 & 0x7f);
  26.140 +	ser_queue(s->cookie, dx1 >> 7);
  26.141 +	ser_queue(s->cookie, dy1 & 0x7f);
  26.142 +	ser_queue(s->cookie, dy1 >> 7);
  26.143 +	s->mouse_dx = 0; 
  26.144 +	s->mouse_dy = 0;
  26.145 +	s->mouse_dz = 0;
  26.146 +	return 0;
  26.147 +
  26.148 +    default:	/* PS/2 style mice */
  26.149 +	/* XXX: increase range to 8 bits ? */
  26.150 +	if (dx1 > 127)
  26.151 +	    dx1 = 127;
  26.152 +	else if (dx1 < -127)
  26.153 +	    dx1 = -127;
  26.154 +	if (dy1 > 127)
  26.155 +	    dy1 = 127;
  26.156 +	else if (dy1 < -127)
  26.157 +	    dy1 = -127;
  26.158 +	b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
  26.159 +	kbd_queue(s, b, 1);
  26.160 +	kbd_queue(s, dx1 & 0xff, 1);
  26.161 +	kbd_queue(s, dy1 & 0xff, 1);
  26.162 +	/* extra byte for IMPS/2 or IMEX */
  26.163 +	switch(s->mouse_type) {
  26.164 +
  26.165 +	default:
  26.166 +	    break;
  26.167 +
  26.168 +	case IMPS2:
  26.169 +	    if (dz1 > 127)
  26.170 +		dz1 = 127;
  26.171 +	    else if (dz1 < -127)
  26.172 +		dz1 = -127;
  26.173 +	    kbd_queue(s, dz1 & 0xff, 1);
  26.174 +	    break;
  26.175 +
  26.176 +	case IMEX:
  26.177 +	    if (dz1 > 7)
  26.178 +		dz1 = 7;
  26.179 +	    else if (dz1 < -7)
  26.180 +		dz1 = -7;
  26.181 +	    b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
  26.182 +	    kbd_queue(s, b, 1);
  26.183 +	    break;
  26.184 +	}
  26.185 +
  26.186 +	/* update deltas */
  26.187 +	s->mouse_dx -= dx1;
  26.188 +	s->mouse_dy -= dy1;
  26.189 +	s->mouse_dz -= dz1;
  26.190 +	return s->mouse_dx || s->mouse_dy || s->mouse_dz;
  26.191 +
  26.192      }
  26.193 -#endif
  26.194 -    /* XXX: increase range to 8 bits ? */
  26.195 -    if (dx1 > 127)
  26.196 -        dx1 = 127;
  26.197 -    else if (dx1 < -127)
  26.198 -        dx1 = -127;
  26.199 -    if (dy1 > 127)
  26.200 -        dy1 = 127;
  26.201 -    else if (dy1 < -127)
  26.202 -        dy1 = -127;
  26.203 -    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
  26.204 -    kbd_queue(s, b, 1);
  26.205 -    kbd_queue(s, dx1 & 0xff, 1);
  26.206 -    kbd_queue(s, dy1 & 0xff, 1);
  26.207 -    /* extra byte for IMPS/2 or IMEX */
  26.208 -    switch(s->mouse_type) {
  26.209 -    default:
  26.210 -        break;
  26.211 -    case 3:
  26.212 -        if (dz1 > 127)
  26.213 -            dz1 = 127;
  26.214 -        else if (dz1 < -127)
  26.215 -                dz1 = -127;
  26.216 -        kbd_queue(s, dz1 & 0xff, 1);
  26.217 -        break;
  26.218 -    case 4:
  26.219 -        if (dz1 > 7)
  26.220 -            dz1 = 7;
  26.221 -        else if (dz1 < -7)
  26.222 -            dz1 = -7;
  26.223 -        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
  26.224 -        kbd_queue(s, b, 1);
  26.225 -        break;
  26.226 -    }
  26.227 -
  26.228 -    /* update deltas */
  26.229 -    s->mouse_dx -= dx1;
  26.230 -    s->mouse_dy -= dy1;
  26.231 -    s->mouse_dz -= dz1;
  26.232  }
  26.233  
  26.234  static void pc_kbd_mouse_event(void *opaque, 
  26.235 -                               int dx, int dy, int dz, int buttons_state)
  26.236 +                               int dx, int dy, int dz, int buttons_state,
  26.237 +			       int x, int y)
  26.238  {
  26.239      KBDState *s = opaque;
  26.240  
  26.241 @@ -502,6 +491,8 @@ static void pc_kbd_mouse_event(void *opa
  26.242      if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
  26.243          return;
  26.244  
  26.245 +    s->mouse_x = x;
  26.246 +    s->mouse_y = y;
  26.247      s->mouse_dx += dx;
  26.248      s->mouse_dy -= dy;
  26.249      s->mouse_dz += dz;
  26.250 @@ -513,23 +504,76 @@ static void pc_kbd_mouse_event(void *opa
  26.251      
  26.252      if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
  26.253          (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
  26.254 -        for(;;) {
  26.255 -            /* if not remote, send event. Multiple events are sent if
  26.256 -               too big deltas */
  26.257 -            kbd_mouse_send_packet(s);
  26.258 -            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
  26.259 -                break;
  26.260 -        }
  26.261 +		while (kbd_mouse_send_packet(s))
  26.262 +		    ;
  26.263      }
  26.264  }
  26.265  
  26.266 +static void summa(KBDState *s, int val)
  26.267 +{
  26.268 +    static int summa = 0;
  26.269 +
  26.270 +    if (s->mouse_type == TABLET) {
  26.271 +	switch (val) {
  26.272 +
  26.273 +	case '?':	/* read firmware ID */
  26.274 +	    ser_queue(s->cookie, '0');
  26.275 +	    break;
  26.276 +
  26.277 +	case 'a':	/* read config */
  26.278 +	    /*
  26.279 +	     *  Config looks like a movement packet but, because of scaling
  26.280 +	     *    issues we can't use `kbd_send_packet' to do this.
  26.281 +	     */
  26.282 +	    ser_queue(s->cookie, 0);
  26.283 +	    ser_queue(s->cookie, (SUMMA_MAXX & 0x7f));
  26.284 +	    ser_queue(s->cookie, (SUMMA_MAXX >> 7));
  26.285 +	    ser_queue(s->cookie, (SUMMA_MAXY & 0x7f));
  26.286 +	    ser_queue(s->cookie, (SUMMA_MAXY >> 7));
  26.287 +	    break;
  26.288 +
  26.289 +	default:	/* ignore all others */
  26.290 +	    break;
  26.291 +
  26.292 +	}
  26.293 +	return;
  26.294 +    }
  26.295 +    if (val == 'B') {
  26.296 +	summa++;
  26.297 +	return;
  26.298 +    } else if (summa && val == 'z') {
  26.299 +	s->mouse_type = TABLET;
  26.300 +	return;
  26.301 +    }
  26.302 +    summa = 0;
  26.303 +    return;
  26.304 +}
  26.305 +
  26.306 +int summa_write(CharDriverState *chr, const uint8_t *buf, int len)
  26.307 +{
  26.308 +    KBDState *s = (KBDState *)chr->opaque;
  26.309 +    int n;
  26.310 +
  26.311 +    n = len;
  26.312 +    while (n-- > 0)
  26.313 +	summa(s, *buf++);
  26.314 +    return len;
  26.315 +}
  26.316 +
  26.317 +void summa_init(void *cookie, CharDriverState *chr)
  26.318 +{
  26.319 +
  26.320 +    if (summa_ok == 0)
  26.321 +	return;
  26.322 +    kbd_state.chr = chr;
  26.323 +    kbd_state.cookie = (void *)cookie;
  26.324 +    chr->chr_write = summa_write;
  26.325 +    chr->opaque = (void *)&kbd_state;
  26.326 +    return;
  26.327 +}
  26.328 +
  26.329  static void kbd_write_mouse(KBDState *s, int val)
  26.330  {
  26.331 -#ifdef SYNAPTIC
  26.332 -/* variables needed to store synaptics command info */
  26.333 -static int rr = 0, ss = 0, tt = 0, uu = 0, res_count = 0, last_com = 0;
  26.334 -int spare;
  26.335 -#endif
  26.336  #ifdef DEBUG_MOUSE
  26.337      printf("kbd: write mouse 0x%02x\n", val);
  26.338  #endif
  26.339 @@ -547,9 +591,6 @@ int spare;
  26.340                  return;
  26.341              }
  26.342          }
  26.343 -#ifdef SYNAPTIC
  26.344 -	last_com = val;
  26.345 -#endif
  26.346          switch(val) {
  26.347          case AUX_SET_SCALE11:
  26.348              s->mouse_status &= ~MOUSE_STATUS_SCALE21;
  26.349 @@ -581,121 +622,6 @@ int spare;
  26.350              kbd_queue(s, AUX_ACK, 1);
  26.351              break;
  26.352          case AUX_GET_SCALE:
  26.353 -#ifdef SYNAPTIC
  26.354 -	    if (res_count == 4)
  26.355 -	    {
  26.356 -		    /* time for the special stuff */
  26.357 -		    kbd_queue(s, AUX_ACK, 1);
  26.358 -		    /* below is how we get the real synaptic command */
  26.359 -		    val = (rr*64) + (ss*16) + (tt*4) + uu;
  26.360 -		    switch(val)
  26.361 -		    {
  26.362 -			    /* id touchpad */
  26.363 -			    case 0x00:
  26.364 -				    /* info Minor */
  26.365 -				    kbd_queue(s, 0x00, 1);
  26.366 -				    /* special verification byte */
  26.367 -				    kbd_queue(s, 0x47, 1);
  26.368 -				    /* info Major * 0x10 + Info ModelCode*/
  26.369 -				    kbd_queue(s, 4 * 0x10 + 0, 1);
  26.370 -				    break;
  26.371 -				    /* read touchpad modes */
  26.372 -			    case 0x01:
  26.373 -				    /* special verification byte */
  26.374 -				    kbd_queue(s, 0x3B, 1);
  26.375 -				    /* mode */
  26.376 -				    /*
  26.377 -					bit 7 - absolute or relative position
  26.378 -					bit 6 - 0 for 40 packets/sec, 1 for 80 pack/sec
  26.379 -					bit 3 - 1 for sleep mode, 0 for normal
  26.380 -					bit 2 - 1 to detect tap/drag, 0 to disable
  26.381 -					bit 1 - packet size, only valid for serial protocol
  26.382 -					bit 0 - 0 for normal packets, 1 for enhanced packets
  26.383 -					(absolute mode packets which have finger width)
  26.384 -					*/
  26.385 -				    if (s->touchpad.absolute && s->touchpad.high)
  26.386 -				    {
  26.387 -					    spare = 0xC0;
  26.388 -				    }
  26.389 -				    else if (s->touchpad.absolute)
  26.390 -				    {
  26.391 -					    spare = 0x80;
  26.392 -				    }
  26.393 -				    else if (s->touchpad.high)
  26.394 -				    {
  26.395 -					    spare = 0x40;
  26.396 -				    }
  26.397 -				    else
  26.398 -				    {
  26.399 -					    spare = 0x00;
  26.400 -				    }
  26.401 -				    kbd_queue(s, spare, 1);
  26.402 -				    /* special verification byte */
  26.403 -				    kbd_queue(s, 0x47, 1);
  26.404 -				    break;
  26.405 -				    /* read touchpad capabilites */
  26.406 -			    case 0x02:
  26.407 -				    /* extended capability first 8 bits */
  26.408 -				    kbd_queue(s, 0x00, 1);
  26.409 -				    /* special verification byte */
  26.410 -				    kbd_queue(s, 0x47, 1);
  26.411 -				    /* extended capability last 8 bits */
  26.412 -				    kbd_queue(s, 0x00, 1);
  26.413 -				    /* basicly, we don't have any capabilites ;0 */
  26.414 -				    break;
  26.415 -				    /* read model id */
  26.416 -			    case 0x03:
  26.417 -				    /*
  26.418 -					bit 23 = 0 (1 for upsidedownpad)
  26.419 -					bit 22 = 0 (1 for 90 degree rotated pad)
  26.420 -					bits 21-16 = 1 (standard model)
  26.421 -					bits 15-9 = ??? (reserved for synaptics use)
  26.422 -					bit 7 = 1
  26.423 -					bit 6 = 0 (1 for sensing pens)
  26.424 -					bit 5 = 1
  26.425 -					bits 3-0 = 1 (rectangular geometery)
  26.426 -				    */
  26.427 -				    kbd_queue(s, 0xFC, 1);
  26.428 -				    kbd_queue(s, 0x00, 1);
  26.429 -				    kbd_queue(s, 0xF5, 1); //F7 for sensing pens
  26.430 -				    break;
  26.431 -				    /* read serial number prefix */
  26.432 -			    case 0x06:
  26.433 -				    /* strange how they have this query even though
  26.434 -					no touchpad actually has serial numbers */
  26.435 -				    /* return serial prefix of 0 if we dont have one */
  26.436 -				    kbd_queue(s, 0x00, 1);
  26.437 -				    kbd_queue(s, 0x00, 1);
  26.438 -				    kbd_queue(s, 0x00, 1);
  26.439 -				    break;
  26.440 -				    /* read serial number suffix */
  26.441 -			    case 0x07:
  26.442 -				    /* undefined if we dont have a valid serial prefix */
  26.443 -				    kbd_queue(s, 0x00, 1);
  26.444 -				    kbd_queue(s, 0x00, 1);
  26.445 -				    kbd_queue(s, 0x00, 1);
  26.446 -				    break;
  26.447 -				    /* read resolutions */
  26.448 -			    case 0x08:
  26.449 -				    /* going to go with infoSensor = 1 (Standard model) here */
  26.450 -				    /* absolute X in abolute units per mm */
  26.451 -				    kbd_queue(s, 85, 1);
  26.452 -				    /* undefined but first bit 7 will be set to 1...
  26.453 -					hell I'm going to set them all to 1 */
  26.454 -				    kbd_queue(s, 0xFF, 1);
  26.455 -				    /* absolute Y in abolute units per mm */
  26.456 -				    kbd_queue(s, 94, 1);
  26.457 -				    break;
  26.458 -			    default:
  26.459 -				    /* invalid commands return undefined data */
  26.460 -				    kbd_queue(s, 0x00, 1);
  26.461 -				    kbd_queue(s, 0x00, 1);
  26.462 -				    kbd_queue(s, 0x00, 1);
  26.463 -				    break;
  26.464 -		    }
  26.465 -	    }
  26.466 -	    else
  26.467 -#endif
  26.468  	    {
  26.469  		    /* not a special command, just do the regular stuff */
  26.470              kbd_queue(s, AUX_ACK, 1);
  26.471 @@ -720,18 +646,12 @@ int spare;
  26.472              s->mouse_sample_rate = 100;
  26.473              s->mouse_resolution = 2;
  26.474              s->mouse_status = 0;
  26.475 -#ifdef SYNAPTIC
  26.476 -       	    s->touchpad.absolute = 0;
  26.477 -#endif
  26.478              kbd_queue(s, AUX_ACK, 1);
  26.479              break;
  26.480          case AUX_RESET:
  26.481              s->mouse_sample_rate = 100;
  26.482              s->mouse_resolution = 2;
  26.483              s->mouse_status = 0;
  26.484 -#ifdef SYNAPTIC
  26.485 -	    s->touchpad.absolute = 0;
  26.486 -#endif
  26.487              kbd_queue(s, AUX_ACK, 1);
  26.488              kbd_queue(s, 0xaa, 1);
  26.489              kbd_queue(s, s->mouse_type, 1);
  26.490 @@ -741,15 +661,6 @@ int spare;
  26.491          }
  26.492          break;
  26.493      case AUX_SET_SAMPLE:
  26.494 -#ifdef SYNAPTIC
  26.495 -	if (res_count == 4 && val == 0x14)
  26.496 -	{
  26.497 -		/* time for the special stuff */
  26.498 -		/* below is how we get the real synaptic command */
  26.499 -		val = (rr*64) + (ss*16) + (tt*4) + uu;
  26.500 -		/* TODO: set the mode byte */
  26.501 -	} else
  26.502 -#endif
  26.503          s->mouse_sample_rate = val;
  26.504  #if 0
  26.505          /* detect IMPS/2 or IMEX */
  26.506 @@ -769,12 +680,12 @@ int spare;
  26.507              break;
  26.508          case 2:
  26.509              if (val == 80) 
  26.510 -                s->mouse_type = 3; /* IMPS/2 */
  26.511 +                s->mouse_type = IMPS2; /* IMPS/2 */
  26.512              s->mouse_detect_state = 0;
  26.513              break;
  26.514          case 3:
  26.515              if (val == 80) 
  26.516 -                s->mouse_type = 4; /* IMEX */
  26.517 +                s->mouse_type = IMEX; /* IMEX */
  26.518              s->mouse_detect_state = 0;
  26.519              break;
  26.520          }
  26.521 @@ -783,36 +694,6 @@ int spare;
  26.522          s->mouse_write_cmd = -1;
  26.523          break;
  26.524      case AUX_SET_RES:
  26.525 -#ifdef SYNAPTIC
  26.526 -	if (last_com != AUX_SET_RES)
  26.527 -	{
  26.528 -		/* if its not 4 in a row, its not a command */
  26.529 -		/* FIXME: if we are set 8 of these in a row, or 12, or 16,
  26.530 -		   or etc ... or 4^n commands, then the nth'd mode byte sent might
  26.531 -		   still work. not sure if this is how things are suppose to be
  26.532 -		   or not. */
  26.533 -		res_count = 0;
  26.534 -	}
  26.535 -	res_count++;
  26.536 -	if (res_count > 4) res_count = 4;
  26.537 -	switch(res_count)
  26.538 -		/* we need to save the val in the right spots to get the
  26.539 -		   real command later */
  26.540 -	{
  26.541 -		case 1:
  26.542 -			break;
  26.543 -			rr = val;
  26.544 -		case 2:
  26.545 -			ss = val;
  26.546 -			break;
  26.547 -		case 3:
  26.548 -			tt = val;
  26.549 -			break;
  26.550 -		case 4:
  26.551 -			uu = val;
  26.552 -			break;
  26.553 -	}
  26.554 -#endif
  26.555          s->mouse_resolution = val;
  26.556          kbd_queue(s, AUX_ACK, 1);
  26.557          s->mouse_write_cmd = -1;
  26.558 @@ -881,23 +762,19 @@ static void kbd_save(QEMUFile* f, void* 
  26.559      qemu_put_8s(f, &s->write_cmd);
  26.560      qemu_put_8s(f, &s->status);
  26.561      qemu_put_8s(f, &s->mode);
  26.562 -    qemu_put_be32s(f, &s->kbd_write_cmd);
  26.563 -    qemu_put_be32s(f, &s->scan_enabled);
  26.564 -    qemu_put_be32s(f, &s->mouse_write_cmd);
  26.565 +    qemu_put_be32s(f, (uint32_t *)&s->kbd_write_cmd);
  26.566 +    qemu_put_be32s(f, (uint32_t *)&s->scan_enabled);
  26.567 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_write_cmd);
  26.568      qemu_put_8s(f, &s->mouse_status);
  26.569      qemu_put_8s(f, &s->mouse_resolution);
  26.570      qemu_put_8s(f, &s->mouse_sample_rate);
  26.571      qemu_put_8s(f, &s->mouse_wrap);
  26.572      qemu_put_8s(f, &s->mouse_type);
  26.573      qemu_put_8s(f, &s->mouse_detect_state);
  26.574 -    qemu_put_be32s(f, &s->mouse_dx);
  26.575 -    qemu_put_be32s(f, &s->mouse_dy);
  26.576 -    qemu_put_be32s(f, &s->mouse_dz);
  26.577 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dx);
  26.578 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dy);
  26.579 +    qemu_put_be32s(f, (uint32_t *)&s->mouse_dz);
  26.580      qemu_put_8s(f, &s->mouse_buttons);
  26.581 -#ifdef SYNAPTIC
  26.582 -    qemu_put_be32s(f, &s->touchpad.absolute);
  26.583 -    qemu_put_be32s(f, &s->touchpad.high);
  26.584 -#endif
  26.585  }
  26.586  
  26.587  static int kbd_load(QEMUFile* f, void* opaque, int version_id)
  26.588 @@ -909,23 +786,19 @@ static int kbd_load(QEMUFile* f, void* o
  26.589      qemu_get_8s(f, &s->write_cmd);
  26.590      qemu_get_8s(f, &s->status);
  26.591      qemu_get_8s(f, &s->mode);
  26.592 -    qemu_get_be32s(f, &s->kbd_write_cmd);
  26.593 -    qemu_get_be32s(f, &s->scan_enabled);
  26.594 -    qemu_get_be32s(f, &s->mouse_write_cmd);
  26.595 +    qemu_get_be32s(f, (uint32_t *)&s->kbd_write_cmd);
  26.596 +    qemu_get_be32s(f, (uint32_t *)&s->scan_enabled);
  26.597 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_write_cmd);
  26.598      qemu_get_8s(f, &s->mouse_status);
  26.599      qemu_get_8s(f, &s->mouse_resolution);
  26.600      qemu_get_8s(f, &s->mouse_sample_rate);
  26.601      qemu_get_8s(f, &s->mouse_wrap);
  26.602      qemu_get_8s(f, &s->mouse_type);
  26.603      qemu_get_8s(f, &s->mouse_detect_state);
  26.604 -    qemu_get_be32s(f, &s->mouse_dx);
  26.605 -    qemu_get_be32s(f, &s->mouse_dy);
  26.606 -    qemu_get_be32s(f, &s->mouse_dz);
  26.607 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dx);
  26.608 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dy);
  26.609 +    qemu_get_be32s(f, (uint32_t *)&s->mouse_dz);
  26.610      qemu_get_8s(f, &s->mouse_buttons);
  26.611 -#ifdef SYNAPTIC
  26.612 -    qemu_get_be32s(f, &s->touchpad.absolute);
  26.613 -    qemu_get_be32s(f, &s->touchpad.high);
  26.614 -#endif
  26.615      return 0;
  26.616  }
  26.617  
  26.618 @@ -933,6 +806,7 @@ void kbd_init(void)
  26.619  {
  26.620      KBDState *s = &kbd_state;
  26.621      
  26.622 +    s->mouse_type = PS2;
  26.623      kbd_reset(s);
  26.624      register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s);
  26.625      register_ioport_read(0x60, 1, 1, kbd_read_data, s);
    27.1 --- a/tools/ioemu/hw/serial.c	Fri Mar 17 14:26:24 2006 -0700
    27.2 +++ b/tools/ioemu/hw/serial.c	Fri Mar 17 15:37:28 2006 -0700
    27.3 @@ -70,6 +70,11 @@
    27.4  #define UART_LSR_OE	0x02	/* Overrun error indicator */
    27.5  #define UART_LSR_DR	0x01	/* Receiver data ready */
    27.6  
    27.7 +/*
    27.8 + * Size of ring buffer for characters to send to host
    27.9 + */
   27.10 +#define MAXCHRS	256
   27.11 +
   27.12  struct SerialState {
   27.13      uint8_t divider;
   27.14      uint8_t rbr; /* receive register */
   27.15 @@ -84,11 +89,22 @@ struct SerialState {
   27.16         it can be reset while reading iir */
   27.17      int thr_ipending;
   27.18      int irq;
   27.19 +    struct cbuf {
   27.20 +	    uint8_t buf[MAXCHRS];
   27.21 +	    int in;
   27.22 +	    int out;
   27.23 +    } cbuf;
   27.24      CharDriverState *chr;
   27.25  };
   27.26  
   27.27  static void serial_update_irq(SerialState *s)
   27.28  {
   27.29 +    if ((s->lsr & UART_LSR_DR) == 0 && s->cbuf.in != s->cbuf.out) {
   27.30 +	s->rbr = s->cbuf.buf[s->cbuf.out++];
   27.31 +	if (s->cbuf.out >= MAXCHRS)
   27.32 +	    s->cbuf.out = 0;
   27.33 +	s->lsr |= UART_LSR_DR;
   27.34 +    }
   27.35      if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
   27.36          s->iir = UART_IIR_RDI;
   27.37      } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
   27.38 @@ -220,6 +236,22 @@ static uint32_t serial_ioport_read(void 
   27.39      return ret;
   27.40  }
   27.41  
   27.42 +void ser_queue(SerialState *s, unsigned char c)
   27.43 +{
   27.44 +    int n;
   27.45 +
   27.46 +    n = s->cbuf.in - s->cbuf.out;
   27.47 +    if (n < 0)
   27.48 +	n += MAXCHRS;
   27.49 +    if (n < (MAXCHRS - 1)) {
   27.50 +	s->cbuf.buf[s->cbuf.in++] = c;
   27.51 +	if (s->cbuf.in >= MAXCHRS)
   27.52 +	    s->cbuf.in = 0;
   27.53 +	serial_update_irq(s);
   27.54 +    }
   27.55 +    return;
   27.56 +}
   27.57 +
   27.58  static int serial_can_receive(SerialState *s)
   27.59  {
   27.60      return !(s->lsr & UART_LSR_DR);
   27.61 @@ -227,6 +259,9 @@ static int serial_can_receive(SerialStat
   27.62  
   27.63  static void serial_receive_byte(SerialState *s, int ch)
   27.64  {
   27.65 +#ifdef	DEBUG_SERIAL
   27.66 +    printf("serial: serial_receive_byte: ch=0x%02x\n", ch);
   27.67 +#endif	// DEBUG_SERIAL
   27.68      s->rbr = ch;
   27.69      s->lsr |= UART_LSR_DR;
   27.70      serial_update_irq(s);
   27.71 @@ -266,6 +301,8 @@ SerialState *serial_init(int base, int i
   27.72      s = qemu_mallocz(sizeof(SerialState));
   27.73      if (!s)
   27.74          return NULL;
   27.75 +    s->cbuf.in = 0;
   27.76 +    s->cbuf.out = 0;
   27.77      s->irq = irq;
   27.78      s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
   27.79      s->iir = UART_IIR_NO_INT;
   27.80 @@ -273,6 +310,7 @@ SerialState *serial_init(int base, int i
   27.81      register_ioport_write(base, 8, 1, serial_ioport_write, s);
   27.82      register_ioport_read(base, 8, 1, serial_ioport_read, s);
   27.83      s->chr = chr;
   27.84 +    summa_init(s, chr);
   27.85      qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
   27.86      qemu_chr_add_event_handler(chr, serial_event);
   27.87      return s;
    28.1 --- a/tools/ioemu/hw/vga.c	Fri Mar 17 14:26:24 2006 -0700
    28.2 +++ b/tools/ioemu/hw/vga.c	Fri Mar 17 15:37:28 2006 -0700
    28.3 @@ -1340,6 +1340,99 @@ void vga_invalidate_scanlines(VGAState *
    28.4      }
    28.5  }
    28.6  
    28.7 +static inline int cmp_vram(VGAState *s, int offset, int n)
    28.8 +{
    28.9 +    long *vp, *sp;
   28.10 +
   28.11 +    if (s->vram_shadow == NULL)
   28.12 +        return 1;
   28.13 +    vp = (long *)(s->vram_ptr + offset);
   28.14 +    sp = (long *)(s->vram_shadow + offset);
   28.15 +    while ((n -= sizeof(*vp)) >= 0) {
   28.16 +        if (*vp++ != *sp++) {
   28.17 +            memcpy(sp - 1, vp - 1, n + sizeof(*vp));
   28.18 +            return 1;
   28.19 +        }
   28.20 +    }
   28.21 +    return 0;
   28.22 +}
   28.23 +
   28.24 +#ifdef USE_SSE2
   28.25 +
   28.26 +#include <signal.h>
   28.27 +#include <setjmp.h>
   28.28 +#include <emmintrin.h>
   28.29 +
   28.30 +int sse2_ok = 1;
   28.31 +
   28.32 +static inline unsigned int cpuid_edx(unsigned int op)
   28.33 +{
   28.34 +    unsigned int eax, edx;
   28.35 +
   28.36 +    __asm__("cpuid"
   28.37 +            : "=a" (eax), "=d" (edx)
   28.38 +            : "0" (op)
   28.39 +            : "bx", "cx");
   28.40 +
   28.41 +    return edx;
   28.42 +}
   28.43 +
   28.44 +jmp_buf sse_jbuf;
   28.45 +
   28.46 +void intr(int sig)
   28.47 +{
   28.48 +    sse2_ok = 0;
   28.49 +    longjmp(sse_jbuf, 1);
   28.50 +}
   28.51 +
   28.52 +void check_sse2(void)
   28.53 +{
   28.54 +    /* Check 1: What does CPUID say? */
   28.55 +    if ((cpuid_edx(1) & 0x4000000) == 0) {
   28.56 +        sse2_ok = 0;
   28.57 +        return;
   28.58 +    }
   28.59 +
   28.60 +    /* Check 2: Can we use SSE2 in anger? */
   28.61 +    signal(SIGILL, intr);
   28.62 +    if (setjmp(sse_jbuf) == 0)
   28.63 +        __asm__("xorps %xmm0,%xmm0\n");
   28.64 +}
   28.65 +
   28.66 +int vram_dirty(VGAState *s, int offset, int n)
   28.67 +{
   28.68 +    __m128i *sp, *vp;
   28.69 +
   28.70 +    if (s->vram_shadow == NULL)
   28.71 +        return 1;
   28.72 +    if (sse2_ok == 0)
   28.73 +        return cmp_vram(s, offset, n);
   28.74 +    vp = (__m128i *)(s->vram_ptr + offset);
   28.75 +    sp = (__m128i *)(s->vram_shadow + offset);
   28.76 +    while ((n -= sizeof(*vp)) >= 0) {
   28.77 +        if (_mm_movemask_epi8(_mm_cmpeq_epi8(*sp, *vp)) != 0xffff) {
   28.78 +            while (n >= 0) {
   28.79 +                _mm_store_si128(sp++, _mm_load_si128(vp++));
   28.80 +                n -= sizeof(*vp);
   28.81 +            }
   28.82 +            return 1;
   28.83 +        }
   28.84 +        sp++;
   28.85 +        vp++;
   28.86 +    }
   28.87 +    return 0;
   28.88 +}
   28.89 +#else /* !USE_SSE2 */
   28.90 +int vram_dirty(VGAState *s, int offset, int n)
   28.91 +{
   28.92 +    return cmp_vram(s, offset, n);
   28.93 +}
   28.94 +
   28.95 +void check_sse2(void)
   28.96 +{
   28.97 +}
   28.98 +#endif /* !USE_SSE2 */
   28.99 +
  28.100  /* 
  28.101   * graphic modes
  28.102   */
  28.103 @@ -1434,6 +1527,9 @@ static void vga_draw_graphic(VGAState *s
  28.104      printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
  28.105             width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
  28.106  #endif
  28.107 +    for (y = 0; y < s->vram_size; y += TARGET_PAGE_SIZE)
  28.108 +        if (vram_dirty(s, y, TARGET_PAGE_SIZE))
  28.109 +            cpu_physical_memory_set_dirty(s->vram_offset + y);
  28.110      addr1 = (s->start_addr * 4);
  28.111      bwidth = width * 4;
  28.112      y_start = -1;
  28.113 @@ -1536,9 +1632,18 @@ static void vga_draw_blank(VGAState *s, 
  28.114  
  28.115  void vga_update_display(void)
  28.116  {
  28.117 +    static int loop;
  28.118      VGAState *s = vga_state;
  28.119      int full_update, graphic_mode;
  28.120  
  28.121 +    /*
  28.122 +     * Only update the display every other time.  The responsiveness is
  28.123 +     * acceptable and it cuts down on the overhead of the VRAM compare
  28.124 +     * in `vram_dirty'.
  28.125 +     */
  28.126 +    if (loop++ & 1)
  28.127 +        return;
  28.128 +
  28.129      if (s->ds->depth == 0) {
  28.130          /* nothing to do */
  28.131      } else {
  28.132 @@ -1569,7 +1674,6 @@ void vga_update_display(void)
  28.133              full_update = 1;
  28.134          }
  28.135  
  28.136 -        full_update = 1;
  28.137          switch(graphic_mode) {
  28.138          case GMODE_TEXT:
  28.139              vga_draw_text(s, full_update);
  28.140 @@ -1874,7 +1978,13 @@ void vga_common_init(VGAState *s, Displa
  28.141  #else
  28.142      s->vram_ptr = qemu_malloc(vga_ram_size);
  28.143  #endif
  28.144 -
  28.145 +    check_sse2();
  28.146 +    s->vram_shadow = qemu_malloc(vga_ram_size+TARGET_PAGE_SIZE+1);
  28.147 +    if (s->vram_shadow == NULL)
  28.148 +        fprintf(stderr, "Cannot allocate %d bytes for VRAM shadow, "
  28.149 +                "mouse will be slow\n", vga_ram_size);
  28.150 +    s->vram_shadow = (uint8_t *)((long)(s->vram_shadow + TARGET_PAGE_SIZE - 1)
  28.151 +                                 & ~(TARGET_PAGE_SIZE - 1));
  28.152      s->vram_offset = vga_ram_offset;
  28.153      s->vram_size = vga_ram_size;
  28.154      s->ds = ds;
    29.1 --- a/tools/ioemu/hw/vga_int.h	Fri Mar 17 14:26:24 2006 -0700
    29.2 +++ b/tools/ioemu/hw/vga_int.h	Fri Mar 17 15:37:28 2006 -0700
    29.3 @@ -76,6 +76,7 @@
    29.4  
    29.5  #define VGA_STATE_COMMON                                                \
    29.6      uint8_t *vram_ptr;                                                  \
    29.7 +    uint8_t *vram_shadow;                                               \
    29.8      unsigned long vram_offset;                                          \
    29.9      unsigned int vram_size;                                             \
   29.10      uint32_t latch;                                                     \
    30.1 --- a/tools/ioemu/sdl.c	Fri Mar 17 14:26:24 2006 -0700
    30.2 +++ b/tools/ioemu/sdl.c	Fri Mar 17 15:37:28 2006 -0700
    30.3 @@ -405,7 +405,7 @@ static void sdl_send_mouse_event(void)
    30.4      if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
    30.5          dz++;
    30.6  #endif
    30.7 -    kbd_mouse_event(dx, dy, dz, buttons);
    30.8 +    kbd_mouse_event(dx, dy, dz, buttons, 0, 0);
    30.9  }
   30.10  
   30.11  static void toggle_full_screen(DisplayState *ds)
    31.1 --- a/tools/ioemu/target-i386-dm/Makefile	Fri Mar 17 14:26:24 2006 -0700
    31.2 +++ b/tools/ioemu/target-i386-dm/Makefile	Fri Mar 17 15:37:28 2006 -0700
    31.3 @@ -13,8 +13,15 @@ ifdef CONFIG_USER_ONLY
    31.4  VPATH+=:$(SRC_PATH)/linux-user
    31.5  DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
    31.6  endif
    31.7 -CFLAGS+=-g -fno-strict-aliasing
    31.8 -LDFLAGS=-g
    31.9 +
   31.10 +SSE2 := $(call test-gcc-flag,$(CC),-msse2)
   31.11 +ifeq ($(SSE2),-msse2)
   31.12 +CFLAGS += -DUSE_SSE2=1 -msse2
   31.13 +endif
   31.14 +
   31.15 +CFLAGS += -g -fno-strict-aliasing $(LOCAL_CFLAGS)
   31.16 +LDFLAGS = -g
   31.17 +
   31.18  LIBS=
   31.19  HELPER_CFLAGS=$(CFLAGS)
   31.20  DYNGEN=../dyngen$(EXESUF)
    32.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Fri Mar 17 14:26:24 2006 -0700
    32.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Fri Mar 17 15:37:28 2006 -0700
    32.3 @@ -447,9 +447,9 @@ int main_loop(void)
    32.4              }
    32.5          }
    32.6  
    32.7 -        /* Wait up to one seconds. */
    32.8 +        /* Wait up to 10 msec. */
    32.9          tv.tv_sec = 0;
   32.10 -        tv.tv_usec = 100000;
   32.11 +        tv.tv_usec = 10000;
   32.12  
   32.13          retval = select(highest_fds+1, &wakeup_rfds, NULL, NULL, &tv);
   32.14          if (retval == -1) {
    33.1 --- a/tools/ioemu/vl.c	Fri Mar 17 14:26:24 2006 -0700
    33.2 +++ b/tools/ioemu/vl.c	Fri Mar 17 15:37:28 2006 -0700
    33.3 @@ -464,11 +464,11 @@ void kbd_put_keycode(int keycode)
    33.4      }
    33.5  }
    33.6  
    33.7 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
    33.8 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y)
    33.9  {
   33.10      if (qemu_put_mouse_event) {
   33.11          qemu_put_mouse_event(qemu_put_mouse_event_opaque,
   33.12 -                             dx, dy, dz, buttons_state);
   33.13 +                             dx, dy, dz, buttons_state, x, y);
   33.14      }
   33.15  }
   33.16  
    34.1 --- a/tools/ioemu/vl.h	Fri Mar 17 14:26:24 2006 -0700
    34.2 +++ b/tools/ioemu/vl.h	Fri Mar 17 15:37:28 2006 -0700
    34.3 @@ -139,13 +139,13 @@ extern int graphic_depth;
    34.4  #define MOUSE_EVENT_MBUTTON 0x04
    34.5  
    34.6  typedef void QEMUPutKBDEvent(void *opaque, int keycode);
    34.7 -typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
    34.8 +typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state, int x, int y);
    34.9  
   34.10  void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
   34.11  void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
   34.12  
   34.13  void kbd_put_keycode(int keycode);
   34.14 -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
   34.15 +void kbd_mouse_event(int dx, int dy, int dz, int buttons_state, int x, int y);
   34.16  
   34.17  /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
   34.18     constants) */
   34.19 @@ -618,6 +618,12 @@ void kbd_init(void);
   34.20  extern const char* keyboard_layout;
   34.21  extern int repeat_key;
   34.22  
   34.23 +/* Mice */
   34.24 +
   34.25 +void summa_init(void *cookie, CharDriverState *chr);
   34.26 +
   34.27 +extern int summa_ok;
   34.28 +
   34.29  /* mc146818rtc.c */
   34.30  
   34.31  typedef struct RTCState RTCState;
   34.32 @@ -630,6 +636,7 @@ void rtc_set_date(RTCState *s, const str
   34.33  
   34.34  typedef struct SerialState SerialState;
   34.35  SerialState *serial_init(int base, int irq, CharDriverState *chr);
   34.36 +void ser_queue(SerialState *s, unsigned char c);
   34.37  
   34.38  /* i8259.c */
   34.39  
    35.1 --- a/tools/ioemu/vnc.c	Fri Mar 17 14:26:24 2006 -0700
    35.2 +++ b/tools/ioemu/vnc.c	Fri Mar 17 15:37:28 2006 -0700
    35.3 @@ -46,8 +46,9 @@
    35.4  #endif
    35.5  
    35.6  static rfbScreenInfoPtr screen;
    35.7 -static DisplayState* ds_sdl=0;
    35.8 -static void* kbd_layout=0; // TODO: move into rfbClient
    35.9 +static DisplayState* ds_sdl;
   35.10 +static void* kbd_layout; // TODO: move into rfbClient
   35.11 +static int ctl_keys; // Ctrl+Alt starts calibration
   35.12  
   35.13  /* mouse stuff */
   35.14  
   35.15 @@ -123,12 +124,15 @@ typedef struct {
   35.16  static rectangle_t last_update, before_update;
   35.17  static int updates_since_mouse=0;
   35.18  
   35.19 +extern int mouse_maxx, mouse_maxy;
   35.20  static int mouse_x,mouse_y;
   35.21  static int new_mouse_x,new_mouse_y,new_mouse_z,new_mouse_buttons;
   35.22  
   35.23 -static void init_mouse(int initial_x,int initial_y) {
   35.24 -	mouse_x=new_mouse_x=initial_x;
   35.25 -	mouse_y=new_mouse_y=initial_y;
   35.26 +static void init_mouse(int max_x,int max_y) {
   35.27 +	mouse_maxx=max_x - 1;
   35.28 +	mouse_maxy=max_y - 1;
   35.29 +	mouse_x=new_mouse_x=max_x/2;
   35.30 +	mouse_y=new_mouse_y=max_y/2;
   35.31  	new_mouse_z=new_mouse_buttons=0;
   35.32  	mouse_magic->calibration = 0;
   35.33  }
   35.34 @@ -137,6 +141,15 @@ static void mouse_refresh() {
   35.35  	int dx=0,dy=0,dz=new_mouse_z;
   35.36  	static int counter=1;
   35.37  
   35.38 +	/*
   35.39 +	 *  Simulate lifting the mouse by pressing left <ctl><alt> together
   35.40 +	 *  e.g. don't send mouse events.
   35.41 +	 */
   35.42 +	if (ctl_keys == 3) {
   35.43 +		mouse_x = new_mouse_x;
   35.44 +		mouse_y = new_mouse_y;
   35.45 +		return;
   35.46 +	}
   35.47  	counter++;
   35.48  	if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
   35.49  
   35.50 @@ -153,7 +166,7 @@ static void mouse_refresh() {
   35.51  		}
   35.52  	}
   35.53  	//fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
   35.54 -	kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
   35.55 +	kbd_mouse_event(dx,dy,dz,new_mouse_buttons,new_mouse_x,new_mouse_y);
   35.56  	mouse_x+=dx;
   35.57  	mouse_y+=dy;
   35.58  		
   35.59 @@ -237,7 +250,7 @@ static void mouse_calibration_refresh() 
   35.60  	
   35.61  	if(calibration_step==0) {
   35.62  		x=0; y=1;
   35.63 -		kbd_mouse_event(0,-1,0,0);
   35.64 +		kbd_mouse_event(0,-1,0,0,x,y);
   35.65  		calibration_step++;
   35.66  	} else if(calibration_step==1) {
   35.67  		// find out the initial position of the cursor
   35.68 @@ -269,7 +282,7 @@ static void mouse_calibration_refresh() 
   35.69  		} else {
   35.70  			y++;
   35.71  move_calibrate:
   35.72 -			kbd_mouse_event(-x,-y,0,0);
   35.73 +			kbd_mouse_event(-x,-y,0,0,x,y);
   35.74  			before_update=last_update;
   35.75  		}
   35.76  	} else if(calibration_step==3) {
   35.77 @@ -375,12 +388,11 @@ static void vnc_resize(DisplayState *ds,
   35.78  		fprintf(stderr,"Warning: mouse calibration interrupted by video mode change\n");
   35.79  		stop_mouse_calibration();
   35.80  	}
   35.81 -	init_mouse(w/2,h/2);
   35.82 +	init_mouse(w,h);
   35.83  }
   35.84  
   35.85  static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
   35.86  {
   35.87 -	static int magic=0; // Ctrl+Alt starts calibration
   35.88  
   35.89  	if(is_active_console(vga_console)) {
   35.90  		WORD keycode=keysym2scancode(kbd_layout, keySym);
   35.91 @@ -416,24 +428,28 @@ static void vnc_process_key(rfbBool down
   35.92  	}
   35.93  	if(down) {
   35.94  		if(keySym==XK_Control_L)
   35.95 -			magic|=1;
   35.96 +			ctl_keys|=1;
   35.97  		else if(keySym==XK_Alt_L)
   35.98 -			magic|=2;
   35.99 +			ctl_keys|=2;
  35.100  	} else {
  35.101 -		if((magic&3)==3) {
  35.102 +		if (keySym == XK_Control_L)
  35.103 +			ctl_keys &= ~1;
  35.104 +		else if (keySym == XK_Alt_L)
  35.105 +			ctl_keys &= ~2;
  35.106 +		if((ctl_keys&3)==3) {
  35.107  			switch(keySym) {
  35.108  				case XK_Control_L:
  35.109 -					magic&=~1;
  35.110 +					ctl_keys&=~1;
  35.111  					break;
  35.112  				case XK_Alt_L:
  35.113 -					magic&=~2;
  35.114 +					ctl_keys&=~2;
  35.115  					break;
  35.116  				case XK_m:
  35.117 -					magic=0;
  35.118 +					ctl_keys=0;
  35.119  					start_mouse_calibration();
  35.120  					break;
  35.121  				case XK_1 ... XK_9:
  35.122 -					magic=0;
  35.123 +					ctl_keys=0;
  35.124  					fprintf(stderr,"switch to %d\n",keySym-XK_1);
  35.125  					console_select(keySym - XK_1);
  35.126  					if (is_active_console(vga_console)) {
  35.127 @@ -483,7 +499,8 @@ void vnc_display_init(DisplayState *ds, 
  35.128      char  host[1024];
  35.129      char *p;
  35.130      rfbClientPtr cl;
  35.131 -    
  35.132 +
  35.133 +	summa_ok = 1;
  35.134  	if(!keyboard_layout) {
  35.135  		fprintf(stderr, "No keyboard language specified\n");
  35.136  		exit(1);
  35.137 @@ -514,6 +531,10 @@ void vnc_display_init(DisplayState *ds, 
  35.138  	screen->serverFormat.greenMax = 63;
  35.139  	screen->serverFormat.blueMax = 31;
  35.140  
  35.141 +#ifdef	VNC_EAGER_EVENTS
  35.142 +	screen->handleEventsEagerly = TRUE;
  35.143 +#endif	// VNC_EAGER_EVENTS
  35.144 +
  35.145      if (port != 0) 
  35.146          screen->port = port;
  35.147      else
    36.1 --- a/tools/libxc/xg_private.c	Fri Mar 17 14:26:24 2006 -0700
    36.2 +++ b/tools/libxc/xg_private.c	Fri Mar 17 15:37:28 2006 -0700
    36.3 @@ -77,10 +77,11 @@ char *xc_inflate_buffer(const char *in_b
    36.4          return (char *)in_buf;
    36.5      }
    36.6  
    36.7 -    out_len = in_buf[in_size-4] +
    36.8 -        (256 * (in_buf[in_size-3] +
    36.9 -                (256 * (in_buf[in_size-2] +
   36.10 -                        (256 * in_buf[in_size-1])))));
   36.11 +    out_len = (unsigned char)in_buf[in_size-4] +
   36.12 +        (256 * ((unsigned char)in_buf[in_size-3] +
   36.13 +                (256 * ((unsigned char)in_buf[in_size-2] +
   36.14 +                        (256 * (unsigned char)in_buf[in_size-1])))));
   36.15 +
   36.16      bzero(&zStream, sizeof(zStream));
   36.17      out_buf = malloc(out_len + 16);        /* Leave a little extra space */
   36.18      if ( out_buf == NULL )
    37.1 --- a/tools/xenstore/xenstored_core.c	Fri Mar 17 14:26:24 2006 -0700
    37.2 +++ b/tools/xenstore/xenstored_core.c	Fri Mar 17 15:37:28 2006 -0700
    37.3 @@ -1113,6 +1113,34 @@ static void do_set_perms(struct connecti
    37.4  	send_ack(conn, XS_SET_PERMS);
    37.5  }
    37.6  
    37.7 +static void do_debug(struct connection *conn, struct buffered_data *in)
    37.8 +{
    37.9 +	int num;
   37.10 +
   37.11 +	num = xs_count_strings(in->buffer, in->used);
   37.12 +
   37.13 +	if (streq(in->buffer, "print")) {
   37.14 +		if (num < 2) {
   37.15 +			send_error(conn, EINVAL);
   37.16 +			return;
   37.17 +		}
   37.18 +		xprintf("debug: %s", in->buffer + get_string(in, 0));
   37.19 +	}
   37.20 +	if (streq(in->buffer, "check"))
   37.21 +		check_store();
   37.22 +#ifdef TESTING
   37.23 +	/* For testing, we allow them to set id. */
   37.24 +	if (streq(in->buffer, "setid")) {
   37.25 +		conn->id = atoi(in->buffer + get_string(in, 0));
   37.26 +	} else if (streq(in->buffer, "failtest")) {
   37.27 +		if (get_string(in, 0) < in->used)
   37.28 +			srandom(atoi(in->buffer + get_string(in, 0)));
   37.29 +		failtest = true;
   37.30 +	}
   37.31 +#endif /* TESTING */
   37.32 +	send_ack(conn, XS_DEBUG);
   37.33 +}
   37.34 +
   37.35  /* Process "in" for conn: "in" will vanish after this conversation, so
   37.36   * we can talloc off it for temporary variables.  May free "conn".
   37.37   */
   37.38 @@ -1159,21 +1187,7 @@ static void process_message(struct conne
   37.39  		break;
   37.40  
   37.41  	case XS_DEBUG:
   37.42 -		if (streq(in->buffer, "print"))
   37.43 -			xprintf("debug: %s", in->buffer + get_string(in, 0));
   37.44 -		if (streq(in->buffer, "check"))
   37.45 -			check_store();
   37.46 -#ifdef TESTING
   37.47 -		/* For testing, we allow them to set id. */
   37.48 -		if (streq(in->buffer, "setid")) {
   37.49 -			conn->id = atoi(in->buffer + get_string(in, 0));
   37.50 -		} else if (streq(in->buffer, "failtest")) {
   37.51 -			if (get_string(in, 0) < in->used)
   37.52 -				srandom(atoi(in->buffer + get_string(in, 0)));
   37.53 -			failtest = true;
   37.54 -		}
   37.55 -#endif /* TESTING */
   37.56 -		send_ack(conn, XS_DEBUG);
   37.57 +		do_debug(conn, in);
   37.58  		break;
   37.59  
   37.60  	case XS_WATCH:
    38.1 --- a/xen/arch/ia64/xen/xentime.c	Fri Mar 17 14:26:24 2006 -0700
    38.2 +++ b/xen/arch/ia64/xen/xentime.c	Fri Mar 17 15:37:28 2006 -0700
    38.3 @@ -265,4 +265,8 @@ int reprogram_timer(s_time_t timeout)
    38.4  	return 1;
    38.5  }
    38.6  
    38.7 +void send_timer_event(struct vcpu *v)
    38.8 +{
    38.9 +	send_guest_virq(v, VIRQ_TIMER);
   38.10 +}
   38.11  
    39.1 --- a/xen/arch/x86/domain.c	Fri Mar 17 14:26:24 2006 -0700
    39.2 +++ b/xen/arch/x86/domain.c	Fri Mar 17 15:37:28 2006 -0700
    39.3 @@ -1030,10 +1030,10 @@ void domain_relinquish_resources(struct 
    39.4  
    39.5              v->arch.guest_table_user = mk_pagetable(0);
    39.6          }
    39.7 +    }
    39.8  
    39.9 -        if ( hvm_guest(v) )
   39.10 -            hvm_relinquish_guest_resources(v);
   39.11 -    }
   39.12 +    if ( hvm_guest(d->vcpu[0]) )
   39.13 +        hvm_relinquish_guest_resources(d);
   39.14  
   39.15      shadow_mode_disable(d);
   39.16  
    40.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Mar 17 14:26:24 2006 -0700
    40.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Fri Mar 17 15:37:28 2006 -0700
    40.3 @@ -77,6 +77,8 @@ void svm_manual_event_injection32(struct
    40.4          int vector, int has_code);
    40.5  void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
    40.6  
    40.7 +static void svm_relinquish_guest_resources(struct domain *d);
    40.8 +
    40.9  static struct asid_pool ASIDpool[NR_CPUS];
   40.10  
   40.11  /*
   40.12 @@ -198,12 +200,6 @@ int svm_initialize_guest_resources(struc
   40.13      return 1;
   40.14  }
   40.15  
   40.16 -int svm_relinquish_guest_resources(struct vcpu *v)
   40.17 -{
   40.18 -    svm_relinquish_resources(v);
   40.19 -    return 1;
   40.20 -}
   40.21 -
   40.22  void svm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
   40.23  {
   40.24      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   40.25 @@ -722,43 +718,35 @@ void svm_final_setup_guest(struct vcpu *
   40.26  }
   40.27  
   40.28  
   40.29 -void svm_relinquish_resources(struct vcpu *v)
   40.30 +static void svm_relinquish_guest_resources(struct domain *d)
   40.31  {
   40.32 -    struct hvm_virpit *vpit;
   40.33      extern void destroy_vmcb(struct arch_svm_struct *); /* XXX */
   40.34 -
   40.35 -#if 0
   40.36 -    /* 
   40.37 -     * This is not stored at the moment. We need to keep it somewhere and free
   40.38 -     * it Or maybe not, as it's a per-cpu-core item, and I guess we don't
   40.39 -     * normally remove CPU's other than for hot-plug capable systems, where I
   40.40 -     * guess we have to allocate and free host-save area in this case. Let's
   40.41 -     * not worry about it at the moment, as loosing one page per CPU hot-plug
   40.42 -     * event doesn't seem that excessive. But I may be wrong.
   40.43 -     */
   40.44 -    free_host_save_area(v->arch.hvm_svm.host_save_area);
   40.45 -#endif
   40.46 -
   40.47 -    if ( v->vcpu_id == 0 )
   40.48 +    struct vcpu *v;
   40.49 +
   40.50 +    for_each_vcpu ( d, v )
   40.51      {
   40.52 -        /* unmap IO shared page */
   40.53 -        struct domain *d = v->domain;
   40.54 -        if ( d->arch.hvm_domain.shared_page_va )
   40.55 -            unmap_domain_page_global(
   40.56 -                (void *)d->arch.hvm_domain.shared_page_va);
   40.57 -        shadow_direct_map_clean(d);
   40.58 +#if 0
   40.59 +        /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
   40.60 +        free_host_save_area(v->arch.hvm_svm.host_save_area);
   40.61 +#endif
   40.62 +
   40.63 +        destroy_vmcb(&v->arch.hvm_svm);
   40.64 +        free_monitor_pagetable(v);
   40.65 +        kill_timer(&v->arch.hvm_svm.hlt_timer);
   40.66 +        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
   40.67 +        {
   40.68 +            kill_timer( &(VLAPIC(v)->vlapic_timer) );
   40.69 +            xfree(VLAPIC(v));
   40.70 +        }
   40.71      }
   40.72  
   40.73 -    destroy_vmcb(&v->arch.hvm_svm);
   40.74 -    free_monitor_pagetable(v);
   40.75 -    vpit = &v->domain->arch.hvm_domain.vpit;
   40.76 -    kill_timer(&vpit->pit_timer);
   40.77 -    kill_timer(&v->arch.hvm_svm.hlt_timer);
   40.78 -    if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
   40.79 -    {
   40.80 -        kill_timer( &(VLAPIC(v)->vlapic_timer) );
   40.81 -        xfree( VLAPIC(v) );
   40.82 -    }
   40.83 +    kill_timer(&d->arch.hvm_domain.vpit.pit_timer);
   40.84 +
   40.85 +    if ( d->arch.hvm_domain.shared_page_va )
   40.86 +        unmap_domain_page_global(
   40.87 +            (void *)d->arch.hvm_domain.shared_page_va);
   40.88 +
   40.89 +    shadow_direct_map_clean(d);
   40.90  }
   40.91  
   40.92  
    41.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 17 14:26:24 2006 -0700
    41.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 17 15:37:28 2006 -0700
    41.3 @@ -78,30 +78,30 @@ void vmx_final_setup_guest(struct vcpu *
    41.4      }
    41.5  }
    41.6  
    41.7 -void vmx_relinquish_resources(struct vcpu *v)
    41.8 +static void vmx_relinquish_guest_resources(struct domain *d)
    41.9  {
   41.10 -    struct hvm_virpit *vpit;
   41.11 +    struct vcpu *v;
   41.12  
   41.13 -    if (v->vcpu_id == 0) {
   41.14 -        /* unmap IO shared page */
   41.15 -        struct domain *d = v->domain;
   41.16 -        if ( d->arch.hvm_domain.shared_page_va )
   41.17 -            unmap_domain_page_global(
   41.18 -	        (void *)d->arch.hvm_domain.shared_page_va);
   41.19 -        shadow_direct_map_clean(d);
   41.20 +    for_each_vcpu ( d, v )
   41.21 +    {
   41.22 +        vmx_request_clear_vmcs(v);
   41.23 +        destroy_vmcs(&v->arch.hvm_vmx);
   41.24 +        free_monitor_pagetable(v);
   41.25 +        kill_timer(&v->arch.hvm_vmx.hlt_timer);
   41.26 +        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
   41.27 +        {
   41.28 +            kill_timer(&VLAPIC(v)->vlapic_timer);
   41.29 +            xfree(VLAPIC(v));
   41.30 +        }
   41.31      }
   41.32  
   41.33 -    vmx_request_clear_vmcs(v);
   41.34 -    destroy_vmcs(&v->arch.hvm_vmx);
   41.35 -    free_monitor_pagetable(v);
   41.36 -    vpit = &v->domain->arch.hvm_domain.vpit;
   41.37 -    kill_timer(&vpit->pit_timer);
   41.38 -    kill_timer(&v->arch.hvm_vmx.hlt_timer);
   41.39 -    if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
   41.40 -    {
   41.41 -        kill_timer(&VLAPIC(v)->vlapic_timer);
   41.42 -        xfree(VLAPIC(v));
   41.43 -    }
   41.44 +    kill_timer(&d->arch.hvm_domain.vpit.pit_timer);
   41.45 +
   41.46 +    if ( d->arch.hvm_domain.shared_page_va )
   41.47 +        unmap_domain_page_global(
   41.48 +	        (void *)d->arch.hvm_domain.shared_page_va);
   41.49 +
   41.50 +    shadow_direct_map_clean(d);
   41.51  }
   41.52  
   41.53  #ifdef __x86_64__
   41.54 @@ -231,10 +231,9 @@ static inline int long_mode_do_msr_write
   41.55          if ((msr_content & EFER_LME) ^
   41.56              test_bit(VMX_CPU_STATE_LME_ENABLED,
   41.57                       &vc->arch.hvm_vmx.cpu_state)){
   41.58 -            if (test_bit(VMX_CPU_STATE_PG_ENABLED,
   41.59 -                         &vc->arch.hvm_vmx.cpu_state) ||
   41.60 -                !test_bit(VMX_CPU_STATE_PAE_ENABLED,
   41.61 -                          &vc->arch.hvm_vmx.cpu_state)){
   41.62 +            if ( vmx_paging_enabled(vc) ||
   41.63 +                 !test_bit(VMX_CPU_STATE_PAE_ENABLED,
   41.64 +                           &vc->arch.hvm_vmx.cpu_state)) {
   41.65                  vmx_inject_exception(vc, TRAP_gp_fault, 0);
   41.66              }
   41.67          }
   41.68 @@ -327,12 +326,6 @@ int vmx_initialize_guest_resources(struc
   41.69      return 1;
   41.70  }
   41.71  
   41.72 -int vmx_relinquish_guest_resources(struct vcpu *v)
   41.73 -{
   41.74 -    vmx_relinquish_resources(v);
   41.75 -    return 1;
   41.76 -}
   41.77 -
   41.78  void vmx_migrate_timers(struct vcpu *v)
   41.79  {
   41.80      struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
   41.81 @@ -677,27 +670,31 @@ static void vmx_do_no_device_fault(void)
   41.82  /* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */
   41.83  #define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46
   41.84  
   41.85 -static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
   41.86 +static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs)
   41.87  {
   41.88 +    unsigned int input = (unsigned int)regs->eax;
   41.89 +    unsigned int count = (unsigned int)regs->ecx;
   41.90      unsigned int eax, ebx, ecx, edx;
   41.91      unsigned long eip;
   41.92      struct vcpu *v = current;
   41.93  
   41.94      __vmread(GUEST_RIP, &eip);
   41.95  
   41.96 -    HVM_DBG_LOG(DBG_LEVEL_1,
   41.97 -                "do_cpuid: (eax) %lx, (ebx) %lx, (ecx) %lx, (edx) %lx,"
   41.98 -                " (esi) %lx, (edi) %lx",
   41.99 +    HVM_DBG_LOG(DBG_LEVEL_3, "(eax) 0x%08lx, (ebx) 0x%08lx, "
  41.100 +                "(ecx) 0x%08lx, (edx) 0x%08lx, (esi) 0x%08lx, (edi) 0x%08lx",
  41.101                  (unsigned long)regs->eax, (unsigned long)regs->ebx,
  41.102                  (unsigned long)regs->ecx, (unsigned long)regs->edx,
  41.103                  (unsigned long)regs->esi, (unsigned long)regs->edi);
  41.104  
  41.105 -    cpuid(input, &eax, &ebx, &ecx, &edx);
  41.106 +    if ( input == 4 )
  41.107 +        cpuid_count(input, count, &eax, &ebx, &ecx, &edx);
  41.108 +    else
  41.109 +        cpuid(input, &eax, &ebx, &ecx, &edx);
  41.110  
  41.111      if ( input == 1 )
  41.112      {
  41.113          if ( hvm_apic_support(v->domain) &&
  41.114 -                !vlapic_global_enabled((VLAPIC(v))) )
  41.115 +             !vlapic_global_enabled((VLAPIC(v))) )
  41.116              clear_bit(X86_FEATURE_APIC, &edx);
  41.117  
  41.118  #if CONFIG_PAGING_LEVELS < 3
  41.119 @@ -732,10 +729,12 @@ static void vmx_vmexit_do_cpuid(unsigned
  41.120      regs->ecx = (unsigned long) ecx;
  41.121      regs->edx = (unsigned long) edx;
  41.122  
  41.123 -    HVM_DBG_LOG(DBG_LEVEL_1,
  41.124 -                "vmx_vmexit_do_cpuid: eip: %lx, input: %lx, out:eax=%x, ebx=%x, ecx=%x, edx=%x",
  41.125 -                eip, input, eax, ebx, ecx, edx);
  41.126 -
  41.127 +    HVM_DBG_LOG(DBG_LEVEL_3, "eip@%lx, input: 0x%lx, "
  41.128 +                "output: eax = 0x%08lx, ebx = 0x%08lx, "
  41.129 +                "ecx = 0x%08lx, edx = 0x%08lx",
  41.130 +                (unsigned long)eip, (unsigned long)input,
  41.131 +                (unsigned long)eax, (unsigned long)ebx,
  41.132 +                (unsigned long)ecx, (unsigned long)edx);
  41.133  }
  41.134  
  41.135  #define CASE_GET_REG_P(REG, reg)    \
  41.136 @@ -1220,8 +1219,6 @@ static int vmx_set_cr0(unsigned long val
  41.137  
  41.138      if ( (value & X86_CR0_PE) && (value & X86_CR0_PG) && !paging_enabled )
  41.139      {
  41.140 -        unsigned long cr4;
  41.141 -
  41.142          /*
  41.143           * Trying to enable guest paging.
  41.144           * The guest CR3 must be pointing to the guest physical.
  41.145 @@ -1272,16 +1269,6 @@ static int vmx_set_cr0(unsigned long val
  41.146  #endif
  41.147          }
  41.148  
  41.149 -        /* update CR4's PAE if needed */
  41.150 -        __vmread(GUEST_CR4, &cr4);
  41.151 -        if ( (!(cr4 & X86_CR4_PAE)) &&
  41.152 -             test_bit(VMX_CPU_STATE_PAE_ENABLED,
  41.153 -                      &v->arch.hvm_vmx.cpu_state) )
  41.154 -        {
  41.155 -            HVM_DBG_LOG(DBG_LEVEL_1, "enable PAE in cr4\n");
  41.156 -            __vmwrite(GUEST_CR4, cr4 | X86_CR4_PAE);
  41.157 -        }
  41.158 -
  41.159          /*
  41.160           * Now arch.guest_table points to machine physical.
  41.161           */
  41.162 @@ -2033,8 +2020,8 @@ asmlinkage void vmx_vmexit_handler(struc
  41.163          __hvm_bug(&regs);
  41.164          break;
  41.165      case EXIT_REASON_CPUID:
  41.166 +        vmx_vmexit_do_cpuid(&regs);
  41.167          __get_instruction_length(inst_len);
  41.168 -        vmx_vmexit_do_cpuid(regs.eax, &regs);
  41.169          __update_guest_eip(inst_len);
  41.170          break;
  41.171      case EXIT_REASON_HLT:
    42.1 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S	Fri Mar 17 14:26:24 2006 -0700
    42.2 +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S	Fri Mar 17 15:37:28 2006 -0700
    42.3 @@ -89,7 +89,7 @@ ENTRY(vmx_asm_vmexit_handler)
    42.4          call vmx_vmexit_handler
    42.5          jmp vmx_asm_do_resume
    42.6  
    42.7 -.macro vmx_asm_common launch initialized
    42.8 +.macro vmx_asm_common launch, initialized
    42.9  1:
   42.10  /* vmx_test_all_events */
   42.11          .if \initialized
   42.12 @@ -140,10 +140,10 @@ 2:
   42.13  .endm
   42.14  
   42.15  ENTRY(vmx_asm_do_launch)
   42.16 -    vmx_asm_common 1 0
   42.17 +    vmx_asm_common 1, 0
   42.18  
   42.19  ENTRY(vmx_asm_do_resume)
   42.20 -    vmx_asm_common 0 1
   42.21 +    vmx_asm_common 0, 1
   42.22  
   42.23  ENTRY(vmx_asm_do_relaunch)
   42.24 -    vmx_asm_common 1 1
   42.25 +    vmx_asm_common 1, 1
    43.1 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S	Fri Mar 17 14:26:24 2006 -0700
    43.2 +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S	Fri Mar 17 15:37:28 2006 -0700
    43.3 @@ -97,7 +97,7 @@ ENTRY(vmx_asm_vmexit_handler)
    43.4          call vmx_vmexit_handler
    43.5          jmp vmx_asm_do_resume
    43.6  
    43.7 -.macro vmx_asm_common launch initialized 
    43.8 +.macro vmx_asm_common launch, initialized 
    43.9  1:
   43.10          .if \initialized
   43.11  /* vmx_test_all_events */
   43.12 @@ -147,10 +147,10 @@ 2:
   43.13  .endm
   43.14  
   43.15  ENTRY(vmx_asm_do_launch)
   43.16 -      vmx_asm_common 1 0
   43.17 +      vmx_asm_common 1, 0
   43.18  
   43.19  ENTRY(vmx_asm_do_resume)
   43.20 -      vmx_asm_common 0 1
   43.21 +      vmx_asm_common 0, 1
   43.22  
   43.23  ENTRY(vmx_asm_do_relaunch)
   43.24 -      vmx_asm_common 1 1
   43.25 +      vmx_asm_common 1, 1
    44.1 --- a/xen/arch/x86/time.c	Fri Mar 17 14:26:24 2006 -0700
    44.2 +++ b/xen/arch/x86/time.c	Fri Mar 17 15:37:28 2006 -0700
    44.3 @@ -923,6 +923,11 @@ void __init early_time_init(void)
    44.4      setup_irq(0, &irq0);
    44.5  }
    44.6  
    44.7 +void send_timer_event(struct vcpu *v)
    44.8 +{
    44.9 +    send_guest_virq(v, VIRQ_TIMER);
   44.10 +}
   44.11 +
   44.12  /*
   44.13   * Local variables:
   44.14   * mode: C
    45.1 --- a/xen/common/sched_sedf.c	Fri Mar 17 14:26:24 2006 -0700
    45.2 +++ b/xen/common/sched_sedf.c	Fri Mar 17 15:37:28 2006 -0700
    45.3 @@ -57,11 +57,9 @@
    45.4  #define WEIGHT_PERIOD (MILLISECS(100))
    45.5  #define WEIGHT_SAFETY (MILLISECS(5))
    45.6  
    45.7 -/* FIXME: need to validate that these are sane */
    45.8 -#define PERIOD_MAX ULONG_MAX
    45.9 -#define PERIOD_MIN (MICROSECS(10))
   45.10 -#define SLICE_MAX ULONG_MAX
   45.11 -#define SLICE_MIN (MICROSECS(5))
   45.12 +#define PERIOD_MAX MILLISECS(10000) /* 10s  */
   45.13 +#define PERIOD_MIN (MICROSECS(10))  /* 10us */
   45.14 +#define SLICE_MIN (MICROSECS(5))    /*  5us */
   45.15  
   45.16  #define IMPLY(a, b) (!(a) || (b))
   45.17  #define EQ(a, b) ((!!(a)) == (!!(b)))
   45.18 @@ -1617,9 +1615,8 @@ static int sedf_adjdom(struct domain *p,
   45.19                   */
   45.20                  if ( (cmd->u.sedf.period > PERIOD_MAX) ||
   45.21                       (cmd->u.sedf.period < PERIOD_MIN) ||
   45.22 -                     (cmd->u.sedf.slice  > SLICE_MAX)  ||
   45.23 -                     (cmd->u.sedf.slice  < SLICE_MIN)  ||
   45.24 -                     (cmd->u.sedf.slice > cmd->u.sedf.period) )
   45.25 +                     (cmd->u.sedf.slice  > cmd->u.sedf.period) ||
   45.26 +                     (cmd->u.sedf.slice  < SLICE_MIN) )
   45.27                      return -EINVAL;
   45.28                  EDOM_INFO(v)->weight = 0;
   45.29                  EDOM_INFO(v)->extraweight = 0;
    46.1 --- a/xen/common/schedule.c	Fri Mar 17 14:26:24 2006 -0700
    46.2 +++ b/xen/common/schedule.c	Fri Mar 17 15:37:28 2006 -0700
    46.3 @@ -574,7 +574,7 @@ static void __enter_scheduler(void)
    46.4      {
    46.5          update_dom_time(next);
    46.6          if ( next->sleep_tick != schedule_data[cpu].tick )
    46.7 -            send_guest_virq(next, VIRQ_TIMER);
    46.8 +            send_timer_event(next);
    46.9      }
   46.10  
   46.11      TRACE_4D(TRC_SCHED_SWITCH,
   46.12 @@ -610,7 +610,7 @@ static void t_timer_fn(void *unused)
   46.13      if ( !is_idle_vcpu(v) )
   46.14      {
   46.15          update_dom_time(v);
   46.16 -        send_guest_virq(v, VIRQ_TIMER);
   46.17 +        send_timer_event(v);
   46.18      }
   46.19  
   46.20      page_scrub_schedule_work();
   46.21 @@ -624,7 +624,7 @@ static void dom_timer_fn(void *data)
   46.22      struct vcpu *v = data;
   46.23  
   46.24      update_dom_time(v);
   46.25 -    send_guest_virq(v, VIRQ_TIMER);
   46.26 +    send_timer_event(v);
   46.27  }
   46.28  
   46.29  /* SCHEDOP_poll timeout callback. */
    47.1 --- a/xen/drivers/char/console.c	Fri Mar 17 14:26:24 2006 -0700
    47.2 +++ b/xen/drivers/char/console.c	Fri Mar 17 15:37:28 2006 -0700
    47.3 @@ -683,8 +683,6 @@ void panic(const char *fmt, ...)
    47.4      (void)vsnprintf(buf, sizeof(buf), fmt, args);
    47.5      va_end(args);
    47.6  
    47.7 -    debugger_trap_immediate();
    47.8 -
    47.9      /* Spit out multiline message in one go. */
   47.10      spin_lock_irqsave(&lock, flags);
   47.11      printk("\n****************************************\n");
   47.12 @@ -694,6 +692,8 @@ void panic(const char *fmt, ...)
   47.13      printk("Reboot in five seconds...\n");
   47.14      spin_unlock_irqrestore(&lock, flags);
   47.15  
   47.16 +    debugger_trap_immediate();
   47.17 +
   47.18      watchdog_disable();
   47.19      mdelay(5000);
   47.20      machine_restart(0);
    48.1 --- a/xen/include/asm-x86/hvm/hvm.h	Fri Mar 17 14:26:24 2006 -0700
    48.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Fri Mar 17 15:37:28 2006 -0700
    48.3 @@ -35,8 +35,8 @@ struct hvm_function_table {
    48.4      /*
    48.5       * Initialize/relinguish HVM guest resources
    48.6       */
    48.7 -    int (*initialize_guest_resources)(struct vcpu *v);
    48.8 -    int (*relinquish_guest_resources)(struct vcpu *v);
    48.9 +    int  (*initialize_guest_resources)(struct vcpu *v);
   48.10 +    void (*relinquish_guest_resources)(struct domain *d);
   48.11  
   48.12      /*
   48.13       * Store and load guest state:
   48.14 @@ -80,24 +80,23 @@ extern struct hvm_function_table hvm_fun
   48.15  static inline void
   48.16  hvm_disable(void)
   48.17  {
   48.18 -    if (hvm_funcs.disable)
   48.19 -	hvm_funcs.disable();
   48.20 +    if ( hvm_funcs.disable )
   48.21 +        hvm_funcs.disable();
   48.22  }
   48.23  
   48.24  static inline int
   48.25  hvm_initialize_guest_resources(struct vcpu *v)
   48.26  {
   48.27 -    if (hvm_funcs.initialize_guest_resources)
   48.28 -	return hvm_funcs.initialize_guest_resources(v);
   48.29 +    if ( hvm_funcs.initialize_guest_resources )
   48.30 +        return hvm_funcs.initialize_guest_resources(v);
   48.31      return 0;
   48.32  }
   48.33  
   48.34 -static inline int
   48.35 -hvm_relinquish_guest_resources(struct vcpu *v)
   48.36 +static inline void
   48.37 +hvm_relinquish_guest_resources(struct domain *d)
   48.38  {
   48.39      if (hvm_funcs.relinquish_guest_resources)
   48.40 -	return hvm_funcs.relinquish_guest_resources(v);
   48.41 -    return 0;
   48.42 +        hvm_funcs.relinquish_guest_resources(d);
   48.43  }
   48.44  
   48.45  static inline void
   48.46 @@ -134,9 +133,9 @@ hvm_restore_msrs(struct vcpu *v)
   48.47          hvm_funcs.restore_msrs(v);
   48.48  }
   48.49  #else
   48.50 -#define	hvm_save_segments(v)	((void)0)
   48.51 -#define	hvm_load_msrs(v)	((void)0)
   48.52 -#define	hvm_restore_msrs(v)	((void)0)
   48.53 +#define hvm_save_segments(v)    ((void)0)
   48.54 +#define hvm_load_msrs(v)        ((void)0)
   48.55 +#define hvm_restore_msrs(v)     ((void)0)
   48.56  #endif /* __x86_64__ */
   48.57  
   48.58  static inline void
    49.1 --- a/xen/include/asm-x86/hvm/svm/svm.h	Fri Mar 17 14:26:24 2006 -0700
    49.2 +++ b/xen/include/asm-x86/hvm/svm/svm.h	Fri Mar 17 15:37:28 2006 -0700
    49.3 @@ -44,7 +44,6 @@ extern void svm_vmread(struct vcpu *v, i
    49.4  extern void svm_vmwrite(struct vcpu *v, int index, unsigned long value);
    49.5  extern void svm_final_setup_guest(struct vcpu *v); 
    49.6  extern int svm_paging_enabled(struct vcpu *v); 
    49.7 -extern void svm_relinquish_resources(struct vcpu *v);
    49.8  extern void svm_dump_vmcb(const char *from, struct vmcb_struct *vmcb);
    49.9  extern void svm_stts(struct vcpu *v); 
   49.10  extern void svm_do_launch(struct vcpu *v);
    50.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 17 14:26:24 2006 -0700
    50.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 17 15:37:28 2006 -0700
    50.3 @@ -28,13 +28,11 @@ extern int start_vmx(void);
    50.4  extern void stop_vmx(void);
    50.5  
    50.6  void vmx_final_setup_guest(struct vcpu *v);
    50.7 -void vmx_relinquish_resources(struct vcpu *v);
    50.8  
    50.9  void vmx_enter_scheduler(void);
   50.10  
   50.11  enum {
   50.12 -    VMX_CPU_STATE_PG_ENABLED=0,
   50.13 -    VMX_CPU_STATE_PAE_ENABLED,
   50.14 +    VMX_CPU_STATE_PAE_ENABLED=0,
   50.15      VMX_CPU_STATE_LME_ENABLED,
   50.16      VMX_CPU_STATE_LMA_ENABLED,
   50.17      VMX_CPU_STATE_ASSIST_ENABLED,
    51.1 --- a/xen/include/asm-x86/mm.h	Fri Mar 17 14:26:24 2006 -0700
    51.2 +++ b/xen/include/asm-x86/mm.h	Fri Mar 17 15:37:28 2006 -0700
    51.3 @@ -100,7 +100,7 @@ struct page_info
    51.4  
    51.5  #ifdef __x86_64__
    51.6  #define PGT_high_mfn_shift  52
    51.7 -#define PGT_high_mfn_mask   (0x7ffUL << PGT_high_mfn_shift)
    51.8 +#define PGT_high_mfn_mask   (0xfffUL << PGT_high_mfn_shift)
    51.9  #define PGT_mfn_mask        (((1U<<23)-1) | PGT_high_mfn_mask)
   51.10  #define PGT_high_mfn_nx     (0x800UL << PGT_high_mfn_shift)
   51.11  #else
   51.12 @@ -363,8 +363,8 @@ void audit_domains(void);
   51.13  
   51.14  #ifdef PERF_ARRAYS
   51.15  
   51.16 -void ptwr_eip_stat_reset();
   51.17 -void ptwr_eip_stat_print();
   51.18 +void ptwr_eip_stat_reset(void);
   51.19 +void ptwr_eip_stat_print(void);
   51.20  
   51.21  #else
   51.22  
    52.1 --- a/xen/include/public/sched.h	Fri Mar 17 14:26:24 2006 -0700
    52.2 +++ b/xen/include/public/sched.h	Fri Mar 17 15:37:28 2006 -0700
    52.3 @@ -12,24 +12,18 @@
    52.4  #include "event_channel.h"
    52.5  
    52.6  /*
    52.7 - * There are two forms of this hypercall.
    52.8 - * 
    52.9 - * The first and preferred version is only available from Xen 3.0.2. 
   52.10   * The prototype for this hypercall is:
   52.11   *  long sched_op_new(int cmd, void *arg)
   52.12   * @cmd == SCHEDOP_??? (scheduler operation).
   52.13   * @arg == Operation-specific extra argument(s), as described below.
   52.14   * 
   52.15 - * The legacy version of this hypercall supports only the following commands:
   52.16 - * SCHEDOP_yield, SCHEDOP_block, and SCHEDOP_shutdown. The prototype for the
   52.17 - * legacy hypercall is:
   52.18 + * **NOTE**:
   52.19 + * Versions of Xen prior to 3.0.2 provide only the following legacy version
   52.20 + * of this hypercall, supporting only the commands yield, block and shutdown:
   52.21   *  long sched_op(int cmd, unsigned long arg)
   52.22   * @cmd == SCHEDOP_??? (scheduler operation).
   52.23   * @arg == 0               (SCHEDOP_yield and SCHEDOP_block)
   52.24   *      == SHUTDOWN_* code (SCHEDOP_shutdown)
   52.25 - * 
   52.26 - * The sub-command descriptions below describe extra arguments for the
   52.27 - * sched_op_new() hypercall.
   52.28   */
   52.29  
   52.30  /*
    53.1 --- a/xen/include/xen/time.h	Fri Mar 17 14:26:24 2006 -0700
    53.2 +++ b/xen/include/xen/time.h	Fri Mar 17 15:37:28 2006 -0700
    53.3 @@ -59,6 +59,8 @@ extern void update_dom_time(struct vcpu 
    53.4  extern void do_settime(
    53.5      unsigned long secs, unsigned long nsecs, u64 system_time_base);
    53.6  
    53.7 +extern void send_timer_event(struct vcpu *v);
    53.8 +
    53.9  #endif /* __XEN_TIME_H__ */
   53.10  
   53.11  /*