summaryrefslogtreecommitdiff
path: root/sos-code-article6.5/sos/kmem_vmm.h
blob: 49b262dfe0c39f53a05a9f03c05735517cc50f40 (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
/* Copyright (C) 2000 Thomas Petazzoni
   Copyright (C) 2004 David Decotigny

   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_KMEM_VMM_H_
#define _SOS_KMEM_VMM_H_

/**
 * @file kmem_vmm.h
 *
 * Kernel Memory Allocator for multiple-page-sized objects residing in
 * the kernel (virtual memory) space. Relies on the slab cache
 * allocator to allocate its (internal) "range" data structure.
 */

#include <hwcore/paging.h>

/* The base and top virtual addresses covered by the kernel allocator */
#define SOS_KMEM_VMM_BASE 0x4000 /* 16kB */
#define SOS_KMEM_VMM_TOP  SOS_PAGING_MIRROR_VADDR /* 1GB - 4MB */

/** Opaque structure used internally and declared here for physmem.h */
struct sos_kmem_range;

#include <sos/kmem_slab.h>

/**
 * Mark the areas belonging to SOS_KMEM_VMM_BASE and SOS_KMEM_VMM_TOP
 * are either used or free. Those that are already mapped are marked
 * as "used", and the 0..SOS_KMEM_VMM_BASE virtual addresses as marked
 * as "used" too (to detect incorrect pointer dereferences).
 */
sos_ret_t
sos_kmem_vmm_subsystem_setup(sos_vaddr_t kernel_core_base_vaddr,
			     sos_vaddr_t kernel_core_top_vaddr,
			     sos_vaddr_t bootstrap_stack_bottom_vaddr,
			     sos_vaddr_t bootstrap_stack_top_vaddr);


/*
 * Flags for kmem_vmm_new_range and kmem_vmm_alloc
 */
/** Physical pages should be immediately mapped */
#define SOS_KMEM_VMM_MAP    (1<<0)
/** Allocation should either success or fail, without blocking */
#define SOS_KMEM_VMM_ATOMIC (1<<1)

/**
 * Allocate a new kernel area spanning one or multiple pages.
 *
 * @param range_base_vaddr If not NULL, the start address of the range
 * is stored in this location
 * @eturn a new range structure
 */
struct sos_kmem_range *sos_kmem_vmm_new_range(sos_size_t  nb_pages,
					      sos_ui32_t  flags,
					      sos_vaddr_t *range_base_vaddr);
sos_ret_t sos_kmem_vmm_del_range(struct sos_kmem_range *range);


/**
 * Straighforward variant of sos_kmem_vmm_new_range() returning the
 * range's start address instead of the range structure
 */
sos_vaddr_t sos_kmem_vmm_alloc(sos_size_t nb_pages,
			       sos_ui32_t flags);

/**
 * @note you are perfectly allowed to give the address of the
 * kernel image, or the address of the bios area here, it will work:
 * the kernel/bios WILL be "deallocated". But if you really want to do
 * this, well..., do expect some "surprises" ;)
 */
sos_ret_t sos_kmem_vmm_free(sos_vaddr_t vaddr);


/**
 * @return TRUE when vaddr is covered by any (used) kernel range
 */
sos_bool_t sos_kmem_vmm_is_valid_vaddr(sos_vaddr_t vaddr);


/* *****************************
 * Reserved to kmem_slab.c ONLY.
 */
/**
 * Associate the range with the given slab.
 */
sos_ret_t sos_kmem_vmm_set_slab(struct sos_kmem_range *range,
				struct sos_kslab *slab);

/**
 * Retrieve the (used) slab associated with the range covering vaddr.
 *
 * @return NULL if the range is not associated with a KMEM range
 */
struct sos_kslab *sos_kmem_vmm_resolve_slab(sos_vaddr_t vaddr);

#endif /* _SOS_KMEM_VMM_H_ */