source: GPL/trunk/lib32/stack.cpp@ 76

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

Latest ALSA patches
HDA patches
Patch for Intel from Rudy's
Fixes locks on NM256 chipsets
Fixes PM on Maestro3 chipsets

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 8
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.