Пример #1
0
int main(int argc, char *argv[]) {
    int keepRunning = 1;
    int command;

    while (keepRunning == 1) {
        showRegisters();
        command = inputCommand();
        switch (command) {
        case 0:
            keepRunning--;
            break;
        case 1:
            assignment();
            break;
        case 2:
            addRegisters();
            break;
        case 3:
            subtractRegisters();
            break;
        }
    }

    return 0;
}
Пример #2
0
//================================================================================================
//
//   powerStateDidChangeTo
//
//================================================================================================
//
IOReturn
AppleUSBUHCI::powerStateDidChangeTo ( IOPMPowerFlags capabilities, unsigned long newState, IOService* whichDevice)
{
	USBTrace( kUSBTUHCI, KTPUHCIPowerState, (uintptr_t)this, newState, 0, 2);
	USBLog(5, "AppleUSBUHCI[%p]::powerStateDidChangeTo new state (%d)", this, (int)newState);
	showRegisters(7, "powerStateDidChangeTo");
	return super::powerStateDidChangeTo(capabilities, newState, whichDevice);
}
Пример #3
0
int main(void)
{
   unsigned long int registers[12];

   showRegisters(registers, 12);

    printf("\nsuma:%d\tresta:%d\tAND:%d\tOR:%d\tXOR:%d\n",suma(registers[1],registers[2]),resta(registers[1],registers[2]),ANDS(registers[1],registers[2]),ORES(registers[1],registers[2]),XOR(registers[1],registers[2]));
}
Пример #4
0
//================================================================================================
//
//   powerChangeDone
//
//================================================================================================
//
void
AppleUSBUHCI::powerChangeDone ( unsigned long fromState)
{
	unsigned long newState = getPowerState();
	
	USBTrace( kUSBTUHCI, KTPUHCIPowerState, (uintptr_t)this, fromState, newState, 3);
	USBLog((fromState == newState) || !_controllerAvailable ? 7 : 5, "AppleUSBUHCI[%p]::powerChangeDone from state (%d) to state (%d) _controllerAvailable(%s)", this, (int)fromState, (int)newState, _controllerAvailable ? "true" : "false");
	if (_controllerAvailable)
		showRegisters(7, "powerChangeDone");
	super::powerChangeDone(fromState);
}
Пример #5
0
//================================================================================================
//
//   DozeController
//
//================================================================================================
//
IOReturn
AppleUSBUHCI::DozeController(void)
{
    UInt16				cmd;
	int				i;
	bool			portsBeingResumed = false;

	USBTrace( kUSBTUHCI, KTPUHCIDozeController, (uintptr_t)this, 0, 0, 0);
	
	USBLog(6, "AppleUSBUHCI[%p]::DozeController", this);
	
    for (i=0; i<kUHCI_NUM_PORTS; i++) 
	{
		if (_rhPortBeingResumed[i])
		{
			USBLog(1, "AppleUSBUHCI[%p]::DozeController - port (%d) is being resumed. not stopping the controller", this, i+1);
			portsBeingResumed = true;
		}
	}
	
	if (!portsBeingResumed)
	{
		showRegisters(7, "+DozeController -  stopping controller");
		Run(false);
		
		// In order to get a Resume Detected interrupt, the controller needs to be in Global suspend mode, so we will do that even when "dozing".
		
		USBLog(6, "AppleUSBUHCI[%p]::DozeController  Globally suspending", this);
		// Put the controller in Global Suspend
		cmd = ioRead16(kUHCI_CMD) & ~kUHCI_CMD_FGR;
		cmd |= kUHCI_CMD_EGSM;
		ioWrite16(kUHCI_CMD, cmd);
		
		_myBusState = kUSBBusStateSuspended;
		
		IOSleep(3);
		
	}

	return kIOReturnSuccess;
}
Пример #6
0
static DebugWaitFor dbgShowRegisters(char *line, processPo p, termPo loc, insWord ins, void *cl) {
  showRegisters(p, p->heap, p->prog, p->pc, p->fp, p->sp);

  resetDeflt("n");
  return moreDebug;
}
Пример #7
0
int loadExtension(int pid, char *path, int isBeingDebugged)
{
    uintptr_t dlopen;
    uintptr_t str;
    int status;
    int pathlen=strlen(path)+1; //0-terminater

    printf("loadExtension(%d, %s, %d)\n", pid, path, isBeingDebugged);

    printf("Phase 0: Check if it's already open\n");
    if (isExtensionLoaded(pid))
    {
      printf("Already loaded\n");
      return TRUE;
    }
    else
      printf("Not yet loaded\n");



    printf("Phase 1: Find dlopen in target\n");

    dlopen=finddlopen(pid);
    printf("dlopen=%p\n", (void *)dlopen);

    if (!isBeingDebugged)
    {
      ptrace(PTRACE_ATTACH, pid, 0,0);

      pid=WaitForPid();
      printf("After wait. PID=%d\n", pid);
      ptrace(PTRACE_CONT,pid,0,0);
    }

    printf("Killing pid %d\n", pid);
    int e=kill(pid, SIGSTOP);

    printf("kill returned %d\n", e);
    printf("Waiting...\n");
    pid=WaitForPid();


    showRegisters(pid);



printf("After wait 2. PID=%d\n", pid);




    //save the current state and set the state to what I need it to be

#ifdef __arm__
  struct pt_regs origregs;
  struct pt_regs newregs;
#else
  struct user_regs_struct origregs;
  char bla[1024];


  struct user_regs_struct newregs;
  char bla2[1024];
#endif

      if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0)
      {
        printf("PTRACE_GETREGS FAILED\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }

      if (ptrace(PTRACE_GETREGS, pid, 0, &origregs)!=0)
      {
        printf("PTRACE_GETREGS FAILED 2\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }



      uintptr_t returnaddress=0x0ce0;


#ifdef __arm__
      //allocate space in the stack

      newregs.ARM_sp-=8+4*((pathlen+3)/ 4);

      //not sur eif [sp] is written to with a push or if it's [sp-4] and then sp decreased, so start at sp+4 instead
      str=newregs.ARM_sp+4;
      writeString(pid, str, path);




      newregs.ARM_lr=returnaddress;
      newregs.ARM_pc=dlopen;
      newregs.ARM_r0=str;
      newregs.ARM_r1=RTLD_NOW;

      if (newregs.ARM_pc & 1)
      {
         //THUMB Address link
         printf("THUMB destination\n");
         newregs.ARM_cpsr=newregs.ARM_cpsr | (1 << 5);

         //not sure how to set the J bit (thumbee uses it...)
         //for now disable it until a bug happens
         newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<25)); //unset J


      }
      else
      {
        printf("ARM destination\n");
        printf("newregs.ARM_cpsr was %x\n", newregs.ARM_cpsr);
        newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<5)); //unset T
        newregs.ARM_cpsr=newregs.ARM_cpsr & (~(1<<25)); //unset J
        printf("newregs.ARM_cpsr is %x\n", newregs.ARM_cpsr);
      }

      printf("r0=%lx\n", origregs.ARM_r0);
      printf("orig_r0=%lx\n", origregs.ARM_ORIG_r0);
      printf("pc=%lx\n", origregs.ARM_pc);
      printf("cpsr=%lx\n", origregs.ARM_cpsr);

