Ejemplo n.º 1
0
static uintptr_t smm_region_start(void)
{
	/*
	 * Calculate the top of usable (low) DRAM.
	 * The FSP's reserved memory sits just below the SMM region,
	 * allowing calculation of the top of usable memory.
	 */
	uintptr_t tom = sideband_read(B_UNIT, BMBOUND);
	uintptr_t bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20;
	if (bsmmrrl) {
		tom = bsmmrrl;
	}

	return tom;
}
Ejemplo n.º 2
0
unsigned long get_top_of_ram(void)
{
	/*
	 * Calculate the top of usable (low) DRAM.
	 * The FSP's reserved memory sits just below the SMM region,
	 * allowing calculation of the top of usable memory.
	 */
	u32 tom = sideband_read(B_UNIT, BMBOUND);
	u32 bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20;
	if (bsmmrrl) {
		tom = bsmmrrl;
	}
	tom -= FSP_RESERVE_MEMORY_SIZE;

	return (unsigned long) tom;
}
Ejemplo n.º 3
0
unsigned long acpi_fill_mcfg(unsigned long current)
{
	device_t dev;
	u32 pciexbar = 0;
	u32 pciexbar_reg;
	int max_buses;
	int pci_dev_id;

	for (pci_dev_id = PCI_DEVICE_ID_RG_MIN; pci_dev_id <= PCI_DEVICE_ID_RG_MAX; pci_dev_id++) {
		dev = dev_find_device(PCI_VENDOR_ID_INTEL, pci_dev_id, 0);
		if (dev)
			break;
	}

	if (!dev)
		return current;

	pciexbar_reg = sideband_read(B_UNIT, BECREG);

	/* MMCFG not supported or not enabled. */
	if (!(pciexbar_reg & (1 << 0)))
		return current;

	/* 256MB ECAM range */
	pciexbar = pciexbar_reg & ((1 << 31)|(1 << 30)|(1 << 29)|(1 << 28));
	max_buses = 256;

	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current,
			pciexbar, 0x0, 0x0, max_buses - 1);

	return current;
}
Ejemplo n.º 4
0
void northbridge_acpi_fill_ssdt_generator(device_t device)
{
	u32 bmbound;
	char pscope[] = "\\_SB.PCI0";

	bmbound = sideband_read(B_UNIT, BMBOUND);
	acpigen_write_scope(pscope);
	acpigen_write_name_dword("BMBD", bmbound);
	acpigen_pop_len();
	generate_cpu_entries(device);
}
Ejemplo n.º 5
0
static void mc_add_dram_resources(device_t dev)
{
	u32 tomlow, bmbound, bsmmrrl, bsmmrrh;
	u64 bmbound_hi;
	int index = 0;

	/*
	 *  These are the host memory ranges :
	 * - 0 -> SMM (SMMRRL) : cacheable
	 * - SMM -> LOW TOM (BMBOUND) : cacheable WP
	 * - 4GB ->  HIGH TOM (BMBOUND_HI): cacheable
	 *
	 */

	tomlow = bmbound = sideband_read(B_UNIT, BMBOUND);
	printk(BIOS_SPEW, "Top of Low Used DRAM (BMBOUND): 0x%08x\n", bmbound);

	bmbound_hi = (u64)(sideband_read(B_UNIT, BMBOUND_HI)) << 4;
	printk(BIOS_SPEW, "Top of Upper Used DRAM (BMBOUND_HI): 0x%llx\n", bmbound_hi);

	bsmmrrl = sideband_read(B_UNIT, BSMMRRL) << 20;
	bsmmrrh = ((sideband_read(B_UNIT, BSMMRRH) + 1) << 20) - 1;
	if (bsmmrrl) {
		tomlow = bsmmrrl;
		printk(BIOS_DEBUG, "SMM memory location: 0x%x  SMM memory size: 0x%x\n", bsmmrrl, (bsmmrrh - bsmmrrl + 1));
		printk(BIOS_DEBUG, "Subtracting %dM for SMM\n", (bmbound - bsmmrrl) >> 20);
	}
	tomlow -= FSP_RESERVE_MEMORY_SIZE;
	printk(BIOS_SPEW, "Available memory below 4GB: 0x%08x (%dM)\n", tomlow, tomlow >> 20);

	/* Report the memory regions. */
	ram_resource(dev, index++, 0, legacy_hole_base_k);
	ram_resource(dev, index++, legacy_hole_base_k + legacy_hole_size_k,
	     ((tomlow >> 10) - (legacy_hole_base_k + legacy_hole_size_k)));

	mmio_resource(dev, index++, tomlow >> 10, (bmbound - bsmmrrl) >> 10);

	if (bmbound_hi > 0x100000000) {
		ram_resource(dev, index++, 0x100000000 >> 10, (bmbound_hi - 0x100000000) >> 10 );
		printk(BIOS_INFO, "Available memory above 4GB: %lluM\n", (bmbound_hi - 0x100000000) >> 20);
	}
Ejemplo n.º 6
0
static int get_pcie_bar(u32 *base, u32 *len)
{
	device_t dev;
	u32 pciexbar_reg;

	*base = 0;
	*len = 0;

	dev = dev_find_slot(0, PCI_DEVFN(0, 0));
	if (!dev)
		return 0;

	pciexbar_reg = sideband_read(B_UNIT, BECREG);

	if (!(pciexbar_reg & (1 << 0)))
		return 0;

	*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
				(1 << 28));
	*len = 256 * 1024 * 1024; /* 256MB ECAM range */
	return 1;

}
Ejemplo n.º 7
0
int try_pch(struct pci_access *pci) {
  pciaddr_t sbreg_addr;
  if(get_pch_sbreg_addr(pci, &sbreg_addr)) {
    MSG("Re-enumerating PCI devices will probably crash the system");
    ERR("Probing Series 100 PCH failed");
  }

  int memfd = open("/dev/mem", O_RDWR);
  if(memfd == -1) {
    ERR("Cannot open /dev/mem");
  }

  void *sbmap = mmap((void*)sbreg_addr, 1<<24, PROT_READ|PROT_WRITE, MAP_SHARED,
                     memfd, sbreg_addr);
  if(sbmap == MAP_FAILED) {
    if(errno == EPERM) {
      // The requirement might be relaxed to CONFIG_IO_DEVMEM_STRICT=n, but I'm not sure.
      MSG("Is your kernel configured with CONFIG_DEVMEM_STRICT=n?");
    }
    ERR("Cannot map SBREG");
  }

  close(memfd);

  for(unsigned port = 0; port < 4; port++) {
    uint16_t port_id = P2SB_PORT_GPIO0 - port;
    uint32_t padbar = sideband_read(sbmap, port_id, REG_PCH_GPIO_PADBAR);
    MSG("GPIO%d_PADBAR=%x", port, padbar);

    for(unsigned pad = 0; pad < 32; pad++) {
      uint32_t dw0 = sideband_read(sbmap, port_id, padbar + pad * 8);
      uint32_t dw1 = sideband_read(sbmap, port_id, padbar + pad * 8 + 4);
      if(dw1 == 0) {
        // Not documented as such, but appears to be a reliable last pad marker.
        break;
      }

      const char *state = "???", *rxstate = "", *txstate = "";
      if((dw0 & REG_PCH_GPIO_DW0_PMODE) != 0) {
        state = "Native";
      } else if((dw0 & REG_PCH_GPIO_DW0_TXDIS) != 0 &&
                (dw0 & REG_PCH_GPIO_DW0_RXDIS) != 0) {
        state = "Off";
      } else {
        state = "GPIO";
        if((dw0 & REG_PCH_GPIO_DW0_RXDIS) == 0) {
          if((dw0 & REG_PCH_GPIO_DW0_RXSTATE) != 0) {
            rxstate = " InHigh";
          } else {
            rxstate = " InLow";
          }
        }

        if((dw0 & REG_PCH_GPIO_DW0_TXDIS) == 0) {
          if((dw0 & REG_PCH_GPIO_DW0_TXSTATE) != 0) {
            txstate = " OutHigh";
          } else {
            txstate = " OutLow";
          }
        }
      }

      const char *pull = "???";
      switch(dw1 >> 10) {
        case REG_PCH_GPIO_DW1_TERM_NONE:   pull = "None";   break;
        case REG_PCH_GPIO_DW1_TERM_5K_PD:  pull = "Dn5k";   break;
        case REG_PCH_GPIO_DW1_TERM_20K_PD: pull = "Dn20k";  break;
        case REG_PCH_GPIO_DW1_TERM_5K_PU:  pull = "Up5k";   break;
        case REG_PCH_GPIO_DW1_TERM_20K_PU: pull = "Up20k";  break;
        case REG_PCH_GPIO_DW1_TERM_NATIVE: pull = "Native"; break;
      }

      printf("[+] GPIO%d_PAD%d: DW0=%08x DW1=%08x State=%s%s%s Pull=%s\n",
              port, pad, dw0, dw1, state, rxstate, txstate, pull);
    }
  }

  return 0;
}