📄 head.s
字号:
/* head.S: kernel entry point for FR-V kernel * * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */#include <linux/config.h>#include <linux/threads.h>#include <linux/linkage.h>#include <asm/ptrace.h>#include <asm/page.h>#include <asm/spr-regs.h>#include <asm/mb86943a.h>#include <asm/cache.h>#include "head.inc"################################################################################# void _boot(unsigned long magic, char *command_line) __attribute__((noreturn))## - if magic is 0xdead1eaf, then command_line is assumed to point to the kernel# command line string################################################################################ .section .text.head,"ax" .balign 4 .globl _boot, __head_reference .type _boot,@function_boot:__head_reference: sethi.p %hi(LED_ADDR),gr30 setlo %lo(LED_ADDR),gr30 LEDS 0x0000 # calculate reference address for PC-relative stuff call 0f0: movsg lr,gr26 addi gr26,#__head_reference-0b,gr26 # invalidate and disable both of the caches and turn off the memory access checking dcef @(gr0,gr0),1 bar sethi.p %hi(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4 setlo %lo(~(HSR0_ICE|HSR0_DCE|HSR0_CBM|HSR0_EIMMU|HSR0_EDMMU)),gr4 movsg hsr0,gr5 and gr4,gr5,gr5 movgs gr5,hsr0 movsg hsr0,gr5 LEDS 0x0001 icei @(gr0,gr0),1 dcei @(gr0,gr0),1 bar # turn the instruction cache back on sethi.p %hi(HSR0_ICE),gr4 setlo %lo(HSR0_ICE),gr4 movsg hsr0,gr5 or gr4,gr5,gr5 movgs gr5,hsr0 movsg hsr0,gr5 bar LEDS 0x0002 # retrieve the parameters (including command line) before we overwrite them sethi.p %hi(0xdead1eaf),gr7 setlo %lo(0xdead1eaf),gr7 subcc gr7,gr8,gr0,icc0 bne icc0,#0,__head_no_parameters sethi.p %hi(redboot_command_line-1),gr6 setlo %lo(redboot_command_line-1),gr6 sethi.p %hi(__head_reference),gr4 setlo %lo(__head_reference),gr4 sub gr6,gr4,gr6 add.p gr6,gr26,gr6 subi gr9,#1,gr9 setlos.p #511,gr4 setlos #1,gr5__head_copy_cmdline: ldubu.p @(gr9,gr5),gr16 subicc gr4,#1,gr4,icc0 stbu.p gr16,@(gr6,gr5) subicc gr16,#0,gr0,icc1 bls icc0,#0,__head_end_cmdline bne icc1,#1,__head_copy_cmdline__head_end_cmdline: stbu gr0,@(gr6,gr5)__head_no_parameters:################################################################################# we need to relocate the SDRAM to 0x00000000 (linux) or 0xC0000000 (uClinux)# - note that we're going to have to run entirely out of the icache whilst# fiddling with the SDRAM controller registers#################################################################################ifdef CONFIG_MMU call __head_fr451_describe_sdram#else movsg psr,gr5 srli gr5,#28,gr5 subicc gr5,#3,gr0,icc0 beq icc0,#0,__head_fr551_sdram call __head_fr401_describe_sdram bra __head_do_sdram__head_fr551_sdram: call __head_fr555_describe_sdram LEDS 0x000d__head_do_sdram:#endif # preload the registers with invalid values in case any DBR/DARS are marked not present sethi.p %hi(0xfe000000),gr17 ; unused SDRAM DBR value setlo %lo(0xfe000000),gr17 or.p gr17,gr0,gr20 or gr17,gr0,gr21 or.p gr17,gr0,gr22 or gr17,gr0,gr23 # consult the SDRAM controller CS address registers cld @(gr14,gr0 ),gr20, cc0,#1 ; DBR0 / DARS0 cld @(gr14,gr11),gr21, cc1,#1 ; DBR1 / DARS1 cld @(gr14,gr12),gr22, cc2,#1 ; DBR2 / DARS2 cld.p @(gr14,gr13),gr23, cc3,#1 ; DBR3 / DARS3 sll gr20,gr15,gr20 ; shift values up for FR551 sll gr21,gr15,gr21 sll gr22,gr15,gr22 sll gr23,gr15,gr23 LEDS 0x0003 # assume the lowest valid CS line to be the SDRAM base and get its address subcc gr20,gr17,gr0,icc0 subcc.p gr21,gr17,gr0,icc1 subcc gr22,gr17,gr0,icc2 subcc.p gr23,gr17,gr0,icc3 ckne icc0,cc4 ; T if DBR0 != 0xfe000000 ckne icc1,cc5 ckne icc2,cc6 ckne icc3,cc7 cor gr23,gr0,gr24, cc7,#1 ; GR24 = SDRAM base cor gr22,gr0,gr24, cc6,#1 cor gr21,gr0,gr24, cc5,#1 cor gr20,gr0,gr24, cc4,#1 # calculate the displacement required to get the SDRAM into the right place in memory sethi.p %hi(__sdram_base),gr16 setlo %lo(__sdram_base),gr16 sub gr16,gr24,gr16 ; delta = __sdram_base - DBRx # calculate the new values to go in the controller regs cadd.p gr20,gr16,gr20, cc4,#1 ; DCS#0 (new) = DCS#0 (old) + delta cadd gr21,gr16,gr21, cc5,#1 cadd.p gr22,gr16,gr22, cc6,#1 cadd gr23,gr16,gr23, cc7,#1 srl gr20,gr15,gr20 ; shift values down for FR551 srl gr21,gr15,gr21 srl gr22,gr15,gr22 srl gr23,gr15,gr23 # work out the address at which the reg updater resides and lock it into icache # also work out the address the updater will jump to when finished sethi.p %hi(__head_move_sdram-__head_reference),gr18 setlo %lo(__head_move_sdram-__head_reference),gr18 sethi.p %hi(__head_sdram_moved-__head_reference),gr19 setlo %lo(__head_sdram_moved-__head_reference),gr19 add.p gr18,gr26,gr18 add gr19,gr26,gr19 add.p gr19,gr16,gr19 ; moved = addr + (__sdram_base - DBRx) add gr18,gr5,gr4 ; two cachelines probably required icpl gr18,gr0,#1 ; load and lock the cachelines icpl gr4,gr0,#1 LEDS 0x0004 membar bar jmpl @(gr18,gr0) .balign L1_CACHE_BYTES__head_move_sdram: cst gr20,@(gr14,gr0 ), cc4,#1 cst gr21,@(gr14,gr11), cc5,#1 cst gr22,@(gr14,gr12), cc6,#1 cst gr23,@(gr14,gr13), cc7,#1 cld @(gr14,gr0 ),gr20, cc4,#1 cld @(gr14,gr11),gr21, cc5,#1 cld @(gr14,gr12),gr22, cc4,#1 cld @(gr14,gr13),gr23, cc7,#1 bar membar jmpl @(gr19,gr0) .balign L1_CACHE_BYTES__head_sdram_moved: icul gr18 add gr18,gr5,gr4 icul gr4 icei @(gr0,gr0),1 dcei @(gr0,gr0),1 LEDS 0x0005 # recalculate reference address call 0f0: movsg lr,gr26 addi gr26,#__head_reference-0b,gr26################################################################################# move the kernel image down to the bottom of the SDRAM################################################################################ sethi.p %hi(__kernel_image_size_no_bss+15),gr4 setlo %lo(__kernel_image_size_no_bss+15),gr4 srli.p gr4,#4,gr4 ; count or gr26,gr26,gr16 ; source sethi.p %hi(__sdram_base),gr17 ; destination setlo %lo(__sdram_base),gr17 setlos #8,gr5 sub.p gr16,gr5,gr16 ; adjust src for LDDU sub gr17,gr5,gr17 ; adjust dst for LDDU sethi.p %hi(__head_move_kernel-__head_reference),gr18 setlo %lo(__head_move_kernel-__head_reference),gr18 sethi.p %hi(__head_kernel_moved-__head_reference+__sdram_base),gr19 setlo %lo(__head_kernel_moved-__head_reference+__sdram_base),gr19 add gr18,gr26,gr18 icpl gr18,gr0,#1 jmpl @(gr18,gr0) .balign 32__head_move_kernel: lddu @(gr16,gr5),gr10 lddu @(gr16,gr5),gr12 stdu.p gr10,@(gr17,gr5) subicc gr4,#1,gr4,icc0 stdu.p gr12,@(gr17,gr5) bhi icc0,#0,__head_move_kernel jmpl @(gr19,gr0) .balign 32__head_kernel_moved: icul gr18 icei @(gr0,gr0),1 dcei @(gr0,gr0),1 LEDS 0x0006 # recalculate reference address call 0f0: movsg lr,gr26 addi gr26,#__head_reference-0b,gr26################################################################################# rearrange the iomem map and set the protection registers#################################################################################ifdef CONFIG_MMU LEDS 0x3301 call __head_fr451_set_busctl LEDS 0x3303 call __head_fr451_survey_sdram LEDS 0x3305 call __head_fr451_set_protection#else movsg psr,gr5 srli gr5,#PSR_IMPLE_SHIFT,gr5 subicc gr5,#PSR_IMPLE_FR551,gr0,icc0 beq icc0,#0,__head_fr555_memmap subicc gr5,#PSR_IMPLE_FR451,gr0,icc0 beq icc0,#0,__head_fr451_memmap LEDS 0x3101 call __head_fr401_set_busctl LEDS 0x3103 call __head_fr401_survey_sdram LEDS 0x3105 call __head_fr401_set_protection bra __head_done_memmap__head_fr451_memmap: LEDS 0x3301 call __head_fr401_set_busctl LEDS 0x3303 call __head_fr401_survey_sdram LEDS 0x3305 call __head_fr451_set_protection bra __head_done_memmap__head_fr555_memmap: LEDS 0x3501 call __head_fr555_set_busctl LEDS 0x3503 call __head_fr555_survey_sdram
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -