⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.asm

📁 <BIOS研发技术剖析>书的源代码,包括完整的BIOS汇编语言源程序.
💻 ASM
📖 第 1 页 / 共 2 页
字号:
        page    ,132
        title   CHIPSET INIT/MEMORY SIZING
;---------------------------------------------------------------;
; NOTE: Do not destroy EBP,FS,GS,SS,DS,ES unless otherwise specified.
;---------------------------------------------------------------;
;*****************************************************************;
;*****************************************************************;
;**                                                             **;
;**     (C)Copyright 1985-1996, American Megatrends Inc.        **;
;**                                                             **;
;**                     All Rights Reserved.                    **;
;**                                                             **;
;**             6145-F, Northbelt Parkway, Norcross,            **;
;**                                                             **;
;**             Georgia - 30071, USA. Phone-(770)-246-8600.     **;
;**                                                             **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------;
        include mbiosmac.mac
        include mbiosequ.equ
        include makeflag.equ
;---------------------------------------;
        extrn   u_sis5595_pci2isa_init_table:byte
        extrn   u_sis530_init_table:byte

        extrn   read_sio_byte_x:near
        extrn   read_pci_byte_x:near
        extrn   write_sio_byte_x:near
        extrn   write_pci_byte_x:near
        extrn   cmos_data_in:near
        extrn   cmos_data_out:near
;---------------------------------------;
cgroup  group   _text
_text   segment word    public  'CODE'
        assume  cs:cgroup
.586p
;---------------------------------------;
        public  _MEMORY_STARTS
_MEMORY_STARTS  label   byte            ; marks start of module
;-----------------------------------------------------------------------;
;                       U_POWER_ON_INIT                                 ;
;-----------------------------------------------------------------------;
;  this routine is invoked just after bios gets control at power-on.    ;
;  NOTHING IS DEFINED (except EDX) ON ENTRY TO THIS ROUTINE.            ;
;  input :                                                              ;
;       EDX     cpu id                                                  ;
;       SS = CS                                                         ;
;       stack   not available                                           ;
;  output:                                                              ;
;       none                                                            ;
;  register usage : can destroy any register except EDX,SS,FS,GS        ;
;  NOTE: 1. this routine can be used to enable RTC/KBC, etc. if KBC/RTC ;
;        is handled by the chipset.                                     ;
;        2. if KBC/RTC is handled by onboard I/O chipset, then selected ;
;        I/O chipset routines will handle KBC/RTC, this routine does not;
;        need to do anything.                                           ;
;-----------------------------------------------------------------------;
        public  u_power_on_init
        public  oem_u_power_on_init_end
        extrn   oem_u_power_on_init:near
        extrn   u_power_on_init_end:near
u_power_on_init:
        mov     ebp, edx                        ;Save CPUID in EBP

        mov     si,offset cgroup:u_sis5595_pci2isa_init_table
u_sio_init:
        mov     ah,cs:[si]
        or      ah,ah
        jz      u_sio_init_done

        jmp_di  read_sio_byte_x
        inc     si
        and     al,cs:[si]
        inc     si
        or      al,cs:[si]
        inc     si
        jmp_di  write_sio_byte_x
        jmp     short u_sio_init
u_sio_init_done:

        mov     ah,45h                          ; Open APC
        jmp_di  read_sio_byte_x         
        mov     bx,ax                           ; Save Reg.45h to BX
        or      al,02h                  
        jmp_di  write_sio_byte_x        

        mov     ax,8787h                        ; APC Register 07h  
        ret_sp  cmos_data_in
        and     al,0feh                         ; Clear KPR_LST  
        xchg    al,ah
        ret_sp  cmos_data_out

        mov     ax,8383h                        ; APC Register 03h 
        ret_sp  cmos_data_in
        or      al,040h                         ; Enable APC Function
        and     al,not 2ch                      ; Disable Ring/RTC/STREQ0
        xchg    al,ah                           ; 
        ret_sp  cmos_data_out
                                                
        mov     ax,bx                           ; Close APC       
        jmp_di  write_sio_byte_x                ; Restore Reg.45h 

        mov     si,offset cgroup:u_sis530_init_table
u_pci_init:
        mov     ah,cs:[si]
        or      ah,ah
        jz      u_pci_inti_done
        jmp_di  read_pci_byte_x
        inc     si
        and     al,cs:[si]
        inc     si
        or      al,cs:[si]
        inc     si
        jmp_di  write_pci_byte_x
        jmp     short u_pci_init
u_pci_inti_done:

