Commit 4a5c5ee6 authored by Ben Avison's avatar Ben Avison
Browse files

Lots of improvements, working towards support for UDMA etc.

Detail:
  * No longer uses temporay HAL DMA entry points, all hardware access is
    accomplished using device entry points.
  * Supports multiple DMA controllers, including dynamic addition and
    removal of controllers (using OS_Hardware 4 and Service_Hardware).
  * Added *DMAChannels, which enumerates the currently registered DMA
    channels, listed according to physical location.
  * Logical channel blocks are dynamically allocated (as a requirement of
    the above changes) so logical channel handles are now pointers, no
    longer an array index. Just so you know.
  * Removed now-obsolete EnumerateLogical entry from controller device API.
  * Added pointer-to-controller-device item in publically visible part of
    channel device structure.
  * Moved memory-to-memory channel device entries to end of channel device
    structure (I'm considering removing them).
  * Added support for GPA debugging listing (requires BuildSys 3.86).
Admin:
  Tested on Tungsten (ie floppies still work).

Version 0.15, 4.4.2.6. Tagged as 'DMA-0_15-4_4_2_6'
parent 77cdce3b
......@@ -39,9 +39,7 @@ struct dmacontroller
uint32_t (*Features)(struct dmacontroller *);
__value_in_regs struct { struct dmachannel **channel; uint32_t count; }
(*EnumeratePhysical)(struct dmacontroller *);
__value_in_regs struct { uint32_t *channel; uint32_t count; }
(*EnumerateLogical)(struct dmacontroller *);
(*Enumerate)(struct dmacontroller *);
struct dmachannel *(*Allocate)(struct dmacontroller *, uint32_t channel);
void (*Deallocate)(struct dmacontroller *, uint32_t channel);
}
......@@ -59,7 +57,7 @@ dev.Sleep
dev.devicenumber
dev.TestIRQ
Standard functions as defined in Docs.HAL.NewAPI.
Type = &301.
Type = &302.
Address is not used.
Controllers are activated/deactivated on module initialisation/finalisation.
Interrupts are ignored - provide them using the DMA channel device instead.
......@@ -68,12 +66,9 @@ Features
Returns a flags word indicating the capabilities of the controller.
Currently no bits defined, all bits should be zero.
EnumeratePhysical
Enumerate
Returns a static list of available physical DMA channel devices.
EnumerateLogical
Returns a static list of logical DMA channels supported by the controller.
Allocate
Returns pointer to the physical DMA channel struct to associate with the
given logical DMA channel. If the hardware requires a particular logical-
......@@ -95,8 +90,8 @@ Deallocate
DMA channel device
------------------
DMA channel device - buffer type
--------------------------------
struct dmachannel
{
......@@ -104,6 +99,7 @@ struct dmachannel
struct device dev;
uint32_t (*Features)(struct dmachannel *);
dmacontroller *Controller;
void (*Abort)(struct device *);
void (*SetOptions)(struct dmachannel *, uint32_t flags, uint32_t address);
void (*SetCurrentTransfer)(struct dmachannel *, uint32_t address,
......@@ -112,14 +108,14 @@ struct dmachannel
uint32_t length, uint32_t flags);
__value_in_regs struct { uint32_t address; uint32_t length; }
(*TransferState)(struct dmachannel *);
void (*IRQClear)(struct dmachannel *);
uint32_t (*Status)(struct dmachannel *);
void (*SetCurrentTransfer2)(struct dmachannel *, uint32_t srcaddress,
uint32_t dstaddress, uint32_t length, uint32_t flags);
void (*SetNextTransfer2)(struct dmachannel *, uint32_t srcaddress,
uint32_t dstaddress, uint32_t length, uint32_t flags);
__value_in_regs struct { uint32_t srcaddress; uint32_t dstaddress;
uint32_t length; } (*TransferState2)(struct dmachannel *);
void (*IRQClear)(struct dmachannel *);
uint32_t (*Status)(struct dmachannel *);
}
dev.type
......@@ -135,7 +131,7 @@ dev.Sleep
dev.devicenumber
dev.TestIRQ
Standard functions as defined in Docs.HAL.NewAPI.
Type = &302.
Type = &303.
Address is not used.
Channels are activated/deactivated around each transfer.
......@@ -161,6 +157,9 @@ Features
activated, then the whole transfer must be delayed
other bits reserved, should be zero
Controller
A pointer to this channel's DMA controller device.
Abort
This should be considered a "forced" version of dev.Deactivate, and is only
used for SWI DMA_TerminateTransfer. The call must not block, but the values
......@@ -204,13 +203,9 @@ TransferState
If the DMA controller will not report accurate progress, report values
corresponding to a pessimistic amount of progress.
SetCurrentTransfer2 / SetNextTransfer2 / TransferState2
are same as above but with two address arguments and one length argument. For
use in memory-to-memory transfers only.
IRQClear
Clears the interrupt for this physical DMA channel (unless some other action
carried out during or since since TestIRQ has already done so).
carried out during or since TestIRQ has already done so).
Status
Returns status bits for the current channel:
......@@ -231,3 +226,7 @@ Status
this time using SetCurrentTransfer. This bit must be clear if
the last transfer was programmed using SetCurrentTransfer, or if
bit 1 is clear.
SetCurrentTransfer2 / SetNextTransfer2 / TransferState2
are same as above but with two address arguments and one length argument. For
use in memory-to-memory transfers only.
| Copyright 2002 Tematic Ltd
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|
Dir <Obey$Dir>
amu_machine gpa_debug THROWBACK=-throwback
No preview for this file type
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.15"
Module_Version SETA 15
Module_MinorVersion SETS "4.4.2.5"
Module_Date SETS "22 Nov 2002"
Module_ApplicationDate SETS "22-Nov-02"
Module_MinorVersion SETS "4.4.2.6"
Module_Date SETS "13 Dec 2002"
Module_ApplicationDate SETS "13-Dec-02"
Module_ComponentName SETS "DMA"
Module_ComponentPath SETS "RiscOS/Sources/HWSupport/DMA"
Module_FullVersion SETS "0.15 (4.4.2.5)"
Module_HelpVersion SETS "0.15 (22 Nov 2002) 4.4.2.5"
Module_FullVersion SETS "0.15 (4.4.2.6)"
Module_HelpVersion SETS "0.15 (13 Dec 2002) 4.4.2.6"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 0.15
#define Module_MinorVersion_CMHG 4.4.2.5
#define Module_Date_CMHG 22 Nov 2002
#define Module_MinorVersion_CMHG 4.4.2.6
#define Module_Date_CMHG 13 Dec 2002
#define Module_MajorVersion "0.15"
#define Module_Version 15
#define Module_MinorVersion "4.4.2.5"
#define Module_Date "22 Nov 2002"
#define Module_MinorVersion "4.4.2.6"
#define Module_Date "13 Dec 2002"
#define Module_ApplicationDate "22-Nov-02"
#define Module_ApplicationDate "13-Dec-02"
#define Module_ComponentName "DMA"
#define Module_ComponentPath "RiscOS/Sources/HWSupport/DMA"
#define Module_FullVersion "0.15 (4.4.2.5)"
#define Module_HelpVersion "0.15 (22 Nov 2002) 4.4.2.5"
#define Module_FullVersion "0.15 (4.4.2.6)"
#define Module_HelpVersion "0.15 (13 Dec 2002) 4.4.2.6"
#define Module_LibraryVersionInfo "0:15"
......@@ -29,27 +29,27 @@ Included_Hdr_DMADevice SETL {TRUE}
^ 0
# HALDeviceSize
HALDevice_DMACFeatures # 4
HALDevice_DMACEnumeratePhysical # 4
HALDevice_DMACEnumerateLogical # 4
HALDevice_DMACEnumerate # 4
HALDevice_DMACAllocate # 4
HALDevice_DMACDeallocate # 4
HALDevice_DMAC_Size * :INDEX: @
; Device for each physical DMA channel
; Device for each physical DMA channel (buffer type)
^ 0
# HALDeviceSize
HALDevice_DMAFeatures # 4
HALDevice_DMAController # 4
HALDevice_DMAAbort # 4
HALDevice_DMASetOptions # 4
HALDevice_DMASetCurrentTransfer # 4
HALDevice_DMASetNextTransfer # 4
HALDevice_DMATransferState # 4
HALDevice_DMAIRQClear # 4
HALDevice_DMAStatus # 4
HALDevice_DMASetCurrentTransfer2 # 4
HALDevice_DMASetNextTransfer2 # 4
HALDevice_DMATransferState2 # 4
HALDevice_DMAIRQClear # 4
HALDevice_DMAStatus # 4
HALDevice_DMA_Size * :INDEX: @
DMAFeaturesFlag_CantSuspend * 1 :SHL: 0 ; don't activate transfer until all of the scatter list is on safe pages
......
......@@ -14,9 +14,6 @@
;
; CallHAL
;
; Attempt to insulate HAL caller from the differences between the HAL's
; device-based and non-device-based calling standards
;
; On entry:
; r0-r3 hold first 4 arguments
; up to 4 more arguments are on the stack
......@@ -27,68 +24,12 @@
;
; Macro parameters:
; $routine = name of routine to call
; $savelist = *comma-separated* list of additional registers to save
; $savelist = list of additional registers to save
; across the call (from the set r0,r1,r2,r3,r14);
; note that if there is more than one register in the list,
; this means that the list must be enclosed by quotes
; $stackedargs = number of arguments that are on the stack (0-4)
[ {TRUE}
GET hdr:HALEntries
MACRO
$label CallHAL $routine, $savelist, $stackedargs
LCLS arglist
arglist SETS ""
[ "$stackedargs"<>""
LCLA tempa
tempa SETA 3+$stackedargs
WHILE tempa>3
[ :LEN:arglist=0
arglist SETS "r"
|
arglist SETS "$arglist,r"
]
arglist SETS "$arglist":CC::CHR:(48+tempa)
tempa SETA tempa-1
WEND
]
LCLS reglist
reglist SETS "r8,r9"
[ "$savelist"<>""
reglist SETS "$reglist,$savelist"
]
[ :LEN:arglist>0
reglist SETS "$reglist,$arglist"
]
Push "$reglist"
[ "$stackedargs"<>""
LCLA listlen
listlen SETA 1
LCLS temps
temps SETS reglist
WHILE :LEN:temps>0
[ temps:LEFT:1 = ","
listlen SETA listlen+1
]
temps SETS temps:RIGHT:(:LEN:temps-1)
WEND
[ $stackedargs=1
LDR r4,[sp,#4*$listlen]
|
ADD r8,sp,#4*$listlen
LDMIA r8,{$arglist}
]
]
MOV r8,#0 ; OS_Hardware 0 calls routine immediately
MOV r9,#EntryNo_HAL_DMA_$routine
SWI XOS_Hardware
Pull "$reglist"
MEND
|
MACRO
$label CallHAL $routine, $savelist, $stackedargs
LCLS reglist
......@@ -102,6 +43,4 @@ reglist SETS "$reglist,$savelist"
Pull "$reglist"
MEND
]
END
; Copyright 2002 Tematic Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > Sources.Command
ASSERT international
DMAChannels_Code
LDR r12, [r12]
Entry "r7-r11"
LDR r11, CtrlrList
TEQ r11, #0
EXIT EQ
; Cache information about the logical channel table.
ADR r1, I06
MOV r2, #0
BL MsgTrans_Lookup
STRVC r0, Header+4*0
ADDVC r1, r0, #1
01 LDRVCB r2, [r0], #1
TEQ r2, #0
BNE %BT01
SUBVC r1, r0, r1
STRVCB r1, Width+1*0
ADRVC r1, I07
MOVVC r2, #0
BLVC MsgTrans_Lookup
STRVC r0, Header+4*1
ADDVC r1, r0, #1
02 LDRVCB r2, [r0], #1
TEQ r2, #0
BNE %BT02
SUBVC r1, r0, r1
STRVCB r1, Width+1*1
ADRVC r1, I08
MOVVC r2, #0
BLVC MsgTrans_Lookup
STRVC r0, Header+4*2
ADDVC r1, r0, #1
03 LDRVCB r2, [r0], #1
TEQ r2, #0
BNE %BT03
SUBVC r1, r0, r1
STRVCB r1, Width+1*2
BVS %FT90
10 ; Print controller header.
ADR r1, I00
ADR r2, Scratch
MOV r3, #?Scratch
LDR r4, [r11, #ctrlr_Device]
LDR r4, [r4, #HALDevice_Description]
BL MsgTrans_Lookup
SWIVC XOS_Write0
SWIVC XOS_NewLine
SWIVC XOS_NewLine
BVS %FT90
LDR r10, [r11, #ctrlr_PhysicalChannels]
; Count used channels.
ADD r6, r11, #ctrlr_DMAQueues + dmaq_Usage
MOV r7, r10
MOV r9, #0
20 LDR r14, [r6], #DMAQSize
TEQ r14, #0
ADDNE r9, r9, #1
SUBS r7, r7, #1
BNE %BT20
; Print number of free channels.
ADR r1, I04
MOV r2, #0
BL MsgTrans_Lookup
BVS %FT90
MOV r4, r0
SUB r0, r10, r9
CMP r0, #1
ADRLO r1, I01
ADREQ r1, I02
ADRHI r1, Scratch + ?Scratch - 16
MOVHI r2, #16
SWIHI XOS_ConvertCardinal4
MOVHI r5, r4
MOVHI r4, r0
ADRHI r1, I03
ADR r2, Scratch
MOV r3, #?Scratch
BL MsgTrans_Lookup
SWIVC XOS_Write0
SWIVC XOS_NewLine
BVS %FT90
; Print number of used channels.
ADR r1, I05
MOV r2, #0
BL MsgTrans_Lookup
BVS %FT90
MOV r4, r0
MOV r0, r9
CMP r0, #1
ADRLO r1, I01
ADREQ r1, I02
ADRHI r1, Scratch + ?Scratch - 16
MOVHI r2, #16
SWIHI XOS_ConvertCardinal4
MOVHI r5, r4
MOVHI r4, r0
ADRHI r1, I03
ADR r2, Scratch
MOV r3, #?Scratch
BL MsgTrans_Lookup
SWIVC XOS_Write0
SWIVC XOS_NewLine
BVS %FT90
TEQ r9, #0
BEQ %FT80
ASSERT DMAQSize=96
MOV r10, r10, LSL #5
ADD r10, r10, r10, LSL #6-5
ADD r10, r11, r10
ADD r10, r10, #ctrlr_DMAQueues
30 ; Find a used channel
SUB r10, r10, #DMAQSize
LDR r8, [r10, #dmaq_Usage]
TEQ r8, #0
BEQ %BT30
; Print channel name
SWI XOS_NewLine
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVC r0, [r10, #dmaq_DMADevice]
LDRVC r0, [r0, #HALDevice_Description]
SWIVC XOS_Write0
SWIVC XOS_NewLine
; Print headers
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVC r0, Header+4*0
SWIVC XOS_Write0
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVC r0, Header+4*1
SWIVC XOS_Write0
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVC r0, Header+4*2
SWIVC XOS_Write0
SWIVC XOS_NewLine
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVCB r0, Width+1*0
31 SWIVC XOS_WriteI+'-'
BVS %FT90
SUBS r0, r0, #1
BNE %BT31
SWI XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVCB r0, Width+1*1
32 SWIVC XOS_WriteI+'-'
BVS %FT90
SUBS r0, r0, #1
BNE %BT32
SWI XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
LDRVCB r0, Width+1*2
33 SWIVC XOS_WriteI+'-'
BVS %FT90
SUBS r0, r0, #1
BNE %BT33
SWI XOS_NewLine
; Find a logical channel that uses this physical channel
LDR r7, ChannelList
40 LDR r0, [r7, #lcb_Queue]
TEQ r0, r10
LDRNE r7, [r7, #lcb_Next]
BNE %BT40
; Print logical channel details
SWI XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+' '
SWIVC XOS_WriteI+'&'
LDRVC r0, [r7, #lcb_ChannelNo]
ADRVC r1, Scratch
MOVVC r2, #16
SWIVC XOS_ConvertHex8
SWIVC XOS_Write0
LDRVCB r0, Width+1*0
SUBVC r0, r0, #9-3
41 SWIVC XOS_WriteI+' '
BVS %FT90
SUBS r0, r0, #1
BNE %BT41
SWI XOS_WriteI+'&'
LDRVC r0, [r7, #lcb_Vector]
ADRVC r1, Scratch
MOVVC r2, #16
SWIVC XOS_ConvertHex8
SWIVC XOS_Write0
LDRVCB r0, Width+1*1
SUBVC r0, r0, #9-3
42 SWIVC XOS_WriteI+' '
BVS %FT90
SUBS r0, r0, #1
BNE %BT42
SWI XOS_WriteI+'&'
LDRVC r0, [r7, #lcb_R12]
ADRVC r1, Scratch
MOVVC r2, #16
SWIVC XOS_ConvertHex8
SWIVC XOS_Write0
SWIVC XOS_NewLine
BVS %FT90
; Next logical channel for this physical channel
SUBS r8, r8, #1
LDRNE r7, [r7, #lcb_Next]
BNE %BT40
; Next physical channel for this controller
SUBS r9, r9, #1
BNE %BT30
80 ; Next controller
LDR r11, [r11, #ctrlr_Next]
TEQ r11, #0
EXIT EQ
SWI XOS_NewLine
B %BT10
90
EXIT
I00 = "I00", 0
I01 = "I01", 0
I02 = "I02", 0
I03 = "I03", 0
I04 = "I04", 0
I05 = "I05", 0
I06 = "I06", 0
I07 = "I07", 0
I08 = "I08", 0
ALIGN
END
......@@ -754,7 +754,7 @@ DMAForceActivate
Debug dma," activating"
[ HAL
LDR r5, [r8, #lcb_DMADevice] ; r5 = HAL device for this channel
LDR r5, [r9, #dmaq_DMADevice] ; r5 = HAL device for this channel
|
LDR r1, [r8, #lcb_Physical]
DMARegBlk r3, r1 ; r3->DMA register block for this channel
......@@ -782,8 +782,7 @@ DMAForceActivate
[ HAL
MOV r0, r5
MOV lr, pc
LDR pc, [r0, #HALDevice_Reset]
CallHAL Reset
LDR r1, [r8, #lcb_Vector] ; r1->vector of routines
|
MOV lr, #IOMD_DMA_C_Bit ; Clear DMA channel before calling Enable (stop extra transfers).
......@@ -839,7 +838,7 @@ DMAForceActivate
LDRNE r2, [r8, #lcb_PeripheralWrite]
ORR r1, r1, r3, LSL #1 ; note lcbf_Registered is shifted off end, and lcbf_Blocked will be clear
MOV r0, r5
CallHAL DMA_SetOptions
CallHAL DMASetOptions
LDR r12, [sp, #28+Proc_RegOffset] ; Restore our workspace pointer.
|
LDR r4, [r8, #lcb_Flags] ; Set up control register.
......@@ -895,8 +894,7 @@ DMAForceActivate
BLNE CopyToBounceBuffer ; then we need to fill in the bounce buffer.
MOV r0, r5
MOV lr, pc
LDR pc, [r0, #HALDevice_Activate]
CallHAL Activate
LDR r0, [r5, #HALDevice_Device] ; If the channel has an interrupt,
CMP r0, #-1 ; then it has already or will shortly be triggered.
......@@ -916,7 +914,7 @@ DMAForceActivate
MOV r0, r5
; r2 is already the transfer length
MOV r3, #DMASetTransferFlag_Stop
CallHAL DMA_SetCurrentTransfer
CallHAL DMASetCurrentTransfer
EXITS , f
|
......@@ -991,7 +989,7 @@ DMATerminate
BNE %FT80 ; deal with it.
[ HAL
LDR r4, [r8, #lcb_DMADevice] ; r4 = HAL device for this channel
LDR r4, [r9, #dmaq_DMADevice] ; r4 = HAL device for this channel
TEQ r0, #0 ; Terminate or suspend?
MOV r0, r4
ADR lr, %FT01
......@@ -1024,7 +1022,7 @@ DMATerminate
[ HAL
MOV r0, r4
CallHAL DMA_Status
CallHAL DMAStatus
MOV r11, r0
LDR r8, [r10, #dmar_Flags]
......@@ -1052,7 +1050,7 @@ DMATerminate
BNE %FT10
MOV r0, r4 ; Otherwise account for halted buffer.
MOV r4, r3
CallHAL DMA_TransferState
CallHAL DMATransferState
MOV r3, r4
LDR r2, [r5, #ptab_Physical]
ADD r2, r2, r6 ; This is what the hardware was originally programmed with.
......@@ -1302,19 +1300,28 @@ DMAPagesUnsafe
STMIA lr, {r2,r3} ; when new transfers are activated.
[ HAL
LDR r0, PhysicalChannels
LDR r9, DMAQueues