|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2004 David Decotigny 002 Copyright (C) 2000 The KOS Team 003 004 This program is free software; you can redistribute it and/or 005 modify it under the terms of the GNU General Public License 006 as published by the Free Software Foundation; either version 2 007 of the License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU General Public License for more details. 013 014 You should have received a copy of the GNU General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 017 USA. 018 */ 019 #ifndef _SOS_PHYSMEM_H_ 020 #define _SOS_PHYSMEM_H_ 021 022 /** 023 * @file physmem.h 024 * 025 * Physical pages of memory 026 */ 027 028 #include <sos/errno.h> 029 #include <sos/types.h> 030 #include <sos/macros.h> 031 032 /** The size of a physical page (arch-dependent) */ 033 #define SOS_PAGE_SIZE (4*1024) 034 035 /** The corresponding shift */ 036 #define SOS_PAGE_SHIFT 12 /* 4 kB = 2^12 B */ 037 038 /** The corresponding mask */ 039 #define SOS_PAGE_MASK ((1<<12) - 1) 040 041 #define SOS_PAGE_ALIGN_INF(val) \ 042 SOS_ALIGN_INF((val), SOS_PAGE_SIZE) 043 #define SOS_PAGE_ALIGN_SUP(val) \ 044 SOS_ALIGN_SUP((val), SOS_PAGE_SIZE) 045 #define SOS_IS_PAGE_ALIGNED(val) \ 046 SOS_IS_ALIGNED((val), SOS_PAGE_SIZE) 047 048 /** 049 * This is the reserved physical interval for the x86 video memory and 050 * BIOS area. In physmem.c, we have to mark this area as "nonfree" in 051 * order to prevent from allocating it. And in paging.c, we'd better 052 * map it in virtual space if we really want to be able to print to 053 * the screen (for debugging purpose, at least): for this, the 054 * simplest is to identity-map this area in virtual space (note 055 * however that this mapping could also be non-identical). 056 */ 057 #define BIOS_N_VIDEO_START 0xa0000 058 #define BIOS_N_VIDEO_END 0x100000 059 060 061 /** 062 * Initialize the physical memory subsystem, for the physical area [0, 063 * ram_size). This routine takes into account the BIOS and video 064 * areas, to prevent them from future allocations. 065 * 066 * @param ram_size The size of the RAM that will be managed by this subsystem 067 * 068 * @param kernel_core_base The lowest address for which the kernel 069 * assumes identity mapping (ie virtual address == physical address) 070 * will be stored here 071 * 072 * @param kernel_core_top The top address for which the kernel 073 * assumes identity mapping (ie virtual address == physical address) 074 * will be stored here 075 */ 076 sos_ret_t sos_physmem_subsystem_setup(sos_size_t ram_size, 077 /* out */sos_paddr_t *kernel_core_base, 078 /* out */sos_paddr_t *kernel_core_top); 079 080 081 /** 082 * Retrieve the total number of pages, and the number of free pages 083 * 084 * @note both parameters may be NULL 085 */ 086 sos_ret_t sos_physmem_get_state(/* out */sos_count_t *total_ppages, 087 /* out */sos_count_t *nonfree_ppages); 088 089 090 /** 091 * Get a free page. 092 * 093 * @return The (physical) address of the (physical) page allocated, or 094 * NULL when none currently available. 095 * 096 * @param can_block TRUE if the function is allowed to block 097 * @note The page returned has a reference count equal to 1. 098 */ 099 sos_paddr_t sos_physmem_ref_physpage_new(sos_bool_t can_block); 100 101 102 /** 103 * Increment the reference count of a given physical page. Useful for 104 * VM code which tries to map a precise physical address. 105 * 106 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 107 * 108 * @return TRUE when the page was previously referenced, FALSE when 109 * the page was previously unreferenced, <0 when the page address is 110 * invalid. 111 */ 112 sos_ret_t sos_physmem_ref_physpage_at(sos_paddr_t ppage_paddr); 113 114 115 /** 116 * Decrement the reference count of the given physical page. When the 117 * reference count of the page reaches 0, the page is marked free, ie 118 * is available for future sos_physmem_ref_physpage_new() 119 * 120 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 121 * 122 * @return FALSE when the page is still referenced, TRUE when the page 123 * is now unreferenced, <0 when the page address is invalid 124 */ 125 sos_ret_t sos_physmem_unref_physpage(sos_paddr_t ppage_paddr); 126 127 128 /** 129 * Return the reference count of the given page 130 * 131 * @return >= 0 (the referebce count of the page) if the physical 132 * address is valid, or an error status 133 */ 134 sos_ret_t sos_physmem_get_physpage_refcount(sos_paddr_t ppage_paddr); 135 136 137 138 /* 139 * In some cases (Page Tables on x86 for example), the physical pages 140 * might contain a set of slots available for "allocation" (x86 141 * example: a PT contains a set of PTE). We provide here a set of 142 * functions to manage a per-page additional counter that holds this 143 * number of slots currently in use in the page. 144 * 145 * A newly allocated physical page has a occupation count of 0. 146 * 147 * The management of this counter is up to the subsystem that manages 148 * the page (mainly: paging), however a simple set of rules applies: 149 * - it can only be incremented/decremented if the page is referenced 150 * - when it reaches 0, no automatic action is undertaken 151 * The first rule means in particular that a page whose reference 152 * count reaches 0 (=> being freed) cannot have a occupation_cnt 153 * value > 0 ! The system will be HALTED if this ever happens 154 */ 155 156 157 /** 158 * Increment the occupation count of the given physical page. 159 * 160 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 161 * 162 * @return TRUE when the occupation count was previously NON-ZERO, FALSE 163 * when this occupation count was 0, <0 when the page address is invalid. 164 * 165 * @note the page MUST be marked as REFERENCED by somebody ! 166 */ 167 sos_ret_t sos_physmem_inc_physpage_occupation(sos_paddr_t ppage_paddr); 168 169 170 /** 171 * Decrement the occupation count of the given physical page. 172 * 173 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 174 * 175 * @return FALSE when the occupation count is still NON-ZERO, TRUE when the 176 * page now is ZERO, <0 when the page address is invalid 177 * 178 * @note the page MUST be marked as REFERENCED by somebody ! 179 */ 180 sos_ret_t sos_physmem_dec_physpage_occupation(sos_paddr_t ppage_paddr); 181 182 183 #include <sos/kmem_vmm.h> 184 185 /** 186 * Return the kernel memory allocation range associated with the given 187 * physical page, or NULL when page has no associated range 188 * 189 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 190 */ 191 struct sos_kmem_range* sos_physmem_get_kmem_range(sos_paddr_t ppage_paddr); 192 193 194 /** 195 * Set the kernel memory allocation range associated to the given 196 * physical page. 197 * 198 * @param ppage_paddr Physical address of the page (MUST be page-aligned) 199 * 200 * @return error if page is invalid 201 */ 202 sos_ret_t sos_physmem_set_kmem_range(sos_paddr_t ppage_paddr, 203 struct sos_kmem_range *range); 204 205 #endif /* _SOS_PHYSMEM_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |