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