Ejemplo n.º 1
0
Archivo: pci.c Proyecto: google/rekall
u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) {
  u32 v;
  __outdword(PCI_CONFIG_ADDRESS,
	     0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset);
  v = __indword(PCI_CONFIG_DATA);
  return v;
}
Ejemplo n.º 2
0
// Perform IO instruction according with parameters
_Use_decl_annotations_ static void VmmpIoWrapper(bool to_memory, bool is_string,
                                                 SIZE_T size_of_access,
                                                 unsigned short port,
                                                 void *address,
                                                 unsigned long count) {
  NT_ASSERT(size_of_access == 1 || size_of_access == 2 || size_of_access == 4);

  // Update CR3 with that of the guest since below code is going to access
  // memory.
  const auto guest_cr3 = UtilVmRead(VmcsField::kGuestCr3);
  const auto vmm_cr3 = __readcr3();
  __writecr3(guest_cr3);

  // clang-format off
  if (to_memory) {
    if (is_string) {
      // IN
      switch (size_of_access) {
      case 1: *reinterpret_cast<UCHAR*>(address) = __inbyte(port); break;
      case 2: *reinterpret_cast<USHORT*>(address) = __inword(port); break;
      case 4: *reinterpret_cast<ULONG*>(address) = __indword(port); break;
      }
    } else {
      // INS
      switch (size_of_access) {
      case 1: __inbytestring(port, reinterpret_cast<UCHAR*>(address), count); break;
      case 2: __inwordstring(port, reinterpret_cast<USHORT*>(address), count); break;
      case 4: __indwordstring(port, reinterpret_cast<ULONG*>(address), count); break;
      }
    }
  } else {
    if (is_string) {
      // OUT
      switch (size_of_access) {
      case 1: __outbyte(port, *reinterpret_cast<UCHAR*>(address)); break;
      case 2: __outword(port, *reinterpret_cast<USHORT*>(address)); break;
      case 4: __outdword(port, *reinterpret_cast<ULONG*>(address)); break;
      }
    } else {
      // OUTS
      switch (size_of_access) {
      case 1: __outbytestring(port, reinterpret_cast<UCHAR*>(address), count); break;
      case 2: __outwordstring(port, reinterpret_cast<USHORT*>(address), count); break;
      case 4: __outdwordstring(port, reinterpret_cast<ULONG*>(address), count); break;
      }
    }
  }
  // clang-format on

  __writecr3(vmm_cr3);
}
Ejemplo n.º 3
0
NTSTATUS __fastcall DispatchIOCTL(IN PIOCTL_INFO RequestInfo, OUT PULONG ResponseLength) {
	NTSTATUS Status = STATUS_SUCCESS;

#define INPUT(Type)  ((Type)(RequestInfo->InputBuffer)) 
#define OUTPUT(Type) ((Type)(RequestInfo->OutputBuffer))
#define SET_RESPONSE_LENGTH(Length) if (ResponseLength != NULL) {*ResponseLength = (Length);}

	switch (RequestInfo->ControlCode) {
	
// DriverFunctions:

	case GET_HANDLES_COUNT:
		*OUTPUT(PULONG) = GetHandlesCount();
		SET_RESPONSE_LENGTH(sizeof(ULONG));
		break;

// NativeFunctions:

	case START_BEEPER:
		__outbyte(0x61, __inbyte(0x61) | 3); 
		break;
	
	case STOP_BEEPER: 
		__outbyte(0x61, __inbyte(0x61) & 252);
		break;
	
	case SET_BEEPER_REGIME: 
		__outbyte(0x43, 0xB6);
		break;
	
	case SET_BEEPER_OUT: 
		__outbyte(0x61, __inbyte(0x61) | 2);
		break;
	
	case SET_BEEPER_IN: 
		__outbyte(0x61, __inbyte(0x61) & 253);
		break;

	case SET_BEEPER_DIVIDER:
		SetBeeperDivider(*INPUT(PWORD));
		break;

	case SET_BEEPER_FREQUENCY:
		SetBeeperFrequency(*INPUT(PWORD));
		break;

	case READ_IO_PORT_BYTE:
		*OUTPUT(PBYTE) = __inbyte(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(BYTE));
		break;

	case READ_IO_PORT_WORD:
		*OUTPUT(PWORD) = __inword(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(WORD));
		break;

	case READ_IO_PORT_DWORD:
		*OUTPUT(PDWORD32) = __indword(*INPUT(PWORD));
		SET_RESPONSE_LENGTH(sizeof(DWORD));
		break;

	case WRITE_IO_PORT_BYTE:
		__outbyte(
			INPUT(PWRITE_IO_PORT_BYTE_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_BYTE_INPUT)->Data
		);
		break;

	case WRITE_IO_PORT_WORD:
		__outword(
			INPUT(PWRITE_IO_PORT_WORD_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_WORD_INPUT)->Data
		);
		break;

	case WRITE_IO_PORT_DWORD:
		__outdword(
			INPUT(PWRITE_IO_PORT_DWORD_INPUT)->PortNumber,
			INPUT(PWRITE_IO_PORT_DWORD_INPUT)->Data
		);
		break;

	case RDPMC:
		*OUTPUT(PULONGLONG) = __readpmc(*INPUT(PULONG));
		SET_RESPONSE_LENGTH(sizeof(ULONGLONG));
		break;

	case RDMSR:
		*OUTPUT(PULONGLONG) = __readmsr(*INPUT(PULONG));
		SET_RESPONSE_LENGTH(sizeof(ULONGLONG));
		break;

	case WRMSR:
		__writemsr(INPUT(PWRMSR_INPUT)->Index, INPUT(PWRMSR_INPUT)->Data);
		break;

// MemoryUtils:

	case ALLOC_KERNEL_MEMORY:
		*OUTPUT(PUINT64) = (SIZE_T)GetMem(*INPUT(PSIZE_T));
		SET_RESPONSE_LENGTH(sizeof(UINT64));
		break;

	case FREE_KERNEL_MEMORY:
		FreeMem((PVOID)*INPUT(PUINT64));
		break;

	case COPY_MEMORY:
		RtlCopyMemory(
			(PVOID)INPUT(PCOPY_MEMORY_INPUT)->Destination,
			(PVOID)INPUT(PCOPY_MEMORY_INPUT)->Source,
			(SIZE_T)INPUT(PCOPY_MEMORY_INPUT)->Size
		);
		break;

	case FILL_MEMORY:
		RtlFillMemory(
			(PVOID)INPUT(PFILL_MEMORY_INPUT)->Destination,
			(SIZE_T)INPUT(PFILL_MEMORY_INPUT)->Size,
			(BYTE)INPUT(PFILL_MEMORY_INPUT)->FillingByte
		);
		break;

	case ALLOC_PHYSICAL_MEMORY:
		*OUTPUT(PUINT64) = (SIZE_T)AllocPhysicalMemory(
			INPUT(PALLOC_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(SIZE_T)INPUT(PALLOC_PHYSICAL_MEMORY_INPUT)->Size
		);
		SET_RESPONSE_LENGTH(sizeof(UINT64));
		break;

	case FREE_PHYSICAL_MEMORY:
		FreePhysicalMemory((PVOID)*INPUT(PUINT64));
		break;

	case GET_PHYSICAL_ADDRESS:
		*OUTPUT(PPHYSICAL_ADDRESS) = GetPhysicalAddressInProcess(
			(HANDLE)INPUT(PGET_PHYSICAL_ADDRESS_INPUT)->ProcessID,
			(PVOID)INPUT(PGET_PHYSICAL_ADDRESS_INPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(PHYSICAL_ADDRESS));
		break;

	case READ_PHYSICAL_MEMORY:
		*OUTPUT(PBOOL) = ReadPhysicalMemory(
			INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(PVOID)INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->Buffer,
			INPUT(PREAD_PHYSICAL_MEMORY_INPUT)->BufferSize
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case WRITE_PHYSICAL_MEMORY:
		*OUTPUT(PBOOL) = WritePhysicalMemory(
			INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->PhysicalAddress,
			(PVOID)INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->Buffer,
			INPUT(PWRITE_PHYSICAL_MEMORY_INPUT)->BufferSize
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case READ_DMI_MEMORY:
		ReadDmiMemory((PVOID)*INPUT(PUINT64), DMI_SIZE);
		SET_RESPONSE_LENGTH(DMI_SIZE);
		break;

// ShellCode:

	case EXECUTE_SHELL_CODE:
		*OUTPUT(PSHELL_STATUS) = ExecuteShell(
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->EntryPoint,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->CodeBlock,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->InputData,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->OutputData,
			(PVOID)INPUT(PEXECUTE_SHELL_CODE_INPUT)->Result
		);
		SET_RESPONSE_LENGTH(sizeof(SHELL_STATUS));
		break;

// ProcessesUtils:

	case ALLOC_VIRTUAL_MEMORY:
		OUTPUT(PALLOC_VIRTUAL_MEMORY_OUTPUT)->Status = VirtualAllocInProcess(
			(HANDLE)INPUT(PALLOC_VIRTUAL_MEMORY_INPUT)->ProcessId,
			(SIZE_T)INPUT(PALLOC_VIRTUAL_MEMORY_INPUT)->Size,
			(PVOID*)&OUTPUT(PALLOC_VIRTUAL_MEMORY_OUTPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(ALLOC_VIRTUAL_MEMORY_OUTPUT));
		break;

	case FREE_VIRTUAL_MEMORY:
		*OUTPUT(PNTSTATUS) = VirtualFreeInProcess(
			(HANDLE)INPUT(PFREE_VIRTUAL_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PFREE_VIRTUAL_MEMORY_INPUT)->VirtualAddress
		);
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
		break;

	case MAP_VIRTUAL_MEMORY:
		OUTPUT(PMAP_VIRTUAL_MEMORY_OUTPUT)->MappedMemory = MapVirtualMemory(
			(HANDLE)INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->ProcessId,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->VirtualAddress,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->MapToVirtualAddress,
			INPUT(PMAP_VIRTUAL_MEMORY_INPUT)->Size,
			UserMode,
			(PMDL*)&(OUTPUT(PMAP_VIRTUAL_MEMORY_OUTPUT)->Mdl)
		);
		SET_RESPONSE_LENGTH(sizeof(MAP_VIRTUAL_MEMORY_OUTPUT));
		break;

	case UNMAP_VIRTUAL_MEMORY:
		UnmapVirtualMemory(
			INPUT(PUNMAP_VIRTUAL_MEMORY_INPUT)->Mdl,
			INPUT(PUNMAP_VIRTUAL_MEMORY_INPUT)->MappedMemory
		);
		break;

	case READ_PROCESS_MEMORY:
		*OUTPUT(PBOOL) = ReadProcessMemory(
			(HANDLE)INPUT(PREAD_PROCESS_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PREAD_PROCESS_MEMORY_INPUT)->VirtualAddress,
			(PVOID)INPUT(PREAD_PROCESS_MEMORY_INPUT)->Buffer,
			INPUT(PREAD_PROCESS_MEMORY_INPUT)->BytesToRead,
			TRUE,
			(MEMORY_ACCESS_TYPE)INPUT(PREAD_PROCESS_MEMORY_INPUT)->AccessType
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case WRITE_PROCESS_MEMORY:
		*OUTPUT(PBOOL) = WriteProcessMemory(
			(HANDLE)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->ProcessId,
			(PVOID)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->VirtualAddress,
			(PVOID)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->Buffer,
			INPUT(PWRITE_PROCESS_MEMORY_INPUT)->BytesToWrite,
			TRUE,
			(MEMORY_ACCESS_TYPE)INPUT(PWRITE_PROCESS_MEMORY_INPUT)->AccessType
		);
		SET_RESPONSE_LENGTH(sizeof(BOOL));
		break;

	case RAISE_IOPL_BY_TF:
#ifdef _AMD64_
		RaiseIOPLByTrapFrame();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPL_BY_TF:
#ifdef _AMD64_
		ResetIOPLByTrapFrame();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RAISE_IOPL_BY_TF_SCAN:
		RaiseIOPLByTrapFrameScan();
		break;

	case RESET_IOPL_BY_TF_SCAN:
		ResetIOPLByTrapFrameScan();
		break;

	case RAISE_IOPL_BY_TSS:
#ifdef _X86_
		RaiseIOPLByTSS();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPL_BY_TSS:
#ifdef _x86_
		ResetIOPLByTSS();
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RAISE_IOPM:
#ifdef _X86_
		*OUTPUT(PNTSTATUS) = RaiseIOPM((HANDLE)*INPUT(PUINT64));
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

	case RESET_IOPM:
#ifdef _X86_
		*OUTPUT(PNTSTATUS) = ResetIOPM((HANDLE)*INPUT(PUINT64));
		SET_RESPONSE_LENGTH(sizeof(NTSTATUS));
#else
		Status = STATUS_NOT_IMPLEMENTED;
#endif
		break;

// PCI:

	case READ_PCI_CONFIG:
		OUTPUT(PREAD_PCI_CONFIG_OUTPUT)->Status = ReadPciConfig(
			INPUT(PREAD_PCI_CONFIG_INPUT)->PciAddress,
			INPUT(PREAD_PCI_CONFIG_INPUT)->PciOffset,
			(PVOID)INPUT(PREAD_PCI_CONFIG_INPUT)->Buffer,
			INPUT(PREAD_PCI_CONFIG_INPUT)->BufferSize,
			&OUTPUT(PREAD_PCI_CONFIG_OUTPUT)->BytesRead
		);
		SET_RESPONSE_LENGTH(sizeof(READ_PCI_CONFIG_OUTPUT));
		break;

	case WRITE_PCI_CONFIG:
		OUTPUT(PWRITE_PCI_CONFIG_OUTPUT)->Status = WritePciConfig(
			INPUT(PWRITE_PCI_CONFIG_INPUT)->PciAddress,
			INPUT(PWRITE_PCI_CONFIG_INPUT)->PciOffset,
			(PVOID)INPUT(PWRITE_PCI_CONFIG_INPUT)->Buffer,
			INPUT(PWRITE_PCI_CONFIG_INPUT)->BufferSize,
			&OUTPUT(PWRITE_PCI_CONFIG_OUTPUT)->BytesWritten
		);
		SET_RESPONSE_LENGTH(sizeof(WRITE_PCI_CONFIG_OUTPUT));
		break;

	default: 
		Status = STATUS_NOT_IMPLEMENTED;
		break;
	}

	return Status;

#undef INPUT
#undef OUTPUT

#undef SET_RESPONSE_LENGTH

}
Ejemplo n.º 4
0
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
  u32 val;
  u8 reg8;

  // all cores: allow caching of flash chip code and data
  // (there are no cache-as-ram reliability concerns with family 14h)
  __writemsr (0x20c, (0x0100000000ull - CONFIG_ROM_SIZE) | 5);
  __writemsr (0x20d, (0x1000000000ull - CONFIG_ROM_SIZE) | 0x800);

  // all cores: set pstate 0 (1600 MHz) early to save a few ms of boot time
  __writemsr (0xc0010062, 0);

  if (boot_cpu())
    {
    u8 reg8;
    // SB800: program AcpiMmioEn to enable MMIO access to MiscCntrl register
    outb(0x24, 0xCD6);
    reg8 = inb(0xCD7);
    reg8 |= 1;
    reg8 &= ~(1 << 1);
    outb(reg8, 0xCD7);
  
    // program SB800 MiscCntrl
    *(volatile u32 *)(0xFED80000+0xE00+0x40) &= ~((1 << 0) | (1 << 2)); /* 48Mhz */
    *(volatile u32 *)(0xFED80000+0xE00+0x40) |= 1 << 1; /* 48Mhz */
    }

  // early enable of PrefetchEnSPIFromHost
  if (boot_cpu())
    {
    __outdword (0xcf8, 0x8000a3b8);
    __outdword (0xcfc, __indword (0xcfc) | 1 << 24);
    }

  // early enable of SPI 33 MHz fast mode read
  if (boot_cpu())
    {
    volatile u32 *spiBase = (void *) 0xa0000000;
    u32 save;
    __outdword (0xcf8, 0x8000a3a0);
    save = __indword (0xcfc);
    __outdword (0xcfc, (u32) spiBase | 2); // set temp MMIO base
    spiBase [3] = (spiBase [3] & ~(3 << 14)) | (1 << 14);
    spiBase [0] |= 1 << 18; // fast read enable
    __outdword (0xcfc, save); // clear temp base
    }

  if (!cpu_init_detectedx && boot_cpu()) {
    post_code(0x30);
    sb_poweron_init();

    post_code(0x31);
    f81865f_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
    console_init();
  }

  /* Halt if there was a built in self test failure */
  post_code(0x34);
  report_bist_failure(bist);

  // Load MPB
  val = cpuid_eax(1);
  printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val);
  printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx);

  post_code(0x35);
  val = agesawrapper_amdinitmmio();

  post_code(0x37);
  val = agesawrapper_amdinitreset();
  if(val) {
    printk(BIOS_DEBUG, "agesawrapper_amdinitreset failed: %x \n", val);
  }

  post_code(0x38);
  printk(BIOS_DEBUG, "Got past sb800_early_setup\n");

  post_code(0x39);
  val = agesawrapper_amdinitearly ();
  if(val) {
    printk(BIOS_DEBUG, "agesawrapper_amdinitearly failed: %x \n", val);
  }
  printk(BIOS_DEBUG, "Got past agesawrapper_amdinitearly\n");

  post_code(0x40);
  val = agesawrapper_amdinitpost ();
  if(val) {
    printk(BIOS_DEBUG, "agesawrapper_amdinitpost failed: %x \n", val);
  }
  printk(BIOS_DEBUG, "Got past agesawrapper_amdinitpost\n");

  post_code(0x41);
  val = agesawrapper_amdinitenv ();
  if(val) {
    printk(BIOS_DEBUG, "agesawrapper_amdinitenv failed: %x \n", val);
  }
  printk(BIOS_DEBUG, "Got past agesawrapper_amdinitenv\n");

  /* Initialize i8259 pic */
  post_code(0x41);
  setup_i8259 ();

  /* Initialize i8254 timers */
  post_code(0x42);
  setup_i8254 ();

  post_code(0x50);
  copy_and_run(0);

  post_code(0x54);  // Should never see this post code.
}