Author: uwe Date: 2007-05-19 23:31:23 +0200 (Sat, 19 May 2007) New Revision: 326
Modified: LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S Log: Lots of cosmetic and coding style fixes (trivial).
Signed-off-by: Uwe Hermann uwe@hermann-uwe.de Acked-by: Uwe Hermann uwe@hermann-uwe.de
Modified: LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S =================================================================== --- LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S 2007-05-19 08:57:59 UTC (rev 325) +++ LinuxBIOSv3/arch/x86/stage0_amd_geodelx.S 2007-05-19 21:31:23 UTC (rev 326) @@ -1,91 +1,93 @@ -## +## ## This file is part of the LinuxBIOS project. -## +## ## Copyright (C) 2000,2007 Ronald G. Minnich rminnich@gmail.com -## ## Copyright (C) 2005 Eswar Nallusamy, LANL -## ## Copyright (C) 2005 Tyan -## Written by Yinghai Lu yhlu@tyan.com for Tyan. -## +## (Written by Yinghai Lu yhlu@tyan.com for Tyan) ## Copyright (C) 2007 coresystems GmbH -## Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH. +## (Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) +## Copyright (C) 2007 Advanced Micro Devices, Inc. ## -## Copyright (C) 2007 Advanced Micro Devices -## ## 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; version 2 of the License. -## +## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -## +## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -## +##
-# init code - switch cpu to pmode and enable cache as ram. +/* Init code - Switch CPU to protected mode and enable Cache-as-Ram. */
#include "macros.h" #include <amd_geodelx.h>
-#define LX_STACK_BASE DCACHE_RAM_BASE /* this is where the DCache will be mapped and be used as stack, It would be cool if it was the same base as LinuxBIOS normal stack */ +/* This is where the DCache will be mapped and be used as stack. It would be + * cool if it was the same base as LinuxBIOS normal stack. + */ +#define LX_STACK_BASE DCACHE_RAM_BASE #define LX_STACK_END LX_STACK_BASE+(DCACHE_RAM_SIZE-4)
-#define LX_NUM_CACHELINES 0x080 /* there are 128lines per way */ -#define LX_CACHELINE_SIZE 0x020 /* there are 32bytes per line */ +#define LX_NUM_CACHELINES 0x080 /* There are 128 lines per way. */ +#define LX_CACHELINE_SIZE 0x020 /* There are 32 bytes per line. */ #define LX_CACHEWAY_SIZE (LX_NUM_CACHELINES * LX_CACHELINE_SIZE) -#define CR0_CD 0x40000000 /* bit 30 = Cache Disable */ -#define CR0_NW 0x20000000 /* bit 29 = Not Write Through */ +#define CR0_CD 0x40000000 /* Bit 30 = Cache Disable */ +#define CR0_NW 0x20000000 /* Bit 29 = Not Write Through */
#define ROM_CODE_SEG 0x08 #define ROM_DATA_SEG 0x10
#define CACHE_RAM_CODE_SEG 0x18 #define CACHE_RAM_DATA_SEG 0x20 + .code16 .globl _stage0 _stage0: cli
- /* save the BIST result */ + /* Save the BIST result. */ movl %eax, %ebp;
- /* thanks to kmliu@sis.com.tw for this TLB fix */ + /* Thanks to kmliu@sis.com.tw for this TLB fix. */ /* IMMEDIATELY invalidate the translation lookaside buffer before - * executing any further code. Even though paging is disabled we - * could still get false address translations due to the TLB if we + * executing any further code. Even though paging is disabled we + * could still get false address translations due to the TLB if we * didn't invalidate it. */
xorl %eax, %eax movl %eax, %cr3 /* Invalidate TLB */
- /* switch to protected mode */ + /* Switch to protected mode. */
/* NOTE: With GNU assembler version 2.15.94.0.2.2 (i386-redhat-linux) - * using BFD version 2.15.94.0.2.2 20041220 this works fine without all - * the ld hackery and other things. So leave it as is with this comment. + * using BFD version 2.15.94.0.2.2 20041220 this works fine without + * all the ld hackery and so on. So leave it as is with this comment. */
data32 lgdt %cs:gdtptr
movl %cr0, %eax - andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */ + andl $0x7FFAFFD1, %eax /* PG, AM, WP, NE, TS, EM, MP = 0 */ orl $0x60000001, %eax /* CD, NW, PE = 1 */ movl %eax, %cr0
- /* Restore BIST result */ + /* Restore BIST result. */ movl %ebp, %eax
+ // port80_post(0x23)
- // port80_post (0x23) /* post 0x01 */ /* Now we are in protected mode. Jump to a 32 bit code segment. */ data32 ljmp $ROM_CODE_SEG, $protected_stage0 - /* I am leaving this weird jump in here in the event that future gas bugs force it to be used. */ + /* I am leaving this weird jump in here in the event that future gas + * bugs force it to be used. + */ #.byte 0x66 .code32 #ljmp $ROM_CODE_SEG, $protected_stage0 @@ -95,126 +97,125 @@ .globl gdt16 gdt16 = . - _stage0 gdt16x: - .word gdt16xend - gdt16x -1 /* compute the table limit */ + .word gdt16xend - gdt16x -1 /* Compute the table limit. */ .long gdt16x - .word 0 + .word 0
/* selgdt 0x08, flat code segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xcf, 0x00 + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00
- /* selgdt 0x10,flat data segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x93, 0xcf, 0x00 + /* selgdt 0x10, flat data segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00 gdt16xend:
- /* From now on we are 32bit */ - + /* From now on we are 32bit. */ .code32
-/* We have two gdts where we could have one. That is ok. - * - * Let's not worry about this -- optimizing gdt is pointless since we're - * only in it for a little bit. - * - * BTW note the trick below: The GDT points to ITSELF, and the first good - * descriptor is at offset 8. So you word-align the table, and then because - * you chose 8, you get a nice 64-bit aligned GDT entry, which is good as - * this is the size of the entry. - * Just in case you ever wonder why people do this. - */ + /* We have two gdts where we could have one. That is ok. + * + * Let's not worry about this -- optimizing gdt is pointless since + * we're only in it for a little bit. + * + * BTW note the trick below: The GDT points to ITSELF, and the first + * good descriptor is at offset 8. So you word-align the table, and + * then because you chose 8, you get a nice 64-bit aligned GDT entry, + * which is good as this is the size of the entry. + * + * Just in case you ever wonder why people do this. + */ .align 4 .globl gdtptr .globl gdt_limit -gdt_limit = gdt_end - gdt - 1 /* compute the table limit */ +gdt_limit = gdt_end - gdt - 1 /* Compute the table limit. */
gdt: gdtptr: - .word gdt_end - gdt -1 /* compute the table limit */ - .long gdt /* we know the offset */ - .word 0 + .word gdt_end - gdt -1 /* Compute the table limit. */ + .long gdt /* We know the offset. */ + .word 0
/* selgdt 0x08, flat code segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xcf, 0x00 + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00
- /* selgdt 0x10,flat data segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x93, 0xcf, 0x00 + /* selgdt 0x10, flat data segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00
/* selgdt 0x18, flat code segment for CAR */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xcf, 0x00 + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00
- /* selgdt 0x20,flat data segment for CAR */ - .word 0xffff, 0x0000 - .byte 0x00, 0x93, 0xcf, 0x00 + /* selgdt 0x20, flat data segment for CAR */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00 gdt_end:
-/* - * When we come here we are in protected mode. We expand - * the stack and copies the data segment from ROM to the - * memory. - * - * After that, we call the chipset bootstrap routine that - * does what is left of the chipset initialization. - * - * NOTE: Aligned to 4 so that we are sure that the prefetch - * cache will be reloaded. - */ + /* + * When we come here we are in protected mode. We expand the stack + * and copy the data segment from ROM to the memory. + * + * After that, we call the chipset bootstrap routine that + * does what is left of the chipset initialization. + * + * NOTE: Aligned to 4 so that we are sure that the prefetch + * cache will be reloaded. + */
.align 4 .globl protected_stage0 protected_stage0: - //This code was used by v2. TODO - lgdt %cs:gdtptr - ljmp $ROM_CODE_SEG, $__protected_stage0 + // This code was used by v2. TODO + lgdt %cs:gdtptr + ljmp $ROM_CODE_SEG, $__protected_stage0
.globl __protected_stage0 __protected_stage0: - /* Save the BIST value */ - movl %eax, %ebp + /* Save the BIST value. */ + movl %eax, %ebp
- port80_post (0x01) /* post 0x01 */ + port80_post(0x01)
- movw $ROM_DATA_SEG, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss - movw %ax, %fs - movw %ax, %gs + movw $ROM_DATA_SEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs
- /* Restore the BIST value to %eax */ - movl %ebp, %eax + /* Restore the BIST value to %eax. */ + movl %ebp, %eax
.align 4 - /* here begins CAR support */ - /* this particular code is straight from LinuxBIOS V2 */ -/*************************************************************************** -/** -/** DCacheSetup -/** -/** Setup data cache for use as RAM for a stack. -/** -/***************************************************************************/ + /* Here begins CAR support. */ + /* This particular code is straight from LinuxBIOS V2. */ + + /* DCacheSetup: Setup data cache for use as RAM for a stack. */ DCacheSetup:
invd - /* set cache properties */ + /* Set cache properties. */ movl $CPU_RCONF_DEFAULT, %ecx rdmsr - movl $0x010010000, %eax /*1MB system memory in write back 1|00100|00 */ + /* 1MB system memory in write back 1|00100|00. */ + movl $0x010010000, %eax wrmsr
- /* in LX DCDIS is set after POR which disables the cache..., clear this bit */ + /* In LX DCDIS is set after POR which disables the cache..., clear + * this bit. + */ movl CPU_DM_CONFIG0,%ecx rdmsr - andl $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax /* TODO: make consistent with i$ init, either whole reg = 0, or just this bit... */ + /* TODO: Make consistent with i$ init, either whole reg = 0, or just + * this bit... + */ + andl $(~(DM_CONFIG0_LOWER_DCDIS_SET)), %eax wrmsr
- /* get cache timing params from BIOS config data locations and apply */ - /* fix delay controls for DM and IM arrays */ - /* fix delay controls for DM and IM arrays */ + /* Get cache timing params from BIOS config data locations and apply. */ + /* Fix delay controls for DM and IM arrays. */ movl $CPU_BC_MSS_ARRAY_CTL0, %ecx xorl %edx, %edx movl $0x2814D352, %eax @@ -235,7 +236,7 @@ movl $0x00000005, %edx wrmsr
- /* Enable setting */ + /* Enable setting. */ movl $CPU_BC_MSS_ARRAY_CTL_ENA, %ecx xorl %edx, %edx movl $0x01, %eax @@ -246,63 +247,86 @@ xorl %esi, %esi xorl %ebp, %ebp
- /* DCache Ways0 through Ways7 will be tagged for LX_STACK_BASE + DCACHE_RAM_SIZE for holding stack */ - /* remember, there is NO stack yet... */ + /* DCache Ways0 through Ways7 will be tagged for + * LX_STACK_BASE + DCACHE_RAM_SIZE for holding stack. + */ + /* Remember, there is NO stack yet... */
- /* Tell cache we want to fill WAY 0 starting at the top */ + /* Tell cache we want to fill Way 0 starting at the top. */ xorl %edx, %edx xorl %eax, %eax movl $CPU_DC_INDEX, %ecx wrmsr
- /* startaddress for tag of Way0: ebp will hold the incrementing address. dont destroy! */ - movl $LX_STACK_BASE, %ebp /* init to start address */ - orl $1, %ebp /* set valid bit and tag for this Way (B[31:12] : Cache tag value for line/way curr. selected by CPU_DC_INDEX */ + /* Startaddress for tag of Way0: ebp will hold the incrementing + * address. dont destroy! + */ + movl $LX_STACK_BASE, %ebp /* Init to start address. */ + /* Set valid bit and tag for this Way (B[31:12] : Cache tag value for + * line/way curr. selected by CPU_DC_INDEX. + */ + orl $1, %ebp
- /* start tag Ways 0 with 128 lines with 32bytes each: edi will hold the line counter. dont destroy! */ + /* Start tag Ways 0 with 128 lines with 32 bytes each: edi will hold + * the line counter. dont destroy! + */ movl $LX_NUM_CACHELINES, %edi + DCacheSetupFillWay: - - /* fill with dummy data: zero it so we can tell it from PCI memory space (returns FFs). */ - /* We will now store a line (32 bytes = 4 x 8bytes = 4 quadWords) */ + /* Fill with dummy data: zero it so we can tell it from PCI memory + * space (returns FFs). + */ + /* We will now store a line (32 bytes = 4 x 8 bytes = 4 quad-words). */ movw $0x04, %si xorl %edx, %edx xorl %eax, %eax movl $CPU_DC_DATA, %ecx + DCacheSetup_quadWordLoop: wrmsr decw %si jnz DCacheSetup_quadWordLoop
- /* Set the tag for this line, need to do this for every new cache line to validate it! */ - /* accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX increment and thus cont. in the next cache line... */ + /* Set the tag for this line, need to do this for every new cache + * line to validate it! + */ + /* Accessing CPU_DC_TAG_I makes the LINE field in CPU_DC_INDEX + * increment and thus continue in the next cache line... + */ xorl %edx, %edx movl %ebp, %eax movl $CPU_DC_TAG, %ecx wrmsr
- /* switch to next line */ - /* lines are in Bits10:4 */ - /* when index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is not a valid CL anymore! */ + /* Switch to next line. Lines are in Bits10:4. */ + /* When index is crossing 0x7F -> 0x80 writing a RSVD bit as 0x80 is + * not a valid CL anymore! + */ movl $CPU_DC_INDEX, %ecx rdmsr - addl $0x010, %eax /* TODO: prob. would be more elegant to calc. this from counter var edi... */ + /* TODO: Probably would be more elegant to calculate this from + * counter var edi... + */ + addl $0x010, %eax wrmsr
decl %edi jnz DCacheSetupFillWay
- /* 1 Way has been filled, forward start address for next Way, terminate if we have reached end of desired address range */ + /* 1 Way has been filled, forward start address for next Way, + * terminate if we have reached end of desired address range. + */ addl $LX_CACHEWAY_SIZE, %ebp cmpl $LX_STACK_END, %ebp jge leave_DCacheSetup movl $LX_NUM_CACHELINES, %edi
- /* switch to next way */ + /* Switch to next way. */ movl $CPU_DC_INDEX, %ecx rdmsr addl $0x01, %eax - andl $0xFFFFF80F, %eax /* lets be sure: reset line index Bits10:4 */ + /* Let's be sure: reset line index Bits10:4. */ + andl $0xFFFFF80F, %eax wrmsr
jmp DCacheSetupFillWay @@ -312,20 +336,22 @@ xorl %esi, %esi xorl %ebp, %ebp
- /* Disable the cache, but ... DO NOT INVALIDATE the tags. */ + /* Disable the cache, but... DO NOT INVALIDATE the tags. */ /* Memory reads and writes will all hit in the cache. */ - /* Cache updates and memory write-backs will not occur ! */ + /* Cache updates and memory write-backs will not occur! */ movl %cr0, %eax - orl $(CR0_CD + CR0_NW), %eax /* set the CD and NW bits */ + orl $(CR0_CD + CR0_NW), %eax /* Set the CD and NW bits. */ movl %eax, %cr0
/* Now point sp to the cached stack. */ - /* The stack will be fully functional at this location. No system memory is required at all ! */ - /* set up the stack pointer */ + /* The stack will be fully functional at this location. No system + * memory is required at all! + */ + /* Set up the stack pointer. */ movl $LX_STACK_END, %eax movl %eax, %esp
- /* test the stack*/ + /* Test the stack. */ movl $0x0F0F05A5A, %edx pushl %edx popl %ecx @@ -333,57 +359,63 @@ je DCacheSetupGood movb $0xC5, %al outb %al, $0x80 + DCacheSetupBad: - hlt /* issues */ + hlt /* Issues */ jmp DCacheSetupBad + DCacheSetupGood: - - /* If you wanted to maintain the stack in memory you would need to set the tags as dirty - so the wbinvd would push out the old stack contents to memory */ - /* Clear the cache, the following code from crt0.S.lb will setup a new stack*/ + /* If you wanted to maintain the stack in memory you would need to + * set the tags as dirty so the wbinvd would push out the old stack + * contents to memory. + */ + /* Clear the cache, the following code from crt0.S.lb will setup + * a new stack. + */ wbinvd
- /* at this point, CAR should be working */ + /* At this point, CAR should be working. */ movl $(LX_STACK_END), %eax - movl %eax, %esp + movl %eax, %esp
- /* Load a different set of data segments */ - movw $CACHE_RAM_DATA_SEG, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %ss + /* Load a different set of data segments. */ + movw $CACHE_RAM_DATA_SEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss
lout: - - /* Restore the BIST result */ + /* Restore the BIST result. */ movl %ebp, %eax - /* We need to set ebp ? No need */ + /* We need to set ebp? No need. */ movl %esp, %ebp - pushl %eax /* bist */ - call stage1_main - /* We will not go back */ -fixed_mtrr_msr: - .long 0x250, 0x258, 0x259 - .long 0x268, 0x269, 0x26A - .long 0x26B, 0x26C, 0x26D - .long 0x26E, 0x26F -var_mtrr_msr: - .long 0x200, 0x201, 0x202, 0x203 - .long 0x204, 0x205, 0x206, 0x207 - .long 0x208, 0x209, 0x20A, 0x20B - .long 0x20C, 0x20D, 0x20E, 0x20F - .long 0x000 /* NULL, end of table */ + pushl %eax /* BIST */ + call stage1_main + /* We will not go back. */
+fixed_mtrr_msr: + .long 0x250, 0x258, 0x259 + .long 0x268, 0x269, 0x26A + .long 0x26B, 0x26C, 0x26D + .long 0x26E, 0x26F +var_mtrr_msr: + .long 0x200, 0x201, 0x202, 0x203 + .long 0x204, 0x205, 0x206, 0x207 + .long 0x208, 0x209, 0x20A, 0x20B + .long 0x20C, 0x20D, 0x20E, 0x20F + .long 0x000 /* NULL, end of table */ + # Reset vector.
/* - RVECTOR: size of reset vector, default is 0x10 - RESRVED: size of vpd code, default is 0xf0 - BOOTBLK: size of bootblock code, default is 0x1f00 (8k-256b) -*/ + * RVECTOR: size of reset vector, default is 0x10 + * RESRVED: size of vpd code, default is 0xf0 + * BOOTBLK: size of bootblock code, default is 0x1f00 (8k-256b) + */
SEGMENT_SIZE = 0x10000 RVECTOR = 0x00010 + # Due to YET ANOTHER BUG in GNU bintools, you can NOT have a code16 here. # I think we should leave it this way forever, as the bugs come and # go -- and come again. @@ -397,8 +429,8 @@ .byte 0xe9 .int _stage0 - ( . + 2 ) /* Note: The above jump is hand coded to work around bugs in binutils. - * 5 byte are used for a 3 byte instruction. This works because x86 - * is little endian and allows us to use supported 32bit relocations + * 5 bytes are used for a 3 byte instruction. This works because x86 + * is little endian and allows us to use supported 32 bit relocations * instead of the weird 16 bit relocations that binutils does not * handle consistenly between versions because they are used so rarely. */