Commit 327d3980 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Update OS_IICOp to support multiple IIC buses

Detail:
  OS_IICOp (and in turn, RISCOS_IICOpV) now treat the top byte of R1 as containing the IIC bus number, allowing multiple buses to be used.
  hdr/KernelWS - Changed workspace a bit so that the kernel can support up to IICBus_Count buses (currently 3), each with its own IICBus_* block.
  s/HAL - Update Reset_IRQ_Handler to cope with interrupts from all IIC buses instead of just the first. Fix/update RISCOS_IICOpV description.
  s/NewIRQs - Update InitialiseIRQ1Vtable to set up interrupt handlers for all IRQ-supporting IIC buses
  s/NewReset - Get rid of the IICAbort call that was just before IICInit. IICInit now calls IICAbort itself.
  s/PMF/IIC - Bulk of the changes. Code now uses the IICBus_ structures instead of the IICStatus and IICType variables. Re-entrancy code has been updated to take into account the possiblity of multiple buses; when OS_IICOp calls are nested, the IIC transfers will be added to bus-specific queues instead of all going in the same queue. However only one queue will be processed at a time.
  s/ChangeDyn - Workspace shuffling means a couple of MOV's needed to be swapped with LDR's when getting immediate constants
Admin:
  Tested with OMAP & IOMD ROM builds.
  Both high & low-level bus types seem to work OK, along with re-entrancy, both on the same bus and on a different bus.


Version 5.35, 4.79.2.98.2.33. Tagged as 'Kernel-5_35-4_79_2_98_2_33'
parent e718080c
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.98.2.32"
Module_Date SETS "04 Oct 2010"
Module_ApplicationDate SETS "04-Oct-10"
Module_MinorVersion SETS "4.79.2.98.2.33"
Module_Date SETS "19 Feb 2011"
Module_ApplicationDate SETS "19-Feb-11"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.98.2.32)"
Module_HelpVersion SETS "5.35 (04 Oct 2010) 4.79.2.98.2.32"
Module_FullVersion SETS "5.35 (4.79.2.98.2.33)"
Module_HelpVersion SETS "5.35 (19 Feb 2011) 4.79.2.98.2.33"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.98.2.32
#define Module_Date_CMHG 04 Oct 2010
#define Module_MinorVersion_CMHG 4.79.2.98.2.33
#define Module_Date_CMHG 19 Feb 2011
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.98.2.32"
#define Module_Date "04 Oct 2010"
#define Module_MinorVersion "4.79.2.98.2.33"
#define Module_Date "19 Feb 2011"
#define Module_ApplicationDate "04-Oct-10"
#define Module_ApplicationDate "19-Feb-11"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.98.2.32)"
#define Module_HelpVersion "5.35 (04 Oct 2010) 4.79.2.98.2.32"
#define Module_FullVersion "5.35 (4.79.2.98.2.33)"
#define Module_HelpVersion "5.35 (19 Feb 2011) 4.79.2.98.2.33"
#define Module_LibraryVersionInfo "5:35"
......@@ -991,6 +991,14 @@ VDWSSize # 0
ASSERT VDWSSize <= 12 * 1024
; IIC bus info block
^ 0
IICBus_Type # 4 ; Bus type (HAL_IICType)
IICBus_Status # 4 ; Bus status (HAL_IICMonitorTransfer)
IICBus_Device # 4 ; Bus device (HAL_IICDevice)
IICBus_Size # 0
; *****************************************************************************
; Space in the first 32K is allocated below
; *****************************************************************************
......@@ -1287,8 +1295,8 @@ NVRamWriteSize # 1 ; Size of writable region (256byte units
AlignSpace
IICType # 4
IICStatus # 4
IICBus_Count * 3 ; 3 busses is enough for all current machines
IICBus_Base # IICBus_Size*IICBus_Count
AppSpaceDANode # DANode_NodeSize ; Dummy area node for application space (not on list)
FreePoolDANode # DANode_NodeSize ; Area node for free pool
......
......@@ -2746,7 +2746,7 @@ InitDynamicAreas Entry "r0-r8,r11,r12"
MOV r0, #0 ; initialise module list to empty
STR r0, [r0, #Module_List]
MOV lr, #SysHeapDANode ; initialise system heap node
LDR lr, =SysHeapDANode ; initialise system heap node
ADR r0, InitSysHeapTable
LDMIA r0, {r0-r8}
STMIA lr, {r0-r8}
......@@ -2851,7 +2851,7 @@ DynArea_QHinit_loop2
STR R1, [r2, #DANode_SortLink] ; ...and last
ADR r1, DynArea_SysQHandleArray
MOV r2, #SysHeapDANode
LDR r2, =SysHeapDANode
STR r2, [r1, #ChangeDyn_SysHeap:SHL:2]
MOV r2, #FreePoolDANode
STR r2, [r1, #ChangeDyn_FreePool:SHL:2]
......
......@@ -2093,7 +2093,7 @@ RISCOS_LogToPhys
MOVCS a1, #-1
Pull "r4,r5,r8,r9,pc"
; kernel_oserror *RISCOS_IICOpV(int ndesc, IICDesc *descs)
; kernel_oserror *RISCOS_IICOpV(IICDesc *descs, uint32_t ndesc_and_bus)
RISCOS_IICOpV
Push "lr"
BL IIC_OpV
......@@ -2383,22 +2383,28 @@ DebugHALPrint
Reset_IRQ_Handler
SUB lr, lr, #4
Push "a1-a4,sb,ip,lr"
Push "a1-a4,v1-v2,sb,ip,lr"
MRS lr, SPSR
Push "lr"
MOV a1, #ZeroPage
AddressHAL a1
LDR a2, [a1, #IICType]
MOV v2, #0
AddressHAL v2
MOV v1, #IICBus_Base
10
LDR a2, [v1, #IICBus_Type]
TST a2, #IICFlag_Background
MOVNE ip, sb
MOVNE ip, v2
BLNE IICIRQ
ADD v2, v2, #1
ADD v1, v1, #IICBus_Size
CMP v2, #IICBus_Count
BNE %BT10
MOV a1, #InitIRQWs
LDRB a1, [a1, #KbdScanActive]
TEQ a1, #0
CallHAL HAL_KbdScanInterrupt,NE
Pull "lr"
MSR SPSR_cxsf, lr
Pull "a1-a4,sb,ip,pc",,^
Pull "a1-a4,v1-v2,sb,ip,pc",,^
END
......@@ -754,7 +754,7 @@ DefaultIRQ1Vcode_end
InitialiseIRQ1Vtable
Push "v1,sb,lr"
Push "v1-v3,sb,lr"
; copy IRQ handler: not done with rest of copying
; because soft break needs the info to free any claimed blocks.
......@@ -820,25 +820,29 @@ FillInDefaultIRQ1VDevices
]
; Now IIC - if any
MOV a1, #0
CallHAL HAL_IICType
LDR a2, =IICType
STR a1, [a2]
MOV v2, #IICBus_Base
MOV v3, #0
80
LDR a1, [v2, #IICBus_Type]
TST a1, #IICFlag_HighLevel
TSTNE a1, #IICFlag_Background
BEQ %FT90
SUB sp, sp, #12
MOV a1, sp
MOV a2, #0
MOV a2, v3
CallHAL HAL_IICDevice
; I think it's safe to call A SWI here...
LDMIA sp!, {r0, r3, r4}
LDR r1, =IICIRQ
MOV r2, sb
MOV r2, v3
SWI XOS_ClaimDeviceVector
90
ADD v2, v2, #IICBus_Size
ADD v3, v3, #1
CMP v3, #IICBus_Count
BNE %BT80
]
Pull "v1,sb,pc"
Pull "v1-v3,sb,pc"
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......
......@@ -560,10 +560,6 @@ Continue_after_HALInit
MSR CPSR_c, r0
]
; Ensure any CMOS operation aborted
BL IICAbort
BL IICInit
[ CacheCMOSRAM
......
......@@ -142,7 +142,8 @@ IIC_Op
; IIC_OpV - perform IIC operations based on a list of descriptors
;
; in: R0 -> array of transfer descriptors
; R1 = number of transfers
; R1 = bits 0-23: number of transfers
; bits 24-31: bus number
;
; out: transfer descriptors may be updated (beware)
;
......@@ -157,6 +158,7 @@ IIC_OpV ROUT
Push "r0-r3,r6-r12,lr"
MOV lr, #0
STR lr, [sp, #-8]!
MOV r3, r1, LSR #24
MRS r10, CPSR
BIC r7, r10, #I32_bit :OR: F32_bit
ORR r8, r7, #I32_bit
......@@ -182,10 +184,14 @@ IIC_OpV_PCReference
BGT %BT01
; IC code is already threaded
Push "r12" ; put original sp on stack for our exit routine
LDR r0, [r2, #4*4] ; retrieve interrupted iicsp
BIC r0, r0, #(1:SHL:IICStackAlignment)-1
LDR r1, [r0, #-8] ; old list tail
LDRB r11, [r1, #IICLink_Size+3] ; get bus number
CMP r11, r3
BNE %BT01 ; wrong bus, don't add ourselves to this list
Push "r12" ; put original sp on stack for our exit routine
STR r12, [r0, #-8] ; new list tail
STR r12, [r1, #IICLink_Next] ; point old link to new link
ADR r0, IIC_OpV_CommonExit
......@@ -261,25 +267,33 @@ IICLoop
; IICDoOp - main serial-execution entry point
;
; in: R0 -> array of transfer descriptors
; R1 = number of transfers
; R1 = bits 0-23: number of transfers
; bits 24-31: bus number
;
; out: if V set, r0 -> error block
; otherwise r0-r3,r12 may be corrupted
;
IICDoOp ROUT
MOV R1, R1, ROR #24 ; Move xfer count to low byte
MOV R2, #0
iicPush "R1,R2,iiclr" ; two words on stack are RepeatedStart flag and transfers remaining
; Get correct IICBus ptr in R2
AND R3, R1, #255
MOV iiclr, #IICBus_Size
MOV R2, #IICBus_Base
MLA R2, R3, iiclr, R2
MOV R3, R0
LDR iiclr, [R2, #IICType]
LDR iiclr, [R2, #IICBus_Type]
TST iiclr, #IICFlag_HighLevel
BNE IIC_OpV_HAL ; HAL can make use of a hardware IIC engine
05 LDR R0, [iicsp]
SUBS R0, R0, #1
BCC %FT90
SUBS R0, R0, #256
BLT %FT90
STR R0, [iicsp]
LDMIA R3!, {R0-R2}
......@@ -330,6 +344,7 @@ IICDoOp ROUT
MOVNES R0, R0, LSR #2 ; no, so definitely needs acknowledging (with 0 bit)
; now Z is set, and C set => just read last byte for this descriptor
LDRCS iiclr, [iicsp]
MOVCS iiclr, iiclr, LSR #8
TEQCS iiclr, #0 ; if we've finished this descriptor, check for another transfer descriptor
; Z clear => last byte, and there is another descriptor
LDRNE iiclr, [R3]
......@@ -349,6 +364,7 @@ IICDoOp ROUT
MOVNES R0, R0, LSR #2 ; no, so definitely needs acknowledging (with 0 bit)
; now Z is set, and C set => just read last byte for this descriptor
LDRCS iiclr, [iicsp]
MOVCS iiclr, iiclr, LSR #8
TEQCS iiclr, #0 ; if we've finished this descriptor, check for another transfer descriptor
; Z clear => last byte, and there is another descriptor
LDRNE iiclr, [R3]
......@@ -368,9 +384,13 @@ IIC_ExitOK
80
iicBL Stop
LDRB R0, [iicsp]
MOV R1, #IICBus_Size
MOV R2, #IICBus_Base
MLA R2, R0, R1, R2
IIC_ExitNoAck
MOV R0, #0
STR R0, [R0, #IICStatus]
STR R0, [R2, #IICBus_Status]
ADR R0, ErrorBlock_IIC_NoAcknowledge
IIC_ExitError
......@@ -406,7 +426,9 @@ SetC1C0 ROUT
[ HAL
MOV R2, R1
MOV R1, R0
MOV R0, #0
BIC r0, iicsp, #(1:SHL:IICStackAlignment)-1
LDR r0, [r0, #-4] ; list head
LDRB r0, [r0, #IICLink_Size+3] ; bus number
MSR CPSR_c, r8 ; IRQs off for use of ATPCS
Push "lr"
CallHAL HAL_IICSetLines
......@@ -449,6 +471,9 @@ SetC1C0 ROUT
ReadC1C0 ROUT
[ HAL
iicPush "r2,r3,iiclr"
BIC r0, iicsp, #(1:SHL:IICStackAlignment)-1
LDR r0, [r0, #-4] ; list head
LDRB r0, [r0, #IICLink_Size+3] ; bus number
MSR CPSR_c, r8 ; IRQs off for use of ATPCS
Push "lr"
CallHAL HAL_IICReadLines
......@@ -781,13 +806,14 @@ RXByte ROUT
; *****************************************************************************
IIC_OpV_HAL
; R2 = 0
; R2 = IICBus ptr
; R3 -> array of transfer descriptors
; [iicsp, #0] = number of transfers
; [iicsp, #0] = bits 0-7: bus number
; bits 8-31: number of transfers
; [iicsp, #4] unused on entry, used to hold number of retries remaining
; [iicsp, #8] = return address
LDR iiclr, [R2, #IICStatus]
LDR iiclr, [R2, #IICBus_Status]
TEQ iiclr, #0
BNE IIC_Busy
......@@ -799,30 +825,30 @@ IIC_OpV_HAL
IIC_OpV_HAL_Retry
MOV iiclr, #1
STR iiclr, [R2, #IICStatus]
STR iiclr, [R2, #IICBus_Status]
iicPush "R3"
MOV R0, #0
LDR R1, [iicsp, #4]
iicPush "R2,R3"
LDR R1, [iicsp, #8]
MOV R2, R3
AND R0, R1, #255
MOV R1, R1, LSR #8
MSR CPSR_c, R8 ; IRQs off for use of ATPCS
Push "lr"
CallHAL HAL_IICTransfer
Pull "lr"
MSR CPSR_c, R7 ; IRQs back on
iicPull "R3"
MOV R2, #0
iicPull "R2,R3"
20 TEQ R0, #2
BEQ IIC_NoAck
TEQ R0, #3
BEQ IIC_Busy
TEQ R0, #0
STREQ R0, [R2, #IICStatus] ; mark IIC system as free
STREQ R0, [R2, #IICBus_Status] ; mark IIC system as free
BEQ IIC_ExitOK
TEQ R0, #1
BNE IIC_Error
LDR R0, [R2, #IICStatus]
LDR R0, [R2, #IICBus_Status]
B %BT20
IIC_NoAck
......@@ -841,7 +867,7 @@ IICBusy_Error
IIC_Error
MOV R0, #0
STR R0, [R0, #IICStatus]
STR R0, [R2, #IICBus_Status]
ADR R0,IICError_Error
B IIC_ExitError
......@@ -852,26 +878,27 @@ interrupt_protected_end
IICIRQ
Push "R9,R14"
MOV R9, R12
MOV R0, #0
; R12 = bus number
Push "R8-R9,R14"
MOV R14,#0
AddressHAL R14
; Get IICBus ptr
MOV R0, #IICBus_Size
MOV R1, #IICBus_Base
MLA R8, R12, R0, R1
MOV R0, R12
CallHAL HAL_IICMonitorTransfer
MOV R12, #0
STR R0, [R12, #IICStatus]
; this is a bit ugly - we really need a way to pass the device number to IRQ handlers
SUB sp, sp, #12
MOV a1, sp
MOV a2, #0
CallHAL HAL_IICDevice
LDR a1, [sp]
STR R0, [R8, #IICBus_Status]
LDR R0, [R8, #IICBus_Device]
CallHAL HAL_IRQClear
ADD sp, sp, #12
Pull "R9,PC"
Pull "R8-R9,PC"
IICAbort
Push "R7,R8,R9,R11,R12"
Push "R0-R3,R7,R8,R9,R11,R12,R14"
MOV R11,R13
SUB R13,R13,#&80
SUB R13,R13,#(1:SHL:IICStackAlignment)+4
MRS R7,CPSR
ORR R8,R7,#I32_bit
[ HAL
......@@ -879,6 +906,22 @@ IICAbort
|
MOV R9,#IOC
]
CallHAL HAL_IICBuses
SUBS R0,R0,#1
BLT %FT20
MOV R1,#IICBus_Base
MOV R12,#IICBus_Size
MLA R1,R12,R0,R1
LDR R12,[R1,#IICBus_Type]
MOV R0,R0,LSL #24
05
TST R12,#IICFlag_HighLevel
BNE %FT10
; Set up a fake transfer list for Start/Stop/TXAck to read the bus number from
Push "R0,R1"
BIC R0, iicsp, #(1:SHL:IICStackAlignment)-1
STR R13,[R0,#-4]
[ {FALSE}
MOV R1,#16 ; Two bytes in case RTC transmitting
35
......@@ -892,27 +935,42 @@ IICAbort
iicBL TXAck
iicBL Stop
]
ADD R13,R13,#&80
Pull "R7,R8,R9,R11,R12"
MOV PC,R14
Pull "R0,R1"
10
SUBS R0,R0,#1<<24
SUB R1,R1,#IICBus_Size
BGE %BT05
20
ADD R13,R13,#(1:SHL:IICStackAlignment)+4
Pull "R0-R3,R7,R8,R9,R11,R12,PC"
IICInit
Push "R9,R14"
Push "R7-R9,R14"
AddressHAL
MOV a1, #0
MOV R7, #0
MOV R8, #IICBus_Base
10
CallHAL HAL_IICBuses
CMP R7, R0
Pull "R7-R9,R14",HS
BHS IICAbort ; Ensure any CMOS operation aborted
MOV a1, R7
CallHAL HAL_IICType
MOV a2, #0
STR a1, [a2, #IICType]
STR a1, [R8, #IICBus_Type]
TST a1, #IICFlag_Background
Pull "R9,PC",EQ
BEQ %FT20
SUB sp, sp, #12
MOV a1, sp
MOV a2, #0
MOV a2, R7
CallHAL HAL_IICDevice
LDR a1, [sp]
STR a1, [R8, #IICBus_Device]
CallHAL HAL_IRQEnable
ADD sp, sp, #12
Pull "R9,PC"
20
ADD R7, R7, #1
ADD R8, R8, #IICBus_Size
B %BT10
; We need to retain a version of DoMicroDelay with standard calling conventions, because
; it is called from elsewhere in the kernel. But it can't live inside the protected
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment