src/arch/i386/boot/boot.c

- Tone down the severity of error messages
src/arch/i386/lib/console.inc
- Preserve morre registers in __CONSOLE_INLINE_TX_HEX8
src/arch/i386/lib/hardwaremain.c
- Fixup the cmos option to handle multiple cpus
- Move pci setup before ramsize initialization
- Renable keyboard_on
src/arch/i386/smp/Config
Add secondary.S
src/arch/i386/smp/secondary.S
- add
src/arch/i386/smp/secondary.inc
- remove
src/arch/i386/smp/start_stop.c
- Remove unused variables
src/config/Config
- Cleanup the cross compiling options
- Rename cmos.conf cmos.layout as the previous name was too confusing
src/cpu/p6/mtrr.c
- Create subroutines to enable/disable caching
- Call them in all of the appropriate places
- Add an extra argument to range_to_mtrr to allow for
  future optimizations
This commit is contained in:
Eric W. Biederman 2002-10-10 19:02:37 +00:00
parent 36d5c4d8a2
commit b708444232
8 changed files with 154 additions and 87 deletions

View file

@ -85,13 +85,13 @@ void jmp_to_elf_entry(void *entry, unsigned long buffer)
adjusted_boot_notes = (unsigned long)&elf_boot_notes;
adjusted_boot_notes += adjust;
printk_info("entry = 0x%08lx\n", (unsigned long)entry);
printk_info("lb_start = 0x%08lx\n", lb_start);
printk_info("lb_size = 0x%08lx\n", lb_size);
printk_info("adjust = 0x%08lx\n", adjust);
printk_info("buffer = 0x%08lx\n", buffer);
printk_info(" elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
printk_info("adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
printk_spew("entry = 0x%08lx\n", (unsigned long)entry);
printk_spew("lb_start = 0x%08lx\n", lb_start);
printk_spew("lb_size = 0x%08lx\n", lb_size);
printk_spew("adjust = 0x%08lx\n", adjust);
printk_spew("buffer = 0x%08lx\n", buffer);
printk_spew(" elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
printk_spew("adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
/* Jump to kernel */
__asm__ __volatile__(

View file

@ -42,7 +42,8 @@ console_test:
/* uses: byte, ax, dx */
#define __CONSOLE_INLINE_TX_HEX8(byte) \
mov byte, %al ; \
movb byte, %dl ; \
shll $16, %edx ; \
shr $4, %al ; \
add $'0', %al ; \
cmp $'9', %al ; \
@ -50,7 +51,8 @@ console_test:
add $39, %al ; \
9: ; \
__CONSOLE_INLINE_TX_AL ; \
mov byte, %al ; \
shrl $16, %edx ; \
movb %dl, %al ; \
and $0x0f, %al ; \
add $'0', %al ; \
cmp $'9', %al ; \
@ -423,24 +425,7 @@ console_tx_al:
/* uses: esp, ax, edx */
console_tx_hex8:
movb %al, %dl
shll $16, %edx
shr $4, %al
add $'0', %al
cmp $'9', %al
jle 9f
add $39, %al
9:
__CONSOLE_INLINE_TX_AL
shrl $16, %edx
movb %dl, %al
and $0x0f, %al
add $'0', %al
cmp $'9', %al
jle 9f
add $39, %al
9:
__CONSOLE_INLINE_TX_AL
__CONSOLE_INLINE_TX_HEX8(%al)
RETSP

View file

@ -153,8 +153,7 @@ static void wait_for_other_cpus(void)
old_active_count = 1;
active_count = atomic_read(&active_cpus);
while (active_count > 1) {
while(active_count > 1) {
if (active_count != old_active_count) {
printk_info("Waiting for %d CPUS to stop\n", active_count);
old_active_count = active_count;
@ -180,15 +179,16 @@ static void remove_logical_cpus(void)
/* To turn off hyperthreading just remove the logical
* cpus from the processor map.
*/
int cnt;
cnt=0;
if (get_option(&cnt,"logical_cpus")==0) {
if (cnt) {
int disable_logical_cpus = !CONFIG_LOGICAL_CPUS;
if (get_option(&disable_logical_cpus,"hyper_threading")) {
disable_logical_cpus = !CONFIG_LOGICAL_CPUS;
}
if (disable_logical_cpus) {
/* disable logical cpus */
for(cnt=MAX_PHYSICAL_CPUS;cnt<MAX_CPUS;cnt++)
processor_map[cnt]=0;
printk_debug("logical cpus disabled\n");
}
int cnt;
for(cnt=MAX_PHYSICAL_CPUS;cnt<MAX_CPUS;cnt++)
processor_map[cnt]=0;
printk_debug("logical cpus disabled\n");
}
}
#else
@ -296,6 +296,16 @@ void hardwaremain(int boot_complete)
// So you really need to run this before you size ram.
framebuffer_on();
// Now do the real bus
// we round the total ram up a lot for thing like the SISFB, which
// shares high memory with the CPU.
pci_configure();
post_code(0x88);
pci_enable();
pci_initialize();
post_code(0x89);
mem = get_ramsize();
post_code(0x70);
totalmem = 0;
@ -318,16 +328,6 @@ void hardwaremain(int boot_complete)
startup_other_cpus(processor_map);
post_code(0x77);
// Now do the real bus
// we round the total ram up a lot for thing like the SISFB, which
// shares high memory with the CPU.
pci_configure();
post_code(0x88);
pci_enable();
pci_initialize();
post_code(0x89);
// generic mainboard fixup
mainboard_fixup();
@ -342,7 +342,7 @@ void hardwaremain(int boot_complete)
nvram_on();
//keyboard_on();
keyboard_on();
#ifndef USE_NEW_SUPERIO_INTERFACE
enable_floppy();

View file

@ -1,3 +1,5 @@
object mpspec.o HAVE_MP_TABLE
object ioapic.o IOAPIC
object start_stop.o SMP
object secondary.S SMP

View file

@ -0,0 +1,76 @@
#include <arch/asm.h>
#include <arch/intel.h>
#include <cpu/p6/mtrr.h>
#include <cpu/p6/apic.h>
.text
.globl _secondary_start
.balign 4096
_secondary_start:
.code16
cli
xorl %eax, %eax
movl %eax, %cr3 /* Invalidate TLB*/
/* On hyper threaded cpus invalidating the cache here is
* very very bad. Don't.
*/
/* setup the data segment */
movw %cs, %ax
movw %ax, %ds
data32 lgdt gdtaddr - _secondary_start
movl %cr0, %eax
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
orl $0x60000001, %eax /* CD, NW, PE = 1 */
movl %eax, %cr0
ljmpl $0x10, $1f
1:
.code32
movw $0x18, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
/* Enable the local apic, and map it where we expext it */
movl $APIC_BASE_MSR, %ecx
rdmsr
orl $APIC_BASE_MSR_ENABLE, %eax
andl $(~APIC_BASE_MSR_ADDR_MASK), %eax
orl $APIC_DEFAULT_BASE, %eax
wrmsr
/* Get the apic_id */
movl (APIC_ID + APIC_DEFAULT_BASE), %edi
shrl $24, %edi
/* Get the cpu index (MAX_CPUS on error) */
movl $-4, %ebx
1: addl $4, %ebx
cmpl $(MAX_CPUS << 2), %ebx
je 2
cmpl %edi, EXT(initial_apicid)(%ebx)
jne 1b
2: shrl $2, %ebx
/* set the stack pointer */
movl $_estack, %esp
movl %ebx, %eax
movl $STACK_SIZE, %ebx
mull %ebx
subl %eax, %esp
call EXT(secondary_cpu_init)
1: hlt
jmp 1b
gdtaddr:
.word gdt_limit /* the table limit */
.long gdt /* we know the offset */
.code32

View file

@ -88,8 +88,6 @@ int start_cpu(unsigned long apicid)
int timeout;
unsigned long send_status, accept_status, start_eip;
int j, num_starts, maxlvt;
//extern char _start[], _estart[];
//extern char reboot_halt[];
extern char _secondary_start[];
/*

View file

@ -2,18 +2,17 @@
option LINUXBIOS_VERSION=1.0.0
option CROSS_COMPILE=
option CC=$(CROSS_COMPILE)gcc
option HOSTCC=$(CROSS_COMPILE)gcc
option OBJCOPY=objcopy
makedefine CC:=$(CROSS_COMPILE)gcc
makedefine CPP:= $(CROSS_COMPILE)gcc -x assembler-with-cpp -DASSEMBLY -E
makedefine OBJCOPY:=$(CROSS_COMPILE)objcopy
makedefine CPP:= $(CC) -x assembler-with-cpp -DASSEMBLY -E
makedefine LIBGCC_FILE_NAME := $(shell $(CC) -print-libgcc-file-name)
makedefine GCC_INC_DIR := $(shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp")
makedefine CPPFLAGS := -I$(TOP)/src/include -I$(TOP)/src/arch/$(ARCH)/include -I$(GCC_INC_DIR) $(CPUFLAGS)
makedefine CFLAGS := $(CPU_OPT) $(CPPFLAGS) -Os -nostdinc -nostdlib -fno-builtin -Wall
makedefine HOSTCC:=gcc
makedefine HOSTCFLAGS:= -Os -Wall
option LINUXBIOS_BUILD = $(shell date)
@ -60,7 +59,7 @@ makerule documentation: $(SOURCES) ; doxygen LinuxBIOSDoc.config
makerule build_opt_tbl: $(TOP)/util/options/build_opt_tbl.c ; $(HOSTCC) $(HOSTCFLAGS) $< -o $@
makerule /$(TARGET_DIR)/option_table.c : build_opt_tbl $(MAINBOARD)/cmos.conf ; ./build_opt_tbl -b --config $(MAINBOARD)/cmos.conf
makerule /$(TARGET_DIR)/option_table.c : build_opt_tbl $(MAINBOARD)/cmos.layout ; ./build_opt_tbl -b --config $(MAINBOARD)/cmos.layout
object /$(TARGET_DIR)/option_table.o HAVE_OPTION_TABLE

View file

@ -63,11 +63,36 @@ static void intel_enable_var_mtrr(void)
wrmsr(MTRRdefType_MSR, low, high);
}
static inline void disable_cache(void)
{
unsigned int tmp;
/* Disable cache */
/* Write back the cache and flush TLB */
asm volatile (
"movl %%cr0, %0\n\t"
"orl $0x40000000, %0\n\t"
"wbinvd\n\t"
"movl %0, %%cr0\n\t"
"wbinvd\n\t"
:"=r" (tmp)
::"memory");
}
static inline void enable_cache(void)
{
unsigned int tmp;
// turn cache back on.
asm volatile (
"movl %%cr0, %0\n\t"
"andl $0x9fffffff, %0\n\t"
"movl %0, %%cr0\n\t"
:"=r" (tmp)
::"memory");
}
/* setting variable mtrr, comes from linux kernel source */
static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
{
unsigned int tmp;
unsigned long base_high, base_low;
unsigned long mask_high, mask_low;
@ -88,14 +113,7 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
// it is recommended that we disable and enable cache when we
// do this.
/* Disable cache */
/* Write back the cache and flush TLB */
asm volatile ("movl %%cr0, %0\n\t"
"orl $0x40000000, %0\n\t"
"wbinvd\n\t"
"movl %0, %%cr0\n\t"
"wbinvd\n\t":"=r" (tmp)::"memory");
disable_cache();
if (sizek == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
@ -105,12 +123,7 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
wrmsr (MTRRphysBase_MSR(reg), base_low | type, base_high);
wrmsr (MTRRphysMask_MSR(reg), mask_low | 0x800, mask_high);
}
// turn cache back on.
asm volatile ("movl %%cr0, %0\n\t"
"andl $0x9fffffff, %0\n\t"
"movl %0, %%cr0\n\t":"=r" (tmp)::"memory");
enable_cache();
}
/* setting variable mtrr, comes from linux kernel source */
@ -123,15 +136,7 @@ void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsi
// it is recommended that we disable and enable cache when we
// do this.
/* Disable cache */
/* Write back the cache and flush TLB */
asm volatile (
"movl %%cr0, %0\n\t"
"orl $0x40000000, %0\n\t"
"movl %0, %%cr0\n\t"
:"=r" (tmp)
::"memory");
disable_cache();
if (size == 0) {
/* The invalid bit is kept in the mask, so we simply clear the
relevant mask register to disable a range. */
@ -143,10 +148,7 @@ void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsi
}
// turn cache back on.
asm volatile ("movl %%cr0, %0\n\t"
"andl $0x9fffffff, %0\n\t"
"movl %0, %%cr0\n\t":"=r" (tmp)::"memory");
enable_cache();
}
/* fms: find most sigificant bit set, stolen from Linux Kernel Source. */
@ -211,7 +213,9 @@ static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char
if (fixed_msr != i >> 3) {
/* But first write out the old msr */
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
disable_cache();
wrmsr(mtrr_msr[fixed_msr], low, high);
enable_cache();
}
fixed_msr = i>>3;
rdmsr(mtrr_msr[fixed_msr], low, high);
@ -226,7 +230,9 @@ static void set_fixed_mtrrs(unsigned int first, unsigned int last, unsigned char
}
/* Write out the final msr */
if (fixed_msr < (NUM_FIXED_RANGES >> 3)) {
disable_cache();
wrmsr(mtrr_msr[fixed_msr], low, high);
enable_cache();
}
}
@ -247,7 +253,8 @@ static unsigned fixed_mtrr_index(unsigned long addrk)
}
static unsigned int range_to_mtrr(unsigned int reg,
unsigned long range_startk, unsigned long range_sizek)
unsigned long range_startk, unsigned long range_sizek,
unsigned long next_range_startk)
{
if (!range_sizek || (reg >= BIOS_MTRRS)) {
return reg;
@ -323,7 +330,7 @@ void setup_mtrrs(struct mem_range *mem)
}
/* Write the range mtrrs */
if (range_sizek != 0) {
reg = range_to_mtrr(reg, range_startk, range_sizek);
reg = range_to_mtrr(reg, range_startk, range_sizek, memp->basek);
range_startk = 0;
range_sizek = 0;
if (reg >= BIOS_MTRRS)
@ -334,7 +341,7 @@ void setup_mtrrs(struct mem_range *mem)
range_sizek = memp->sizek;
}
/* Write the last range */
reg = range_to_mtrr(reg, range_startk, range_sizek);
reg = range_to_mtrr(reg, range_startk, range_sizek, 0);
printk_debug("DONE variable MTRRs\n");
printk_debug("Clear out the extra MTRR's\n");
/* Clear out the extra MTRR's */