Ejemplo n.º 1
0
static void
print_xsdt_table(sfi_info_t *sfi_info)
{
  if(sfi_info->xsdt_table) {
    size_t i;
    DLOGV("Number of XSDT table entries: %u",
          SFI_NUM_XSDT_ENTRIES(sfi_info->xsdt_table));
    DLOGV("(addr, name)");
    for(i = 0; i < SFI_NUM_XSDT_ENTRIES(sfi_info->xsdt_table); i++) {
      ACPI_TABLE_HEADER *table = (ACPI_TABLE_HEADER*)
        map_virtual_page((sfi_info->xsdt_table->TableOffsetEntry[i] & 0xFFFFF000) | 3);

      if(table == NULL) {
        panic("Failed to map XSDT sub-table");
      }

      table = (ACPI_TABLE_HEADER*)(uint32)
        (((uint32)table) | (sfi_info->xsdt_table->TableOffsetEntry[i] & 0xFFF));

      DLOGV("(0x%llX, %c%c%c%c)", sfi_info->xsdt_table->TableOffsetEntry[i],
            table->Signature[0], table->Signature[1], table->Signature[2],
            table->Signature[3]);
      if(strncmp(table->Signature, SFI_SIG_MCFG, 4) == 0) {
        sfi_info->mcfg_table = (sfi_mcfg_table_t*)table;
        print_mcfg_table(sfi_info);
      }
      else {
        unmap_virtual_page(table);
      }
    }
  }
  else {
    DLOGV("NO XSDT Table");
  }
}
Ejemplo n.º 2
0
static phys_addr_t
sfi_syst_phys(void)
{
  phys_addr_t phys = SFI_SYST_SEARCH_BEGIN;

  do {
    char *virt = map_virtual_page((phys & 0xFFFFF000) | 3);

    if(virt == NULL) {
      panic("Failed to map virtual page in sfi_present");
    }
    int i;
    for(i = 0; i < 0x1000; i+=16) {
      if(strncmp(&virt[i], SFI_SIG_SYST, SFI_SIG_SIZE) == 0) {
        unmap_virtual_page(virt);
        return phys + i;
      }
    }
    unmap_virtual_page(virt);
    phys += 0x1000;

  } while(phys < SFI_SYST_SEARCH_END);

  return -1;
}
Ejemplo n.º 3
0
/**
* alloc_virtual_pages - varataan virtuaalisia sivuja muuhun kuin aktiiviseen tauluun
* @phys_pd: käytettävän sivuhakemiston fyysinen sivu
* @count: haluttujen sivujen määrä
* @user: sivuja kernelille (0) vai käyttäjälle (1)
**/
uint_t alloc_virtual_pages(uint_t phys_pd, uint_t count, int user)
{
	uint_t first, page;

	if (!user || !phys_pd) {
		// Kaikilla on samat kernelsivut
		phys_pd = cur_phys_pd();
	}

	first = find_free_virtual_pages(phys_pd, count, user);

	if (!first) {
		return 0;
	}

	for (page = first; page < first + count; ++page) {
		if (map_virtual_page(phys_pd, page, 0, user)) {
			goto free_pages_on_error;
		}
	}

	return first;

free_pages_on_error:
	while (page > first) {
		--page;
		unmap_virtual_page(phys_pd, page);
	}
	return 0;
}
Ejemplo n.º 4
0
Archivo: init.c Proyecto: Quest-V/quest
static uint16
alloc_idle_TSS (int cpu_num)
{
  int i;
  descriptor *ad = (descriptor *)KERN_GDT;
  quest_tss *pTSS = (quest_tss *) (&idleTSS[cpu_num]);
  void idle_task (void);

  /* Search 2KB GDT for first free entry */
  for (i = 1; i < 256; i++)
    if (!(ad[i].fPresent))
      break;

  if (i == 256)
    panic ("No free selector for TSS");

  ad[i].uLimit0 = sizeof (idleTSS[cpu_num]) - 1;
  ad[i].uLimit1 = 0;
  ad[i].pBase0 = (u32) pTSS & 0xFFFF;
  ad[i].pBase1 = ((u32) pTSS >> 16) & 0xFF;
  ad[i].pBase2 = (u32) pTSS >> 24;
  ad[i].uType = 0x09;           /* 32-bit tss */
  ad[i].uDPL = 0;               /* Only let kernel perform task-switching */
  ad[i].fPresent = 1;
  ad[i].f0 = 0;
  ad[i].fX = 0;
  ad[i].fGranularity = 0;       /* Set granularity of tss in bytes */

  u32 *stk = map_virtual_page (alloc_phys_frame () | 3);

  pTSS->CR3 = (u32) get_pdbr ();
  pTSS->initial_EIP = (u32) & idle_task;
  stk[1023] = pTSS->initial_EIP;
  pTSS->EFLAGS = F_1 | F_IOPL0;

  pTSS->ESP = (u32) &stk[1023];
  pTSS->EBP = pTSS->ESP;

  /* Return the index into the GDT for the segment */
  return i << 3;
}
Ejemplo n.º 5
0
/**
* resize_stack - laajennetaan säikeen pinoa
* @phys_pd: sivuhakemiston fyysinen sijainti
* @stack_num: pinon numero (prosessin pinoista)
* @size: pinon uusi vähimmäiskoko (tavuina)
*
* return 0 = onnistui
**/
int resize_stack(uint_t phys_pd, int stack_num, uint_t size, int user)
{
	if ((stack_num < 0 || stack_num > MAX_STACKS) || size > MAX_STACK_SIZE) {
		return -1;
	}
	uint_t pages, alloced, i;
	if (!size) {
		pages = 0;
	} else {
		pages = 1 + ((size - 1) / MEMORY_PAGE_SIZE);
	}

	i = STACK_TOP_PAGE(stack_num);
	alloced = 0;
	while (alloced < pages && temp_virt_page(0, phys_pd, i)) {
		temp_virt_page(0, 0, 0);
		++alloced;
		++i;
	}
	while (alloced < pages) {
		if (temp_virt_page(0, phys_pd, i)) {
			temp_virt_page(0, 0, 0);
		} else {
			if (map_virtual_page(phys_pd, i, 0, user) != 0) {
				panic("resize_stack: map_virtual_page != 0\n");
			}
		}
		++alloced;
		++i;
	}
	while (temp_virt_page(0, phys_pd, i)) {
		temp_virt_page(0, 0, 0);
		unmap_virtual_page(phys_pd, i);
		++i;
	}

	return 0;
}
Ejemplo n.º 6
0
Archivo: init.c Proyecto: Quest-V/quest
/* Create an address space for boot modules */
static uint16
load_module (multiboot_module * pmm, int mod_num)
{

  uint32 *plPageDirectory = get_phys_addr (pg_dir[mod_num]);
  uint32 *plPageTable = get_phys_addr (pg_table[mod_num]);
  void *pStack = get_phys_addr (ul_stack[mod_num]);
  /* temporarily map pmm->pe in order to read pph->p_memsz */
  Elf32_Ehdr *pe, *pe0 = map_virtual_page ((uint) pmm->pe | 3);
  Elf32_Phdr *pph = (void *) pe0 + pe0->e_phoff;
  void *pEntry = (void *) pe0->e_entry;
  int i, c, j;
  uint32 *stack_virt_addr;
  uint32 page_count = 1;

  /* find out how many pages for the module */
  for (i = 0; i < pe0->e_phnum; i++) {
    if (pph->p_type == PT_LOAD)
      page_count += (pph->p_memsz >> 12);
    pph = (void *) pph + pe0->e_phentsize;
  }

  /* now map the entire module */
  pe = map_contiguous_virtual_pages ((uint) pmm->pe | 3, page_count);

  unmap_virtual_page (pe0);

  pph = (void *) pe + pe->e_phoff;

  /* Populate ring 3 page directory with kernel mappings */
  memcpy (&plPageDirectory[1023], (void *) (((uint32) get_pdbr ()) + 4092),
          4);
  /* LAPIC/IOAPIC mappings */
  memcpy (&plPageDirectory[1019], (void *) (((uint32) get_pdbr ()) + 4076),
          4);

  /* Populate ring 3 page directory with entries for its private address
     space */
  plPageDirectory[0] = (uint32) plPageTable | 7;

  plPageDirectory[1022] = (uint32) get_phys_addr (kls_pg_table[mod_num]) | 3;
  kls_pg_table[mod_num][0] = (uint32) get_phys_addr (kl_stack[mod_num]) | 3;

  /* Walk ELF header */
  for (i = 0; i < pe->e_phnum; i++) {

    if (pph->p_type == PT_LOAD) {
      /* map pages loaded from file */
      c = (pph->p_filesz + 0xFFF) >> 12;        /* #pages to load for module */

      for (j = 0; j < c; j++)
        plPageTable[((uint32) pph->p_vaddr >> 12) + j] =
          (uint32) pmm->pe + (pph->p_offset & 0xFFFFF000) + (j << 12) + 7;

      /* zero remainder of final page */
      memset ((void *) pe + pph->p_offset + pph->p_filesz,
              0, (pph->p_memsz - pph->p_filesz) & 0x0FFF);

      /* map additional zeroed pages */
      c = (pph->p_memsz + 0xFFF) >> 12;

      /* Allocate space for bss section.  Use temporary virtual memory for
       * memset call to clear physical frame(s)
       */
      for (; j <= c; j++) {
        uint32 page_frame = (uint32) alloc_phys_frame ();
        void *virt_addr = map_virtual_page (page_frame | 3);
        memset (virt_addr, 0, 0x1000);
        plPageTable[((uint32) pph->p_vaddr >> 12) + j] = page_frame + 7;
        unmap_virtual_page (virt_addr);
      }
    }

    pph = (void *) pph + pe->e_phentsize;
  }
Ejemplo n.º 7
0
Archivo: init.c Proyecto: Quest-V/quest
      for (; j <= c; j++) {
        uint32 page_frame = (uint32) alloc_phys_frame ();
        void *virt_addr = map_virtual_page (page_frame | 3);
        memset (virt_addr, 0, 0x1000);
        plPageTable[((uint32) pph->p_vaddr >> 12) + j] = page_frame + 7;
        unmap_virtual_page (virt_addr);
      }
    }

    pph = (void *) pph + pe->e_phentsize;
  }

  /* map stack */
  plPageTable[1023] = (uint32) pStack | 7;

  stack_virt_addr = map_virtual_page ((uint32) pStack | 3);

  /* This sets up the module's stack with command-line args from grub */
  memcpy ((char *) stack_virt_addr + 0x1000 - 80, pmm->string, 80);
  *(uint32 *) ((char *) stack_virt_addr + 0x1000 - 84) = 0;   /* argv[1] */
  *(uint32 *) ((char *) stack_virt_addr + 0x1000 - 88) = 0x400000 - 80;       /* argv[0] */
  *(uint32 *) ((char *) stack_virt_addr + 0x1000 - 92) = 0x400000 - 88;       /* argv */
  *(uint32 *) ((char *) stack_virt_addr + 0x1000 - 96) = 1;   /* argc -- hard-coded right now */
  /* Dummy return address placed here for the simulated "call" to our
     library */
  *(uint32 *) ((char *) stack_virt_addr + 0x1000 - 100) = 0;  /* NULL return address -- never used */

  unmap_virtual_page (stack_virt_addr);
  unmap_virtual_pages (pe, page_count);

  u16 pid = alloc_TSS (plPageDirectory, pEntry, mod_num);
