#include #include #include #include #include #include #include #include #include #include #include /* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */ unsigned long long opt_mem; static void parse_mem(char *s) { opt_mem = parse_size_and_unit(s, NULL); } custom_param("mem", parse_mem); /* opt_nomtrr_check: Don't clip ram to highest cacheable MTRR. */ static int __initdata e820_mtrr_clip = -1; boolean_param("e820-mtrr-clip", e820_mtrr_clip); /* opt_e820_verbose: Be verbose about clipping, the original e820, &c */ static int __initdata e820_verbose; boolean_param("e820-verbose", e820_verbose); struct e820map e820; /* * This function checks if the entire range is mapped with type. * * Note: this function only works correct if the e820 table is sorted and * not-overlapping, which is the case */ int __init e820_all_mapped(u64 start, u64 end, unsigned type) { int i; for (i = 0; i < e820.nr_map; i++) { struct e820entry *ei = &e820.map[i]; if (type && ei->type != type) continue; /* is the region (part) in overlap with the current region ?*/ if (ei->addr >= end || ei->addr + ei->size <= start) continue; /* if the region is at the beginning of we move * start to the end of the region since it's ok until there */ if (ei->addr <= start) start = ei->addr + ei->size; /* * if start is now at or beyond end, we're done, full * coverage */ if (start >= end) return 1; } return 0; } static void __init add_memory_region(unsigned long long start, unsigned long long size, int type) { int x; /*if (!efi_enabled)*/ { x = e820.nr_map; if (x == E820MAX) { printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); return; } e820.map[x].addr = start; e820.map[x].size = size; e820.map[x].type = type; e820.nr_map++; } } /* add_memory_region */ static void __init print_e820_memory_map(struct e820entry *map, int entries) { int i; for (i = 0; i < entries; i++) { printk(" %016Lx - %016Lx ", (unsigned long long)(map[i].addr), (unsigned long long)(map[i].addr + map[i].size)); switch (map[i].type) { case E820_RAM: printk("(usable)\n"); break; case E820_RESERVED: printk("(reserved)\n"); break; case E820_ACPI: printk("(ACPI data)\n"); break; case E820_NVS: printk("(ACPI NVS)\n"); break; case E820_UNUSABLE: printk("(unusable)\n"); break; default: printk("type %u\n", map[i].type); break; } } } /* * Sanitize the BIOS e820 map. * * Some e820 responses include overlapping entries. The following * replaces the original e820 map with a new one, removing overlaps. * */ struct change_member { struct e820entry *pbios; /* pointer to original bios entry */ unsigned long long addr; /* address for this change point */ }; static struct change_member change_point_list[2*E820MAX] __initdata; static struct change_member *change_point[2*E820MAX] __initdata; static struct e820entry *overlap_list[E820MAX] __initdata; static struct e820entry new_bios[E820MAX] __initdata; static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) { struct change_member *change_tmp; unsigned long current_type, last_type; unsigned long long last_addr; int chgidx, still_changing; int overlap_entries; int new_bios_entry; int old_nr, new_nr, chg_nr; int i; /* Visually we're performing the following (1,2,3,4 = memory types)... Sample memory map (w/overlaps): ____22__________________ ______________________4_ ____1111________________ _44_____________________ 11111111________________ ____________________33__ ___________44___________ __________33333_________ ______________22________ ___________________2222_ _________111111111______ _____________________11_ _________________4______ Sanitized equivalent (no overlap): 1_______________________ _44_____________________ ___1____________________ ____22__________________ ______11________________ _________1______________ __________3_____________ ___________44___________ _____________33_________ _______________2________ ________________1_______ _________________4______ ___________________2____ ____________________33__ ______________________4_ */ /* if there's only one memory region, don't bother */ if (*pnr_map < 2) return -1; old_nr = *pnr_map; /* bail out if we find any unreasonable addresses in bios map */ for (i=0; iaddr = biosmap[i].addr; change_point[chgidx++]->pbios = &biosmap[i]; change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; change_point[chgidx++]->pbios = &biosmap[i]; } } chg_nr = chgidx; /* true number of change-points */ /* sort change-point list by memory addresses (low -> high) */ still_changing = 1; while (still_changing) { still_changing = 0; for (i=1; i < chg_nr; i++) { /* if > , swap */ /* or, if current= & last=, swap */ if ((change_point[i]->addr < change_point[i-1]->addr) || ((change_point[i]->addr == change_point[i-1]->addr) && (change_point[i]->addr == change_point[i]-
/*
    ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

/**
 * @file    memstreams.h
 * @brief   Memory streams structures and macros.
 
 * @addtogroup memory_streams
 * @{
 */

#ifndef MEMSTREAMS_H
#define MEMSTREAMS_H

/*===========================================================================*/
/* Driver constants.                                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Driver pre-compile time settings.                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Derived constants and error checks.                                       */
/*===========================================================================*/

/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/**
 * @brief   @p MemStream specific data.
 */
#define _memory_stream_data                                                 \
  _base_sequential_stream_data                                              \
  /* Pointer to the stream buffer.*/                                        \
  uint8_t               *buffer;                                            \
  /* Size of the stream.*/                                                  \
  size_t                size;                                               \
  /* Current end of stream.*/                                               \
  size_t                eos;                                                \
  /* Current read offset.*/                                                 \
  size_t                offset;

/**
 * @brief   @p MemStream virtual methods table.
 */
struct MemStreamVMT {
  _base_sequential_stream_methods
};

/**
 * @extends BaseSequentialStream
 *
 * @brief Memory stream object.
 */
typedef struct {
  /** @brief Virtual Methods Table.*/
  const struct MemStreamVMT *vmt;
  _memory_stream_data
} MemoryStream;

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#ifdef __cplusplus
extern "C" {
#endif
  void msObjectInit(MemoryStream *msp, uint8_t *buffer,
                    size_t size, size_t eos);
#ifdef __cplusplus
}
#endif

#endif /* MEMSTREAMS_H */

/** @} */
[i+2].size = re - e; } /* Finally, look for any opportunities to merge adjacent e820 entries. */ for ( i = 0; i < (e820->nr_map - 1); i++ ) { if ( (e820->map[i].type != e820->map[i+1].type) || ((e820->map[i].addr + e820->map[i].size) != e820->map[i+1].addr) ) continue; e820->map[i].size += e820->map[i+1].size; memmove(&e820->map[i+1], &e820->map[i+2], (e820->nr_map-i-2) * sizeof(e820->map[0])); e820->nr_map--; i--; } return 1; overflow: printk("Overflow in e820 while reserving region %"PRIx64"-%"PRIx64"\n", s, e); return 0; } /* Set E820_RAM area (@s,@e) as RESERVED in specified e820 map. */ int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e) { return e820_change_range_type(e820, s, e, E820_RAM, E820_RESERVED); } unsigned long __init init_e820( const char *str, struct e820entry *raw, int *raw_nr) { if ( e820_verbose ) { printk("Initial %s RAM map:\n", str); print_e820_memory_map(raw, *raw_nr); } machine_specific_memory_setup(raw, raw_nr); printk("%s RAM map:\n", str); print_e820_memory_map(e820.map, e820.nr_map); return find_max_pfn(); }