Fork me on GitHub

root/mm/bios_map.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. addr_in_bios_map
  2. bios_map_add
  3. bios_map_init

   1 /*
   2  * fiwix/mm/bios_map.c
   3  *
   4  * Copyright 2018-2022, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/mm.h>
  10 #include <fiwix/bios.h>
  11 #include <fiwix/stdio.h>
  12 #include <fiwix/string.h>
  13 
  14 static char *bios_mem_type[] = {
  15         NULL,
  16         "available",
  17         "reserved",
  18         "ACPI Reclaim",
  19         "ACPI NVS",
  20         "unusable",
  21         "disabled"
  22 };
  23 
  24 /* check if an specific address is available in the BIOS memory map */
  25 int addr_in_bios_map(unsigned int addr)
  26 {
  27         int n, retval;
  28         struct bios_mem_map *bmm;
  29 
  30         retval = 0;
  31         bmm = &bios_mem_map[0];
  32 
  33         for(n = 0; n < NR_BIOS_MM_ENT; n++, bmm++) {
  34                 if(bmm->to && bmm->type == MULTIBOOT_MEMORY_AVAILABLE) {
  35                         if(addr >= bmm->from && addr < (bmm->to & PAGE_MASK)) {
  36                                 retval = 1;
  37                         }
  38                 }
  39         }
  40 
  41         /* this second pass is necessary because the array is not sorted */
  42         bmm = &bios_mem_map[0];
  43         for(n = 0; n < NR_BIOS_MM_ENT; n++, bmm++) {
  44                 if(bmm->to && bmm->type == MULTIBOOT_MEMORY_RESERVED) {
  45                         if(addr >= bmm->from && addr < (bmm->to & PAGE_MASK)) {
  46                                 retval = 0;
  47                         }
  48                 }
  49         }
  50 
  51         return retval;  /* not in BIOS map or not available (reserved, ...) */
  52 }
  53 
  54 void bios_map_add(unsigned long int from, unsigned long int to, int from_type, int to_type)
  55 {
  56         int n;
  57 
  58         for(n = 0; n < NR_BIOS_MM_ENT; n++) {
  59                 if(!bios_mem_map[n].type) {
  60                         if(from_type == to_type) {
  61                                 printk("memory    0x%08x%08x-0x%08x%08x %s\n",
  62                                         0, from,
  63                                         0, to - 1,
  64                                         bios_mem_type[to_type]
  65                                 );
  66                         } else {
  67                                 printk("memory    0x%08x%08x-0x%08x%08x %s -> %s\n",
  68                                         0, from,
  69                                         0, to - 1,
  70                                         bios_mem_type[from_type],
  71                                         bios_mem_type[to_type]
  72                                 );
  73                         }
  74                         bios_mem_map[n].from = from;
  75                         bios_mem_map[n].to = to;
  76                         bios_mem_map[n].type = to_type;
  77                         break;
  78                 }
  79         }
  80 
  81         if(n >= NR_BIOS_MM_ENT) {
  82                 printk("WARNING: %s(): no more entries in bios_mem_map[].\n", __FUNCTION__);
  83                 return;
  84         }
  85 }
  86 
  87 void bios_map_init(struct multiboot_mmap_entry *bmmap_addr, unsigned long int bmmap_length)
  88 {
  89         struct multiboot_mmap_entry *bmmap;
  90         unsigned int from_high, from_low, to_high, to_low;
  91         unsigned long long to;
  92         int n;
  93 
  94         bmmap = bmmap_addr;
  95         kstat.physical_pages = 0;
  96 
  97         if(bmmap) {
  98                 n = 0;
  99 
 100                 while((unsigned int)bmmap < (unsigned int)bmmap_addr + bmmap_length) {
 101                         from_high = (unsigned int)(bmmap->addr >> 32);
 102                         from_low = (unsigned int)(bmmap->addr & 0xFFFFFFFF);
 103                         to = (bmmap->addr + bmmap->len) - 1;
 104                         to_high = (unsigned int)(to >> 32);
 105                         to_low = (unsigned int)(to & 0xFFFFFFFF);
 106                         printk("%s    0x%08x%08x-0x%08x%08x %s\n",
 107                                 n ? "      " : "memory",
 108                                 from_high,
 109                                 from_low,
 110                                 to_high,
 111                                 to_low,
 112                                 bios_mem_type[(int)bmmap->type]
 113                         );
 114                         /* only memory addresses below 4GB are counted */
 115                         if(!from_high && !to_high) {
 116                                 if(n < NR_BIOS_MM_ENT && bmmap->len) {
 117                                         bios_mem_map[n].from = from_low;
 118                                         bios_mem_map[n].to = to_low;
 119                                         bios_mem_map[n].type = (int)bmmap->type;
 120                                         if(bios_mem_map[n].type == MULTIBOOT_MEMORY_AVAILABLE) {
 121                                                 from_low = bios_mem_map[n].from & PAGE_MASK;
 122                                                 to_low = bios_mem_map[n].to & PAGE_MASK;
 123 
 124                                                 /* the first MB is not counted here */
 125                                                 if(from_low >= 0x100000) {
 126                                                         kstat.physical_pages += (to_low - from_low) / PAGE_SIZE;
 127                                                 }
 128                                         }
 129                                         n++;
 130                                 }
 131                         }
 132                         bmmap = (struct multiboot_mmap_entry *)((unsigned int)bmmap + bmmap->size + sizeof(bmmap->size));
 133                 }
 134                 kstat.physical_pages += (1024 >> 2);    /* add the first MB as a whole */
 135                 if(kstat.physical_pages > (0x40000000 >> PAGE_SHIFT)) {
 136                         printk("WARNING: detected a total of %dMB of available memory below 4GB.\n", (kstat.physical_pages << 2) / 1024);
 137                 }
 138         } else {
 139                 printk("WARNING: your BIOS has not provided a memory map.\n");
 140                 bios_mem_map[0].from = 0;
 141                 bios_mem_map[0].to = _memsize * 1024;
 142                 bios_mem_map[0].type = MULTIBOOT_MEMORY_AVAILABLE;
 143                 bios_mem_map[1].from = 0x00100000;
 144                 bios_mem_map[1].to = (_extmemsize + 1024) * 1024;
 145                 bios_mem_map[1].type = MULTIBOOT_MEMORY_AVAILABLE;
 146                 kstat.physical_pages = (_extmemsize + 1024) >> 2;
 147         }
 148 
 149         /*
 150          * This truncates to 1GB since it's the maximum physical memory
 151          * currently supported.
 152          */
 153         if(kstat.physical_pages > (0x40000000 >> PAGE_SHIFT)) {
 154                 kstat.physical_pages = (0x40000000 >> PAGE_SHIFT);
 155                 printk("WARNING: only up to 1GB of physical memory will be used.\n");
 156         }
 157 }

/* [previous][next][first][last][top][bottom][index][help] */