#else
  #ifdef __x86_64__
      printf("rax=%lx\n", origregs.rax);
      printf("rbp=%lx\n", origregs.rbp);
      printf("rsp=%lx\n", origregs.rsp);
      printf("orig_rax=%lx\n", origregs.orig_rax);
      printf("rip=%lx\n", origregs.rip);



      //allocate stackspace
      newregs.rsp=newregs.rsp-0x28-(8*((pathlen+7) / 8));

      //check that the first 4 bits of rsp are 1000 (8) (aligned with the function return push)
      if ((newregs.rsp & 0xf)!=8)
      {
        printf("Aligning stack.  Was %llx", newregs.rsp);
        newregs.rsp-=8;
        newregs.rsp&=~(0xf); //clear the first 4 bits

        newregs.rsp=newregs.rsp | 8; //set to 8

        printf(" is now %llx\n", newregs.rsp);
      }
      //set the return address

      printf("Writing 0x0ce0 to %lx\n", newregs.rsp);
      if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp, returnaddress)!=0)
      {
        printf("Failed to write return address\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }

      if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp-8, returnaddress)!=0)
      {
        printf("F**k\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }

      if (ptrace(PTRACE_POKEDATA, pid, newregs.rsp+8, returnaddress)!=0)
      {
        printf("F**k\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }


     //write the path at rsp+10

     str=newregs.rsp+0x18;
     writeString(pid, str, path);

     printf("str=%p\n", (void *)str);



     returnaddress=ptrace(PTRACE_PEEKDATA, pid, newregs.rsp, 0);
     printf("[%lx]=%lx", newregs.rsp, returnaddress);


      newregs.rip=dlopen; //+2 //(test)
      newregs.rax=0;
      newregs.rdi=str;
      newregs.rsi=RTLD_NOW;
      newregs.orig_rax=0;
  #else
    printf("32-bit is not yet supported\n");
    printf("eax=%lx\n", origregs.eax);
    printf("ebp=%lx\n", origregs.ebp);
    printf("esp=%lx\n", origregs.esp);
    printf("orig_eax=%lx\n", origregs.orig_eax);
    printf("eip=%lx\n", origregs.eip);

    //allocate stackspace
    newregs.esp=newregs.esp-0x28-(8*((pathlen+7) / 8));
    if ((newregs.esp & 0xf)!=8)
    {
      printf("Aligning stack.  Was %llx", newregs.esp);
      newregs.esp-=8;
      newregs.esp&=~(0xf); //clear the first 4 bits

      newregs.esp=newregs.esp | 8; //set to 8

      printf(" is now %llx\n", newregs.esp);
    }

    //in 32-bit the stack will have to look like:
    //0-3: Return address  (0x0ce0)
    //4-7: Address to path
    //8-11:RTLD_NOW
    //12-...: Path

    //


    if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+0, returnaddress)!=0)
    {
      printf("F**k\n");
      ptrace(PTRACE_DETACH, pid,0,0);

      return FALSE;
    }

    if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+4, newregs.esp+12)!=0)
    {
      printf("Fuck2\n");
      ptrace(PTRACE_DETACH, pid,0,0);

      return FALSE;
    }

    if (ptrace(PTRACE_POKEDATA, pid, newregs.esp+8, RTLD_NOW)!=0)
    {
      printf("Fuck3\n");
      ptrace(PTRACE_DETACH, pid,0,0);

      return FALSE;
    }

    writeString(pid, newregs.esp+12, path);

    newregs.eip=dlopen;
    newregs.orig_eax=0;

  #endif //__x86_64


