Пример #1
0
Файл: uart.c Проект: RTEMS/rtems
ssize_t
BSP_uart_termios_write_com2(int minor, const char *buf, size_t len)
{
  if(len <= 0)
    {
      return 0;
    }

  assert(buf != NULL);

  /* If there TX buffer is busy - something is royally screwed up */
  assert((uread(BSP_UART_COM2, LSR) & THRE) != 0);

  if(termios_stopped_com2)
    {
      /* CTS low */
      termios_tx_hold_com2       = *buf;
      termios_tx_hold_valid_com2 = 1;
      return 0;
    }

  /* Write character */
  uwrite(BSP_UART_COM2, THR, *buf & 0xff);

  /* Enable interrupts if necessary */
  if ( !termios_tx_active_com2 ) {
    termios_tx_active_com2 = 1;
    uart_data[BSP_UART_COM2].ier |= TRANSMIT_ENABLE;
    uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
  }

  return 1;
}
Пример #2
0
void
common_putc(dev_t dev, int c)
{
	/* Always send to stdout. */
	(void)uwrite(1, &c, 1);

	/* Copy to serial if open. */
	if (com_fd != -1)
		(void)uwrite(com_fd, &c, 1);
}
Пример #3
0
/*
 * Set baud
 */
void
BSP_uart_set_baud(int uart, int baud)
{
  unsigned char  ier;

  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  /*
   * This function may be called whenever TERMIOS parameters
   * are changed, so we have to make sure that baud change is
   * indeed required
   */

  if(baud == uart_data[uart].baud)
    {
      return;
    }

  ier = uread(uart, IER);

  BSP_uart_init(uart, baud, uart_data[uart].hwFlow);

  uwrite(uart, IER, ier);

  return;
}
Пример #4
0
static void LCD_WR_REG(uint8_t da)	 
{
	
    gpio_set_value(GPIO_PIN_LED_A0,0);
	uwrite(&da,1);
	gpio_set_value(GPIO_PIN_LED_A0,1);
}
Пример #5
0
Файл: uart.c Проект: RTEMS/rtems
/*
 * Enable/disable interrupts
 */
void
BSP_uart_intr_ctrl(int uart, int cmd)
{
  int iStatus = (int)INTERRUPT_DISABLE;

  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  switch(cmd)
    {
    case BSP_UART_INTR_CTRL_ENABLE:
      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | TRANSMIT_ENABLE);
      if ( uart_data[uart].hwFlow ) {
        iStatus |= MODEM_ENABLE;
      }
      break;
    case BSP_UART_INTR_CTRL_TERMIOS:
      iStatus |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
      if ( uart_data[uart].hwFlow ) {
        iStatus |= MODEM_ENABLE;
      }
      break;
    case BSP_UART_INTR_CTRL_GDB:
      iStatus |= RECEIVE_ENABLE;
      break;
    }

  uart_data[uart].ier = iStatus;
  uwrite(uart, IER, iStatus);

  return;
}
Пример #6
0
int
fasttrap_tracepoint_remove(proc_t *p, fasttrap_tracepoint_t *tp)
{
	/* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
	uint32_t instr;
	int size = tp->ftt_thumb ? 2 : 4;

	/*
	 * Distinguish between read or write failures and a changed
	 * instruction.
	 */
	if (uread(p, &instr, size, tp->ftt_pc) != 0)
		goto end;
	if (tp->ftt_thumb) {
		if (*((uint16_t*) &instr) != FASTTRAP_THUMB_INSTR)
			goto end;
	} else {
		if (instr != FASTTRAP_ARM_INSTR)
			goto end;
	}
	if (uwrite(p, &tp->ftt_instr, size, tp->ftt_pc) != 0)
		return (-1);

end:
	tp->ftt_installed = 0;

	return (0);
}
Пример #7
0
void
BSP_uart_termios_isr_com2()
{
  unsigned char buf[40];
  int      off, ret, vect;

  off = 0;

  for(;;)
    {
      vect = uread(BSP_UART_COM2, IIR) & 0xf;

      switch(vect)
	{
	case NO_MORE_INTR :
	  /* No more interrupts */
	  if(off != 0)
	    {
	      /* Update rx buffer */
	      rtems_termios_enqueue_raw_characters(termios_ttyp_com2,
						   (char *)buf,
						   off);
	    }
	  return;
	case TRANSMITTER_HODING_REGISTER_EMPTY :
	  /*
	   * TX holding empty: we have to disable these interrupts
	   * if there is nothing more to send.
	   */

	  ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);

	  /* If nothing else to send disable interrupts */
	  if(ret == 0)
	    {
	      uwrite(BSP_UART_COM2, IER,
		     (RECEIVE_ENABLE  |
		      RECEIVER_LINE_ST_ENABLE
		     )
		    );
              termios_tx_active_com2 = 0;
	    }
	  break;
	case RECEIVER_DATA_AVAIL :
	case CHARACTER_TIMEOUT_INDICATION:
	  /* RX data ready */
	  assert(off < sizeof(buf));
	  buf[off++] = uread(BSP_UART_COM2, RBR);
	  break;
	case RECEIVER_ERROR:
	  /* RX error: eat character */
	   uartError(BSP_UART_COM2);
	  break;
	default:
	  /* Should not happen */
	  assert(0);
	  return;
	}
    }
}
Пример #8
0
static void LCD_WR16(uint16_t da)
{
	char tmp[2], *buf;
	buf=(char* )&da;
	tmp[1]=*buf;
	tmp[0]=*(buf+1);
	uwrite(tmp, 2);
}
Пример #9
0
int
fasttrap_tracepoint_install(proc_t *p, fasttrap_tracepoint_t *tp)
{
	fasttrap_instr_t instr = FASTTRAP_INSTR;

	if (uwrite(p, &instr, 1, tp->ftt_pc) != 0)
		return (-1);

	return (0);
}
Пример #10
0
Файл: uart.c Проект: RTEMS/rtems
void
BSP_uart_set_attributes
(
  int uart,
  unsigned long baud,
  unsigned long databits,
  unsigned long parity,
  unsigned long stopbits
)
{
  unsigned char mcr, ier;

  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  /*
   * This function may be called whenever TERMIOS parameters
   * are changed, so we have to make sure that baud change is
   * indeed required
   */

  if( (baud     == uart_data[uart].baud)     &&
      (databits == uart_data[uart].databits) &&
      (parity   == uart_data[uart].parity)   &&
      (stopbits == uart_data[uart].stopbits) )
    {
      return;
    }

  mcr = uread(uart, MCR);
  ier = uread(uart, IER);

  BSP_uart_init(uart, baud, databits, parity, stopbits, uart_data[uart].hwFlow);

  uwrite(uart, MCR, mcr);
  uwrite(uart, IER, ier);

  return;
}
Пример #11
0
int main( int argc , char **argv )
{

	unsigned long cliaddr;
	unsigned short cliport;
	
	int ufd , nfd;

	fprintf( stderr, "start\n");

	uinit(INADDR_ANY);
	fprintf( stderr, "inited\n");	
	ufd = usocket_serv( 8 );
	fprintf( stderr, "socketd %d\n", ufd );
	ulisten( ufd );
	fprintf( stderr, "listened\n");
	while(1){
		int r =uproc();
/*		fprintf( stderr, "uproced %d\n" , r);*/
		nfd = uaccept( ufd , &cliaddr ,&cliport);
		if( nfd >= 0 ){
			fprintf( stderr, "accepted! nfd:%d %x %d\n" , nfd ,cliaddr , ntohs(cliport) );
			break;
		}
	}
	while(1){
		int r = uproc();
		
		fprintf( stderr,"." );

		if( ureadable( nfd ) ){
			char buffer[800];
			int r;
			fprintf( stderr, "REadable!!\n");
			bzero( buffer ,sizeof(buffer));
			if( (r = uread( nfd, buffer , sizeof( buffer ) )) >= 0 ){
				int wr;
				fprintf( stderr , "ReadData %d: [%s]\n" ,r, buffer );
				wr = uwrite( nfd , buffer , r );
				fprintf( stderr ,"Wrote %dbytes\n",wr );
				
			}
		}
		
		usleep(100*1000);

	}
	

	
}
Пример #12
0
int
BSP_uart_termios_write_com1(int minor, const char *buf, int len)
{
  assert(buf != NULL);

  if(len <= 0)
    {
      return 0;
    }

  /* If there TX buffer is busy - something is royally screwed up */
  assert((uread(BSP_UART_COM1, LSR) & THRE) != 0);

  if(termios_stopped_com1)
    {
      /* CTS low */
      termios_tx_hold_com1       = *buf;
      termios_tx_hold_valid_com1 = 1;
      return 0;
    }

  /* Write character */
  uwrite(BSP_UART_COM1, THR, *buf & 0xff);

  /* Enable interrupts if necessary */
  if(!termios_tx_active_com1)
    {
      termios_tx_active_com1 = 1;
      uwrite(BSP_UART_COM1, IER,
	     (RECEIVE_ENABLE  |
	      TRANSMIT_ENABLE |
	      RECEIVER_LINE_ST_ENABLE
	     )
	    );
    }

  return 0;
}
Пример #13
0
/*
 * Uart initialization, it is hardcoded to 8 bit, no parity,
 * one stop bit, FIFO, things to be changed
 * are baud rate and nad hw flow control,
 * and longest rx fifo setting
 */
