ia64/xen-unstable

changeset 1169:523427204b5a

bitkeeper revision 1.786 (4051a33dlWQlrVd1OVpwmHvW8Lp8Zw)

serial.h, serial.c, traps.c, pdb-stub.c:
Fix serial-char receive for PDB.
author kaf24@scramble.cl.cam.ac.uk
date Fri Mar 12 11:47:09 2004 +0000 (2004-03-12)
parents 9f76e6bae78e
children 3180669cb85d
files xen/arch/i386/pdb-stub.c xen/arch/i386/traps.c xen/drivers/char/serial.c xen/include/xeno/serial.h
line diff
     1.1 --- a/xen/arch/i386/pdb-stub.c	Fri Mar 12 11:08:26 2004 +0000
     1.2 +++ b/xen/arch/i386/pdb-stub.c	Fri Mar 12 11:47:09 2004 +0000
     1.3 @@ -32,11 +32,6 @@ void pdb_put_packet (unsigned char *buff
     1.4  int pdb_initialized = 0;
     1.5  static int pdb_serhnd      = -1;
     1.6  
     1.7 -#define RX_SIZE 32
     1.8 -#define RX_MASK(_i) ((_i)&(RX_SIZE-1))
     1.9 -static unsigned int rx_cons = 0, rx_prod = 0;
    1.10 -static unsigned char rx_ring[RX_RING_SIZE];
    1.11 -
    1.12  static inline void pdb_put_char(unsigned char c)
    1.13  {
    1.14      serial_putc(pdb_serhnd, c);
    1.15 @@ -44,15 +39,7 @@ static inline void pdb_put_char(unsigned
    1.16  
    1.17  static inline unsigned char pdb_get_char(void)
    1.18  {
    1.19 -    while ( rx_cons == rx_prod )
    1.20 -        barrier();
    1.21 -    return rx_ring[RX_MASK(rx_cons++)];
    1.22 -}
    1.23 -
    1.24 -static void pdb_rx_char(unsigned char c, struct pt_regs *regs)
    1.25 -{
    1.26 -    if ( (rx_prod - rx_cons) != RX_SIZE )
    1.27 -        rx_ring[RX_MASK(rx_prod++)] = c;
    1.28 +    return serial_getc(pdb_serhnd);
    1.29  }
    1.30  
    1.31  static volatile int mem_err = 0;
    1.32 @@ -844,8 +831,6 @@ void initialize_pdb()
    1.33          return;
    1.34      }
    1.35  
    1.36 -    serial_set_rx_handler(pdb_serhnd, pdb_rx_char);
    1.37 -
    1.38      printk("Initialised pervasive debugger (PDB) on port %s\n", opt_pdb);
    1.39  
    1.40      /* Acknowledge any spurious GDB packets. */
     2.1 --- a/xen/arch/i386/traps.c	Fri Mar 12 11:08:26 2004 +0000
     2.2 +++ b/xen/arch/i386/traps.c	Fri Mar 12 11:47:09 2004 +0000
     2.3 @@ -196,8 +196,6 @@ static inline void do_trap(int trapnr, c
     2.4      trap_info_t *ti;
     2.5      unsigned long fixup;
     2.6  
     2.7 -    __sti();
     2.8 -
     2.9      if (!(regs->xcs & 3))
    2.10          goto fault_in_hypervisor;
    2.11  
    2.12 @@ -259,8 +257,6 @@ asmlinkage void do_int3(struct pt_regs *
    2.13      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    2.14      trap_info_t *ti;
    2.15  
    2.16 -    __sti();
    2.17 -
    2.18      if ( (regs->xcs & 3) != 3 )
    2.19      {
    2.20          if ( pdb_handle_exception(3, regs) == 0 )
    2.21 @@ -327,8 +323,6 @@ asmlinkage void do_page_fault(struct pt_
    2.22  
    2.23      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
    2.24  
    2.25 -    __sti();
    2.26 -
    2.27      if ( unlikely(addr >= LDT_VIRT_START) && 
    2.28           (addr < (LDT_VIRT_START + (p->mm.ldt_ents*LDT_ENTRY_SIZE))) )
    2.29      {
    2.30 @@ -396,8 +390,6 @@ asmlinkage void do_general_protection(st
    2.31      trap_info_t *ti;
    2.32      unsigned long fixup;
    2.33  
    2.34 -    __sti();
    2.35 -
    2.36      /* Badness if error in ring 0, or result of an interrupt. */
    2.37      if ( !(regs->xcs & 3) || (error_code & 1) )
    2.38          goto gp_in_kernel;
    2.39 @@ -506,8 +498,6 @@ asmlinkage void math_state_restore(struc
    2.40      /* Prevent recursion. */
    2.41      clts();
    2.42  
    2.43 -    __sti();
    2.44 -
    2.45      if ( !test_bit(PF_USEDFPU, &current->flags) )
    2.46      {
    2.47          if ( test_bit(PF_DONEFPUINIT, &current->flags) )
    2.48 @@ -532,8 +522,6 @@ asmlinkage void do_debug_orig(struct pt_
    2.49      struct task_struct *tsk = current;
    2.50      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    2.51  
    2.52 -    __sti();
    2.53 -
    2.54      __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
    2.55  
    2.56      /* Mask out spurious debug traps due to lazy DR7 setting */
    2.57 @@ -580,8 +568,6 @@ asmlinkage void do_debug(struct pt_regs 
    2.58          return;
    2.59      }
    2.60  
    2.61 -    __sti();
    2.62 -
    2.63      __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
    2.64      if ( (condition & (1 << 14)) != (1 << 14) )
    2.65          printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
     3.1 --- a/xen/drivers/char/serial.c	Fri Mar 12 11:08:26 2004 +0000
     3.2 +++ b/xen/drivers/char/serial.c	Fri Mar 12 11:47:09 2004 +0000
     3.3 @@ -70,10 +70,14 @@
     3.4  #define PARITY_MARK     (5<<3)
     3.5  #define PARITY_SPACE    (7<<3)
     3.6  
     3.7 +#define RXBUFSZ 32
     3.8 +#define MASK_RXBUF_IDX(_i) ((_i)&(RXBUFSZ-1))
     3.9  typedef struct {
    3.10 -    int          baud, data_bits, parity, stop_bits, io_base, irq;
    3.11 -    serial_rx_fn rx_lo, rx_hi, rx;
    3.12 -    spinlock_t   lock;
    3.13 +    int           baud, data_bits, parity, stop_bits, io_base, irq;
    3.14 +    serial_rx_fn  rx_lo, rx_hi, rx;
    3.15 +    spinlock_t    lock;
    3.16 +    unsigned char rxbuf[RXBUFSZ];
    3.17 +    unsigned int  rxbufp, rxbufc;
    3.18  } uart_t;
    3.19  
    3.20  static uart_t com[2] = {
    3.21 @@ -103,6 +107,7 @@ static void uart_rx(uart_t *uart, struct
    3.22      /*
    3.23       * No need for the uart spinlock here. Only the uart's own interrupt
    3.24       * handler will read from the RBR and the handler isn't reentrant.
    3.25 +     * Calls to serial_getc() will disable this handler before proceeding.
    3.26       */
    3.27      while ( inb(uart->io_base + LSR) & LSR_DR )
    3.28      {
    3.29 @@ -113,6 +118,8 @@ static void uart_rx(uart_t *uart, struct
    3.30              uart->rx_hi(c&0x7f, regs);
    3.31          else if ( !(c & 0x80) && (uart->rx_lo != NULL) )
    3.32              uart->rx_lo(c&0x7f, regs);
    3.33 +        else if ( (uart->rxbufp - uart->rxbufc) != RXBUFSZ )
    3.34 +            uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufp++)] = c;            
    3.35      }
    3.36  }
    3.37  
    3.38 @@ -396,3 +403,59 @@ void serial_puts(int handle, const unsig
    3.39  
    3.40      spin_unlock_irqrestore(&uart->lock, flags);
    3.41  }
    3.42 +
    3.43 +/* Returns TRUE if given character (*pc) matches the serial handle. */
    3.44 +static int byte_matches(int handle, unsigned char *pc)
    3.45 +{
    3.46 +    if ( !(handle & SERHND_HI) )
    3.47 +    {
    3.48 +        if ( !(handle & SERHND_LO) || !(*pc & 0x80) )
    3.49 +            return 1;
    3.50 +    }
    3.51 +    else if ( *pc & 0x80 )
    3.52 +    {
    3.53 +        *pc &= 0x7f;
    3.54 +        return 1;
    3.55 +    }
    3.56 +    return 0;
    3.57 +}
    3.58 +
    3.59 +unsigned char serial_getc(int handle)
    3.60 +{
    3.61 +    uart_t *uart = &com[handle & SERHND_IDX];
    3.62 +    unsigned char c;
    3.63 +    unsigned long flags;
    3.64 +
    3.65 +    spin_lock_irqsave(&uart->lock, flags);
    3.66 +
    3.67 +    while ( uart->rxbufp != uart->rxbufc )
    3.68 +    {
    3.69 +        c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)];
    3.70 +        if ( byte_matches(handle, &c) )
    3.71 +            goto out;
    3.72 +    }
    3.73 +    
    3.74 +    disable_irq(uart->irq);
    3.75 +    
    3.76 +    /* disable_irq() may have raced execution of uart_rx(). */
    3.77 +    while ( uart->rxbufp != uart->rxbufc )
    3.78 +    {
    3.79 +        c = uart->rxbuf[MASK_RXBUF_IDX(uart->rxbufc++)];
    3.80 +        if ( byte_matches(handle, &c) )
    3.81 +            goto enable_and_out;
    3.82 +    }
    3.83 +
    3.84 +    /* We now wait for the UART to receive a suitable character. */
    3.85 +    do {
    3.86 +        while ( (inb(uart->io_base + LSR) & LSR_DR) == 0 )
    3.87 +            barrier();
    3.88 +        c = inb(uart->io_base + RBR);
    3.89 +    }
    3.90 +    while ( !byte_matches(handle, &c) );
    3.91 +    
    3.92 + enable_and_out:
    3.93 +    enable_irq(uart->irq);
    3.94 + out:
    3.95 +    spin_unlock_irqrestore(&uart->lock, flags);
    3.96 +    return c;
    3.97 +}
     4.1 --- a/xen/include/xeno/serial.h	Fri Mar 12 11:08:26 2004 +0000
     4.2 +++ b/xen/include/xeno/serial.h	Fri Mar 12 11:47:09 2004 +0000
     4.3 @@ -36,4 +36,11 @@ void serial_putc(int handle, unsigned ch
     4.4  /* Transmit a NULL-terminated string via the specified COM port. */
     4.5  void serial_puts(int handle, const unsigned char *s);
     4.6  
     4.7 +/*
     4.8 + * An alternative to registering a character-receive hook. This function
     4.9 + * will not return until a character is available. It can safely be
    4.10 + * called with interrupts disabled.
    4.11 + */
    4.12 +unsigned char serial_getc(int handle);
    4.13 +
    4.14  #endif /* __XEN_SERIAL_H__ */