📄 ns36x.asm
字号:
;**************************************************************************
;*
;* NS36X.ASM
;*
;* Copyright (c) 1999 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* LPC 36X family Super I/O configuration
;*
;* $Revision:: 2 $
;*
;**************************************************************************
.486P
INCLUDE DEF.INC
INCLUDE MACROS.INC
INCLUDE PORT80.INC
INCLUDE MPC.inc
INCLUDE NSSIO.inc
INCLUDE OPTIONS.inc
INCLUDE strings.inc
INCLUDE BDCFG.INC
INCLUDE NVRAMTOK.INC
INSTALL_NSSIO NS36X
NSSIO_INIT_S STRUCT 1
index db ? ; index
token dw ? ; token or 0
val db ? ; shift factor or value if token = 0
; this is number of bytes to shift
NSSIO_INIT_S ends
_TEXT SEGMENT PUBLIC use16 'CODE'
EXTERN GetTransNVRAM:NEAR
;************************************************************
; translate table for translating
; mvram entries into real working values
;************************************************************
LPCSIOTransTable LABEL NVRAMTransStruct
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_DIS,0h> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_378,01000378h> ; 378
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_278,01000278h> ; 278
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_3BC,010003BCh> ; 3BC
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_MODE,TVALUE_LPT_MODE_SPP, 00000002h> ; SPP
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_MODE,TVALUE_LPT_MODE_PS2, 00000022h> ; PS/2 BI-DIR
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_MODE,TVALUE_LPT_MODE_EPP17,00000042h> ; EPP 1.7
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_MODE,TVALUE_LPT_MODE_EPP19,00000062h> ; EPP 1.9
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_MODE,TVALUE_LPT_MODE_ECP, 000000F2h> ; ECP
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_DIS,0> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_3F8,010403f8h> ; 3f8,4
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_2F8,010302f8h> ; 2f8,3
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_3E8,010703e8h> ; 3e8,4
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_2E8,010a02e8h> ; 2e8,3
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_DIS,0> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_3F8,010403f8h> ; 3f8,4
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_2F8,010302f8h> ; 2f8,3
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_3E8,010703e8h> ; 3e8,4
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_2E8,010a02e8h> ; 2e8,3
NVRAMTransStruct <0,0,0,0> ; end of table
LPCBAR1TransTable LABEL NVRAMTransStruct
; mask is reg 1 0 10 14 values
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_DIS,0> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_3F8,00100200h> ; irq 4,serial 0,3f8
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_2F8,00080204h> ; 2f8,3
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_3E8,0080021Ch> ; 3e8,7
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART1,TVALUE_UART_CONFIG_2E8,04000214h> ; 2e8,10
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_DIS,0> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_3F8,00100400h> ; 3f8,4
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_2F8,00080420h> ; 2f8,3
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_3E8,008004e0h> ; 3e8,7
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_UART2,TVALUE_UART_CONFIG_2E8,040004a0h> ; 2e8,10
; mask is reg 10 14 values
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_DIS,0h> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_378,00000100h> ; 378
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_278,00000101h> ; 278
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_PORT,TVALUE_LPT_PORT_3BC,00000102h> ; 3BC
; lpt irq mask reg is reg 1/0 bits
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,0,00000000h> ; disabled
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,5,00000020h> ; 5
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,7,00000080h> ; 7
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,9,00000200h> ; 9
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,10,00000400h> ; 10
NVRAMTransStruct <MEDIA_ANY,TOKEN_LPC_LPT_IRQ,11,00000800h> ; 11
NVRAMTransStruct <0,0,0,0> ; end of table
NSLPCSIO_INIT_TABLE:
NSSIO_INIT_S <NSSIO_CFG3,0, 03h> ; Enable SCL/SDA, GA20, KBRST pins
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_FDD_DEVICE> ; Select the FDC device
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_OPTION_REG0,0, 24h> ; Set DENSEL & PC-AT mode
NSSIO_INIT_S <NSSIO_INTERRUPT_MODE,0, 6> ; Set the interrupt mode
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 1> ; Enable it
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_KEYBOARD_DEVICE> ; Select the KBC device
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_PRIMARY_INTERRUPT_SELECT,0, 1> ; Set the keyboard interrupt
NSSIO_INIT_S <NSSIO_INTERRUPT_MODE,0, 3> ; Set the interrupt mode
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 1> ; Enable it
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_AUX_IO_DEVICE> ; Select the mouse device
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_PRIMARY_INTERRUPT_SELECT,0, 0Ch> ; Set the mouse interrupt
NSSIO_INIT_S <NSSIO_INTERRUPT_MODE,0, 2> ; Set the interrupt mode
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 1> ; Enable it
; LPT port on LPC
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_LPT_DEVICE> ; parallel port
NSSIO_INIT_S <NSSIO_ACTIVATE, 0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_HI,TOKEN_LPC_LPT_PORT,1> ; base address high
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_LOW,TOKEN_LPC_LPT_PORT,0> ; base address low
NSSIO_INIT_S <NSSIO_PRIMARY_INTERRUPT_SELECT,TOKEN_LPC_LPT_IRQ,0> ; irq
NSSIO_INIT_S <NSSIO_DMA_CHANNEL_SELECT,TOKEN_LPC_LPT_DMA,0> ; dma port
NSSIO_INIT_S <NSSIO_OPTION_REG0,TOKEN_LPC_LPT_MODE,0> ; mode
; if dowser force lpt to output only regardless of what CMOS contains
IF DOWSER_ON
; code to set to output only for dowser
NSSIO_INIT_S <NSSIO_OPTION_REG0,0,02h> ; output only
ENDIF
NSSIO_INIT_S <NSSIO_ACTIVATE,TOKEN_LPC_LPT_PORT, 3> ; Enable it
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_UART1_DEVICE> ; Select the UART 1 device
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_HI,TOKEN_LPC_UART1,1>
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_LOW,TOKEN_LPC_UART1,0>
NSSIO_INIT_S <NSSIO_PRIMARY_INTERRUPT_SELECT,TOKEN_LPC_UART1,2>
NSSIO_INIT_S <NSSIO_OPTION_REG0,0, 82h> ; Enable bank switching and normal power mode
NSSIO_INIT_S <NSSIO_ACTIVATE,TOKEN_LPC_UART1, 3> ; Enable it
NSSIO_INIT_S <NSSIO_LOGICAL_DEVICE_NUMBER,0, NSSIO_UART2_DEVICE> ; Select the UART 2 device
NSSIO_INIT_S <NSSIO_ACTIVATE,0, 0> ; Disable it
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_HI,TOKEN_LPC_UART2,1>
NSSIO_INIT_S <NSSIO_PRIMARY_BASE_IO_ADDR_LOW,TOKEN_LPC_UART2,0>
NSSIO_INIT_S <NSSIO_PRIMARY_INTERRUPT_SELECT,TOKEN_LPC_UART2,2>
NSSIO_INIT_S <NSSIO_OPTION_REG0,0, 82h> ; Enable bank switching and normal power mode
NSSIO_INIT_S <NSSIO_ACTIVATE,TOKEN_LPC_UART2, 3> ; Enable it
NSLPCSIO_INIT_COUNT EQU ($ - NSLPCSIO_INIT_TABLE)
NSLPCBAR1_INIT_TABLE:
NSSIO_INIT_S <GEODE_REG14,TOKEN_LPC_UART1,0> ; reg 14 - addressing
NSSIO_INIT_S <GEODE_REG10,TOKEN_LPC_UART1,1> ; reg 10 - addr enable
NSSIO_INIT_S <GEODE_REG00,TOKEN_LPC_UART1,2> ; reg 0 - irq 0-7
NSSIO_INIT_S <GEODE_REG01,TOKEN_LPC_UART1,3> ; reg 1 - irq 8-15
NSSIO_INIT_S <GEODE_REG14,TOKEN_LPC_UART2,0> ; reg 14 - addressing
NSSIO_INIT_S <GEODE_REG10,TOKEN_LPC_UART2,1> ; reg 10 - addr enable
NSSIO_INIT_S <GEODE_REG00,TOKEN_LPC_UART2,2> ; reg 0 - irq 0-7
NSSIO_INIT_S <GEODE_REG01,TOKEN_LPC_UART2,3> ; reg 1 - irq 8-15
NSSIO_INIT_S <GEODE_REG14,TOKEN_LPC_LPT_PORT,0> ; reg 14 - addressing
NSSIO_INIT_S <GEODE_REG10,TOKEN_LPC_LPT_PORT,1> ; reg 10 - addr enable
NSSIO_INIT_S <GEODE_REG00,TOKEN_LPC_LPT_IRQ,0> ; reg 0 - irq 0-7
NSSIO_INIT_S <GEODE_REG01,TOKEN_LPC_LPT_IRQ,1> ; reg 1 - irq 8-15
NSLPCBAR1_INIT_COUNT EQU ($ - NSLPCBAR1_INIT_TABLE)
;**************************************************************
; killLPC
;
; code to disable the lpc if an lpc sio is not
; detected
;
; we do this so things that LPC interferes with
; (such as legacy USB and fasta20) will work
;
;**************************************************************
KillLPC PROC NEAR PUBLIC
; 1st clear all the LPC registers in f0bar1
mov cx, 23h ; number of registers
mov dx, GEODE_LPC_BASE ; base of f0bar1
LPCbusloop:
mov al, 0 ; Get value
out dx, al ; Write the value to register
inc dl ; next one
loop LPCbusloop
; now clear lpc enable in pmr
mov dx, GEODE_CONFIG_BASE ; config registers
add dx, GEODE_PMR ; pint to pmr
IF (SCx1xx_PROCESSOR NE 1)
mov ebx,NOT ((1 shl 14) or (1 shl 22)) ; mask off 14 & 22
ELSE
mov ebx,NOT (1 shl 14) ; mask off 14 & 22
ENDIF
in eax,dx ; get pmr
and eax,ebx ; mask off lpc
out dx,eax
ret
KillLPC ENDP
;**************************************************************************
;*
;* LPCsioTest
;*
;* LPC 36x SuperI/O test and configuration
;*
;* Entry:
;* BX - return address
;*
;* Exit:
;* None
;*
;* Destroys:
;* AX, DX, SI, CX
;*
;**************************************************************************
LPCsioTest PROC NEAR PUBLIC
push ebx ; save return address
mov ax, LPC
cmp ax, 0
je noLPCBus ; neither installed, get out.
mov cx,3 ; try 3 times
tryagain:
; Attempt to id the SIO and if not identified then put out post code and stop
mov dx, NSLPC_SIO_BASE
mov al, NSSIO_DEVICE_ID_REG
out dx, al
xor dx, 1
in al, dx
and al, 0F0h
cmp al, NSSIO_36X_ID
je lpcsioPresent
PORT80 P80_SIO+0Dh ; Indicate invalid SIO response
loop tryagain ; trysome more incase it was a fluke
IFDEF LPC_ROM
; LPC_ROM should be defined in BDCFG.INC if required.
; See \XPRESS\CPU\SCx2xx\include\BDCFG.INC for an example of how to define
; LPC_ROM and its associated EQUs. This is setup this way so that this
; code isn't compiled in if the EQU isn't in the system. It also allows
; the EQU to only be defined in the systems that actually need it.
IF LPC_ROM
; If we have an LPC ROM/DOC in the system we need to leave LPC alive even
; if we don't find an SIO. Since we didn't find and SIO we don't need to
; try and configure it.
jmp noLPCBus ; Skip the "kill" no matter what
ENDIF
ENDIF
call KillLPC ; disable LPC interface
jmp noLPCBus ; done
lpcsioPresent:
mov cx, NSLPCSIO_INIT_COUNT
lea si, NSLPCSIO_INIT_TABLE
nsloop:
push cx ; save count
mov cx,cs:[si].NSSIO_INIT_S.token ; get token
or cx,cx ; see if have token
jz litvalue ; no - have literal value
; go get the value for the token
push si ; save pointer
lea si,LPCSIOTransTable
call GetTransNVRAM ; get translated NVRAM value
pop si ; restore pointer
jc point_next ; error *****************
ok:
mov cl,cs:[si].NSSIO_INIT_S.val ; get shift factor
shl cl,3 ; *8
jz writevalue ; don't need shift
shr eax,cl ; shift down
jmp short writevalue
litvalue:
mov al,cs:[si].NSSIO_INIT_S.val ; get literal value
writevalue:
mov dx, NSLPC_SIO_BASE ; point to base IO address
mov ah,cs:[si].NSSIO_INIT_S.index ; get index
xchg al,ah ; save value in ah index to al
out dx,al ; write index
xchg al,ah ; get value back
inc dx ; point to data reg
out dx,al ; write data value
point_next:
add si,size NSSIO_INIT_S ; point to next table entry
pop cx ; restore count
loop nsloop ; go do another if we have one
;********************************************************************
; now we have to setup the registers pointer to by f0bar1
; for the lpc this includes irq & address decoding
;********************************************************************
mov cx, NSLPCBAR1_INIT_COUNT
lea si, NSLPCBAR1_INIT_TABLE
barloop:
push cx ; save count
mov cx,cs:[si].NSSIO_INIT_S.token ; get token
or cx,cx ; see if have token
jz litvalue_bar ; no - have literal value
; go get the value for the token
push si ; save pointer
lea si,LPCBAR1TransTable
call GetTransNVRAM ; get translated NVRAM value
pop si ; restore pointer
jc point_next_bar ; error *****************
ok_bar:
mov cl,cs:[si].NSSIO_INIT_S.val ; get shift factor
shl cl,3 ; *8
jz writevalue_bar ; don't need shift
shr eax,cl ; shift down
jmp short writevalue_bar
litvalue_bar:
mov al,cs:[si].NSSIO_INIT_S.val ; get literal value
writevalue_bar:
mov bl,al ; move value to bl
mov dx, GEODE_LPC_BASE ; base port
add dl,cs:[si].NSSIO_INIT_S.index ; get index
in al,dx ; read old value
or al,bl ; or in new value
out dx,al ; write data value
point_next_bar:
add si,size NSSIO_INIT_S ; point to next table entry
pop cx ; restore count
loop barloop ; go do another if we have one
noLPCBus:
pop ebx ; restore return address
jmp bx
LPCsioTest ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -