akaros/kern/arch/x86/intel.c
<<
>>
Prefs
   1/* Copyright (c) 2014 The Regents of the University of California
   2 * See LICENSE for details.
   3 *
   4 * Barret Rhoden <brho@cs.berkeley.edu> */
   5
   6#include <arch/x86.h>
   7#include <arch/pci.h>
   8#include <trap.h>
   9#include <stdio.h>
  10#include <string.h>
  11#include <assert.h>
  12#include <kmalloc.h>
  13#include <time.h>
  14#include <mm.h>
  15
  16/* super-shoddy LPC chip initialization.
  17 *
  18 * the PCH (old southbridge) is a c602, TBDF x:1f:00 LPC controller
  19 * - PMBASE is the mnemonic for "ACPI Base Address"
  20 * - TCO is 0x60 off in the PMBASE space
  21 * - PMBASE + 0x30 is an SMI control reg
  22 *
  23 * TODO:
  24 * - why don't we find the other functions (1f.2 and 1f.3, in linux)?
  25 */
  26static void lpc_init_pci(struct pci_device *pcidev)
  27{
  28        uint32_t pmbase = pcidev_read32(pcidev, 0x40);
  29
  30        pmbase &= ~1; /* clear bit 0 */
  31        uint32_t smi_ctl = inl(pmbase + 0x30);
  32        #if 0
  33        /* halt the tco timer: this busts things, and won't work with the lock
  34         * on */
  35        uint16_t tco1 = inw(pmbase + 0x60 + 0x08);
  36        if (tco1 & (1 << 12)) {
  37                printk("\t\tTCO_LOCK is on!\n");
  38        } else {
  39                outw(pmbase + 0x60 + 0x08, tco1 & ~(1 << 11));
  40                tco1 = inw(pmbase + 0x60 + 0x08);
  41        }
  42        #endif
  43        /* bit 6 is another timer, one that messes up c89. */
  44        outl(pmbase + 0x30, smi_ctl & ~(1 << 6));
  45        smi_ctl = inl(pmbase + 0x30);
  46}
  47
  48void intel_lpc_init(void)
  49{
  50        struct pci_device *i;
  51
  52        STAILQ_FOREACH(i, &pci_devices, all_dev) {
  53                if ((i->dev == 0x1f) && (i->func == 0x00))
  54                        lpc_init_pci(i);
  55        }
  56}
  57