1 | /*
|
---|
2 | * Custom 32 bits stack management
|
---|
3 | *
|
---|
4 | * (C) 2000-2002 InnoTek Systemberatung GmbH
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or
|
---|
7 | * modify it under the terms of the GNU General Public License as
|
---|
8 | * published by the Free Software Foundation; either version 2 of
|
---|
9 | * the License, or (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public
|
---|
17 | * License along with this program; if not, write to the Free
|
---|
18 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
|
---|
19 | * USA.
|
---|
20 | */
|
---|
21 |
|
---|
22 | #define INCL_NOPMAPI
|
---|
23 | #define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION
|
---|
24 | #include <os2.h>
|
---|
25 | #include <devhelp.h>
|
---|
26 | #include <ossidc.h>
|
---|
27 | #include <dbgos2.h>
|
---|
28 | #include <stacktoflat.h>
|
---|
29 | #ifdef KEE
|
---|
30 | #include <kee.h>
|
---|
31 | #endif
|
---|
32 |
|
---|
33 | #define MAX_STACK 16
|
---|
34 | #define STACKSIZE (16*1024)
|
---|
35 | #define TOTAL_STACKSIZE MAX_STACK*(16*1024)
|
---|
36 | #define MAX_STACK_SEL TOTAL_STACKSIZE/(64*1024)
|
---|
37 |
|
---|
38 | #define STACK_FREE 0
|
---|
39 | #define STACK_USED 1
|
---|
40 |
|
---|
41 | typedef struct {
|
---|
42 | int state;
|
---|
43 | LINEAR addr;
|
---|
44 | SEL sel;
|
---|
45 | } PDDStack;
|
---|
46 |
|
---|
47 | static PDDStack Ring0Stack[MAX_STACK] = {0};
|
---|
48 | static SEL Ring0StackSel[MAX_STACK_SEL] = {0};
|
---|
49 | static LINEAR StackBase = NULL;
|
---|
50 | static BOOL fInitialized = FALSE;
|
---|
51 |
|
---|
52 | //*********************************************************************************************
|
---|
53 | //StackAlloc:
|
---|
54 | //
|
---|
55 | // Allocate stack when called the first time;
|
---|
56 | // Return private stack base
|
---|
57 | //
|
---|
58 | // NOTE: Stack is 16 bits when called
|
---|
59 | //*********************************************************************************************
|
---|
60 | DWORD StackAlloc();
|
---|
61 | #pragma aux StackAlloc "StackAlloc";
|
---|
62 | DWORD StackAlloc()
|
---|
63 | {
|
---|
64 | int i;
|
---|
65 | DWORD cpuflags;
|
---|
66 | APIRET rc;
|
---|
67 | SEL gdts[MAX_STACK_SEL];
|
---|
68 | SEL FAR48 *gdt;
|
---|
69 |
|
---|
70 | cpuflags = DevPushfCli();
|
---|
71 |
|
---|
72 | if(fInitialized == FALSE) {
|
---|
73 | fInitialized = TRUE;
|
---|
74 |
|
---|
75 | //allocate our private stack
|
---|
76 | rc = DevVMAlloc(VMDHA_USEHIGHMEM|VMDHA_FIXED|VMDHL_CONTIGUOUS, TOTAL_STACKSIZE, (LINEAR)-1, (LINEAR)&StackBase);
|
---|
77 |
|
---|
78 | if(rc) {
|
---|
79 | if (rc == 87)
|
---|
80 | {
|
---|
81 | rc = DevVMAlloc(VMDHA_FIXED|VMDHL_CONTIGUOUS, TOTAL_STACKSIZE, (LINEAR)-1, (LINEAR)&StackBase);
|
---|
82 | }
|
---|
83 | if (rc)
|
---|
84 | {
|
---|
85 | DebugInt3();
|
---|
86 | return 0;
|
---|
87 | }
|
---|
88 | }
|
---|
89 | Ring0Stack[0].addr = StackBase;
|
---|
90 |
|
---|
91 | //allocate GDT selectors (so we can map a flat stack address to a 16:16 pointer)
|
---|
92 | rc = DevAllocGDTSel(MAKE_FARPTR16_STACK((LINEAR)&gdts[0]), MAX_STACK_SEL);
|
---|
93 | if(rc) {
|
---|
94 | DebugInt3();
|
---|
95 | return 0;
|
---|
96 | }
|
---|
97 | //and map linear stack addresses to GDT selectors
|
---|
98 | for(i=0;i<MAX_STACK_SEL;i++) {
|
---|
99 | LINEAR addr = (LINEAR)StackBase + i*64*1024;
|
---|
100 |
|
---|
101 | gdt = (SEL FAR48 *)MAKE_FARPTR32_STACK((LINEAR)&gdts[i]);
|
---|
102 | if(DevHelp_LinToGDTSelector(*gdt, addr, 64*1024)) {
|
---|
103 | DebugInt3();
|
---|
104 | return 0;
|
---|
105 | }
|
---|
106 | Ring0StackSel[i] = *gdt;
|
---|
107 | }
|
---|
108 |
|
---|
109 | for(i=0;i<MAX_STACK;i++) {
|
---|
110 | Ring0Stack[i].addr = StackBase + i*STACKSIZE;
|
---|
111 | Ring0Stack[i].sel = Ring0StackSel[i*STACKSIZE/(64*1024)];
|
---|
112 | }
|
---|
113 | }
|
---|
114 |
|
---|
115 | for(i=0;i<MAX_STACK;i++) {
|
---|
116 | if(Ring0Stack[i].state == STACK_FREE) {
|
---|
117 | Ring0Stack[i].state = STACK_USED;
|
---|
118 | DevPopf(cpuflags);
|
---|
119 | return (ULONG)(Ring0Stack[i].addr + STACKSIZE);
|
---|
120 | }
|
---|
121 | }
|
---|
122 | DevPopf(cpuflags);
|
---|
123 | DebugInt3(); //oh, oh!!
|
---|
124 | return 0;
|
---|
125 | }
|
---|
126 | //*********************************************************************************************
|
---|
127 | //*********************************************************************************************
|
---|
128 | void StackFree(DWORD stackaddr);
|
---|
129 | #pragma aux StackFree "StackFree" parm [eax];
|
---|
130 | void StackFree(DWORD stackaddr)
|
---|
131 | {
|
---|
132 | int i;
|
---|
133 | DWORD cpuflags;
|
---|
134 |
|
---|
135 | cpuflags = DevPushfCli();
|
---|
136 |
|
---|
137 | stackaddr -= STACKSIZE;
|
---|
138 | for(i=0;i<MAX_STACK;i++) {
|
---|
139 | if(Ring0Stack[i].addr == (LINEAR)stackaddr) {
|
---|
140 | Ring0Stack[i].state = STACK_FREE;
|
---|
141 | DevPopf(cpuflags);
|
---|
142 | return;
|
---|
143 | }
|
---|
144 | }
|
---|
145 | DevPopf(cpuflags);
|
---|
146 | DebugInt3();
|
---|
147 | }
|
---|
148 | //*********************************************************************************************
|
---|
149 | // FlatToSel:
|
---|
150 | // Convert a flat stack address to a 16:16 address
|
---|
151 | //
|
---|
152 | //*********************************************************************************************
|
---|
153 | ULONG FlatToSel(ULONG addr32)
|
---|
154 | {
|
---|
155 | ULONG offset;
|
---|
156 |
|
---|
157 | offset = addr32 - (ULONG)StackBase;
|
---|
158 |
|
---|
159 | if(offset > TOTAL_STACKSIZE) {
|
---|
160 | //bad boy!
|
---|
161 | DebugInt3();
|
---|
162 | return 0;
|
---|
163 | }
|
---|
164 |
|
---|
165 | return MAKE_FP16(Ring0StackSel[offset/(64*1024)], offset);
|
---|
166 | }
|
---|
167 | //*********************************************************************************************
|
---|
168 | //*********************************************************************************************
|
---|
169 |
|
---|