direct-io.hg

changeset 1625:489b925b0e22

bitkeeper revision 1.1030 (40e1c7ecu4wKzzQZ32aoNCXtRj9smw)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/hp.bk
author kaf24@scramble.cl.cam.ac.uk
date Tue Jun 29 19:50:04 2004 +0000 (2004-06-29)
parents 236a9f2698a3 954bece440ef
children 3304775ae8eb
files .rootkeys linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c xen/arch/x86/boot/boot.S xen/arch/x86/mm.c xen/common/kernel.c xen/common/memory.c xen/common/shadow.c xen/include/asm-x86/config.h xen/include/asm-x86/page.h xen/include/asm-x86/string.h xen/include/asm-x86/types.h xen/include/asm-x86/x86_32/string.h xen/include/asm-x86/x86_64/string.h xen/include/xen/mm.h
line diff
     1.1 --- a/.rootkeys	Tue Jun 29 19:45:18 2004 +0000
     1.2 +++ b/.rootkeys	Tue Jun 29 19:50:04 2004 +0000
     1.3 @@ -454,18 +454,20 @@ 3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/inclu
     1.4  3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/include/asm-x86/smp.h
     1.5  3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-x86/smpboot.h
     1.6  3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-x86/spinlock.h
     1.7 -3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/string.h
     1.8 +40e1966akOHWvvunCED7x3HPv35QvQ xen/include/asm-x86/string.h
     1.9  3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-x86/system.h
    1.10  3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-x86/types.h
    1.11  40cf1596saFaHD5DC5zvrSn7CDCWGQ xen/include/asm-x86/uaccess.h
    1.12  3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h
    1.13  3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/ptrace.h
    1.14 +3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
    1.15  3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
    1.16  404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
    1.17  404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
    1.18  404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
    1.19  404f1bb1LSCqrMDSfRAti5NdMQPJBQ xen/include/asm-x86/x86_64/page.h
    1.20  404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/ptrace.h
    1.21 +40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
    1.22  404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
    1.23  400304fcmRQmDdFYEzDh0wcBba9alg xen/include/hypervisor-ifs/COPYING
    1.24  404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/hypervisor-ifs/arch-x86_32.h
     2.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c	Tue Jun 29 19:45:18 2004 +0000
     2.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/main.c	Tue Jun 29 19:50:04 2004 +0000
     2.3 @@ -28,12 +28,6 @@ static DECLARE_TASKLET(net_tx_tasklet, n
     2.4  static void net_rx_action(unsigned long unused);
     2.5  static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0);
     2.6  
     2.7 -typedef struct {
     2.8 -    u16 id;
     2.9 -    unsigned long old_mach_ptr;
    2.10 -    unsigned long new_mach_pfn;
    2.11 -    netif_t *netif;
    2.12 -} rx_info_t;
    2.13  static struct sk_buff_head rx_queue;
    2.14  static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2];
    2.15  static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE*3];
    2.16 @@ -48,8 +42,10 @@ static unsigned long mmap_vstart;
    2.17  
    2.18  #define PKT_PROT_LEN (ETH_HLEN + 20)
    2.19  
    2.20 -static u16 pending_id[MAX_PENDING_REQS];
    2.21 -static netif_t *pending_netif[MAX_PENDING_REQS];
    2.22 +static struct {
    2.23 +    netif_tx_request_t req;
    2.24 +    netif_t *netif;
    2.25 +} pending_tx_info[MAX_PENDING_REQS];
    2.26  static u16 pending_ring[MAX_PENDING_REQS];
    2.27  typedef unsigned int PEND_RING_IDX;
    2.28  #define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1))
    2.29 @@ -61,11 +57,6 @@ static u16 dealloc_ring[MAX_PENDING_REQS
    2.30  static spinlock_t dealloc_lock = SPIN_LOCK_UNLOCKED;
    2.31  static PEND_RING_IDX dealloc_prod, dealloc_cons;
    2.32  
    2.33 -typedef struct {
    2.34 -    u16 idx;
    2.35 -    netif_tx_request_t req;
    2.36 -    netif_t *netif;
    2.37 -} tx_info_t;
    2.38  static struct sk_buff_head tx_queue;
    2.39  static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
    2.40  
    2.41 @@ -127,6 +118,8 @@ int netif_be_start_xmit(struct sk_buff *
    2.42  {
    2.43      netif_t *netif = (netif_t *)dev->priv;
    2.44  
    2.45 +    ASSERT(skb->dev == dev);
    2.46 +
    2.47      /* Drop the packet if the target domain has no receive buffers. */
    2.48      if ( (netif->rx_req_cons == netif->rx->req_prod) ||
    2.49           ((netif->rx_req_cons-netif->rx_resp_prod) == NETIF_RX_RING_SIZE) )
    2.50 @@ -152,15 +145,14 @@ int netif_be_start_xmit(struct sk_buff *
    2.51          skb_reserve(nskb, hlen);
    2.52          __skb_put(nskb, skb->len);
    2.53          (void)skb_copy_bits(skb, -hlen, nskb->head, hlen + skb->len);
    2.54 +        nskb->dev = skb->dev;
    2.55          dev_kfree_skb(skb);
    2.56          skb = nskb;
    2.57      }
    2.58  
    2.59 -    ((rx_info_t *)&skb->cb[0])->id    =
    2.60 -        netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_req_cons++)].req.id;
    2.61 -    ((rx_info_t *)&skb->cb[0])->netif = netif;
    2.62 -        
    2.63 -    __skb_queue_tail(&rx_queue, skb);
    2.64 +    netif->rx_req_cons++;
    2.65 +
    2.66 +    skb_queue_tail(&rx_queue, skb);
    2.67      tasklet_schedule(&net_rx_tasklet);
    2.68  
    2.69      return 0;
    2.70 @@ -195,7 +187,7 @@ static void net_rx_action(unsigned long 
    2.71      netif_t *netif;
    2.72      s8 status;
    2.73      u16 size, id, evtchn;
    2.74 -    mmu_update_t *mmu = rx_mmu;
    2.75 +    mmu_update_t *mmu;
    2.76      multicall_entry_t *mcl;
    2.77      unsigned long vdata, mdata, new_mfn;
    2.78      struct sk_buff_head rxq;
    2.79 @@ -206,9 +198,10 @@ static void net_rx_action(unsigned long 
    2.80      skb_queue_head_init(&rxq);
    2.81  
    2.82      mcl = rx_mcl;
    2.83 -    while ( (skb = __skb_dequeue(&rx_queue)) != NULL )
    2.84 +    mmu = rx_mmu;
    2.85 +    while ( (skb = skb_dequeue(&rx_queue)) != NULL )
    2.86      {
    2.87 -        netif   = ((rx_info_t *)&skb->cb[0])->netif;
    2.88 +        netif   = (netif_t *)skb->dev->priv;
    2.89          vdata   = (unsigned long)skb->data;
    2.90          mdata   = virt_to_machine(vdata);
    2.91          new_mfn = get_new_mfn();
    2.92 @@ -231,11 +224,9 @@ static void net_rx_action(unsigned long 
    2.93          mcl[1].args[1] = 3;
    2.94          mcl[1].args[2] = 0;
    2.95  
    2.96 +        mcl += 2;
    2.97          mmu += 3;
    2.98 -        mcl += 2;
    2.99  
   2.100 -        ((rx_info_t *)&skb->cb[0])->old_mach_ptr = mdata;
   2.101 -        ((rx_info_t *)&skb->cb[0])->new_mach_pfn = new_mfn;
   2.102          __skb_queue_tail(&rxq, skb);
   2.103  
   2.104          /* Filled the batch queue? */
   2.105 @@ -250,14 +241,17 @@ static void net_rx_action(unsigned long 
   2.106      (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
   2.107  
   2.108      mcl = rx_mcl;
   2.109 +    mmu = rx_mmu;
   2.110      while ( (skb = __skb_dequeue(&rxq)) != NULL )
   2.111      {
   2.112 -        netif   = ((rx_info_t *)&skb->cb[0])->netif;
   2.113 +        netif   = (netif_t *)skb->dev->priv;
   2.114          size    = skb->tail - skb->data;
   2.115 -        id      = ((rx_info_t *)&skb->cb[0])->id;
   2.116 -        new_mfn = ((rx_info_t *)&skb->cb[0])->new_mach_pfn;
   2.117 -        mdata   = ((rx_info_t *)&skb->cb[0])->old_mach_ptr;
   2.118  
   2.119 +        /* Rederive the machine addresses. */
   2.120 +        new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
   2.121 +        mdata   = ((mmu[2].ptr & PAGE_MASK) |
   2.122 +                   ((unsigned long)skb->data & ~PAGE_MASK));
   2.123 +        
   2.124          /* Check the reassignment error code. */
   2.125          if ( unlikely(mcl[1].args[5] != 0) )
   2.126          {
   2.127 @@ -285,6 +279,7 @@ static void net_rx_action(unsigned long 
   2.128          }
   2.129  
   2.130          evtchn = netif->evtchn;
   2.131 +        id = netif->rx->ring[MASK_NETIF_RX_IDX(netif->rx_resp_prod)].req.id;
   2.132          if ( make_rx_response(netif, id, status, mdata, size) &&
   2.133               (rx_notify[evtchn] == 0) )
   2.134          {
   2.135 @@ -295,6 +290,7 @@ static void net_rx_action(unsigned long 
   2.136          dev_kfree_skb(skb);
   2.137  
   2.138          mcl += 2;
   2.139 +        mmu += 3;
   2.140      }
   2.141  
   2.142      while ( notify_nr != 0 )
   2.143 @@ -406,10 +402,11 @@ static void net_tx_action(unsigned long 
   2.144      {
   2.145          pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)];
   2.146  
   2.147 -        netif = pending_netif[pending_idx];
   2.148 +        netif = pending_tx_info[pending_idx].netif;
   2.149  
   2.150          spin_lock(&netif->tx_lock);
   2.151 -        make_tx_response(netif, pending_id[pending_idx], NETIF_RSP_OKAY);
   2.152 +        make_tx_response(netif, pending_tx_info[pending_idx].req.id, 
   2.153 +                         NETIF_RSP_OKAY);
   2.154          spin_unlock(&netif->tx_lock);
   2.155          
   2.156          pending_ring[MASK_PEND_IDX(pending_prod++)] = pending_idx;
   2.157 @@ -512,10 +509,11 @@ static void net_tx_action(unsigned long 
   2.158          mcl[0].args[2] = 0;
   2.159          mcl[0].args[3] = netif->domid;
   2.160          mcl++;
   2.161 -        
   2.162 -        ((tx_info_t *)&skb->cb[0])->idx = pending_idx;
   2.163 -        ((tx_info_t *)&skb->cb[0])->netif = netif;
   2.164 -        memcpy(&((tx_info_t *)&skb->cb[0])->req, &txreq, sizeof(txreq));
   2.165 +
   2.166 +        memcpy(&pending_tx_info[pending_idx].req, &txreq, sizeof(txreq));
   2.167 +        pending_tx_info[pending_idx].netif = netif;
   2.168 +        *((u16 *)skb->data) = pending_idx;
   2.169 +
   2.170          __skb_queue_tail(&tx_queue, skb);
   2.171  
   2.172          pending_cons++;
   2.173 @@ -533,9 +531,9 @@ static void net_tx_action(unsigned long 
   2.174      mcl = tx_mcl;
   2.175      while ( (skb = __skb_dequeue(&tx_queue)) != NULL )
   2.176      {
   2.177 -        pending_idx = ((tx_info_t *)&skb->cb[0])->idx;
   2.178 -        netif       = ((tx_info_t *)&skb->cb[0])->netif;
   2.179 -        memcpy(&txreq, &((tx_info_t *)&skb->cb[0])->req, sizeof(txreq));
   2.180 +        pending_idx = *((u16 *)skb->data);
   2.181 +        netif       = pending_tx_info[pending_idx].netif;
   2.182 +        memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
   2.183  
   2.184          /* Check the remap error code. */
   2.185          if ( unlikely(mcl[0].args[5] != 0) )
   2.186 @@ -581,8 +579,6 @@ static void net_tx_action(unsigned long 
   2.187           */
   2.188          page->mapping = (struct address_space *)netif_page_release;
   2.189          atomic_set(&page->count, 1);
   2.190 -        pending_id[pending_idx] = txreq.id;
   2.191 -        pending_netif[pending_idx] = netif;
   2.192  
   2.193          netif->stats.tx_bytes += txreq.size;
   2.194          netif->stats.tx_packets++;
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Tue Jun 29 19:45:18 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Tue Jun 29 19:50:04 2004 +0000
     3.3 @@ -99,8 +99,6 @@ static struct net_device *find_dev_by_ha
     3.4      return NULL;
     3.5  }
     3.6  
     3.7 -#define MULTIVIF
     3.8 -
     3.9  /** Network interface info. */
    3.10  struct netif_ctrl {
    3.11      /** Number of interfaces. */
    3.12 @@ -385,14 +383,8 @@ static void netif_int(int irq, void *dev
    3.13      unsigned long flags;
    3.14  
    3.15      spin_lock_irqsave(&np->tx_lock, flags);
    3.16 -    
    3.17 -    if( !netif_carrier_ok(dev) )
    3.18 -    {
    3.19 -        spin_unlock_irqrestore(&np->tx_lock, flags);
    3.20 -        return;
    3.21 -    }
    3.22 -    
    3.23 -    network_tx_buf_gc(dev);
    3.24 +    if ( likely(netif_carrier_ok(dev)) )
    3.25 +        network_tx_buf_gc(dev);
    3.26      spin_unlock_irqrestore(&np->tx_lock, flags);
    3.27  
    3.28      if ( np->rx_resp_cons != np->rx->resp_prod )
    3.29 @@ -414,7 +406,7 @@ static int netif_poll(struct net_device 
    3.30  
    3.31      spin_lock(&np->rx_lock);
    3.32  
    3.33 -    /* if the device is undergoing recovery then don't do anything */
    3.34 +    /* If the device is undergoing recovery then don't do anything. */
    3.35      if ( !netif_carrier_ok(dev) )
    3.36      {
    3.37          spin_unlock(&np->rx_lock);
    3.38 @@ -721,20 +713,17 @@ static void netif_status_change(netif_fe
    3.39  
    3.40          memcpy(dev->dev_addr, status->mac, ETH_ALEN);
    3.41  
    3.42 -        if(netif_carrier_ok(dev)){
    3.43 +        if ( netif_carrier_ok(dev) )
    3.44              np->state = NETIF_STATE_CONNECTED;
    3.45 -        } else {
    3.46 +        else
    3.47              network_reconnect(dev, status);
    3.48 -        }
    3.49  
    3.50          np->evtchn = status->evtchn;
    3.51          np->irq = bind_evtchn_to_irq(np->evtchn);
    3.52          (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 
    3.53                            dev->name, dev);
    3.54          
    3.55 -#ifdef MULTIVIF
    3.56          netctrl_connected_count();
    3.57 -#endif
    3.58          break;
    3.59  
    3.60      default:
    3.61 @@ -744,13 +733,13 @@ static void netif_status_change(netif_fe
    3.62      }
    3.63  }
    3.64  
    3.65 -/** Create a network devices.
    3.66 - *
    3.67 +/** Create a network device.
    3.68   * @param handle device handle
    3.69   * @param val return parameter for created device
    3.70   * @return 0 on success, error code otherwise
    3.71   */
    3.72 -static int create_netdev(int handle, struct net_device **val){
    3.73 +static int create_netdev(int handle, struct net_device **val)
    3.74 +{
    3.75      int err = 0;
    3.76      struct net_device *dev = NULL;
    3.77      struct net_private *np = NULL;
    3.78 @@ -847,11 +836,7 @@ static int __init init_module(void)
    3.79  {
    3.80      ctrl_msg_t                       cmsg;
    3.81      netif_fe_driver_status_changed_t st;
    3.82 -    int err = 0;
    3.83 -#ifdef MULTIVIF
    3.84 -    int wait_n = 20;
    3.85 -    int wait_i;
    3.86 -#endif
    3.87 +    int err = 0, wait_i, wait_n = 20;
    3.88  
    3.89      if ( (start_info.flags & SIF_INITDOMAIN) ||
    3.90           (start_info.flags & SIF_NET_BE_DOMAIN) )
    3.91 @@ -860,9 +845,8 @@ static int __init init_module(void)
    3.92      printk("Initialising Xen virtual ethernet frontend driver");
    3.93  
    3.94      INIT_LIST_HEAD(&dev_list);
    3.95 -#ifdef MULTIVIF
    3.96 +
    3.97      netctrl_init();
    3.98 -#endif
    3.99  
   3.100      (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx,
   3.101                                      CALLBACK_IN_BLOCKING_CONTEXT);
   3.102 @@ -876,7 +860,6 @@ static int __init init_module(void)
   3.103      memcpy(cmsg.msg, &st, sizeof(st));
   3.104      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   3.105  
   3.106 -#ifdef MULTIVIF
   3.107      /* Wait for all interfaces to be connected. */
   3.108      for ( wait_i = 0; ; wait_i++)
   3.109      {
   3.110 @@ -888,7 +871,6 @@ static int __init init_module(void)
   3.111          set_current_state(TASK_INTERRUPTIBLE);
   3.112          schedule_timeout(1);
   3.113       }
   3.114 -#endif
   3.115  
   3.116      if ( err )
   3.117          ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx);
     4.1 --- a/xen/arch/x86/boot/boot.S	Tue Jun 29 19:45:18 2004 +0000
     4.2 +++ b/xen/arch/x86/boot/boot.S	Tue Jun 29 19:50:04 2004 +0000
     4.3 @@ -101,7 +101,7 @@ continue_boot_cpu:
     4.4          mov     0x4(%eax),%eax               /* %eax = mod[mod_count-1]->end */
     4.5          mov     %eax,%ecx
     4.6          sub     %ebx,%ecx                    /* %ecx = byte len of all mods */
     4.7 -        mov     $(MAX_DIRECTMAP_ADDRESS), %edi
     4.8 +        mov     $(DIRECTMAP_PHYS_END), %edi
     4.9          add     %ecx, %edi                   /* %edi = src + length */        
    4.10          shr     $2,%ecx                      /* %ecx = length/4 */
    4.11  1:      sub     $4,%eax                      /* %eax = src, %edi = dst */
    4.12 @@ -117,7 +117,7 @@ skip_dom0_copy:
    4.13  1:      mov     %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
    4.14          stosl                                /* low mapping */
    4.15          add     $(1<<L2_PAGETABLE_SHIFT),%eax
    4.16 -        cmp     $MAX_DIRECTMAP_ADDRESS+0x1e3,%eax
    4.17 +        cmp     $DIRECTMAP_PHYS_END+0x1e3,%eax
    4.18          jne     1b
    4.19  
    4.20          call    start_paging        
     5.1 --- a/xen/arch/x86/mm.c	Tue Jun 29 19:45:18 2004 +0000
     5.2 +++ b/xen/arch/x86/mm.c	Tue Jun 29 19:50:04 2004 +0000
     5.3 @@ -347,7 +347,7 @@ void *memguard_init(void *heap_start)
     5.4                            PAGE_MASK);
     5.5  
     5.6      /* Memory guarding is incompatible with super pages. */
     5.7 -    for ( i = 0; i < (MAX_XENHEAP_ADDRESS >> L2_PAGETABLE_SHIFT); i++ )
     5.8 +    for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
     5.9      {
    5.10          l1 = (l1_pgentry_t *)heap_start;
    5.11          heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
     6.1 --- a/xen/common/kernel.c	Tue Jun 29 19:45:18 2004 +0000
     6.2 +++ b/xen/common/kernel.c	Tue Jun 29 19:50:04 2004 +0000
     6.3 @@ -27,6 +27,8 @@
     6.4  #include <asm/domain_page.h>
     6.5  #include <hypervisor-ifs/dom0_ops.h>
     6.6  
     6.7 +unsigned long xenheap_phys_end;
     6.8 +
     6.9  kmem_cache_t *domain_struct_cachep;
    6.10  
    6.11  struct e820entry {
    6.12 @@ -69,6 +71,11 @@ char opt_physdev_dom0_hide[200] = "";
    6.13  /*                                    level- or edge-triggered.         */
    6.14  /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
    6.15  char opt_leveltrigger[30] = "", opt_edgetrigger[30] = "";
    6.16 +/*
    6.17 + * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
    6.18 + * pfn_info table and allocation bitmap.
    6.19 + */
    6.20 +unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
    6.21  
    6.22  static struct {
    6.23      unsigned char *name;
    6.24 @@ -91,6 +98,7 @@ static struct {
    6.25      { "physdev_dom0_hide", OPT_STR,  &opt_physdev_dom0_hide },
    6.26      { "leveltrigger",      OPT_STR,  &opt_leveltrigger },
    6.27      { "edgetrigger",       OPT_STR,  &opt_edgetrigger },
    6.28 +    { "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
    6.29      { NULL,               0,        NULL     }
    6.30  };
    6.31  
    6.32 @@ -180,52 +188,78 @@ void cmain(unsigned long magic, multiboo
    6.33          for ( ; ; ) ;
    6.34      }
    6.35  
    6.36 -    max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
    6.37 -
    6.38 -    /* The array of pfn_info structures must fit into the reserved area. */
    6.39 -    if ( (sizeof(struct pfn_info) * max_page) >
    6.40 -         (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) )
    6.41 +    if ( opt_xenheap_megabytes < 4 )
    6.42      {
    6.43 -        unsigned long new_max =
    6.44 -            (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) /
    6.45 -            sizeof(struct pfn_info);
    6.46 -        printk("Truncating available memory to %lu/%luMB\n",
    6.47 -               new_max >> (20 - PAGE_SHIFT), max_page >> (20 - PAGE_SHIFT));
    6.48 -        max_page = new_max;
    6.49 +        printk("Xen heap size is too small to safely continue!\n");
    6.50 +        for ( ; ; ) ;
    6.51      }
    6.52  
    6.53      set_current(&idle0_task);
    6.54  
    6.55 -    init_frametable(max_page);
    6.56 -    printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
    6.57 -           max_page >> (20-PAGE_SHIFT), max_page,
    6.58 -	   max_mem  >> (20-PAGE_SHIFT));
    6.59 +    xenheap_phys_end = opt_xenheap_megabytes << 20;
    6.60 +
    6.61 +    max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
    6.62 +
    6.63 +#if defined(__i386__)
    6.64  
    6.65 -    initial_images_start = MAX_DIRECTMAP_ADDRESS;
    6.66 +    if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
    6.67 +    {
    6.68 +        printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
    6.69 +               XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
    6.70 +        for ( ; ; ) ;
    6.71 +    }
    6.72 +
    6.73 +    ASSERT((sizeof(struct pfn_info) << 20) >
    6.74 +           (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
    6.75 +
    6.76 +    init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
    6.77 +
    6.78 +    /* Initial images stashed away above DIRECTMAP area in boot.S. */
    6.79 +    initial_images_start = DIRECTMAP_PHYS_END;
    6.80      initial_images_end   = initial_images_start + 
    6.81          (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    6.82 +
    6.83 +#elif defined(__x86_64__)
    6.84 +
    6.85 +    init_frametable(__va(xenheap_phys_end), max_page);
    6.86 +
    6.87 +    initial_images_start = __pa(frame_table) + frame_table_size;
    6.88 +    initial_images_end   = initial_images_start + 
    6.89 +        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    6.90 +    if ( initial_images_end > (max_page << PAGE_SHIFT) )
    6.91 +    {
    6.92 +        printk("Not enough memory to stash the DOM0 kernel image.\n");
    6.93 +        for ( ; ; ) ;
    6.94 +    }
    6.95 +    memmove(__va(initial_images_start),
    6.96 +            __va(mod[0].mod_start),
    6.97 +            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
    6.98 +
    6.99 +#endif
   6.100 +
   6.101      dom0_memory_start    = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
   6.102      dom0_memory_end      = dom0_memory_start + (opt_dom0_mem << 10);
   6.103      dom0_memory_end      = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
   6.104      
   6.105      /* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
   6.106 -    if ( (dom0_memory_end + (8<<20)) > (max_page<<PAGE_SHIFT) )
   6.107 -        panic("Not enough memory to craete initial domain!\n");
   6.108 +    if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
   6.109 +    {
   6.110 +        printk("Not enough memory for DOM0 memory reservation.\n");
   6.111 +        for ( ; ; ) ;
   6.112 +    }
   6.113 +
   6.114 +    printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
   6.115 +           max_page >> (20-PAGE_SHIFT), max_page,
   6.116 +	   max_mem  >> (20-PAGE_SHIFT));
   6.117  
   6.118      add_to_domain_alloc_list(dom0_memory_end, max_page << PAGE_SHIFT);
   6.119  
   6.120      heap_start = memguard_init(&_end);
   6.121  
   6.122      printk("Xen heap size is %luKB\n", 
   6.123 -	   (MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024 );
   6.124 +	   (xenheap_phys_end-__pa(heap_start))/1024 );
   6.125  
   6.126 -    if ( ((MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024) <= 4096 )
   6.127 -    {
   6.128 -        printk("Xen heap size is too small to safely continue!\n");
   6.129 -        for ( ; ; ) ;
   6.130 -    }
   6.131 -
   6.132 -    init_page_allocator(__pa(heap_start), MAX_XENHEAP_ADDRESS);
   6.133 +    init_page_allocator(__pa(heap_start), xenheap_phys_end);
   6.134   
   6.135      /* Initialise the slab allocator. */
   6.136      kmem_cache_init();
   6.137 @@ -253,8 +287,7 @@ void cmain(unsigned long magic, multiboo
   6.138  
   6.139      /*
   6.140       * We're going to setup domain0 using the module(s) that we stashed safely
   6.141 -     * above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if
   6.142 -     * present, is an initrd ramdisk.
   6.143 +     * above our heap. The second module, if present, is an initrd ramdisk.
   6.144       */
   6.145      if ( construct_dom0(new_dom, dom0_memory_start, dom0_memory_end,
   6.146                          (char *)initial_images_start, 
     7.1 --- a/xen/common/memory.c	Tue Jun 29 19:45:18 2004 +0000
     7.2 +++ b/xen/common/memory.c	Tue Jun 29 19:50:04 2004 +0000
     7.3 @@ -144,7 +144,7 @@ static struct {
     7.4  #define GPS (percpu_info[smp_processor_id()].gps ? : current)
     7.5  
     7.6  
     7.7 -void __init init_frametable(unsigned long nr_pages)
     7.8 +void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
     7.9  {
    7.10      unsigned long mfn;
    7.11  
    7.12 @@ -153,22 +153,23 @@ void __init init_frametable(unsigned lon
    7.13      max_page = nr_pages;
    7.14      frame_table_size = nr_pages * sizeof(struct pfn_info);
    7.15      frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
    7.16 -    frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START;
    7.17 +    frame_table = frametable_vstart;
    7.18 +
    7.19 +    if ( (__pa(frame_table) + frame_table_size) > (max_page << PAGE_SHIFT) )
    7.20 +        panic("Not enough memory for frame table - reduce Xen heap size?\n");
    7.21 +
    7.22      memset(frame_table, 0, frame_table_size);
    7.23  
    7.24      spin_lock_init(&free_list_lock);
    7.25      INIT_LIST_HEAD(&free_list);    
    7.26      free_pfns = 0;
    7.27  
    7.28 -    /* initialise to a magic of 0x55555555 so easier to spot bugs later */
    7.29 -    memset( machine_to_phys_mapping, 0x55, 4*1024*1024 );
    7.30 -
    7.31 -    /* The array is sized for a 4GB machine regardless of actuall mem size. 
    7.32 -       This costs 4MB -- may want to fix some day */
    7.33 +    /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
    7.34 +    memset(machine_to_phys_mapping, 0x55, 4<<20);
    7.35  
    7.36      /* Pin the ownership of the MP table so that DOM0 can map it later. */
    7.37 -    for ( mfn = virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
    7.38 -          mfn < virt_to_phys(&machine_to_phys_mapping[1024*1024])>>PAGE_SHIFT;
    7.39 +    for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
    7.40 +          mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
    7.41            mfn++ )
    7.42      {
    7.43          frame_table[mfn].count_and_flags = 1 | PGC_allocated;
    7.44 @@ -471,6 +472,7 @@ static int alloc_l2_table(struct pfn_inf
    7.45          if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
    7.46              goto fail;
    7.47      
    7.48 +#if defined(__i386__)
    7.49      /* Now we add our private high mappings. */
    7.50      memcpy(&pl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
    7.51             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
    7.52 @@ -480,6 +482,7 @@ static int alloc_l2_table(struct pfn_inf
    7.53      pl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
    7.54          mk_l2_pgentry(__pa(page->u.domain->mm.perdomain_pt) | 
    7.55                        __PAGE_HYPERVISOR);
    7.56 +#endif
    7.57  
    7.58      unmap_domain_mem(pl2e);
    7.59      return 1;
     8.1 --- a/xen/common/shadow.c	Tue Jun 29 19:45:18 2004 +0000
     8.2 +++ b/xen/common/shadow.c	Tue Jun 29 19:50:04 2004 +0000
     8.3 @@ -151,7 +151,9 @@ static inline int shadow_page_op( struct
     8.4               PGT_l2_page_table )
     8.5  		{
     8.6  			unsigned long * spl1e = map_domain_mem( spfn<<PAGE_SHIFT );
     8.7 -			memset( spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e) );
     8.8 +#ifdef __i386__
     8.9 +			memset(spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e));
    8.10 +#endif
    8.11  			unmap_domain_mem( spl1e );
    8.12  		}
    8.13      }
    8.14 @@ -574,6 +576,7 @@ unsigned long shadow_l2_table(
    8.15      // we need to do this before the linear map is set up
    8.16      spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT);
    8.17  
    8.18 +#ifdef __i386__
    8.19      // get hypervisor and 2x linear PT mapings installed 
    8.20      memcpy(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE], 
    8.21             &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
    8.22 @@ -585,6 +588,7 @@ unsigned long shadow_l2_table(
    8.23      spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
    8.24          mk_l2_pgentry(__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) | 
    8.25                        __PAGE_HYPERVISOR);
    8.26 +#endif
    8.27  
    8.28      // can't use the linear map as we may not be in the right PT
    8.29      gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT);
     9.1 --- a/xen/include/asm-x86/config.h	Tue Jun 29 19:45:18 2004 +0000
     9.2 +++ b/xen/include/asm-x86/config.h	Tue Jun 29 19:50:04 2004 +0000
     9.3 @@ -93,6 +93,8 @@ extern void __out_of_line_bug(int line) 
     9.4  
     9.5  #if defined(__x86_64__)
     9.6  
     9.7 +#define XENHEAP_DEFAULT_MB (16)
     9.8 +
     9.9  #define PML4_ENTRY_BITS  39
    9.10  #define PML4_ENTRY_BYTES (1UL<<PML4_ENTRY_BITS)
    9.11  
    9.12 @@ -158,9 +160,8 @@ extern void __out_of_line_bug(int line) 
    9.13  
    9.14  #elif defined(__i386__)
    9.15  
    9.16 -/* The following are machine addresses. */
    9.17 -#define MAX_XENHEAP_ADDRESS   (12*1024*1024)
    9.18 -#define MAX_DIRECTMAP_ADDRESS (40*1024*1024)
    9.19 +#define XENHEAP_DEFAULT_MB (12)
    9.20 +#define DIRECTMAP_PHYS_END (40*1024*1024)
    9.21  
    9.22  /* Hypervisor owns top 64MB of virtual address space. */
    9.23  #define HYPERVISOR_VIRT_START (0xFC000000UL)
    9.24 @@ -173,9 +174,9 @@ extern void __out_of_line_bug(int line) 
    9.25  #define RO_MPT_VIRT_END       (RO_MPT_VIRT_START + (4*1024*1024))
    9.26  /* The virtual addresses for the 40MB direct-map region. */
    9.27  #define DIRECTMAP_VIRT_START  (RO_MPT_VIRT_END)
    9.28 -#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
    9.29 +#define DIRECTMAP_VIRT_END    (DIRECTMAP_VIRT_START + DIRECTMAP_PHYS_END)
    9.30  #define XENHEAP_VIRT_START    (DIRECTMAP_VIRT_START)
    9.31 -#define XENHEAP_VIRT_END      (XENHEAP_VIRT_START + MAX_XENHEAP_ADDRESS)
    9.32 +#define XENHEAP_VIRT_END      (XENHEAP_VIRT_START + (XENHEAP_DEFAULT_MB<<20))
    9.33  #define RDWR_MPT_VIRT_START   (XENHEAP_VIRT_END)
    9.34  #define RDWR_MPT_VIRT_END     (RDWR_MPT_VIRT_START + (4*1024*1024))
    9.35  #define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
    9.36 @@ -207,6 +208,10 @@ extern void __out_of_line_bug(int line) 
    9.37  
    9.38  #endif /* __i386__ */
    9.39  
    9.40 +#ifndef __ASSEMBLY__
    9.41 +extern unsigned long xenheap_phys_end; /* user-configurable */
    9.42 +#endif
    9.43 +
    9.44  #define GDT_VIRT_START        (PERDOMAIN_VIRT_START)
    9.45  #define GDT_VIRT_END          (GDT_VIRT_START + (64*1024))
    9.46  #define LDT_VIRT_START        (GDT_VIRT_END)
    10.1 --- a/xen/include/asm-x86/page.h	Tue Jun 29 19:45:18 2004 +0000
    10.2 +++ b/xen/include/asm-x86/page.h	Tue Jun 29 19:50:04 2004 +0000
    10.3 @@ -95,12 +95,12 @@ typedef struct { unsigned long pt_lo; } 
    10.4  extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
    10.5  extern void paging_init(void);
    10.6  
    10.7 -#define __flush_tlb()                                    \
    10.8 -    do {                                                 \
    10.9 -        __asm__ __volatile__ (                           \
   10.10 -            "movl %%cr3, %%eax; movl %%eax, %%cr3"       \
   10.11 -            : : : "memory", "eax" );                     \
   10.12 -        tlb_clocktick();                                 \
   10.13 +#define __flush_tlb()                                             \
   10.14 +    do {                                                          \
   10.15 +        __asm__ __volatile__ (                                    \
   10.16 +            "mov %%cr3, %%"__OP"ax; mov %%"__OP"ax, %%cr3"        \
   10.17 +            : : : "memory", __OP"ax" );                           \
   10.18 +        tlb_clocktick();                                          \
   10.19      } while ( 0 )
   10.20  
   10.21  /* Flush global pages as well. */
   10.22 @@ -108,14 +108,14 @@ extern void paging_init(void);
   10.23  #define __pge_off()                                                     \
   10.24          do {                                                            \
   10.25                  __asm__ __volatile__(                                   \
   10.26 -                        "movl %0, %%cr4;  # turn off PGE     "          \
   10.27 +                        "mov %0, %%cr4;  # turn off PGE     "           \
   10.28                          :: "r" (mmu_cr4_features & ~X86_CR4_PGE));      \
   10.29          } while (0)
   10.30  
   10.31  #define __pge_on()                                                      \
   10.32          do {                                                            \
   10.33                  __asm__ __volatile__(                                   \
   10.34 -                        "movl %0, %%cr4;  # turn off PGE     "          \
   10.35 +                        "mov %0, %%cr4;  # turn off PGE     "           \
   10.36                          :: "r" (mmu_cr4_features));                     \
   10.37          } while (0)
   10.38  
    11.1 --- a/xen/include/asm-x86/string.h	Tue Jun 29 19:45:18 2004 +0000
    11.2 +++ b/xen/include/asm-x86/string.h	Tue Jun 29 19:50:04 2004 +0000
    11.3 @@ -1,485 +1,5 @@
    11.4 -#ifndef _I386_STRING_H_
    11.5 -#define _I386_STRING_H_
    11.6 -
    11.7 -#include <xen/config.h>
    11.8 -
    11.9 -/*
   11.10 - * This string-include defines all string functions as inline
   11.11 - * functions. Use gcc. It also assumes ds=es=data space, this should be
   11.12 - * normal. Most of the string-functions are rather heavily hand-optimized,
   11.13 - * see especially strtok,strstr,str[c]spn. They should work, but are not
   11.14 - * very easy to understand. Everything is done entirely within the register
   11.15 - * set, making the functions fast and clean. String instructions have been
   11.16 - * used through-out, making for "slightly" unclear code :-)
   11.17 - *
   11.18 - *		NO Copyright (C) 1991, 1992 Linus Torvalds,
   11.19 - *		consider these trivial functions to be PD.
   11.20 - */
   11.21 -
   11.22 -
   11.23 -#define __HAVE_ARCH_STRCPY
   11.24 -static inline char * strcpy(char * dest,const char *src)
   11.25 -{
   11.26 -int d0, d1, d2;
   11.27 -__asm__ __volatile__(
   11.28 -	"1:\tlodsb\n\t"
   11.29 -	"stosb\n\t"
   11.30 -	"testb %%al,%%al\n\t"
   11.31 -	"jne 1b"
   11.32 -	: "=&S" (d0), "=&D" (d1), "=&a" (d2)
   11.33 -	:"0" (src),"1" (dest) : "memory");
   11.34 -return dest;
   11.35 -}
   11.36 -
   11.37 -#define __HAVE_ARCH_STRNCPY
   11.38 -static inline char * strncpy(char * dest,const char *src,size_t count)
   11.39 -{
   11.40 -int d0, d1, d2, d3;
   11.41 -__asm__ __volatile__(
   11.42 -	"1:\tdecl %2\n\t"
   11.43 -	"js 2f\n\t"
   11.44 -	"lodsb\n\t"
   11.45 -	"stosb\n\t"
   11.46 -	"testb %%al,%%al\n\t"
   11.47 -	"jne 1b\n\t"
   11.48 -	"rep\n\t"
   11.49 -	"stosb\n"
   11.50 -	"2:"
   11.51 -	: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
   11.52 -	:"0" (src),"1" (dest),"2" (count) : "memory");
   11.53 -return dest;
   11.54 -}
   11.55 -
   11.56 -#define __HAVE_ARCH_STRCAT
   11.57 -static inline char * strcat(char * dest,const char * src)
   11.58 -{
   11.59 -int d0, d1, d2, d3;
   11.60 -__asm__ __volatile__(
   11.61 -	"repne\n\t"
   11.62 -	"scasb\n\t"
   11.63 -	"decl %1\n"
   11.64 -	"1:\tlodsb\n\t"
   11.65 -	"stosb\n\t"
   11.66 -	"testb %%al,%%al\n\t"
   11.67 -	"jne 1b"
   11.68 -	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
   11.69 -	: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
   11.70 -return dest;
   11.71 -}
   11.72 -
   11.73 -#define __HAVE_ARCH_STRNCAT
   11.74 -static inline char * strncat(char * dest,const char * src,size_t count)
   11.75 -{
   11.76 -int d0, d1, d2, d3;
   11.77 -__asm__ __volatile__(
   11.78 -	"repne\n\t"
   11.79 -	"scasb\n\t"
   11.80 -	"decl %1\n\t"
   11.81 -	"movl %8,%3\n"
   11.82 -	"1:\tdecl %3\n\t"
   11.83 -	"js 2f\n\t"
   11.84 -	"lodsb\n\t"
   11.85 -	"stosb\n\t"
   11.86 -	"testb %%al,%%al\n\t"
   11.87 -	"jne 1b\n"
   11.88 -	"2:\txorl %2,%2\n\t"
   11.89 -	"stosb"
   11.90 -	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
   11.91 -	: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
   11.92 -	: "memory");
   11.93 -return dest;
   11.94 -}
   11.95 -
   11.96 -#define __HAVE_ARCH_STRCMP
   11.97 -static inline int strcmp(const char * cs,const char * ct)
   11.98 -{
   11.99 -int d0, d1;
  11.100 -register int __res;
  11.101 -__asm__ __volatile__(
  11.102 -	"1:\tlodsb\n\t"
  11.103 -	"scasb\n\t"
  11.104 -	"jne 2f\n\t"
  11.105 -	"testb %%al,%%al\n\t"
  11.106 -	"jne 1b\n\t"
  11.107 -	"xorl %%eax,%%eax\n\t"
  11.108 -	"jmp 3f\n"
  11.109 -	"2:\tsbbl %%eax,%%eax\n\t"
  11.110 -	"orb $1,%%al\n"
  11.111 -	"3:"
  11.112 -	:"=a" (__res), "=&S" (d0), "=&D" (d1)
  11.113 -		     :"1" (cs),"2" (ct));
  11.114 -return __res;
  11.115 -}
  11.116 -
  11.117 -#define __HAVE_ARCH_STRNCMP
  11.118 -static inline int strncmp(const char * cs,const char * ct,size_t count)
  11.119 -{
  11.120 -register int __res;
  11.121 -int d0, d1, d2;
  11.122 -__asm__ __volatile__(
  11.123 -	"1:\tdecl %3\n\t"
  11.124 -	"js 2f\n\t"
  11.125 -	"lodsb\n\t"
  11.126 -	"scasb\n\t"
  11.127 -	"jne 3f\n\t"
  11.128 -	"testb %%al,%%al\n\t"
  11.129 -	"jne 1b\n"
  11.130 -	"2:\txorl %%eax,%%eax\n\t"
  11.131 -	"jmp 4f\n"
  11.132 -	"3:\tsbbl %%eax,%%eax\n\t"
  11.133 -	"orb $1,%%al\n"
  11.134 -	"4:"
  11.135 -		     :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
  11.136 -		     :"1" (cs),"2" (ct),"3" (count));
  11.137 -return __res;
  11.138 -}
  11.139 -
  11.140 -#define __HAVE_ARCH_STRCHR
  11.141 -static inline char * strchr(const char * s, int c)
  11.142 -{
  11.143 -int d0;
  11.144 -register char * __res;
  11.145 -__asm__ __volatile__(
  11.146 -	"movb %%al,%%ah\n"
  11.147 -	"1:\tlodsb\n\t"
  11.148 -	"cmpb %%ah,%%al\n\t"
  11.149 -	"je 2f\n\t"
  11.150 -	"testb %%al,%%al\n\t"
  11.151 -	"jne 1b\n\t"
  11.152 -	"movl $1,%1\n"
  11.153 -	"2:\tmovl %1,%0\n\t"
  11.154 -	"decl %0"
  11.155 -	:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
  11.156 -return __res;
  11.157 -}
  11.158 -
  11.159 -#define __HAVE_ARCH_STRRCHR
  11.160 -static inline char * strrchr(const char * s, int c)
  11.161 -{
  11.162 -int d0, d1;
  11.163 -register char * __res;
  11.164 -__asm__ __volatile__(
  11.165 -	"movb %%al,%%ah\n"
  11.166 -	"1:\tlodsb\n\t"
  11.167 -	"cmpb %%ah,%%al\n\t"
  11.168 -	"jne 2f\n\t"
  11.169 -	"leal -1(%%esi),%0\n"
  11.170 -	"2:\ttestb %%al,%%al\n\t"
  11.171 -	"jne 1b"
  11.172 -	:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
  11.173 -return __res;
  11.174 -}
  11.175 -
  11.176 -#define __HAVE_ARCH_STRLEN
  11.177 -static inline size_t strlen(const char * s)
  11.178 -{
  11.179 -int d0;
  11.180 -register int __res;
  11.181 -__asm__ __volatile__(
  11.182 -	"repne\n\t"
  11.183 -	"scasb\n\t"
  11.184 -	"notl %0\n\t"
  11.185 -	"decl %0"
  11.186 -	:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
  11.187 -return __res;
  11.188 -}
  11.189 -
  11.190 -static inline void * __memcpy(void * to, const void * from, size_t n)
  11.191 -{
  11.192 -int d0, d1, d2;
  11.193 -__asm__ __volatile__(
  11.194 -	"rep ; movsl\n\t"
  11.195 -	"testb $2,%b4\n\t"
  11.196 -	"je 1f\n\t"
  11.197 -	"movsw\n"
  11.198 -	"1:\ttestb $1,%b4\n\t"
  11.199 -	"je 2f\n\t"
  11.200 -	"movsb\n"
  11.201 -	"2:"
  11.202 -	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
  11.203 -	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
  11.204 -	: "memory");
  11.205 -return (to);
  11.206 -}
  11.207 -
  11.208 -/*
  11.209 - * This looks horribly ugly, but the compiler can optimize it totally,
  11.210 - * as the count is constant.
  11.211 - */
  11.212 -static inline void * __constant_memcpy(void * to, const void * from, size_t n)
  11.213 -{
  11.214 -	switch (n) {
  11.215 -		case 0:
  11.216 -			return to;
  11.217 -		case 1:
  11.218 -			*(unsigned char *)to = *(const unsigned char *)from;
  11.219 -			return to;
  11.220 -		case 2:
  11.221 -			*(unsigned short *)to = *(const unsigned short *)from;
  11.222 -			return to;
  11.223 -		case 3:
  11.224 -			*(unsigned short *)to = *(const unsigned short *)from;
  11.225 -			*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
  11.226 -			return to;
  11.227 -		case 4:
  11.228 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.229 -			return to;
  11.230 -		case 6:	/* for Ethernet addresses */
  11.231 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.232 -			*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
  11.233 -			return to;
  11.234 -		case 8:
  11.235 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.236 -			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  11.237 -			return to;
  11.238 -		case 12:
  11.239 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.240 -			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  11.241 -			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  11.242 -			return to;
  11.243 -		case 16:
  11.244 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.245 -			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  11.246 -			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  11.247 -			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  11.248 -			return to;
  11.249 -		case 20:
  11.250 -			*(unsigned long *)to = *(const unsigned long *)from;
  11.251 -			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  11.252 -			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  11.253 -			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  11.254 -			*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
  11.255 -			return to;
  11.256 -	}
  11.257 -#define COMMON(x) \
  11.258 -__asm__ __volatile__( \
  11.259 -	"rep ; movsl" \
  11.260 -	x \
  11.261 -	: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
  11.262 -	: "0" (n/4),"1" ((long) to),"2" ((long) from) \
  11.263 -	: "memory");
  11.264 -{
  11.265 -	int d0, d1, d2;
  11.266 -	switch (n % 4) {
  11.267 -		case 0: COMMON(""); return to;
  11.268 -		case 1: COMMON("\n\tmovsb"); return to;
  11.269 -		case 2: COMMON("\n\tmovsw"); return to;
  11.270 -		default: COMMON("\n\tmovsw\n\tmovsb"); return to;
  11.271 -	}
  11.272 -}
  11.273 -  
  11.274 -#undef COMMON
  11.275 -}
  11.276 -
  11.277 -#define __HAVE_ARCH_MEMCPY
  11.278 -
  11.279 -#define memcpy(t, f, n) \
  11.280 -(__builtin_constant_p(n) ? \
  11.281 - __constant_memcpy((t),(f),(n)) : \
  11.282 - __memcpy((t),(f),(n)))
  11.283 -
  11.284 -
  11.285 -/*
  11.286 - * struct_cpy(x,y), copy structure *x into (matching structure) *y.
  11.287 - *
  11.288 - * We get link-time errors if the structure sizes do not match.
  11.289 - * There is no runtime overhead, it's all optimized away at
  11.290 - * compile time.
  11.291 - */
  11.292 -//extern void __struct_cpy_bug (void);
  11.293 -
  11.294 -/*
  11.295 -#define struct_cpy(x,y) 			\
  11.296 -({						\
  11.297 -	if (sizeof(*(x)) != sizeof(*(y))) 	\
  11.298 -		__struct_cpy_bug;		\
  11.299 -	memcpy(x, y, sizeof(*(x)));		\
  11.300 -})
  11.301 -*/
  11.302 -
  11.303 -#define __HAVE_ARCH_MEMMOVE
  11.304 -static inline void * memmove(void * dest,const void * src, size_t n)
  11.305 -{
  11.306 -int d0, d1, d2;
  11.307 -if (dest<src)
  11.308 -__asm__ __volatile__(
  11.309 -	"rep\n\t"
  11.310 -	"movsb"
  11.311 -	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
  11.312 -	:"0" (n),"1" (src),"2" (dest)
  11.313 -	: "memory");
  11.314 -else
  11.315 -__asm__ __volatile__(
  11.316 -	"std\n\t"
  11.317 -	"rep\n\t"
  11.318 -	"movsb\n\t"
  11.319 -	"cld"
  11.320 -	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
  11.321 -	:"0" (n),
  11.322 -	 "1" (n-1+(const char *)src),
  11.323 -	 "2" (n-1+(char *)dest)
  11.324 -	:"memory");
  11.325 -return dest;
  11.326 -}
  11.327 -
  11.328 -#define __HAVE_ARCH_MEMCMP
  11.329 -#define memcmp __builtin_memcmp
  11.330 -
  11.331 -#define __HAVE_ARCH_MEMCHR
  11.332 -static inline void * memchr(const void * cs,int c,size_t count)
  11.333 -{
  11.334 -int d0;
  11.335 -register void * __res;
  11.336 -if (!count)
  11.337 -	return NULL;
  11.338 -__asm__ __volatile__(
  11.339 -	"repne\n\t"
  11.340 -	"scasb\n\t"
  11.341 -	"je 1f\n\t"
  11.342 -	"movl $1,%0\n"
  11.343 -	"1:\tdecl %0"
  11.344 -	:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
  11.345 -return __res;
  11.346 -}
  11.347 -
  11.348 -static inline void * __memset_generic(void * s, char c,size_t count)
  11.349 -{
  11.350 -int d0, d1;
  11.351 -__asm__ __volatile__(
  11.352 -	"rep\n\t"
  11.353 -	"stosb"
  11.354 -	: "=&c" (d0), "=&D" (d1)
  11.355 -	:"a" (c),"1" (s),"0" (count)
  11.356 -	:"memory");
  11.357 -return s;
  11.358 -}
  11.359 -
  11.360 -/* we might want to write optimized versions of these later */
  11.361 -#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
  11.362 -
  11.363 -/*
  11.364 - * memset(x,0,y) is a reasonably common thing to do, so we want to fill
  11.365 - * things 32 bits at a time even when we don't know the size of the
  11.366 - * area at compile-time..
  11.367 - */
  11.368 -static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
  11.369 -{
  11.370 -int d0, d1;
  11.371 -__asm__ __volatile__(
  11.372 -	"rep ; stosl\n\t"
  11.373 -	"testb $2,%b3\n\t"
  11.374 -	"je 1f\n\t"
  11.375 -	"stosw\n"
  11.376 -	"1:\ttestb $1,%b3\n\t"
  11.377 -	"je 2f\n\t"
  11.378 -	"stosb\n"
  11.379 -	"2:"
  11.380 -	: "=&c" (d0), "=&D" (d1)
  11.381 -	:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
  11.382 -	:"memory");
  11.383 -return (s);	
  11.384 -}
  11.385 -
  11.386 -/* Added by Gertjan van Wingerde to make minix and sysv module work */
  11.387 -#define __HAVE_ARCH_STRNLEN
  11.388 -static inline size_t strnlen(const char * s, size_t count)
  11.389 -{
  11.390 -int d0;
  11.391 -register int __res;
  11.392 -__asm__ __volatile__(
  11.393 -	"movl %2,%0\n\t"
  11.394 -	"jmp 2f\n"
  11.395 -	"1:\tcmpb $0,(%0)\n\t"
  11.396 -	"je 3f\n\t"
  11.397 -	"incl %0\n"
  11.398 -	"2:\tdecl %1\n\t"
  11.399 -	"cmpl $-1,%1\n\t"
  11.400 -	"jne 1b\n"
  11.401 -	"3:\tsubl %2,%0"
  11.402 -	:"=a" (__res), "=&d" (d0)
  11.403 -	:"c" (s),"1" (count));
  11.404 -return __res;
  11.405 -}
  11.406 -/* end of additional stuff */
  11.407 -
  11.408 -//#define __HAVE_ARCH_STRSTR
  11.409 -
  11.410 -//extern char *strstr(const char *cs, const char *ct);
  11.411 -
  11.412 -/*
  11.413 - * This looks horribly ugly, but the compiler can optimize it totally,
  11.414 - * as we by now know that both pattern and count is constant..
  11.415 - */
  11.416 -static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
  11.417 -{
  11.418 -	switch (count) {
  11.419 -		case 0:
  11.420 -			return s;
  11.421 -		case 1:
  11.422 -			*(unsigned char *)s = pattern;
  11.423 -			return s;
  11.424 -		case 2:
  11.425 -			*(unsigned short *)s = pattern;
  11.426 -			return s;
  11.427 -		case 3:
  11.428 -			*(unsigned short *)s = pattern;
  11.429 -			*(2+(unsigned char *)s) = pattern;
  11.430 -			return s;
  11.431 -		case 4:
  11.432 -			*(unsigned long *)s = pattern;
  11.433 -			return s;
  11.434 -	}
  11.435 -#define COMMON(x) \
  11.436 -__asm__  __volatile__( \
  11.437 -	"rep ; stosl" \
  11.438 -	x \
  11.439 -	: "=&c" (d0), "=&D" (d1) \
  11.440 -	: "a" (pattern),"0" (count/4),"1" ((long) s) \
  11.441 -	: "memory")
  11.442 -{
  11.443 -	int d0, d1;
  11.444 -	switch (count % 4) {
  11.445 -		case 0: COMMON(""); return s;
  11.446 -		case 1: COMMON("\n\tstosb"); return s;
  11.447 -		case 2: COMMON("\n\tstosw"); return s;
  11.448 -		default: COMMON("\n\tstosw\n\tstosb"); return s;
  11.449 -	}
  11.450 -}
  11.451 -  
  11.452 -#undef COMMON
  11.453 -}
  11.454 -
  11.455 -#define __constant_c_x_memset(s, c, count) \
  11.456 -(__builtin_constant_p(count) ? \
  11.457 - __constant_c_and_count_memset((s),(c),(count)) : \
  11.458 - __constant_c_memset((s),(c),(count)))
  11.459 -
  11.460 -#define __memset(s, c, count) \
  11.461 -(__builtin_constant_p(count) ? \
  11.462 - __constant_count_memset((s),(c),(count)) : \
  11.463 - __memset_generic((s),(c),(count)))
  11.464 -
  11.465 -#define __HAVE_ARCH_MEMSET
  11.466 -#define memset(s, c, count) \
  11.467 -(__builtin_constant_p(c) ? \
  11.468 - __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
  11.469 - __memset((s),(c),(count)))
  11.470 -
  11.471 -/*
  11.472 - * find the first occurrence of byte 'c', or 1 past the area if none
  11.473 - */
  11.474 -#define __HAVE_ARCH_MEMSCAN
  11.475 -static inline void * memscan(void * addr, int c, size_t size)
  11.476 -{
  11.477 -	if (!size)
  11.478 -		return addr;
  11.479 -	__asm__("repnz; scasb\n\t"
  11.480 -		"jnz 1f\n\t"
  11.481 -		"dec %%edi\n"
  11.482 -		"1:"
  11.483 -		: "=D" (addr), "=c" (size)
  11.484 -		: "0" (addr), "1" (size), "a" (c));
  11.485 -	return addr;
  11.486 -}
  11.487 -
  11.488 +#ifdef __x86_64__
  11.489 +#include <asm/x86_64/string.h>
  11.490 +#else
  11.491 +#include <asm/x86_32/string.h>
  11.492  #endif
    12.1 --- a/xen/include/asm-x86/types.h	Tue Jun 29 19:45:18 2004 +0000
    12.2 +++ b/xen/include/asm-x86/types.h	Tue Jun 29 19:50:04 2004 +0000
    12.3 @@ -3,7 +3,6 @@
    12.4  
    12.5  typedef unsigned short umode_t;
    12.6  
    12.7 -typedef unsigned int size_t;
    12.8  
    12.9  /*
   12.10   * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
   12.11 @@ -44,10 +43,12 @@ typedef unsigned int u32;
   12.12  typedef signed long long s64;
   12.13  typedef unsigned long long u64;
   12.14  #define BITS_PER_LONG 32
   12.15 +typedef unsigned int size_t;
   12.16  #elif defined(__x86_64__)
   12.17  typedef signed long s64;
   12.18  typedef unsigned long u64;
   12.19  #define BITS_PER_LONG 64
   12.20 +typedef unsigned long size_t;
   12.21  #endif
   12.22  
   12.23  /* DMA addresses come in generic and 64-bit flavours.  */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/xen/include/asm-x86/x86_32/string.h	Tue Jun 29 19:50:04 2004 +0000
    13.3 @@ -0,0 +1,485 @@
    13.4 +#ifndef _I386_STRING_H_
    13.5 +#define _I386_STRING_H_
    13.6 +
    13.7 +#include <xen/config.h>
    13.8 +
    13.9 +/*
   13.10 + * This string-include defines all string functions as inline
   13.11 + * functions. Use gcc. It also assumes ds=es=data space, this should be
   13.12 + * normal. Most of the string-functions are rather heavily hand-optimized,
   13.13 + * see especially strtok,strstr,str[c]spn. They should work, but are not
   13.14 + * very easy to understand. Everything is done entirely within the register
   13.15 + * set, making the functions fast and clean. String instructions have been
   13.16 + * used through-out, making for "slightly" unclear code :-)
   13.17 + *
   13.18 + *		NO Copyright (C) 1991, 1992 Linus Torvalds,
   13.19 + *		consider these trivial functions to be PD.
   13.20 + */
   13.21 +
   13.22 +
   13.23 +#define __HAVE_ARCH_STRCPY
   13.24 +static inline char * strcpy(char * dest,const char *src)
   13.25 +{
   13.26 +int d0, d1, d2;
   13.27 +__asm__ __volatile__(
   13.28 +	"1:\tlodsb\n\t"
   13.29 +	"stosb\n\t"
   13.30 +	"testb %%al,%%al\n\t"
   13.31 +	"jne 1b"
   13.32 +	: "=&S" (d0), "=&D" (d1), "=&a" (d2)
   13.33 +	:"0" (src),"1" (dest) : "memory");
   13.34 +return dest;
   13.35 +}
   13.36 +
   13.37 +#define __HAVE_ARCH_STRNCPY
   13.38 +static inline char * strncpy(char * dest,const char *src,size_t count)
   13.39 +{
   13.40 +int d0, d1, d2, d3;
   13.41 +__asm__ __volatile__(
   13.42 +	"1:\tdecl %2\n\t"
   13.43 +	"js 2f\n\t"
   13.44 +	"lodsb\n\t"
   13.45 +	"stosb\n\t"
   13.46 +	"testb %%al,%%al\n\t"
   13.47 +	"jne 1b\n\t"
   13.48 +	"rep\n\t"
   13.49 +	"stosb\n"
   13.50 +	"2:"
   13.51 +	: "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
   13.52 +	:"0" (src),"1" (dest),"2" (count) : "memory");
   13.53 +return dest;
   13.54 +}
   13.55 +
   13.56 +#define __HAVE_ARCH_STRCAT
   13.57 +static inline char * strcat(char * dest,const char * src)
   13.58 +{
   13.59 +int d0, d1, d2, d3;
   13.60 +__asm__ __volatile__(
   13.61 +	"repne\n\t"
   13.62 +	"scasb\n\t"
   13.63 +	"decl %1\n"
   13.64 +	"1:\tlodsb\n\t"
   13.65 +	"stosb\n\t"
   13.66 +	"testb %%al,%%al\n\t"
   13.67 +	"jne 1b"
   13.68 +	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
   13.69 +	: "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
   13.70 +return dest;
   13.71 +}
   13.72 +
   13.73 +#define __HAVE_ARCH_STRNCAT
   13.74 +static inline char * strncat(char * dest,const char * src,size_t count)
   13.75 +{
   13.76 +int d0, d1, d2, d3;
   13.77 +__asm__ __volatile__(
   13.78 +	"repne\n\t"
   13.79 +	"scasb\n\t"
   13.80 +	"decl %1\n\t"
   13.81 +	"movl %8,%3\n"
   13.82 +	"1:\tdecl %3\n\t"
   13.83 +	"js 2f\n\t"
   13.84 +	"lodsb\n\t"
   13.85 +	"stosb\n\t"
   13.86 +	"testb %%al,%%al\n\t"
   13.87 +	"jne 1b\n"
   13.88 +	"2:\txorl %2,%2\n\t"
   13.89 +	"stosb"
   13.90 +	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
   13.91 +	: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
   13.92 +	: "memory");
   13.93 +return dest;
   13.94 +}
   13.95 +
   13.96 +#define __HAVE_ARCH_STRCMP
   13.97 +static inline int strcmp(const char * cs,const char * ct)
   13.98 +{
   13.99 +int d0, d1;
  13.100 +register int __res;
  13.101 +__asm__ __volatile__(
  13.102 +	"1:\tlodsb\n\t"
  13.103 +	"scasb\n\t"
  13.104 +	"jne 2f\n\t"
  13.105 +	"testb %%al,%%al\n\t"
  13.106 +	"jne 1b\n\t"
  13.107 +	"xorl %%eax,%%eax\n\t"
  13.108 +	"jmp 3f\n"
  13.109 +	"2:\tsbbl %%eax,%%eax\n\t"
  13.110 +	"orb $1,%%al\n"
  13.111 +	"3:"
  13.112 +	:"=a" (__res), "=&S" (d0), "=&D" (d1)
  13.113 +		     :"1" (cs),"2" (ct));
  13.114 +return __res;
  13.115 +}
  13.116 +
  13.117 +#define __HAVE_ARCH_STRNCMP
  13.118 +static inline int strncmp(const char * cs,const char * ct,size_t count)
  13.119 +{
  13.120 +register int __res;
  13.121 +int d0, d1, d2;
  13.122 +__asm__ __volatile__(
  13.123 +	"1:\tdecl %3\n\t"
  13.124 +	"js 2f\n\t"
  13.125 +	"lodsb\n\t"
  13.126 +	"scasb\n\t"
  13.127 +	"jne 3f\n\t"
  13.128 +	"testb %%al,%%al\n\t"
  13.129 +	"jne 1b\n"
  13.130 +	"2:\txorl %%eax,%%eax\n\t"
  13.131 +	"jmp 4f\n"
  13.132 +	"3:\tsbbl %%eax,%%eax\n\t"
  13.133 +	"orb $1,%%al\n"
  13.134 +	"4:"
  13.135 +		     :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
  13.136 +		     :"1" (cs),"2" (ct),"3" (count));
  13.137 +return __res;
  13.138 +}
  13.139 +
  13.140 +#define __HAVE_ARCH_STRCHR
  13.141 +static inline char * strchr(const char * s, int c)
  13.142 +{
  13.143 +int d0;
  13.144 +register char * __res;
  13.145 +__asm__ __volatile__(
  13.146 +	"movb %%al,%%ah\n"
  13.147 +	"1:\tlodsb\n\t"
  13.148 +	"cmpb %%ah,%%al\n\t"
  13.149 +	"je 2f\n\t"
  13.150 +	"testb %%al,%%al\n\t"
  13.151 +	"jne 1b\n\t"
  13.152 +	"movl $1,%1\n"
  13.153 +	"2:\tmovl %1,%0\n\t"
  13.154 +	"decl %0"
  13.155 +	:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
  13.156 +return __res;
  13.157 +}
  13.158 +
  13.159 +#define __HAVE_ARCH_STRRCHR
  13.160 +static inline char * strrchr(const char * s, int c)
  13.161 +{
  13.162 +int d0, d1;
  13.163 +register char * __res;
  13.164 +__asm__ __volatile__(
  13.165 +	"movb %%al,%%ah\n"
  13.166 +	"1:\tlodsb\n\t"
  13.167 +	"cmpb %%ah,%%al\n\t"
  13.168 +	"jne 2f\n\t"
  13.169 +	"leal -1(%%esi),%0\n"
  13.170 +	"2:\ttestb %%al,%%al\n\t"
  13.171 +	"jne 1b"
  13.172 +	:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
  13.173 +return __res;
  13.174 +}
  13.175 +
  13.176 +#define __HAVE_ARCH_STRLEN
  13.177 +static inline size_t strlen(const char * s)
  13.178 +{
  13.179 +int d0;
  13.180 +register int __res;
  13.181 +__asm__ __volatile__(
  13.182 +	"repne\n\t"
  13.183 +	"scasb\n\t"
  13.184 +	"notl %0\n\t"
  13.185 +	"decl %0"
  13.186 +	:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
  13.187 +return __res;
  13.188 +}
  13.189 +
  13.190 +static inline void * __memcpy(void * to, const void * from, size_t n)
  13.191 +{
  13.192 +int d0, d1, d2;
  13.193 +__asm__ __volatile__(
  13.194 +	"rep ; movsl\n\t"
  13.195 +	"testb $2,%b4\n\t"
  13.196 +	"je 1f\n\t"
  13.197 +	"movsw\n"
  13.198 +	"1:\ttestb $1,%b4\n\t"
  13.199 +	"je 2f\n\t"
  13.200 +	"movsb\n"
  13.201 +	"2:"
  13.202 +	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
  13.203 +	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
  13.204 +	: "memory");
  13.205 +return (to);
  13.206 +}
  13.207 +
  13.208 +/*
  13.209 + * This looks horribly ugly, but the compiler can optimize it totally,
  13.210 + * as the count is constant.
  13.211 + */
  13.212 +static inline void * __constant_memcpy(void * to, const void * from, size_t n)
  13.213 +{
  13.214 +	switch (n) {
  13.215 +		case 0:
  13.216 +			return to;
  13.217 +		case 1:
  13.218 +			*(unsigned char *)to = *(const unsigned char *)from;
  13.219 +			return to;
  13.220 +		case 2:
  13.221 +			*(unsigned short *)to = *(const unsigned short *)from;
  13.222 +			return to;
  13.223 +		case 3:
  13.224 +			*(unsigned short *)to = *(const unsigned short *)from;
  13.225 +			*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
  13.226 +			return to;
  13.227 +		case 4:
  13.228 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.229 +			return to;
  13.230 +		case 6:	/* for Ethernet addresses */
  13.231 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.232 +			*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
  13.233 +			return to;
  13.234 +		case 8:
  13.235 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.236 +			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  13.237 +			return to;
  13.238 +		case 12:
  13.239 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.240 +			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  13.241 +			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  13.242 +			return to;
  13.243 +		case 16:
  13.244 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.245 +			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  13.246 +			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  13.247 +			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  13.248 +			return to;
  13.249 +		case 20:
  13.250 +			*(unsigned long *)to = *(const unsigned long *)from;
  13.251 +			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
  13.252 +			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
  13.253 +			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
  13.254 +			*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
  13.255 +			return to;
  13.256 +	}
  13.257 +#define COMMON(x) \
  13.258 +__asm__ __volatile__( \
  13.259 +	"rep ; movsl" \
  13.260 +	x \
  13.261 +	: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
  13.262 +	: "0" (n/4),"1" ((long) to),"2" ((long) from) \
  13.263 +	: "memory");
  13.264 +{
  13.265 +	int d0, d1, d2;
  13.266 +	switch (n % 4) {
  13.267 +		case 0: COMMON(""); return to;
  13.268 +		case 1: COMMON("\n\tmovsb"); return to;
  13.269 +		case 2: COMMON("\n\tmovsw"); return to;
  13.270 +		default: COMMON("\n\tmovsw\n\tmovsb"); return to;
  13.271 +	}
  13.272 +}
  13.273 +  
  13.274 +#undef COMMON
  13.275 +}
  13.276 +
  13.277 +#define __HAVE_ARCH_MEMCPY
  13.278 +
  13.279 +#define memcpy(t, f, n) \
  13.280 +(__builtin_constant_p(n) ? \
  13.281 + __constant_memcpy((t),(f),(n)) : \
  13.282 + __memcpy((t),(f),(n)))
  13.283 +
  13.284 +
  13.285 +/*
  13.286 + * struct_cpy(x,y), copy structure *x into (matching structure) *y.
  13.287 + *
  13.288 + * We get link-time errors if the structure sizes do not match.
  13.289 + * There is no runtime overhead, it's all optimized away at
  13.290 + * compile time.
  13.291 + */
  13.292 +//extern void __struct_cpy_bug (void);
  13.293 +
  13.294 +/*
  13.295 +#define struct_cpy(x,y) 			\
  13.296 +({						\
  13.297 +	if (sizeof(*(x)) != sizeof(*(y))) 	\
  13.298 +		__struct_cpy_bug;		\
  13.299 +	memcpy(x, y, sizeof(*(x)));		\
  13.300 +})
  13.301 +*/
  13.302 +
  13.303 +#define __HAVE_ARCH_MEMMOVE
  13.304 +static inline void * memmove(void * dest,const void * src, size_t n)
  13.305 +{
  13.306 +int d0, d1, d2;
  13.307 +if (dest<src)
  13.308 +__asm__ __volatile__(
  13.309 +	"rep\n\t"
  13.310 +	"movsb"
  13.311 +	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
  13.312 +	:"0" (n),"1" (src),"2" (dest)
  13.313 +	: "memory");
  13.314 +else
  13.315 +__asm__ __volatile__(
  13.316 +	"std\n\t"
  13.317 +	"rep\n\t"
  13.318 +	"movsb\n\t"
  13.319 +	"cld"
  13.320 +	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
  13.321 +	:"0" (n),
  13.322 +	 "1" (n-1+(const char *)src),
  13.323 +	 "2" (n-1+(char *)dest)
  13.324 +	:"memory");
  13.325 +return dest;
  13.326 +}
  13.327 +
  13.328 +#define __HAVE_ARCH_MEMCMP
  13.329 +#define memcmp __builtin_memcmp
  13.330 +
  13.331 +#define __HAVE_ARCH_MEMCHR
  13.332 +static inline void * memchr(const void * cs,int c,size_t count)
  13.333 +{
  13.334 +int d0;
  13.335 +register void * __res;
  13.336 +if (!count)
  13.337 +	return NULL;
  13.338 +__asm__ __volatile__(
  13.339 +	"repne\n\t"
  13.340 +	"scasb\n\t"
  13.341 +	"je 1f\n\t"
  13.342 +	"movl $1,%0\n"
  13.343 +	"1:\tdecl %0"
  13.344 +	:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
  13.345 +return __res;
  13.346 +}
  13.347 +
  13.348 +static inline void * __memset_generic(void * s, char c,size_t count)
  13.349 +{
  13.350 +int d0, d1;
  13.351 +__asm__ __volatile__(
  13.352 +	"rep\n\t"
  13.353 +	"stosb"
  13.354 +	: "=&c" (d0), "=&D" (d1)
  13.355 +	:"a" (c),"1" (s),"0" (count)
  13.356 +	:"memory");
  13.357 +return s;
  13.358 +}
  13.359 +
  13.360 +/* we might want to write optimized versions of these later */
  13.361 +#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
  13.362 +
  13.363 +/*
  13.364 + * memset(x,0,y) is a reasonably common thing to do, so we want to fill
  13.365 + * things 32 bits at a time even when we don't know the size of the
  13.366 + * area at compile-time..
  13.367 + */
  13.368 +static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
  13.369 +{
  13.370 +int d0, d1;
  13.371 +__asm__ __volatile__(
  13.372 +	"rep ; stosl\n\t"
  13.373 +	"testb $2,%b3\n\t"
  13.374 +	"je 1f\n\t"
  13.375 +	"stosw\n"
  13.376 +	"1:\ttestb $1,%b3\n\t"
  13.377 +	"je 2f\n\t"
  13.378 +	"stosb\n"
  13.379 +	"2:"
  13.380 +	: "=&c" (d0), "=&D" (d1)
  13.381 +	:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
  13.382 +	:"memory");
  13.383 +return (s);	
  13.384 +}
  13.385 +
  13.386 +/* Added by Gertjan van Wingerde to make minix and sysv module work */
  13.387 +#define __HAVE_ARCH_STRNLEN
  13.388 +static inline size_t strnlen(const char * s, size_t count)
  13.389 +{
  13.390 +int d0;
  13.391 +register int __res;
  13.392 +__asm__ __volatile__(
  13.393 +	"movl %2,%0\n\t"
  13.394 +	"jmp 2f\n"
  13.395 +	"1:\tcmpb $0,(%0)\n\t"
  13.396 +	"je 3f\n\t"
  13.397 +	"incl %0\n"
  13.398 +	"2:\tdecl %1\n\t"
  13.399 +	"cmpl $-1,%1\n\t"
  13.400 +	"jne 1b\n"
  13.401 +	"3:\tsubl %2,%0"
  13.402 +	:"=a" (__res), "=&d" (d0)
  13.403 +	:"c" (s),"1" (count));
  13.404 +return __res;
  13.405 +}
  13.406 +/* end of additional stuff */
  13.407 +
  13.408 +//#define __HAVE_ARCH_STRSTR
  13.409 +
  13.410 +//extern char *strstr(const char *cs, const char *ct);
  13.411 +
  13.412 +/*
  13.413 + * This looks horribly ugly, but the compiler can optimize it totally,
  13.414 + * as we by now know that both pattern and count is constant..
  13.415 + */
  13.416 +static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
  13.417 +{
  13.418 +	switch (count) {
  13.419 +		case 0:
  13.420 +			return s;
  13.421 +		case 1:
  13.422 +			*(unsigned char *)s = pattern;
  13.423 +			return s;
  13.424 +		case 2:
  13.425 +			*(unsigned short *)s = pattern;
  13.426 +			return s;
  13.427 +		case 3:
  13.428 +			*(unsigned short *)s = pattern;
  13.429 +			*(2+(unsigned char *)s) = pattern;
  13.430 +			return s;
  13.431 +		case 4:
  13.432 +			*(unsigned long *)s = pattern;
  13.433 +			return s;
  13.434 +	}
  13.435 +#define COMMON(x) \
  13.436 +__asm__  __volatile__( \
  13.437 +	"rep ; stosl" \
  13.438 +	x \
  13.439 +	: "=&c" (d0), "=&D" (d1) \
  13.440 +	: "a" (pattern),"0" (count/4),"1" ((long) s) \
  13.441 +	: "memory")
  13.442 +{
  13.443 +	int d0, d1;
  13.444 +	switch (count % 4) {
  13.445 +		case 0: COMMON(""); return s;
  13.446 +		case 1: COMMON("\n\tstosb"); return s;
  13.447 +		case 2: COMMON("\n\tstosw"); return s;
  13.448 +		default: COMMON("\n\tstosw\n\tstosb"); return s;
  13.449 +	}
  13.450 +}
  13.451 +  
  13.452 +#undef COMMON
  13.453 +}
  13.454 +
  13.455 +#define __constant_c_x_memset(s, c, count) \
  13.456 +(__builtin_constant_p(count) ? \
  13.457 + __constant_c_and_count_memset((s),(c),(count)) : \
  13.458 + __constant_c_memset((s),(c),(count)))
  13.459 +
  13.460 +#define __memset(s, c, count) \
  13.461 +(__builtin_constant_p(count) ? \
  13.462 + __constant_count_memset((s),(c),(count)) : \
  13.463 + __memset_generic((s),(c),(count)))
  13.464 +
  13.465 +#define __HAVE_ARCH_MEMSET
  13.466 +#define memset(s, c, count) \
  13.467 +(__builtin_constant_p(c) ? \
  13.468 + __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
  13.469 + __memset((s),(c),(count)))
  13.470 +
  13.471 +/*
  13.472 + * find the first occurrence of byte 'c', or 1 past the area if none
  13.473 + */
  13.474 +#define __HAVE_ARCH_MEMSCAN
  13.475 +static inline void * memscan(void * addr, int c, size_t size)
  13.476 +{
  13.477 +	if (!size)
  13.478 +		return addr;
  13.479 +	__asm__("repnz; scasb\n\t"
  13.480 +		"jnz 1f\n\t"
  13.481 +		"dec %%edi\n"
  13.482 +		"1:"
  13.483 +		: "=D" (addr), "=c" (size)
  13.484 +		: "0" (addr), "1" (size), "a" (c));
  13.485 +	return addr;
  13.486 +}
  13.487 +
  13.488 +#endif
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xen/include/asm-x86/x86_64/string.h	Tue Jun 29 19:50:04 2004 +0000
    14.3 @@ -0,0 +1,69 @@
    14.4 +#ifndef _X86_64_STRING_H_
    14.5 +#define _X86_64_STRING_H_
    14.6 +
    14.7 +#ifdef __KERNEL__
    14.8 +
    14.9 +#define struct_cpy(x,y) (*(x)=*(y))
   14.10 +
   14.11 +/* Written 2002 by Andi Kleen */ 
   14.12 +
   14.13 +/* Only used for special circumstances. Stolen from i386/string.h */ 
   14.14 +static inline void * __inline_memcpy(void * to, const void * from, size_t n)
   14.15 +{
   14.16 +unsigned long d0, d1, d2;
   14.17 +__asm__ __volatile__(
   14.18 +	"rep ; movsl\n\t"
   14.19 +	"testb $2,%b4\n\t"
   14.20 +	"je 1f\n\t"
   14.21 +	"movsw\n"
   14.22 +	"1:\ttestb $1,%b4\n\t"
   14.23 +	"je 2f\n\t"
   14.24 +	"movsb\n"
   14.25 +	"2:"
   14.26 +	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
   14.27 +	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
   14.28 +	: "memory");
   14.29 +return (to);
   14.30 +}
   14.31 +
   14.32 +/* Even with __builtin_ the compiler may decide to use the out of line
   14.33 +   function. */
   14.34 +
   14.35 +#define __HAVE_ARCH_MEMCPY 1
   14.36 +extern void *__memcpy(void *to, const void *from, size_t len); 
   14.37 +#define memcpy(dst,src,len) \
   14.38 +	({ size_t __len = (len);				\
   14.39 +	   void *__ret;						\
   14.40 +	   if (__builtin_constant_p(len) && __len >= 64)	\
   14.41 +		 __ret = __memcpy((dst),(src),__len);		\
   14.42 +	   else							\
   14.43 +		 __ret = __builtin_memcpy((dst),(src),__len);	\
   14.44 +	   __ret; }) 
   14.45 +
   14.46 +
   14.47 +#define __HAVE_ARCH_MEMSET
   14.48 +#define memset __builtin_memset
   14.49 +
   14.50 +#define __HAVE_ARCH_MEMMOVE
   14.51 +void * memmove(void * dest,const void *src,size_t count);
   14.52 +
   14.53 +/* Use C out of line version for memcmp */ 
   14.54 +#define memcmp __builtin_memcmp
   14.55 +int memcmp(const void * cs,const void * ct,size_t count);
   14.56 +
   14.57 +/* out of line string functions use always C versions */ 
   14.58 +#define strlen __builtin_strlen
   14.59 +size_t strlen(const char * s);
   14.60 +
   14.61 +#define strcpy __builtin_strcpy
   14.62 +char * strcpy(char * dest,const char *src);
   14.63 +
   14.64 +#define strcat __builtin_strcat
   14.65 +char * strcat(char * dest, const char * src);
   14.66 +
   14.67 +#define strcmp __builtin_strcmp
   14.68 +int strcmp(const char * cs,const char * ct);
   14.69 +
   14.70 +#endif /* __KERNEL__ */
   14.71 +
   14.72 +#endif
    15.1 --- a/xen/include/xen/mm.h	Tue Jun 29 19:45:18 2004 +0000
    15.2 +++ b/xen/include/xen/mm.h	Tue Jun 29 19:50:04 2004 +0000
    15.3 @@ -86,7 +86,7 @@ struct pfn_info
    15.4  #define PageSetSlab(page)	((void)0)
    15.5  #define PageClearSlab(page)	((void)0)
    15.6  
    15.7 -#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < MAX_XENHEAP_ADDRESS)
    15.8 +#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
    15.9  
   15.10  #define SHARE_PFN_WITH_DOMAIN(_pfn, _dom)                                   \
   15.11      do {                                                                    \
   15.12 @@ -104,7 +104,7 @@ extern struct list_head free_list;
   15.13  extern spinlock_t free_list_lock;
   15.14  extern unsigned int free_pfns;
   15.15  extern unsigned long max_page;
   15.16 -void init_frametable(unsigned long nr_pages);
   15.17 +void init_frametable(void *frametable_vstart, unsigned long nr_pages);
   15.18  void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
   15.19  
   15.20  struct pfn_info *alloc_domain_page(struct domain *p);