aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/i386/transitions/librm_mgmt.c
blob: bfe963d4196c2f470f17e654b871e5a46281c5c7 (plain)
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
/*
 * librm: a library for interfacing to real-mode code
 *
 * Michael Brown <mbrown@fensystems.co.uk>
 *
 */

#ifdef KEEP_IT_REAL
/* Build a null object under -DKEEP_IT_REAL */
#else

#include "stdint.h"
#include "stddef.h"
#include "string.h"
#include "librm.h"

/*
 * This file provides functions for managing librm.
 *
 */

/* Current location of librm in base memory */
char *installed_librm = librm;

/*
 * Install librm to base memory
 *
 */
void install_librm ( void *addr ) {
	memcpy ( addr, librm, librm_size );
	installed_librm = addr;
}

/*
 * Increment lock count of librm
 *
 */
void lock_librm ( void ) {
	inst_librm_ref_count++;
}

/*
 * Decrement lock count of librm
 *
 */
void unlock_librm ( void ) {
#ifdef DEBUG_LIBRM
	if ( inst_librm_ref_count == 0 ) {
		printf ( "librm: ref count gone negative\n" );
		lockup();
	}
#endif
	inst_librm_ref_count--;
}

/*
 * Allocate space on the real-mode stack and copy data there.
 *
 */
uint16_t copy_to_rm_stack ( void *data, size_t size ) {
#ifdef DEBUG_LIBRM
	if ( inst_rm_stack.offset <= size ) {
		printf ( "librm: out of space in RM stack\n" );
		lockup();
	}
#endif
	inst_rm_stack.offset -= size;
	copy_to_real ( inst_rm_stack.segment, inst_rm_stack.offset,
		       data, size );
	return inst_rm_stack.offset;
};

/*
 * Deallocate space on the real-mode stack, optionally copying back
 * data.
 *
 */
void remove_from_rm_stack ( void *data, size_t size ) {
	if ( data ) {
		copy_from_real ( data,
				 inst_rm_stack.segment, inst_rm_stack.offset,
				 size );
	}
	inst_rm_stack.offset += size;
};

#endif /* KEEP_IT_REAL */