Browse Source

Add INIT_FNs to make sure that librm gets reallocated when needed.

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
6a4ac358f3
1 changed files with 109 additions and 29 deletions
  1. 109
    29
      src/arch/i386/transitions/librm_mgmt.c

+ 109
- 29
src/arch/i386/transitions/librm_mgmt.c View File

@@ -12,6 +12,8 @@
12 12
 #include "stdint.h"
13 13
 #include "stddef.h"
14 14
 #include "string.h"
15
+#include "init.h"
16
+#include "basemem.h"
15 17
 #include "librm.h"
16 18
 
17 19
 /*
@@ -21,37 +23,14 @@
21 23
 
22 24
 /* Current location of librm in base memory */
23 25
 char *installed_librm = librm;
26
+static uint32_t installed_librm_phys;
24 27
 
25
-/*
26
- * Install librm to base memory
27
- *
28
+/* Whether or not we have base memory currently allocated for librm.
29
+ * Note that we *can* have a working librm present in unallocated base
30
+ * memory; this is the situation at startup for all real-mode
31
+ * prefixes.
28 32
  */
29
-void install_librm ( void *addr ) {
30
-	memcpy ( addr, librm, librm_size );
31
-	installed_librm = addr;
32
-}
33
-
34
-/*
35
- * Increment lock count of librm
36
- *
37
- */
38
-void lock_librm ( void ) {
39
-	inst_librm_ref_count++;
40
-}
41
-
42
-/*
43
- * Decrement lock count of librm
44
- *
45
- */
46
-void unlock_librm ( void ) {
47
-#ifdef DEBUG_LIBRM
48
-	if ( inst_librm_ref_count == 0 ) {
49
-		printf ( "librm: ref count gone negative\n" );
50
-		lockup();
51
-	}
52
-#endif
53
-	inst_librm_ref_count--;
54
-}
33
+static int allocated_librm = 0;
55 34
 
56 35
 /*
57 36
  * Allocate space on the real-mode stack and copy data there.
@@ -84,4 +63,105 @@ void remove_from_rm_stack ( void *data, size_t size ) {
84 63
 	inst_rm_stack.offset += size;
85 64
 };
86 65
 
66
+/*
67
+ * Install librm to base memory
68
+ *
69
+ */
70
+static inline void install_librm ( char *addr ) {
71
+	memcpy ( addr, librm, librm_size );
72
+	installed_librm = addr;
73
+}
74
+
75
+/*
76
+ * Uninstall librm from base memory.  This copies librm back to the
77
+ * "master" copy, so that it can be reinstalled to a new location,
78
+ * preserving the values for rm_ss and rm_sp from the old installed
79
+ * copy.
80
+ *
81
+ */
82
+static inline void uninstall_librm ( void ) {
83
+	memcpy ( librm, installed_librm, librm_size );
84
+}
85
+
86
+/*
87
+ * On entry, record the physical location of librm.  Do this so that
88
+ * we can update installed_librm after relocation.
89
+ *
90
+ * Doing this is probably more efficient than making installed_librm
91
+ * be a physical address, because of the number of times that
92
+ * installed_librm gets referenced in the remainder of the code.
93
+ *
94
+ */
95
+static void librm_init ( void ) {
96
+	installed_librm_phys = virt_to_phys ( installed_librm );
97
+}
98
+
99
+/*
100
+ * On exit, we want to leave a copy of librm in *unallocated* base
101
+ * memory.  It must be there so that we can exit via a 16-bit exit
102
+ * path, but it must not be allocated because nothing will ever
103
+ * deallocate it once we exit.
104
+ *
105
+ */
106
+static void librm_exit ( void ) {
107
+	/* Free but do not zero the base memory */
108
+	if ( allocated_librm ) {
109
+		free_base_memory ( installed_librm, librm_size );
110
+		allocated_librm = 0;
111
+	}
112
+}
113
+
114
+/*
115
+ * On reset, we want to free up our old installed copy of librm, if
116
+ * any, then allocate a new base memory block and install there.
117
+ *
118
+ */
119
+
120
+static void librm_reset ( void ) {
121
+	char *new_librm;
122
+
123
+	/* Point installed_librm back at last known physical location */
124
+	installed_librm = phys_to_virt ( installed_librm_phys );
125
+
126
+	/* Uninstall old librm */
127
+	uninstall_librm();
128
+
129
+	/* Free allocated base memory, if applicable */
130
+	librm_exit();
131
+
132
+	/* Allocate space for new librm */
133
+	new_librm = alloc_base_memory ( librm_size );
134
+	allocated_librm = 1;
135
+
136
+	/* Install new librm */
137
+	install_librm ( new_librm );
138
+}
139
+
140
+INIT_FN ( INIT_LIBRM, librm_init, librm_reset, librm_exit );
141
+
142
+
143
+
144
+
145
+/*
146
+ * Increment lock count of librm
147
+ *
148
+ */
149
+void lock_librm ( void ) {
150
+	inst_librm_ref_count++;
151
+}
152
+
153
+/*
154
+ * Decrement lock count of librm
155
+ *
156
+ */
157
+void unlock_librm ( void ) {
158
+#ifdef DEBUG_LIBRM
159
+	if ( inst_librm_ref_count == 0 ) {
160
+		printf ( "librm: ref count gone negative\n" );
161
+		lockup();
162
+	}
163
+#endif
164
+	inst_librm_ref_count--;
165
+}
166
+
87 167
 #endif /* KEEP_IT_REAL */

Loading…
Cancel
Save