void
BSP_uart_init(int uart, int baud, int hwFlow)
{
  unsigned char tmp;

  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  switch(baud)
    {
    case 50:
    case 75:
    case 110:
    case 134:
    case 300:
    case 600:
    case 1200:
    case 2400:
    case 9600:
    case 19200:
    case 38400:
    case 57600:
    case 115200:
      break;
    default:
      assert(0);
      return;
    }

  /* Enable UART block */
  uwrite(uart, CNT, UART_ENABLE | PAD_ENABLE);

  /* Set DLAB bit to 1 */
  uwrite(uart, LCR, DLAB);

  /* Set baud rate */
  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);

  /* 8-bit, no parity , 1 stop */
  uwrite(uart, LCR, CHR_8_BITS);

  /* Enable FIFO */
  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);

  /* Disable Interrupts */
  uwrite(uart, IER, 0);

  /* Read status to clear them */
  tmp = uread(uart, LSR);
  tmp = uread(uart, RBR);

  /* Remember state */
  uart_data[uart].hwFlow     = hwFlow;
  uart_data[uart].baud       = baud;
  return;
}
Пример #14
0
int main(int argc, char *argv[]) { 
	char name[64];
	int pid, cmd;
	int pd[2];

	while(1){

		printf("\n----------------------------------------------\n");
		#ifndef _LAB_3_
			printf("I am proc %d in U mode with ppid %d: running segment=%x\n",getpid(), getppid(), getcs());
		#else
			printf("I am proc "); getpid(); printf(" in U mode: running segment=%x\n", getcs());
		#endif

		#ifdef _SLEEPER_
			while(1) {
				printf("PID: %d PPID: %d\n", getpid(), getppid());
				sleep(5);
				return 0;
			}
		#endif

		show_menu();
		printf("Command? ");
		gets(name);
		printf("\n"); 
		if (name[0]==0) 
		continue;

		cmd = find_cmd(name);
		switch(cmd){
			case 0:		getpid();	break;
			case 1:		ps();		break;
			case 2:		chname();	break;
			case 3:		kswitch();	break;
			case 4:		wait();		break;
			case 5:		ufork();	break;
			case 6:		uexec();	break;
			case 7: 	exit();		break;
			case 8: 	pipe(pd);	break;
			case 9: 	pfd();		break;
			case 10:	uclose();	break;
			case 11:	uread();	break;
			case 12:	uwrite();	break;
			case 13:	usleep();	break;
			default:invalid(name);break;
		}
	}
}
Пример #15
0
/*
 * Enable/disable interrupts
 */
void
BSP_uart_intr_ctrl(int uart, int cmd)
{

  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  switch(cmd)
    {
    case BSP_UART_INTR_CTRL_DISABLE:
      uwrite(uart, IER, INTERRUPT_DISABLE);
      break;
    case BSP_UART_INTR_CTRL_ENABLE:
      uwrite(uart, IER,
	     (RECEIVE_ENABLE  |
	      TRANSMIT_ENABLE |
	      RECEIVER_LINE_ST_ENABLE
	      )
	     );
      break;
    case BSP_UART_INTR_CTRL_TERMIOS:
      uwrite(uart, IER,
	     (RECEIVE_ENABLE  |
	      RECEIVER_LINE_ST_ENABLE
	      )
	     );
      break;
    case BSP_UART_INTR_CTRL_GDB:
      uwrite(uart, IER, RECEIVE_ENABLE);
      break;
    default:
      assert(0);
      break;
    }

  return;
}
Пример #16
0
Файл: uart.c Проект: RTEMS/rtems
/*
 * Polled mode write function
 */
