Пример #1
0
static void pci_bus_assign_space(pci_bus_t *pcibus, 
                                 intptr_t mem_base, intptr_t io_base)
{
  pci_bar_t **bars = kernel_sbrk(0);
  unsigned nbars = 0;

  for (int j = 0; j < pcibus->ndevs; j++) {
    pci_device_t *pcidev = &pcibus->dev[j];

    for (int i = 0; i < pcidev->nbars; i++) {
      void *ptr __attribute__((unused));
      ptr = kernel_sbrk(sizeof(pci_bar_t *));
      bars[nbars++] = &pcidev->bar[i];
    }
  }

  qsort(bars, nbars, sizeof(pci_bar_t *), pci_bar_compare);

  for (int j = 0; j < nbars; j++) {
    pci_bar_t *bar = bars[j];
    if (bar->addr & PCI_BAR_IO) {
      bar->addr |= io_base;
      io_base += bar->size;
    } else {
      bar->addr |= mem_base;
      mem_base += bar->size;
    }
  }

  kernel_brk(bars);
}
Пример #2
0
static void pci_bus_enumerate(pci_bus_t *pcibus) {
  pcibus->dev = kernel_sbrk(0);
  pcibus->ndevs = 0;

  for (int j = 0; j < 32; j++) {
    for (int k = 0; k < 8; k++) {
      PCI0_CFG_ADDR_R = PCI0_CFG_ENABLE | PCI0_CFG_REG(j, k, 0);

      if (PCI0_CFG_DATA_R == -1)
        continue;

      pci_device_t *pcidev = kernel_sbrk(sizeof(pci_device_t));

      pcidev->addr.bus = 0;
      pcidev->addr.device = j;
      pcidev->addr.function = k;
      pcidev->device_id = PCI0_CFG_DATA_R >> 16;
      pcidev->vendor_id = PCI0_CFG_DATA_R;

      PCI0_CFG_ADDR_R = PCI0_CFG_ENABLE | PCI0_CFG_REG(j, k, 2);
      pcidev->class_code = (PCI0_CFG_DATA_R & 0xff000000) >> 24;

      PCI0_CFG_ADDR_R = PCI0_CFG_ENABLE | PCI0_CFG_REG(j, k, 15);
      pcidev->pin = PCI0_CFG_DATA_R >> 8;
      pcidev->irq = PCI0_CFG_DATA_R;

      for (int i = 0; i < 6; i++) {
        PCI0_CFG_ADDR_R = PCI0_CFG_ENABLE |
          PCI0_CFG_REG(pcidev->addr.device, pcidev->addr.function, 4 + i);
        unsigned addr = PCI0_CFG_DATA_R;
        PCI0_CFG_DATA_R = -1;
        unsigned size = PCI0_CFG_DATA_R;
        if (size == 0 || addr == size)
          continue;

        size &= (addr & PCI_BAR_IO) ? ~PCI_BAR_IO_MASK : ~PCI_BAR_MEMORY_MASK;
        size = -size;

        pci_bar_t *bar = &pcidev->bar[pcidev->nbars++];
        bar->addr = addr;
        bar->size = size;
      }

      pcibus->ndevs++;
    }
  }
}
Пример #3
0
static char *make_pair(char *key, char *value) {
  int arglen = strlen(key) + strlen(value) + 2;
  char *arg = kernel_sbrk(arglen * sizeof(char));
  strlcpy(arg, key, arglen);
  strlcat(arg, "=", arglen);
  strlcat(arg, value, arglen);
  return arg;
}
Пример #4
0
/* Note that morecore has to take a signed argument so
   that negative values can return memory to the system. */
void *
_default_morecore(long size)
{
    void *result;

    result = kernel_sbrk(size);
    if (result == (void *) -1)
	return NULL;
    return result;
}
Пример #5
0
/*
 * For some reason arguments passed to kernel are not correctly splitted
 * in argv array - in our case all arguments are stored in one string argv[1],
 * but we want to keep every argument in separate argv entry. This function
 * tokenize all argv strings and store every single token into individual entry
 * of new array.
 *
 * For our needs we also convert passed environment variables and put them
 * into new argv array.
 *
 * Example:
 *
 *   For arguments:
 *     argc=3;
 *     argv={"test.elf", "arg1 arg2=val   arg3=foobar  ", "  init=/bin/sh "};
 *     envp={"memsize", "128MiB", "uart.speed", "115200"};
 *
 *   instruction:
 *     setup_kenv(argc, argv, envp);
 *
 *   will set global variable _kenv as follows:
 *     _kenv.argc=5;
 *     _kenv.argv={"test.elf", "arg1", "arg2=val", "arg3=foobar",
 *                 "init=/bin/sh", "memsize=128MiB", "uart.speed=115200"};
 */
static void setup_kenv(int argc, char **argv, char **envp) {
  unsigned ntokens = 0;

  for (int i = 0; i < argc; ++i)
    ntokens += count_tokens(argv[i]);
  for (char **pair = envp; *pair; pair += 2)
    ntokens++;

  _kenv.argc = ntokens;

  char **tokens = kernel_sbrk(ntokens * sizeof(char *));

  _kenv.argv = tokens;

  for (int i = 0; i < argc; ++i)
    tokens = extract_tokens(argv[i], tokens);
  for (char **pair = envp; *pair; pair += 2)
    *tokens++ = make_pair(pair[0], pair[1]);
}