···11-/*
22- * FreeLoader
33- *
44- * Copyright (C) 2003 Eric Kohl
55- *
66- * This program is free software; you can redistribute it and/or modify
77- * it under the terms of the GNU General Public License as published by
88- * the Free Software Foundation; either version 2 of the License, or
99- * (at your option) any later version.
1010- *
1111- * This program is distributed in the hope that it will be useful,
1212- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1313- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414- * GNU General Public License for more details.
1515- *
1616- * You should have received a copy of the GNU General Public License along
1717- * with this program; if not, write to the Free Software Foundation, Inc.,
1818- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1919- */
2020-2121-#pragma once
2222-2323-#ifndef __REGISTRY_H
2424-#include "../../reactos/registry.h"
2525-#endif
2626-2727-/* PROTOTYPES ***************************************************************/
2828-2929-/* hardware.c */
3030-3131-VOID StallExecutionProcessor(ULONG Microseconds);
3232-3333-VOID HalpCalibrateStallExecution(VOID);
3434-3535-ULONGLONG RDTSC(VOID);
3636-3737-/* EOF */
-16
boot/freeldr/freeldr/include/of.h
···11-#pragma once
22-33-#define OF_FAILED 0
44-#define ERR_NOT_FOUND 0xc0000010
55-66-#include "of_call.h"
77-#include <string.h>
88-99-typedef int (*of_proxy)
1010- ( int table_off, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5, void *arg6 );
1111-typedef long jmp_buf[100];
1212-extern of_proxy ofproxy;
1313-1414-int setjmp( jmp_buf buf );
1515-int longjmp( jmp_buf buf, int retval );
1616-int ofw_callmethod_ret(const char *method, int handle, int nargs, int *args, int ret);
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * FILE: hal/halppc/generic/beep.c
55- * PURPOSE: Speaker function (it's only one)
66- * PROGRAMMER: Eric Kohl
77- * UPDATE HISTORY:
88- * Created 31/01/99
99- */
1010-1111-/* INCLUDES *****************************************************************/
1212-1313-#include <hal.h>
1414-#define NDEBUG
1515-#include <debug.h>
1616-1717-1818-/* CONSTANTS *****************************************************************/
1919-2020-#define TIMER2 0x42
2121-#define TIMER3 0x43
2222-#define PORT_B 0x61
2323-#define CLOCKFREQ 1193167
2424-2525-2626-/* FUNCTIONS *****************************************************************/
2727-/*
2828- * FUNCTION: Beeps the speaker.
2929- * ARGUMENTS:
3030- * Frequency = If 0, the speaker will be switched off, otherwise
3131- * the speaker beeps with the specified frequency.
3232- */
3333-3434-BOOLEAN
3535-NTAPI
3636-HalMakeBeep (
3737- ULONG Frequency
3838- )
3939-{
4040- return TRUE;
4141-}
4242-
-356
hal/halppc/generic/bus.c
···11-/*
22- * PROJECT: ReactOS HAL
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: hal/halppc/generic/bus.c
55- * PURPOSE: Bus Support Routines
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- */
88-99-/* INCLUDES ******************************************************************/
1010-1111-#include <hal.h>
1212-#define NDEBUG
1313-#include <debug.h>
1414-1515-/* GLOBALS *******************************************************************/
1616-1717-ULONG HalpBusType;
1818-1919-/* PRIVATE FUNCTIONS *********************************************************/
2020-2121-VOID
2222-NTAPI
2323-HalpRegisterKdSupportFunctions(VOID)
2424-{
2525- /* Register PCI Device Functions */
2626- KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging;
2727- KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging;
2828-2929- /* Register memory functions */
3030- KdMapPhysicalMemory64 = HalpMapPhysicalMemory64;
3131- KdUnmapVirtualAddress = HalpUnmapVirtualAddress;
3232-3333- /* Register ACPI stub */
3434- KdCheckPowerButton = HalpCheckPowerButton;
3535-}
3636-3737-NTSTATUS
3838-NTAPI
3939-HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath,
4040- IN PUNICODE_STRING DriverClassName,
4141- IN PDRIVER_OBJECT DriverObject,
4242- IN PDEVICE_OBJECT DeviceObject,
4343- IN INTERFACE_TYPE BusType,
4444- IN ULONG BusNumber,
4545- IN ULONG SlotNumber,
4646- IN OUT PCM_RESOURCE_LIST *AllocatedResources)
4747-{
4848- BUS_HANDLER BusHandler;
4949- PAGED_CODE();
5050-5151- /* Only PCI is supported */
5252- if (BusType != PCIBus) return STATUS_NOT_IMPLEMENTED;
5353-5454- /* Setup fake PCI Bus handler */
5555- RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
5656- BusHandler.BusNumber = BusNumber;
5757-5858- /* Call the PCI function */
5959- return HalpAssignPCISlotResources(&BusHandler,
6060- &BusHandler,
6161- RegistryPath,
6262- DriverClassName,
6363- DriverObject,
6464- DeviceObject,
6565- SlotNumber,
6666- AllocatedResources);
6767-}
6868-6969-BOOLEAN
7070-NTAPI
7171-HalpTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
7272- IN ULONG BusNumber,
7373- IN PHYSICAL_ADDRESS BusAddress,
7474- IN OUT PULONG AddressSpace,
7575- OUT PPHYSICAL_ADDRESS TranslatedAddress)
7676-{
7777- /* Translation is easy */
7878- TranslatedAddress->QuadPart = BusAddress.QuadPart;
7979- return TRUE;
8080-}
8181-8282-ULONG
8383-NTAPI
8484-HalpGetSystemInterruptVector(IN ULONG BusNumber,
8585- IN ULONG BusInterruptLevel,
8686- IN ULONG BusInterruptVector,
8787- OUT PKIRQL Irql,
8888- OUT PKAFFINITY Affinity)
8989-{
9090- ULONG Vector = IRQ2VECTOR(BusInterruptLevel);
9191- *Irql = (KIRQL)VECTOR2IRQL(Vector);
9292- *Affinity = 0xFFFFFFFF;
9393- return Vector;
9494-}
9595-9696-BOOLEAN
9797-NTAPI
9898-HalpFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress,
9999- IN OUT PULONG AddressSpace,
100100- OUT PPHYSICAL_ADDRESS TranslatedAddress,
101101- IN OUT PULONG_PTR Context,
102102- IN BOOLEAN NextBus)
103103-{
104104- /* Make sure we have a context */
105105- if (!Context) return FALSE;
106106-107107- /* If we have data in the context, then this shouldn't be a new lookup */
108108- if ((*Context != 0) && (NextBus != FALSE)) return FALSE;
109109-110110- /* Return bus data */
111111- TranslatedAddress->QuadPart = BusAddress.QuadPart;
112112-113113- /* Set context value and return success */
114114- *Context = 1;
115115- return TRUE;
116116-}
117117-118118-VOID
119119-NTAPI
120120-HalpInitNonBusHandler(VOID)
121121-{
122122- /* These should be written by the PCI driver later, but we give defaults */
123123- HalPciTranslateBusAddress = HalpTranslateBusAddress;
124124- HalPciAssignSlotResources = HalpAssignSlotResources;
125125- HalFindBusAddressTranslation = HalpFindBusAddressTranslation;
126126-}
127127-128128-/* PUBLIC FUNCTIONS **********************************************************/
129129-130130-/*
131131- * @implemented
132132- */
133133-NTSTATUS
134134-NTAPI
135135-HalAdjustResourceList(IN PCM_RESOURCE_LIST Resources)
136136-{
137137- /* Deprecated, return success */
138138- return STATUS_SUCCESS;
139139-}
140140-141141-/*
142142- * @implemented
143143- */
144144-NTSTATUS
145145-NTAPI
146146-HalAssignSlotResources(IN PUNICODE_STRING RegistryPath,
147147- IN PUNICODE_STRING DriverClassName,
148148- IN PDRIVER_OBJECT DriverObject,
149149- IN PDEVICE_OBJECT DeviceObject,
150150- IN INTERFACE_TYPE BusType,
151151- IN ULONG BusNumber,
152152- IN ULONG SlotNumber,
153153- IN OUT PCM_RESOURCE_LIST *AllocatedResources)
154154-{
155155- /* Check the bus type */
156156- if (BusType != PCIBus)
157157- {
158158- /* Call our internal handler */
159159- return HalpAssignSlotResources(RegistryPath,
160160- DriverClassName,
161161- DriverObject,
162162- DeviceObject,
163163- BusType,
164164- BusNumber,
165165- SlotNumber,
166166- AllocatedResources);
167167- }
168168- else
169169- {
170170- /* Call the PCI registered function */
171171- return HalPciAssignSlotResources(RegistryPath,
172172- DriverClassName,
173173- DriverObject,
174174- DeviceObject,
175175- PCIBus,
176176- BusNumber,
177177- SlotNumber,
178178- AllocatedResources);
179179- }
180180-}
181181-182182-/*
183183- * @implemented
184184- */
185185-ULONG
186186-NTAPI
187187-HalGetBusData(IN BUS_DATA_TYPE BusDataType,
188188- IN ULONG BusNumber,
189189- IN ULONG SlotNumber,
190190- IN PVOID Buffer,
191191- IN ULONG Length)
192192-{
193193- /* Call the extended function */
194194- return HalGetBusDataByOffset(BusDataType,
195195- BusNumber,
196196- SlotNumber,
197197- Buffer,
198198- 0,
199199- Length);
200200-}
201201-202202-/*
203203- * @implemented
204204- */
205205-ULONG
206206-NTAPI
207207-HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
208208- IN ULONG BusNumber,
209209- IN ULONG SlotNumber,
210210- IN PVOID Buffer,
211211- IN ULONG Offset,
212212- IN ULONG Length)
213213-{
214214- BUS_HANDLER BusHandler;
215215-216216- /* Look as the bus type */
217217- if (BusDataType == Cmos)
218218- {
219219- /* Call CMOS Function */
220220- return HalpGetCmosData(0, SlotNumber, Buffer, Length);
221221- }
222222- else if (BusDataType == EisaConfiguration)
223223- {
224224- /* FIXME: TODO */
225225- ASSERT(FALSE);
226226- }
227227- else if ((BusDataType == PCIConfiguration) &&
228228- (HalpPCIConfigInitialized) &&
229229- ((BusNumber >= HalpMinPciBus) && (BusNumber <= HalpMaxPciBus)))
230230- {
231231- /* Setup fake PCI Bus handler */
232232- RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
233233- BusHandler.BusNumber = BusNumber;
234234-235235- /* Call PCI function */
236236- return HalpGetPCIData(&BusHandler,
237237- &BusHandler,
238238- *(PPCI_SLOT_NUMBER)&SlotNumber,
239239- Buffer,
240240- Offset,
241241- Length);
242242- }
243243-244244- /* Invalid bus */
245245- return 0;
246246-}
247247-248248-/*
249249- * @implemented
250250- */
251251-ULONG
252252-NTAPI
253253-HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType,
254254- IN ULONG BusNumber,
255255- IN ULONG BusInterruptLevel,
256256- IN ULONG BusInterruptVector,
257257- OUT PKIRQL Irql,
258258- OUT PKAFFINITY Affinity)
259259-{
260260- /* Call the system bus translator */
261261- return HalpGetSystemInterruptVector(BusNumber,
262262- BusInterruptLevel,
263263- BusInterruptVector,
264264- Irql,
265265- Affinity);
266266-}
267267-268268-/*
269269- * @implemented
270270- */
271271-ULONG
272272-NTAPI
273273-HalSetBusData(IN BUS_DATA_TYPE BusDataType,
274274- IN ULONG BusNumber,
275275- IN ULONG SlotNumber,
276276- IN PVOID Buffer,
277277- IN ULONG Length)
278278-{
279279- /* Call the extended function */
280280- return HalSetBusDataByOffset(BusDataType,
281281- BusNumber,
282282- SlotNumber,
283283- Buffer,
284284- 0,
285285- Length);
286286-}
287287-288288-/*
289289- * @implemented
290290- */
291291-ULONG
292292-NTAPI
293293-HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
294294- IN ULONG BusNumber,
295295- IN ULONG SlotNumber,
296296- IN PVOID Buffer,
297297- IN ULONG Offset,
298298- IN ULONG Length)
299299-{
300300- BUS_HANDLER BusHandler;
301301-302302- /* Look as the bus type */
303303- if (BusDataType == Cmos)
304304- {
305305- /* Call CMOS Function */
306306- return HalpSetCmosData(0, SlotNumber, Buffer, Length);
307307- }
308308- else if ((BusDataType == PCIConfiguration) && (HalpPCIConfigInitialized))
309309- {
310310- /* Setup fake PCI Bus handler */
311311- RtlCopyMemory(&BusHandler, &HalpFakePciBusHandler, sizeof(BUS_HANDLER));
312312- BusHandler.BusNumber = BusNumber;
313313-314314- /* Call PCI function */
315315- return HalpSetPCIData(&BusHandler,
316316- &BusHandler,
317317- *(PPCI_SLOT_NUMBER)&SlotNumber,
318318- Buffer,
319319- Offset,
320320- Length);
321321- }
322322-323323- /* Invalid bus */
324324- return 0;
325325-}
326326-327327-/*
328328- * @implemented
329329- */
330330-BOOLEAN
331331-NTAPI
332332-HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
333333- IN ULONG BusNumber,
334334- IN PHYSICAL_ADDRESS BusAddress,
335335- IN OUT PULONG AddressSpace,
336336- OUT PPHYSICAL_ADDRESS TranslatedAddress)
337337-{
338338- /* Look as the bus type */
339339- if (InterfaceType == PCIBus)
340340- {
341341- /* Call the PCI registered function */
342342- return HalPciTranslateBusAddress(PCIBus,
343343- BusNumber,
344344- BusAddress,
345345- AddressSpace,
346346- TranslatedAddress);
347347- }
348348- else
349349- {
350350- /* Translation is easy */
351351- TranslatedAddress->QuadPart = BusAddress.QuadPart;
352352- return TRUE;
353353- }
354354-}
355355-356356-/* EOF */
-291
hal/halppc/generic/cmos.c
···11-/*
22- * PROJECT: ReactOS HAL
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: hal/halppc/generic/cmos.c
55- * PURPOSE: CMOS Access Routines (Real Time Clock and LastKnownGood)
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- * Eric Kohl
88- */
99-1010-/* INCLUDES ******************************************************************/
1111-1212-#include <hal.h>
1313-#define NDEBUG
1414-#include <debug.h>
1515-1616-/* GLOBALS *******************************************************************/
1717-1818-KSPIN_LOCK HalpSystemHardwareLock;
1919-2020-/* PRIVATE FUNCTIONS *********************************************************/
2121-2222-UCHAR
2323-FORCEINLINE
2424-HalpReadCmos(IN UCHAR Reg)
2525-{
2626- /* Select the register */
2727- WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
2828-2929- /* Query the value */
3030- return READ_PORT_UCHAR(CMOS_DATA_PORT);
3131-}
3232-3333-VOID
3434-FORCEINLINE
3535-HalpWriteCmos(IN UCHAR Reg,
3636- IN UCHAR Value)
3737-{
3838- /* Select the register */
3939- WRITE_PORT_UCHAR(CMOS_CONTROL_PORT, Reg);
4040-4141- /* Write the value */
4242- WRITE_PORT_UCHAR(CMOS_DATA_PORT, Value);
4343-}
4444-4545-ULONG
4646-NTAPI
4747-HalpGetCmosData(IN ULONG BusNumber,
4848- IN ULONG SlotNumber,
4949- IN PVOID Buffer,
5050- IN ULONG Length)
5151-{
5252- PUCHAR Ptr = (PUCHAR)Buffer;
5353- ULONG Address = SlotNumber;
5454- ULONG Len = Length;
5555-5656- /* FIXME: Acquire CMOS Lock */
5757-5858- /* Do nothing if we don't have a length */
5959- if (!Length) return 0;
6060-6161- /* Check if this is simple CMOS */
6262- if (!BusNumber)
6363- {
6464- /* Loop the buffer up to 0xFF */
6565- while ((Len > 0) && (Address < 0x100))
6666- {
6767- /* Read the data */
6868- *Ptr = HalpReadCmos((UCHAR)Address);
6969-7070- /* Update position and length */
7171- Ptr++;
7272- Address++;
7373- Len--;
7474- }
7575- }
7676- else if (BusNumber == 1)
7777- {
7878- /* Loop the buffer up to 0xFFFF */
7979- while ((Len > 0) && (Address < 0x10000))
8080- {
8181- /* Write the data */
8282- *Ptr = HalpReadCmos((UCHAR)Address);
8383-8484- /* Update position and length */
8585- Ptr++;
8686- Address++;
8787- Len--;
8888- }
8989- }
9090-9191- /* FIXME: Release the CMOS Lock */
9292-9393- /* Return length read */
9494- return Length - Len;
9595-}
9696-9797-ULONG
9898-NTAPI
9999-HalpSetCmosData(IN ULONG BusNumber,
100100- IN ULONG SlotNumber,
101101- IN PVOID Buffer,
102102- IN ULONG Length)
103103-{
104104- PUCHAR Ptr = (PUCHAR)Buffer;
105105- ULONG Address = SlotNumber;
106106- ULONG Len = Length;
107107-108108- /* FIXME: Acquire CMOS Lock */
109109-110110- /* Do nothing if we don't have a length */
111111- if (!Length) return 0;
112112-113113- /* Check if this is simple CMOS */
114114- if (!BusNumber)
115115- {
116116- /* Loop the buffer up to 0xFF */
117117- while ((Len > 0) && (Address < 0x100))
118118- {
119119- /* Write the data */
120120- HalpWriteCmos((UCHAR)Address, *Ptr);
121121-122122- /* Update position and length */
123123- Ptr++;
124124- Address++;
125125- Len--;
126126- }
127127- }
128128- else if (BusNumber == 1)
129129- {
130130- /* Loop the buffer up to 0xFFFF */
131131- while ((Len > 0) && (Address < 0x10000))
132132- {
133133- /* Write the data */
134134- HalpWriteCmos((UCHAR)Address, *Ptr);
135135-136136- /* Update position and length */
137137- Ptr++;
138138- Address++;
139139- Len--;
140140- }
141141- }
142142-143143- /* FIXME: Release the CMOS Lock */
144144-145145- /* Return length read */
146146- return Length - Len;
147147-}
148148-149149-/* PUBLIC FUNCTIONS **********************************************************/
150150-151151-/*
152152- * @implemented
153153- */
154154-ARC_STATUS
155155-NTAPI
156156-HalGetEnvironmentVariable(IN PCH Name,
157157- IN USHORT ValueLength,
158158- IN PCH Value)
159159-{
160160- UCHAR Val;
161161-162162- /* Only variable supported on x86 */
163163- if (_stricmp(Name, "LastKnownGood")) return ENOENT;
164164-165165- /* FIXME: Acquire CMOS Lock */
166166-167167- /* Query the current value */
168168- Val = HalpReadCmos(RTC_REGISTER_B) & 0x01;
169169-170170- /* FIXME: Release CMOS lock */
171171-172172- /* Check the flag */
173173- if (Val)
174174- {
175175- /* Return false */
176176- strncpy(Value, "FALSE", ValueLength);
177177- }
178178- else
179179- {
180180- /* Return true */
181181- strncpy(Value, "TRUE", ValueLength);
182182- }
183183-184184- /* Return success */
185185- return ESUCCESS;
186186-}
187187-188188-/*
189189- * @implemented
190190- */
191191-ARC_STATUS
192192-NTAPI
193193-HalSetEnvironmentVariable(IN PCH Name,
194194- IN PCH Value)
195195-{
196196- UCHAR Val;
197197-198198- /* Only variable supported on x86 */
199199- if (_stricmp(Name, "LastKnownGood")) return ENOMEM;
200200-201201- /* Check if this is true or false */
202202- if (!_stricmp(Value, "TRUE"))
203203- {
204204- /* It's true, acquire CMOS lock (FIXME) */
205205-206206- /* Read the current value and add the flag */
207207- Val = HalpReadCmos(RTC_REGISTER_B) | 1;
208208- }
209209- else if (!_stricmp(Value, "FALSE"))
210210- {
211211- /* It's false, acquire CMOS lock (FIXME) */
212212-213213- /* Read the current value and mask out the flag */
214214- Val = HalpReadCmos(RTC_REGISTER_B) & ~1;
215215- }
216216- else
217217- {
218218- /* Fail */
219219- return ENOMEM;
220220- }
221221-222222- /* Write new value */
223223- HalpWriteCmos(RTC_REGISTER_B, Val);
224224-225225- /* Release the lock and return success */
226226- return ESUCCESS;
227227-}
228228-229229-/*
230230- * @implemented
231231- */
232232-BOOLEAN
233233-NTAPI
234234-HalQueryRealTimeClock(OUT PTIME_FIELDS Time)
235235-{
236236- /* FIXME: Acquire CMOS Lock */
237237-238238- /* Loop while update is in progress */
239239- while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
240240-241241- /* Set the time data */
242242- Time->Second = BCD_INT(HalpReadCmos(0));
243243- Time->Minute = BCD_INT(HalpReadCmos(2));
244244- Time->Hour = BCD_INT(HalpReadCmos(4));
245245- Time->Weekday = BCD_INT(HalpReadCmos(6));
246246- Time->Day = BCD_INT(HalpReadCmos(7));
247247- Time->Month = BCD_INT(HalpReadCmos(8));
248248- Time->Year = BCD_INT(HalpReadCmos(9));
249249- Time->Milliseconds = 0;
250250-251251- /* FIXME: Check century byte */
252252-253253- /* Compensate for the century field */
254254- Time->Year += (Time->Year > 80) ? 1900: 2000;
255255-256256- /* FIXME: Release CMOS Lock */
257257-258258- /* Always return TRUE */
259259- return TRUE;
260260-}
261261-262262-/*
263263- * @implemented
264264- */
265265-BOOLEAN
266266-NTAPI
267267-HalSetRealTimeClock(IN PTIME_FIELDS Time)
268268-{
269269- /* FIXME: Acquire CMOS Lock */
270270-271271- /* Loop while update is in progress */
272272- while ((HalpReadCmos(RTC_REGISTER_A)) & RTC_REG_A_UIP);
273273-274274- /* Write time fields to CMOS RTC */
275275- HalpWriteCmos(0, INT_BCD(Time->Second));
276276- HalpWriteCmos(2, INT_BCD(Time->Minute));
277277- HalpWriteCmos(4, INT_BCD(Time->Hour));
278278- HalpWriteCmos(6, INT_BCD(Time->Weekday));
279279- HalpWriteCmos(7, INT_BCD(Time->Day));
280280- HalpWriteCmos(8, INT_BCD(Time->Month));
281281- HalpWriteCmos(9, INT_BCD(Time->Year % 100));
282282-283283- /* FIXME: Set the century byte */
284284-285285- /* FIXME: Release the CMOS Lock */
286286-287287- /* Always return TRUE */
288288- return TRUE;
289289-}
290290-291291-/* EOF */
-383
hal/halppc/generic/display.c
···11-/*
22- * ReactOS kernel
33- * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
44- *
55- * This program is free software; you can redistribute it and/or modify
66- * it under the terms of the GNU General Public License as published by
77- * the Free Software Foundation; either version 2 of the License, or
88- * (at your option) any later version.
99- *
1010- * This program is distributed in the hope that it will be useful,
1111- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1212- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313- * GNU General Public License for more details.
1414- *
1515- * You should have received a copy of the GNU General Public License along
1616- * with this program; if not, write to the Free Software Foundation, Inc.,
1717- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818- */
1919-/*
2020- * COPYRIGHT: See COPYING in the top level directory
2121- * PROJECT: ReactOS kernel
2222- * FILE: hal/halppc/generic/display.c
2323- * PURPOSE: Blue screen display
2424- * PROGRAMMER: Eric Kohl
2525- * UPDATE HISTORY:
2626- * Created 08/10/99
2727- */
2828-2929-/*
3030- * Portions of this code are from the XFree86 Project and available from the
3131- * following license:
3232- *
3333- * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
3434- *
3535- * Permission is hereby granted, free of charge, to any person obtaining a copy
3636- * of this software and associated documentation files (the "Software"), to
3737- * deal in the Software without restriction, including without limitation the
3838- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
3939- * sell copies of the Software, and to permit persons to whom the Software is
4040- * furnished to do so, subject to the following conditions:
4141- *
4242- * The above copyright notice and this permission notice shall be included in
4343- * all copies or substantial portions of the Software.
4444- *
4545- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4646- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4747- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4848- * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
4949- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
5050- * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5151- *
5252- * Except as contained in this notice, the name of the XFree86 Project shall
5353- * not be used in advertising or otherwise to promote the sale, use or other
5454- * dealings in this Software without prior written authorization from the
5555- * XFree86 Project.
5656-*/
5757-5858-/* DISPLAY OWNERSHIP
5959- *
6060- * So, who owns the physical display and is allowed to write to it?
6161- *
6262- * In MS NT, upon boot HAL owns the display. Somewhere in the boot
6363- * sequence (haven't figured out exactly where or by who), some
6464- * component calls HalAcquireDisplayOwnership. From that moment on,
6565- * the display is owned by that component and is switched to graphics
6666- * mode. The display is not supposed to return to text mode, except
6767- * in case of a bug check. The bug check will call HalDisplayString
6868- * to output a string to the text screen. HAL will notice that it
6969- * currently doesn't own the display and will re-take ownership, by
7070- * calling the callback function passed to HalAcquireDisplayOwnership.
7171- * After the bugcheck, execution is halted. So, under NT, the only
7272- * possible sequence of display modes is text mode -> graphics mode ->
7373- * text mode (the latter hopefully happening very infrequently).
7474- *
7575- * Things are a little bit different in the current state of ReactOS.
7676- * We want to have a functional interactive text mode. We should be
7777- * able to switch from text mode to graphics mode when a GUI app is
7878- * started and switch back to text mode when it's finished. Then, when
7979- * another GUI app is started, another switch to and from graphics mode
8080- * is possible. Also, when the system bugchecks in graphics mode we want
8181- * to switch back to text mode to show the registers and stack trace.
8282- * Last but not least, HalDisplayString is used a lot more in ReactOS,
8383- * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
8484- * is present.
8585- * 3 Components are involved in ReactOS: HAL, BLUE.SYS and VIDEOPRT.SYS.
8686- * As in NT, on boot HAL owns the display. When entering the text mode
8787- * command interpreter, BLUE.SYS kicks in. It will write directly to the
8888- * screen, more or less behind HALs back.
8989- * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
9090- * This open call will end up in VIDEOPRT.SYS. That component will then
9191- * take ownership of the display by calling HalAcquireDisplayOwnership.
9292- * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
9393- * we want to give ownership of the display back to HAL. Using the
9494- * standard exported HAL functions, that's a bit of a problem, because
9595- * there is no function defined to do that. In NT, this is handled by
9696- * HalDisplayString, but that solution isn't satisfactory in ReactOS,
9797- * because HalDisplayString is (in some cases) also used to output debug
9898- * messages. If we do it the NT way, the first debug message output while
9999- * in graphics mode would switch the display back to text mode.
100100- * So, instead, if HalDisplayString detects that HAL doesn't have ownership
101101- * of the display, it doesn't do anything.
102102- * To return ownership to HAL, a new function is exported,
103103- * HalReleaseDisplayOwnership. This function is called by the DISPLAY
104104- * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
105105- * of a bug check, so HalDisplayString is activated again.
106106- * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
107107- * should also refrain from writing to the screen buffer. The text mode
108108- * screen buffer might overlap the graphics mode screen buffer, so changing
109109- * something in the text mode buffer might mess up the graphics screen. To
110110- * allow BLUE.SYS to detect if HAL owns the display, another new function is
111111- * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
112112- * check if it's allowed to touch the text mode buffer.
113113- *
114114- * In an ideal world, when HAL takes ownership of the display, it should set
115115- * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
116116- * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
117117- * table etc. So, we chickened out of that by having the loader set up the
118118- * display before switching to protected mode. If HAL is given back ownership
119119- * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
120120- * since there is already support for them via the VideoPortInt10 routine.
121121- */
122122-123123-#include <hal.h>
124124-#include <ppcboot.h>
125125-#include <ppcdebug.h>
126126-127127-#define NDEBUG
128128-#include <debug.h>
129129-130130-boot_infos_t PpcEarlybootInfo;
131131-132132-#define SCREEN_SYNCHRONIZATION
133133-134134-/* VARIABLES ****************************************************************/
135135-136136-static ULONG CursorX = 0; /* Cursor Position */
137137-static ULONG CursorY = 0;
138138-static ULONG SizeX = 80; /* Display size */
139139-static ULONG SizeY = 25;
140140-141141-static BOOLEAN DisplayInitialized = FALSE;
142142-static BOOLEAN HalOwnsDisplay = TRUE;
143143-static ULONG GraphVideoBuffer = 0;
144144-static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
145145-146146-extern UCHAR XboxFont8x16[];
147147-extern void SetPhys( ULONG Addr, ULONG Data );
148148-extern ULONG GetPhys( ULONG Addr );
149149-extern void SetPhysByte( ULONG Addr, ULONG Data );
150150-151151-/* PRIVATE FUNCTIONS *********************************************************/
152152-153153-VOID FASTCALL
154154-HalClearDisplay (UCHAR CharAttribute)
155155-{
156156- ULONG i;
157157- ULONG deviceSize =
158158- PpcEarlybootInfo.dispDeviceRowBytes *
159159- PpcEarlybootInfo.dispDeviceRect[3];
160160- for(i = 0; i < deviceSize; i += sizeof(int) )
161161- SetPhys(GraphVideoBuffer + i, CharAttribute);
162162-163163- CursorX = 0;
164164- CursorY = 0;
165165-}
166166-167167-168168-/* STATIC FUNCTIONS *********************************************************/
169169-170170-VOID STATIC
171171-HalScrollDisplay (VOID)
172172-{
173173- ULONG i, deviceSize =
174174- PpcEarlybootInfo.dispDeviceRowBytes *
175175- PpcEarlybootInfo.dispDeviceRect[3];
176176- ULONG Dest = (ULONG)GraphVideoBuffer,
177177- Src = (ULONG)(GraphVideoBuffer + (16 * PpcEarlybootInfo.dispDeviceRowBytes));
178178- ULONG End = (ULONG)
179179- GraphVideoBuffer +
180180- (PpcEarlybootInfo.dispDeviceRowBytes *
181181- (PpcEarlybootInfo.dispDeviceRect[3]-16));
182182-183183- while( Src < End )
184184- {
185185- SetPhys((ULONG)Dest, GetPhys(Src));
186186- Src += 4; Dest += 4;
187187- }
188188-189189- /* Clear the bottom row */
190190- for(i = End; i < deviceSize; i += sizeof(int) )
191191- SetPhys(GraphVideoBuffer + i, 1);
192192-}
193193-194194-VOID STATIC FASTCALL
195195-HalPutCharacter (CHAR Character)
196196-{
197197- WRITE_PORT_UCHAR((PVOID)0x3f8, Character);
198198-#if 0
199199- int i,j,k;
200200- ULONG Dest =
201201- (GraphVideoBuffer +
202202- (16 * PpcEarlybootInfo.dispDeviceRowBytes * CursorY) +
203203- (8 * (PpcEarlybootInfo.dispDeviceDepth / 8) * CursorX)), RowDest;
204204- UCHAR ByteToPlace;
205205-206206- for( i = 0; i < 16; i++ ) {
207207- RowDest = Dest;
208208- for( j = 0; j < 8; j++ ) {
209209- ByteToPlace = ((128 >> j) & (XboxFont8x16[(16 * Character) + i])) ? 0xff : 1;
210210- for( k = 0; k < PpcEarlybootInfo.dispDeviceDepth / 8; k++, RowDest++ ) {
211211- SetPhysByte(RowDest, ByteToPlace);
212212- }
213213- }
214214- Dest += PpcEarlybootInfo.dispDeviceRowBytes;
215215- }
216216-#endif
217217-}
218218-219219-/* PRIVATE FUNCTIONS ********************************************************/
220220-221221-VOID FASTCALL
222222-HalInitializeDisplay (PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
223223-/*
224224- * FUNCTION: Initialize the display
225225- * ARGUMENTS:
226226- * InitParameters = Parameters setup by the boot loader
227227- */
228228-{
229229- if (! DisplayInitialized)
230230- {
231231- boot_infos_t *XBootInfo = (boot_infos_t *)LoaderBlock->ArchExtra;
232232- GraphVideoBuffer = (ULONG)XBootInfo->dispDeviceBase;
233233- memcpy(&PpcEarlybootInfo, XBootInfo, sizeof(*XBootInfo));
234234-235235- /* Set cursor position */
236236- CursorX = 0;
237237- CursorY = 0;
238238-239239- SizeX = XBootInfo->dispDeviceRowBytes / XBootInfo->dispDeviceDepth;
240240- SizeY = XBootInfo->dispDeviceRect[3] / 16;
241241-242242- HalClearDisplay(1);
243243-244244- DisplayInitialized = TRUE;
245245- }
246246-}
247247-248248-249249-/* PUBLIC FUNCTIONS *********************************************************/
250250-251251-VOID NTAPI
252252-HalReleaseDisplayOwnership(VOID)
253253-/*
254254- * FUNCTION: Release ownership of display back to HAL
255255- */
256256-{
257257- if (HalResetDisplayParameters == NULL)
258258- return;
259259-260260- if (HalOwnsDisplay != FALSE)
261261- return;
262262-263263- HalOwnsDisplay = TRUE;
264264- HalClearDisplay(0);
265265-}
266266-267267-268268-VOID NTAPI
269269-HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
270270-/*
271271- * FUNCTION:
272272- * ARGUMENTS:
273273- * ResetDisplayParameters = Pointer to a driver specific
274274- * reset routine.
275275- */
276276-{
277277- HalOwnsDisplay = FALSE;
278278- HalResetDisplayParameters = ResetDisplayParameters;
279279-}
280280-281281-VOID NTAPI
282282-HalDisplayString(IN PCH String)
283283-/*
284284- * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
285285- * already and displays a string
286286- * ARGUMENT:
287287- * string = ASCII string to display
288288- * NOTE: Use with care because there is no support for returning from BSOD
289289- * mode
290290- */
291291-{
292292- PCH pch;
293293- //static KSPIN_LOCK Lock;
294294- KIRQL OldIrql;
295295- BOOLEAN InterruptsEnabled = __readmsr();
296296-297297- /* See comment at top of file */
298298- if (! HalOwnsDisplay || ! DisplayInitialized)
299299- {
300300- return;
301301- }
302302-303303- pch = String;
304304-305305- KeRaiseIrql(HIGH_LEVEL, &OldIrql);
306306- //KiAcquireSpinLock(&Lock);
307307-308308- _disable();
309309-310310- while (*pch != 0)
311311- {
312312- if (*pch == '\n')
313313- {
314314- CursorY++;
315315- CursorX = 0;
316316- }
317317- else if (*pch == '\b')
318318- {
319319- if (CursorX > 0)
320320- {
321321- CursorX--;
322322- }
323323- }
324324- else if (*pch != '\r')
325325- {
326326- HalPutCharacter (*pch);
327327- CursorX++;
328328-329329- if (CursorX >= SizeX)
330330- {
331331- CursorY++;
332332- CursorX = 0;
333333- }
334334- }
335335-336336- if (CursorY >= SizeY)
337337- {
338338- HalScrollDisplay ();
339339- CursorY = SizeY - 1;
340340- }
341341-342342- pch++;
343343- }
344344-345345- __writemsr(InterruptsEnabled);
346346-347347- //KiReleaseSpinLock(&Lock);
348348- KeLowerIrql(OldIrql);
349349-}
350350-351351-VOID NTAPI
352352-HalQueryDisplayParameters(OUT PULONG DispSizeX,
353353- OUT PULONG DispSizeY,
354354- OUT PULONG CursorPosX,
355355- OUT PULONG CursorPosY)
356356-{
357357- if (DispSizeX)
358358- *DispSizeX = SizeX;
359359- if (DispSizeY)
360360- *DispSizeY = SizeY;
361361- if (CursorPosX)
362362- *CursorPosX = CursorX;
363363- if (CursorPosY)
364364- *CursorPosY = CursorY;
365365-}
366366-367367-368368-VOID NTAPI
369369-HalSetDisplayParameters(IN ULONG CursorPosX,
370370- IN ULONG CursorPosY)
371371-{
372372- CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
373373- CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
374374-}
375375-376376-377377-BOOLEAN NTAPI
378378-HalQueryDisplayOwnership(VOID)
379379-{
380380- return !HalOwnsDisplay;
381381-}
382382-383383-/* EOF */
-2020
hal/halppc/generic/dma.c
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * FILE: hal/halppc/generic/dma.c
55- * PURPOSE: DMA functions
66- * PROGRAMMERS: David Welch (welch@mcmail.com)
77- * Filip Navara (navaraf@reactos.com)
88- * UPDATE HISTORY:
99- * Created 22/05/98
1010- */
1111-1212-/**
1313- * @page DMA Implementation Notes
1414- *
1515- * Concepts:
1616- *
1717- * - Map register
1818- *
1919- * Abstract encapsulation of physically contiguous buffer that resides
2020- * in memory accessible by both the DMA device / controller and the system.
2121- * The map registers are allocated and distributed on demand and are
2222- * scarce resource.
2323- *
2424- * The actual use of map registers is to allow transfers from/to buffer
2525- * located in physical memory at address inaccessible by the DMA device /
2626- * controller directly. For such transfers the map register buffers
2727- * are used as intermediate data storage.
2828- *
2929- * - Master adapter
3030- *
3131- * A container for map registers (typically corresponding to one physical
3232- * bus connection type). There can be master adapters for 24-bit address
3333- * ranges, 32-bit address ranges, etc. Every time a new DMA adapter is
3434- * created it's associated with a corresponding master adapter that
3535- * is used for any map register allocation requests.
3636- *
3737- * - Bus-master / Slave DMA
3838- *
3939- * Slave DMA is term used for DMA transfers done by the system (E)ISA
4040- * controller as opposed to transfers mastered by the device itself
4141- * (hence the name).
4242- *
4343- * For slave DMA special care is taken to actually access the system
4444- * controller and handle the transfers. The relevant code is in
4545- * HalpDmaInitializeEisaAdapter, HalReadDmaCounter, IoFlushAdapterBuffers
4646- * and IoMapTransfer.
4747- *
4848- * Implementation:
4949- *
5050- * - Allocation of map registers
5151- *
5252- * Initial set of map registers is allocated on the system start to
5353- * ensure that low memory won't get filled up later. Additional map
5454- * registers are allocated as needed by HalpGrowMapBuffers. This
5555- * routine is called on two places:
5656- *
5757- * - HalGetAdapter, since we're at PASSIVE_LEVEL and it's known that
5858- * more map registers will probably be needed.
5959- * - IoAllocateAdapterChannel (indirectly using HalpGrowMapBufferWorker
6060- * since we're at DISPATCH_LEVEL and call HalpGrowMapBuffers directly)
6161- * when no more map registers are free.
6262- *
6363- * Note that even if no more map registers can be allocated it's not
6464- * the end of the world. The adapters waiting for free map registers
6565- * are queued in the master adapter's queue and once one driver hands
6666- * back it's map registers (using IoFreeMapRegisters or indirectly using
6767- * the execution routine callback in IoAllocateAdapterChannel) the
6868- * queue gets processed and the map registers are reassigned.
6969- */
7070-7171-/* INCLUDES *****************************************************************/
7272-7373-#include <hal.h>
7474-#define NDEBUG
7575-#include <debug.h>
7676-7777-static KEVENT HalpDmaLock;
7878-static LIST_ENTRY HalpDmaAdapterList;
7979-static PADAPTER_OBJECT HalpEisaAdapter[8];
8080-static BOOLEAN HalpEisaDma;
8181-static PADAPTER_OBJECT HalpMasterAdapter;
8282-8383-static const ULONG_PTR HalpEisaPortPage[8] = {
8484- FIELD_OFFSET(DMA_PAGE, Channel0),
8585- FIELD_OFFSET(DMA_PAGE, Channel1),
8686- FIELD_OFFSET(DMA_PAGE, Channel2),
8787- FIELD_OFFSET(DMA_PAGE, Channel3),
8888- 0,
8989- FIELD_OFFSET(DMA_PAGE, Channel5),
9090- FIELD_OFFSET(DMA_PAGE, Channel6),
9191- FIELD_OFFSET(DMA_PAGE, Channel7)
9292-};
9393-9494-static DMA_OPERATIONS HalpDmaOperations = {
9595- sizeof(DMA_OPERATIONS),
9696- (PPUT_DMA_ADAPTER)HalPutDmaAdapter,
9797- (PALLOCATE_COMMON_BUFFER)HalAllocateCommonBuffer,
9898- (PFREE_COMMON_BUFFER)HalFreeCommonBuffer,
9999- NULL, /* Initialized in HalpInitDma() */
100100- NULL, /* Initialized in HalpInitDma() */
101101- NULL, /* Initialized in HalpInitDma() */
102102- NULL, /* Initialized in HalpInitDma() */
103103- NULL, /* Initialized in HalpInitDma() */
104104- (PGET_DMA_ALIGNMENT)HalpDmaGetDmaAlignment,
105105- (PREAD_DMA_COUNTER)HalReadDmaCounter,
106106- /* FIXME: Implement the S/G funtions. */
107107- NULL /*(PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList*/,
108108- NULL /*(PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList*/,
109109- NULL /*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize*/,
110110- NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/,
111111- NULL /*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*/
112112-};
113113-114114-#define MAX_MAP_REGISTERS 64
115115-116116-#define TAG_DMA ' AMD'
117117-118118-/* FUNCTIONS *****************************************************************/
119119-120120-VOID
121121-HalpInitDma(VOID)
122122-{
123123- /*
124124- * Initialize the DMA Operation table
125125- */
126126- HalpDmaOperations.AllocateAdapterChannel = (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel;
127127- HalpDmaOperations.FlushAdapterBuffers = (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers;
128128- HalpDmaOperations.FreeAdapterChannel = (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel;
129129- HalpDmaOperations.FreeMapRegisters = (PFREE_MAP_REGISTERS)IoFreeMapRegisters;
130130- HalpDmaOperations.MapTransfer = (PMAP_TRANSFER)IoMapTransfer;
131131-132132- /*
133133- * Check if Extended DMA is available. We're just going to do a random
134134- * read and write.
135135- */
136136-137137- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A);
138138- if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A)
139139- HalpEisaDma = TRUE;
140140-141141- /*
142142- * Intialize all the global variables and allocate master adapter with
143143- * first map buffers.
144144- */
145145-146146- InitializeListHead(&HalpDmaAdapterList);
147147- KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE);
148148-149149- HalpMasterAdapter = HalpDmaAllocateMasterAdapter();
150150-151151- /*
152152- * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
153153- * used by IoGetDmaAdapter in the kernel.
154154- */
155155-156156- HalGetDmaAdapter = HalpGetDmaAdapter;
157157-}
158158-159159-/**
160160- * @name HalpGetAdapterMaximumPhysicalAddress
161161- *
162162- * Get the maximum physical address acceptable by the device represented
163163- * by the passed DMA adapter.
164164- */
165165-166166-PHYSICAL_ADDRESS NTAPI
167167-HalpGetAdapterMaximumPhysicalAddress(
168168- IN PADAPTER_OBJECT AdapterObject)
169169-{
170170- PHYSICAL_ADDRESS HighestAddress;
171171-172172- if (AdapterObject->MasterDevice)
173173- {
174174- if (AdapterObject->Dma64BitAddresses)
175175- {
176176- HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
177177- return HighestAddress;
178178- }
179179- else if (AdapterObject->Dma32BitAddresses)
180180- {
181181- HighestAddress.QuadPart = 0xFFFFFFFF;
182182- return HighestAddress;
183183- }
184184- }
185185-186186- HighestAddress.QuadPart = 0xFFFFFF;
187187- return HighestAddress;
188188-}
189189-190190-/**
191191- * @name HalpGrowMapBuffers
192192- *
193193- * Allocate initial, or additional, map buffers for DMA master adapter.
194194- *
195195- * @param MasterAdapter
196196- * DMA master adapter to allocate buffers for.
197197- * @param SizeOfMapBuffers
198198- * Size of the map buffers to allocate (not including the size
199199- * already allocated).
200200- */
201201-202202-BOOLEAN NTAPI
203203-HalpGrowMapBuffers(
204204- IN PADAPTER_OBJECT AdapterObject,
205205- IN ULONG SizeOfMapBuffers)
206206-{
207207- PVOID VirtualAddress;
208208- PHYSICAL_ADDRESS PhysicalAddress;
209209- PHYSICAL_ADDRESS HighestAcceptableAddress;
210210- PHYSICAL_ADDRESS LowestAcceptableAddress;
211211- PHYSICAL_ADDRESS BoundryAddressMultiple;
212212- KIRQL OldIrql;
213213- ULONG MapRegisterCount;
214214-215215- /* FIXME: Check if enough map register slots are available. */
216216-217217- MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
218218-219219- /*
220220- * Allocate memory for the new map registers. For 32-bit adapters we use
221221- * two passes in order not to waste scare resource (low memory).
222222- */
223223-224224- HighestAcceptableAddress =
225225- HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
226226- LowestAcceptableAddress.HighPart = 0;
227227- LowestAcceptableAddress.LowPart =
228228- HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
229229- BoundryAddressMultiple.QuadPart = 0;
230230-231231- VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
232232- MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
233233- HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
234234-235235- if (VirtualAddress == NULL && LowestAcceptableAddress.LowPart != 0)
236236- {
237237- LowestAcceptableAddress.LowPart = 0;
238238- VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
239239- MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
240240- HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
241241- }
242242-243243- if (VirtualAddress == NULL)
244244- return FALSE;
245245-246246- PhysicalAddress = MmGetPhysicalAddress(VirtualAddress);
247247-248248- /*
249249- * All the following must be done with the master adapter lock held
250250- * to prevent corruption.
251251- */
252252-253253- OldIrql = KfAcquireSpinLock(&AdapterObject->SpinLock);
254254-255255- /*
256256- * Setup map register entries for the buffer allocated. Each entry has
257257- * a virtual and physical address and corresponds to PAGE_SIZE large
258258- * buffer.
259259- */
260260-261261- if (MapRegisterCount > 0)
262262- {
263263- PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
264264-265265- CurrentEntry = AdapterObject->MapRegisterBase +
266266- AdapterObject->NumberOfMapRegisters;
267267- do
268268- {
269269- /*
270270- * Leave one entry free for every non-contiguous memory region
271271- * in the map register bitmap. This ensures that we can search
272272- * using RtlFindClearBits for contiguous map register regions.
273273- *
274274- * Also for non-EISA DMA leave one free entry for every 64Kb
275275- * break, because the DMA controller can handle only coniguous
276276- * 64Kb regions.
277277- */
278278-279279- if (CurrentEntry != AdapterObject->MapRegisterBase)
280280- {
281281- PreviousEntry = CurrentEntry - 1;
282282- if (PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE ==
283283- PhysicalAddress.LowPart)
284284- {
285285- if (!HalpEisaDma)
286286- {
287287- if ((PreviousEntry->PhysicalAddress.LowPart ^
288288- PhysicalAddress.LowPart) & 0xFFFF0000)
289289- {
290290- CurrentEntry++;
291291- AdapterObject->NumberOfMapRegisters++;
292292- }
293293- }
294294- }
295295- else
296296- {
297297- CurrentEntry++;
298298- AdapterObject->NumberOfMapRegisters++;
299299- }
300300- }
301301-302302- RtlClearBit(AdapterObject->MapRegisters,
303303- CurrentEntry - AdapterObject->MapRegisterBase);
304304- CurrentEntry->VirtualAddress = VirtualAddress;
305305- CurrentEntry->PhysicalAddress = PhysicalAddress;
306306-307307- PhysicalAddress.LowPart += PAGE_SIZE;
308308- VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);
309309-310310- CurrentEntry++;
311311- AdapterObject->NumberOfMapRegisters++;
312312- MapRegisterCount--;
313313- }
314314- while (MapRegisterCount != 0);
315315- }
316316-317317- KfReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
318318-319319- return TRUE;
320320-}
321321-322322-/**
323323- * @name HalpDmaAllocateMasterAdapter
324324- *
325325- * Helper routine to allocate and initialize master adapter object and it's
326326- * associated map register buffers.
327327- *
328328- * @see HalpInitDma
329329- */
330330-331331-PADAPTER_OBJECT NTAPI
332332-HalpDmaAllocateMasterAdapter(VOID)
333333-{
334334- PADAPTER_OBJECT MasterAdapter;
335335- ULONG Size, SizeOfBitmap;
336336-337337- SizeOfBitmap = MAX_MAP_REGISTERS;
338338- Size = sizeof(ADAPTER_OBJECT);
339339- Size += sizeof(RTL_BITMAP);
340340- Size += (SizeOfBitmap + 7) >> 3;
341341-342342- MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA);
343343- if (MasterAdapter == NULL)
344344- return NULL;
345345-346346- RtlZeroMemory(MasterAdapter, Size);
347347-348348- KeInitializeSpinLock(&MasterAdapter->SpinLock);
349349- InitializeListHead(&MasterAdapter->AdapterQueue);
350350-351351- MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
352352- RtlInitializeBitMap(
353353- MasterAdapter->MapRegisters,
354354- (PULONG)(MasterAdapter->MapRegisters + 1),
355355- SizeOfBitmap);
356356- RtlSetAllBits(MasterAdapter->MapRegisters);
357357- MasterAdapter->NumberOfMapRegisters = 0;
358358- MasterAdapter->CommittedMapRegisters = 0;
359359-360360- MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(
361361- NonPagedPool,
362362- SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY),
363363- TAG_DMA);
364364- if (MasterAdapter->MapRegisterBase == NULL)
365365- {
366366- ExFreePool(MasterAdapter);
367367- return NULL;
368368- }
369369-370370- RtlZeroMemory(MasterAdapter->MapRegisterBase,
371371- SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
372372- if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
373373- {
374374- ExFreePool(MasterAdapter);
375375- return NULL;
376376- }
377377-378378- return MasterAdapter;
379379-}
380380-381381-/**
382382- * @name HalpDmaAllocateChildAdapter
383383- *
384384- * Helper routine of HalGetAdapter. Allocate child adapter object and
385385- * fill out some basic fields.
386386- *
387387- * @see HalGetAdapter
388388- */
389389-390390-PADAPTER_OBJECT NTAPI
391391-HalpDmaAllocateChildAdapter(
392392- ULONG NumberOfMapRegisters,
393393- PDEVICE_DESCRIPTION DeviceDescription)
394394-{
395395- PADAPTER_OBJECT AdapterObject;
396396- OBJECT_ATTRIBUTES ObjectAttributes;
397397- NTSTATUS Status;
398398- HANDLE Handle;
399399-400400- InitializeObjectAttributes(
401401- &ObjectAttributes,
402402- NULL,
403403- OBJ_KERNEL_HANDLE | OBJ_PERMANENT,
404404- NULL,
405405- NULL);
406406-407407- Status = ObCreateObject(
408408- KernelMode,
409409- IoAdapterObjectType,
410410- &ObjectAttributes,
411411- KernelMode,
412412- NULL,
413413- sizeof(ADAPTER_OBJECT),
414414- 0,
415415- 0,
416416- (PVOID)&AdapterObject);
417417- if (!NT_SUCCESS(Status))
418418- return NULL;
419419-420420- Status = ObReferenceObjectByPointer(
421421- AdapterObject,
422422- FILE_READ_DATA | FILE_WRITE_DATA,
423423- IoAdapterObjectType,
424424- KernelMode);
425425- if (!NT_SUCCESS(Status))
426426- return NULL;
427427-428428- RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
429429-430430- Status = ObInsertObject(
431431- AdapterObject,
432432- NULL,
433433- FILE_READ_DATA | FILE_WRITE_DATA,
434434- 0,
435435- NULL,
436436- &Handle);
437437- if (!NT_SUCCESS(Status))
438438- return NULL;
439439-440440- ZwClose(Handle);
441441-442442- AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
443443- AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
444444- AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
445445- AdapterObject->MapRegistersPerChannel = 1;
446446- AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
447447- AdapterObject->ChannelNumber = 0xFF;
448448- AdapterObject->MasterAdapter = HalpMasterAdapter;
449449- KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
450450-451451- return AdapterObject;
452452-}
453453-454454-/**
455455- * @name HalpDmaInitializeEisaAdapter
456456- *
457457- * Setup DMA modes and extended modes for (E)ISA DMA adapter object.
458458- */
459459-460460-BOOLEAN NTAPI
461461-HalpDmaInitializeEisaAdapter(
462462- PADAPTER_OBJECT AdapterObject,
463463- PDEVICE_DESCRIPTION DeviceDescription)
464464-{
465465- UCHAR Controller;
466466- DMA_MODE DmaMode = {{0 }};
467467- DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
468468- PVOID AdapterBaseVa;
469469-470470- Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
471471-472472- if (Controller == 1)
473473- AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
474474- else
475475- AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
476476-477477- AdapterObject->AdapterNumber = Controller;
478478- AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
479479- AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
480480- AdapterObject->Width16Bits = FALSE;
481481- AdapterObject->AdapterBaseVa = AdapterBaseVa;
482482-483483- if (HalpEisaDma)
484484- {
485485- ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
486486-487487- switch (DeviceDescription->DmaSpeed)
488488- {
489489- case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
490490- case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
491491- case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
492492- case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
493493- default:
494494- return FALSE;
495495- }
496496-497497- switch (DeviceDescription->DmaWidth)
498498- {
499499- case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
500500- case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
501501- case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
502502- default:
503503- return FALSE;
504504- }
505505-506506- if (Controller == 1)
507507- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
508508- ExtendedMode.Byte);
509509- else
510510- WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
511511- ExtendedMode.Byte);
512512- }
513513- else
514514- {
515515- /*
516516- * Validate setup for non-busmaster DMA adapter. Secondary controller
517517- * supports only 16-bit transfers and main controller supports only
518518- * 8-bit transfers. Anything else is invalid.
519519- */
520520-521521- if (!DeviceDescription->Master)
522522- {
523523- if (Controller == 2 && DeviceDescription->DmaWidth == Width16Bits)
524524- AdapterObject->Width16Bits = TRUE;
525525- else if (Controller != 1 || DeviceDescription->DmaWidth != Width8Bits)
526526- return FALSE;
527527- }
528528- }
529529-530530- DmaMode.Channel = AdapterObject->ChannelNumber;
531531- DmaMode.AutoInitialize = DeviceDescription->AutoInitialize;
532532-533533- /*
534534- * Set the DMA request mode.
535535- *
536536- * For (E)ISA bus master devices just unmask (enable) the DMA channel
537537- * and set it to cascade mode. Otherwise just select the right one
538538- * bases on the passed device description.
539539- */
540540-541541- if (DeviceDescription->Master)
542542- {
543543- DmaMode.RequestMode = CASCADE_REQUEST_MODE;
544544- if (Controller == 1)
545545- {
546546- /* Set the Request Data */
547547- WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode,
548548- DmaMode.Byte);
549549- /* Unmask DMA Channel */
550550- WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
551551- AdapterObject->ChannelNumber | DMA_CLEARMASK);
552552- } else {
553553- /* Set the Request Data */
554554- WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode,
555555- DmaMode.Byte);
556556- /* Unmask DMA Channel */
557557- WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
558558- AdapterObject->ChannelNumber | DMA_CLEARMASK);
559559- }
560560- }
561561- else
562562- {
563563- if (DeviceDescription->DemandMode)
564564- DmaMode.RequestMode = DEMAND_REQUEST_MODE;
565565- else
566566- DmaMode.RequestMode = SINGLE_REQUEST_MODE;
567567- }
568568-569569- AdapterObject->AdapterMode = DmaMode;
570570-571571- return TRUE;
572572-}
573573-574574-/**
575575- * @name HalGetAdapter
576576- *
577577- * Allocate an adapter object for DMA device.
578578- *
579579- * @param DeviceDescription
580580- * Structure describing the attributes of the device.
581581- * @param NumberOfMapRegisters
582582- * On return filled with the maximum number of map registers the
583583- * device driver can allocate for DMA transfer operations.
584584- *
585585- * @return The DMA adapter on success, NULL otherwise.
586586- *
587587- * @implemented
588588- */
589589-590590-PADAPTER_OBJECT NTAPI
591591-HalGetAdapter(
592592- PDEVICE_DESCRIPTION DeviceDescription,
593593- PULONG NumberOfMapRegisters)
594594-{
595595- PADAPTER_OBJECT AdapterObject = NULL;
596596- PADAPTER_OBJECT MasterAdapter;
597597- BOOLEAN EisaAdapter;
598598- ULONG MapRegisters;
599599- ULONG MaximumLength;
600600-601601- /* Validate parameters in device description */
602602- if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION2)
603603- return NULL;
604604-605605- /*
606606- * See if we're going to use ISA/EISA DMA adapter. These adapters are
607607- * special since they're reused.
608608- *
609609- * Also note that we check for channel number since there are only 8 DMA
610610- * channels on ISA, so any request above this requires new adapter.
611611- */
612612-613613- if (DeviceDescription->InterfaceType == Isa || !DeviceDescription->Master)
614614- {
615615- if (DeviceDescription->InterfaceType == Isa &&
616616- DeviceDescription->DmaChannel >= 8)
617617- EisaAdapter = FALSE;
618618- else
619619- EisaAdapter = TRUE;
620620- }
621621- else
622622- {
623623- EisaAdapter = FALSE;
624624- }
625625-626626- /*
627627- * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
628628- * for cascading the controllers and it's not available for software use.
629629- */
630630-631631- if (EisaAdapter && DeviceDescription->DmaChannel == 4)
632632- return NULL;
633633-634634- /*
635635- * Calculate the number of map registers.
636636- *
637637- * - For EISA and PCI scatter/gather no map registers are needed.
638638- * - For ISA slave scatter/gather one map register is needed.
639639- * - For all other cases the number of map registers depends on
640640- * DeviceDescription->MaximumLength.
641641- */
642642-643643- MaximumLength = DeviceDescription->MaximumLength & MAXLONG;
644644- if (DeviceDescription->ScatterGather &&
645645- (DeviceDescription->InterfaceType == Eisa ||
646646- DeviceDescription->InterfaceType == PCIBus))
647647- {
648648- MapRegisters = 0;
649649- }
650650- else if (DeviceDescription->ScatterGather &&
651651- !DeviceDescription->Master)
652652- {
653653- MapRegisters = 1;
654654- }
655655- else
656656- {
657657- /*
658658- * In the equation below the additional map register added by
659659- * the "+1" accounts for the case when a transfer does not start
660660- * at a page-aligned address.
661661- */
662662- MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
663663- if (MapRegisters > 16)
664664- MapRegisters = 16;
665665- }
666666-667667- /*
668668- * Acquire the DMA lock that is used to protect adapter lists and
669669- * EISA adapter array.
670670- */
671671-672672- KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
673673- FALSE, NULL);
674674-675675- /*
676676- * Now we must get ahold of the adapter object. For first eight ISA/EISA
677677- * channels there are static adapter objects that are reused and updated
678678- * on succesive HalGetAdapter calls. In other cases a new adapter object
679679- * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
680680- */
681681-682682- if (EisaAdapter)
683683- {
684684- AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
685685- if (AdapterObject != NULL)
686686- {
687687- if (AdapterObject->NeedsMapRegisters &&
688688- MapRegisters > AdapterObject->MapRegistersPerChannel)
689689- AdapterObject->MapRegistersPerChannel = MapRegisters;
690690- }
691691- }
692692-693693- if (AdapterObject == NULL)
694694- {
695695- AdapterObject = HalpDmaAllocateChildAdapter(
696696- MapRegisters, DeviceDescription);
697697- if (AdapterObject == NULL)
698698- {
699699- KeSetEvent(&HalpDmaLock, 0, 0);
700700- return NULL;
701701- }
702702-703703- if (EisaAdapter)
704704- {
705705- HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
706706- }
707707-708708- if (MapRegisters > 0)
709709- {
710710- AdapterObject->NeedsMapRegisters = TRUE;
711711- MasterAdapter = HalpMasterAdapter;
712712- AdapterObject->MapRegistersPerChannel = MapRegisters;
713713-714714- /*
715715- * FIXME: Verify that the following makes sense. Actually
716716- * MasterAdapter->NumberOfMapRegisters contains even the number
717717- * of gaps, so this will not work correctly all the time. It
718718- * doesn't matter much since it's only optimization to avoid
719719- * queuing work items in HalAllocateAdapterChannel.
720720- */
721721-722722- MasterAdapter->CommittedMapRegisters += MapRegisters;
723723- if (MasterAdapter->CommittedMapRegisters > MasterAdapter->NumberOfMapRegisters)
724724- HalpGrowMapBuffers(MasterAdapter, 0x10000);
725725- }
726726- else
727727- {
728728- AdapterObject->NeedsMapRegisters = FALSE;
729729- if (DeviceDescription->Master)
730730- AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
731731- else
732732- AdapterObject->MapRegistersPerChannel = 1;
733733- }
734734- }
735735-736736- if (!EisaAdapter)
737737- InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
738738-739739- /*
740740- * Release the DMA lock. HalpDmaAdapterList and HalpEisaAdapter will
741741- * no longer be touched, so we don't need it.
742742- */
743743-744744- KeSetEvent(&HalpDmaLock, 0, 0);
745745-746746- /*
747747- * Setup the values in the adapter object that are common for all
748748- * types of buses.
749749- */
750750-751751- if (DeviceDescription->Version >= DEVICE_DESCRIPTION_VERSION1)
752752- AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
753753- else
754754- AdapterObject->IgnoreCount = 0;
755755-756756- AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
757757- AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
758758- AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
759759- AdapterObject->MasterDevice = DeviceDescription->Master;
760760- *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
761761-762762- /*
763763- * For non-(E)ISA adapters we have already done all the work. On the
764764- * other hand for (E)ISA adapters we must still setup the DMA modes
765765- * and prepare the controller.
766766- */
767767-768768- if (EisaAdapter)
769769- {
770770- if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription))
771771- {
772772- ObDereferenceObject(AdapterObject);
773773- return NULL;
774774- }
775775- }
776776-777777- return AdapterObject;
778778-}
779779-780780-/**
781781- * @name HalpGetDmaAdapter
782782- *
783783- * Internal routine to allocate PnP DMA adapter object. It's exported through
784784- * HalDispatchTable and used by IoGetDmaAdapter.
785785- *
786786- * @see HalGetAdapter
787787- */
788788-789789-PDMA_ADAPTER NTAPI
790790-HalpGetDmaAdapter(
791791- IN PVOID Context,
792792- IN PDEVICE_DESCRIPTION DeviceDescription,
793793- OUT PULONG NumberOfMapRegisters)
794794-{
795795- return &HalGetAdapter(DeviceDescription, NumberOfMapRegisters)->DmaHeader;
796796-}
797797-798798-/**
799799- * @name HalPutDmaAdapter
800800- *
801801- * Internal routine to free DMA adapter and resources for reuse. It's exported
802802- * using the DMA_OPERATIONS interface by HalGetAdapter.
803803- *
804804- * @see HalGetAdapter
805805- */
806806-807807-VOID NTAPI
808808-HalPutDmaAdapter(
809809- PADAPTER_OBJECT AdapterObject)
810810-{
811811- if (AdapterObject->ChannelNumber == 0xFF)
812812- {
813813- KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
814814- FALSE, NULL);
815815- RemoveEntryList(&AdapterObject->AdapterList);
816816- KeSetEvent(&HalpDmaLock, 0, 0);
817817- }
818818-819819- ObDereferenceObject(AdapterObject);
820820-}
821821-822822-/**
823823- * @name HalAllocateCommonBuffer
824824- *
825825- * Allocates memory that is visible to both the processor(s) and the DMA
826826- * device.
827827- *
828828- * @param AdapterObject
829829- * Adapter object representing the bus master or system dma controller.
830830- * @param Length
831831- * Number of bytes to allocate.
832832- * @param LogicalAddress
833833- * Logical address the driver can use to access the buffer.
834834- * @param CacheEnabled
835835- * Specifies if the memory can be cached.
836836- *
837837- * @return The base virtual address of the memory allocated or NULL on failure.
838838- *
839839- * @remarks
840840- * On real NT x86 systems the CacheEnabled parameter is ignored, we honour
841841- * it. If it proves to cause problems change it.
842842- *
843843- * @see HalFreeCommonBuffer
844844- *
845845- * @implemented
846846- */
847847-848848-PVOID NTAPI
849849-HalAllocateCommonBuffer(
850850- PADAPTER_OBJECT AdapterObject,
851851- ULONG Length,
852852- PPHYSICAL_ADDRESS LogicalAddress,
853853- BOOLEAN CacheEnabled)
854854-{
855855- PHYSICAL_ADDRESS LowestAcceptableAddress;
856856- PHYSICAL_ADDRESS HighestAcceptableAddress;
857857- PHYSICAL_ADDRESS BoundryAddressMultiple;
858858- PVOID VirtualAddress;
859859-860860- LowestAcceptableAddress.QuadPart = 0;
861861- HighestAcceptableAddress =
862862- HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
863863- BoundryAddressMultiple.QuadPart = 0;
864864-865865- /*
866866- * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
867867- * slave DMA devices the 64Kb boundary mustn't be crossed since the
868868- * controller wouldn't be able to handle it.
869869- */
870870-871871- if (AdapterObject->MasterDevice)
872872- BoundryAddressMultiple.HighPart = 1;
873873- else
874874- BoundryAddressMultiple.LowPart = 0x10000;
875875-876876- VirtualAddress = MmAllocateContiguousMemorySpecifyCache(
877877- Length, LowestAcceptableAddress, HighestAcceptableAddress,
878878- BoundryAddressMultiple, CacheEnabled ? MmCached : MmNonCached);
879879- if (VirtualAddress == NULL)
880880- return NULL;
881881-882882- *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
883883-884884- return VirtualAddress;
885885-}
886886-887887-/**
888888- * @name HalFreeCommonBuffer
889889- *
890890- * Free common buffer allocated with HalAllocateCommonBuffer.
891891- *
892892- * @see HalAllocateCommonBuffer
893893- *
894894- * @implemented
895895- */
896896-897897-VOID NTAPI
898898-HalFreeCommonBuffer(
899899- PADAPTER_OBJECT AdapterObject,
900900- ULONG Length,
901901- PHYSICAL_ADDRESS LogicalAddress,
902902- PVOID VirtualAddress,
903903- BOOLEAN CacheEnabled)
904904-{
905905- MmFreeContiguousMemory(VirtualAddress);
906906-}
907907-908908-/**
909909- * @name HalpDmaGetDmaAlignment
910910- *
911911- * Internal routine to return the DMA alignment requirement. It's exported
912912- * using the DMA_OPERATIONS interface by HalGetAdapter.
913913- *
914914- * @see HalGetAdapter
915915- */
916916-917917-ULONG NTAPI
918918-HalpDmaGetDmaAlignment(
919919- PADAPTER_OBJECT AdapterObject)
920920-{
921921- return 1;
922922-}
923923-924924-/*
925925- * @name HalReadDmaCounter
926926- *
927927- * Read DMA operation progress counter.
928928- *
929929- * @implemented
930930- */
931931-932932-ULONG NTAPI
933933-HalReadDmaCounter(
934934- PADAPTER_OBJECT AdapterObject)
935935-{
936936- KIRQL OldIrql;
937937- ULONG Count, OldCount;
938938-939939- ASSERT(!AdapterObject->MasterDevice);
940940-941941- /*
942942- * Acquire the master adapter lock since we're going to mess with the
943943- * system DMA controller registers and we really don't want anyone
944944- * to do the same at the same time.
945945- */
946946-947947- KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
948948-949949- /* Send the request to the specific controller. */
950950- if (AdapterObject->AdapterNumber == 1)
951951- {
952952- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
953953-954954- Count = 0xffff00;
955955- do
956956- {
957957- OldCount = Count;
958958- /* Send Reset */
959959- WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
960960- /* Read Count */
961961- Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
962962- [AdapterObject->ChannelNumber].DmaBaseCount);
963963- Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
964964- [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
965965- }
966966- while (0xffff00 & (OldCount ^ Count));
967967- }
968968- else
969969- {
970970- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
971971-972972- Count = 0xffff00;
973973- do
974974- {
975975- OldCount = Count;
976976- /* Send Reset */
977977- WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
978978- /* Read Count */
979979- Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
980980- [AdapterObject->ChannelNumber].DmaBaseCount);
981981- Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
982982- [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
983983- }
984984- while (0xffff00 & (OldCount ^ Count));
985985- }
986986-987987- KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
988988-989989- Count++;
990990- Count &= 0xffff;
991991- if (AdapterObject->Width16Bits)
992992- Count *= 2;
993993-994994- return Count;
995995-}
996996-997997-/**
998998- * @name HalpGrowMapBufferWorker
999999- *
10001000- * Helper routine of HalAllocateAdapterChannel for allocating map registers
10011001- * at PASSIVE_LEVEL in work item.
10021002- */
10031003-10041004-VOID NTAPI
10051005-HalpGrowMapBufferWorker(PVOID DeferredContext)
10061006-{
10071007- PGROW_WORK_ITEM WorkItem = (PGROW_WORK_ITEM)DeferredContext;
10081008- KIRQL OldIrql;
10091009- BOOLEAN Succeeded;
10101010-10111011- /*
10121012- * Try to allocate new map registers for the adapter.
10131013- *
10141014- * NOTE: The NT implementation actually tries to allocate more map
10151015- * registers than needed as an optimization.
10161016- */
10171017-10181018- KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode,
10191019- FALSE, NULL);
10201020- Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
10211021- WorkItem->NumberOfMapRegisters);
10221022- KeSetEvent(&HalpDmaLock, 0, 0);
10231023-10241024- if (Succeeded)
10251025- {
10261026- /*
10271027- * Flush the adapter queue now that new map registers are ready. The
10281028- * easiest way to do that is to call IoFreeMapRegisters to not free
10291029- * any registers. Note that we use the magic (PVOID)2 map register
10301030- * base to bypass the parameter checking.
10311031- */
10321032-10331033- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
10341034- IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
10351035- KeLowerIrql(OldIrql);
10361036- }
10371037-10381038- ExFreePool(WorkItem);
10391039-}
10401040-10411041-/**
10421042- * @name HalAllocateAdapterChannel
10431043- *
10441044- * Setup map registers for an adapter object.
10451045- *
10461046- * @param AdapterObject
10471047- * Pointer to an ADAPTER_OBJECT to set up.
10481048- * @param WaitContextBlock
10491049- * Context block to be used with ExecutionRoutine.
10501050- * @param NumberOfMapRegisters
10511051- * Number of map registers requested.
10521052- * @param ExecutionRoutine
10531053- * Callback to call when map registers are allocated.
10541054- *
10551055- * @return
10561056- * If not enough map registers can be allocated then
10571057- * STATUS_INSUFFICIENT_RESOURCES is returned. If the function
10581058- * succeeds or the callback is queued for later delivering then
10591059- * STATUS_SUCCESS is returned.
10601060- *
10611061- * @see IoFreeAdapterChannel
10621062- *
10631063- * @implemented
10641064- */
10651065-10661066-NTSTATUS NTAPI
10671067-HalAllocateAdapterChannel(
10681068- PADAPTER_OBJECT AdapterObject,
10691069- PWAIT_CONTEXT_BLOCK WaitContextBlock,
10701070- ULONG NumberOfMapRegisters,
10711071- PDRIVER_CONTROL ExecutionRoutine)
10721072-{
10731073- PADAPTER_OBJECT MasterAdapter;
10741074- PGROW_WORK_ITEM WorkItem;
10751075- ULONG Index = MAXULONG;
10761076- ULONG Result;
10771077- KIRQL OldIrql;
10781078-10791079- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
10801080-10811081- /* Set up the wait context block in case we can't run right away. */
10821082- WaitContextBlock->DeviceRoutine = ExecutionRoutine;
10831083- WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
10841084-10851085- /* Returns true if queued, else returns false and sets the queue to busy */
10861086- if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
10871087- return STATUS_SUCCESS;
10881088-10891089- MasterAdapter = AdapterObject->MasterAdapter;
10901090-10911091- AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
10921092- AdapterObject->CurrentWcb = WaitContextBlock;
10931093-10941094- if (NumberOfMapRegisters && AdapterObject->NeedsMapRegisters)
10951095- {
10961096- if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
10971097- {
10981098- AdapterObject->NumberOfMapRegisters = 0;
10991099- IoFreeAdapterChannel(AdapterObject);
11001100- return STATUS_INSUFFICIENT_RESOURCES;
11011101- }
11021102-11031103- /*
11041104- * Get the map registers. This is partly complicated by the fact
11051105- * that new map registers can only be allocated at PASSIVE_LEVEL
11061106- * and we're currently at DISPATCH_LEVEL. The following code has
11071107- * two code paths:
11081108- *
11091109- * - If there is no adapter queued for map register allocation,
11101110- * try to see if enough contiguous map registers are present.
11111111- * In case they're we can just get them and proceed further.
11121112- *
11131113- * - If some adapter is already present in the queue we must
11141114- * respect the order of adapters asking for map registers and
11151115- * so the fast case described above can't take place.
11161116- * This case is also entered if not enough coniguous map
11171117- * registers are present.
11181118- *
11191119- * A work queue item is allocated and queued, the adapter is
11201120- * also queued into the master adapter queue. The worker
11211121- * routine does the job of allocating the map registers at
11221122- * PASSIVE_LEVEL and calling the ExecutionRoutine.
11231123- */
11241124-11251125- OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
11261126-11271127- if (IsListEmpty(&MasterAdapter->AdapterQueue))
11281128- {
11291129- Index = RtlFindClearBitsAndSet(
11301130- MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
11311131- if (Index != MAXULONG)
11321132- {
11331133- AdapterObject->MapRegisterBase =
11341134- MasterAdapter->MapRegisterBase + Index;
11351135- if (!AdapterObject->ScatterGather)
11361136- {
11371137- AdapterObject->MapRegisterBase =
11381138- (PROS_MAP_REGISTER_ENTRY)(
11391139- (ULONG_PTR)AdapterObject->MapRegisterBase |
11401140- MAP_BASE_SW_SG);
11411141- }
11421142- }
11431143- }
11441144-11451145- if (Index == MAXULONG)
11461146- {
11471147- WorkItem = ExAllocatePoolWithTag(
11481148- NonPagedPool, sizeof(GROW_WORK_ITEM), TAG_DMA);
11491149- if (WorkItem == NULL)
11501150- {
11511151- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
11521152- AdapterObject->NumberOfMapRegisters = 0;
11531153- IoFreeAdapterChannel(AdapterObject);
11541154- return STATUS_INSUFFICIENT_RESOURCES;
11551155- }
11561156-11571157- InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
11581158-11591159- ExInitializeWorkItem(
11601160- &WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem);
11611161- WorkItem->AdapterObject = AdapterObject;
11621162- WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
11631163-11641164- ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
11651165-11661166- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
11671167-11681168- return STATUS_SUCCESS;
11691169- }
11701170-11711171- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
11721172- }
11731173- else
11741174- {
11751175- AdapterObject->MapRegisterBase = NULL;
11761176- AdapterObject->NumberOfMapRegisters = 0;
11771177- }
11781178-11791179- AdapterObject->CurrentWcb = WaitContextBlock;
11801180-11811181- Result = ExecutionRoutine(
11821182- WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
11831183- AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
11841184-11851185- /*
11861186- * Possible return values:
11871187- *
11881188- * - KeepObject
11891189- * Don't free any resources, the ADAPTER_OBJECT is still in use and
11901190- * the caller will call IoFreeAdapterChannel later.
11911191- *
11921192- * - DeallocateObject
11931193- * Deallocate the map registers and release the ADAPTER_OBJECT, so
11941194- * someone else can use it.
11951195- *
11961196- * - DeallocateObjectKeepRegisters
11971197- * Release the ADAPTER_OBJECT, but hang on to the map registers. The
11981198- * client will later call IoFreeMapRegisters.
11991199- *
12001200- * NOTE:
12011201- * IoFreeAdapterChannel runs the queue, so it must be called unless
12021202- * the adapter object is not to be freed.
12031203- */
12041204-12051205- if (Result == DeallocateObject)
12061206- {
12071207- IoFreeAdapterChannel(AdapterObject);
12081208- }
12091209- else if (Result == DeallocateObjectKeepRegisters)
12101210- {
12111211- AdapterObject->NumberOfMapRegisters = 0;
12121212- IoFreeAdapterChannel(AdapterObject);
12131213- }
12141214-12151215- return STATUS_SUCCESS;
12161216-}
12171217-12181218-/**
12191219- * @name IoFreeAdapterChannel
12201220- *
12211221- * Free DMA resources allocated by IoAllocateAdapterChannel.
12221222- *
12231223- * @param AdapterObject
12241224- * Adapter object with resources to free.
12251225- *
12261226- * @remarks
12271227- * This function releases map registers registers assigned to the DMA
12281228- * adapter. After releasing the adapter, it checks the adapter's queue
12291229- * and runs each queued device object in series until the queue is
12301230- * empty. This is the only way the device queue is emptied.
12311231- *
12321232- * @see IoAllocateAdapterChannel
12331233- *
12341234- * @implemented
12351235- */
12361236-12371237-VOID NTAPI
12381238-IoFreeAdapterChannel(
12391239- PADAPTER_OBJECT AdapterObject)
12401240-{
12411241- PADAPTER_OBJECT MasterAdapter;
12421242- PKDEVICE_QUEUE_ENTRY DeviceQueueEntry;
12431243- PWAIT_CONTEXT_BLOCK WaitContextBlock;
12441244- ULONG Index = MAXULONG;
12451245- ULONG Result;
12461246- KIRQL OldIrql;
12471247-12481248- MasterAdapter = AdapterObject->MasterAdapter;
12491249-12501250- for (;;)
12511251- {
12521252- /*
12531253- * To keep map registers, call here with AdapterObject->
12541254- * NumberOfMapRegisters set to zero. This trick is used in
12551255- * HalAllocateAdapterChannel for example.
12561256- */
12571257- if (AdapterObject->NumberOfMapRegisters)
12581258- {
12591259- IoFreeMapRegisters(
12601260- AdapterObject,
12611261- AdapterObject->MapRegisterBase,
12621262- AdapterObject->NumberOfMapRegisters);
12631263- }
12641264-12651265- DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
12661266- if (DeviceQueueEntry == NULL)
12671267- {
12681268- break;
12691269- }
12701270-12711271- WaitContextBlock = CONTAINING_RECORD(
12721272- DeviceQueueEntry,
12731273- WAIT_CONTEXT_BLOCK,
12741274- WaitQueueEntry);
12751275-12761276- AdapterObject->CurrentWcb = WaitContextBlock;
12771277- AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
12781278-12791279- if (WaitContextBlock->NumberOfMapRegisters &&
12801280- AdapterObject->MasterAdapter)
12811281- {
12821282- OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
12831283-12841284- if (IsListEmpty(&MasterAdapter->AdapterQueue))
12851285- {
12861286- Index = RtlFindClearBitsAndSet(
12871287- MasterAdapter->MapRegisters,
12881288- WaitContextBlock->NumberOfMapRegisters, 0);
12891289- if (Index != MAXULONG)
12901290- {
12911291- AdapterObject->MapRegisterBase =
12921292- MasterAdapter->MapRegisterBase + Index;
12931293- if (!AdapterObject->ScatterGather)
12941294- {
12951295- AdapterObject->MapRegisterBase =
12961296- (PROS_MAP_REGISTER_ENTRY)(
12971297- (ULONG_PTR)AdapterObject->MapRegisterBase |
12981298- MAP_BASE_SW_SG);
12991299- }
13001300- }
13011301- }
13021302-13031303- if (Index == MAXULONG)
13041304- {
13051305- InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
13061306- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
13071307- break;
13081308- }
13091309-13101310- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
13111311- }
13121312- else
13131313- {
13141314- AdapterObject->MapRegisterBase = NULL;
13151315- AdapterObject->NumberOfMapRegisters = 0;
13161316- }
13171317-13181318- /* Call the adapter control routine. */
13191319- Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(
13201320- WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
13211321- AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
13221322-13231323- switch (Result)
13241324- {
13251325- case KeepObject:
13261326- /*
13271327- * We're done until the caller manually calls IoFreeAdapterChannel
13281328- * or IoFreeMapRegisters.
13291329- */
13301330- return;
13311331-13321332- case DeallocateObjectKeepRegisters:
13331333- /*
13341334- * Hide the map registers so they aren't deallocated next time
13351335- * around.
13361336- */
13371337- AdapterObject->NumberOfMapRegisters = 0;
13381338- break;
13391339-13401340- default:
13411341- break;
13421342- }
13431343- }
13441344-}
13451345-13461346-/**
13471347- * @name IoFreeMapRegisters
13481348- *
13491349- * Free map registers reserved by the system for a DMA.
13501350- *
13511351- * @param AdapterObject
13521352- * DMA adapter to free map registers on.
13531353- * @param MapRegisterBase
13541354- * Handle to map registers to free.
13551355- * @param NumberOfRegisters
13561356- * Number of map registers to be freed.
13571357- *
13581358- * @implemented
13591359- */
13601360-13611361-VOID NTAPI
13621362-IoFreeMapRegisters(
13631363- IN PADAPTER_OBJECT AdapterObject,
13641364- IN PVOID MapRegisterBase,
13651365- IN ULONG NumberOfMapRegisters)
13661366-{
13671367- PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
13681368- PLIST_ENTRY ListEntry;
13691369- KIRQL OldIrql;
13701370- ULONG Index;
13711371- ULONG Result;
13721372-13731373- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
13741374-13751375- if (MasterAdapter == NULL || MapRegisterBase == NULL)
13761376- return;
13771377-13781378- OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
13791379-13801380- if (NumberOfMapRegisters != 0)
13811381- {
13821382- PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
13831383-13841384- RealMapRegisterBase =
13851385- (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
13861386- RtlClearBits(MasterAdapter->MapRegisters,
13871387- RealMapRegisterBase - MasterAdapter->MapRegisterBase,
13881388- NumberOfMapRegisters);
13891389- }
13901390-13911391- /*
13921392- * Now that we freed few map registers it's time to look at the master
13931393- * adapter queue and see if there is someone waiting for map registers.
13941394- */
13951395-13961396- while (!IsListEmpty(&MasterAdapter->AdapterQueue))
13971397- {
13981398- ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
13991399- AdapterObject = CONTAINING_RECORD(
14001400- ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
14011401-14021402- Index = RtlFindClearBitsAndSet(
14031403- MasterAdapter->MapRegisters,
14041404- AdapterObject->NumberOfMapRegisters,
14051405- MasterAdapter->NumberOfMapRegisters);
14061406- if (Index == MAXULONG)
14071407- {
14081408- InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
14091409- break;
14101410- }
14111411-14121412- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
14131413-14141414- AdapterObject->MapRegisterBase =
14151415- MasterAdapter->MapRegisterBase + Index;
14161416- if (!AdapterObject->ScatterGather)
14171417- {
14181418- AdapterObject->MapRegisterBase =
14191419- (PROS_MAP_REGISTER_ENTRY)(
14201420- (ULONG_PTR)AdapterObject->MapRegisterBase |
14211421- MAP_BASE_SW_SG);
14221422- }
14231423-14241424- Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(
14251425- AdapterObject->CurrentWcb->DeviceObject,
14261426- AdapterObject->CurrentWcb->CurrentIrp,
14271427- AdapterObject->MapRegisterBase,
14281428- AdapterObject->CurrentWcb->DeviceContext);
14291429-14301430- switch (Result)
14311431- {
14321432- case DeallocateObjectKeepRegisters:
14331433- AdapterObject->NumberOfMapRegisters = 0;
14341434- /* fall through */
14351435-14361436- case DeallocateObject:
14371437- if (AdapterObject->NumberOfMapRegisters)
14381438- {
14391439- OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
14401440- RtlClearBits(MasterAdapter->MapRegisters,
14411441- AdapterObject->MapRegisterBase -
14421442- MasterAdapter->MapRegisterBase,
14431443- AdapterObject->NumberOfMapRegisters);
14441444- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
14451445- }
14461446- IoFreeAdapterChannel(AdapterObject);
14471447- break;
14481448-14491449- default:
14501450- break;
14511451- }
14521452-14531453- OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
14541454- }
14551455-14561456- KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
14571457-}
14581458-14591459-/**
14601460- * @name HalpCopyBufferMap
14611461- *
14621462- * Helper function for copying data from/to map register buffers.
14631463- *
14641464- * @see IoFlushAdapterBuffers, IoMapTransfer
14651465- */
14661466-14671467-VOID NTAPI
14681468-HalpCopyBufferMap(
14691469- PMDL Mdl,
14701470- PROS_MAP_REGISTER_ENTRY MapRegisterBase,
14711471- PVOID CurrentVa,
14721472- ULONG Length,
14731473- BOOLEAN WriteToDevice)
14741474-{
14751475- ULONG CurrentLength;
14761476- ULONG_PTR CurrentAddress;
14771477- ULONG ByteOffset;
14781478- PVOID VirtualAddress;
14791479-14801480- VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
14811481- if (VirtualAddress == NULL)
14821482- {
14831483- /*
14841484- * NOTE: On real NT a mechanism with reserved pages is implemented
14851485- * to handle this case in a slow, but graceful non-fatal way.
14861486- */
14871487- KeBugCheckEx(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0);
14881488- }
14891489-14901490- CurrentAddress = (ULONG_PTR)VirtualAddress +
14911491- (ULONG_PTR)CurrentVa -
14921492- (ULONG_PTR)MmGetMdlVirtualAddress(Mdl);
14931493-14941494- while (Length > 0)
14951495- {
14961496- ByteOffset = BYTE_OFFSET(CurrentAddress);
14971497- CurrentLength = PAGE_SIZE - ByteOffset;
14981498- if (CurrentLength > Length)
14991499- CurrentLength = Length;
15001500-15011501- if (WriteToDevice)
15021502- {
15031503- RtlCopyMemory(
15041504- (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
15051505- (PVOID)CurrentAddress,
15061506- CurrentLength);
15071507- }
15081508- else
15091509- {
15101510- RtlCopyMemory(
15111511- (PVOID)CurrentAddress,
15121512- (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
15131513- CurrentLength);
15141514- }
15151515-15161516- Length -= CurrentLength;
15171517- CurrentAddress += CurrentLength;
15181518- MapRegisterBase++;
15191519- }
15201520-}
15211521-15221522-/**
15231523- * @name IoFlushAdapterBuffers
15241524- *
15251525- * Flush any data remaining in the DMA controller's memory into the host
15261526- * memory.
15271527- *
15281528- * @param AdapterObject
15291529- * The adapter object to flush.
15301530- * @param Mdl
15311531- * Original MDL to flush data into.
15321532- * @param MapRegisterBase
15331533- * Map register base that was just used by IoMapTransfer, etc.
15341534- * @param CurrentVa
15351535- * Offset into Mdl to be flushed into, same as was passed to
15361536- * IoMapTransfer.
15371537- * @param Length
15381538- * Length of the buffer to be flushed into.
15391539- * @param WriteToDevice
15401540- * TRUE if it's a write, FALSE if it's a read.
15411541- *
15421542- * @return TRUE in all cases.
15431543- *
15441544- * @remarks
15451545- * This copies data from the map register-backed buffer to the user's
15461546- * target buffer. Data are not in the user buffer until this function
15471547- * is called.
15481548- * For slave DMA transfers the controller channel is masked effectively
15491549- * stopping the current transfer.
15501550- *
15511551- * @unimplemented.
15521552- */
15531553-15541554-BOOLEAN NTAPI
15551555-IoFlushAdapterBuffers(
15561556- PADAPTER_OBJECT AdapterObject,
15571557- PMDL Mdl,
15581558- PVOID MapRegisterBase,
15591559- PVOID CurrentVa,
15601560- ULONG Length,
15611561- BOOLEAN WriteToDevice)
15621562-{
15631563- BOOLEAN SlaveDma = FALSE;
15641564- PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
15651565- PHYSICAL_ADDRESS HighestAcceptableAddress;
15661566- PHYSICAL_ADDRESS PhysicalAddress;
15671567- PPFN_NUMBER MdlPagesPtr;
15681568-15691569- ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
15701570-15711571- if (AdapterObject != NULL && !AdapterObject->MasterDevice)
15721572- {
15731573- /* Mask out (disable) the DMA channel. */
15741574- if (AdapterObject->AdapterNumber == 1)
15751575- {
15761576- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
15771577- WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
15781578- AdapterObject->ChannelNumber | DMA_SETMASK);
15791579- }
15801580- else
15811581- {
15821582- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
15831583- WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
15841584- AdapterObject->ChannelNumber | DMA_SETMASK);
15851585- }
15861586- SlaveDma = TRUE;
15871587- }
15881588-15891589- /* This can happen if the device supports hardware scatter/gather. */
15901590- if (MapRegisterBase == NULL)
15911591- return TRUE;
15921592-15931593- RealMapRegisterBase =
15941594- (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
15951595-15961596- if (!WriteToDevice)
15971597- {
15981598- if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
15991599- {
16001600- if (RealMapRegisterBase->Counter != MAXULONG)
16011601- {
16021602- if (SlaveDma && !AdapterObject->IgnoreCount)
16031603- Length -= HalReadDmaCounter(AdapterObject);
16041604- HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
16051605- }
16061606- }
16071607- else
16081608- {
16091609- MdlPagesPtr = MmGetMdlPfnArray(Mdl);
16101610- MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
16111611-16121612- PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
16131613- PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
16141614-16151615- HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
16161616- if (PhysicalAddress.QuadPart + Length >
16171617- HighestAcceptableAddress.QuadPart)
16181618- {
16191619- HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
16201620- }
16211621- }
16221622- }
16231623-16241624- RealMapRegisterBase->Counter = 0;
16251625-16261626- return TRUE;
16271627-}
16281628-16291629-/**
16301630- * @name IoMapTransfer
16311631- *
16321632- * Map a DMA for transfer and do the DMA if it's a slave.
16331633- *
16341634- * @param AdapterObject
16351635- * Adapter object to do the DMA on. Bus-master may pass NULL.
16361636- * @param Mdl
16371637- * Locked-down user buffer to DMA in to or out of.
16381638- * @param MapRegisterBase
16391639- * Handle to map registers to use for this dma.
16401640- * @param CurrentVa
16411641- * Index into Mdl to transfer into/out of.
16421642- * @param Length
16431643- * Length of transfer. Number of bytes actually transferred on
16441644- * output.
16451645- * @param WriteToDevice
16461646- * TRUE if it's an output DMA, FALSE otherwise.
16471647- *
16481648- * @return
16491649- * A logical address that can be used to program a DMA controller, it's
16501650- * not meaningful for slave DMA device.
16511651- *
16521652- * @remarks
16531653- * This function does a copyover to contiguous memory <16MB represented
16541654- * by the map registers if needed. If the buffer described by MDL can be
16551655- * used as is no copyover is done.
16561656- * If it's a slave transfer, this function actually performs it.
16571657- *
16581658- * @implemented
16591659- */
16601660-16611661-PHYSICAL_ADDRESS NTAPI
16621662-IoMapTransfer(
16631663- IN PADAPTER_OBJECT AdapterObject,
16641664- IN PMDL Mdl,
16651665- IN PVOID MapRegisterBase,
16661666- IN PVOID CurrentVa,
16671667- IN OUT PULONG Length,
16681668- IN BOOLEAN WriteToDevice)
16691669-{
16701670- PPFN_NUMBER MdlPagesPtr;
16711671- PFN_NUMBER MdlPage1, MdlPage2;
16721672- ULONG ByteOffset;
16731673- ULONG TransferOffset;
16741674- ULONG TransferLength;
16751675- BOOLEAN UseMapRegisters;
16761676- PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
16771677- PHYSICAL_ADDRESS PhysicalAddress;
16781678- PHYSICAL_ADDRESS HighestAcceptableAddress;
16791679- ULONG Counter;
16801680- DMA_MODE AdapterMode;
16811681- KIRQL OldIrql;
16821682-16831683- /*
16841684- * Precalculate some values that are used in all cases.
16851685- *
16861686- * ByteOffset is offset inside the page at which the transfer starts.
16871687- * MdlPagesPtr is pointer inside the MDL page chain at the page where the
16881688- * transfer start.
16891689- * PhysicalAddress is physical address corresponding to the transfer
16901690- * start page and offset.
16911691- * TransferLength is the initial length of the transfer, which is reminder
16921692- * of the first page. The actual value is calculated below.
16931693- *
16941694- * Note that all the variables can change during the processing which
16951695- * takes place below. These are just initial values.
16961696- */
16971697-16981698- ByteOffset = BYTE_OFFSET(CurrentVa);
16991699-17001700- MdlPagesPtr = MmGetMdlPfnArray(Mdl);
17011701- MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
17021702-17031703- PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
17041704- PhysicalAddress.QuadPart += ByteOffset;
17051705-17061706- TransferLength = PAGE_SIZE - ByteOffset;
17071707-17081708- /*
17091709- * Special case for bus master adapters with S/G support. We can directly
17101710- * use the buffer specified by the MDL, so not much work has to be done.
17111711- *
17121712- * Just return the passed VA's corresponding physical address and update
17131713- * length to the number of physically contiguous bytes found. Also
17141714- * pages crossing the 4Gb boundary aren't considered physically contiguous.
17151715- */
17161716-17171717- if (MapRegisterBase == NULL)
17181718- {
17191719- while (TransferLength < *Length)
17201720- {
17211721- MdlPage1 = *MdlPagesPtr;
17221722- MdlPage2 = *(MdlPagesPtr + 1);
17231723- if (MdlPage1 + 1 != MdlPage2)
17241724- break;
17251725- if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF)
17261726- break;
17271727- TransferLength += PAGE_SIZE;
17281728- MdlPagesPtr++;
17291729- }
17301730-17311731- if (TransferLength < *Length)
17321732- *Length = TransferLength;
17331733-17341734- return PhysicalAddress;
17351735- }
17361736-17371737- /*
17381738- * The code below applies to slave DMA adapters and bus master adapters
17391739- * without hardward S/G support.
17401740- */
17411741-17421742- RealMapRegisterBase =
17431743- (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
17441744-17451745- /*
17461746- * Try to calculate the size of the transfer. We can only transfer
17471747- * pages that are physically contiguous and that don't cross the
17481748- * 64Kb boundary (this limitation applies only for ISA controllers).
17491749- */
17501750-17511751- while (TransferLength < *Length)
17521752- {
17531753- MdlPage1 = *MdlPagesPtr;
17541754- MdlPage2 = *(MdlPagesPtr + 1);
17551755- if (MdlPage1 + 1 != MdlPage2)
17561756- break;
17571757- if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF))
17581758- break;
17591759- TransferLength += PAGE_SIZE;
17601760- MdlPagesPtr++;
17611761- }
17621762-17631763- if (TransferLength > *Length)
17641764- TransferLength = *Length;
17651765-17661766- /*
17671767- * If we're about to simulate software S/G and not all the pages are
17681768- * physically contiguous then we must use the map registers to store
17691769- * the data and allow the whole transfer to proceed at once.
17701770- */
17711771-17721772- if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG &&
17731773- TransferLength < *Length)
17741774- {
17751775- UseMapRegisters = TRUE;
17761776- PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
17771777- PhysicalAddress.QuadPart += ByteOffset;
17781778- TransferLength = *Length;
17791779- RealMapRegisterBase->Counter = MAXULONG;
17801780- Counter = 0;
17811781- }
17821782- else
17831783- {
17841784- /*
17851785- * This is ordinary DMA transfer, so just update the progress
17861786- * counters. These are used by IoFlushAdapterBuffers to track
17871787- * the transfer progress.
17881788- */
17891789-17901790- UseMapRegisters = FALSE;
17911791- Counter = RealMapRegisterBase->Counter;
17921792- RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
17931793-17941794- /*
17951795- * Check if the buffer doesn't exceed the highest physical address
17961796- * limit of the device. In that case we must use the map registers to
17971797- * store the data.
17981798- */
17991799-18001800- HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
18011801- if (PhysicalAddress.QuadPart + TransferLength >
18021802- HighestAcceptableAddress.QuadPart)
18031803- {
18041804- UseMapRegisters = TRUE;
18051805- PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
18061806- PhysicalAddress.QuadPart += ByteOffset;
18071807- if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
18081808- {
18091809- RealMapRegisterBase->Counter = MAXULONG;
18101810- Counter = 0;
18111811- }
18121812- }
18131813- }
18141814-18151815- /*
18161816- * If we decided to use the map registers (see above) and we're about
18171817- * to transfer data to the device then copy the buffers into the map
18181818- * register memory.
18191819- */
18201820-18211821- if (UseMapRegisters && WriteToDevice)
18221822- {
18231823- HalpCopyBufferMap(Mdl, RealMapRegisterBase + Counter,
18241824- CurrentVa, TransferLength, WriteToDevice);
18251825- }
18261826-18271827- /*
18281828- * Return the length of transfer that actually takes place.
18291829- */
18301830-18311831- *Length = TransferLength;
18321832-18331833- /*
18341834- * If we're doing slave (system) DMA then program the (E)ISA controller
18351835- * to actually start the transfer.
18361836- */
18371837-18381838- if (AdapterObject != NULL && !AdapterObject->MasterDevice)
18391839- {
18401840- AdapterMode = AdapterObject->AdapterMode;
18411841-18421842- if (WriteToDevice)
18431843- {
18441844- AdapterMode.TransferType = WRITE_TRANSFER;
18451845- }
18461846- else
18471847- {
18481848- AdapterMode.TransferType = READ_TRANSFER;
18491849- if (AdapterObject->IgnoreCount)
18501850- {
18511851- RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress +
18521852- ByteOffset, TransferLength);
18531853- }
18541854- }
18551855-18561856- TransferOffset = PhysicalAddress.LowPart & 0xFFFF;
18571857- if (AdapterObject->Width16Bits)
18581858- {
18591859- TransferLength >>= 1;
18601860- TransferOffset >>= 1;
18611861- }
18621862-18631863- OldIrql = KfAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock);
18641864-18651865- if (AdapterObject->AdapterNumber == 1)
18661866- {
18671867- PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
18681868-18691869- /* Reset Register */
18701870- WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
18711871- /* Set the Mode */
18721872- WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
18731873- /* Set the Offset Register */
18741874- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
18751875- (UCHAR)(TransferOffset));
18761876- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
18771877- (UCHAR)(TransferOffset >> 8));
18781878- /* Set the Page Register */
18791879- WRITE_PORT_UCHAR(AdapterObject->PagePort +
18801880- FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
18811881- (UCHAR)(PhysicalAddress.LowPart >> 16));
18821882- if (HalpEisaDma)
18831883- {
18841884- WRITE_PORT_UCHAR(AdapterObject->PagePort +
18851885- FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
18861886- 0);
18871887- }
18881888- /* Set the Length */
18891889- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
18901890- (UCHAR)(TransferLength - 1));
18911891- WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
18921892- (UCHAR)((TransferLength - 1) >> 8));
18931893- /* Unmask the Channel */
18941894- WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
18951895- AdapterObject->ChannelNumber | DMA_CLEARMASK);
18961896- }
18971897- else
18981898- {
18991899- PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
19001900-19011901- /* Reset Register */
19021902- WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
19031903- /* Set the Mode */
19041904- WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
19051905- /* Set the Offset Register */
19061906- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
19071907- (UCHAR)(TransferOffset));
19081908- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
19091909- (UCHAR)(TransferOffset >> 8));
19101910- /* Set the Page Register */
19111911- WRITE_PORT_UCHAR(AdapterObject->PagePort +
19121912- FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
19131913- (UCHAR)(PhysicalAddress.u.LowPart >> 16));
19141914- if (HalpEisaDma)
19151915- {
19161916- WRITE_PORT_UCHAR(AdapterObject->PagePort +
19171917- FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
19181918- 0);
19191919- }
19201920- /* Set the Length */
19211921- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
19221922- (UCHAR)(TransferLength - 1));
19231923- WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
19241924- (UCHAR)((TransferLength - 1) >> 8));
19251925- /* Unmask the Channel */
19261926- WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
19271927- AdapterObject->ChannelNumber | DMA_CLEARMASK);
19281928- }
19291929-19301930- KfReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
19311931- }
19321932-19331933- /*
19341934- * Return physical address of the buffer with data that is used for the
19351935- * transfer. It can either point inside the Mdl that was passed by the
19361936- * caller or into the map registers if the Mdl buffer can't be used
19371937- * directly.
19381938- */
19391939-19401940- return PhysicalAddress;
19411941-}
19421942-19431943-/**
19441944- * @name HalFlushCommonBuffer
19451945- *
19461946- * @implemented
19471947- */
19481948-BOOLEAN
19491949-NTAPI
19501950-HalFlushCommonBuffer(IN PADAPTER_OBJECT AdapterObject,
19511951- IN ULONG Length,
19521952- IN PHYSICAL_ADDRESS LogicalAddress,
19531953- IN PVOID VirtualAddress)
19541954-{
19551955- /* Function always returns true */
19561956- return TRUE;
19571957-}
19581958-19591959-/*
19601960- * @implemented
19611961- */
19621962-PVOID
19631963-NTAPI
19641964-HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject,
19651965- IN OUT PULONG NumberOfMapRegisters)
19661966-{
19671967- PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
19681968- ULONG MapRegisterNumber;
19691969-19701970- /* Check if it needs map registers */
19711971- if (AdapterObject->NeedsMapRegisters)
19721972- {
19731973- /* Check if we have enough */
19741974- if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
19751975- {
19761976- /* We don't, fail */
19771977- AdapterObject->NumberOfMapRegisters = 0;
19781978- return NULL;
19791979- }
19801980-19811981- /* Try to find free map registers */
19821982- MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
19831983- *NumberOfMapRegisters,
19841984- 0);
19851985-19861986- /* Check if nothing was found */
19871987- if (MapRegisterNumber == MAXULONG)
19881988- {
19891989- /* No free registers found, so use the base registers */
19901990- RtlSetBits(MasterAdapter->MapRegisters,
19911991- 0,
19921992- *NumberOfMapRegisters);
19931993- MapRegisterNumber = 0;
19941994- }
19951995-19961996- /* Calculate the new base */
19971997- AdapterObject->MapRegisterBase =
19981998- (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
19991999- MapRegisterNumber);
20002000-20012001- /* Check if scatter gather isn't supported */
20022002- if (!AdapterObject->ScatterGather)
20032003- {
20042004- /* Set the flag */
20052005- AdapterObject->MapRegisterBase =
20062006- (PROS_MAP_REGISTER_ENTRY)
20072007- ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
20082008- }
20092009- }
20102010- else
20112011- {
20122012- AdapterObject->MapRegisterBase = NULL;
20132013- AdapterObject->NumberOfMapRegisters = 0;
20142014- }
20152015-20162016- /* Return the base */
20172017- return AdapterObject->MapRegisterBase;
20182018-}
20192019-20202020-/* EOF */
-74
hal/halppc/generic/drive.c
···11-/*
22- * PROJECT: ReactOS HAL
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: hal/halppc/generic/drive.c
55- * PURPOSE: I/O HAL Routines for Disk Access
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- */
88-99-/* INCLUDES ******************************************************************/
1010-1111-#include <hal.h>
1212-#define NDEBUG
1313-#include <debug.h>
1414-1515-/* FUNCTIONS *****************************************************************/
1616-1717-VOID
1818-NTAPI
1919-HalpAssignDriveLetters(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
2020- IN PSTRING NtDeviceName,
2121- OUT PUCHAR NtSystemPath,
2222- OUT PSTRING NtSystemPathString)
2323-{
2424- /* Call the kernel */
2525- IoAssignDriveLetters(LoaderBlock,
2626- NtDeviceName,
2727- NtSystemPath,
2828- NtSystemPathString);
2929-}
3030-3131-NTSTATUS
3232-NTAPI
3333-HalpReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
3434- IN ULONG SectorSize,
3535- IN BOOLEAN ReturnRecognizedPartitions,
3636- IN OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
3737-{
3838- /* Call the kernel */
3939- return IoReadPartitionTable(DeviceObject,
4040- SectorSize,
4141- ReturnRecognizedPartitions,
4242- PartitionBuffer);
4343-}
4444-4545-NTSTATUS
4646-NTAPI
4747-HalpWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
4848- IN ULONG SectorSize,
4949- IN ULONG SectorsPerTrack,
5050- IN ULONG NumberOfHeads,
5151- IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
5252-{
5353- /* Call the kernel */
5454- return IoWritePartitionTable(DeviceObject,
5555- SectorSize,
5656- SectorsPerTrack,
5757- NumberOfHeads,
5858- PartitionBuffer);
5959-}
6060-6161-NTSTATUS
6262-NTAPI
6363-HalpSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
6464- IN ULONG SectorSize,
6565- IN ULONG PartitionNumber,
6666- IN ULONG PartitionType)
6767-{
6868- /* Call the kernel */
6969- return IoSetPartitionInformation(DeviceObject,
7070- SectorSize,
7171- PartitionNumber,
7272- PartitionType);
7373-}
7474-/* EOF */
-22
hal/halppc/generic/enum.c
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * FILE: hal/halppc/generic/enum.c
55- * PURPOSE: Motherboard device enumerator
66- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
77- * UPDATE HISTORY:
88- * Created 01/05/2001
99- */
1010-1111-/* INCLUDES *****************************************************************/
1212-1313-#include <hal.h>
1414-#define NDEBUG
1515-#include <debug.h>
1616-1717-VOID
1818-HalpStartEnumerator (VOID)
1919-{
2020-}
2121-2222-/* EOF */
-100
hal/halppc/generic/fmutex.c
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS HAL
44- * FILE: hal/halppc/generic/fmutex.c
55- * PURPOSE: Deprecated HAL Fast Mutex
66- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
77- */
88-99-/*
1010- * NOTE: Even HAL itself has #defines to use the Exi* APIs inside NTOSKRNL.
1111- * These are only exported here for compatibility with really old
1212- * drivers. Also note that in theory, these can be made much faster
1313- * by using assembly and inlining all the operations, including
1414- * raising and lowering irql.
1515- */
1616-1717-/* INCLUDES *****************************************************************/
1818-1919-#include <hal.h>
2020-#define NDEBUG
2121-#include <debug.h>
2222-2323-#undef ExAcquireFastMutex
2424-#undef ExReleaseFastMutex
2525-2626-/* FUNCTIONS *****************************************************************/
2727-2828-VOID
2929-FASTCALL
3030-ExAcquireFastMutex(PFAST_MUTEX FastMutex)
3131-{
3232- KIRQL OldIrql;
3333-3434- /* Raise IRQL to APC */
3535- KeRaiseIrql(APC_LEVEL, &OldIrql);
3636-3737- /* Decrease the count */
3838- if (InterlockedDecrement(&FastMutex->Count))
3939- {
4040- /* Someone is still holding it, use slow path */
4141- FastMutex->Contention++;
4242- KeWaitForSingleObject(&FastMutex->Event,
4343- WrExecutive,
4444- KernelMode,
4545- FALSE,
4646- NULL);
4747- }
4848-4949- /* Set the owner and IRQL */
5050- FastMutex->Owner = KeGetCurrentThread();
5151- FastMutex->OldIrql = OldIrql;
5252-}
5353-5454-VOID
5555-FASTCALL
5656-ExReleaseFastMutex(PFAST_MUTEX FastMutex)
5757-{
5858- KIRQL OldIrql;
5959-6060- /* Erase the owner */
6161- FastMutex->Owner = (PVOID)1;
6262- OldIrql = FastMutex->OldIrql;
6363-6464- /* Increase the count */
6565- if (InterlockedIncrement(&FastMutex->Count) <= 0)
6666- {
6767- /* Someone was waiting for it, signal the waiter */
6868- KeSetEventBoostPriority(&FastMutex->Event, IO_NO_INCREMENT);
6969- }
7070-7171- /* Lower IRQL back */
7272- KeLowerIrql(OldIrql);
7373-}
7474-7575-BOOLEAN
7676-FASTCALL
7777-ExiTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
7878-{
7979- KIRQL OldIrql;
8080-8181- /* Raise to APC_LEVEL */
8282- KeRaiseIrql(APC_LEVEL, &OldIrql);
8383-8484- /* Check if we can quickly acquire it */
8585- if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
8686- {
8787- /* We have, set us as owners */
8888- FastMutex->Owner = KeGetCurrentThread();
8989- FastMutex->OldIrql = OldIrql;
9090- return TRUE;
9191- }
9292- else
9393- {
9494- /* Acquire attempt failed */
9595- KeLowerIrql(OldIrql);
9696- return FALSE;
9797- }
9898-}
9999-100100-/* EOF */
···11-/*
22- * ReactOS kernel
33- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
44- *
55- * This program is free software; you can redistribute it and/or modify
66- * it under the terms of the GNU General Public License as published by
77- * the Free Software Foundation; either version 2 of the License, or
88- * (at your option) any later version.
99- *
1010- * This program is distributed in the hope that it will be useful,
1111- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1212- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1313- * GNU General Public License for more details.
1414- *
1515- * You should have received a copy of the GNU General Public License along
1616- * with this program; if not, write to the Free Software Foundation, Inc.,
1717- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818- */
1919-2020-#pragma once
2121-2222-#include <ndk/powerpc/ketypes.h>
2323-2424-/* Possible values for KTHREAD's NpxState */
2525-#define KPCR_BASE 0xff000000
2626-#define NPX_STATE_INVALID 0x01
2727-#define NPX_STATE_VALID 0x02
2828-#define NPX_STATE_DIRTY 0x04
2929-3030-#ifndef __ASM__
3131-3232-typedef struct _KIRQ_TRAPFRAME
3333-{
3434-} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
3535-3636-extern ULONG KePPCCacheAlignment;
3737-3838-//#define KD_BREAKPOINT_TYPE
3939-//#define KD_BREAKPOINT_SIZE
4040-//#define KD_BREAKPOINT_VALUE
4141-4242-//
4343-// Macro to get the second level cache size field name which differs between
4444-// CISC and RISC architectures, as the former has unified I/D cache
4545-//
4646-#define KiGetSecondLevelDCacheSize() ((PKIPCR)KeGetPcr())->SecondLevelDcacheSize
4747-4848-//
4949-// Macros for getting and setting special purpose registers in portable code
5050-//
5151-#define KeGetContextPc(Context) \
5252- ((Context)->Dr0)
5353-5454-#define KeSetContextPc(Context, ProgramCounter) \
5555- ((Context)->Dr0 = (ProgramCounter))
5656-5757-#define KeGetTrapFramePc(TrapFrame) \
5858- ((TrapFrame)->Dr0)
5959-6060-#define KeGetContextReturnRegister(Context) \
6161- ((Context)->Gpr3)
6262-6363-#define KeSetContextReturnRegister(Context, ReturnValue) \
6464- ((Context)->Gpr3 = (ReturnValue))
6565-6666-//
6767-// Returns the Interrupt State from a Trap Frame.
6868-// ON = TRUE, OFF = FALSE
6969-//
7070-//#define KeGetTrapFrameInterruptState(TrapFrame) \
7171-7272-#define KePPCRdmsr(msr,val1,val2) __asm__ __volatile__("mfmsr 3")
7373-7474-#define KePPCWrmsr(msr,val1,val2) __asm__ __volatile__("mtmsr 3")
7575-7676-#define PPC_MIN_CACHE_LINE_SIZE 32
7777-7878-FORCEINLINE struct _KPCR * NTHALAPI KeGetCurrentKPCR(
7979- VOID)
8080-{
8181- return (struct _KPCR *)__readfsdword(0x1c);
8282-}
8383-8484-FORCEINLINE
8585-VOID
8686-KeFlushProcessTb(VOID)
8787-{
8888- /* Flush the TLB */
8989- __asm__("sync\n\tisync\n\t");
9090-}
9191-9292-FORCEINLINE
9393-VOID
9494-KeSweepICache(IN PVOID BaseAddress,
9595- IN SIZE_T FlushSize)
9696-{
9797- //
9898- // Always sweep the whole cache
9999- //
100100- UNREFERENCED_PARAMETER(BaseAddress);
101101- UNREFERENCED_PARAMETER(FlushSize);
102102- __asm__ __volatile__("tlbsync");
103103-}
104104-105105-FORCEINLINE
106106-PRKTHREAD
107107-KeGetCurrentThread(VOID)
108108-{
109109- /* Return the current thread */
110110- return KeGetCurrentPrcb()->CurrentThread;
111111-}
112112-113113-FORCEINLINE
114114-VOID
115115-KiRundownThread(IN PKTHREAD Thread)
116116-{
117117- /* FIXME */
118118-}
119119-120120-#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
121121-VOID
122122-NTAPI
123123-KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
124124- PKSTART_ROUTINE StartRoutine,
125125- PVOID StartContext,
126126- BOOLEAN UserThread,
127127- KTRAP_FRAME TrapFrame);
128128-#endif
129129-130130-#endif /* __ASM__ */
131131-132132-/* EOF */
-271
ntoskrnl/ke/powerpc/cpu.c
···11-/*
22- * PROJECT: ReactOS Kernel
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: ntoskrnl/ke/powerpc/cpu.c
55- * PURPOSE: Routines for CPU-level support
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- */
88-99-/* INCLUDES *****************************************************************/
1010-1111-#include <ntoskrnl.h>
1212-#define NDEBUG
1313-#include <debug.h>
1414-1515-/* GLOBALS *******************************************************************/
1616-1717-/* CPU Features and Flags */
1818-ULONG KeLargestCacheLine = 0x40;
1919-ULONG KeDcacheFlushCount = 0;
2020-ULONG KeIcacheFlushCount = 0;
2121-ULONG KiDmaIoCoherency = 0;
2222-BOOLEAN KiSMTProcessorsPresent;
2323-2424-/* CPU Signatures */
2525-#if 0
2626-CHAR CmpIntelID[] = "GenuineIntel";
2727-CHAR CmpAmdID[] = "AuthenticAMD";
2828-CHAR CmpCyrixID[] = "CyrixInstead";
2929-CHAR CmpTransmetaID[] = "GenuineTMx86";
3030-CHAR CmpCentaurID[] = "CentaurHauls";
3131-CHAR CmpRiseID[] = "RiseRiseRise";
3232-#endif
3333-3434-/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
3535-3636-VOID
3737-NTAPI
3838-CPUID(IN ULONG CpuInfo[4],
3939- IN ULONG InfoType)
4040-{
4141- RtlZeroMemory(CpuInfo, 4 * sizeof(ULONG));
4242-}
4343-4444-VOID
4545-WRMSR(IN ULONG Register,
4646- IN LONGLONG Value)
4747-{
4848-}
4949-5050-LONGLONG
5151-RDMSR(IN ULONG Register)
5252-{
5353- LARGE_INTEGER LargeVal;
5454- LargeVal.QuadPart = 0;
5555- return LargeVal.QuadPart;
5656-}
5757-5858-/* FUNCTIONS *****************************************************************/
5959-6060-VOID
6161-NTAPI
6262-KiSetProcessorType(VOID)
6363-{
6464-}
6565-6666-ULONG
6767-NTAPI
6868-KiGetCpuVendor(VOID)
6969-{
7070- return 0;
7171-}
7272-7373-ULONG
7474-NTAPI
7575-KiGetFeatureBits(VOID)
7676-{
7777- ULONG FeatureBits = 0;
7878- /* Return the Feature Bits */
7979- return FeatureBits;
8080-}
8181-8282-VOID
8383-NTAPI
8484-KiGetCacheInformation(VOID)
8585-{
8686-}
8787-8888-VOID
8989-NTAPI
9090-KiSetCR0Bits(VOID)
9191-{
9292-}
9393-9494-VOID
9595-NTAPI
9696-KiInitializeTSS2(IN PKTSS Tss,
9797- IN PKGDTENTRY TssEntry OPTIONAL)
9898-{
9999-}
100100-101101-VOID
102102-NTAPI
103103-KiInitializeTSS(IN PKTSS Tss)
104104-{
105105-}
106106-107107-VOID
108108-FASTCALL
109109-Ki386InitializeTss(IN PKTSS Tss,
110110- IN PKIDTENTRY Idt,
111111- IN PKGDTENTRY Gdt)
112112-{
113113-}
114114-115115-VOID
116116-NTAPI
117117-KeFlushCurrentTb(VOID)
118118-{
119119-}
120120-121121-VOID
122122-NTAPI
123123-KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
124124-{
125125-}
126126-127127-VOID
128128-NTAPI
129129-KiInitializeMachineType(VOID)
130130-{
131131-}
132132-133133-ULONG_PTR
134134-NTAPI
135135-KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
136136-{
137137- return 0;
138138-}
139139-140140-VOID
141141-NTAPI
142142-KiRestoreFastSyscallReturnState(VOID)
143143-{
144144-}
145145-146146-ULONG_PTR
147147-NTAPI
148148-Ki386EnableDE(IN ULONG_PTR Context)
149149-{
150150- return 0;
151151-}
152152-153153-ULONG_PTR
154154-NTAPI
155155-Ki386EnableFxsr(IN ULONG_PTR Context)
156156-{
157157- return 0;
158158-}
159159-160160-ULONG_PTR
161161-NTAPI
162162-Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
163163-{
164164- /* FIXME: Support this */
165165- DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n");
166166- return 0;
167167-}
168168-169169-VOID
170170-NTAPI
171171-KiI386PentiumLockErrataFixup(VOID)
172172-{
173173- /* FIXME: Support this */
174174- DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
175175-}
176176-177177-/* PUBLIC FUNCTIONS **********************************************************/
178178-179179-/*
180180- * @implemented
181181- */
182182-NTSTATUS
183183-NTAPI
184184-KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
185185-{
186186- return STATUS_SUCCESS;
187187-}
188188-189189-/*
190190- * @implemented
191191- */
192192-NTSTATUS
193193-NTAPI
194194-KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
195195-{
196196- return STATUS_SUCCESS;
197197-}
198198-199199-/*
200200- * @implemented
201201- */
202202-ULONG
203203-NTAPI
204204-KeGetRecommendedSharedDataAlignment(VOID)
205205-{
206206- /* Return the global variable */
207207- return KeLargestCacheLine;
208208-}
209209-210210-/*
211211- * @implemented
212212- */
213213-VOID
214214-NTAPI
215215-KeFlushEntireTb(IN BOOLEAN Invalid,
216216- IN BOOLEAN AllProcessors)
217217-{
218218- KIRQL OldIrql;
219219-220220- /* Raise the IRQL for the TB Flush */
221221- OldIrql = KeRaiseIrqlToSynchLevel();
222222-223223-#ifdef CONFIG_SMP
224224- /* FIXME: Support IPI Flush */
225225-#error Not yet implemented!
226226-#endif
227227-228228- /* Flush the TB for the Current CPU */
229229- //KeFlushCurrentTb();
230230-231231- /* Return to Original IRQL */
232232- KeLowerIrql(OldIrql);
233233-}
234234-235235-/*
236236- * @implemented
237237- */
238238-VOID
239239-NTAPI
240240-KeSetDmaIoCoherency(IN ULONG Coherency)
241241-{
242242- /* Save the coherency globally */
243243- KiDmaIoCoherency = Coherency;
244244-}
245245-246246-/*
247247- * @implemented
248248- */
249249-KAFFINITY
250250-NTAPI
251251-KeQueryActiveProcessors(VOID)
252252-{
253253- PAGED_CODE();
254254-255255- /* Simply return the number of active processors */
256256- return KeActiveProcessors;
257257-}
258258-259259-/*
260260- * @implemented
261261- */
262262-VOID
263263-__cdecl
264264-KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
265265-{
266266- /* Capture the context */
267267- RtlCaptureContext(&State->ContextFrame);
268268-269269- /* Capture the control state */
270270- KiSaveProcessorControlState(State);
271271-}
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * FILE: ntoskrnl/ke/powerpc/ctxswitch.c
55- * PURPOSE: Thread Context Switching
66- *
77- * PROGRAMMERS: arty
88- (i386 implementation by Alex Ionescu)
99- */
1010-1111-/* INCLUDES ******************************************************************/
1212-1313-#include <ntoskrnl.h>
1414-#define NDEBUG
1515-#include <debug.h>
1616-#include <ppcmmu/mmu.h>
1717-1818-/*++
1919- * KiThreadStartup
2020- *
2121- * The KiThreadStartup routine is the beginning of any thread.
2222- *
2323- * Params:
2424- * SystemRoutine - Pointer to the System Startup Routine. Either
2525- * PspUserThreadStartup or PspSystemThreadStartup
2626- *
2727- * StartRoutine - For Kernel Threads only, specifies the starting execution
2828- * point of the new thread.
2929- *
3030- * StartContext - For Kernel Threads only, specifies a pointer to variable
3131- * context data to be sent to the StartRoutine above.
3232- *
3333- * UserThread - Indicates whether or not this is a user thread. This tells
3434- * us if the thread has a context or not.
3535- *
3636- * TrapFrame - Pointer to the KTHREAD to which the caller wishes to
3737- * switch from.
3838- *
3939- * Returns:
4040- * Should never return for a system thread. Returns through the System Call
4141- * Exit Dispatcher for a user thread.
4242- *
4343- * Remarks:
4444- * If a return from a system thread is detected, a bug check will occur.
4545- *
4646- *--*/
4747-4848-VOID
4949-NTAPI
5050-KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
5151- PKSTART_ROUTINE StartRoutine,
5252- PVOID StartContext,
5353- BOOLEAN UserThread,
5454- KTRAP_FRAME TrapFrame)
5555-{
5656- KeLowerIrql(APC_LEVEL);
5757- __asm__("mr 0,%0\n\t"
5858- "mr 3,%1\n\t"
5959- "mr 4,%2\n\t"
6060- "mr 5,%3\n\t"
6161- "mr 6,%4\n\t"
6262- "sc" : :
6363- "r" (0xf0000), /* Thread start function */
6464- "r" (SystemRoutine),
6565- "r" (StartRoutine),
6666- "r" (StartContext),
6767- "r" (UserThread));
6868- PspTerminateThreadByPointer(PsGetCurrentThread(), STATUS_THREAD_IS_TERMINATING, TRUE);
6969-}
7070-7171-/* Take a decrementer trap, and prepare the given trap frame, swapping
7272- * process and thread context as appropriate. */
7373-VOID KiDecrementerTrapFinish(PKTRAP_FRAME TrapFrame);
7474-7575-VOID
7676-FASTCALL
7777-KiQueueReadyThread(IN PKTHREAD Thread,
7878- IN PKPRCB Prcb);
7979-8080-PKTHREAD KiLastThread = NULL;
8181-PKTRAP_FRAME KiLastThreadTrapFrame = NULL;
8282-8383-VOID
8484-NTAPI
8585-KiDecrementerTrap(PKTRAP_FRAME TrapFrame)
8686-{
8787- KIRQL Irql;
8888- PKPRCB Prcb = KeGetPcr()->Prcb;
8989- if (!KiLastThread)
9090- KiLastThread = KeGetCurrentThread();
9191-9292- if (KiLastThread->State == Running)
9393- KiQueueReadyThread(KiLastThread, Prcb);
9494-9595- if (!KiLastThreadTrapFrame)
9696- KiLastThreadTrapFrame = Prcb->IdleThread->TrapFrame;
9797-9898- TrapFrame->OldIrql = KeGetCurrentIrql();
9999- *KiLastThreadTrapFrame = *TrapFrame;
100100-101101- if (Prcb->NextThread)
102102- {
103103- Prcb->CurrentThread = Prcb->NextThread;
104104- Prcb->NextThread = NULL;
105105- }
106106- else
107107- Prcb->CurrentThread = Prcb->IdleThread;
108108-109109- Prcb->CurrentThread->State = Running;
110110-111111- KiLastThreadTrapFrame = Prcb->CurrentThread->TrapFrame;
112112- KiLastThread = Prcb->CurrentThread;
113113-114114- *TrapFrame = *KiLastThreadTrapFrame;
115115- Irql = KeGetCurrentIrql();
116116-117117- if (Irql > TrapFrame->OldIrql)
118118- KfRaiseIrql(Irql);
119119- else if (Irql < TrapFrame->OldIrql)
120120- KfLowerIrql(Irql);
121121-122122- /* When we return, we'll go through rfi and be in new thread land */
123123- __asm__("mtdec %0" : : "r" (0x1000000)); // Reset the trap
124124-}
-103
ntoskrnl/ke/powerpc/exp.c
···11-/*
22- * PROJECT: ReactOS Kernel
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: ntoskrnl/ke/powerpc/exp.c
55- * PURPOSE: Exception Dispatching and Context<->Trap Frame Conversion
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- * Gregor Anich
88- * Skywing (skywing@valhallalegends.com)
99- */
1010-1111-/* INCLUDES ******************************************************************/
1212-1313-#include <ntoskrnl.h>
1414-#define NDEBUG
1515-#include <debug.h>
1616-#include <ppcmmu/mmu.h>
1717-1818-/* FUNCTIONS *****************************************************************/
1919-2020-CODE_SEG("INIT")
2121-VOID
2222-NTAPI
2323-KeInitExceptions(VOID)
2424-{
2525-}
2626-2727-ULONG
2828-NTAPI
2929-KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
3030-{
3131- return 0;
3232-}
3333-3434-VOID
3535-NTAPI
3636-KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
3737- IN ULONG Esp)
3838-{
3939-}
4040-4141-ULONG
4242-NTAPI
4343-KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
4444-{
4545- return 0;
4646-}
4747-4848-VOID
4949-NTAPI
5050-KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
5151- IN ULONG Ss)
5252-{
5353-}
5454-5555-USHORT
5656-NTAPI
5757-KiTagWordFnsaveToFxsave(USHORT TagWord)
5858-{
5959- return 0;
6060-}
6161-6262-VOID
6363-NTAPI
6464-KeContextToTrapFrame(IN PCONTEXT Context,
6565- IN OUT PKEXCEPTION_FRAME ExceptionFrame,
6666- IN OUT PKTRAP_FRAME TrapFrame,
6767- IN ULONG ContextFlags,
6868- IN KPROCESSOR_MODE PreviousMode)
6969-{
7070-}
7171-7272-VOID
7373-NTAPI
7474-KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
7575- IN PKEXCEPTION_FRAME ExceptionFrame,
7676- IN OUT PCONTEXT Context)
7777-{
7878-}
7979-8080-VOID
8181-NTAPI
8282-KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
8383- IN PKEXCEPTION_FRAME ExceptionFrame,
8484- IN PKTRAP_FRAME TrapFrame,
8585- IN KPROCESSOR_MODE PreviousMode,
8686- IN BOOLEAN FirstChance)
8787-{
8888- DbgPrint("EXCEPTION! Record %08x Frame %08x\n",
8989- ExceptionRecord, ExceptionFrame);
9090- MmuDumpMap();
9191- KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
9292-}
9393-9494-/*
9595- * @implemented
9696- */
9797-NTSTATUS
9898-NTAPI
9999-KeRaiseUserException(IN NTSTATUS ExceptionCode)
100100-{
101101- return STATUS_SUCCESS;
102102-}
103103-
-356
ntoskrnl/ke/powerpc/kiinit.c
···11-/*
22- * PROJECT: ReactOS Kernel
33- * LICENSE: GPL - See COPYING in the top level directory
44- * FILE: ntoskrnl/ke/powerpc/kiinit.c
55- * PURPOSE: Kernel Initialization for x86 CPUs
66- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
77- * Art Yerkes (ayerkes@speakeasy.net)
88- */
99-1010-/* INCLUDES *****************************************************************/
1111-1212-#include <ntoskrnl.h>
1313-1414-//#define NDEBUG
1515-#include <debug.h>
1616-#include "ppcmmu/mmu.h"
1717-1818-/* GLOBALS *******************************************************************/
1919-2020-/* Ku bit should be set, so that we get the best options for page protection */
2121-#define PPC_SEG_Ku 0x40000000
2222-#define PPC_SEG_Ks 0x20000000
2323-2424-extern LOADER_MODULE KeLoaderModules[64];
2525-extern ULONG KeLoaderModuleCount;
2626-extern ULONG_PTR MmFreeLdrLastKernelAddress;
2727-KPRCB PrcbData[MAXIMUM_PROCESSORS];
2828-/* BIOS Memory Map. Not NTLDR-compliant yet */
2929-extern ULONG KeMemoryMapRangeCount;
3030-extern ADDRESS_RANGE KeMemoryMap[64];
3131-3232-/* FUNCTIONS *****************************************************************/
3333-/*
3434- * Trap frame:
3535- * r0 .. r32
3636- * lr, ctr, srr0, srr1, dsisr
3737- */
3838-3939-extern int syscall_start[], syscall_end, KiDecrementerTrapHandler[],
4040- KiDecrementerTrapHandlerEnd;
4141-4242-VOID
4343-NTAPI
4444-KiSetupSyscallHandler(VOID)
4545-{
4646- paddr_t handler_target;
4747- int *source;
4848- for(source = syscall_start, handler_target = 0xc00;
4949- source < &syscall_end;
5050- source++, handler_target += sizeof(int))
5151- {
5252- SetPhys(handler_target, *source);
5353- }
5454-}
5555-5656-VOID
5757-NTAPI
5858-KiSetupDecrementerTrap(VOID)
5959-{
6060- paddr_t handler_target;
6161- int *source;
6262-6363- /* Turn off EE bit while redefining dec trap */
6464- _disable();
6565-6666- for(source = KiDecrementerTrapHandler, handler_target = 0x900;
6767- source != &KiDecrementerTrapHandlerEnd;
6868- source++, handler_target += sizeof(int))
6969- SetPhys(handler_target, *source);
7070-7171- DPRINT("CurrentThread %08x IdleThread %08x\n",
7272- KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread);
7373-7474- /* Kick decmrenter! */
7575- __asm__("mtdec %0" : : "r" (0));
7676-7777- /* Enable interrupts! */
7878- _enable();
7979-}
8080-8181-VOID
8282-NTAPI
8383-KiInitializePcr(IN ULONG ProcessorNumber,
8484- IN PKIPCR Pcr,
8585- IN PKTHREAD IdleThread,
8686- IN PVOID DpcStack)
8787-{
8888- Pcr->MajorVersion = PCR_MAJOR_VERSION;
8989- Pcr->MinorVersion = PCR_MINOR_VERSION;
9090- Pcr->CurrentIrql = PASSIVE_LEVEL;
9191- Pcr->PrcbData = &PrcbData[ProcessorNumber];
9292- Pcr->PrcbData->MajorVersion = PRCB_MAJOR_VERSION;
9393- Pcr->PrcbData->MinorVersion = 0;
9494- Pcr->PrcbData->Number = 0; /* UP for now */
9595- Pcr->PrcbData->SetMember = 1;
9696-#if DBG
9797- Pcr->PrcbData->BuildType = PRCB_BUILD_DEBUG;
9898-#else
9999- Pcr->PrcbData->BuildType = 0;
100100-#endif
101101- Pcr->PrcbData->DpcStack = DpcStack;
102102- KeGetPcr()->Prcb = Pcr->PrcbData;
103103- KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
104104-}
105105-106106-extern ULONG KiGetFeatureBits();
107107-extern VOID KiSetProcessorType();
108108-extern VOID KiGetCacheInformation();
109109-110110-VOID
111111-NTAPI
112112-KiInitializeKernel(IN PKPROCESS InitProcess,
113113- IN PKTHREAD InitThread,
114114- IN PVOID IdleStack,
115115- IN PKPRCB Prcb,
116116- IN CCHAR Number,
117117- IN PLOADER_PARAMETER_BLOCK LoaderBlock)
118118-{
119119- ULONG FeatureBits;
120120- LARGE_INTEGER PageDirectory;
121121- PVOID DpcStack;
122122-123123- /* Detect and set the CPU Type */
124124- KiSetProcessorType();
125125-126126- /* Initialize the Power Management Support for this PRCB */
127127- PoInitializePrcb(Prcb);
128128-129129- /* Get the processor features for the CPU */
130130- FeatureBits = KiGetFeatureBits();
131131-132132- /* Save feature bits */
133133- Prcb->FeatureBits = FeatureBits;
134134-135135- /* Get cache line information for this CPU */
136136- KiGetCacheInformation();
137137-138138- /* Initialize spinlocks and DPC data */
139139- KiInitSpinLocks(Prcb, Number);
140140-141141- /* Check if this is the Boot CPU */
142142- if (!Number)
143143- {
144144- /* Set Node Data */
145145- KeNodeBlock[0] = &KiNode0;
146146- Prcb->ParentNode = KeNodeBlock[0];
147147- KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
148148-149149- /* Set boot-level flags */
150150- KeProcessorArchitecture = 0;
151151- KeProcessorLevel = (USHORT)Prcb->CpuType;
152152- KeFeatureBits = FeatureBits;
153153-154154- /* Set the current MP Master KPRCB to the Boot PRCB */
155155- Prcb->MultiThreadSetMaster = Prcb;
156156-157157- /* Lower to APC_LEVEL */
158158- KeLowerIrql(APC_LEVEL);
159159-160160- /* Initialize portable parts of the OS */
161161- KiInitSystem();
162162-163163- /* Initialize the Idle Process and the Process Listhead */
164164- InitializeListHead(&KiProcessListHead);
165165- PageDirectory.QuadPart = 0;
166166- KeInitializeProcess(InitProcess,
167167- 0,
168168- 0xFFFFFFFF,
169169- &PageDirectory,
170170- TRUE);
171171- InitProcess->QuantumReset = MAXCHAR;
172172- }
173173- else
174174- {
175175- /* FIXME */
176176- DPRINT1("SMP Boot support not yet present\n");
177177- }
178178-179179- /* Setup the Idle Thread */
180180- KeInitializeThread(InitProcess,
181181- InitThread,
182182- NULL,
183183- NULL,
184184- NULL,
185185- NULL,
186186- NULL,
187187- IdleStack);
188188- InitThread->NextProcessor = Number;
189189- InitThread->Priority = HIGH_PRIORITY;
190190- InitThread->State = Running;
191191- InitThread->Affinity = 1 << Number;
192192- InitThread->WaitIrql = DISPATCH_LEVEL;
193193- InitProcess->ActiveProcessors = 1 << Number;
194194-195195- /* HACK for MmUpdatePageDir */
196196- ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
197197-198198- /* Set up the thread-related fields in the PRCB */
199199- Prcb->CurrentThread = InitThread;
200200- Prcb->NextThread = NULL;
201201- Prcb->IdleThread = InitThread;
202202-203203- /* Initialize Kernel Memory Address Space */
204204- MmInit1(MmFreeLdrFirstKrnlPhysAddr,
205205- MmFreeLdrLastKrnlPhysAddr,
206206- MmFreeLdrLastKernelAddress,
207207- KeMemoryMap,
208208- KeMemoryMapRangeCount,
209209- 4096);
210210-211211- /* Initialize the Kernel Executive */
212212- ExpInitializeExecutive(0, LoaderBlock);
213213-214214- /* Only do this on the boot CPU */
215215- if (!Number)
216216- {
217217- /* Calculate the time reciprocal */
218218- KiTimeIncrementReciprocal =
219219- KiComputeReciprocal(KeMaximumIncrement,
220220- &KiTimeIncrementShiftCount);
221221-222222- /* Update DPC Values in case they got updated by the executive */
223223- Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
224224- Prcb->MinimumDpcRate = KiMinimumDpcRate;
225225- Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
226226-227227- /* Allocate the DPC Stack */
228228- DpcStack = MmCreateKernelStack(FALSE, 0);
229229- if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
230230- Prcb->DpcStack = DpcStack;
231231- }
232232-233233- KfRaiseIrql(DISPATCH_LEVEL);
234234-235235- KeSetPriorityThread(InitThread, 0);
236236- /* Setup decrementer exception */
237237- KiSetupDecrementerTrap();
238238-239239- KfLowerIrql(PASSIVE_LEVEL);
240240-241241- /* Should not return */
242242- while(1)
243243- {
244244- NtYieldExecution();
245245- }
246246-}
247247-248248-extern int KiPageFaultTrap();
249249-KTRAP_FRAME KiInitialTrapFrame;
250250-251251-/* Use this for early boot additions to the page table */
252252-VOID
253253-NTAPI
254254-KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
255255-{
256256- ULONG Cpu;
257257- ppc_map_info_t info[4];
258258- PKIPCR Pcr = (PKIPCR)KPCR_BASE;
259259- PKPRCB Prcb;
260260-261261- __asm__("mr 13,%0" : : "r" (KPCR_BASE));
262262-263263- /* Set the page fault handler to the kernel */
264264- MmuSetTrapHandler(3,KiPageFaultTrap);
265265- MmuSetTrapHandler(4,KiPageFaultTrap);
266266-267267- // Make 0xf... special
268268- MmuAllocVsid(2, 0x8000);
269269- MmuSetVsid(15,16,2);
270270-271271- /* Get the current CPU */
272272- Cpu = KeNumberProcessors;
273273- if (!Cpu)
274274- {
275275- /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
276276- * change when we get SMP support.
277277- */
278278- info[0].phys = 0;
279279- info[0].proc = 2;
280280- info[0].addr = (vaddr_t)Pcr;
281281- info[0].flags = MMU_KRW_UR;
282282- info[1].phys = 0;
283283- info[1].proc = 2;
284284- info[1].addr = ((vaddr_t)Pcr) + (1 << PAGE_SHIFT);
285285- info[1].flags = MMU_KRW_UR;
286286- info[2].phys = 0;
287287- info[2].proc = 2;
288288- info[2].addr = (vaddr_t)KI_USER_SHARED_DATA;
289289- info[2].flags = MMU_KRW_UR;
290290- info[3].phys = 0;
291291- info[3].proc = 2;
292292- info[3].addr = (vaddr_t)KIP0PCRADDRESS;
293293- info[3].flags = MMU_KRW_UR;
294294- MmuMapPage(info, 4);
295295- }
296296-297297- /* Skip initial setup if this isn't the Boot CPU */
298298- if (Cpu) goto AppCpuInit;
299299-300300- /* Initialize the PCR */
301301- RtlZeroMemory(Pcr, PAGE_SIZE);
302302- KiInitializePcr(Cpu,
303303- Pcr,
304304- &KiInitialThread.Tcb,
305305- KiDoubleFaultStack);
306306-307307- /* Set us as the current process */
308308- KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
309309- KiInitialThread.Tcb.TrapFrame = &KiInitialTrapFrame;
310310-311311- /* Setup CPU-related fields */
312312-AppCpuInit:
313313- Pcr->Number = Cpu;
314314- Pcr->SetMember = 1 << Cpu;
315315- Prcb = KeGetCurrentPrcb();
316316- Prcb->SetMember = 1 << Cpu;
317317-318318- /* Initialize the Processor with HAL */
319319- HalInitializeProcessor(Cpu, LoaderBlock);
320320-321321- /* Set active processors */
322322- KeActiveProcessors |= Pcr->SetMember;
323323- KeNumberProcessors++;
324324-325325- /* Initialize the Debugger for the Boot CPU */
326326- if (!Cpu) KdInitSystem (0, LoaderBlock);
327327-328328- /* Check for break-in */
329329- if (KdPollBreakIn())
330330- {
331331- DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
332332- }
333333-334334- /* Raise to HIGH_LEVEL */
335335- KfRaiseIrql(HIGH_LEVEL);
336336-337337- /* Call main kernel intialization */
338338- KiInitializeKernel(&KiInitialProcess.Pcb,
339339- &KiInitialThread.Tcb,
340340- P0BootStack,
341341- Prcb,
342342- Cpu,
343343- (PVOID)LoaderBlock);
344344-}
345345-346346-VOID
347347-NTAPI
348348-KiInitMachineDependent(VOID)
349349-{
350350-}
351351-352352-void abort(VOID)
353353-{
354354- KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
355355- while(1);
356356-}
-76
ntoskrnl/ke/powerpc/main_asm.S
···11-#include <ndk/asm.h>
22-33-#define AP_MAGIC (0x12481020)
44-55-.global P0BootStack
66-.global KiDoubleFaultStack
77-.global _kernel_stack
88-.global _kernel_stack_top
99-.global _kernel_trap_stack
1010-.global _kernel_trap_stack_top
1111-1212- .section .bss
1313- .align 12
1414-1515-1616-/* guard page for the kernel stack */
1717-.fill 4096, 1, 0
1818-1919-_kernel_stack:
2020-.fill 3*4096, 1, 0
2121-P0BootStack:
2222-_kernel_stack_top:
2323-2424-/* guard page for the trap stack */
2525-.fill 4096, 1, 0
2626-2727-_kernel_trap_stack:
2828-.fill 3*4096, 1, 0
2929-_kernel_trap_stack_top:
3030-3131-.fill 3*4096, 1, 0
3232-KiDoubleFaultStack:
3333-3434- .text
3535- .globl KiSystemStartup
3636- .globl KiRosPrepareForSystemStartup
3737- .globl DrawNumber
3838-3939-KiSystemStartup:
4040- /*
4141- * Set a normal MSR value
4242- */
4343- xor 0,0,0
4444- ori 30,0,0x3030
4545- mtmsr 30
4646-4747- /*
4848- * Reserve space for the floating point save area.
4949- */
5050- addi 1,1,-SIZEOF_FX_SAVE_AREA
5151-5252- /* Bye bye asm land! */
5353- mr 4,3
5454-5555- /* Load the initial kernel stack */
5656- lis 1,_kernel_stack_top@ha
5757- ori 1,1,_kernel_stack_top@l
5858- addi 1,1,-SIZEOF_FX_SAVE_AREA
5959-6060- /* Call the main kernel initialization */
6161- bl KiRosPrepareForSystemStartup
6262-6363- .global NtCurrentTeb
6464-NtCurrentTeb:
6565- mr 3,12
6666- blr
6767-6868- .globl KeSynchronizeExecution
6969-7070-KeSynchronizeExecution:
7171- blr
7272-7373- .globl PearPCDebug
7474-PearPCDebug:
7575-// .long 0x00333303
7676- blr
-805
ntoskrnl/ke/powerpc/ppc_irq.c
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * FILE: ntoskrnl/ke/powerpc/ppc_irq.c
55- * PURPOSE: IRQ handling
66- *
77- * PROGRAMMERS: David Welch (welch@mcmail.com)
88- */
99-1010-/*
1111- * NOTE: In general the PIC interrupt priority facilities are used to
1212- * preserve the NT IRQL semantics, global interrupt disables are only used
1313- * to keep the PIC in a consistent state
1414- *
1515- */
1616-1717-/* INCLUDES ****************************************************************/
1818-1919-#include <ntoskrnl.h>
2020-#include <ppcmmu/mmu.h>
2121-2222-#define NDEBUG
2323-#include <debug.h>
2424-2525-KDPC KiExpireTimerDpc;
2626-extern ULONG KiMaximumDpcQueueDepth;
2727-extern ULONG KiMinimumDpcRate;
2828-extern ULONG KiAdjustDpcThreshold;
2929-extern ULONG KiIdealDpcRate;
3030-extern LONG KiTickOffset;
3131-extern ULONG KeMaximumIncrement;
3232-extern ULONG KeMinimumIncrement;
3333-extern ULONG KeTimeAdjustment;
3434-3535-extern void PearPCDebug(int ch);
3636-3737-/* GLOBALS *****************************************************************/
3838-3939-/* Interrupt handler list */
4040-4141-#define NR_TRAPS 16
4242-#ifdef CONFIG_SMP
4343-4444-#define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum
4545-4646-#define BUILD_INTERRUPT_HANDLER(intnum) \
4747-VOID INT_NAME2(intnum)(VOID);
4848-4949-#define D(x,y) \
5050- BUILD_INTERRUPT_HANDLER(x##y)
5151-5252-#define D16(x) \
5353- D(x,0) D(x,1) D(x,2) D(x,3) \
5454- D(x,4) D(x,5) D(x,6) D(x,7) \
5555- D(x,8) D(x,9) D(x,A) D(x,B) \
5656- D(x,C) D(x,D) D(x,E) D(x,F)
5757-5858-D16(3) D16(4) D16(5) D16(6)
5959-D16(7) D16(8) D16(9) D16(A)
6060-D16(B) D16(C) D16(D) D16(E)
6161-D16(F)
6262-6363-#define L(x,y) \
6464- (ULONG)& INT_NAME2(x##y)
6565-6666-#define L16(x) \
6767- L(x,0), L(x,1), L(x,2), L(x,3), \
6868- L(x,4), L(x,5), L(x,6), L(x,7), \
6969- L(x,8), L(x,9), L(x,A), L(x,B), \
7070- L(x,C), L(x,D), L(x,E), L(x,F)
7171-7272-static ULONG irq_handler[ROUND_UP(NR_TRAPS, 16)] = {
7373- L16(3), L16(4), L16(5), L16(6),
7474- L16(7), L16(8), L16(9), L16(A),
7575- L16(B), L16(C), L16(D), L16(E)
7676-};
7777-7878-#undef L
7979-#undef L16
8080-#undef D
8181-#undef D16
8282-8383-#else /* CONFIG_SMP */
8484-8585-void trap_handler_0(void);
8686-void trap_handler_1(void);
8787-void trap_handler_2(void);
8888-void trap_handler_3(void);
8989-void trap_handler_4(void);
9090-void trap_handler_5(void);
9191-void trap_handler_6(void);
9292-void trap_handler_7(void);
9393-void trap_handler_8(void);
9494-void trap_handler_9(void);
9595-void trap_handler_10(void);
9696-void trap_handler_11(void);
9797-void trap_handler_12(void);
9898-void trap_handler_13(void);
9999-void trap_handler_14(void);
100100-void trap_handler_15(void);
101101-102102-static unsigned int trap_handler[NR_TRAPS] __attribute__((unused)) =
103103-{
104104- (int)&trap_handler_0,
105105- (int)&trap_handler_1,
106106- (int)&trap_handler_2,
107107- (int)&trap_handler_3,
108108- (int)&trap_handler_4,
109109- (int)&trap_handler_5,
110110- (int)&trap_handler_6,
111111- (int)&trap_handler_7,
112112- (int)&trap_handler_8,
113113- (int)&trap_handler_9,
114114- (int)&trap_handler_10,
115115- (int)&trap_handler_11,
116116- (int)&trap_handler_12,
117117- (int)&trap_handler_13,
118118- (int)&trap_handler_14,
119119- (int)&trap_handler_15,
120120-};
121121-122122-#endif /* CONFIG_SMP */
123123-124124-/*
125125- * PURPOSE: Object describing each isr
126126- * NOTE: The data in this table is only modified at passsive level but can
127127- * be accessed at any irq level.
128128- */
129129-130130-typedef struct
131131-{
132132- LIST_ENTRY ListHead;
133133- KSPIN_LOCK Lock;
134134- ULONG Count;
135135-}
136136-ISR_TABLE, *PISR_TABLE;
137137-138138-#ifdef CONFIG_SMP
139139-static ISR_TABLE IsrTable[NR_TRAPS][MAXIMUM_PROCESSORS];
140140-#else
141141-static ISR_TABLE IsrTable[NR_TRAPS][1];
142142-#endif
143143-144144-#define TAG_ISR_LOCK 'LRSI'
145145-146146-/* FUNCTIONS ****************************************************************/
147147-148148-CODE_SEG("INIT")
149149-VOID
150150-NTAPI
151151-KeInitInterrupts (VOID)
152152-{
153153- int i, j;
154154-155155- /*
156156- * Setup the IDT entries to point to the interrupt handlers
157157- */
158158- for (i=0;i<NR_TRAPS;i++)
159159- {
160160-#ifdef CONFIG_SMP
161161- for (j = 0; j < MAXIMUM_PROCESSORS; j++)
162162-#else
163163- j = 0;
164164-#endif
165165- {
166166- InitializeListHead(&IsrTable[i][j].ListHead);
167167- KeInitializeSpinLock(&IsrTable[i][j].Lock);
168168- IsrTable[i][j].Count = 0;
169169- }
170170- }
171171-}
172172-173173-static VOID
174174-KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
175175- PKTRAP_FRAME TrapFrame)
176176-{
177177-}
178178-179179-static VOID
180180-KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame,
181181- PKIRQ_TRAPFRAME IrqTrapFrame)
182182-{
183183-}
184184-185185-/*
186186- * NOTE: On Windows this function takes exactly one parameter and EBP is
187187- * guaranteed to point to KTRAP_FRAME. The function is used only
188188- * by HAL, so there's no point in keeping that prototype.
189189- *
190190- * @implemented
191191- */
192192-VOID
193193-NTAPI
194194-KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
195195- IN KIRQL Irql)
196196-{
197197- PKPRCB Prcb = KeGetCurrentPrcb();
198198- PKTHREAD CurrentThread;
199199- PKPROCESS CurrentProcess;
200200-201201- /* Make sure we don't go further if we're in early boot phase. */
202202- if (!(Prcb) || !(Prcb->CurrentThread)) return;
203203-204204- /* Get the current thread and process */
205205- CurrentThread = Prcb->CurrentThread;
206206- CurrentProcess = CurrentThread->ApcState.Process;
207207-208208- /* Check if we came from user mode */
209209- if (TrapFrame->PreviousMode != KernelMode)
210210- {
211211- /* Update user times */
212212- CurrentThread->UserTime++;
213213- InterlockedIncrement((PLONG)&CurrentProcess->UserTime);
214214- Prcb->UserTime++;
215215- }
216216- else
217217- {
218218- /* Check IRQ */
219219- if (Irql > DISPATCH_LEVEL)
220220- {
221221- /* This was an interrupt */
222222- Prcb->InterruptTime++;
223223- }
224224- else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive))
225225- {
226226- /* This was normal kernel time */
227227- CurrentThread->KernelTime++;
228228- InterlockedIncrement((PLONG)&CurrentProcess->KernelTime);
229229- }
230230- else if (Irql == DISPATCH_LEVEL)
231231- {
232232- /* This was DPC time */
233233- Prcb->DpcTime++;
234234- }
235235-236236- /* Update CPU kernel time in all cases */
237237- Prcb->KernelTime++;
238238- }
239239-240240- /* Set the last DPC Count and request rate */
241241- Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
242242- Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
243243- Prcb->DpcRequestRate) / 2;
244244-245245- /* Check if we should request a DPC */
246246- if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
247247- {
248248- /* Request one */
249249- HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
250250-251251- /* Update the depth if needed */
252252- if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
253253- (Prcb->MaximumDpcQueueDepth > 1))
254254- {
255255- /* Decrease the maximum depth by one */
256256- Prcb->MaximumDpcQueueDepth--;
257257- }
258258- }
259259- else
260260- {
261261- /* Decrease the adjustment threshold */
262262- if (!(--Prcb->AdjustDpcThreshold))
263263- {
264264- /* We've hit 0, reset it */
265265- Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
266266-267267- /* Check if we've hit queue maximum */
268268- if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
269269- {
270270- /* Increase maximum by one */
271271- Prcb->MaximumDpcQueueDepth++;
272272- }
273273- }
274274- }
275275-276276- /*
277277- * If we're at end of quantum request software interrupt. The rest
278278- * is handled in KiDispatchInterrupt.
279279- *
280280- * NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine
281281- * which checks for quantum end will not be executed and decrementing
282282- * the quantum here can result in overflow. This is not a problem since
283283- * we don't care about the quantum value anymore after the QuantumEnd
284284- * flag is set.
285285- */
286286- if ((CurrentThread->Quantum -= 3) <= 0)
287287- {
288288- Prcb->QuantumEnd = TRUE;
289289- HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
290290- }
291291-}
292292-293293-294294-/*
295295- * NOTE: On Windows this function takes exactly zero parameters and EBP is
296296- * guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL.
297297- * The function is used only by HAL, so there's no point in keeping
298298- * that prototype.
299299- *
300300- * @implemented
301301- */
302302-VOID
303303-NTAPI
304304-KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
305305- IN KIRQL Irql,
306306- IN ULONG Increment)
307307-{
308308- LONG OldOffset;
309309- LARGE_INTEGER Time;
310310- ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
311311-312312- /* Update interrupt time */
313313- Time.LowPart = SharedUserData->InterruptTime.LowPart;
314314- Time.HighPart = SharedUserData->InterruptTime.High1Time;
315315- Time.QuadPart += Increment;
316316- SharedUserData->InterruptTime.High2Time = Time.u.HighPart;
317317- SharedUserData->InterruptTime.LowPart = Time.u.LowPart;
318318- SharedUserData->InterruptTime.High1Time = Time.u.HighPart;
319319-320320- /* Increase the tick offset */
321321- KiTickOffset -= Increment;
322322- OldOffset = KiTickOffset;
323323-324324- /* Check if this isn't a tick yet */
325325- if (KiTickOffset > 0)
326326- {
327327- /* Expire timers */
328328- KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
329329- }
330330- else
331331- {
332332- /* Setup time structure for system time */
333333- Time.LowPart = SharedUserData->SystemTime.LowPart;
334334- Time.HighPart = SharedUserData->SystemTime.High1Time;
335335- Time.QuadPart += KeTimeAdjustment;
336336- SharedUserData->SystemTime.High2Time = Time.HighPart;
337337- SharedUserData->SystemTime.LowPart = Time.LowPart;
338338- SharedUserData->SystemTime.High1Time = Time.HighPart;
339339-340340- /* Setup time structure for tick time */
341341- Time.LowPart = KeTickCount.LowPart;
342342- Time.HighPart = KeTickCount.High1Time;
343343- Time.QuadPart += 1;
344344- KeTickCount.High2Time = Time.HighPart;
345345- KeTickCount.LowPart = Time.LowPart;
346346- KeTickCount.High1Time = Time.HighPart;
347347- SharedUserData->TickCount.High2Time = Time.HighPart;
348348- SharedUserData->TickCount.LowPart = Time.LowPart;
349349- SharedUserData->TickCount.High1Time = Time.HighPart;
350350-351351- /* Queue a DPC that will expire timers */
352352- KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
353353- }
354354-355355- /* Update process and thread times */
356356- if (OldOffset <= 0)
357357- {
358358- /* This was a tick, calculate the next one */
359359- KiTickOffset += KeMaximumIncrement;
360360- KeUpdateRunTime(TrapFrame, Irql);
361361- }
362362-}
363363-364364-VOID NTAPI
365365-KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
366366-/*
367367- * FUNCTION: Calls all the interrupt handlers for a given irq.
368368- * ARGUMENTS:
369369- * vector - The number of the vector to call handlers for.
370370- * old_level - The irql of the processor when the irq took place.
371371- * NOTES: Must be called at DIRQL.
372372- */
373373-{
374374- PKINTERRUPT isr;
375375- PLIST_ENTRY current;
376376- KIRQL oldlvl;
377377- PISR_TABLE CurrentIsr;
378378-379379- DPRINT("I(0x%.08x, 0x%.08x)\n", vector, old_level);
380380-381381- /*
382382- * Iterate the list until one of the isr tells us its device interrupted
383383- */
384384- CurrentIsr = &IsrTable[vector][(ULONG)KeGetCurrentProcessorNumber()];
385385-386386- KiAcquireSpinLock(&CurrentIsr->Lock);
387387-388388- CurrentIsr->Count++;
389389- current = CurrentIsr->ListHead.Flink;
390390-391391- while (current != &CurrentIsr->ListHead)
392392- {
393393- isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
394394- oldlvl = KeAcquireInterruptSpinLock(isr);
395395- if (isr->ServiceRoutine(isr, isr->ServiceContext))
396396- {
397397- KeReleaseInterruptSpinLock(isr, oldlvl);
398398- break;
399399- }
400400- KeReleaseInterruptSpinLock(isr, oldlvl);
401401- current = current->Flink;
402402- }
403403- KiReleaseSpinLock(&CurrentIsr->Lock);
404404-}
405405-406406-VOID
407407-KiInterruptDispatch3 (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
408408-/*
409409- * FUNCTION: Calls the irq specific handler for an irq
410410- * ARGUMENTS:
411411- * irq = IRQ that has interrupted
412412- */
413413-{
414414- KIRQL old_level;
415415- KTRAP_FRAME KernelTrapFrame;
416416- PKTHREAD CurrentThread;
417417- PKTRAP_FRAME OldTrapFrame=NULL;
418418-419419- /*
420420- * At this point we have interrupts disabled, nothing has been done to
421421- * the PIC.
422422- */
423423-424424- KeGetCurrentPrcb()->InterruptCount++;
425425-426426- /*
427427- * Notify the rest of the kernel of the raised irq level. For the
428428- * default HAL this will send an EOI to the PIC and alter the IRQL.
429429- */
430430- if (!HalBeginSystemInterrupt (vector,
431431- vector,
432432- &old_level))
433433- {
434434- return;
435435- }
436436-437437-438438- /*
439439- * Enable interrupts
440440- * NOTE: Only higher priority interrupts will get through
441441- */
442442- _enable();
443443-444444-#ifndef CONFIG_SMP
445445- if (vector == 0)
446446- {
447447- KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
448448- KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
449449- }
450450- else
451451-#endif
452452- {
453453- /*
454454- * Actually call the ISR.
455455- */
456456- KiInterruptDispatch2(vector, old_level);
457457- }
458458-459459- /*
460460- * End the system interrupt.
461461- */
462462- _disable();
463463-464464- if (old_level==PASSIVE_LEVEL)
465465- {
466466- HalEndSystemInterrupt (APC_LEVEL, 0);
467467-468468- CurrentThread = KeGetCurrentThread();
469469- if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending)
470470- {
471471- if (CurrentThread->TrapFrame == NULL)
472472- {
473473- OldTrapFrame = CurrentThread->TrapFrame;
474474- KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
475475- CurrentThread->TrapFrame = &KernelTrapFrame;
476476- }
477477-478478- _enable();
479479- KiDeliverApc(UserMode, NULL, NULL);
480480- _disable();
481481-482482- ASSERT(KeGetCurrentThread() == CurrentThread);
483483- if (CurrentThread->TrapFrame == &KernelTrapFrame)
484484- {
485485- KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe);
486486- CurrentThread->TrapFrame = OldTrapFrame;
487487- }
488488- }
489489- KeLowerIrql(PASSIVE_LEVEL);
490490- }
491491- else
492492- {
493493- HalEndSystemInterrupt (old_level, 0);
494494- }
495495-496496-}
497497-498498-static VOID
499499-KeDumpIrqList(VOID)
500500-{
501501- PKINTERRUPT current;
502502- PLIST_ENTRY current_entry;
503503- LONG i, j;
504504- KIRQL oldlvl;
505505- BOOLEAN printed;
506506-507507- for (i=0;i<NR_TRAPS;i++)
508508- {
509509- printed = FALSE;
510510- KeRaiseIrql(i,&oldlvl);
511511-512512- for (j=0; j < KeNumberProcessors; j++)
513513- {
514514- KiAcquireSpinLock(&IsrTable[i][j].Lock);
515515-516516- current_entry = IsrTable[i][j].ListHead.Flink;
517517- current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
518518- while (current_entry!=&(IsrTable[i][j].ListHead))
519519- {
520520- if (printed == FALSE)
521521- {
522522- printed = TRUE;
523523- DPRINT("For irq %x:\n",i);
524524- }
525525- DPRINT(" Isr %x\n",current);
526526- current_entry = current_entry->Flink;
527527- current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
528528- }
529529- KiReleaseSpinLock(&IsrTable[i][j].Lock);
530530- }
531531- KeLowerIrql(oldlvl);
532532- }
533533-}
534534-535535-/*
536536- * @implemented
537537- */
538538-BOOLEAN
539539-NTAPI
540540-KeConnectInterrupt(PKINTERRUPT InterruptObject)
541541-{
542542- KIRQL oldlvl,synch_oldlvl;
543543- PKINTERRUPT ListHead;
544544- ULONG Vector;
545545- PISR_TABLE CurrentIsr;
546546- BOOLEAN Result;
547547-548548- DPRINT("KeConnectInterrupt()\n");
549549-550550- Vector = InterruptObject->Vector;
551551-552552- if (Vector < 0 || Vector >= NR_TRAPS)
553553- return FALSE;
554554-555555- ASSERT (InterruptObject->Number < KeNumberProcessors);
556556-557557- KeSetSystemAffinityThread(1 << InterruptObject->Number);
558558-559559- CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->Number];
560560-561561- KeRaiseIrql(Vector,&oldlvl);
562562- KiAcquireSpinLock(&CurrentIsr->Lock);
563563-564564- /*
565565- * Check if the vector is already in use that we can share it
566566- */
567567- if (!IsListEmpty(&CurrentIsr->ListHead))
568568- {
569569- ListHead = CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
570570- if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
571571- {
572572- KiReleaseSpinLock(&CurrentIsr->Lock);
573573- KeLowerIrql(oldlvl);
574574- KeRevertToUserAffinityThread();
575575- return FALSE;
576576- }
577577- }
578578-579579- synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
580580-581581- DPRINT("%x %x\n",CurrentIsr->ListHead.Flink, CurrentIsr->ListHead.Blink);
582582-583583- Result = HalEnableSystemInterrupt(Vector, InterruptObject->Irql, InterruptObject->Mode);
584584- if (Result)
585585- {
586586- InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
587587- DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink, InterruptObject->InterruptListEntry.Blink);
588588- }
589589-590590- InterruptObject->Connected = TRUE;
591591- KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
592592-593593- /*
594594- * Release the table spinlock
595595- */
596596- KiReleaseSpinLock(&CurrentIsr->Lock);
597597- KeLowerIrql(oldlvl);
598598-599599- KeDumpIrqList();
600600-601601- KeRevertToUserAffinityThread();
602602-603603- return Result;
604604-}
605605-606606-/*
607607- * @implemented
608608- *
609609- * FUNCTION: Releases a drivers isr
610610- * ARGUMENTS:
611611- * InterruptObject = isr to release
612612- */
613613-BOOLEAN
614614-NTAPI
615615-KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
616616-{
617617- KIRQL oldlvl,synch_oldlvl;
618618- PISR_TABLE CurrentIsr;
619619- BOOLEAN State;
620620-621621- DPRINT1("KeDisconnectInterrupt\n");
622622- ASSERT (InterruptObject->Number < KeNumberProcessors);
623623-624624- /* Set the affinity */
625625- KeSetSystemAffinityThread(1 << InterruptObject->Number);
626626-627627- /* Get the ISR Tabe */
628628- CurrentIsr = &IsrTable[InterruptObject->Vector]
629629- [(ULONG)InterruptObject->Number];
630630-631631- /* Raise IRQL to required level and lock table */
632632- KeRaiseIrql(InterruptObject->Vector,&oldlvl);
633633- KiAcquireSpinLock(&CurrentIsr->Lock);
634634-635635- /* Check if it's actually connected */
636636- if ((State = InterruptObject->Connected))
637637- {
638638- /* Lock the Interrupt */
639639- synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
640640-641641- /* Remove this one, and check if all are gone */
642642- RemoveEntryList(&InterruptObject->InterruptListEntry);
643643- if (IsListEmpty(&CurrentIsr->ListHead))
644644- {
645645- /* Completely Disable the Interrupt */
646646- HalDisableSystemInterrupt(InterruptObject->Vector, InterruptObject->Irql);
647647- }
648648-649649- /* Disconnect it */
650650- InterruptObject->Connected = FALSE;
651651-652652- /* Release the interrupt lock */
653653- KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
654654- }
655655- /* Release the table spinlock */
656656- KiReleaseSpinLock(&CurrentIsr->Lock);
657657- KeLowerIrql(oldlvl);
658658-659659- /* Go back to default affinity */
660660- KeRevertToUserAffinityThread();
661661-662662- /* Return Old Interrupt State */
663663- return State;
664664-}
665665-666666-/*
667667- * @implemented
668668- */
669669-VOID
670670-NTAPI
671671-KeInitializeInterrupt(PKINTERRUPT Interrupt,
672672- PKSERVICE_ROUTINE ServiceRoutine,
673673- PVOID ServiceContext,
674674- PKSPIN_LOCK SpinLock,
675675- ULONG Vector,
676676- KIRQL Irql,
677677- KIRQL SynchronizeIrql,
678678- KINTERRUPT_MODE InterruptMode,
679679- BOOLEAN ShareVector,
680680- CHAR ProcessorNumber,
681681- BOOLEAN FloatingSave)
682682-{
683683- /* Set the Interrupt Header */
684684- Interrupt->Type = InterruptObject;
685685- Interrupt->Size = sizeof(KINTERRUPT);
686686-687687- /* Check if we got a spinlock */
688688- if (SpinLock)
689689- {
690690- Interrupt->ActualLock = SpinLock;
691691- }
692692- else
693693- {
694694- /* This means we'll be usin the built-in one */
695695- KeInitializeSpinLock(&Interrupt->SpinLock);
696696- Interrupt->ActualLock = &Interrupt->SpinLock;
697697- }
698698-699699- /* Set the other settings */
700700- Interrupt->ServiceRoutine = ServiceRoutine;
701701- Interrupt->ServiceContext = ServiceContext;
702702- Interrupt->Vector = Vector;
703703- Interrupt->Irql = Irql;
704704- Interrupt->SynchronizeIrql = SynchronizeIrql;
705705- Interrupt->Mode = InterruptMode;
706706- Interrupt->ShareVector = ShareVector;
707707- Interrupt->Number = ProcessorNumber;
708708- Interrupt->FloatingSave = FloatingSave;
709709-710710- /* Disconnect it at first */
711711- Interrupt->Connected = FALSE;
712712-}
713713-714714-VOID KePrintInterruptStatistic(VOID)
715715-{
716716- LONG i, j;
717717-718718- for (j = 0; j < KeNumberProcessors; j++)
719719- {
720720- DPRINT1("CPU%d:\n", j);
721721- for (i = 0; i < NR_TRAPS; i++)
722722- {
723723- if (IsrTable[i][j].Count)
724724- {
725725- DPRINT1(" Irq %x(%d): %d\n", i, i, IsrTable[i][j].Count);
726726- }
727727- }
728728- }
729729-}
730730-731731-BOOLEAN
732732-NTAPI
733733-KeDisableInterrupts(VOID)
734734-{
735735- ULONG Flags = 0;
736736- BOOLEAN Return;
737737-738738- Flags = __readmsr();
739739- Return = (Flags & 0x8000) ? TRUE: FALSE;
740740-741741- /* Disable interrupts */
742742- _disable();
743743- return Return;
744744-}
745745-746746-ULONG
747747-NTAPI
748748-KdpServiceDispatcher(ULONG Service,
749749- PVOID Buffer1,
750750- ULONG Buffer1Length,
751751- KPROCESSOR_MODE PreviousMode);
752752-753753-typedef ULONG (*PSYSCALL_FUN)
754754-(ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG,ULONG);
755755-756756-VOID
757757-NTAPI
758758-KiSystemService(ppc_trap_frame_t *trap_frame)
759759-{
760760- int i;
761761- PKSYSTEM_ROUTINE SystemRoutine;
762762- PSYSCALL_FUN SyscallFunction;
763763-764764- switch(trap_frame->gpr[0])
765765- {
766766- case 0x10000: /* DebugService */
767767- for( i = 0; i < trap_frame->gpr[5]; i++ )
768768- {
769769- PearPCDebug(((PCHAR)trap_frame->gpr[4])[i]);
770770- WRITE_PORT_UCHAR((PVOID)0x800003f8, ((PCHAR)trap_frame->gpr[4])[i]);
771771- }
772772- trap_frame->gpr[3] = KdpServiceDispatcher
773773- (trap_frame->gpr[3],
774774- (PCHAR)trap_frame->gpr[4],
775775- trap_frame->gpr[5],
776776- UserMode /*KernelMode*/);
777777- break;
778778- case 0xf0000: /* Thread startup */
779779- /* XXX how to use UserThread (gpr[6]) */
780780- SystemRoutine = (PKSYSTEM_ROUTINE)trap_frame->gpr[3];
781781- SystemRoutine((PKSTART_ROUTINE)trap_frame->gpr[4],
782782- (PVOID)trap_frame->gpr[5]);
783783- break;
784784-785785- /* Handle a normal system call */
786786- default:
787787- SyscallFunction =
788788- ((PSYSCALL_FUN*)KeServiceDescriptorTable
789789- [trap_frame->gpr[0] >> 12].Base)[trap_frame->gpr[0] & 0xfff];
790790- trap_frame->gpr[3] = SyscallFunction
791791- (trap_frame->gpr[3],
792792- trap_frame->gpr[4],
793793- trap_frame->gpr[5],
794794- trap_frame->gpr[6],
795795- trap_frame->gpr[7],
796796- trap_frame->gpr[8],
797797- trap_frame->gpr[9],
798798- trap_frame->gpr[10],
799799- trap_frame->gpr[11],
800800- trap_frame->gpr[12]);
801801- break;
802802- }
803803-}
804804-805805-/* EOF */
···11-#ifndef FREELDR_MMU_H
22-#define FREELDR_MMU_H
33-44-int GetDEC(void);
55-int GetMSR(void);
66-int GetPhys( paddr_t addr );
77-int GetPhysHalf( paddr_t addr );
88-int GetPhysByte( paddr_t addr );
99-void SetPhys( paddr_t addr, int val );
1010-void SetPhysHalf( paddr_t addr, int val );
1111-void SetPhysByte( paddr_t addr, int val );
1212-int GetSR(int n);
1313-void SetSR(int n, int val);
1414-void GetBat( int bat, int inst, int *batHi, int *batLo );
1515-void SetBat( int bat, int inst, int batHi, int batLo );
1616-int GetSDR1(void);
1717-void SetSDR1( int newsdr );
1818-int BatHit( int bath, int batl, int virt );
1919-int BatTranslate( int bath, int batl, int virt );
2020-/* translate address */
2121-int PpcVirt2phys( vaddr_t virt, int inst );
2222-int PtegNumber( vaddr_t virt, int hfun );
2323-#endif/*FREELDR_MMU_H*/
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS kernel
44- * PURPOSE: Stack checker
55- * FILE: lib/sdk/crt/except/powerpc/chkstk_asm.s
66- * PROGRAMER: arty
77- */
88-99-.globl _chkstk
1010-.globl _alloca_probe
1111-1212-/*
1313- _chkstk() is called by all stack allocations of more than 4 KB. It grows the
1414- stack in areas of 4 KB each, trying to access each area. This ensures that the
1515- guard page for the stack is hit, and the stack growing triggered
1616- */
1717-_chkstk:
1818-_alloca_probe:
1919- /* return */
2020- blr
2121-2222-/* EOF */
-75
sdk/lib/crt/except/powerpc/seh.s
···11-/*
22- * COPYRIGHT: See COPYING in the top level directory
33- * PROJECT: ReactOS CRT
44- * FILE: lib/sdk/crt/except/powerpc/seh.s
55- * PURPOSE: SEH Support for the CRT
66- * PROGRAMMERS: arty
77- */
88-99-/* INCLUDES ******************************************************************/
1010-1111-#include <ndk/asm.h>
1212-1313-#define DISPOSITION_DISMISS 0
1414-#define DISPOSITION_CONTINUE_SEARCH 1
1515-#define DISPOSITION_COLLIDED_UNWIND 3
1616-1717-/* GLOBALS *******************************************************************/
1818-1919-.globl _global_unwind2
2020-.globl _local_unwind2
2121-.globl _abnormal_termination
2222-.globl _except_handler2
2323-.globl _except_handler3
2424-2525-/* FUNCTIONS *****************************************************************/
2626-2727-unwind_handler:
2828- blr
2929-3030-_global_unwind2:
3131- blr
3232-3333-_local_unwind2:
3434- blr
3535-3636-_except_handler2:
3737- blr
3838-3939-_except_handler3:
4040- blr
4141-4242-//
4343-//
4444-// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME
4545-// sorry
4646-//
4747-//
4848-.globl RtlpGetStackLimits
4949-RtlpGetStackLimits:
5050- stwu 1,16(1)
5151- mflr 0
5252-5353- stw 0,4(1)
5454- stw 3,8(1)
5555- stw 4,12(1)
5656-5757- /* Get the current thread */
5858- lwz 3,KPCR_CURRENT_THREAD(13)
5959-6060- /* Get the stack limits */
6161- lwz 4,KTHREAD_STACK_LIMIT(3)
6262- lwz 5,KTHREAD_INITIAL_STACK(3)
6363- subi 5,5,SIZEOF_FX_SAVE_AREA
6464-6565- /* Return them */
6666- lwz 3,8(1)
6767- stw 4,0(3)
6868-6969- lwz 3,12(1)
7070- stw 5,0(3)
7171-7272- addi 1,1,16
7373-7474- /* return */
7575- blr
···11-// Copyright (c) 2004/2005 KJK::Hyperion
22-33-// Permission is hereby granted, free of charge, to any person obtaining a copy
44-// of this software and associated documentation files (the "Software"), to deal
55-// in the Software without restriction, including without limitation the rights
66-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
77-// copies of the Software, and to permit persons to whom the Software is
88-// furnished to dos so, subject to the following conditions:
99-1010-// The above copyright notice and this permission notice shall be included in all
1111-// copies or substantial portions of the Software.
1212-1313-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1414-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1515-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1616-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1717-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1818-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919-// SOFTWARE.
2020-2121-.text
2222-2323-.globl _SEHCleanHandlerEnvironment
2424-_SEHCleanHandlerEnvironment:
2525- blr
2626-2727-.globl _SEHCurrentRegistration
2828-_SEHCurrentRegistration:
2929- lwz 3,0(13)
3030- blr
3131-3232- // R3: Frame to store in
3333-.globl _SEHRegisterFrame
3434-_SEHRegisterFrame:
3535- lwz 4,0(13)
3636- stw 3,0(13)
3737- stw 4,0(3)
3838- blr
3939-4040-.globl _SEHUnregisterFrame
4141-_SEHUnregisterFrame:
4242- lwz 3,0(13)
4343- lwz 3,0(3)
4444- stw 3,0(13)
4545- blr
4646-4747-.globl _SEHGlobalUnwind
4848-_SEHGlobalUnwind:
4949-5050-.extern _SEHRtlUnwind
5151-5252-// RtlUnwind clobbers all the "don't clobber" registers, so we save them
5353- lwz 3,4(1)
5454- stwu 1,-132(1)
5555- stmw 2,-128(1)
5656-5757- xor 6,6,6
5858- xor 5,5,5
5959- lis 4,.RestoreRegisters@ha
6060- addi 4,4,.RestoreRegisters@l # Where to jump back to
6161- # We already have r3
6262- bl _SEHRtlUnwind
6363-6464-.RestoreRegisters:
6565- lmw 2,-128(1)
6666- addi 1,1,132
6767- blr
6868-6969-// EOF