void
BSP_uart_polled_write(int uart, int val)
{
  unsigned char val1;

  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  for(;;)
    {
      if((val1=uread(uart, LSR)) & THRE)
	{
	  break;
	}
    }

  if(uart_data[uart].hwFlow)
    {
      for(;;)
	{
	  if(uread(uart, MSR) & CTS)
	    {
	      break;
	    }
	}
    }

  uwrite(uart, THR, val & 0xff);

  /*
   * Wait for character to be transmitted.
   * This ensures that printk and printf play nicely together
   * when using the same serial port.
   * Yes, there's a performance hit here, but if we're doing
   * polled writes to a serial port we're probably not that
   * interested in efficiency anyway.....
   */
  for(;;)
    {
      if((val1=uread(uart, LSR)) & THRE)
      {
      break;
      }
    }

  return;
}
Пример #17
0
static char*
sendMediaproxyCommand(char *command)
{
    struct sockaddr_un addr;
    int smpSocket, len;
    static char buf[1024];

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_LOCAL;
    strncpy(addr.sun_path, mediaproxySocket, sizeof(addr.sun_path) - 1);
#ifdef HAVE_SOCKADDR_SA_LEN
    addr.sun_len = strlen(addr.sun_path);
#endif

    smpSocket = socket(AF_LOCAL, SOCK_STREAM, 0);
    if (smpSocket < 0) {
        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't create socket\n");
        return NULL;
    }
    if (connect(smpSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
        close(smpSocket);
        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't connect to MediaProxy\n");
        return NULL;
    }

    len = uwrite(smpSocket, command, strlen(command));

    if (len <= 0) {
        close(smpSocket);
        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't send command to MediaProxy\n");
        return NULL;
    }

    len = readall(smpSocket, buf, sizeof(buf)-1);

    close(smpSocket);

    if (len < 0) {
        LOG(L_ERR, "error: mediaproxy/sendMediaproxyCommand(): can't read reply from MediaProxy\n");
        return NULL;
    }

    buf[len] = 0;

    return buf;
}
Пример #18
0
int
fasttrap_tracepoint_remove(proc_t *p, fasttrap_tracepoint_t *tp)
{
	uint8_t instr;

	/*
	 * Distinguish between read or write failures and a changed
	 * instruction.
	 */
	if (uread(p, &instr, 1, tp->ftt_pc) != 0)
		return (0);
	if (instr != FASTTRAP_INSTR)
		return (0);
	if (uwrite(p, &tp->ftt_instr[0], 1, tp->ftt_pc) != 0)
		return (-1);

	return (0);
}
Пример #19
0
int
fasttrap_tracepoint_install(proc_t *p, fasttrap_tracepoint_t *tp)
{
	/* The thumb patch is a 2 byte instruction regardless of the size of the original instruction */
	uint32_t instr;
	int size = tp->ftt_thumb ? 2 : 4;

	if (tp->ftt_thumb) {
		*((uint16_t*) &instr) = FASTTRAP_THUMB_INSTR;
	} else {
		instr = FASTTRAP_ARM_INSTR;
	}

	if (uwrite(p, &instr, size, tp->ftt_pc) != 0)
		return (-1);

	tp->ftt_installed = 1;

	return (0);
}
Пример #20
0
Файл: uart.c Проект: RTEMS/rtems
void
BSP_uart_unthrottle(int uart)
{
  unsigned int mcr;

  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  if(!uart_data[uart].hwFlow)
    {
      /* Should not happen */
      assert(0);
      return;
    }
  mcr = uread (uart, MCR);
  /* RTS up */
  mcr |= RTS;
  uwrite(uart, MCR, mcr);

  return;
}
Пример #21
0
/*
 * Polled mode write function
 */
void
BSP_uart_polled_write(int uart, int val)
{
  unsigned char val1;

  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  for(;;)
    {
      if((val1=uread(uart, LSR)) & THRE)
	{
	  break;
	}
    }

  uwrite(uart, THR, val & 0xff);

  return;
}
Пример #22
0
Файл: uart.c Проект: RTEMS/rtems
int
BSP_uart_termios_read_com2(int uart)
{
  int     off = (int)0;
  char    buf[40];

  /* read current byte */
  while (( off < sizeof(buf) ) && ( uread(BSP_UART_COM2, LSR) & DR )) {
    buf[off++] = uread(BSP_UART_COM2, RBR);
  }

  /* write out data */
  if ( off > 0 ) {
    rtems_termios_enqueue_raw_characters(termios_ttyp_com2, buf, off);
  }

  /* enable receive interrupts */
  uart_data[BSP_UART_COM2].ier |= (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
  uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);

  return ( EOF );
}
Пример #23
0
Файл: uart.c Проект: RTEMS/rtems
/*
 * Uart initialization, it is hardcoded to 8 bit, no parity,
 * one stop bit, FIFO, things to be changed
 * are baud rate and nad hw flow control,
 * and longest rx fifo setting
 */
void
BSP_uart_init
(
  int uart,
  unsigned long baud,
  unsigned long databits,
  unsigned long parity,
  unsigned long stopbits,
  int hwFlow
)
{
  /* Sanity check */
  assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2);

  switch(baud)
    {
    case 50:
    case 75:
    case 110:
    case 134:
    case 300:
    case 600:
    case 1200:
    case 2400:
    case 9600:
    case 19200:
    case 38400:
    case 57600:
    case 115200:
      break;
    default:
      assert(0);
      return;
    }

  /* Set DLAB bit to 1 */
  uwrite(uart, LCR, DLAB);

  /* Set baud rate */
  uwrite(uart, DLL,  (BSPBaseBaud/baud) & 0xff);
  uwrite(uart, DLM,  ((BSPBaseBaud/baud) >> 8) & 0xff);

  /* 8-bit, no parity , 1 stop */
  uwrite(uart, LCR, databits | parity | stopbits);

  /* Set DTR, RTS and OUT2 high */
  uwrite(uart, MCR, DTR | RTS | OUT_2);

  /* Enable FIFO */
  uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);

  /* Disable Interrupts */
  uwrite(uart, IER, 0);

  /* Read status to clear them */
  uread(uart, LSR);
  uread(uart, RBR);
  uread(uart, MSR);

  /* Remember state */
  uart_data[uart].baud       = baud;
  uart_data[uart].databits   = databits;
  uart_data[uart].parity     = parity;
  uart_data[uart].stopbits   = stopbits;
  uart_data[uart].hwFlow     = hwFlow;
  return;
}
Пример #24
0
Файл: uart.c Проект: RTEMS/rtems
void
BSP_uart_termios_isr_com2(void *ignored)
{
  unsigned char buf[40];
  unsigned char val;
  int      off, ret, vect;

  off = 0;

  for(;;)
    {
      vect = uread(BSP_UART_COM2, IIR) & 0xf;

      switch(vect)
	{
	case MODEM_STATUS :
	  val = uread(BSP_UART_COM2, MSR);
	  if(uart_data[BSP_UART_COM2].hwFlow)
	    {
	      if(val & CTS)
		{
		  /* CTS high */
		  termios_stopped_com2 = 0;
		  if(termios_tx_hold_valid_com2)
		    {
		      termios_tx_hold_valid_com2 = 0;
		      BSP_uart_termios_write_com2(0, &termios_tx_hold_com2,
						    1);
		    }
		}
	      else
		{
		  /* CTS low */
		  termios_stopped_com2 = 1;
		}
	    }
	  break;
	case NO_MORE_INTR :
	  /* No more interrupts */
	  if(off != 0)
	    {
	      /* Update rx buffer */
         if( driver_input_handler_com2 )
         {
             driver_input_handler_com2( termios_ttyp_com2, (char *)buf, off );
         }
         else
         {
	        rtems_termios_enqueue_raw_characters(termios_ttyp_com2, (char *)buf, off);
         }
	    }
	  return;
	case TRANSMITTER_HODING_REGISTER_EMPTY :
	  /*
	   * TX holding empty: we have to disable these interrupts
	   * if there is nothing more to send.
	   */

	  /* If nothing else to send disable interrupts */
	  ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1);
          if ( ret == 0 ) {
            termios_tx_active_com2 = 0;
            uart_data[BSP_UART_COM2].ier &= ~(TRANSMIT_ENABLE);
            uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
          }
	  break;
	case RECEIVER_DATA_AVAIL :
	case CHARACTER_TIMEOUT_INDICATION:
          if ( uart_data[BSP_UART_COM2].ioMode == TERMIOS_TASK_DRIVEN ) {
            /* ensure interrupts are enabled */
            if ( uart_data[BSP_UART_COM2].ier & RECEIVE_ENABLE ) {
              /* disable interrupts and notify termios */
              uart_data[BSP_UART_COM2].ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
              uwrite(BSP_UART_COM2, IER, uart_data[BSP_UART_COM2].ier);
              rtems_termios_rxirq_occured(termios_ttyp_com2);
            }
          }
          else {
	    /* RX data ready */
	    assert(off < sizeof(buf));
	    buf[off++] = uread(BSP_UART_COM2, RBR);
          }
	  break;
	case RECEIVER_ERROR:
	  /* RX error: eat character */
	   uartError(BSP_UART_COM2);
	  break;
	default:
	  /* Should not happen */
	  assert(0);
	  return;
	}
    }
}
Пример #25
0
void
main(int argc, char **argv)
{
	unsigned long countdown = 0;
	int wntDiskAdmin = 0;
	char char0 = 'a';
	char defltr = 0;
	char force = 0;

	char const *dev_name;
	int fd_dev;

	if (argc < 2) {
		usage();
		exit(1);
	}
	dev_name = argv[1];
	fd_dev = open(dev_name, 0);
	if (fd_dev < 0) {
		perror(dev_name);
		exit(1);
	}
	get_sector(fd_dev, &dev_mbr, 0);
	uread(0, &new_mbr, 5, ".bin hdr");  /* discard header */
	uread(0, &new_mbr, sizeof(new_mbr), "new mbr");  /* prototype mbr */
	chk_magic(&new_mbr, "new mbr");

	for (	(argv+=2), (argc-=2);
		argc > 0;
		(++argv), (--argc)
	) if ('-'==**argv) {
		char *value = strchr(*argv, '=');
		if (0!=value) {
			*value++ = 0;
		}
		if (0==strcmp("-wait", *argv)) {
			if (0!=value) {
				countdown = atoi(value);
				if (0 < countdown && countdown < 4000) {
					countdown *= 1000000;
				}
			}
		}
		else if (0==strcmp("-char0", *argv)) {
			if (0!=value) {
				char0 = *value;
			}
		}
		else if (0==strcmp("-default", *argv)) {
			if (0!=value) {
				defltr = *value;
			}
		}
		else if (0==strcmp("-force", *argv)) {
			if (0!=value) {
				force = *value;
			}
		}
		else if (0==strcmp("-WNTDiskAdmin", *argv)) {
			wntDiskAdmin = 6;
		}
		else {
			fprintf(stderr,"ignoring option %s\n", *argv);
		}
	}
	else {
		break;
	}

	/* Somebody please tell me how to read an .obj symbol table
	   so I can do these magic offsets symbolically!
	*/
#define COUNT  0x184
#define DEFLTR 0x172
#define DESLTR 0x038
#define NAMES  0x19a
	memcpy(&new_mbr.random[COUNT -4], &countdown, sizeof(countdown));
	memcpy(&new_mbr.random[DEFLTR -1], &defltr, sizeof(defltr));
	memcpy(&new_mbr.random[DESLTR -2], &char0, sizeof(char0));
	memcpy(&new_mbr.random[DESLTR -1], &force, sizeof(force));
	if (0==countdown) {/* wait forever: no count at all */
		new_mbr.random[COUNT -6] = 0xeb;  /* JMP rel8 */
		new_mbr.random[COUNT -5] = 0x0d;  /* skip to getcWait */
	}

    if (0 < argc) {
	char *labels = &new_mbr.random[NAMES];
	int avail = (0x200 - 2 - 4*16 - wntDiskAdmin) - NAMES;
		qsort(argv, argc, sizeof(*argv), (qsort_fn_t)strcmp);
	for (	;
		0!=argc;
		++argv, --argc
	) {
		int const len = 1+strlen(2+*argv);
		if ((avail -= len) < 0) {
			fprintf(stderr,"Use shorter labels; "
				"`%c=%s' won't fit.\n",
				**argv, 2+*argv);
		}
		else {
			strcpy(labels, 2+*argv);
			labels += len;
		}
		if (1 < argc  /* not last */
		&& (1 + *argv[0]) != *argv[1] ) {
			fprintf(stderr, "letters must be consecutive: %s %s\n",
				argv[0], argv[1] );
			exit(1);
		}
	}
	fprintf(stderr, "%d bytes available.\n", avail);
    }

    if (0!=wntDiskAdmin) {
	/* WindowsNT disk administrator uses these 6 bytes */
	memcpy(&new_mbr.random[446-6], &dev_mbr.random[446-6], 6);
    }

	memcpy(&new_mbr.part[0], &dev_mbr.part[0], 4*16);
	uwrite(1, &new_mbr, sizeof(new_mbr), "stdout");
	exit(0);
}
Пример #26
0
int main(int argc, char** argv) {
#if (defined WIN32 || defined _WIN32)
  WSADATA wsadata;
  int rc = WSAStartup(MAKEWORD(2,0), &wsadata); 
  if (rc) return 1;
#endif

  upoll_t* upq = upoll_create(32);
  intptr_t sd1 = usocket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  printf("server: %li\n", sd1);

  printf("bind: %d\n", ubind(sd1, "127.0.0.1", "1976"));
  printf("listen: %d\n", ulisten(sd1, 128));

  upoll_event_t ev1, ev2;
  upoll_event_t events[8];

  ev1.events = UPOLLIN;
  ev1.data.fd = sd1;

  upoll_ctl(upq, UPOLL_CTL_ADD, sd1, &ev1);

  int r = 0, x = 0;
  while (1) {
    int i, e;
    e = upoll_wait(upq, events, 8, -1);
    printf("events: %i\n", e);
    if (x++ == 50) return 0;
    for (i = 0; i < e; i++) {
      char buf[4096];
      if (events[i].events & UPOLLERR) {
        printf("ERROR on %li\n", events[i].data.fd);
        upoll_ctl(upq, UPOLL_CTL_DEL, events[i].data.fd, NULL);
        uclose(events[i].data.fd);
      }
      else if (events[i].events & UPOLLIN) {
        printf("have POLLIN on %li\n", events[i].data.fd);
        if (events[i].data.fd == sd1) {
          int sd2 = uaccept(sd1);
          printf("uaccept: %i\n", sd2);
          ev2.events = UPOLLIN;
          ev2.data.fd = sd2;
          upoll_ctl(upq, UPOLL_CTL_ADD, sd2, &ev2);
        }
        else {
          int cfd = events[i].data.fd;
          memset(buf, 0, 4096);
          printf("client input...\n");
          r = uread(cfd, buf, 4096);
          printf("read %i bytes\n", r);
          if (r == 0) {
            printf("EOF DETECTED\n");
            upoll_ctl(upq, UPOLL_CTL_DEL, events[i].data.fd, NULL);
            uclose(events[i].data.fd);
          }
          else {
            ev2.events = UPOLLOUT;
            upoll_ctl(upq, UPOLL_CTL_MOD, cfd, &ev2);
          }
        }
      }
      else if (events[i].events & UPOLLOUT) {
        printf("client writable...\n");
        int cfd = events[i].data.fd;
        int w = uwrite(cfd, buf, r);
        ev2.events = UPOLLIN;
        printf("wrote %i bytes, mod for UPOLLIN again\n", w);
        upoll_ctl(upq, UPOLL_CTL_MOD, cfd, &ev2);
      }
    }
  }

#if (defined WIN32 || defined _WIN32)
  WSACleanup();
#endif

  return 0;
}
Пример #27
0
static void LCD_WR_DATA_FOR_REG_INIT(RegParaPos pos)
{
	
	uwrite(InitData+InitDataPos[pos].offset,InitDataPos[pos].len);
}
Пример #28
0
static void
common_putc(int fd, int c)
{

	(void)uwrite(fd, &c, 1);
}
Пример #29
0
static int
zboot_exec(int fd, u_long *marks, int flags)
{
	char buf[512];
	char *p;
	int tofd;
	int sz;
	int i;

	/* XXX cheating here by assuming that Xboot() was called before. */

	tofd = uopen(_PATH_ZBOOT, O_WRONLY);
	if (tofd == -1) {
		printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno);
		return 1;
	}

	p = cmd.path;
	for (; *p != '\0'; p++)
		if (*p == ':') {
			strlcpy(buf, p+1, sizeof(buf));
			break;
		}
	if (*p == '\0')
		strlcpy(buf, cmd.path, sizeof(buf));

	p = buf;
	for (; *p == '/'; p++)
		;

	sz = strlen(p);
	if (uwrite(tofd, p, sz) != sz) {
		printf("zboot_exec: argument write error\n");
		goto err;
	}

	buf[0] = ' ';
	buf[1] = '-';
	if (uwrite(tofd, buf, 2) != 2) {
		printf("zboot_exec: argument write error\n");
		goto err;
	}

	i = (cmd.argc > 1 && cmd.argv[1][0] != '-') ? 2 : 1;
	for (; i < cmd.argc; i++) {
		p = cmd.argv[i];
		if (*p == '-')
			p++;
		sz = strlen(p);
		if (uwrite(tofd, p, sz) != sz) {
			printf("zboot_exec: argument write error\n");
			goto err;
		}
	}

	/* Select UART unit for serial console. */
	if (cn_tab && major(cn_tab->cn_dev) == 12) {
		buf[0] = '0' + minor(cn_tab->cn_dev);
		if (uwrite(tofd, buf, 1) != 1) {
			printf("zboot_exec: argument write error\n");
			goto err;
		}
	}

	/* Commit boot arguments. */
	uclose(tofd);

	tofd = uopen(_PATH_ZBOOT, O_WRONLY);
	if (tofd == -1) {
		printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno);
		return 1;
	}

	if (lseek(fd, 0, SEEK_SET) != 0) {
		printf("%s: seek error\n", _PATH_ZBOOT);
		goto err;
	}

	while ((sz = read(fd, buf, sizeof(buf))) == sizeof(buf)) {
		if ((sz = uwrite(tofd, buf, sz)) != sizeof(buf)) {
			printf("%s: write error\n", _PATH_ZBOOT);
			goto err;
		}
	}

	if (sz < 0) {
		printf("zboot_exec: read error\n");
		goto err;
	}

	if (sz >= 0 && uwrite(tofd, buf, sz) != sz) {
		printf("zboot_exec: write error\n");
		goto err;
	}

	uclose(tofd);
	return 0;