; set all IRQs to edge trigger
        xor     ax, ax
        mov     dx, 04D0h
        out     dx, al
        jmp     short $+2
        inc     dx
        out     dx,al
        jmp     short $+2

;  Do OEM specific stuff
        jmp     oem_u_power_on_init     ; in OEMMEMRY.ASM
oem_u_power_on_init_end:

        mov     edx, ebp                        ;Restore CPUID

        jmp     u_power_on_init_end

;-----------------------------------------------------------------------;
;                               U_CP_INIT                               ;
;-----------------------------------------------------------------------;
; check_point           : D3                                            ;
; This routine is used to do chipset register initialisation and memory ;
; sizing.                                                               ;
; input :                                                               ;
;       refresh not started (start the refresh through timer if refresh ;
;                           is not controlled by chipset)               ;
;       SS      = CS                                                    ;
;       DS      0000H                                                   ;
;       ES      0000H                                                   ;
;       DS & ES set to 4GB limit                                        ;
;       stack   NOT available                                           ;
; register usage : can destroy any register except EBP,DS,ES,FS,GS      ;
; Note:                                                                 ;
; 1. Set BIOS size to 128K.                                             ;
; 2. Do memory sizing.                                                  ;
;-----------------------------------------------------------------------;
        public  u_cp_init
        public  oem_u_cp_init_end
        extrn   u_cp_init_end:near
        extrn   oem_u_cp_init:near
u_cp_init:
        jmp     oem_u_cp_init           ; in OEMMEMRY.ASM
oem_u_cp_init_end:

if (MKF_NCPU eq 2)
        jmp     u_init_local_apic
u_init_local_apic_end:
endif

        jmp     cas_latency_set
cas_latency_set_end:

        jmp     cp_init_x
cp_init_x_end:

        jmp     cache_test      ;return bl
cache_test_end:

%out === Memory refresh starts after memory sizing ===
;---------------------------------------;
;       START MEMORY REFRESH            ;
;---------------------------------------;
        extrn   refresh_low_value:byte
        mov     al,00h                  ; initialise DMA-PAGE reg.
        out     8fh,al                  ; (used in MEMORY REFRESH)
        mov     al,01010100b            ; start CH_1 (REFRESH)
        out     timer_control_port,al   ; one byte count used
        io_delay
        mov     al,cgroup:refresh_low_value; low byte count
        out     timer_1_port,al
        mov     cx,100h                 ; 400h..01/11/95
        xor     di,di
        mov     es,di                   ; ES = 0
wpulse1:
        stosb
        loop    wpulse1

        jmp     u_cp_init_end

;------------------------------------------------;
sdram                   = 1
;-----------------------------------------------;
DATA_PATTERN1           EQU     012345678H
DATA_PATTERN2           EQU     087654321H
DATA_PATTERN3           EQU     05a5a5a5aH
DATA_PATTERN4           EQU     0a5a5a5a5H
;-----------------------------------------------;
;***************************************************************************;
        PushNS          macro   Reg
                shl     Reg,16
        endm
;***************************************************************************;
        PopNS           macro   Reg
                shr     Reg,16
        endm
;***************************************************************************;
;---------------------------------------;
;       JMP_DI MACRO DEFINITION         ;
;---------------------------------------;
jmp_BX  macro   dummy                   ; goto routine & back (via DI)
        local   llll                    ; local label
        mov     BX,offset cgroup:llll   ; return address
        jmp     dummy
llll:
endm

;---------------------------------------;
;       AW_DELAY MACRO DEFINITION               ;
;---------------------------------------;
aw_delay macro

        out    0e0h,al
endm


init_dram label byte
         db     056h,002h

         db     063h,007h

         db     05ch,010h
         db     05ch,090h
         db     05ch,050h
         db     05ch,000h
         db     05ch,020h
         db     05ch,020h
         db     05ch,020h
         db     05ch,020h
         db     05ch,020h
         db     05ch,020h

         db     063h,004h

         db     0ffh

cp_init_x:
;;============>init the initiail reg value
       mov si,offset cgroup:init_dram  ;; init reg 60 - 6F for memory sizing
id_loop_1:
        mov ah,byte ptr cs:[si]
        cmp ah,0ffh
        jz  short id_loop_1_end
        mov al,byte ptr cs:[si+1]
        jmp_di write_pci_byte_x
        inc si
        inc si
        jmp short id_loop_1
id_loop_1_end:

;;=================================================================
;       EXTRN   csMem_MatrixJBX:near
;       EXTRN   csMem_MatrixsJBX:near
;       EXTRN   csPattern_TestJBX:near
;EDO_DRAM       =       1
;SDRAM          =       1