#endif

      if (ptrace(PTRACE_SETREGS, pid, 0, &newregs)!=0)
      {
        printf("PTRACE_SETREGS FAILED\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }

      if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0)
      {
        printf("PTRACE_GETREGS FAILED 4\n");
        ptrace(PTRACE_DETACH, pid,0,0);

        return FALSE;
      }

     printf("after setregs:\n");

#ifdef __arm__
     printf("r0=%lx\n", newregs.ARM_r0);
     printf("orig_r0=%lx\n", newregs.ARM_ORIG_r0);
     printf("pc=%lx\n", newregs.ARM_pc);
     printf("cpsr=%lx\n", newregs.ARM_cpsr);
#else
  #ifdef __x86_64__
     printf("rax=%lx\n", newregs.rax);
     printf("rdi=%lx\n", newregs.rdi);
     printf("rsi=%lx\n", newregs.rsi);
     printf("rbp=%lx\n", newregs.rbp);
     printf("rsp=%lx\n", newregs.rsp);
     printf("orig_rax=%lx\n", newregs.orig_rax);
     printf("rip=%lx\n", newregs.rip);
  #else
     printf("eax=%lx\n", newregs.eax);
     printf("edi=%lx\n", newregs.edi);
     printf("esi=%lx\n", newregs.esi);
     printf("ebp=%lx\n", newregs.ebp);
     printf("esp=%lx\n", newregs.esp);
     printf("orig_eax=%lx\n", newregs.orig_eax);
     printf("eip=%lx\n", newregs.eip);
  #endif //__x86_64__
#endif

    printf("\n\nContinuing thread\n");


    int ptr;
    ptr=ptrace(PTRACE_CONT,pid,(void *)0,(void *)SIGCONT);

    printf("PRACE_CONT=%d\n", ptr);
    if (ptr!=0)
      {
        printf("PTRACE_CONT FAILED\n");
        return 1;
      }

      //wait for this thread to crash

      pid=-1;
      while (pid==-1)
      {
        pid=waitpid(-1, &status,  WUNTRACED| __WALL);

        if ((pid==-1) && (errno!=EINTR))
        {
          printf("LoadExtension wait fail. :%d\n", errno);

          return FALSE;
        }

        if (pid==0)
          pid=-1;
        printf(".");
      }

     printf("after wait: pid=%d (status=%x)\n", pid, status);

     siginfo_t si;
     if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)!=0)
     {
       printf("GETSIGINFO FAILED\n");
       ptrace(PTRACE_DETACH, pid,0,0);

       return FALSE;
     }

     printf("si.si_signo=%d\n", si.si_signo);



     if (ptrace(PTRACE_GETREGS, pid, 0, &newregs)!=0)
     {
       printf("PTRACE_GETREGS FAILED (2)\n");
       ptrace(PTRACE_DETACH, pid,0,0);

       return FALSE;
     }