err:
	uclose(tofd);
	return 1;
}
Пример #30
0
int
fasttrap_pid_probe(struct reg *rp)
{
	proc_t *p = curproc;
	uintptr_t pc = rp->r_rip - 1;
	uintptr_t new_pc = 0;
	fasttrap_bucket_t *bucket;
#if defined(sun)
	kmutex_t *pid_mtx;
#endif
	fasttrap_tracepoint_t *tp, tp_local;
	pid_t pid;
	dtrace_icookie_t cookie;
	uint_t is_enabled = 0;

	/*
	 * It's possible that a user (in a veritable orgy of bad planning)
	 * could redirect this thread's flow of control before it reached the
	 * return probe fasttrap. In this case we need to kill the process
	 * since it's in a unrecoverable state.
	 */
	if (curthread->t_dtrace_step) {
		ASSERT(curthread->t_dtrace_on);
		fasttrap_sigtrap(p, curthread, pc);
		return (0);
	}

	/*
	 * Clear all user tracing flags.
	 */
	curthread->t_dtrace_ft = 0;
	curthread->t_dtrace_pc = 0;
	curthread->t_dtrace_npc = 0;
	curthread->t_dtrace_scrpc = 0;
	curthread->t_dtrace_astpc = 0;
#ifdef __amd64
	curthread->t_dtrace_regv = 0;
#endif

#if defined(sun)
	/*
	 * Treat a child created by a call to vfork(2) as if it were its
	 * parent. We know that there's only one thread of control in such a
	 * process: this one.
	 */
	while (p->p_flag & SVFORK) {
		p = p->p_parent;
	}
#endif

	PROC_LOCK(p);
	_PHOLD(p);
	pid = p->p_pid;
#if defined(sun)
	pid_mtx = &cpu_core[CPU->cpu_id].cpuc_pid_lock;
	mutex_enter(pid_mtx);
#endif
	bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)];

	/*
	 * Lookup the tracepoint that the process just hit.
	 */
	for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
		if (pid == tp->ftt_pid && pc == tp->ftt_pc &&
		    tp->ftt_proc->ftpc_acount != 0)
			break;
	}

	/*
	 * If we couldn't find a matching tracepoint, either a tracepoint has
	 * been inserted without using the pid<pid> ioctl interface (see
	 * fasttrap_ioctl), or somehow we have mislaid this tracepoint.
	 */
	if (tp == NULL) {
#if defined(sun)
		mutex_exit(pid_mtx);
#endif
		_PRELE(p);
		PROC_UNLOCK(p);
		return (-1);
	}

	/*
	 * Set the program counter to the address of the traced instruction
	 * so that it looks right in ustack() output.
	 */
	rp->r_rip = pc;

	if (tp->ftt_ids != NULL) {
		fasttrap_id_t *id;

#ifdef __amd64
		if (p->p_model == DATAMODEL_LP64) {
			for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
				fasttrap_probe_t *probe = id->fti_probe;

				if (id->fti_ptype == DTFTP_ENTRY) {
					/*
					 * We note that this was an entry
					 * probe to help ustack() find the
					 * first caller.
					 */
					cookie = dtrace_interrupt_disable();
					DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
					dtrace_probe(probe->ftp_id, rp->r_rdi,
					    rp->r_rsi, rp->r_rdx, rp->r_rcx,
					    rp->r_r8);
					DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
					dtrace_interrupt_enable(cookie);
				} else if (id->fti_ptype == DTFTP_IS_ENABLED) {
					/*
					 * Note that in this case, we don't
					 * call dtrace_probe() since it's only
					 * an artificial probe meant to change
					 * the flow of control so that it
					 * encounters the true probe.
					 */
					is_enabled = 1;
				} else if (probe->ftp_argmap == NULL) {
					dtrace_probe(probe->ftp_id, rp->r_rdi,
					    rp->r_rsi, rp->r_rdx, rp->r_rcx,
					    rp->r_r8);
				} else {
					uintptr_t t[5];

					fasttrap_usdt_args64(probe, rp,
					    sizeof (t) / sizeof (t[0]), t);

					dtrace_probe(probe->ftp_id, t[0], t[1],
					    t[2], t[3], t[4]);
				}
			}
		} else {
#else /* __amd64 */
			uintptr_t s0, s1, s2, s3, s4, s5;
			uint32_t *stack = (uint32_t *)rp->r_esp;

			/*
			 * In 32-bit mode, all arguments are passed on the
			 * stack. If this is a function entry probe, we need
			 * to skip the first entry on the stack as it
			 * represents the return address rather than a
			 * parameter to the function.
			 */
			s0 = fasttrap_fuword32_noerr(&stack[0]);
			s1 = fasttrap_fuword32_noerr(&stack[1]);
			s2 = fasttrap_fuword32_noerr(&stack[2]);
			s3 = fasttrap_fuword32_noerr(&stack[3]);
			s4 = fasttrap_fuword32_noerr(&stack[4]);
			s5 = fasttrap_fuword32_noerr(&stack[5]);

			for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
				fasttrap_probe_t *probe = id->fti_probe;

				if (id->fti_ptype == DTFTP_ENTRY) {
					/*
					 * We note that this was an entry
					 * probe to help ustack() find the
					 * first caller.
					 */
					cookie = dtrace_interrupt_disable();
					DTRACE_CPUFLAG_SET(CPU_DTRACE_ENTRY);
					dtrace_probe(probe->ftp_id, s1, s2,
					    s3, s4, s5);
					DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_ENTRY);
					dtrace_interrupt_enable(cookie);
				} else if (id->fti_ptype == DTFTP_IS_ENABLED) {
					/*
					 * Note that in this case, we don't
					 * call dtrace_probe() since it's only
					 * an artificial probe meant to change
					 * the flow of control so that it
					 * encounters the true probe.
					 */
					is_enabled = 1;
				} else if (probe->ftp_argmap == NULL) {
					dtrace_probe(probe->ftp_id, s0, s1,
					    s2, s3, s4);
				} else {
					uint32_t t[5];

					fasttrap_usdt_args32(probe, rp,
					    sizeof (t) / sizeof (t[0]), t);

					dtrace_probe(probe->ftp_id, t[0], t[1],
					    t[2], t[3], t[4]);
				}
			}
