Commit 8f009a86 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://gkernel.bkbits.net/net-drivers-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents b97490bf da9886d2
......@@ -85,15 +85,22 @@ ifdef CONFIG_MCYRIXIII
CFLAGS += -march=i586
endif
ifdef CONFIG_VISWS
MACHINE := mach-visws
else
MACHINE := mach-generic
endif
HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
libs-y += arch/i386/lib/
core-y += arch/i386/kernel/ arch/i386/mm/
core-y += arch/i386/kernel/ arch/i386/mm/ arch/i386/$(MACHINE)/
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += arch/i386/pci/
CFLAGS += -I$(TOPDIR)/arch/i386/$(MACHINE)
AFLAGS += -I$(TOPDIR)/arch/i386/$(MACHINE)
MAKEBOOT = +$(MAKE) -C arch/$(ARCH)/boot
.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
......
......@@ -260,6 +260,7 @@ else
if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_X86_IO_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
define_bool CONFIG_X86_MPPARSE y
fi
bool 'PCI support' CONFIG_PCI
if [ "$CONFIG_PCI" = "y" ]; then
......@@ -437,7 +438,19 @@ if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
fi
fi
if [ "$CONFIG_X86_LOCAL_APIC" = "y" ]; then
define_bool CONFIG_X86_EXTRA_IRQS y
define_bool CONFIG_X86_FIND_SMP_CONFIG y
fi
endmenu
source security/Config.in
source lib/Config.in
if [ "$CONFIG_SMP" = "y" ]; then
define_bool CONFIG_X86_SMP y
define_bool CONFIG_X86_HT y
fi
define_bool CONFIG_X86_BIOS_REBOOT y
......@@ -12,6 +12,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
bootflag.o
obj-y += cpu/
obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
......@@ -19,15 +20,12 @@ obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_ACPI) += acpi.o
obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o
obj-$(CONFIG_X86_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
obj-$(CONFIG_X86_NUMAQ) += numaq.o
ifdef CONFIG_VISWS
obj-y += setup-visws.o
obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
endif
EXTRA_AFLAGS := -traditional
......
......@@ -29,6 +29,21 @@
#include <asm/mtrr.h>
#include <asm/mpspec.h>
#include <asm/pgalloc.h>
#include <asm/desc.h>
#include <asm/arch_hooks.h>
void __init apic_intr_init(void)
{
#ifdef CONFIG_SMP
smp_intr_init();
#endif
/* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
/* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
}
/* Using APIC to generate smp_local_timer_interrupt? */
int using_apic_timer = 0;
......
......@@ -257,7 +257,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
if ( p )
strcpy(c->x86_model_id, p);
#ifdef CONFIG_SMP
#ifdef CONFIG_X86_HT
if (test_bit(X86_FEATURE_HT, c->x86_capability) && !disable_P4_HT) {
extern int phys_proc_id[NR_CPUS];
......
......@@ -47,7 +47,7 @@
#include <asm/errno.h>
#include <asm/segment.h>
#include <asm/smp.h>
#include <asm/irq_vectors.h>
#include "irq_vectors.h"
EBX = 0x00
ECX = 0x04
......@@ -344,34 +344,8 @@ ENTRY(name) \
call smp_/**/name; \
jmp ret_from_intr;
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent for them, they are triggered
* through the ICC by us (IPIs)
*/
#ifdef CONFIG_SMP
BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
#endif
/*
* every pentium local APIC has two 'local interrupts', with a
* soft-definable vector attached to both interrupts, one of
* which is a timer interrupt, the other one is error counter
* overflow. Linux uses the local APIC timer interrupt to get
* a much simpler SMP time architecture:
*/
#ifdef CONFIG_X86_LOCAL_APIC
BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
#ifdef CONFIG_X86_MCE_P4THERMAL
BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
#endif
#endif
/* The include is where all of the SMP etc. interrupts come from */
#include "entry_arch.h"
ENTRY(divide_error)
pushl $0 # no error code
......
......@@ -21,6 +21,7 @@
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/apic.h>
#include <asm/arch_hooks.h>
#include <linux/irq.h>
......@@ -332,15 +333,6 @@ static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
*/
static struct irqaction irq13 = { math_error_irq, 0, 0, "fpu", NULL, NULL };
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
#ifndef CONFIG_VISWS
static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
#endif
void __init init_ISA_irqs (void)
{
int i;
......@@ -373,11 +365,9 @@ void __init init_IRQ(void)
{
int i;
#ifndef CONFIG_X86_VISWS_APIC
init_ISA_irqs();
#else
init_VISWS_APIC_irqs();
#endif
/* all the set up before the call gates are initialised */
pre_intr_init_hook();
/*
* Cover the whole vector space, no vector can escape
* us. (some of these will be overridden and become
......@@ -389,39 +379,9 @@ void __init init_IRQ(void)
set_intr_gate(vector, interrupt[i]);
}
#ifdef CONFIG_SMP
/*
* IRQ0 must be given a fixed assignment and initialized,
* because it's used before the IO-APIC is set up.
*/
set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
/*
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
*/
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
/* IPI for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
/* self generated IPI for local APIC timer */
set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
/* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
/* thermal monitor LVT interrupt */
#ifdef CONFIG_X86_MCE_P4THERMAL
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
#endif
/* setup after call gates are initialised (usually add in
* the architecture specific gates */
intr_init_hook();
/*
* Set the clock to HZ Hz, we already have a valid
......@@ -431,10 +391,6 @@ void __init init_IRQ(void)
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
#ifndef CONFIG_VISWS
setup_irq(2, &irq2);
#endif
/*
* External FPU? Set up irq13 if so, for
* original braindamaged IBM FERR coupling.
......
......@@ -52,6 +52,7 @@
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <asm/arch_hooks.h>
/* This structure holds MCA information. Each (plug-in) adapter has
* eight POS registers. Then the machine may have integrated video and
......@@ -379,12 +380,7 @@ void mca_handle_nmi(void)
}
}
/* If I recall correctly, there's a whole bunch of other things that
* we can do to check for NMI problems, but that's all I know about
* at the moment.
*/
printk("NMI generated from unknown source!\n");
mca_nmi_hook();
} /* mca_handle_nmi */
/*--------------------------------------------------------------------*/
......
......@@ -73,7 +73,7 @@ unsigned long phys_cpu_present_map;
* Intel MP BIOS table parsing routines:
*/
#ifndef CONFIG_X86_VISWS_APIC
/*
* Checksum an MP configuration block.
*/
......@@ -737,7 +737,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
return 0;
}
void __init find_intel_smp (void)
void __init find_smp_config (void)
{
unsigned int address;
......@@ -777,40 +777,6 @@ void __init find_intel_smp (void)
printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n");
}
#else
/*
* The Visual Workstation is Intel MP compliant in the hardware
* sense, but it doesn't have a BIOS(-configuration table).
* No problem for Linux.
*/
void __init find_visws_smp(void)
{
smp_found_config = 1;
phys_cpu_present_map |= 2; /* or in id 1 */
apic_version[1] |= 0x10; /* integrated APIC */
apic_version[0] |= 0x10;
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
}
#endif
/*
* - Intel MP Configuration Table
* - or SGI Visual Workstation configuration
*/
void __init find_smp_config (void)
{
#ifdef CONFIG_X86_LOCAL_APIC
find_intel_smp();
#endif
#ifdef CONFIG_VISWS
find_visws_smp();
#endif
}
/* --------------------------------------------------------------------------
ACPI-based MP Configuration
......
......@@ -66,11 +66,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
*/
void (*pm_idle)(void);
/*
* Power off function, if any
*/
void (*pm_power_off)(void);
void disable_hlt(void)
{
hlt_counter++;
......@@ -160,282 +155,6 @@ static int __init idle_setup (char *str)
__setup("idle=", idle_setup);
static long no_idt[2];
static int reboot_mode;
int reboot_thru_bios;
#ifdef CONFIG_SMP
int reboot_smp = 0;
static int reboot_cpu = -1;
/* shamelessly grabbed from lib/vsprintf.c for readability */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
#endif
static int __init reboot_setup(char *str)
{
while(1) {
switch (*str) {
case 'w': /* "warm" reboot (no memory testing etc) */
reboot_mode = 0x1234;
break;
case 'c': /* "cold" reboot (with memory testing etc) */
reboot_mode = 0x0;
break;
case 'b': /* "bios" reboot by jumping through the BIOS */
reboot_thru_bios = 1;
break;
case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
reboot_thru_bios = 0;
break;
#ifdef CONFIG_SMP
case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
reboot_smp = 1;
if (is_digit(*(str+1))) {
reboot_cpu = (int) (*(str+1) - '0');
if (is_digit(*(str+2)))
reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
}
/* we will leave sorting out the final value
when we are ready to reboot, since we might not
have set up boot_cpu_id or smp_num_cpu */
break;
#endif
}
if((str = strchr(str,',')) != NULL)
str++;
else
break;
}
return 1;
}
__setup("reboot=", reboot_setup);
/* The following code and data reboots the machine by switching to real
mode and jumping to the BIOS reset entry point, as if the CPU has
really been reset. The previous version asked the keyboard
controller to pulse the CPU reset line, which is more thorough, but
doesn't work with at least one type of 486 motherboard. It is easy
to stop this code working; hence the copious comments. */
static unsigned long long
real_mode_gdt_entries [3] =
{
0x0000000000000000ULL, /* Null descriptor */
0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
};
static struct
{
unsigned short size __attribute__ ((packed));
unsigned long long * base __attribute__ ((packed));
}
real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
real_mode_idt = { 0x3ff, 0 };
/* This is 16-bit protected mode code to disable paging and the cache,
switch to real mode and jump to the BIOS reset code.
The instruction that switches to real mode by writing to CR0 must be
followed immediately by a far jump instruction, which set CS to a
valid value for real mode, and flushes the prefetch queue to avoid
running instructions that have already been decoded in protected
mode.
Clears all the flags except ET, especially PG (paging), PE
(protected-mode enable) and TS (task switch for coprocessor state
save). Flushes the TLB after paging has been disabled. Sets CD and
NW, to disable the cache on a 486, and invalidates the cache. This
is more like the state of a 486 after reset. I don't know if
something else should be done for other chips.
More could be done here to set up the registers as if a CPU reset had
occurred; hopefully real BIOSs don't assume much. */
static unsigned char real_mode_switch [] =
{
0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax */
0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */
0x66, 0x0f, 0x22, 0xd8, /* movl %eax,%cr3 */
0x66, 0x0f, 0x20, 0xc3, /* movl %cr0,%ebx */
0x66, 0x81, 0xe3, 0x00, 0x00, 0x00, 0x60, /* andl $0x60000000,%ebx */
0x74, 0x02, /* jz f */
0x0f, 0x08, /* invd */
0x24, 0x10, /* f: andb $0x10,al */
0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
};
static unsigned char jump_to_bios [] =
{
0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
};
static inline void kb_wait(void)
{
int i;
for (i=0; i<0x10000; i++)
if ((inb_p(0x64) & 0x02) == 0)
break;
}
/*
* Switch to real mode and then execute the code
* specified by the code and length parameters.
* We assume that length will aways be less that 100!
*/
void machine_real_restart(unsigned char *code, int length)
{
unsigned long flags;
local_irq_disable();
/* Write zero to CMOS register number 0x0f, which the BIOS POST
routine will recognize as telling it to do a proper reboot. (Well
that's what this book in front of me says -- it may only apply to
the Phoenix BIOS though, it's not clear). At the same time,
disable NMIs by setting the top bit in the CMOS address register,
as we're about to do peculiar things to the CPU. I'm not sure if
`outb_p' is needed instead of just `outb'. Use it to be on the
safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
*/
spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(0x00, 0x8f);
spin_unlock_irqrestore(&rtc_lock, flags);
/* Remap the kernel at virtual address zero, as well as offset zero
from the kernel segment. This assumes the kernel segment starts at
virtual address PAGE_OFFSET. */
memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
/*
* Use `swapper_pg_dir' as our page directory.
*/
load_cr3(swapper_pg_dir);
/* Write 0x1234 to absolute memory location 0x472. The BIOS reads
this on booting to tell it to "Bypass memory test (also warm
boot)". This seems like a fairly standard thing that gets set by
REBOOT.COM programs, and the previous reset routine did this
too. */
*((unsigned short *)0x472) = reboot_mode;
/* For the switch to real mode, copy some code to low memory. It has
to be in the first 64k because it is running in 16-bit mode, and it
has to have the same physical and virtual address, because it turns
off paging. Copy it near the end of the first page, out of the way
of BIOS variables. */
memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
real_mode_switch, sizeof (real_mode_switch));
memcpy ((void *) (0x1000 - 100), code, length);
/* Set up the IDT for real mode. */
__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));
/* Set up a GDT from which we can load segment descriptors for real
mode. The GDT is not used in real mode; it is just needed here to
prepare the descriptors. */
__asm__ __volatile__ ("lgdt %0" : : "m" (real_mode_gdt));
/* Load the data segment registers, and thus the descriptors ready for
real mode. The base address of each segment is 0x100, 16 times the
selector value being loaded here. This is so that the segment
registers don't have to be reloaded after switching to real mode:
the values are consistent for real mode operation already. */
__asm__ __volatile__ ("movl $0x0010,%%eax\n"
"\tmovl %%eax,%%ds\n"
"\tmovl %%eax,%%es\n"
"\tmovl %%eax,%%fs\n"
"\tmovl %%eax,%%gs\n"
"\tmovl %%eax,%%ss" : : : "eax");
/* Jump to the 16-bit code that we copied earlier. It disables paging
and the cache, switches to real mode, and jumps to the BIOS reset
entry point. */
__asm__ __volatile__ ("ljmp $0x0008,%0"
:
: "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
}
void machine_restart(char * __unused)
{
#if CONFIG_SMP
int cpuid;
cpuid = GET_APIC_ID(apic_read(APIC_ID));
if (reboot_smp) {
/* check to see if reboot_cpu is valid
if its not, default to the BSP */
if ((reboot_cpu == -1) ||
(reboot_cpu > (NR_CPUS -1)) ||
!(phys_cpu_present_map & (1<<cpuid)))
reboot_cpu = boot_cpu_physical_apicid;
reboot_smp = 0; /* use this as a flag to only go through this once*/
/* re-run this function on the other CPUs
it will fall though this section since we have
cleared reboot_smp, and do the reboot if it is the
correct CPU, otherwise it halts. */
if (reboot_cpu != cpuid)
smp_call_function((void *)machine_restart , NULL, 1, 0);
}
/* if reboot_cpu is still -1, then we want a tradional reboot,
and if we are not running on the reboot_cpu,, halt */
if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
for (;;)
__asm__ __volatile__ ("hlt");
}
/*
* Stop all CPUs and turn off local APICs and the IO-APIC, so
* other OSs see a clean IRQ state.
*/
smp_send_stop();
disable_IO_APIC();
#endif
if(!reboot_thru_bios) {
/* rebooting needs to touch the page at absolute addr 0 */
*((unsigned short *)__va(0x472)) = reboot_mode;
for (;;) {
int i;
for (i=0; i<100; i++) {
kb_wait();
udelay(50);
outb(0xfe,0x64); /* pulse reset low */
udelay(50);
}
/* That didn't work - force a triple fault.. */
__asm__ __volatile__("lidt %0": :"m" (no_idt));
__asm__ __volatile__("int3");
}
}
machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
}
void machine_halt(void)
{
}
void machine_power_off(void)
{
if (pm_power_off)
pm_power_off();
}
extern void show_trace(unsigned long* esp);
void show_regs(struct pt_regs * regs)
......
This diff is collapsed.
......@@ -37,6 +37,10 @@
#include <asm/e820.h>
#include <asm/mpspec.h>
#include <asm/setup.h>
#include <asm/arch_hooks.h>
#include "setup_arch_pre.h"
static inline char * __init machine_specific_memory_setup(void);
/*
* Machine setup..
......@@ -470,31 +474,8 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
static void __init setup_memory_region(void)
{
char *who = "BIOS-e820";
/*
* Try to copy the BIOS-supplied E820-map.
*
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
sanitize_e820_map(E820_MAP, &E820_MAP_NR);
if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
unsigned long mem_size;
/* compare results from other methods and take the greater */
if (ALT_MEM_K < EXT_MEM_K) {
mem_size = EXT_MEM_K;
who = "BIOS-88";
} else {
mem_size = ALT_MEM_K;
who = "BIOS-e801";
}
char *who = machine_specific_memory_setup();
e820.nr_map = 0;
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
}
printk(KERN_INFO "BIOS-provided physical RAM map:\n");
print_memory_map(who);
} /* setup_memory_region */
......@@ -757,7 +738,7 @@ static unsigned long __init setup_memory(void)
*/
acpi_reserve_bootmem();
#endif
#ifdef CONFIG_X86_LOCAL_APIC
#ifdef CONFIG_X86_FIND_SMP_CONFIG
/*
* Find and reserve possible boot-time SMP configuration:
*/
......@@ -838,12 +819,9 @@ void __init setup_arch(char **cmdline_p)
{
unsigned long max_low_pfn;
pre_setup_arch_hook();
early_cpu_init();
#ifdef CONFIG_VISWS
visws_get_board_type_and_rev();
#endif
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO;
screen_info = SCREEN_INFO;
......@@ -863,6 +841,7 @@ void __init setup_arch(char **cmdline_p)
rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif
ARCH_SETUP
setup_memory_region();
if (!MOUNT_ROOT_RDONLY)
......@@ -922,6 +901,8 @@ static int __init highio_setup(char *str)
}
__setup("nohighio", highio_setup);
#include "setup_arch_post.h"
/*
* Local Variables:
* mode:c
......
......@@ -48,6 +48,9 @@
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/smpboot.h>
#include <asm/desc.h>
#include <asm/arch_hooks.h>
#include "smpboot_hooks.h"
/* Set if we find a B stepping CPU */
static int __initdata smp_b_stepping;
......@@ -1003,9 +1006,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
*/
if (!smp_found_config) {
printk(KERN_NOTICE "SMP motherboard not detected.\n");
#ifndef CONFIG_VISWS
io_apic_irqs = 0;
#endif
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = 1;
if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected."
......@@ -1032,9 +1033,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
boot_cpu_physical_apicid);
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
#ifndef CONFIG_VISWS
io_apic_irqs = 0;
#endif
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = 1;
return;
}
......@@ -1047,9 +1046,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
if (!max_cpus) {
smp_found_config = 0;
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
#ifndef CONFIG_VISWS
io_apic_irqs = 0;
#endif
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = 1;
return;
}
......@@ -1106,22 +1103,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
/*
* Cleanup possible dangling ends...
*/
#ifndef CONFIG_VISWS
{
/*
* Install writable page 0 entry to set BIOS data area.
*/
local_flush_tlb();
/*
* Paranoid: Set warm reset code and vector here back
* to default values.
*/
CMOS_WRITE(0, 0xf);
*((volatile long *) phys_to_virt(0x467)) = 0;
}
#endif
smpboot_setup_warm_reset_vector();
/*
* Allow the user to impress friends.
......@@ -1173,15 +1155,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
}
}
}
#ifndef CONFIG_VISWS
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up:
*/
if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
#endif
smpboot_setup_io_apic();
setup_boot_APIC_clock();
......@@ -1220,3 +1195,29 @@ void __init smp_cpus_done(unsigned int max_cpus)
{
zap_low_mappings();
}
void __init smp_intr_init()
{
/*
* IRQ0 must be given a fixed assignment and initialized,
* because it's used before the IO-APIC is set up.
*/
set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
/*
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
*/
set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
/* IPI for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
/* thermal monitor LVT interrupt */
#ifdef CONFIG_X86_MCE_P4THERMAL
set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
#endif
}
......@@ -57,8 +57,11 @@
#include <linux/timex.h>
#include <linux/config.h>
#include <asm/fixmap.h>
#include <asm/cobalt.h>
#include <asm/arch_hooks.h>
extern spinlock_t i8259A_lock;
#include "do_timer.h"
/*
* for x86_do_profile()
......@@ -120,8 +123,6 @@ static inline unsigned long do_fast_gettimeoffset(void)
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(i8253_lock);
extern spinlock_t i8259A_lock;
#ifndef CONFIG_X86_TSC
/* This function must be called with interrupts disabled
......@@ -202,47 +203,11 @@ static unsigned long do_slow_gettimeoffset(void)
* (see c't 95/10 page 335 for Neptun bug.)
*/
/* you can safely undefine this if you don't have the Neptune chipset */
#define BUGGY_NEPTUN_TIMER
if( jiffies_t == jiffies_p ) {
if( count > count_p ) {
/* the nutcase */
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
#ifdef BUGGY_NEPTUN_TIMER
/*
* for the Neptun bug we know that the 'latch'
* command doesnt latch the high and low value
* of the counter atomically. Thus we have to
* substract 256 from the counter
* ... funny, isnt it? :)
*/
count -= 256;
#else
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
#endif
}
count = do_timer_overflow(count);
}
} else
jiffies_p = jiffies_t;
......@@ -413,23 +378,7 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
}
#endif
#ifdef CONFIG_VISWS
/* Clear the interrupt */
co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
#endif
do_timer(regs);
/*
* In the SMP case we use the local APIC timer interrupt to do the
* profiling, except when we simulate SMP mode on a uniprocessor
* system, in that case we have to call the local interrupt handler.
*/
#ifndef CONFIG_X86_LOCAL_APIC
if (!user_mode(regs))
x86_do_profile(regs->eip);
#else
if (!using_apic_timer)
smp_local_timer_interrupt(regs);
#endif
do_timer_interrupt_hook(regs);
/*
* If we have an externally synchronized Linux clock, then update
......@@ -470,7 +419,7 @@ static int use_tsc;
* Time Stamp Counter value at the time of the timer interrupt, so that
* we later on can estimate the time of day more exactly.
*/
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int count;
......@@ -560,8 +509,6 @@ unsigned long get_cmos_time(void)
return mktime(year, mon, day, hour, min, sec);
}
static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
/* ------ Calibrate the TSC -------
* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
* Too much 64-bit arithmetic here to do this cleanly in C, and for
......@@ -574,6 +521,7 @@ static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NUL
#define CALIBRATE_LATCH (5 * LATCH)
#define CALIBRATE_TIME (5 * 1000020/HZ)
#ifdef CONFIG_X86_TSC
static unsigned long __init calibrate_tsc(void)
{
/* Set the Gate high, disable speaker */
......@@ -638,6 +586,7 @@ static unsigned long __init calibrate_tsc(void)
bad_ctc:
return 0;
}
#endif /* CONFIG_X86_TSC */
static struct device device_i8253 = {
.name = "i8253",
......@@ -653,7 +602,9 @@ __initcall(time_init_driverfs);
void __init time_init(void)
{
#ifdef CONFIG_X86_TSC
extern int x86_udelay_tsc;
#endif
xtime.tv_sec = get_cmos_time();
xtime.tv_nsec = 0;
......@@ -672,6 +623,7 @@ void __init time_init(void)
* to disk; this won't break the kernel, though, 'cuz we're
* smart. See arch/i386/kernel/apm.c.
*/
#ifdef CONFIG_X86_TSC
/*
* Firstly we have to do a CPU check for chips with
* a potentially buggy TSC. At this point we haven't run
......@@ -712,22 +664,7 @@ void __init time_init(void)
}
}
}
#endif /* CONFIG_X86_TSC */
#ifdef CONFIG_VISWS
printk("Starting Cobalt Timer system clock\n");
/* Set the countdown value */
co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
/* Start the timer */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
/* Enable (unmask) the timer interrupt */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
/* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
setup_irq(CO_IRQ_TIMER, &irq0);
#else
setup_irq(0, &irq0);
#endif
time_init_hook();
}
......@@ -43,12 +43,7 @@
#include <asm/smp.h>
#include <asm/pgalloc.h>
#ifdef CONFIG_X86_VISWS_APIC
#include <asm/fixmap.h>
#include <asm/cobalt.h>
#include <asm/lithium.h>
#endif
#include <asm/arch_hooks.h>
#include <linux/irq.h>
#include <linux/module.h>
......@@ -840,96 +835,6 @@ static void __init set_call_gate(void *a, void *addr)
_set_gate(a,12,3,addr);
}
#ifdef CONFIG_X86_VISWS_APIC
/*
* On Rev 005 motherboards legacy device interrupt lines are wired directly
* to Lithium from the 307. But the PROM leaves the interrupt type of each
* 307 logical device set appropriate for the 8259. Later we'll actually use
* the 8259, but for now we have to flip the interrupt types to
* level triggered, active lo as required by Lithium.
*/
#define REG 0x2e /* The register to read/write */
#define DEV 0x07 /* Register: Logical device select */
#define VAL 0x2f /* The value to read/write */
static void
superio_outb(int dev, int reg, int val)
{
outb(DEV, REG);
outb(dev, VAL);
outb(reg, REG);
outb(val, VAL);
}
static int __attribute__ ((unused))
superio_inb(int dev, int reg)
{
outb(DEV, REG);
outb(dev, VAL);
outb(reg, REG);
return inb(VAL);
}
#define FLOP 3 /* floppy logical device */
#define PPORT 4 /* parallel logical device */
#define UART5 5 /* uart2 logical device (not wired up) */
#define UART6 6 /* uart1 logical device (THIS is the serial port!) */
#define IDEST 0x70 /* int. destination (which 307 IRQ line) reg. */
#define ITYPE 0x71 /* interrupt type register */
/* interrupt type bits */
#define LEVEL 0x01 /* bit 0, 0 == edge triggered */
#define ACTHI 0x02 /* bit 1, 0 == active lo */
static void
superio_init(void)
{
if (visws_board_type == VISWS_320 && visws_board_rev == 5) {
superio_outb(UART6, IDEST, 0); /* 0 means no intr propagated */
printk("SGI 320 rev 5: disabling 307 uart1 interrupt\n");
}
}
static void
lithium_init(void)
{
set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
printk("Lithium PCI Bridge A, Bus Number: %d\n",
li_pcia_read16(LI_PCI_BUSNUM) & 0xff);
set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
printk("Lithium PCI Bridge B (PIIX4), Bus Number: %d\n",
li_pcib_read16(LI_PCI_BUSNUM) & 0xff);
/* XXX blindly enables all interrupts */
li_pcia_write16(LI_PCI_INTEN, 0xffff);
li_pcib_write16(LI_PCI_INTEN, 0xffff);
}
static void
cobalt_init(void)
{
/*
* On normal SMP PC this is used only with SMP, but we have to
* use it and set it up here to start the Cobalt clock
*/
set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
printk("Local APIC ID %lx\n", apic_read(APIC_ID));
printk("Local APIC Version %lx\n", apic_read(APIC_LVR));
set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
printk("Cobalt Revision %lx\n", co_cpu_read(CO_CPU_REV));
set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
printk("Cobalt APIC ID %lx\n", co_apic_read(CO_APIC_ID));
/* Enable Cobalt APIC being careful to NOT change the ID! */
co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID)|CO_APIC_ENABLE);
printk("Cobalt APIC enabled: ID reg %lx\n", co_apic_read(CO_APIC_ID));
}
#endif
#ifdef CONFIG_EISA
int EISA_bus;
......@@ -985,9 +890,5 @@ void __init trap_init(void)
*/
cpu_init();
#ifdef CONFIG_X86_VISWS_APIC
superio_init();
lithium_init();
cobalt_init();
#endif
trap_init_hook();
}
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
EXTRA_CFLAGS += -I../kernel
export-objs :=
obj-y := setup.o
include $(TOPDIR)/Rules.make
/* defines for inline arch setup functions */
/**
* do_timer_interrupt_hook - hook into timer tick
* @regs: standard registers from interrupt
*
* Description:
* This hook is called immediately after the timer interrupt is ack'd.
* It's primary purpose is to allow architectures that don't possess
* individual per CPU clocks (like the CPU APICs supply) to broadcast the
* timer interrupt as a means of triggering reschedules etc.
**/
static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
do_timer(regs);
/*
* In the SMP case we use the local APIC timer interrupt to do the
* profiling, except when we simulate SMP mode on a uniprocessor
* system, in that case we have to call the local interrupt handler.
*/
#ifndef CONFIG_X86_LOCAL_APIC
if (!user_mode(regs))
x86_do_profile(regs->eip);
#else
if (!using_apic_timer)
smp_local_timer_interrupt(regs);
#endif
}
/* you can safely undefine this if you don't have the Neptune chipset */
#define BUGGY_NEPTUN_TIMER
/**
* do_timer_overflow - process a detected timer overflow condition
* @count: hardware timer interrupt count on overflow
*
* Description:
* This call is invoked when the jiffies count has not incremented but
* the hardware timer interrupt has. It means that a timer tick interrupt
* came along while the previous one was pending, thus a tick was missed
**/
static inline int do_timer_overflow(int count)
{
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
#ifdef BUGGY_NEPTUN_TIMER
/*
* for the Neptun bug we know that the 'latch'
* command doesnt latch the high and low value
* of the counter atomically. Thus we have to
* substract 256 from the counter
* ... funny, isnt it? :)
*/
count -= 256;
#else
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
#endif
}
return count;
}
/*
* This file is designed to contain the BUILD_INTERRUPT specifications for
* all of the extra named interrupt vectors used by the architecture.
* Usually this is the Inter Process Interrupts (IPIs)
*/
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent for them, they are triggered
* through the ICC by us (IPIs)
*/
#ifdef CONFIG_X86_SMP
BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
#endif
/*
* every pentium local APIC has two 'local interrupts', with a
* soft-definable vector attached to both interrupts, one of
* which is a timer interrupt, the other one is error counter
* overflow. Linux uses the local APIC timer interrupt to get
* a much simpler SMP time architecture:
*/
#ifdef CONFIG_X86_LOCAL_APIC
BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
#ifdef CONFIG_X86_MCE_P4THERMAL
BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
#endif
#endif
/*
* This file should contain #defines for all of the interrupt vector
* numbers used by this architecture.
*
* In addition, there are some standard defines:
*
* FIRST_EXTERNAL_VECTOR:
* The first free place for external interrupts
*
* SYSCALL_VECTOR:
* The IRQ vector a syscall makes the user to kernel transition
* under.
*
* TIMER_IRQ:
* The IRQ number the timer interrupt comes in at.
*
* NR_IRQS:
* The total number of interrupt vectors (including all the
* architecture specific interrupts) needed.
*
*/
#ifndef _ASM_IRQ_VECTORS_H
#define _ASM_IRQ_VECTORS_H
/*
* IDT vectors usable for external interrupt sources start
* at 0x20:
*/
#define FIRST_EXTERNAL_VECTOR 0x20
#define SYSCALL_VECTOR 0x80
/*
* Vectors 0x20-0x2f are used for ISA interrupts.
*/
/*
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
*
* some of the following vectors are 'rare', they are merged
* into a single vector (CALL_FUNCTION_VECTOR) to save vector space.
* TLB, reschedule and local APIC vectors are performance-critical.
*
* Vectors 0xf0-0xfa are free (reserved for future Linux use).
*/
#define SPURIOUS_APIC_VECTOR 0xff
#define ERROR_APIC_VECTOR 0xfe
#define INVALIDATE_TLB_VECTOR 0xfd
#define RESCHEDULE_VECTOR 0xfc
#define CALL_FUNCTION_VECTOR 0xfb
#define THERMAL_APIC_VECTOR 0xf0
/*
* Local APIC timer IRQ vector is on a different priority level,
* to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata.
*/
#define LOCAL_TIMER_VECTOR 0xef
/*
* First APIC vector available to drivers: (vectors 0x30-0xee)
* we start at 0x31 to spread out vectors evenly between priority
* levels. (0x80 is the syscall vector)
*/
#define FIRST_DEVICE_VECTOR 0x31
#define FIRST_SYSTEM_VECTOR 0xef
#define TIMER_IRQ 0
/*
* 16 8259A IRQ's, 208 potential APIC interrupt sources.
* Right now the APIC is mostly only used for SMP.
* 256 vectors is an architectural limit. (we can have
* more than 256 devices theoretically, but they will
* have to use shared interrupts)
* Since vectors 0x00-0x1f are used/reserved for the CPU,
* the usable vector space is 0x20-0xff (224 vectors)
*/
#ifdef CONFIG_X86_IO_APIC
#define NR_IRQS 224
#else
#define NR_IRQS 16
#endif
#endif /* _ASM_IRQ_VECTORS_H */
/*
* Machine specific setup for generic
*/
#include <linux/config.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/arch_hooks.h>
/**
* pre_intr_init_hook - initialisation prior to setting up interrupt vectors
*
* Description:
* Perform any necessary interrupt initialisation prior to setting up
* the "ordinary" interrupt call gates. For legacy reasons, the ISA
* interrupts should be initialised here if the machine emulates a PC
* in any way.
**/
void __init pre_intr_init_hook(void)
{
init_ISA_irqs();
}
/*
* IRQ2 is cascade interrupt to second interrupt controller
*/
static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL};
/**
* intr_init_hook - post gate setup interrupt initialisation
*
* Description:
* Fill in any interrupts that may have been left out by the general
* init_IRQ() routine. interrupts having to do with the machine rather
* than the devices on the I/O bus (like APIC interrupts in intel MP
* systems) are started here.
**/
void __init intr_init_hook(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
apic_intr_init();
#endif
setup_irq(2, &irq2);
}
/**
* pre_setup_arch_hook - hook called prior to any setup_arch() execution
*
* Description:
* generally used to activate any machine specific identification
* routines that may be needed before setup_arch() runs. On VISWS
* this is used to get the board revision and type.
**/
void __init pre_setup_arch_hook(void)
{
}
/**
* trap_init_hook - initialise system specific traps
*
* Description:
* Called as the final act of trap_init(). Used in VISWS to initialise
* the various board specific APIC traps.
**/
void __init trap_init_hook(void)
{
}
static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
/**
* time_init_hook - do any specific initialisations for the system timer.
*
* Description:
* Must plug the system timer interrupt source at HZ into the IRQ listed
* in irq_vectors.h:TIMER_IRQ
**/
void __init time_init_hook(void)
{
setup_irq(0, &irq0);
}
#ifdef CONFIG_MCA
/**
* mca_nmi_hook - hook into MCA specific NMI chain
*
* Description:
* The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources
* along the MCA bus. Use this to hook into that chain if you will need
* it.
**/
void __init mca_nmi_hook(void)
{
/* If I recall correctly, there's a whole bunch of other things that
* we can do to check for NMI problems, but that's all I know about
* at the moment.
*/
printk("NMI generated from unknown source!\n");
}
#endif
/**
* machine_specific_memory_setup - Hook for machine specific memory setup.
*
* Description:
* This is included late in kernel/setup.c so that it can make
* use of all of the static functions.
**/
static inline char * __init machine_specific_memory_setup(void)
{
char *who;
who = "BIOS-e820";
/*
* Try to copy the BIOS-supplied E820-map.
*
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
sanitize_e820_map(E820_MAP, &E820_MAP_NR);
if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
unsigned long mem_size;
/* compare results from other methods and take the greater */
if (ALT_MEM_K < EXT_MEM_K) {
mem_size = EXT_MEM_K;
who = "BIOS-88";
} else {
mem_size = ALT_MEM_K;
who = "BIOS-e801";
}
e820.nr_map = 0;
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
}
return who;
}
/* Hook to call BIOS initialisation function */
/* no action for generic */
#define ARCH_SETUP
/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
* which needs to alter them. */
static inline void smpboot_clear_io_apic_irqs(void)
{
io_apic_irqs = 0;
}
static inline void smpboot_setup_warm_reset_vector(void)
{
/*
* Install writable page 0 entry to set BIOS data area.
*/
local_flush_tlb();
/*
* Paranoid: Set warm reset code and vector here back
* to default values.
*/
CMOS_WRITE(0, 0xf);
*((volatile long *) phys_to_virt(0x467)) = 0;
}
static inline void smpboot_setup_io_apic(void)
{
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up:
*/
if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
}
#
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
.S.o:
$(CC) $(AFLAGS) -traditional -c $< -o $*.o
all: mach-visws.o
O_TARGET := mach-visws.o
EXTRA_CFLAGS += -I../kernel
export-objs :=
obj-y := setup.o traps.o
obj-$(CONFIG_PCI) += pci-visws.o
obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o
include $(TOPDIR)/Rules.make
/* defines for inline arch setup functions */
#include <asm/fixmap.h>
#include <asm/cobalt.h>
static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
/* Clear the interrupt */
co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
do_timer(regs);
/*
* In the SMP case we use the local APIC timer interrupt to do the
* profiling, except when we simulate SMP mode on a uniprocessor
* system, in that case we have to call the local interrupt handler.
*/
#ifndef CONFIG_X86_LOCAL_APIC
if (!user_mode(regs))
x86_do_profile(regs->eip);
#else
if (!using_apic_timer)
smp_local_timer_interrupt(regs);
#endif
}
static inline int do_timer_overflow(int count)
{
int i;
spin_lock(&i8259A_lock);
/*
* This is tricky when I/O APICs are used;
* see do_timer_interrupt().
*/
i = inb(0x20);
spin_unlock(&i8259A_lock);
/* assumption about timer being IRQ0 */
if (i & 0x01) {
/*
* We cannot detect lost timer interrupts ...
* well, that's why we call them lost, don't we? :)
* [hmm, on the Pentium and Alpha we can ... sort of]
*/
count -= LATCH;
} else {
printk("do_slow_gettimeoffset(): hardware timer problem?\n");
}
return count;
}
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent for them, they are triggered
* through the ICC by us (IPIs)
*/
#ifdef CONFIG_X86_SMP
BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
#endif
/*
* every pentium local APIC has two 'local interrupts', with a
* soft-definable vector attached to both interrupts, one of
* which is a timer interrupt, the other one is error counter
* overflow. Linux uses the local APIC timer interrupt to get
* a much simpler SMP time architecture:
*/
#ifdef CONFIG_X86_LOCAL_APIC
BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
#endif
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/config.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
#include <asm/smp.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
#include <asm/pgalloc.h>
/* Have we found an MP table */
int smp_found_config;
/*
* Various Linux-internal data structures created from the
* MP-table.
*/
int apic_version [MAX_APICS];
int mp_bus_id_to_type [MAX_MP_BUSSES];
int mp_bus_id_to_node [MAX_MP_BUSSES];
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
int mp_current_pci_id;
/* I/O APIC entries */
struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
/* # of MP IRQ source entries */
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
int mp_irq_entries;
int nr_ioapics;
int pic_mode;
unsigned long mp_lapic_addr;
/* Processor that is doing the boot up */
unsigned int boot_cpu_physical_apicid = -1U;
unsigned int boot_cpu_logical_apicid = -1U;
/* Internal processor count */
static unsigned int num_processors;
/* Bitmask of physically existing CPUs */
unsigned long phys_cpu_present_map;
/*
* The Visual Workstation is Intel MP compliant in the hardware
* sense, but it doesn't have a BIOS(-configuration table).
* No problem for Linux.
*/
void __init find_smp_config(void)
{
smp_found_config = 1;
phys_cpu_present_map |= 2; /* or in id 1 */
apic_version[1] |= 0x10; /* integrated APIC */
apic_version[0] |= 0x10;
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
}
......@@ -3,7 +3,15 @@
* Split out from setup.c by davej@suse.de
*/
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/fixmap.h>
#include <asm/cobalt.h>
#include <asm/arch_hooks.h>
#include <asm/io.h>
char visws_board_type = -1;
char visws_board_rev = -1;
......@@ -120,9 +128,43 @@ void __init visws_get_board_type_and_rev(void)
visws_board_rev = raw;
}
printk(KERN_INFO "Silicon Graphics %s (rev %d)\n",
visws_board_type == VISWS_320 ? "320" :
(visws_board_type == VISWS_540 ? "540" :
"unknown"), visws_board_rev);
}
printk(KERN_INFO "Silicon Graphics %s (rev %d)\n",
visws_board_type == VISWS_320 ? "320" :
(visws_board_type == VISWS_540 ? "540" :
"unknown"), visws_board_rev);
}
void __init pre_intr_init_hook(void)
{
init_VISWS_APIC_irqs();
}
void __init intr_init_hook(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
apic_intr_init();
#endif
}
void __init pre_setup_arch_hook()
{
visws_get_board_type_and_rev();
}
static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
void __init time_init_hook(void)
{
printk("Starting Cobalt Timer system clock\n");
/* Set the countdown value */
co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
/* Start the timer */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
/* Enable (unmask) the timer interrupt */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
/* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
setup_irq(CO_IRQ_TIMER, &irq0);
}
/* Hook for machine specific memory setup.
*
* This is included late in kernel/setup.c so that it can make use of all of
* the static functions. */
static inline char * __init machine_specific_memory_setup(void)
{
char *who;
who = "BIOS-e820";
/*
* Try to copy the BIOS-supplied E820-map.
*
* Otherwise fake a memory map; one section from 0k->640k,
* the next section from 1mb->appropriate_mem_k
*/
sanitize_e820_map(E820_MAP, &E820_MAP_NR);
if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
unsigned long mem_size;
/* compare results from other methods and take the greater */
if (ALT_MEM_K < EXT_MEM_K) {
mem_size = EXT_MEM_K;
who = "BIOS-88";
} else {
mem_size = ALT_MEM_K;
who = "BIOS-e801";
}
e820.nr_map = 0;
add_memory_region(0, LOWMEMSIZE(), E820_RAM);
add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
}
return who;
}
/* Hook to call BIOS initialisation function */
/* no action for visws */
#define ARCH_SETUP
/* for visws do nothing for any of these */
static inline void smpboot_clear_io_apic_irqs(void)
{
}
static inline void smpboot_setup_warm_reset_vector(void)
{
}
static inline void smpboot_setup_io_apic(void)
{
}
/* VISWS traps */
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/atomic.h>
#include <asm/debugreg.h>
#include <asm/desc.h>
#include <asm/i387.h>
#include <asm/smp.h>
#include <asm/pgalloc.h>
#include <asm/arch_hooks.h>
#ifdef CONFIG_X86_VISWS_APIC
#include <asm/fixmap.h>
#include <asm/cobalt.h>
#include <asm/lithium.h>
#endif
#ifdef CONFIG_X86_VISWS_APIC
/*
* On Rev 005 motherboards legacy device interrupt lines are wired directly
* to Lithium from the 307. But the PROM leaves the interrupt type of each
* 307 logical device set appropriate for the 8259. Later we'll actually use
* the 8259, but for now we have to flip the interrupt types to
* level triggered, active lo as required by Lithium.
*/
#define REG 0x2e /* The register to read/write */
#define DEV 0x07 /* Register: Logical device select */
#define VAL 0x2f /* The value to read/write */
static void
superio_outb(int dev, int reg, int val)
{
outb(DEV, REG);
outb(dev, VAL);
outb(reg, REG);
outb(val, VAL);
}
static int __attribute__ ((unused))
superio_inb(int dev, int reg)
{
outb(DEV, REG);
outb(dev, VAL);
outb(reg, REG);
return inb(VAL);
}
#define FLOP 3 /* floppy logical device */
#define PPORT 4 /* parallel logical device */
#define UART5 5 /* uart2 logical device (not wired up) */
#define UART6 6 /* uart1 logical device (THIS is the serial port!) */
#define IDEST 0x70 /* int. destination (which 307 IRQ line) reg. */
#define ITYPE 0x71 /* interrupt type register */
/* interrupt type bits */
#define LEVEL 0x01 /* bit 0, 0 == edge triggered */
#define ACTHI 0x02 /* bit 1, 0 == active lo */
static __init void
superio_init(void)
{
if (visws_board_type == VISWS_320 && visws_board_rev == 5) {
superio_outb(UART6, IDEST, 0); /* 0 means no intr propagated */
printk("SGI 320 rev 5: disabling 307 uart1 interrupt\n");
}
}
static __init void
lithium_init(void)
{
set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
printk("Lithium PCI Bridge A, Bus Number: %d\n",
li_pcia_read16(LI_PCI_BUSNUM) & 0xff);
set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
printk("Lithium PCI Bridge B (PIIX4), Bus Number: %d\n",
li_pcib_read16(LI_PCI_BUSNUM) & 0xff);
/* XXX blindly enables all interrupts */
li_pcia_write16(LI_PCI_INTEN, 0xffff);
li_pcib_write16(LI_PCI_INTEN, 0xffff);
}
static __init void
cobalt_init(void)
{
/*
* On normal SMP PC this is used only with SMP, but we have to
* use it and set it up here to start the Cobalt clock
*/
set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
printk("Local APIC ID %lx\n", apic_read(APIC_ID));
printk("Local APIC Version %lx\n", apic_read(APIC_LVR));
set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
printk("Cobalt Revision %lx\n", co_cpu_read(CO_CPU_REV));
set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
printk("Cobalt APIC ID %lx\n", co_apic_read(CO_APIC_ID));
/* Enable Cobalt APIC being careful to NOT change the ID! */
co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID)|CO_APIC_ENABLE);
printk("Cobalt APIC enabled: ID reg %lx\n", co_apic_read(CO_APIC_ID));
}
#endif
void __init trap_init_hook()
{
#ifdef CONFIG_X86_VISWS_APIC
superio_init();
lithium_init();
cobalt_init();
#endif
}
obj-y := i386.o
ifdef CONFIG_VISWS
obj-y += visws.o
else
obj-$(CONFIG_PCI_BIOS) += pcbios.o
obj-$(CONFIG_PCI_DIRECT) += direct.o
......@@ -20,6 +16,5 @@ obj-y += legacy.o
endif # CONFIG_MULTIQUAD
obj-y += irq.o common.o
endif # CONFIG_VISWS
include $(TOPDIR)/Rules.make
# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:19 cort
#
#
# Makefile for the linux MPC8xx ppc-specific parts of comm processor
#
......
/*
* BK Id: SCCS/s.commproc.c 1.10 10/16/01 16:21:52 trini
*/
/*
* General Purpose functions for the global management of the
* 8260 Communication Processor Module.
......
/*
* BK Id: SCCS/s.enet.c 1.9 09/14/01 18:01:16 trini
*/
/*
* Ethernet driver for Motorola MPC8260.
* Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Fast Ethernet Controller (FCC) driver for Motorola MPC8260.
* Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net)
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* UART driver for MPC8260 CPM SCC or SMC
* Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
......
# BK Id: %F% %I% %G% %U% %#%
#
#
# Makefile for the linux MPC8xx ppc-specific parts of comm processor
#
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* General Purpose functions for the global management of the
* Communication Processor Module.
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Ethernet driver for Motorola MPC8xx.
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* UART driver for MPC860 CPM SCC or SMC
* Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
......
# BK Id: %F% %I% %G% %U% %#%
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
# for "archclean" and "archdep" for cleaning up and making dependencies for
......@@ -24,9 +22,8 @@ endif
LDFLAGS_vmlinux = -Ttext $(KERNELLOAD) -Bstatic
CPPFLAGS := $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH)
AFLAGS := $(AFLAGS) -I$(TOPDIR)/arch/$(ARCH)
CFLAGS := $(CFLAGS) -I$(TOPDIR)/arch/$(ARCH) -fsigned-char \
-msoft-float -pipe -ffixed-r2 -Wno-uninitialized \
-mmultiple -mstring
CFLAGS := $(CFLAGS) -I$(TOPDIR)/arch/$(ARCH) -msoft-float -pipe \
-ffixed-r2 -Wno-uninitialized -mmultiple -mstring
CPP = $(CC) -E $(CFLAGS)
ifdef CONFIG_4xx
......@@ -100,6 +97,8 @@ endif
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm
AFLAGS_vmlinux.lds.o := -Upowerpc
# All the instructions talk about "make bzImage".
bzImage: zImage
......
# BK Id: %F% %I% %G% %U% %#%
#
#
# Makefile for Linux arch/m68k/amiga source directory
#
......
/*
* BK Id: SCCS/s.amiga_ksyms.c 1.5 05/17/01 18:14:20 cort
*/
#include "../../m68k/amiga/amiga_ksyms.c"
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code
* arch/ppc/amiga/amiints.c -- Amiga Linux interrupt handling code
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
......
/*
* BK Id: SCCS/s.amisound.c 1.5 05/17/01 18:14:20 cort
*/
#include "../../m68k/amiga/amisound.c"
/*
* BK Id: SCCS/s.bootinfo.c 1.5 05/17/01 18:14:20 cort
*/
/*
* linux/arch/ppc/amiga/bootinfo.c
* arch/ppc/amiga/bootinfo.c
*
* Extracted from arch/m68k/kernel/setup.c.
* Should be properly generalized and put somewhere else.
......
/*
* BK Id: SCCS/s.chipram.c 1.7 05/21/01 00:49:49 cort
*/
#include "../../m68k/amiga/chipram.c"
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* linux/arch/m68k/amiga/cia.c - CIA support
* arch/ppc/amiga/cia.c - CIA support
*
* Copyright (C) 1996 Roman Zippel
*
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
#define m68k_debug_device debug_device
/*
* linux/arch/m68k/amiga/config.c
* arch/ppc/amiga/config.c
*
* Copyright (C) 1993 Hamish Macdonald
*
......
/*
* BK Id: SCCS/s.ints.c 1.5 05/17/01 18:14:20 cort
*/
/*
* linux/arch/ppc/amiga/ints.c
* arch/ppc/amiga/ints.c
*
* Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c
* Needed to drive the m68k emulating IRQ hardware on the PowerUp boards.
......
/*
* BK Id: SCCS/s.pcmcia.c 1.5 05/17/01 18:14:20 cort
*/
#include "../../m68k/amiga/pcmcia.c"
/*
* BK Id: SCCS/s.time.c 1.5 05/17/01 18:14:20 cort
*/
#include <linux/config.h> /* CONFIG_HEARTBEAT */
#include <linux/errno.h>
#include <linux/sched.h>
......
......@@ -28,7 +28,7 @@ images/vmlinux.gz: $(TOPDIR)/vmlinux
# Subdirs and tools needed for each. Assume we always need to go into
# 'simple' unless told otherwise.
subdir-y := lib common simple
subdir-$(CONFIG_ALL_PPC) := chrp pmac prep
subdir-$(CONFIG_ALL_PPC) := openfirmware prep
tools-$(CONFIG_ALL_PPC) := addnote mknote hack-coff mkprep
tools-$(CONFIG_PPLUS) := mkbugboot mkprep
tools-$(CONFIG_4xx) := mktree
......@@ -47,6 +47,9 @@ NONBOOT := lib common
# These are the subdirs we want to use
BOOTDIRS = $(filter-out $(NONBOOT), $(subdir-y))
makeof1275:
$(MAKE) -C of1275
# This will make the tools we need. We do it like this to ensure that we use
# HOSTCC. -- Tom
maketools:
......@@ -55,7 +58,7 @@ maketools:
# The targets all boards support for boot images.
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
$(BOOT_TARGETS): vmapus lib/lib.a images/vmlinux.gz maketools
$(BOOT_TARGETS): vmapus lib/lib.a images/vmlinux.gz makeof1275 maketools
ifneq ($(BOOTDIRS),)
for d in $(BOOTDIRS); do $(MAKE) -C $$d $@; done
endif
......@@ -80,5 +83,6 @@ vmlinux.sm: $(TOPDIR)/vmlinux utils/addSystemMap
clean:
$(MAKE) -C images clean
$(MAKE) -C utils clean
$(MAKE) -C openfirmware clean
include $(TOPDIR)/Rules.make
# BK Id: %F% %I% %G% %U% %#%
#
# Makefile for making ELF bootable images for booting on CHRP
# using Open Firmware.
#
# Geert Uytterhoeven September 1997
#
# Based on coffboot by Paul Mackerras
LD_ARGS = -T ../ld.script -Ttext 0x00400000
OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o \
../common/ofcommon.o
EXTRA_TARGETS := $(OBJS)
LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
# Utils
ADDNOTE = ../utils/addnote
PIGGYBACK = ../utils/piggyback
ifeq ($(CONFIG_PPC64BRIDGE),y)
END += .64
AFLAGS += -Wa,-mppc64bridge
endif
ifeq ($(CONFIG_SMP),y)
END += .smp
endif
TFTPIMAGE=/tftpboot/zImage.chrp$(END)
all: zImage
znetboot: zImage
cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux$(END)
cp ../images/zImage.chrp $(TFTPIMAGE)
znetboot.initrd: zImage.initrd
cp ../images/zImage.initrd.chrp $(TFTPIMAGE)
floppy: zImage
mcopy zImage a:zImage
image.o: ../images/vmlinux.gz ../common/dummy.o
$(OBJCOPY) ../common/dummy.o $@ \
--add-section=.image=../images/vmlinux.gz \
--set-section-flags=.image=contents,alloc,load,readonly,data
ifdef CONFIG_XMON
$(OBJCOPY) $@ $@ \
--add-section=.sysmap=$(TOPDIR)/System.map \
--set-section-flags=.sysmap=contents,alloc,load,readonly,data
endif
zImage: $(OBJS) $(LIBS) $(ADDNOTE)
$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS)
$(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment -R .ramdisk
cp ../images/$@.chrp ../images/$@.chrp-rs6k
$(ADDNOTE) ../images/$@.chrp-rs6k
zImage.initrd: $(OBJS) $(LIBS) $(ADDNOTE) ../images/ramdisk.image.gz
$(OBJCOPY) image.o image.o \
--add-section=.ramdisk=../images/ramdisk.image.gz \
--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
$(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) $(LIBS)
$(OBJCOPY) ../images/$@.chrp ../images/$@.chrp -R .comment
cp ../images/$@.chrp ../images/$@.chrp-rs6k
$(ADDNOTE) ../images/$@.chrp-rs6k
include $(TOPDIR)/Rules.make
/*
* BK Id: SCCS/s.misc.S 1.6 05/18/01 15:16:59 cort
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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.
*/
.text
/*
* Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000.
*/
.globl setup_bats
setup_bats:
mfpvr 3
rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */
cmpi 0,3,1
lis 4,0x9000
bne 4f
ori 4,4,4 /* set up BAT registers for 601 */
li 5,0x7f
b 5f
4: ori 4,4,0xff /* set up BAT registers for 604 */
li 5,2
mtdbatu 3,4
mtdbatl 3,5
5: mtibatu 3,4
mtibatl 3,5
isync
blr
/*
* Flush the dcache and invalidate the icache for a range of addresses.
*
* flush_cache(addr, len)
*/
.global flush_cache
flush_cache:
addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
rlwinm. 4,4,27,5,31
mtctr 4
beqlr
1: dcbf 0,3
icbi 0,3
addi 3,3,0x20
bdnz 1b
sync
isync
blr
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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 <stdarg.h>
int (*prom)(void *args);
void *chosen_handle;
void *stdin;
void *stdout;
void *stderr;
void exit(void);
void *finddevice(const char *name);
int getprop(void *phandle, const char *name, void *buf, int buflen);
void printk(char *fmt, ...);
extern void chrpboot(int a1, int a2, void *prom);
extern int strlen(const char *s);
void
start(int a1, int a2, void *promptr)
{
prom = promptr;
chosen_handle = finddevice("/chosen");
if (chosen_handle == (void *) -1)
exit();
if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
exit();
stderr = stdout;
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
chrpboot(a1, a2, promptr);
for (;;)
exit();
}
int
write(void *handle, void *ptr, int nb)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *ihandle;
void *addr;
int len;
int actual;
} args;
args.service = "write";
args.nargs = 3;
args.nret = 1;
args.ihandle = handle;
args.addr = ptr;
args.len = nb;
args.actual = -1;
prom(&args);
return args.actual;
}
int
read(void *handle, void *ptr, int nb)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *ihandle;
void *addr;
int len;
int actual;
} args;
args.service = "read";
args.nargs = 3;
args.nret = 1;
args.ihandle = handle;
args.addr = ptr;
args.len = nb;
args.actual = -1;
(*prom)(&args);
return args.actual;
}
void
exit(void)
{
struct prom_args {
char *service;
} args;
for (;;) {
args.service = "exit";
(*prom)(&args);
}
}
void
pause(void)
{
struct prom_args {
char *service;
} args;
args.service = "enter";
(*prom)(&args);
}
void *
finddevice(const char *name)
{
struct prom_args {
char *service;
int nargs;
int nret;
const char *devspec;
void *phandle;
} args;
args.service = "finddevice";
args.nargs = 1;
args.nret = 1;
args.devspec = name;
args.phandle = (void *) -1;
(*prom)(&args);
return args.phandle;
}
void *
claim(unsigned int virt, unsigned int size, unsigned int align)
{
struct prom_args {
char *service;
int nargs;
int nret;
unsigned int virt;
unsigned int size;
unsigned int align;
void *ret;
} args;
args.service = "claim";
args.nargs = 3;
args.nret = 1;
args.virt = virt;
args.size = size;
args.align = align;
(*prom)(&args);
return args.ret;
}
int
getprop(void *phandle, const char *name, void *buf, int buflen)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *phandle;
const char *name;
void *buf;
int buflen;
int size;
} args;
args.service = "getprop";
args.nargs = 4;
args.nret = 1;
args.phandle = phandle;
args.name = name;
args.buf = buf;
args.buflen = buflen;
args.size = -1;
(*prom)(&args);
return args.size;
}
int
putc(int c, void *f)
{
char ch = c;
if (c == '\n')
putc('\r', f);
return write(f, &ch, 1) == 1? c: -1;
}
int
putchar(int c)
{
return putc(c, stdout);
}
int
fputs(char *str, void *f)
{
int n = strlen(str);
return write(f, str, n) == n? 0: -1;
}
int
readchar(void)
{
char ch;
for (;;) {
switch (read(stdin, &ch, 1)) {
case 1:
return ch;
case -1:
printk("read(stdin) returned -1\r\n");
return -1;
}
}
}
static char line[256];
static char *lineptr;
static int lineleft;
int
getchar(void)
{
int c;
if (lineleft == 0) {
lineptr = line;
for (;;) {
c = readchar();
if (c == -1 || c == 4)
break;
if (c == '\r' || c == '\n') {
*lineptr++ = '\n';
putchar('\n');
break;
}
switch (c) {
case 0177:
case '\b':
if (lineptr > line) {
putchar('\b');
putchar(' ');
putchar('\b');
--lineptr;
}
break;
case 'U' & 0x1F:
while (lineptr > line) {
putchar('\b');
putchar(' ');
putchar('\b');
--lineptr;
}
break;
default:
if (lineptr >= &line[sizeof(line) - 1])
putchar('\a');
else {
putchar(c);
*lineptr++ = c;
}
}
}
lineleft = lineptr - line;
lineptr = line;
}
if (lineleft == 0)
return -1;
--lineleft;
return *lineptr++;
}
extern int vsprintf(char *buf, const char *fmt, va_list args);
static char sprint_buf[1024];
void
printk(char *fmt, ...)
{
va_list args;
int n;
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
write(stdout, sprint_buf, n);
}
int
printf(char *fmt, ...)
{
va_list args;
int n;
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
write(stdout, sprint_buf, n);
return n;
}
/*
* arch/ppc/boot/common/cpc700_memory.c
*
* Find memory based upon settings in the CPC700 bridge
*
* Author: Dan Cox
*
* Copyright 2001-2002 MontaVista Software Inc.
*
* 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 <asm/types.h>
#include <asm/io.h>
#include "cpc700.h"
unsigned long
cpc700_get_mem_size(void)
{
int i;
unsigned long len, amt;
/* Start at MB1EA, since MB0EA will most likely be the ending address
for ROM space. */
for(len = 0, i = CPC700_MB1EA; i <= CPC700_MB4EA; i+=4) {
amt = cpc700_read_memreg(i);
if (amt == 0)
break;
len = amt;
}
return len;
}
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/* Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
* Initial Power Macintosh COFF version.
* Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
int main(void)
{
return 0;
......
......@@ -64,6 +64,7 @@ extern char _end[];
extern unsigned long start;
extern int CRT_tstc(void);
extern unsigned long get_mem_size(void);
extern unsigned long serial_init(int chan, void *ignored);
extern void serial_close(unsigned long com_port);
extern void gunzip(void *, int, unsigned char *, int *);
......@@ -75,10 +76,19 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
int timer = 0;
char *cp, ch;
struct bi_record *rec, *birecs;
unsigned long TotalMemory = 0;
serial_fixups();
com_port = serial_init(0, NULL);
#if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4)
/*
* Call get_mem_size(), which is memory controller dependant,
* and we must have the correct file linked in here.
*/
TotalMemory = get_mem_size();
#endif
/* assume the chunk below 8M is free */
end_avail = (char *)0x00800000;
......@@ -194,6 +204,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
rec->size = sizeof(struct bi_record);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
if ( TotalMemory ) {
rec->tag = BI_MEMSIZE;
rec->data[0] = TotalMemory;
rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
rec->tag = BI_CMD_LINE;
memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
......
/*
* arch/ppc/boot/common/mpc10x_common.c
*
* A routine to find out how much memory the machine has.
*
* Based on:
* arch/ppc/kernel/mpc10x_common.c
*
* Author: Mark A. Greer
* mgreer@mvista.com
*
* Copyright 2001-2002 MontaVista Software Inc.
*
* 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/pci.h>
#include <asm/types.h>
#include <asm/io.h>
#include "mpc10x.h"
/*
* *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
*/
/*
* PCI config space macros, similar to indirect_xxx and early_xxx macros.
* We assume bus 0.
*/
#define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr))
#define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val))
#define MPC10X_PCI_OP(rw, size, type, op, mask) \
static void \
mpc10x_##rw##_config_##size(unsigned int *cfg_addr, \
unsigned int *cfg_data, int devfn, int offset, \
type val) \
{ \
out_be32(cfg_addr, \
((offset & 0xfc) << 24) | (devfn << 16) \
| (0 << 8) | 0x80); \
MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \
return; \
}
MPC10X_PCI_OP(read, byte, u8 *, in_8, 3)
MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
/*
* Read the memory controller registers to determine the amount of memory in
* the system. This assumes that the firmware has correctly set up the memory
* controller registers. On CONFIG_ALL_PPC, we know we are being called
* under a PReP memory map. On all other machines, we assume we are under
* a CHRP memory map.
*/
unsigned long
get_mem_size(void)
{
unsigned int *config_addr, *config_data, val;
unsigned long start, end, total, offset;
int i;
unsigned char bank_enables;
#ifdef CONFIG_ALL_PPC
config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR;
config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA;
#else
config_addr = (unsigned int *)MPC10X_MAPB_CNFG_ADDR;
config_data = (unsigned int *)MPC10X_MAPB_CNFG_DATA;
#endif
mpc10x_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0),
MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables);
total = 0;
for (i = 0; i < 8; i++) {
if (bank_enables & (1 << i)) {
offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
mpc10x_read_config_dword(config_addr, config_data,
PCI_DEVFN(0,0), offset, &val);
start = (val >> ((i & 3) << 3)) & 0xff;
offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
mpc10x_read_config_dword(config_addr, config_data,
PCI_DEVFN(0,0), offset, &val);
val = (val >> ((i & 3) << 3)) & 0x03;
start = (val << 28) | (start << 20);
offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
mpc10x_read_config_dword(config_addr, config_data,
PCI_DEVFN(0,0), offset, &val);
end = (val >> ((i & 3) << 3)) & 0xff;
offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
mpc10x_read_config_dword(config_addr, config_data,
PCI_DEVFN(0,0), offset, &val);
val = (val >> ((i & 3) << 3)) & 0x03;
end = (val << 28) | (end << 20) | 0xfffff;
total += (end - start + 1);
}
}
return total;
}
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* COM1 NS16550 support
*/
......
/*
* BK Id: %F% %I% %G% %U% %#%
*
* Copyright (C) Paul Mackerras 1997.
*
* This program is free software; you can redistribute it and/or
......
/*
* BK Id: SCCS/s.string.S 1.8 05/18/01 06:20:29 patch
*/
/*
* String handling functions for PowerPC.
*
......
......@@ -160,11 +160,6 @@ udelay:
blt 2b
3: blr
.globl _put_MSR
_put_MSR:
mtmsr r3
blr
.section ".relocate_code","xa"
/*
* Flush and enable instruction cache
......
#ifndef __PPC_BOOT_CPC700_H
#define __PPC_BOOT_CPC700_H
#define CPC700_MEM_CFGADDR 0xff500008
#define CPC700_MEM_CFGDATA 0xff50000c
#define CPC700_MB0SA 0x38
#define CPC700_MB0EA 0x58
#define CPC700_MB1SA 0x3c
#define CPC700_MB1EA 0x5c
#define CPC700_MB2SA 0x40
#define CPC700_MB2EA 0x60
#define CPC700_MB3SA 0x44
#define CPC700_MB3EA 0x64
#define CPC700_MB4SA 0x48
#define CPC700_MB4EA 0x68
static inline long
cpc700_read_memreg(int reg)
{
out_be32((volatile unsigned int *) CPC700_MEM_CFGADDR, reg);
return in_be32((volatile unsigned int *) CPC700_MEM_CFGDATA);
}
#endif
/*
* arch/ppc/boot/include/mpc10.h
*
* Common defines for the Motorola SPS MPC106/8240/107 Host bridge/Mem
* ctrl/EPIC/etc.
*
* Author: Tom Rini <trini@mvista.com>
*
* This is a heavily stripped down version of:
* include/asm-ppc/mpc10x.h
*
* Author: Mark A. Greer
* mgreer@mvista.com
*
* Copyright 2001-2002 MontaVista Software Inc.
*
* 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.
*/
#ifndef __BOOT_MPC10X_H__
#define __BOOT_MPC10X_H__
/*
* The values here don't completely map everything but should work in most
* cases.
*
* MAP A (PReP Map)
* Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff
* Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff
* PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000
* EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*
* MAP B (CHRP Map)
* Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
* Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
* PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000
* EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
*/
/* Define the type of map to use */
#define MPC10X_MEM_MAP_A 1
#define MPC10X_MEM_MAP_B 2
/* Map A (PReP Map) Defines */
#define MPC10X_MAPA_CNFG_ADDR 0x80000cf8
#define MPC10X_MAPA_CNFG_DATA 0x80000cfc
/* Map B (CHRP Map) Defines */
#define MPC10X_MAPB_CNFG_ADDR 0xfec00000
#define MPC10X_MAPB_CNFG_DATA 0xfee00000
/* Define offsets for the memory controller registers in the config space */
#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */
#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */
#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */
#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */
#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */
#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */
#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */
#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */
#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0
#endif /* __BOOT_MPC10X_H__ */
/*
* BK Id: SCCS/s.nonstdio.h 1.9 07/25/01 18:13:07 trini
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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.
*/
typedef void *prom_handle;
typedef void *ihandle;
typedef void *phandle;
typedef int (*prom_entry)(void *);
#define OF_INVALID_HANDLE ((prom_handle)-1UL)
extern prom_entry of_prom_entry;
/* function declarations */
void * claim(unsigned int virt, unsigned int size, unsigned int align);
void enter(void);
void exit(void);
phandle finddevice(const char *name);
int getprop(phandle node, const char *name, void *buf, int buflen);
void ofinit(prom_entry entry);
int ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr);
int read(ihandle instance, void *buf, int buflen);
void release(void *virt, unsigned int size);
int write(ihandle instance, void *buf, int buflen);
/* inlines */
extern inline void pause(void)
{
enter();
}
/*
* BK Id: SCCS/s.rs6000.h 1.7 05/18/01 15:17:23 cort
*/
/* IBM RS/6000 "XCOFF" file definitions for BFD.
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
FIXME: Can someone provide a transliteration of this name into ASCII?
......
/*
* BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
*/
/*
* This file is derived from zlib.h and zconf.h from the zlib-0.95
* distribution by Jean-loup Gailly and Mark Adler, with some additions
......
......@@ -39,7 +39,7 @@ SECTIONS
PROVIDE (etext = .);
/* Read-write section, merged into data segment: */
. = (. + 0x0FFF) & 0xFFFFF000;
. = ALIGN(8);
.data :
{
*(.data)
......@@ -69,6 +69,7 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
. = ALIGN(8);
__bss_start = .;
.bss :
{
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* This file is derived from various .h and .c files from the zlib-0.95
* distribution by Jean-loup Gailly and Mark Adler, with some additions
......
#
# Makefile of1275 stuff
#
L_TARGET := of1275.a
obj-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o \
ofstdio.o read.o release.o write.o
include $(TOPDIR)/Rules.make
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
void *
claim(unsigned int virt, unsigned int size, unsigned int align)
{
struct prom_args {
char *service;
int nargs;
int nret;
unsigned int virt;
unsigned int size;
unsigned int align;
void *ret;
} args;
args.service = "claim";
args.nargs = 3;
args.nret = 1;
args.virt = virt;
args.size = size;
args.align = align;
(*of_prom_entry)(&args);
return args.ret;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
void
enter(void)
{
struct prom_args {
char *service;
} args;
args.service = "enter";
(*of_prom_entry)(&args);
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
void
exit(void)
{
struct prom_args {
char *service;
} args;
for (;;) {
args.service = "exit";
(*of_prom_entry)(&args);
}
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
phandle
finddevice(const char *name)
{
struct prom_args {
char *service;
int nargs;
int nret;
const char *devspec;
phandle device;
} args;
args.service = "finddevice";
args.nargs = 1;
args.nret = 1;
args.devspec = name;
args.device = OF_INVALID_HANDLE;
(*of_prom_entry)(&args);
return args.device;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
int
getprop(phandle node, const char *name, void *buf, int buflen)
{
struct prom_args {
char *service;
int nargs;
int nret;
phandle node;
const char *name;
void *buf;
int buflen;
int size;
} args;
args.service = "getprop";
args.nargs = 4;
args.nret = 1;
args.node = node;
args.name = name;
args.buf = buf;
args.buflen = buflen;
args.size = -1;
(*of_prom_entry)(&args);
return args.size;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
prom_entry of_prom_entry;
void
ofinit(prom_entry prom_ptr)
{
of_prom_entry = prom_ptr;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
int
ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr)
{
ihandle in, out;
phandle chosen;
if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE)
goto err;
if (getprop(chosen, "stdout", &out, sizeof(out)) != 4)
goto err;
if (getprop(chosen, "stdin", &in, sizeof(in)) != 4)
goto err;
*stdin = in;
*stdout = out;
*stderr = out;
return 0;
err:
return -1;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
int
read(ihandle instance, void *buf, int buflen)
{
struct prom_args {
char *service;
int nargs;
int nret;
ihandle instance;
void *buf;
int buflen;
int actual;
} args;
args.service = "read";
args.nargs = 3;
args.nret = 1;
args.instance = instance;
args.buf = buf;
args.buflen = buflen;
args.actual = -1;
(*of_prom_entry)(&args);
return args.actual;
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
void
release(void *virt, unsigned int size)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *virt;
unsigned int size;
} args;
args.service = "release";
args.nargs = 2;
args.nret = 0;
args.virt = virt;
args.size = size;
(*of_prom_entry)(&args);
}
/*
* Copyright (C) Paul Mackerras 1997.
* Copyright (C) Leigh Brown 2002.
*
* 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 "of1275.h"
int
write(ihandle instance, void *buf, int buflen)
{
struct prom_args {
char *service;
int nargs;
int nret;
ihandle instance;
void *buf;
int buflen;
int actual;
} args;
args.service = "write";
args.nargs = 3;
args.nret = 1;
args.instance = instance;
args.buf = buf;
args.buflen = buflen;
args.actual = -1;
(*of_prom_entry)(&args);
return args.actual;
}
# BK Id: %F% %I% %G% %U% %#%
#
# Makefile for making XCOFF bootable images for booting on PowerMacs
# using Open Firmware.
# Makefile for making bootable images on various OpenFirmware machines.
#
# Paul Mackerras January 1997
#
# Cleaned up, moved into arch/ppc/boot/pmac
# XCOFF bootable images for PowerMacs
# Geert Uytterhoeven September 1997
# ELF bootable iamges for CHRP machines.
# Tom Rini January 2001
# Cleaned up, moved into arch/ppc/boot/pmac
# Tom Rini July/August 2002
# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the
# rules.
OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
COFF_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00500000 -Bstatic
CHRP_LD_ARGS = -T ../ld.script -Ttext 0x01000000
CHRP_LD_ARGS = -T ../ld.script -e _start -Ttext 0x00400000
NEWWORLD_LD_ARGS = -T ../ld.script -e _start -Ttext 0x01000000
COMMONOBJS = start.o misc.o ../common/string.o ../common/ofcommon.o
COMMONOBJS = start.o misc.o ../common/string.o common.o
COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o
CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o
NEWWORLDOBJS = ../common/crt0.o $(COMMONOBJS) newworldmain.o
EXTRA_TARGETS := $(COFFOBJS) $(CHRPOBJS)
LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a
EXTRA_TARGETS := $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS)
LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a ../of1275/of1275.a
ADDNOTE := ../utils/addnote
MKNOTE := ../utils/mknote
SIZE := ../utils/size
OFFSET := ../utils/offset
......@@ -31,7 +36,7 @@ ifdef CONFIG_PPC64BRIDGE
END += .64
endif
TFTPIMAGE=/tftpboot/zImage.pmac$(END)
TFTPIMAGE=/tftpboot/zImage.
../common/coffcrt0.o:
$(MAKE) -C ../common coffcrt0.o
......@@ -46,34 +51,42 @@ ifdef CONFIG_XMON
--set-section-flags=.sysmap=contents,alloc,load,readonly,data
endif
# Place the ramdisk in the initrd image.
image-initrd.o: image.o ../images/ramdisk.image.gz
$(OBJCOPY) image.o $@ \
--add-section=.ramdisk=../images/ramdisk.image.gz \
--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
# Create the note section for New-World PowerMacs.
note: $(MKNOTE)
$(MKNOTE) > note
znetboot: vmlinux.coff vmlinux.elf-pmac zImage
cp ../images/vmlinux.coff $(TFTPIMAGE)
cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).elf
cp ../images/vmlinux.coff $(TFTPIMAGE).pmac$(END)
cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END)elf
cp ../images/zImage.chrp $(TFTPIMAGE).chrp$(END)
znetboot.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac
cp ../images/vmlinux.initrd.coff $(TFTPIMAGE)
cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).elf
cp ../images/vmlinux.initrd.coff $(TFTPIMAGE).pmac$(END)
cp ../images/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
cp ../images/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
miboot.image: ../common/dummy.o ../images/vmlinux.gz
$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \
../common/dummy.o ../images/$@
miboot.initrd.image: miboot.image ../images/ramdisk.image.gz
$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \
$(OBJCOPY) $(OBJCOPY_ARGS) \
--add-section=initrd=../images/ramdisk.image.gz \
../images/miboot.image ../images/$@
coffboot: $(COFFOBJS) image.o $(LIBS) ../ld.script
$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image.o $(LIBS)
$(OBJCOPY) $@ $@ -R .comment
coffboot: $(COFFOBJS) image.o $(LIBS)
$(LD) -o $@ $(COFF_LD_ARGS) $^
$(OBJCOPY) $@ $@ -R .comment -R .ramdisk
coffboot.initrd: $(COFFOBJS) image.o $(LIBS) ../ld.script \
../images/ramdisk.image.gz
$(OBJCOPY) image.o image-coff.o \
--add-section=.ramdisk=../images/ramdisk.image.gz \
--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) image-coff.o $(LIBS)
coffboot.initrd: $(COFFOBJS) image-initrd.o $(LIBS)
$(LD) -o $@ $(COFF_LD_ARGS) $^
$(OBJCOPY) $@ $@ -R .comment
rm -f image-coff.o
vmlinux.coff: coffboot $(HACKCOFF)
$(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@
......@@ -87,26 +100,38 @@ vmlinux.initrd.coff: coffboot.initrd $(HACKCOFF)
rm -f coffboot.initrd
ln -sf vmlinux.initrd.coff ../images/zImage.initrd.pmac
vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o
$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image.o
$(MKNOTE) > note
$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
vmlinux.elf-pmac: $(NEWWORLDOBJS) $(LIBS) image.o
$(LD) $(NEWWORLD_LD_ARGS) -o ../images/$@ $^
vmlinux.initrd.elf-pmac: $(NEWWORLDOBJS) $(LIBS) image-initrd.o
$(LD) $(NEWWORLD_LD_ARGS) -o ../images/$@ $^
zImage.chrp: $(CHRPOBJS) image.o $(LIBS)
$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $^
zImage.initrd.chrp: $(CHRPOBJS) image-initrd.o $(LIBS)
$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $^
zImage: vmlinux.coff vmlinux.elf-pmac zImage.chrp miboot.image $(ADDNOTE) \
note
$(OBJCOPY) ../images/vmlinux.elf-pmac ../images/vmlinux.elf-pmac \
--add-section=.note=note -R .comment -R .ramdisk
$(OBJCOPY) ../images/zImage.chrp ../images/zImage.chrp \
-R .comment -R .ramdisk
rm -f note
cp ../images/zImage.chrp ../images/zImage.chrp-rs6k
$(ADDNOTE) ../images/zImage.chrp-rs6k
vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) $(MKNOTE) image.o \
../images/ramdisk.image.gz
$(OBJCOPY) image.o image-elf.o \
--add-section=.ramdisk=../images/ramdisk.image.gz \
--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
$(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) $(LIBS) image-elf.o
$(MKNOTE) > note
$(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \
zImage.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac zImage.initrd.chrp \
miboot.initrd.image $(ADDNOTE) note
$(OBJCOPY) ../images/vmlinux.initrd.elf-pmac \
../images/vmlinux.initrd.elf-pmac --add-section=.note=note \
-R .comment
rm -f note image-elf.o
zImage: vmlinux.coff vmlinux.elf-pmac miboot.image
$(OBJCOPY) ../images/zImage.initrd.chrp ../images/zImage.initrd.chrp \
-R .comment
cp ../images/zImage.initrd.chrp ../images/zImage.initrd.chrp-rs6k
$(ADDNOTE) ../images/zImage.initrd.chrp-rs6k
zImage.initrd: vmlinux.initrd.coff vmlinux.initrd.elf-pmac miboot.initrd.image
clean:
rm -f note
include $(TOPDIR)/Rules.make
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......@@ -10,23 +7,20 @@
* 2 of the License, or (at your option) any later version.
*/
#include "nonstdio.h"
#include "of1275.h"
#include <asm/processor.h>
#include <asm/page.h>
/* Passed from the linker */
extern char __image_begin, __image_end;
extern char __ramdisk_begin[], __ramdisk_end;
extern char __ramdisk_begin, __ramdisk_end;
extern char _start, _end;
extern int getprop(void *, const char *, void *, int);
extern unsigned int heap_max;
extern void claim(unsigned int virt, unsigned int size, unsigned int align);
extern void *finddevice(const char *);
extern void flush_cache(void *, unsigned long);
extern void gunzip(void *, int, unsigned char *, int *);
extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned int progend);
extern void pause(void);
char *avail_ram;
char *begin_avail, *end_avail;
......@@ -49,7 +43,7 @@ static char scratch[SCRATCH_SIZE]; /* 1MB of scratch space for gunzip */
typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
void
chrpboot(int a1, int a2, void *prom)
boot(int a1, int a2, void *prom)
{
unsigned sa, len;
void *dst;
......@@ -58,23 +52,23 @@ chrpboot(int a1, int a2, void *prom)
printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
initrd_size = &__ramdisk_end - &__ramdisk_begin;
if (initrd_size) {
initrd_start = (RAM_END - initrd_size) & ~0xFFF;
a1 = initrd_start;
a2 = initrd_size;
claim(initrd_start, RAM_END - initrd_start, 0);
printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
initrd_start, (char *)(&__ramdisk_begin), initrd_size);
memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
initrd_start, &__ramdisk_begin, initrd_size);
memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size);
} else {
initrd_start = 0;
initrd_size = 0;
a2 = 0xdeadbeef;
}
im = (char *)(&__image_begin);
len = (char *)(&__image_end) - (char *)(&__image_begin);
im = &__image_begin;
len = &__image_end - &__image_begin;
/* claim 4MB starting at PROG_START */
claim(PROG_START, PROG_SIZE - PROG_START, 0);
dst = (void *) PROG_START;
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......@@ -13,6 +10,7 @@
#include <asm/page.h>
#include "nonstdio.h"
#include "of1275.h"
#include "zlib.h"
/* Passed from the linker */
......@@ -20,17 +18,13 @@ extern char __image_begin, __image_end;
extern char __ramdisk_begin[], __ramdisk_end;
extern char _start, _end;
extern char *claim(unsigned, unsigned, unsigned);
extern char image_data[], initrd_data[];
extern int initrd_len, image_len;
extern int getprop(void *, const char *, void *, int);
extern unsigned int heap_max;
extern void *finddevice(const char *);
extern void flush_cache(void *start, unsigned int len);
extern void gunzip(void *, int, unsigned char *, int *);
extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned int progend);
extern void pause(void);
extern void setup_bats(unsigned long start);
char *avail_ram;
......
/*
* Copyright (C) Paul Mackerras 1997.
*
* 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 "zlib.h"
#include "nonstdio.h"
#include "of1275.h"
#include <asm/bootinfo.h>
#include <asm/page.h>
/* Information from the linker */
extern char __sysmap_begin, __sysmap_end;
extern int strcmp(const char *s1, const char *s2);
extern char *avail_ram, *avail_high;
extern char *end_avail;
unsigned int heap_use, heap_max;
struct memchunk {
unsigned int size;
struct memchunk *next;
};
static struct memchunk *freechunks;
static void *zalloc(void *x, unsigned items, unsigned size)
{
void *p;
struct memchunk **mpp, *mp;
size *= items;
size = (size + 7) & -8;
heap_use += size;
if (heap_use > heap_max)
heap_max = heap_use;
for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
if (mp->size == size) {
*mpp = mp->next;
return mp;
}
}
p = avail_ram;
avail_ram += size;
if (avail_ram > avail_high)
avail_high = avail_ram;
if (avail_ram > end_avail) {
printf("oops... out of memory\n\r");
pause();
}
return p;
}
static void zfree(void *x, void *addr, unsigned nb)
{
struct memchunk *mp = addr;
nb = (nb + 7) & -8;
heap_use -= nb;
if (avail_ram == addr + nb) {
avail_ram = addr;
return;
}
mp->size = nb;
mp->next = freechunks;
freechunks = mp;
}
#define HEAD_CRC 2
#define EXTRA_FIELD 4
#define ORIG_NAME 8
#define COMMENT 0x10
#define RESERVED 0xe0
#define DEFLATED 8
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
z_stream s;
int r, i, flags;
/* skip header */
i = 10;
flags = src[3];
if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
printf("bad gzipped data\n\r");
exit();
}
if ((flags & EXTRA_FIELD) != 0)
i = 12 + src[10] + (src[11] << 8);
if ((flags & ORIG_NAME) != 0)
while (src[i++] != 0)
;
if ((flags & COMMENT) != 0)
while (src[i++] != 0)
;
if ((flags & HEAD_CRC) != 0)
i += 2;
if (i >= *lenp) {
printf("gunzip: ran out of data in header\n\r");
exit();
}
s.zalloc = zalloc;
s.zfree = zfree;
r = inflateInit2(&s, -MAX_WBITS);
if (r != Z_OK) {
printf("inflateInit2 returned %d\n\r", r);
exit();
}
s.next_in = src + i;
s.avail_in = *lenp - i;
s.next_out = dst;
s.avail_out = dstlen;
r = inflate(&s, Z_FINISH);
if (r != Z_OK && r != Z_STREAM_END) {
printf("inflate returned %d msg: %s\n\r", r, s.msg);
exit();
}
*lenp = s.next_out - (unsigned char *) dst;
inflateEnd(&s);
}
/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
* a machine type for BI_MACHTYPE, and the location where the end of the
* bootloader is (PROG_START + PROG_SIZE)
*/
void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned long progend)
{
unsigned long sysmap_size;
struct bi_record *rec;
/* Figure out the size of a possible System.map we're going to
* pass along.
* */
sysmap_size = (unsigned long)(&__sysmap_end) -
(unsigned long)(&__sysmap_begin);
/* leave a 1MB gap then align to the next 1MB boundary */
addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
/* oldworld machine seem very unhappy about this. -- Tom */
if (addr >= progend)
claim(addr, 0x1000, 0);
rec = (struct bi_record *)addr;
rec->tag = BI_FIRST;
rec->size = sizeof(struct bi_record);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
rec->tag = BI_BOOTLOADER_ID;
sprintf( (char *)rec->data, name);
rec->size = sizeof(struct bi_record) + strlen(name) + 1;
rec = (struct bi_record *)((unsigned long)rec + rec->size);
rec->tag = BI_MACHTYPE;
rec->data[0] = mach;
rec->data[1] = 1;
rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
if (sysmap_size) {
rec->tag = BI_SYSMAP;
rec->data[0] = (unsigned long)(&__sysmap_begin);
rec->data[1] = sysmap_size;
rec->size = sizeof(struct bi_record) + 2 *
sizeof(unsigned long);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
rec->tag = BI_LAST;
rec->size = sizeof(struct bi_record);
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
/*
* BK Id: SCCS/s.misc.S 1.6 05/18/01 15:17:15 cort
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......@@ -10,6 +7,7 @@
* 2 of the License, or (at your option) any later version.
*/
#include "nonstdio.h"
#include "of1275.h"
#include <asm/processor.h>
#include <asm/page.h>
......@@ -18,16 +16,11 @@ extern char __image_begin, __image_end;
extern char __ramdisk_begin[], __ramdisk_end;
extern char _start, _end;
extern int getprop(void *, const char *, void *, int);
extern unsigned int heap_max;
extern void *claim(unsigned int virt, unsigned int size, unsigned int align);
extern void *finddevice(const char *);
extern void flush_cache(void *start, unsigned int len);
extern void gunzip(void *, int, unsigned char *, int *);
extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
unsigned int progend);
extern void pause(void);
extern void release(void *ptr, unsigned int len);
char *avail_ram;
char *begin_avail, *end_avail;
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
/*
* Copyright (C) Paul Mackerras 1997.
*
......@@ -10,33 +7,22 @@
* 2 of the License, or (at your option) any later version.
*/
#include <stdarg.h>
#include "of1275.h"
extern int strlen(const char *s);
extern void boot(int a1, int a2, void *prom);
int (*prom)(void *);
void *chosen_handle;
void *stdin;
void *stdout;
void *stderr;
phandle stdin;
phandle stdout;
phandle stderr;
void exit(void);
void *finddevice(const char *name);
int getprop(void *phandle, const char *name, void *buf, int buflen);
void printk(char *fmt, ...);
void
start(int a1, int a2, void *promptr)
{
prom = (int (*)(void *)) promptr;
chosen_handle = finddevice("/chosen");
if (chosen_handle == (void *) -1)
exit();
if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
exit();
stderr = stdout;
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
ofinit(promptr);
if (ofstdio(&stdin, &stdout, &stderr))
exit();
boot(a1, a2, promptr);
......@@ -44,30 +30,6 @@ start(int a1, int a2, void *promptr)
exit();
}
int
write(void *handle, void *ptr, int nb)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *ihandle;
void *addr;
int len;
int actual;
} args;
args.service = "write";
args.nargs = 3;
args.nret = 1;
args.ihandle = handle;
args.addr = ptr;
args.len = nb;
args.actual = -1;
(*prom)(&args);
return args.actual;
}
int writestring(void *f, char *ptr, int nb)
{
int w = 0, i;
......@@ -87,142 +49,6 @@ int writestring(void *f, char *ptr, int nb)
return nb;
}
int
read(void *handle, void *ptr, int nb)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *ihandle;
void *addr;
int len;
int actual;
} args;
args.service = "read";
args.nargs = 3;
args.nret = 1;
args.ihandle = handle;
args.addr = ptr;
args.len = nb;
args.actual = -1;
(*prom)(&args);
return args.actual;
}
void
exit(void)
{
struct prom_args {
char *service;
} args;
for (;;) {
args.service = "exit";
(*prom)(&args);
}
}
void
pause(void)
{
struct prom_args {
char *service;
} args;
args.service = "enter";
(*prom)(&args);
}
void *
finddevice(const char *name)
{
struct prom_args {
char *service;
int nargs;
int nret;
const char *devspec;
void *phandle;
} args;
args.service = "finddevice";
args.nargs = 1;
args.nret = 1;
args.devspec = name;
args.phandle = (void *) -1;
(*prom)(&args);
return args.phandle;
}
void *
claim(unsigned int virt, unsigned int size, unsigned int align)
{
struct prom_args {
char *service;
int nargs;
int nret;
unsigned int virt;
unsigned int size;
unsigned int align;
void *ret;
} args;
args.service = "claim";
args.nargs = 3;
args.nret = 1;
args.virt = virt;
args.size = size;
args.align = align;
(*prom)(&args);
return args.ret;
}
void
release(void *virt, unsigned int size)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *virt;
unsigned int size;
} args;
args.service = "release";
args.nargs = 2;
args.nret = 0;
args.virt = virt;
args.size = size;
(*prom)(&args);
}
int
getprop(void *phandle, const char *name, void *buf, int buflen)
{
struct prom_args {
char *service;
int nargs;
int nret;
void *phandle;
const char *name;
void *buf;
int buflen;
int size;
} args;
args.service = "getprop";
args.nargs = 4;
args.nret = 1;
args.phandle = phandle;
args.name = name;
args.buf = buf;
args.buflen = buflen;
args.size = -1;
(*prom)(&args);
return args.size;
}
int
putc(int c, void *f)
{
......
# BK Id: %F% %I% %G% %U% %#%
#
# arch/ppc/boot/Makefile
#
# This file is subject to the terms and conditions of the GNU General Public
......@@ -21,13 +19,14 @@ TFTPIMAGE = $(TFTPBOOT).smp
endif
LD_ARGS = -T ../ld.script -Ttext 0x00800000 -Bstatic
boot-y := head.o ../simple/legacy.o misc.o of1275.o \
boot-y := head.o ../simple/legacy.o misc.o \
../common/util.o ../common/string.o \
../common/misc-common.o
../common/misc-common.o \
../common/mpc10x_memory.o
OBJCOPY_ARGS = -O elf32-powerpc
LIBS = ../lib/zlib.a
boot-$($CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
boot-$(CONFIG_SERIAL_8250_CONSOLE) += ../common/ns16550.o
boot-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
EXTRA_TARGETS := $(boot-y)
......
/*
* BK Id: %F% %I% %G% %U% %#%
*/
#include <asm/ppc_asm.h>
#include <asm/processor.h>
#include <asm/cache.h>
......@@ -38,10 +34,6 @@ start_:
isync
mr r11,r3 /* Save pointer to residual/board data */
mr r25,r5 /* Save OFW pointer */
/* Save the original MSR value */
mfmsr r26
/* Establish default MSR value */
li r3,MSR_IP|MSR_FP
......@@ -114,17 +106,11 @@ start_ldr:
li r2,0x000F /* Mask pointer to 16-byte boundary */
andc r1,r1,r2
/* Store the original MSR into 'orig_MSR' */
lis r3,orig_MSR@h
ori r3,r3,orig_MSR@l
stw r26,0(r3)
/* Run loader */
mr r3,r8 /* Load point */
mr r4,r7 /* Program length */
mr r5,r6 /* Checksum */
mr r6,r11 /* Residual data */
mr r7,r25 /* OFW interfaces */
bl decompress_kernel
/*
......
/*
* BK Id: SCCS/s.iso_font.h 1.6 05/18/01 15:16:42 cort
*/
static const unsigned char font[] = {
/* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment