summaryrefslogtreecommitdiff
path: root/sos-code-article6.5/sos/physmem.h
blob: 7b4cd2bd92e841911e101db655a3c3ba3af2667d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/* Copyright (C) 2004  David Decotigny
   Copyright (C) 2000  The KOS Team

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   USA. 
*/
#ifndef _SOS_PHYSMEM_H_
#define _SOS_PHYSMEM_H_

/**
 * @file physmem.h
 *
 * Physical pages of memory
 */

#include <sos/errno.h>
#include <sos/types.h>
#include <sos/macros.h>

/** The size of a physical page (arch-dependent) */
#define SOS_PAGE_SIZE  (4*1024)

/** The corresponding shift */
#define SOS_PAGE_SHIFT 12 /* 4 kB = 2^12 B */

/** The corresponding mask */
#define SOS_PAGE_MASK  ((1<<12) - 1)

#define SOS_PAGE_ALIGN_INF(val)  \
  SOS_ALIGN_INF((val), SOS_PAGE_SIZE)
#define SOS_PAGE_ALIGN_SUP(val)  \
  SOS_ALIGN_SUP((val), SOS_PAGE_SIZE)
#define SOS_IS_PAGE_ALIGNED(val) \
  SOS_IS_ALIGNED((val), SOS_PAGE_SIZE)

/**
 * This is the reserved physical interval for the x86 video memory and
 * BIOS area. In physmem.c, we have to mark this area as "used" in
 * order to prevent from allocating it. And in paging.c, we'd better
 * map it in virtual space if we really want to be able to print to
 * the screen (for debugging purpose, at least): for this, the
 * simplest is to identity-map this area in virtual space (note
 * however that this mapping could also be non-identical).
 */
#define BIOS_N_VIDEO_START 0xa0000
#define BIOS_N_VIDEO_END   0x100000


/**
 * Initialize the physical memory subsystem, for the physical area [0,
 * ram_size). This routine takes into account the BIOS and video
 * areas, to prevent them from future allocations.
 *
 * @param ram_size The size of the RAM that will be managed by this subsystem
 *
 * @param kernel_core_base The lowest address for which the kernel
 * assumes identity mapping (ie virtual address == physical address)
 * will be stored here
 *
 * @param kernel_core_top The top address for which the kernel
 * assumes identity mapping (ie virtual address == physical address)
 * will be stored here
 */
sos_ret_t sos_physmem_subsystem_setup(sos_size_t ram_size,
				      /* out */sos_paddr_t *kernel_core_base,
				      /* out */sos_paddr_t *kernel_core_top);

/**
 * Retrieve the total number of pages, and the number of free pages
 */
sos_ret_t sos_physmem_get_state(/* out */sos_count_t *total_ppages,
				/* out */sos_count_t *used_ppages);


/**
 * Get a free page.
 *
 * @return The (physical) address of the (physical) page allocated, or
 * NULL when none currently available.
 *
 * @param can_block TRUE if the function is allowed to block
 * @note The page returned has a reference count equal to 1.
 */
sos_paddr_t sos_physmem_ref_physpage_new(sos_bool_t can_block);


/**
 * Increment the reference count of a given physical page. Useful for
 * VM code which tries to map a precise physical address.
 *
 * @param ppage_paddr Physical address of the page (MUST be page-aligned)
 *
 * @return TRUE when the page was previously in use, FALSE when the
 * page was previously in the free list, <0 when the page address is
 * invalid.
 */
sos_ret_t sos_physmem_ref_physpage_at(sos_paddr_t ppage_paddr);


/**
 * Decrement the reference count of the given physical page. When this
 * reference count reaches 0, the page is marked free, ie is available
 * for future sos_physmem_get_physpage()
 *
 * @param ppage_paddr Physical address of the page (MUST be page-aligned)
 *
 * @return FALSE when the page is still in use, TRUE when the page is now
 * unreferenced, <0 when the page address is invalid
 */
sos_ret_t sos_physmem_unref_physpage(sos_paddr_t ppage_paddr);


#include <sos/kmem_vmm.h>

/**
 * Return the kernel memory allocation range associated with the given
 * physical page, or NULL when page has no associated range
 *
 * @param ppage_paddr Physical address of the page (MUST be page-aligned)
 */
struct sos_kmem_range* sos_physmem_get_kmem_range(sos_paddr_t ppage_paddr);


/**
 * Set the kernel memory allocation range associated to the given
 * physical page.
 *
 * @param ppage_paddr Physical address of the page (MUST be page-aligned)
 *
 * @return error if page is invalid
 */
sos_ret_t sos_physmem_set_kmem_range(sos_paddr_t ppage_paddr,
				     struct sos_kmem_range *range);

#endif /* _SOS_PHYSMEM_H_ */