source: GPL/branches/uniaud-2.0/lib32/stack.cpp@ 304

Last change on this file since 304 was 84, checked in by vladest, 19 years ago

SB code update
HDA code update
Some other updates

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
22extern "C" {
23#define INCL_NOPMAPI
24#define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION
25#include <os2.h>
26}
27#include <devhelp.h>
28#include <ossidc.h>
29#include <dbgos2.h>
30#include <stacktoflat.h>
31#ifdef KEE
32#include <kee.h>
33#endif
34
35#define MAX_STACK 16
36#define STACKSIZE (16*1024)
37#define TOTAL_STACKSIZE MAX_STACK*(16*1024)
38#define MAX_STACK_SEL TOTAL_STACKSIZE/(64*1024)
39
40#define STACK_FREE 0
41#define STACK_USED 1
42
43typedef struct {
44 int state;
45 LINEAR addr;
46 SEL sel;
47} PDDStack;
48
49static PDDStack Ring0Stack[MAX_STACK] = {0};
50static SEL Ring0StackSel[MAX_STACK_SEL] = {0};
51static LINEAR StackBase = NULL;
52static BOOL fInitialized = FALSE;
53
54//*********************************************************************************************
55//StackAlloc:
56//
57// Allocate stack when called the first time;
58// Return private stack base
59//
60// NOTE: Stack is 16 bits when called
61//*********************************************************************************************
62DWORD StackAlloc();
63#pragma aux StackAlloc "StackAlloc";
64DWORD StackAlloc()
65{
66 int i;
67 DWORD cpuflags;
68 APIRET rc;
69 SEL gdts[MAX_STACK_SEL];
70 SEL FAR48 *gdt;
71
72 cpuflags = DevPushfCli();
73
74 if(fInitialized == FALSE) {
75 fInitialized = TRUE;
76
77 //allocate our private stack
78 rc = DevVMAlloc(VMDHA_USEHIGHMEM|VMDHA_FIXED|VMDHL_CONTIGUOUS, TOTAL_STACKSIZE, (LINEAR)-1, (LINEAR)&StackBase);
79
80 if(rc) {
81 if (rc == 87)
82 {
83 rc = DevVMAlloc(VMDHA_FIXED|VMDHL_CONTIGUOUS, TOTAL_STACKSIZE, (LINEAR)-1, (LINEAR)&StackBase);
84 }
85 if (rc)
86 {
87 DebugInt3();
88 return 0;
89 }
90 }
91 Ring0Stack[0].addr = StackBase;
92
93 //allocate GDT selectors (so we can map a flat stack address to a 16:16 pointer)
94 rc = DevAllocGDTSel(MAKE_FARPTR16_STACK((LINEAR)&gdts[0]), MAX_STACK_SEL);
95 if(rc) {
96 DebugInt3();
97 return 0;
98 }
99 //and map linear stack addresses to GDT selectors
100 for(i=0;i<MAX_STACK_SEL;i++) {
101 LINEAR addr = (LINEAR)StackBase + i*64*1024;
102
103 gdt = (SEL FAR48 *)MAKE_FARPTR32_STACK((LINEAR)&gdts[i]);
104 if(DevHelp_LinToGDTSelector(*gdt, addr, 64*1024)) {
105 DebugInt3();
106 return 0;
107 }
108 Ring0StackSel[i] = *gdt;
109 }
110
111 for(i=0;i<MAX_STACK;i++) {
112 Ring0Stack[i].addr = StackBase + i*STACKSIZE;
113 Ring0Stack[i].sel = Ring0StackSel[i*STACKSIZE/(64*1024)];
114 }
115 }
116
117 for(i=0;i<MAX_STACK;i++) {
118 if(Ring0Stack[i].state == STACK_FREE) {
119 Ring0Stack[i].state = STACK_USED;
120 DevPopf(cpuflags);
121 return (ULONG)(Ring0Stack[i].addr + STACKSIZE);
122 }
123 }
124 DevPopf(cpuflags);
125 DebugInt3(); //oh, oh!!
126 return 0;
127}
128//*********************************************************************************************
129//*********************************************************************************************
130void StackFree(DWORD stackaddr);
131#pragma aux StackFree "StackFree" parm [eax];
132void StackFree(DWORD stackaddr)
133{
134 int i;
135 DWORD cpuflags;
136
137 cpuflags = DevPushfCli();
138
139 stackaddr -= STACKSIZE;
140 for(i=0;i<MAX_STACK;i++) {
141 if(Ring0Stack[i].addr == (LINEAR)stackaddr) {
142 Ring0Stack[i].state = STACK_FREE;
143 DevPopf(cpuflags);
144 return;
145 }
146 }
147 DevPopf(cpuflags);
148 DebugInt3();
149}
150//*********************************************************************************************
151// FlatToSel:
152// Convert a flat stack address to a 16:16 address
153//
154//*********************************************************************************************
155ULONG FlatToSel(ULONG addr32)
156{
157 ULONG offset;
158
159 offset = addr32 - (ULONG)StackBase;
160
161 if(offset > TOTAL_STACKSIZE) {
162 //bad boy!
163 DebugInt3();
164 return 0;
165 }
166
167 return MAKE_FP16(Ring0StackSel[offset/(64*1024)], offset);
168}
169//*********************************************************************************************
170//*********************************************************************************************
171
Note: See TracBrowser for help on using the repository browser.