#endif /* __amd64 */
#ifdef __amd64
		}
#endif
	}

	/*
	 * We're about to do a bunch of work so we cache a local copy of
	 * the tracepoint to emulate the instruction, and then find the
	 * tracepoint again later if we need to light up any return probes.
	 */
	tp_local = *tp;
	PROC_UNLOCK(p);
#if defined(sun)
	mutex_exit(pid_mtx);
#endif
	tp = &tp_local;

	/*
	 * Set the program counter to appear as though the traced instruction
	 * had completely executed. This ensures that fasttrap_getreg() will
	 * report the expected value for REG_RIP.
	 */
	rp->r_rip = pc + tp->ftt_size;

	/*
	 * If there's an is-enabled probe connected to this tracepoint it
	 * means that there was a 'xorl %eax, %eax' or 'xorq %rax, %rax'
	 * instruction that was placed there by DTrace when the binary was
	 * linked. As this probe is, in fact, enabled, we need to stuff 1
	 * into %eax or %rax. Accordingly, we can bypass all the instruction
	 * emulation logic since we know the inevitable result. It's possible
	 * that a user could construct a scenario where the 'is-enabled'
	 * probe was on some other instruction, but that would be a rather
	 * exotic way to shoot oneself in the foot.
	 */
	if (is_enabled) {
		rp->r_rax = 1;
		new_pc = rp->r_rip;
		goto done;
	}

	/*
	 * We emulate certain types of instructions to ensure correctness
	 * (in the case of position dependent instructions) or optimize
	 * common cases. The rest we have the thread execute back in user-
	 * land.
	 */
	switch (tp->ftt_type) {
	case FASTTRAP_T_RET:
	case FASTTRAP_T_RET16:
	{
		uintptr_t dst = 0;
		uintptr_t addr = 0;
		int ret = 0;

		/*
		 * We have to emulate _every_ facet of the behavior of a ret
		 * instruction including what happens if the load from %esp
		 * fails; in that case, we send a SIGSEGV.
		 */
#ifdef __amd64
		if (p->p_model == DATAMODEL_NATIVE) {
			ret = dst = fasttrap_fulword((void *)rp->r_rsp);
			addr = rp->r_rsp + sizeof (uintptr_t);
		} else {
#endif
#ifdef __i386__
			uint32_t dst32;
			ret = dst32 = fasttrap_fuword32((void *)rp->r_esp);
			dst = dst32;
			addr = rp->r_esp + sizeof (uint32_t);
#endif
#ifdef __amd64
		}
#endif

		if (ret == -1) {
			fasttrap_sigsegv(p, curthread, rp->r_rsp);
			new_pc = pc;
			break;
		}

		if (tp->ftt_type == FASTTRAP_T_RET16)
			addr += tp->ftt_dest;

		rp->r_rsp = addr;
		new_pc = dst;
		break;
	}

	case FASTTRAP_T_JCC:
	{
		uint_t taken = 0;

		switch (tp->ftt_code) {
		case FASTTRAP_JO:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_OF) != 0;
			break;
		case FASTTRAP_JNO:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0;
			break;
		case FASTTRAP_JB:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) != 0;
			break;
		case FASTTRAP_JAE:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) == 0;
			break;
		case FASTTRAP_JE:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0;
			break;
		case FASTTRAP_JNE:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0;
			break;
		case FASTTRAP_JBE:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) != 0 ||
			    (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0;
			break;
		case FASTTRAP_JA:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_CF) == 0 &&
			    (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0;
			break;
		case FASTTRAP_JS:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_SF) != 0;
			break;
		case FASTTRAP_JNS:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0;
			break;
		case FASTTRAP_JP:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_PF) != 0;
			break;
		case FASTTRAP_JNP:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_PF) == 0;
			break;
		case FASTTRAP_JL:
			taken = ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) !=
			    ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
			break;
		case FASTTRAP_JGE:
			taken = ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) ==
			    ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
			break;
		case FASTTRAP_JLE:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0 ||
			    ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) !=
			    ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
			break;
		case FASTTRAP_JG:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0 &&
			    ((rp->r_rflags & FASTTRAP_EFLAGS_SF) == 0) ==
			    ((rp->r_rflags & FASTTRAP_EFLAGS_OF) == 0);
			break;

		}

		if (taken)
			new_pc = tp->ftt_dest;
		else
			new_pc = pc + tp->ftt_size;
		break;
	}

	case FASTTRAP_T_LOOP:
	{
		uint_t taken = 0;
#ifdef __amd64
		greg_t cx = rp->r_rcx--;
#else
		greg_t cx = rp->r_ecx--;
#endif

		switch (tp->ftt_code) {
		case FASTTRAP_LOOPNZ:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) == 0 &&
			    cx != 0;
			break;
		case FASTTRAP_LOOPZ:
			taken = (rp->r_rflags & FASTTRAP_EFLAGS_ZF) != 0 &&
			    cx != 0;
			break;
		case FASTTRAP_LOOP:
			taken = (cx != 0);
			break;
		}

		if (taken)
			new_pc = tp->ftt_dest;
		else
			new_pc = pc + tp->ftt_size;
		break;
	}

	case FASTTRAP_T_JCXZ:
	{
#ifdef __amd64
		greg_t cx = rp->r_rcx;
#else
		greg_t cx = rp->r_ecx;
#endif

		if (cx == 0)
			new_pc = tp->ftt_dest;
		else
			new_pc = pc + tp->ftt_size;
		break;
	}

	case FASTTRAP_T_PUSHL_EBP:
	{
		int ret = 0;
		uintptr_t addr = 0;

#ifdef __amd64
		if (p->p_model == DATAMODEL_NATIVE) {
			addr = rp->r_rsp - sizeof (uintptr_t);
			ret = fasttrap_sulword((void *)addr, &rp->r_rsp);
		} else {
#endif
#ifdef __i386__
			addr = rp->r_rsp - sizeof (uint32_t);
			ret = fasttrap_suword32((void *)addr, &rp->r_rsp);
#endif
#ifdef __amd64
		}
#endif

		if (ret == -1) {
			fasttrap_sigsegv(p, curthread, addr);
			new_pc = pc;
			break;
		}

		rp->r_rsp = addr;
		new_pc = pc + tp->ftt_size;
		break;
	}

	case FASTTRAP_T_NOP:
		new_pc = pc + tp->ftt_size;
		break;

	case FASTTRAP_T_JMP:
	case FASTTRAP_T_CALL:
		if (tp->ftt_code == 0) {
			new_pc = tp->ftt_dest;
		} else {
#ifdef __amd64
			uintptr_t value;
#endif
			uintptr_t addr = tp->ftt_dest;

			if (tp->ftt_base != FASTTRAP_NOREG)
				addr += fasttrap_getreg(rp, tp->ftt_base);
			if (tp->ftt_index != FASTTRAP_NOREG)
				addr += fasttrap_getreg(rp, tp->ftt_index) <<
				    tp->ftt_scale;

			if (tp->ftt_code == 1) {
				/*
				 * If there's a segment prefix for this
				 * instruction, we'll need to check permissions
				 * and bounds on the given selector, and adjust
				 * the address accordingly.
				 */
				if (tp->ftt_segment != FASTTRAP_SEG_NONE &&
				    fasttrap_do_seg(tp, rp, &addr) != 0) {
					fasttrap_sigsegv(p, curthread, addr);
					new_pc = pc;
					break;
				}

#ifdef __amd64
				if (p->p_model == DATAMODEL_NATIVE) {
					if ((value = fasttrap_fulword((void *)addr))
					     == -1) {
						fasttrap_sigsegv(p, curthread,
						    addr);
						new_pc = pc;
						break;
					}
					new_pc = value;
				} else {
#endif
#ifdef __i386__
					uint32_t value32;
					addr = (uintptr_t)(uint32_t)addr;
					if ((value32 = fasttrap_fuword32((void *)addr))
					    == -1) {
						fasttrap_sigsegv(p, curthread,
						    addr);
						new_pc = pc;
						break;
					}
					new_pc = value32;
#endif
				}
#ifdef __amd64
			} else {
				new_pc = addr;
			}
#endif
		}

		/*
		 * If this is a call instruction, we need to push the return
		 * address onto the stack. If this fails, we send the process
		 * a SIGSEGV and reset the pc to emulate what would happen if
		 * this instruction weren't traced.
		 */
		if (tp->ftt_type == FASTTRAP_T_CALL) {
			int ret = 0;
			uintptr_t addr = 0, pcps;
#ifdef __amd64
			if (p->p_model == DATAMODEL_NATIVE) {
				addr = rp->r_rsp - sizeof (uintptr_t);
				pcps = pc + tp->ftt_size;
				ret = fasttrap_sulword((void *)addr, &pcps);
			} else {
#endif
#ifdef __i386__
				addr = rp->r_rsp - sizeof (uint32_t);
				pcps = (uint32_t)(pc + tp->ftt_size);
				ret = fasttrap_suword32((void *)addr, &pcps);
#endif
#ifdef __amd64
			}
#endif

			if (ret == -1) {
				fasttrap_sigsegv(p, curthread, addr);
				new_pc = pc;
				break;
			}

			rp->r_rsp = addr;
		}

		break;

	case FASTTRAP_T_COMMON:
	{
		uintptr_t addr;
#if defined(__amd64)
		uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 22];