#ifdef __arm__
    printf("r0=%lx\n", newregs.ARM_r0);
    printf("orig_r0=%lx\n", newregs.ARM_ORIG_r0);
    printf("pc=%lx\n", newregs.ARM_pc);
    printf("sp=%lx\n", newregs.ARM_sp);
    printf("cpsr=%lx\n", newregs.ARM_cpsr);
#else
  #ifdef __x86_64__
     printf("rax=%lx\n", newregs.rax);
     printf("rdi=%lx\n", newregs.rdi);
     printf("rsi=%lx\n", newregs.rsi);
     printf("rbp=%lx\n", newregs.rbp);
     printf("rsp=%lx\n", newregs.rsp);
     printf("orig_rax=%lx\n", newregs.rax);
     printf("rip=%lx\n", newregs.rip);
  #else
     printf("eax=%lx\n", newregs.eax);
     printf("edi=%lx\n", newregs.edi);
     printf("esi=%lx\n", newregs.esi);
     printf("ebp=%lx\n", newregs.ebp);
     printf("esp=%lx\n", newregs.esp);
     printf("orig_eax=%lx\n", newregs.eax);
     printf("eip=%lx\n", newregs.eip);
  #endif

#endif

     if (ptrace(PTRACE_SETREGS, pid, 0, &origregs)!=0)
     {
       printf("PTRACE_SETREGS FAILED (20\n");
     }

     if (!isBeingDebugged)
     {
       printf("Detaching\n");
       if (ptrace(PTRACE_DETACH, pid,0,0)!=0)
         printf("PTRACE_DETACH FAILED\n");
     }
     else
     {
       if (ptrace(PTRACE_CONT,pid,(void *)0,(void *)SIGCONT)!=0)
         printf("PTRACE_CONT failed\n");
     }


     printf("End...\n");
}
Пример #8
0
//================================================================================================
//
//   WakeControllerFromDoze
//
//================================================================================================
//
IOReturn				
AppleUSBUHCI::WakeControllerFromDoze(void)
{
    UInt16				cmd;
	int					i;
	bool				portHasRD[kUHCI_NUM_PORTS];
    UInt16				status;

	USBTrace( kUSBTUHCI, KTPUHCIWakeFromDoze, (uintptr_t)this, 0, 0, 0);
	// First, see if we have any ports that have the RD bit set.  If they do, then we can go ahead and clear it after we waited the 20ms for the
	// Global resume
	for (i=0; i<kUHCI_NUM_PORTS; i++) 
	{
		status = ReadPortStatus(i);
		if (status & kUHCI_PORTSC_RD) 
		{
			USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller port %d has kUHCI_PORTSC_RD set", this, i+1);
			portHasRD[i] = true;
		}
		else
		{
			portHasRD[i] = false;
		}
    }
	
	// If we are in Global Suspend mode, we need to resume the controller.   We will wait 20ms with the gate held.  However, since we only
	// get into this mode if all devices are suspended, then delaying while holding the wl will not prevent any completions from happening, since
	// there aren't any.
	cmd = ioRead16(kUHCI_CMD);

	if (cmd & kUHCI_CMD_EGSM)
	{
		USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze controller is globally suspended - forcing resume", this);
		cmd |= kUHCI_CMD_FGR;
		ioWrite16(kUHCI_CMD, cmd);
		cmd = ioRead16(kUHCI_CMD);
		USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze after EGSM->FGR, cmd is[%p], sleeping 20ms", this, (void*)cmd);
		IOSleep(20);
		cmd &= ~kUHCI_CMD_FGR;
		cmd &= ~kUHCI_CMD_EGSM;
		ioWrite16(kUHCI_CMD, cmd);
		
		// Clear any RD bits in the port if they were set, now that we have waited 20ms
		for (i=0; i<kUHCI_NUM_PORTS; i++) 
		{
			if (portHasRD[i] )
			{
				status = ReadPortStatus(i) & kUHCI_PORTSC_MASK;
				status &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND);
				USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze  de-asserting resume signal for port %d by writing (%p)", this, i+1, (void*)status);
				WritePortStatus(i, status);
				IOSync();
				IOSleep(2);																	// allow it to kick in
			}
		}
	}

	USBLog(6, "AppleUSBUHCI[%p]::WakeControllerFromDoze calling Run(true)", this);
	Run(true);
	_myBusState = kUSBBusStateRunning;
	showRegisters(7, "-WakeControllerFromDoze");
	return kIOReturnSuccess;
}
Пример #9
0
//================================================================================================
//
//   ResumeController
//
//================================================================================================
//
void			
AppleUSBUHCI::ResumeController(void)
{
    UInt16			cmd;
	int				i;
    
	USBTrace( kUSBTUHCI, KTPUHCIResumeController , (uintptr_t)this, 0, 0, 0);
	showRegisters(7, "+ResumeController");
	
	cmd = ioRead16(kUHCI_CMD);
	if (cmd & kUHCI_CMD_RS)
	{
		USBLog(3, "AppleUSBUHCI[%p]::ResumeController - already running - returning", this);
		return;
	}
	
	// I need to save the existing frame list before I turn on processing so I can send SOF only for 10ms after we turn the controller on
	for (i=0;i < kUHCI_NVFRAMES; i++)
	{
		_frameList[i] |= HostToUSBLong(kUHCI_FRAME_T);
	}
			
	if (cmd & kUHCI_CMD_EGSM)
	{
		USBLog(5, "AppleUSBUHCI[%p]::ResumeController controller is globally suspended - forcing resume", this);
		cmd |= kUHCI_CMD_FGR;
		ioWrite16(kUHCI_CMD, cmd);
		cmd = ioRead16(kUHCI_CMD);
		USBLog(5, "AppleUSBUHCI[%p]::ResumeController after EGSM->FGR, cmd is[%p]", this, (void*)cmd);
	}
    
	if (cmd & kUHCI_CMD_FGR)
	{
		// this could either be because the remote wwakeup caused this state or because we did above
		// need to wait 20ms
		IOSleep(20);
		cmd &= ~kUHCI_CMD_FGR;
		cmd &= ~kUHCI_CMD_EGSM;
		ioWrite16(kUHCI_CMD, cmd);
	}
	if ((cmd & (kUHCI_CMD_MAXP | kUHCI_CMD_CF)) != (kUHCI_CMD_MAXP | kUHCI_CMD_CF))
	{
		USBLog(5, "AppleUSBUHCI[%p]::ResumeController marking MAXP and CF", this);
		cmd |= (kUHCI_CMD_MAXP | kUHCI_CMD_CF);
		ioWrite16(kUHCI_CMD, cmd);
	}
	
	// restore the frame list register
    if (_framesPaddr != NULL) 
	{
		USBLog(5, "AppleUSBUHCI[%p]::ResumeController setting FRBASEADDR[%p]", this, (void*)_framesPaddr);
        ioWrite32(kUHCI_FRBASEADDR, _framesPaddr);
	}
	
	USBLog(5, "AppleUSBUHCI[%p]::ResumeController starting controller", this);
	Run(true);
	
	// wait 10 ms for the device to recover
	IOSleep(10);
	
	// restore the list
	for (i=0;i < kUHCI_NVFRAMES; i++)
	{
		_frameList[i] &= ~HostToUSBLong(kUHCI_FRAME_T);
	}
    
	USBLog(7, "AppleUSBUHCI[%p]::ResumeController resume done, cmd %x, status %x ports[%p, %p]", this, ioRead16(kUHCI_CMD), ioRead16(kUHCI_STS),(void*)ReadPortStatus(0), (void*)ReadPortStatus(1));
	showRegisters(7, "-ResumeController");
}
Пример #10
0
/**
	Main menu
**/
void menu() {

	int instrReturn;
	char choice;
	int bytesRead;
	unsigned offset, length;

	// initialize memory, declared in myMenu.h
	char memory[MEMSIZE];

	// initialize registers and reset, declared in myMenu.h
	struct Registers myRegisters;
	reset(&myRegisters);

	while (1) {

		// display menu
		fprintf(stdout, "\n\n---------------------------------------------------");
		fprintf(stdout, "\nSheranga Balasuriya: Welcome to my Virtual CPU\nPlease select one of the following");
		fprintf(stdout, "\nd\tdump memory");
		fprintf(stdout, "\ng\tgo");
		fprintf(stdout, "\nl\tload a file into memory");
		fprintf(stdout, "\nm\tmemory modify");
		fprintf(stdout, "\nq\tquit");
		fprintf(stdout, "\nr\tdisplay registers");
		fprintf(stdout, "\nt\ttrace");
		fprintf(stdout, "\nw\twrite file");
		fprintf(stdout, "\nz\treset registers");
		fprintf(stdout, "\nb\tenable/disable debugging");
		fprintf(stdout, "\n? , h\tdisplay help\n");
		fscanf(stdin, " %1c", &choice);
		flush();

		// check choice taken
		switch (choice) {
		case 'd':
		case 'D':
			// get offset from user
			fprintf(stdout, "\nPleae enter the offset in hex: ");
			fscanf(stdin, "%x", &offset);
			flush();

			// get length from user
			fprintf(stdout, "\nPlease enter the length in hex: ");
			fscanf(stdin, "%x", &length);
			flush();

			memDump(memory, offset, length);
			break;
		case 'g':
		case 'G':
			go(&myRegisters,memory);
			break;
		case 'l':
		case 'L':
			bytesRead = loadFile(memory, MEMSIZE);
			if (bytesRead > 0)
				fprintf(stdout, "\n%d(0x%X) bytes read into memory", bytesRead, bytesRead);
			break;
		case 'm':
		case 'M':
			modify(memory);
			break;
		case 'q':
		case 'Q':
			return;
			break;
		case 'r':
		case 'R':
			showRegisters(&myRegisters);
			break;
		case 't':
		case 'T':
			instrReturn = instructionCycle(&myRegisters, memory);
			showRegisters(&myRegisters);
			break;
		case 'w':
		case 'W':
			writeFile(memory);
			break;
		case 'z':
		case 'Z':
			reset(&myRegisters);
			break;
		case 'b':
		case 'B':
			debug(&myRegisters);
			break;
		case '?':
		case 'h':
		case 'H':
			help();
			break;
		default:
			fprintf(stdout, "\nIncorrect entry, try again");
		}
	}
}
Пример #11
0
IOReturn
AppleUSBUHCI::RHSuspendPort(int port, bool suspended)
{
    UInt16 cmd, value;
    
    USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) _rhPortBeingResumed[%d](%s)", this, port, suspended ? "SUSPEND" : "RESUME", (int)port-1, _rhPortBeingResumed[port-1] ? "true" : "false");
	showRegisters(7, "RHSuspendPort");
    port--; // convert 1-based to 0-based.

	if (_rhPortBeingResumed[port])
	{
		if (!suspended)
		{
			USBLog(3, "AppleUSBUHCI[%p]::RHSuspendPort - resume on port (%d) already being resumed - gracefully ignoring", this, (int)port+1);
			return kIOReturnSuccess;
		}
		USBLog(1, "AppleUSBUHCI[%p]::RHSuspendPort - trying to suspend port (%d) which is being resumed - UNEXPECTED", this, (int)port+1);
		USBTrace( kUSBTUHCI, kTPUHCIRHSuspendPort, (uintptr_t)this, (int)port+1, 0, 0);
	}
	
    cmd = ioRead16(kUHCI_CMD);
    value = ReadPortStatus(port) & kUHCI_PORTSC_MASK;
    
    if (suspended) 
	{
        value |= kUHCI_PORTSC_SUSPEND;
        value &= ~kUHCI_PORTSC_RD;
    } else 
	{
        if (cmd & kUHCI_CMD_EGSM) 
		{
            /* Can't un-suspend a port during global suspend. */
            USBError(1, "AppleUSBUHCI[%p]: attempt to resume during global suspend", this);
            return kIOReturnError;
        }
        value |= (kUHCI_PORTSC_SUSPEND | kUHCI_PORTSC_RD);
    }
    // Always enable the port also.
    value |= kUHCI_PORTSC_PED;

    USBLog(5, "AppleUSBUHCI[%p]: writing (%p) to port control", this, (void*)value);
    
    WritePortStatus(port, value);
    
    if (suspended) 
	{
        /* Suspending.
         * Sleep for 3ms to ensure nothing goes out on the bus
         * until devices are suspended.
         */
        IOSleep(3);
        
    } else 
	{
        // Resuming
		USBLog(5,"AppleUSBUHCI[%p]::RHSuspendPort - resuming port %d, calling out to timer", this, (int)port+1);
		_rhPortBeingResumed[port] = true;
		thread_call_enter1(_rhResumePortTimerThread[port], (void*)(port+1));
    }

    USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) calling UIMRootHubStatusChange", this, port+1, suspended ? "SUSPEND" : "RESUME");

    UIMRootHubStatusChange();        
    
    USBLog(5, "AppleUSBUHCI[%p]::RHSuspendPort %d (%s) DONE", this, port+1, suspended ? "SUSPEND" : "RESUME");

    return kIOReturnSuccess;
}