source: GPL/branches/uniaud32-next/lib32/stack.c@ 660

Last change on this file since 660 was 587, checked in by David Azarewicz, 9 years ago

Rearrange directory structure
rework makefiles
cleanup files

File size: 5.1 KB
Line 
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
41typedef struct {
42 int state;
43 LINEAR addr;
44 SEL sel;
45} PDDStack;
46
47static PDDStack Ring0Stack[MAX_STACK] = {0};
48static SEL Ring0StackSel[MAX_STACK_SEL] = {0};
49static LINEAR StackBase = NULL;
50static 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//*********************************************************************************************
60DWORD StackAlloc();
61#pragma aux StackAlloc "StackAlloc";
62DWORD 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//*********************************************************************************************
128void StackFree(DWORD stackaddr);
129#pragma aux StackFree "StackFree" parm [eax];
130void 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//*********************************************************************************************
153ULONG 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
Note: See TracBrowser for help on using the repository browser.