#else
		uint8_t scratch[2 * FASTTRAP_MAX_INSTR_SIZE + 7];
#endif
		uint_t i = 0;
#if defined(sun)
		klwp_t *lwp = ttolwp(curthread);
#endif

		/*
		 * Compute the address of the ulwp_t and step over the
		 * ul_self pointer. The method used to store the user-land
		 * thread pointer is very different on 32- and 64-bit
		 * kernels.
		 */
#if defined(sun)
#if defined(__amd64)
		if (p->p_model == DATAMODEL_LP64) {
			addr = lwp->lwp_pcb.pcb_fsbase;
			addr += sizeof (void *);
		} else {
			addr = lwp->lwp_pcb.pcb_gsbase;
			addr += sizeof (caddr32_t);
		}
#else
		addr = USD_GETBASE(&lwp->lwp_pcb.pcb_gsdesc);
		addr += sizeof (void *);
#endif
#endif /* sun */
#ifdef __i386__
		addr = USD_GETBASE(&curthread->td_pcb->pcb_gsd);
#else
		addr = curthread->td_pcb->pcb_gsbase;
#endif
		addr += sizeof (void *);

		/*
		 * Generic Instruction Tracing
		 * ---------------------------
		 *
		 * This is the layout of the scratch space in the user-land
		 * thread structure for our generated instructions.
		 *
		 *	32-bit mode			bytes
		 *	------------------------	-----
		 * a:	<original instruction>		<= 15
		 *	jmp	<pc + tp->ftt_size>	    5
		 * b:	<original instruction>		<= 15
		 *	int	T_DTRACE_RET		    2
		 *					-----
		 *					<= 37
		 *
		 *	64-bit mode			bytes
		 *	------------------------	-----
		 * a:	<original instruction>		<= 15
		 *	jmp	0(%rip)			    6
		 *	<pc + tp->ftt_size>		    8
		 * b:	<original instruction>		<= 15
		 * 	int	T_DTRACE_RET		    2
		 * 					-----
		 * 					<= 46
		 *
		 * The %pc is set to a, and curthread->t_dtrace_astpc is set
		 * to b. If we encounter a signal on the way out of the
		 * kernel, trap() will set %pc to curthread->t_dtrace_astpc
		 * so that we execute the original instruction and re-enter
		 * the kernel rather than redirecting to the next instruction.
		 *
		 * If there are return probes (so we know that we're going to
		 * need to reenter the kernel after executing the original
		 * instruction), the scratch space will just contain the
		 * original instruction followed by an interrupt -- the same
		 * data as at b.
		 *
		 * %rip-relative Addressing
		 * ------------------------
		 *
		 * There's a further complication in 64-bit mode due to %rip-
		 * relative addressing. While this is clearly a beneficial
		 * architectural decision for position independent code, it's
		 * hard not to see it as a personal attack against the pid
		 * provider since before there was a relatively small set of
		 * instructions to emulate; with %rip-relative addressing,
		 * almost every instruction can potentially depend on the
		 * address at which it's executed. Rather than emulating
		 * the broad spectrum of instructions that can now be
		 * position dependent, we emulate jumps and others as in
		 * 32-bit mode, and take a different tack for instructions
		 * using %rip-relative addressing.
		 *
		 * For every instruction that uses the ModRM byte, the
		 * in-kernel disassembler reports its location. We use the
		 * ModRM byte to identify that an instruction uses
		 * %rip-relative addressing and to see what other registers
		 * the instruction uses. To emulate those instructions,
		 * we modify the instruction to be %rax-relative rather than
		 * %rip-relative (or %rcx-relative if the instruction uses
		 * %rax; or %r8- or %r9-relative if the REX.B is present so
		 * we don't have to rewrite the REX prefix). We then load
		 * the value that %rip would have been into the scratch
		 * register and generate an instruction to reset the scratch
		 * register back to its original value. The instruction
		 * sequence looks like this:
		 *
		 *	64-mode %rip-relative		bytes
		 *	------------------------	-----
		 * a:	<modified instruction>		<= 15
		 *	movq	$<value>, %<scratch>	    6
		 *	jmp	0(%rip)			    6
		 *	<pc + tp->ftt_size>		    8
		 * b:	<modified instruction>  	<= 15
		 * 	int	T_DTRACE_RET		    2
		 * 					-----
		 *					   52
		 *
		 * We set curthread->t_dtrace_regv so that upon receiving
		 * a signal we can reset the value of the scratch register.
		 */

		ASSERT(tp->ftt_size < FASTTRAP_MAX_INSTR_SIZE);

		curthread->t_dtrace_scrpc = addr;
		bcopy(tp->ftt_instr, &scratch[i], tp->ftt_size);
		i += tp->ftt_size;