; assume bank 0,1,2 was set as FP,TYPE3,SINGLE SIDE,64bit
; assume ds,es:0~4G
STARTDRAMSIZE:
        MOV     AH,062H                         ; bank pointer
;---------------------------------------------------------------;
BANKSTART:
        mov     dx,ax
        pushns  edx                             ; save bank pointer

;---------------------------------------------------------------;
        jmp_di  read_pci_byte_x
        or      al,00bh                         ; low nibble already '3'
        jmp_di  write_pci_byte_x                ; Pre-set SDRAM present
;---------------------------------------------------------------;
ram_test_begin:
        mov     al,0                    ; pre-set dram ma_type as none
        jmp_bx  cspattern_testjbx       ; make sure dram present once more
        jnz     bankdone                ; and put data pattern into offset 0

        jmp_bx  csmem_matrixsjbx        ; output= al (actully ma_type+1)

BANKDONE:
;---------------------------------------------------------------;
        dec     al

        popns   edx                     ; save dram type
        mov     dl,al
        pushns  edx

        cmp     al,0ffh
        jz      no_dram

        mov     al,2bh
        jmp_di  write_pci_byte_x

normal_dram_dside_detect:
        xor     edi,edi                                         ; test the other side
        mov     dword ptr es:[edi+10000000h],Data_pattern1      ; write 256M+0
        mov     dword ptr es:[edi+10000008h],Data_pattern2      ; write 256M+8
        cmp     dword ptr es:[edi+10000000h],Data_pattern1
        jz      double_side_prsnt

clear_dside_dram:
        and     al, not 020h
        jmp_di  write_pci_byte_x

double_side_prsnt:
no_dram:
        popns   edx
        mov     ax,dx
        push    edx

        mov     bl,al
        jmp_di  read_pci_byte_x
        cmp     bl,0ffh
        jz      should_clear_cfg
        and     al,0f0h
        or      al,bl
        jmp     @f
should_clear_cfg:
        mov     cl,ah                   ; get correct bank enable bit
        and     cl,07h
        mov     bh,1
        shl     bh,cl
        mov     bl,ah

        mov     ah,63h
        jmp_di  read_pci_byte_x
        not     bh
        and     al,bh                   ; clear bank to be test
        jmp_di  write_pci_byte_x

        mov     ah,bl
        mov     al,0
@@:
        jmp_di  write_pci_byte_x

        dec     AH                      ;DECREASE BANK POINTER
        cmp     ah, 60h
        jb      sizing_done

        mov     dx,ax
        pushns  edx

        mov     cl,ah                   ; get correct bank enable bit
        and     cl,07h
        mov     bh,1
        shl     bh,cl

        mov     ah,63h
        jmp_di  read_pci_byte_x
        or      al,bh
        jmp_di  write_pci_byte_x

bank_finish:
        popns   edx
        mov     ax,dx

        jmp     bankstart

sizing_done:
        mov     ah, 063h
        jmp_di  read_pci_byte_x

        test    al,07h
        Jnz     DRAM_SIZING_DONE
        xor     ecx,ecx
@@:     in      al,80h                  ; NO DRAM COMES HERE
        inc     al
        out     80h,al
        db      67h
        loop    $
        jmp     @b
DRAM_SIZING_DONE:
;;=================================================
        jmp   cp_init_x_end                     ;end

;----------------------------------------------;
;----------------------------------------------;
set_ma_type     macro   x
                xor     al,al
                or      al,x
                endm
;----------------------------------------------;
;----------------------------------------------;
;output ZF=0 means no dram
;  for 64/32 mix system
;       CF=0 means 64, 1 means 32
;  for pure 64 system
;       CF=0 means memory test good, 1 means memory bad
csPattern_TestJBX       proc    near    public
        MOV     DWORD PTR ES:[00h], DATA_PATTERN1   ;WRITE MEMORY
        aw_delay
        jcxz    $+2
        MOV     DWORD PTR ES:[08h], DATA_PATTERN2   ;CLEAR BUS
        aw_delay
        jcxz    $+2
        CMP     DWORD PTR ES:[00h], DATA_PATTERN1   ;MEMORY EXIST?
        aw_delay
        jcxz    $+2
        jnz     @f

        MOV     DWORD PTR ES:[04h], DATA_PATTERN3   ;WRITE MEMORY
        aw_delay
        jcxz    $+2
        MOV     DWORD PTR ES:[0ch], DATA_PATTERN4   ;CLEAR BUS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -