On Sun, 6 Sep 1998, PJ Barbera wrote:

> May be it is just getting hot ?
> Are you using at least the biggest meanest CPU
> cooler you
> could find ?
> I run a Cyrix 166 and 233 and don't have any
> problems.

I use set6x86, and it has caused no problems for me. Like Peter said, make
sure you have got the 'biggest meanest CPU cooler you can find'. These
Cyrix babies get hot!

> > I've read the doc about the Cyrix 'coma' bug and i've try to use
> > set6x86 to set the NO_LOCK bit : no change...

I think the coma bug would only be used in a form of attack by a user, It
would be unlikely to be in the programs you mention

> > (BTW : the doc speaks about a little source code to detect this coma
> > bug but i've found nowhere...)

I downloaded the set6x86 source, and it _is_ in there, but it is more of a
demo of what it can do rather than a detection program.. It is full of
warnings: "UNMOUNT YOUR PARTITIONS __BEFORE__ RUNNING THIS PROGRAM!!!!"

> > I've read the various log files : nothing... Is there a way to have a
> > trace of the crash  (a core dump or something like that ?).
> > 
Pass.. a core dump leaves behind a 'core' file. (usually) check with
`updatedb;locate core` to find any left behind.. but not /dev/core..


The set6x86 source has a kernel source patch, and this is applied to all
but the head.S file in the debian 2.0.34 kernel source package. I have
attached my copy of this, It is not really necessary, It only correctly
identifies the CPU in /proc/cpuinfo.

                       Michael Beattie ([EMAIL PROTECTED])

               PGP Key available, reply with "pgpkey" as subject.
 -----------------------------------------------------------------------------
          WinErr: 013 Reserved for future mistakes of our developers.
 -----------------------------------------------------------------------------
                Debian GNU/Linux....  Ooohh You are missing out!

/*
 *  linux/arch/i386/head.S
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 *  head.S contains the 32-bit startup code.
 */

.text
#include <linux/tasks.h>
#include <linux/linkage.h>
#include <asm/segment.h>
#include <linux/config.h>

#define CL_MAGIC_ADDR   0x90020
#define CL_MAGIC        0xA33F
#define CL_BASE_ADDR    0x90000
#define CL_OFFSET       0x90022

/*
 * swapper_pg_dir is the main page directory, address 0x00001000 (or at
 * address 0x00101000 for a compressed boot).
 */
ENTRY(stext)
ENTRY(_stext)
startup_32:
        cld
        movl $(KERNEL_DS),%eax
        mov %ax,%ds
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
#ifdef __SMP__
        orw  %bx,%bx
        jz  1f                          /* Initial CPU cleans BSS */
/*
 *      Set up the stack
 */
        mov %ax,%ss
        xorl %eax,%eax
        movw %cx, %ax
        movl %eax,%esp
        pushl $0
        popfl
        jmp checkCPUtype
1:
        lss stack_start,%esp
#endif __SMP__
/*
 * Clear BSS first so that there are no surprises...
 */
        xorl %eax,%eax
        movl $ SYMBOL_NAME(_edata),%edi
        movl $ SYMBOL_NAME(_end),%ecx
        subl %edi,%ecx
        cld
        rep
        stosb
/*
 * start system 32-bit setup. We need to re-do some of the things done
 * in 16-bit mode for the "real" operations.
 */
        call setup_idt
        xorl %eax,%eax
1:      incl %eax               # check that A20 really IS enabled
        movl %eax,0x000000      # loop forever if it isn't
        cmpl %eax,0x100000
        je 1b
/*
 * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
 * confuse the debugger if this code is traced.
 * XXX - best to initialize before switching to protected mode.
 */
        pushl $0
        popfl
/*
 * Copy bootup parameters out of the way. First 2kB of
 * _empty_zero_page is for boot parameters, second 2kB
 * is for the command line.
 */
        movl $0x90000,%esi
        movl $ SYMBOL_NAME(empty_zero_page),%edi
        movl $512,%ecx
        cld
        rep
        movsl
        xorl %eax,%eax
        movl $512,%ecx
        rep
        stosl
        cmpw $(CL_MAGIC),CL_MAGIC_ADDR
        jne 1f
        movl $ SYMBOL_NAME(empty_zero_page)+2048,%edi
        movzwl CL_OFFSET,%esi
        addl $(CL_BASE_ADDR),%esi
        movl $2048,%ecx
        rep
        movsb
1:
#ifdef __SMP__
checkCPUtype:
#endif

/* check if it is 486 or 386. */
/*
 * XXX - this does a lot of unnecessary setup.  Alignment checks don't
 * apply at our cpl of 0 and the stack ought to be aligned already, and
 * we don't need to preserve eflags.
 */
        /*
         * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2
         * (and it _must_ be 5 divided by 2) while other CPUs change
         * them in undefined ways. We need to know this since we may
         * need to enable the CPUID instruction at least.
         */
        xor %ax,%ax
        sahf
        movb $5,%ax
        movb $2,%bx
        div %bl
        lahf
        cmpb $2,%ah
        jne ncyrix

        /*
         * It behaves like a Cyrix/IBM 6x86(L) so put "Cyrix" in the 
         * vendor id field. It may be overwritten later with the 
         * real thing if CPUID works.
         */
        movl $0x69727943,SYMBOL_NAME(x86_vendor_id)     # low 4 chars
        movl $0x00000078,SYMBOL_NAME(x86_vendor_id)+4   # next 4 chars

        /*
         * N.B. The pattern of accesses to 0x22 and 0x23 is *essential*
         *      so do not try to "optimize" it! For the same reason we
         *      do all this with interrupts off.
         */
#define setCx86(reg, val) \
        movb reg,%ax;   \
        outb %ax,$0x22; \
        movb val,%ax;   \
        outb %ax,$0x23

#define getCx86(reg) \
        movb reg,%ax;   \
        outb %ax,$0x22; \
        inb $0x23,%ax

        cli
        getCx86($0xc3)          # get CCR3
        movb %ax,%cx            # Save old value
        movb %ax,%bx
        andb $0x0f,%bx          # Enable access to all config registers
        orb $0x10,%bx           # by setting bit 4
        setCx86($0xc3,%bx)

        getCx86($0xe8)          # now we can get CCR4
        orb $0x80,%ax           # and set bit 7 (CPUIDEN)
        movb %ax,%bx            # to enable CPUID execution
        setCx86($0xe8,%bx)

        getCx86($0xfe)          # DIR0 : let's check this is a 6x86(L)
        andb $0xf0,%ax          # should be 3xh
        cmpb $0x30,%ax          # 
        jne n6x86
        getCx86($0xe9)          # CCR5 : we reset the SLOP bit
        andb $0xfd,%ax          # so that udelay calculation
        movb %ax,%bx            # is correct on 6x86(L) CPUs
        setCx86($0xe9,%bx)

n6x86:  setCx86($0xc3,%cx)      # Restore old CCR3
        sti

ncyrix: movl $3, SYMBOL_NAME(x86)
        pushfl                  # push EFLAGS
        popl %eax               # get EFLAGS
        movl %eax,%ecx          # save original EFLAGS
        xorl $0x40000,%eax      # flip AC bit in EFLAGS
        pushl %eax              # copy to EFLAGS
        popfl                   # set EFLAGS
        pushfl                  # get new EFLAGS
        popl %eax               # put it in eax
        xorl %ecx,%eax          # change in flags
        andl $0x40000,%eax      # check if AC bit changed
        je is386
        movl $4,SYMBOL_NAME(x86)
        movl %ecx,%eax
        xorl $0x200000,%eax     # check ID flag
        pushl %eax
        popfl                   # if we are on a straight 486DX, SX, or
        pushfl                  # 487SX we can't change it
        popl %eax
        xorl %ecx,%eax
        andl $0x200000,%eax
        je is486
isnew:  pushl %ecx              # restore original EFLAGS
        popfl
        incl SYMBOL_NAME(have_cpuid)    # we have CPUID
        /*
         *      Technically we should use CPUID 0 to see if we have CPUID 1!
         */
        /* get processor type */
        movl $1, %eax           # Use the CPUID instruction to 
#ifdef GAS_KNOWS_CPUID
        cpuid                   # check the processor type
#else
        .byte 0x0f, 0xa2        # check the processor type
#endif
        movb %al, %cl           # save reg for future use
        andb $0x0f,%ah          # mask processor family
        movb %ah,SYMBOL_NAME(x86)
        andb $0xf0, %al         # mask model
        shrb $4, %al
        movb %al,SYMBOL_NAME(x86_model)
        andb $0x0f, %cl         # mask mask revision
        movb %cl,SYMBOL_NAME(x86_mask)
        movl %edx,SYMBOL_NAME(x86_capability)

        xor %ax,%ax             # test again for Cyrix CPU
        sahf
        movb $5,%ax
        movb $2,%bx
        div %bl
        lahf
        cmpb $2,%ah
        jne ncyrx2              # skip if not Cyrix CPU
        getCx86($0xff)          # DIR1 : let's check the stepping
        movb %al,SYMBOL_NAME(x86_mask)

        /* get vendor info */
ncyrx2: xorl %eax, %eax                 # call CPUID with 0 -> return vendor ID
#ifdef GAS_KNOWS_CPUID
        cpuid
#else
        .byte 0x0f, 0xa2                # CPUID
#endif
        movl %ebx,SYMBOL_NAME(x86_vendor_id)    # lo 4 chars
        movl %edx,SYMBOL_NAME(x86_vendor_id)+4  # next 4 chars
        movl %ecx,SYMBOL_NAME(x86_vendor_id)+8  # last 4 chars

        movl %cr0,%eax          # 486+
        andl $0x80000011,%eax   # Save PG,PE,ET
        orl $0x50022,%eax       # set AM, WP, NE and MP
        jmp 2f
is486:  pushl %ecx              # restore original EFLAGS
        popfl
        movl %cr0,%eax          # 486
        andl $0x80000011,%eax   # Save PG,PE,ET
        orl $0x50022,%eax       # set AM, WP, NE and MP
        jmp 2f
is386:  pushl %ecx              # restore original EFLAGS
        popfl
        movl %cr0,%eax          # 386
        andl $0x80000011,%eax   # Save PG,PE,ET
        orl $2,%eax             # set MP
2:      movl %eax,%cr0
        call check_x87
#ifdef __SMP__
        movb ready,%al
        orb %al,%al
        jz 3f   
        movl $ SYMBOL_NAME(swapper_pg_dir), %eax
        movl %eax, %cr3
#ifdef GAS_KNOWS_CR4
        movl %cr4,%eax
        orl $16,%eax
        movl %eax,%cr4
#else
        .byte 0x0f,0x20,0xe0
        orl $16,%eax
        .byte 0x0f,0x22,0xe0
#endif
        movl %cr0, %eax
        orl $0x80000000, %eax
        movl %eax, %cr0
        jmp 4f
#endif
3:
        call setup_paging
#ifdef __SMP__
        incb ready
#endif
4:
        lgdt gdt_descr
        lidt idt_descr
        ljmp $(KERNEL_CS),$1f
1:      movl $(KERNEL_DS),%eax  # reload all the segment registers
        mov %ax,%ds             # after changing gdt.
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
#ifdef __SMP__
        movl $(KERNEL_DS), %eax
        mov  %ax,%ss            # Reload the stack pointer (segment only)
#else
        lss stack_start,%esp    # Load processor stack
#endif
        xorl %eax,%eax
        lldt %ax
        pushl %eax              # These are the parameters to main :-)
        pushl %eax
        pushl %eax
        cld                     # gcc2 wants the direction flag cleared at all 
times
        call SYMBOL_NAME(start_kernel)
L6:
        jmp L6                  # main should never return here, but
                                # just in case, we know what happens.

#ifdef __SMP__
ready:  .byte 0
#endif

/*
 * We depend on ET to be correct. This checks for 287/387.
 */
check_x87:
        movb $0,SYMBOL_NAME(hard_math)
        clts
        fninit
        fstsw %ax
        cmpb $0,%al
        je 1f
        movl %cr0,%eax          /* no coprocessor: have to set bits */
        xorl $4,%eax            /* set EM */
        movl %eax,%cr0
        ret
        ALIGN
1:      movb $1,SYMBOL_NAME(hard_math)
        .byte 0xDB,0xE4         /* fsetpm for 287, ignored by 387 */
        ret

/*
 *  setup_idt
 *
 *  sets up a idt with 256 entries pointing to
 *  ignore_int, interrupt gates. It doesn't actually load
 *  idt - that can be done only after paging has been enabled
 *  and the kernel moved to 0xC0000000. Interrupts
 *  are enabled elsewhere, when we can be relatively
 *  sure everything is ok.
 */
setup_idt:
        lea ignore_int,%edx
        movl $(KERNEL_CS << 16),%eax
        movw %dx,%ax            /* selector = 0x0010 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */

        lea SYMBOL_NAME(idt),%edi
        mov $256,%ecx
rp_sidt:
        movl %eax,(%edi)
        movl %edx,4(%edi)
        addl $8,%edi
        dec %ecx
        jne rp_sidt
        ret


/*
 * Setup_paging
 *
 * This routine sets up paging by setting the page bit
 * in cr0. The page tables are set up, identity-mapping
 * the first 4MB.  The rest are initialized later.
 *
 * (ref: added support for up to 32mb, 17Apr92)  -- Rik Faith
 * (ref: update, 25Sept92)  -- [EMAIL PROTECTED] 
 * (ref: 92.10.11 - Linus Torvalds. Corrected 16M limit - no upper memory limit)
 */
        ALIGN
setup_paging:
        movl $1024*2,%ecx               /* 2 pages - swapper_pg_dir+1 page 
table */
        xorl %eax,%eax
        movl $ SYMBOL_NAME(swapper_pg_dir),%edi /* swapper_pg_dir is at 0x1000 
*/
        cld;rep;stosl
/* Identity-map the kernel in low 4MB memory for ease of transition */
/* set present bit/user r/w */
        movl $ SYMBOL_NAME(pg0)+7,SYMBOL_NAME(swapper_pg_dir)
/* But the real place is at 0xC0000000 */
/* set present bit/user r/w */
        movl $ SYMBOL_NAME(pg0)+7,SYMBOL_NAME(swapper_pg_dir)+3072
        movl $ SYMBOL_NAME(pg0)+4092,%edi
        movl $0x03ff007,%eax            /*  4Mb - 4096 + 7 (r/w user,p) */
        std
1:      stosl                   /* fill the page backwards - more efficient :-) 
*/
        subl $0x1000,%eax
        jge 1b
        cld
        movl $ SYMBOL_NAME(swapper_pg_dir),%eax
        movl %eax,%cr3                  /* cr3 - page directory start */
        movl %cr0,%eax
        orl $0x80000000,%eax
        movl %eax,%cr0          /* set paging (PG) bit */
        ret                     /* this also flushes the prefetch-queue */

/*
 * page 0 is made non-existent, so that kernel NULL pointer references get
 * caught. Thus the swapper page directory has been moved to 0x1000
 *
 * XXX Actually, the swapper page directory is at 0x1000 plus 1 megabyte,
 * with the introduction of the compressed boot code.  Theoretically,
 * the original design of overlaying the startup code with the swapper
 * page directory is still possible --- it would reduce the size of the kernel
 * by 2-3k.  This would be a good thing to do at some point.....
 */
.org 0x1000
ENTRY(swapper_pg_dir)
/*
 * The page tables are initialized to only 4MB here - the final page
 * tables are set up later depending on memory size.
 */
.org 0x2000
ENTRY(pg0)

.org 0x3000
ENTRY(empty_bad_page)

.org 0x4000
ENTRY(empty_bad_page_table)

.org 0x5000
ENTRY(empty_zero_page)

.org 0x6000

stack_start:
        .long SYMBOL_NAME(init_user_stack)+4096
        .long KERNEL_DS

/* NOTE: keep the idt short behind the above '.org 0x6000'
         It must fit completely within _one_ page */
ENTRY(idt)
        .fill 256,8,0           # idt is uninitialized

/* This is the default interrupt "handler" :-) */
int_msg:
        .asciz "Unknown interrupt\n"
        ALIGN
ignore_int:
        cld
        pushl %eax
        pushl %ecx
        pushl %edx
        push %ds
        push %es
        push %fs
        movl $(KERNEL_DS),%eax
        mov %ax,%ds
        mov %ax,%es
        mov %ax,%fs
        pushl $int_msg
        call SYMBOL_NAME(printk)
        popl %eax
        pop %fs
        pop %es
        pop %ds
        popl %edx
        popl %ecx
        popl %eax
        iret

/*
 * The interrupt descriptor table has room for 256 idt's
 */
        ALIGN
.word 0
idt_descr:
        .word 256*8-1           # idt contains 256 entries
        .long 0xc0000000+SYMBOL_NAME(idt)

        ALIGN
.word 0
gdt_descr:
#ifdef CONFIG_APM
        .word (11+2*NR_TASKS)*8-1
#else
        .word (8+2*NR_TASKS)*8-1
#endif
        .long 0xc0000000+SYMBOL_NAME(gdt)

/*
 * This gdt setup gives the kernel a 1GB address space at virtual
 * address 0xC0000000 - space enough for expansion, I hope.
 */
ENTRY(gdt)
        .quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x0000000000000000        /* not used */
        .quad 0xc0c39a000000ffff        /* 0x10 kernel 1GB code at 0xC0000000 */
        .quad 0xc0c392000000ffff        /* 0x18 kernel 1GB data at 0xC0000000 */
        .quad 0x00cbfa000000ffff        /* 0x23 user   3GB code at 0x00000000 */
        .quad 0x00cbf2000000ffff        /* 0x2b user   3GB data at 0x00000000 */
        .quad 0x0000000000000000        /* not used */
        .quad 0x0000000000000000        /* not used */
        .fill 2*NR_TASKS,8,0            /* space for LDT's and TSS's etc */
#ifdef CONFIG_APM
        .quad 0x00c09a0000000000        /* APM CS    code */
        .quad 0x00809a0000000000        /* APM CS 16 code (16 bit) */
        .quad 0x00c0920000000000        /* APM DS    data */
#endif

Reply via email to