#ifdef __amd64
		if (tp->ftt_ripmode != 0) {
			greg_t *reg = NULL;

			ASSERT(p->p_model == DATAMODEL_LP64);
			ASSERT(tp->ftt_ripmode &
			    (FASTTRAP_RIP_1 | FASTTRAP_RIP_2));

			/*
			 * If this was a %rip-relative instruction, we change
			 * it to be either a %rax- or %rcx-relative
			 * instruction (depending on whether those registers
			 * are used as another operand; or %r8- or %r9-
			 * relative depending on the value of REX.B). We then
			 * set that register and generate a movq instruction
			 * to reset the value.
			 */
			if (tp->ftt_ripmode & FASTTRAP_RIP_X)
				scratch[i++] = FASTTRAP_REX(1, 0, 0, 1);
			else
				scratch[i++] = FASTTRAP_REX(1, 0, 0, 0);

			if (tp->ftt_ripmode & FASTTRAP_RIP_1)
				scratch[i++] = FASTTRAP_MOV_EAX;
			else
				scratch[i++] = FASTTRAP_MOV_ECX;

			switch (tp->ftt_ripmode) {
			case FASTTRAP_RIP_1:
				reg = &rp->r_rax;
				curthread->t_dtrace_reg = REG_RAX;
				break;
			case FASTTRAP_RIP_2:
				reg = &rp->r_rcx;
				curthread->t_dtrace_reg = REG_RCX;
				break;
			case FASTTRAP_RIP_1 | FASTTRAP_RIP_X:
				reg = &rp->r_r8;
				curthread->t_dtrace_reg = REG_R8;
				break;
			case FASTTRAP_RIP_2 | FASTTRAP_RIP_X:
				reg = &rp->r_r9;
				curthread->t_dtrace_reg = REG_R9;
				break;
			}

			/* LINTED - alignment */
			*(uint64_t *)&scratch[i] = *reg;
			curthread->t_dtrace_regv = *reg;
			*reg = pc + tp->ftt_size;
			i += sizeof (uint64_t);
		}