Ejemplo n.º 8
0
int
sfi_early_init(sfi_info_t *sfi_info)
{
  int i;
  size_t syst_num;
  phys_addr_t low_frame;
  phys_addr_t high_frame;
  phys_addr_t syst_phys;

  memset(sfi_info, 0, sizeof(*sfi_info));

  syst_phys = sfi_syst_phys();
  if(syst_phys == -1) {
    return 0;
  }

  low_frame = high_frame = syst_phys;

  sfi_info->system_table = (sfi_system_table_t*)
    (((char*)map_virtual_page((syst_phys & 0xFFFFF000) | 3))
    + (syst_phys & 0xFFF));

  syst_num = SFI_NUM_SYST_ENTRIES(sfi_info->system_table);

  for(i = 0; i < syst_num; i++) {
    if(sfi_info->system_table->entries[i] > 0xFFFFFFFF) {
      panic("SFI table above 4G region");
    }
    if(sfi_info->system_table->entries[i] < low_frame) {
      low_frame = sfi_info->system_table->entries[i];
    }
    if(sfi_info->system_table->entries[i] > high_frame) {
      high_frame = sfi_info->system_table->entries[i];
    }
  }

  sfi_info->low_frame = low_frame = low_frame & 0xFFFFF000;
  high_frame &= 0xFFFFF000;

  unmap_virtual_page(sfi_info->system_table);

  sfi_info->num_frames = ((high_frame - low_frame) / 0x1000) + 1;
  sfi_info->start_addr =
    map_contiguous_virtual_pages(low_frame | 3,
                                 sfi_info->num_frames);

  if(sfi_info->start_addr == NULL) {
    panic("Failed to map STI");
  }

  sfi_info->system_table = (sfi_system_table_t*)
    SFI_PHYS_TO_VIRT(sfi_info, syst_phys);

  print_syst_table(sfi_info);

  sfi_info->cpus_table = get_sfi_table(sfi_info, SFI_SIG_CPUS);
  print_cpus_table(sfi_info);

  sfi_info->apic_table = get_sfi_table(sfi_info, SFI_SIG_APIC);
  print_apic_table(sfi_info);

  sfi_info->mmap_table = get_sfi_table(sfi_info, SFI_SIG_MMAP);
  print_mmap_table(sfi_info);

  sfi_info->freq_table = get_sfi_table(sfi_info, SFI_SIG_FREQ);
  print_freq_table(sfi_info);

  sfi_info->mtmr_table = get_sfi_table(sfi_info, SFI_SIG_MTMR);
  print_mtmr_table(sfi_info);

  sfi_info->mrtc_table = get_sfi_table(sfi_info, SFI_SIG_MRTC);
  print_mrtc_table(sfi_info);

  sfi_info->wake_table = get_sfi_table(sfi_info, SFI_SIG_WAKE);
  print_wake_table(sfi_info);

  sfi_info->devs_table = get_sfi_table(sfi_info, SFI_SIG_DEVS);
  print_devs_table(sfi_info);

  sfi_info->gpio_table = get_sfi_table(sfi_info, SFI_SIG_GPIO);
  print_gpio_table(sfi_info);

  sfi_info->xsdt_table = get_sfi_table(sfi_info, SFI_SIG_XSDT);
  print_xsdt_table(sfi_info);

  return 0;
}