#endif

		/*
		 * Generate the branch instruction to what would have
		 * normally been the subsequent instruction. In 32-bit mode,
		 * this is just a relative branch; in 64-bit mode this is a
		 * %rip-relative branch that loads the 64-bit pc value
		 * immediately after the jmp instruction.
		 */
#ifdef __amd64
		if (p->p_model == DATAMODEL_LP64) {
			scratch[i++] = FASTTRAP_GROUP5_OP;
			scratch[i++] = FASTTRAP_MODRM(0, 4, 5);
			/* LINTED - alignment */
			*(uint32_t *)&scratch[i] = 0;
			i += sizeof (uint32_t);
			/* LINTED - alignment */
			*(uint64_t *)&scratch[i] = pc + tp->ftt_size;
			i += sizeof (uint64_t);
		} else {
#endif
#ifdef __i386__
			/*
			 * Set up the jmp to the next instruction; note that
			 * the size of the traced instruction cancels out.
			 */
			scratch[i++] = FASTTRAP_JMP32;
			/* LINTED - alignment */
			*(uint32_t *)&scratch[i] = pc - addr - 5;
			i += sizeof (uint32_t);
#endif
#ifdef __amd64
		}
#endif

		curthread->t_dtrace_astpc = addr + i;
		bcopy(tp->ftt_instr, &scratch[i], tp->ftt_size);
		i += tp->ftt_size;
		scratch[i++] = FASTTRAP_INT;
		scratch[i++] = T_DTRACE_RET;

		ASSERT(i <= sizeof (scratch));

#if defined(sun)
		if (fasttrap_copyout(scratch, (char *)addr, i)) {
#else
		if (uwrite(curproc, scratch, i, addr)) {
#endif
			fasttrap_sigtrap(p, curthread, pc);
			new_pc = pc;
			break;
		}
		if (tp->ftt_retids != NULL) {
			curthread->t_dtrace_step = 1;
			curthread->t_dtrace_ret = 1;
			new_pc = curthread->t_dtrace_astpc;
		} else {
			new_pc = curthread->t_dtrace_scrpc;
		}

		curthread->t_dtrace_pc = pc;
		curthread->t_dtrace_npc = pc + tp->ftt_size;
		curthread->t_dtrace_on = 1;
		break;
	}

	default:
		panic("fasttrap: mishandled an instruction");
	}

done:
	/*
	 * If there were no return probes when we first found the tracepoint,
	 * we should feel no obligation to honor any return probes that were
	 * subsequently enabled -- they'll just have to wait until the next
	 * time around.
	 */
	if (tp->ftt_retids != NULL) {
		/*
		 * We need to wait until the results of the instruction are
		 * apparent before invoking any return probes. If this
		 * instruction was emulated we can just call
		 * fasttrap_return_common(); if it needs to be executed, we
		 * need to wait until the user thread returns to the kernel.
		 */
		if (tp->ftt_type != FASTTRAP_T_COMMON) {
			/*
			 * Set the program counter to the address of the traced
			 * instruction so that it looks right in ustack()
			 * output. We had previously set it to the end of the
			 * instruction to simplify %rip-relative addressing.
			 */
			rp->r_rip = pc;

			fasttrap_return_common(rp, pc, pid, new_pc);
		} else {
			ASSERT(curthread->t_dtrace_ret != 0);
			ASSERT(curthread->t_dtrace_pc == pc);
			ASSERT(curthread->t_dtrace_scrpc != 0);
			ASSERT(new_pc == curthread->t_dtrace_astpc);
		}
	}

	rp->r_rip = new_pc;

	PROC_LOCK(p);
	proc_write_regs(curthread, rp);
	_PRELE(p);
	PROC_UNLOCK(p);

	return (0);
}

int
fasttrap_return_probe(struct reg *rp)
{
	proc_t *p = curproc;
	uintptr_t pc = curthread->t_dtrace_pc;
	uintptr_t npc = curthread->t_dtrace_npc;

	curthread->t_dtrace_pc = 0;
	curthread->t_dtrace_npc = 0;
	curthread->t_dtrace_scrpc = 0;
	curthread->t_dtrace_astpc = 0;

#if defined(sun)
	/*
	 * Treat a child created by a call to vfork(2) as if it were its
	 * parent. We know that there's only one thread of control in such a
	 * process: this one.
	 */
	while (p->p_flag & SVFORK) {
		p = p->p_parent;
	}
#endif

	/*
	 * We set rp->r_rip to the address of the traced instruction so
	 * that it appears to dtrace_probe() that we're on the original
	 * instruction, and so that the user can't easily detect our
	 * complex web of lies. dtrace_return_probe() (our caller)
	 * will correctly set %pc after we return.
	 */
	rp->r_rip = pc;

	fasttrap_return_common(rp, pc, p->p_pid, npc);

	return (0);
}