From: Peter Tyser Date: Tue, 13 Apr 2010 03:28:17 +0000 (-0500) Subject: i386: Move cpu/i386/* to arch/i386/cpu/* X-Git-Tag: v2010.06-rc1~92 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e9a882803eb59f482ca4aa6ffd6fa21e4c53d618;p=u-boot i386: Move cpu/i386/* to arch/i386/cpu/* Signed-off-by: Peter Tyser --- diff --git a/arch/i386/cpu/Makefile b/arch/i386/cpu/Makefile new file mode 100644 index 0000000000..c658c6e459 --- /dev/null +++ b/arch/i386/cpu/Makefile @@ -0,0 +1,50 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).a + +START = start.o start16.o resetvec.o +COBJS = serial.o interrupts.o cpu.o + +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/i386/cpu/config.mk b/arch/i386/cpu/config.mk new file mode 100644 index 0000000000..16a160d2f3 --- /dev/null +++ b/arch/i386/cpu/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +PLATFORM_RELFLAGS += + +PLATFORM_CPPFLAGS += -march=i386 -Werror diff --git a/arch/i386/cpu/cpu.c b/arch/i386/cpu/cpu.c new file mode 100644 index 0000000000..3010519e74 --- /dev/null +++ b/arch/i386/cpu/cpu.c @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * CPU specific code + */ + +#include +#include +#include + +int cpu_init_f(void) +{ + /* initialize FPU, reset EM, set MP and NE */ + asm ("fninit\n" \ + "movl %cr0, %eax\n" \ + "andl $~0x4, %eax\n" \ + "orl $0x22, %eax\n" \ + "movl %eax, %cr0\n" ); + + return 0; +} + +int cpu_init_r(void) +{ + /* Initialize core interrupt and exception functionality of CPU */ + cpu_init_interrupts (); + return 0; +} + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + printf ("resetting ...\n"); + udelay(50000); /* wait 50 ms */ + disable_interrupts(); + reset_cpu(0); + + /*NOTREACHED*/ + return 0; +} + +void flush_cache (unsigned long dummy1, unsigned long dummy2) +{ + asm("wbinvd\n"); + return; +} + +void __attribute__ ((regparm(0))) generate_gpf(void); + +/* segment 0x70 is an arbitrary segment which does not exist */ +asm(".globl generate_gpf\n" + ".hidden generate_gpf\n" + ".type generate_gpf, @function\n" + "generate_gpf:\n" + "ljmp $0x70, $0x47114711\n"); + +void __reset_cpu(ulong addr) +{ + printf("Resetting using i386 Triple Fault\n"); + set_vector(13, generate_gpf); /* general protection fault handler */ + set_vector(8, generate_gpf); /* double fault handler */ + generate_gpf(); /* start the show */ +} +void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu"))); diff --git a/arch/i386/cpu/interrupts.c b/arch/i386/cpu/interrupts.c new file mode 100644 index 0000000000..4b57437193 --- /dev/null +++ b/arch/i386/cpu/interrupts.c @@ -0,0 +1,501 @@ +/* + * (C) Copyright 2008 + * Graeme Russ, graeme.russ@gmail.com. + * + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#define DECLARE_INTERRUPT(x) \ + ".globl irq_"#x"\n" \ + ".hidden irq_"#x"\n" \ + ".type irq_"#x", @function\n" \ + "irq_"#x":\n" \ + "pushl %ebp\n" \ + "movl %esp,%ebp\n" \ + "pusha\n" \ + "pushl $"#x"\n" \ + "jmp irq_common_entry\n" + +struct idt_entry { + u16 base_low; + u16 selector; + u8 res; + u8 access; + u16 base_high; +} __attribute__ ((packed)); + +struct desc_ptr { + unsigned short size; + unsigned long address; + unsigned short segment; +} __attribute__((packed)); + +struct idt_entry idt[256]; + +struct desc_ptr idt_ptr; + +static inline void load_idt(const struct desc_ptr *dtr) +{ + asm volatile("cs lidt %0"::"m" (*dtr)); +} + +void set_vector(u8 intnum, void *routine) +{ + idt[intnum].base_high = (u16)((u32)(routine) >> 16); + idt[intnum].base_low = (u16)((u32)(routine) & 0xffff); +} + +void irq_0(void); +void irq_1(void); + +int cpu_init_interrupts(void) +{ + int i; + + int irq_entry_size = irq_1 - irq_0; + void *irq_entry = (void *)irq_0; + + /* Just in case... */ + disable_interrupts(); + + /* Setup the IDT */ + for (i=0;i<256;i++) { + idt[i].access = 0x8e; + idt[i].res = 0; + idt[i].selector = 0x10; + set_vector(i, irq_entry); + irq_entry += irq_entry_size; + } + + idt_ptr.size = 256 * 8; + idt_ptr.address = (unsigned long) idt; + idt_ptr.segment = 0x18; + + load_idt(&idt_ptr); + + /* It is now safe to enable interrupts */ + enable_interrupts(); + + return 0; +} + +void __do_irq(int irq) +{ + printf("Unhandled IRQ : %d\n", irq); +} +void do_irq(int irq) __attribute__((weak, alias("__do_irq"))); + +void enable_interrupts(void) +{ + asm("sti\n"); +} + +int disable_interrupts(void) +{ + long flags; + + asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); + + return (flags&0x200); /* IE flags is bit 9 */ +} + +/* IRQ Low-Level Service Routine */ +__isr__ irq_llsr(int ip, int seg, int irq) +{ + /* + * For detailed description of each exception, refer to: + * Intel® 64 and IA-32 Architectures Software Developer's Manual + * Volume 1: Basic Architecture + * Order Number: 253665-029US, November 2008 + * Table 6-1. Exceptions and Interrupts + */ + switch (irq) { + case 0x00: + printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x01: + printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip); + break; + case 0x02: + printf("NMI Interrupt at %04x:%08x\n", seg, ip); + break; + case 0x03: + printf("Breakpoint at %04x:%08x\n", seg, ip); + break; + case 0x04: + printf("Overflow at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x05: + printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x06: + printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x07: + printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x08: + printf("Double fault at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x09: + printf("Co-processor segment overrun at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x0a: + printf("Invalid TSS at %04x:%08x\n", seg, ip); + break; + case 0x0b: + printf("Segment Not Present at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x0c: + printf("Stack Segment Fault at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x0d: + printf("General Protection at %04x:%08x\n", seg, ip); + break; + case 0x0e: + printf("Page fault at %04x:%08x\n", seg, ip); + while(1); + break; + case 0x0f: + printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip); + break; + case 0x10: + printf("Alignment check at %04x:%08x\n", seg, ip); + break; + case 0x11: + printf("Machine Check at %04x:%08x\n", seg, ip); + break; + case 0x12: + printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip); + break; + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip); + break; + + default: + /* Hardware or User IRQ */ + do_irq(irq); + } +} + +/* + * OK - This looks really horrible, but it serves a purpose - It helps create + * fully relocatable code. + * - The call to irq_llsr will be a relative jump + * - The IRQ entries will be guaranteed to be in order + * It's a bit annoying that we need to waste 3 bytes per interrupt entry + * (total of 768 code bytes), but we MUST create a Stack Frame and this is + * the easiest way I could do it. Maybe it can be made better later. + */ +asm(".globl irq_common_entry\n" \ + ".hidden irq_common_entry\n" \ + ".type irq_common_entry, @function\n" \ + "irq_common_entry:\n" \ + "pushl $0\n" \ + "pushl $0\n" \ + "call irq_llsr\n" \ + "popl %eax\n" \ + "popl %eax\n" \ + "popl %eax\n" \ + "popa\n" \ + "leave\n"\ + "iret\n" \ + DECLARE_INTERRUPT(0) \ + DECLARE_INTERRUPT(1) \ + DECLARE_INTERRUPT(2) \ + DECLARE_INTERRUPT(3) \ + DECLARE_INTERRUPT(4) \ + DECLARE_INTERRUPT(5) \ + DECLARE_INTERRUPT(6) \ + DECLARE_INTERRUPT(7) \ + DECLARE_INTERRUPT(8) \ + DECLARE_INTERRUPT(9) \ + DECLARE_INTERRUPT(10) \ + DECLARE_INTERRUPT(11) \ + DECLARE_INTERRUPT(12) \ + DECLARE_INTERRUPT(13) \ + DECLARE_INTERRUPT(14) \ + DECLARE_INTERRUPT(15) \ + DECLARE_INTERRUPT(16) \ + DECLARE_INTERRUPT(17) \ + DECLARE_INTERRUPT(18) \ + DECLARE_INTERRUPT(19) \ + DECLARE_INTERRUPT(20) \ + DECLARE_INTERRUPT(21) \ + DECLARE_INTERRUPT(22) \ + DECLARE_INTERRUPT(23) \ + DECLARE_INTERRUPT(24) \ + DECLARE_INTERRUPT(25) \ + DECLARE_INTERRUPT(26) \ + DECLARE_INTERRUPT(27) \ + DECLARE_INTERRUPT(28) \ + DECLARE_INTERRUPT(29) \ + DECLARE_INTERRUPT(30) \ + DECLARE_INTERRUPT(31) \ + DECLARE_INTERRUPT(32) \ + DECLARE_INTERRUPT(33) \ + DECLARE_INTERRUPT(34) \ + DECLARE_INTERRUPT(35) \ + DECLARE_INTERRUPT(36) \ + DECLARE_INTERRUPT(37) \ + DECLARE_INTERRUPT(38) \ + DECLARE_INTERRUPT(39) \ + DECLARE_INTERRUPT(40) \ + DECLARE_INTERRUPT(41) \ + DECLARE_INTERRUPT(42) \ + DECLARE_INTERRUPT(43) \ + DECLARE_INTERRUPT(44) \ + DECLARE_INTERRUPT(45) \ + DECLARE_INTERRUPT(46) \ + DECLARE_INTERRUPT(47) \ + DECLARE_INTERRUPT(48) \ + DECLARE_INTERRUPT(49) \ + DECLARE_INTERRUPT(50) \ + DECLARE_INTERRUPT(51) \ + DECLARE_INTERRUPT(52) \ + DECLARE_INTERRUPT(53) \ + DECLARE_INTERRUPT(54) \ + DECLARE_INTERRUPT(55) \ + DECLARE_INTERRUPT(56) \ + DECLARE_INTERRUPT(57) \ + DECLARE_INTERRUPT(58) \ + DECLARE_INTERRUPT(59) \ + DECLARE_INTERRUPT(60) \ + DECLARE_INTERRUPT(61) \ + DECLARE_INTERRUPT(62) \ + DECLARE_INTERRUPT(63) \ + DECLARE_INTERRUPT(64) \ + DECLARE_INTERRUPT(65) \ + DECLARE_INTERRUPT(66) \ + DECLARE_INTERRUPT(67) \ + DECLARE_INTERRUPT(68) \ + DECLARE_INTERRUPT(69) \ + DECLARE_INTERRUPT(70) \ + DECLARE_INTERRUPT(71) \ + DECLARE_INTERRUPT(72) \ + DECLARE_INTERRUPT(73) \ + DECLARE_INTERRUPT(74) \ + DECLARE_INTERRUPT(75) \ + DECLARE_INTERRUPT(76) \ + DECLARE_INTERRUPT(77) \ + DECLARE_INTERRUPT(78) \ + DECLARE_INTERRUPT(79) \ + DECLARE_INTERRUPT(80) \ + DECLARE_INTERRUPT(81) \ + DECLARE_INTERRUPT(82) \ + DECLARE_INTERRUPT(83) \ + DECLARE_INTERRUPT(84) \ + DECLARE_INTERRUPT(85) \ + DECLARE_INTERRUPT(86) \ + DECLARE_INTERRUPT(87) \ + DECLARE_INTERRUPT(88) \ + DECLARE_INTERRUPT(89) \ + DECLARE_INTERRUPT(90) \ + DECLARE_INTERRUPT(91) \ + DECLARE_INTERRUPT(92) \ + DECLARE_INTERRUPT(93) \ + DECLARE_INTERRUPT(94) \ + DECLARE_INTERRUPT(95) \ + DECLARE_INTERRUPT(97) \ + DECLARE_INTERRUPT(96) \ + DECLARE_INTERRUPT(98) \ + DECLARE_INTERRUPT(99) \ + DECLARE_INTERRUPT(100) \ + DECLARE_INTERRUPT(101) \ + DECLARE_INTERRUPT(102) \ + DECLARE_INTERRUPT(103) \ + DECLARE_INTERRUPT(104) \ + DECLARE_INTERRUPT(105) \ + DECLARE_INTERRUPT(106) \ + DECLARE_INTERRUPT(107) \ + DECLARE_INTERRUPT(108) \ + DECLARE_INTERRUPT(109) \ + DECLARE_INTERRUPT(110) \ + DECLARE_INTERRUPT(111) \ + DECLARE_INTERRUPT(112) \ + DECLARE_INTERRUPT(113) \ + DECLARE_INTERRUPT(114) \ + DECLARE_INTERRUPT(115) \ + DECLARE_INTERRUPT(116) \ + DECLARE_INTERRUPT(117) \ + DECLARE_INTERRUPT(118) \ + DECLARE_INTERRUPT(119) \ + DECLARE_INTERRUPT(120) \ + DECLARE_INTERRUPT(121) \ + DECLARE_INTERRUPT(122) \ + DECLARE_INTERRUPT(123) \ + DECLARE_INTERRUPT(124) \ + DECLARE_INTERRUPT(125) \ + DECLARE_INTERRUPT(126) \ + DECLARE_INTERRUPT(127) \ + DECLARE_INTERRUPT(128) \ + DECLARE_INTERRUPT(129) \ + DECLARE_INTERRUPT(130) \ + DECLARE_INTERRUPT(131) \ + DECLARE_INTERRUPT(132) \ + DECLARE_INTERRUPT(133) \ + DECLARE_INTERRUPT(134) \ + DECLARE_INTERRUPT(135) \ + DECLARE_INTERRUPT(136) \ + DECLARE_INTERRUPT(137) \ + DECLARE_INTERRUPT(138) \ + DECLARE_INTERRUPT(139) \ + DECLARE_INTERRUPT(140) \ + DECLARE_INTERRUPT(141) \ + DECLARE_INTERRUPT(142) \ + DECLARE_INTERRUPT(143) \ + DECLARE_INTERRUPT(144) \ + DECLARE_INTERRUPT(145) \ + DECLARE_INTERRUPT(146) \ + DECLARE_INTERRUPT(147) \ + DECLARE_INTERRUPT(148) \ + DECLARE_INTERRUPT(149) \ + DECLARE_INTERRUPT(150) \ + DECLARE_INTERRUPT(151) \ + DECLARE_INTERRUPT(152) \ + DECLARE_INTERRUPT(153) \ + DECLARE_INTERRUPT(154) \ + DECLARE_INTERRUPT(155) \ + DECLARE_INTERRUPT(156) \ + DECLARE_INTERRUPT(157) \ + DECLARE_INTERRUPT(158) \ + DECLARE_INTERRUPT(159) \ + DECLARE_INTERRUPT(160) \ + DECLARE_INTERRUPT(161) \ + DECLARE_INTERRUPT(162) \ + DECLARE_INTERRUPT(163) \ + DECLARE_INTERRUPT(164) \ + DECLARE_INTERRUPT(165) \ + DECLARE_INTERRUPT(166) \ + DECLARE_INTERRUPT(167) \ + DECLARE_INTERRUPT(168) \ + DECLARE_INTERRUPT(169) \ + DECLARE_INTERRUPT(170) \ + DECLARE_INTERRUPT(171) \ + DECLARE_INTERRUPT(172) \ + DECLARE_INTERRUPT(173) \ + DECLARE_INTERRUPT(174) \ + DECLARE_INTERRUPT(175) \ + DECLARE_INTERRUPT(176) \ + DECLARE_INTERRUPT(177) \ + DECLARE_INTERRUPT(178) \ + DECLARE_INTERRUPT(179) \ + DECLARE_INTERRUPT(180) \ + DECLARE_INTERRUPT(181) \ + DECLARE_INTERRUPT(182) \ + DECLARE_INTERRUPT(183) \ + DECLARE_INTERRUPT(184) \ + DECLARE_INTERRUPT(185) \ + DECLARE_INTERRUPT(186) \ + DECLARE_INTERRUPT(187) \ + DECLARE_INTERRUPT(188) \ + DECLARE_INTERRUPT(189) \ + DECLARE_INTERRUPT(190) \ + DECLARE_INTERRUPT(191) \ + DECLARE_INTERRUPT(192) \ + DECLARE_INTERRUPT(193) \ + DECLARE_INTERRUPT(194) \ + DECLARE_INTERRUPT(195) \ + DECLARE_INTERRUPT(196) \ + DECLARE_INTERRUPT(197) \ + DECLARE_INTERRUPT(198) \ + DECLARE_INTERRUPT(199) \ + DECLARE_INTERRUPT(200) \ + DECLARE_INTERRUPT(201) \ + DECLARE_INTERRUPT(202) \ + DECLARE_INTERRUPT(203) \ + DECLARE_INTERRUPT(204) \ + DECLARE_INTERRUPT(205) \ + DECLARE_INTERRUPT(206) \ + DECLARE_INTERRUPT(207) \ + DECLARE_INTERRUPT(208) \ + DECLARE_INTERRUPT(209) \ + DECLARE_INTERRUPT(210) \ + DECLARE_INTERRUPT(211) \ + DECLARE_INTERRUPT(212) \ + DECLARE_INTERRUPT(213) \ + DECLARE_INTERRUPT(214) \ + DECLARE_INTERRUPT(215) \ + DECLARE_INTERRUPT(216) \ + DECLARE_INTERRUPT(217) \ + DECLARE_INTERRUPT(218) \ + DECLARE_INTERRUPT(219) \ + DECLARE_INTERRUPT(220) \ + DECLARE_INTERRUPT(221) \ + DECLARE_INTERRUPT(222) \ + DECLARE_INTERRUPT(223) \ + DECLARE_INTERRUPT(224) \ + DECLARE_INTERRUPT(225) \ + DECLARE_INTERRUPT(226) \ + DECLARE_INTERRUPT(227) \ + DECLARE_INTERRUPT(228) \ + DECLARE_INTERRUPT(229) \ + DECLARE_INTERRUPT(230) \ + DECLARE_INTERRUPT(231) \ + DECLARE_INTERRUPT(232) \ + DECLARE_INTERRUPT(233) \ + DECLARE_INTERRUPT(234) \ + DECLARE_INTERRUPT(235) \ + DECLARE_INTERRUPT(236) \ + DECLARE_INTERRUPT(237) \ + DECLARE_INTERRUPT(238) \ + DECLARE_INTERRUPT(239) \ + DECLARE_INTERRUPT(240) \ + DECLARE_INTERRUPT(241) \ + DECLARE_INTERRUPT(242) \ + DECLARE_INTERRUPT(243) \ + DECLARE_INTERRUPT(244) \ + DECLARE_INTERRUPT(245) \ + DECLARE_INTERRUPT(246) \ + DECLARE_INTERRUPT(247) \ + DECLARE_INTERRUPT(248) \ + DECLARE_INTERRUPT(249) \ + DECLARE_INTERRUPT(250) \ + DECLARE_INTERRUPT(251) \ + DECLARE_INTERRUPT(252) \ + DECLARE_INTERRUPT(253) \ + DECLARE_INTERRUPT(254) \ + DECLARE_INTERRUPT(255)); diff --git a/arch/i386/cpu/resetvec.S b/arch/i386/cpu/resetvec.S new file mode 100644 index 0000000000..d9222dd2fc --- /dev/null +++ b/arch/i386/cpu/resetvec.S @@ -0,0 +1,37 @@ +/* + * U-boot - i386 Startup Code + * + * Copyright (c) 2002 Omicron Ceti AB, Daniel Engström + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Reset vector, jumps to start16.S */ + +.extern start16 + +.section .resetvec, "ax" +.code16 +reset_vector: + cli + cld + jmp start16 + + .org 0xf + nop diff --git a/arch/i386/cpu/sc520/Makefile b/arch/i386/cpu/sc520/Makefile new file mode 100644 index 0000000000..87835b2c20 --- /dev/null +++ b/arch/i386/cpu/sc520/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 2008 +# Graeme Russ, graeme.russ@gmail.com. +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2002 +# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)lib$(SOC).a + +COBJS-$(CONFIG_SYS_SC520) += sc520.o +COBJS-$(CONFIG_SYS_SC520_SSI) += sc520_ssi.o +COBJS-$(CONFIG_SYS_SC520_TIMER) += sc520_timer.o +COBJS-$(CONFIG_PCI) += sc520_pci.o + +SOBJS-$(CONFIG_SYS_SC520) += sc520_asm.o + +SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### \ No newline at end of file diff --git a/arch/i386/cpu/sc520/sc520.c b/arch/i386/cpu/sc520/sc520.c new file mode 100644 index 0000000000..4b566a75cc --- /dev/null +++ b/arch/i386/cpu/sc520/sc520.c @@ -0,0 +1,198 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* stuff specific for the sc520, + * but idependent of implementation */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * utility functions for boards based on the AMD sc520 + * + * void init_sc520(void) + * unsigned long init_sc520_dram(void) + */ + +volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000; + +void init_sc520(void) +{ + /* Set the UARTxCTL register at it's slower, + * baud clock giving us a 1.8432 MHz reference + */ + sc520_mmcr->uart1ctl = 0x07; + sc520_mmcr->uart2ctl = 0x07; + + /* first set the timer pin mapping */ + sc520_mmcr->clksel = 0x72; /* no clock frequency selected, use 1.1892MHz */ + + /* enable PCI bus arbitrer */ + sc520_mmcr->sysarbctl = 0x02; /* enable concurrent mode */ + + sc520_mmcr->sysarbmenb = 0x1f; /* enable external grants */ + sc520_mmcr->hbctl = 0x04; /* enable posted-writes */ + + if (CONFIG_SYS_SC520_HIGH_SPEED) { + sc520_mmcr->cpuctl = 0x02; /* set it to 133 MHz and write back */ + gd->cpu_clk = 133000000; + printf("## CPU Speed set to 133MHz\n"); + } else { + sc520_mmcr->cpuctl = 0x01; /* set it to 100 MHz and write back */ + printf("## CPU Speed set to 100MHz\n"); + gd->cpu_clk = 100000000; + } + + + /* wait at least one millisecond */ + asm("movl $0x2000,%%ecx\n" + "0: pushl %%ecx\n" + "popl %%ecx\n" + "loop 0b\n": : : "ecx"); + + /* turn on the SDRAM write buffer */ + sc520_mmcr->dbctl = 0x11; + + /* turn on the cache and disable write through */ + asm("movl %%cr0, %%eax\n" + "andl $0x9fffffff, %%eax\n" + "movl %%eax, %%cr0\n" : : : "eax"); +} + +unsigned long init_sc520_dram(void) +{ + bd_t *bd = gd->bd; + + u32 dram_present=0; + u32 dram_ctrl; +#ifdef CONFIG_SYS_SDRAM_DRCTMCTL + /* these memory control registers are set up in the assember part, + * in sc520_asm.S, during 'mem_init'. If we muck with them here, + * after we are running a stack in RAM, we have troubles. Besides, + * these refresh and delay values are better ? simply specified + * outright in the include/configs/{cfg} file since the HW designer + * simply dictates it. + */ +#else + int val; + + int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY; + int refresh_rate = CONFIG_SYS_SDRAM_REFRESH_RATE; + int ras_cas_delay = CONFIG_SYS_SDRAM_RAS_CAS_DELAY; + + /* set SDRAM speed here */ + + refresh_rate/=78; + if (refresh_rate<=1) { + val = 0; /* 7.8us */ + } else if (refresh_rate==2) { + val = 1; /* 15.6us */ + } else if (refresh_rate==3 || refresh_rate==4) { + val = 2; /* 31.2us */ + } else { + val = 3; /* 62.4us */ + } + + sc520_mmcr->drcctl = (sc520_mmcr->drcctl & 0xcf) | (val<<4); + + val = sc520_mmcr->drctmctl & 0xf0; + + if (cas_precharge_delay==3) { + val |= 0x04; /* 3T */ + } else if (cas_precharge_delay==4) { + val |= 0x08; /* 4T */ + } else if (cas_precharge_delay>4) { + val |= 0x0c; + } + + if (ras_cas_delay > 3) { + val |= 2; + } else { + val |= 1; + } + sc520_mmcr->drctmctl = val; +#endif + + /* We read-back the configuration of the dram + * controller that the assembly code wrote */ + dram_ctrl = sc520_mmcr->drcbendadr; + + bd->bi_dram[0].start = 0; + if (dram_ctrl & 0x80) { + /* bank 0 enabled */ + dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22; + bd->bi_dram[0].size = bd->bi_dram[1].start; + + } else { + bd->bi_dram[0].size = 0; + bd->bi_dram[1].start = bd->bi_dram[0].start; + } + + if (dram_ctrl & 0x8000) { + /* bank 1 enabled */ + dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14; + bd->bi_dram[1].size = bd->bi_dram[2].start - bd->bi_dram[1].start; + } else { + bd->bi_dram[1].size = 0; + bd->bi_dram[2].start = bd->bi_dram[1].start; + } + + if (dram_ctrl & 0x800000) { + /* bank 2 enabled */ + dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6; + bd->bi_dram[2].size = bd->bi_dram[3].start - bd->bi_dram[2].start; + } else { + bd->bi_dram[2].size = 0; + bd->bi_dram[3].start = bd->bi_dram[2].start; + } + + if (dram_ctrl & 0x80000000) { + /* bank 3 enabled */ + dram_present = (dram_ctrl & 0x7f000000) >> 2; + bd->bi_dram[3].size = dram_present - bd->bi_dram[3].start; + } else { + bd->bi_dram[3].size = 0; + } + + +#if 0 + printf("Configured %d bytes of dram\n", dram_present); +#endif + gd->ram_size = dram_present; + + return dram_present; +} + +#ifdef CONFIG_SYS_SC520_RESET +void reset_cpu(ulong addr) +{ + printf("Resetting using SC520 MMCR\n"); + /* Write a '1' to the SYS_RST of the RESCFG MMCR */ + sc520_mmcr->rescfg = 0x01; + + /* NOTREACHED */ +} +#endif diff --git a/arch/i386/cpu/sc520/sc520_asm.S b/arch/i386/cpu/sc520/sc520_asm.S new file mode 100644 index 0000000000..2042d9bfcf --- /dev/null +++ b/arch/i386/cpu/sc520/sc520_asm.S @@ -0,0 +1,581 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This file is largely based on code obtned from AMD. AMD's original + * copyright is included below + */ + +/* + * ============================================================================= + * + * Copyright 1999 Advanced Micro Devices, Inc. + * + * This software is the property of Advanced Micro Devices, Inc (AMD) which + * specifically grants the user the right to modify, use and distribute this + * software provided this COPYRIGHT NOTICE is not removed or altered. All + * other rights are reserved by AMD. + * + * THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY + * OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF + * THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE. + * IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER + * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS + * INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY + * TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR + * LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE + * LIMITATION MAY NOT APPLY TO YOU. + * + * AMD does not assume any responsibility for any errors that may appear in + * the Materials nor any responsibility to support or update the Materials. + * AMD retains the right to make changes to its test specifications at any + * time, without notice. + * + * So that all may benefit from your experience, please report any problems + * or suggestions about this software back to AMD. Please include your name, + * company, telephone number, AMD product requiring support and question or + * problem encountered. + * + * Advanced Micro Devices, Inc. Worldwide support and contact + * Embedded Processor Division information available at: + * Systems Engineering epd.support@amd.com + * 5204 E. Ben White Blvd. -or- + * Austin, TX 78741 http://www.amd.com/html/support/techsup.html + * ============================================================================ + */ + + +/******************************************************************************* + * AUTHOR : Buddy Fey - Original. + ******************************************************************************* + */ + + +/******************************************************************************* + * FUNCTIONAL DESCRIPTION: + * This routine is called to autodetect the geometry of the DRAM. + * + * This routine is called to determine the number of column bits for the DRAM + * devices in this external bank. This routine assumes that the external bank + * has been configured for an 11-bit column and for 4 internal banks. This gives + * us the maximum address reach in memory. By writing a test value to the max + * address and locating where it aliases to, we can determine the number of valid + * column bits. + * + * This routine is called to determine the number of internal banks each DRAM + * device has. The external bank (under test) is configured for maximum reach + * with 11-bit columns and 4 internal banks. This routine will write to a max + * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if + * that column is a "don't care". If BA1 does not affect write/read of data, + * then this device has only 2 internal banks. + * + * This routine is called to determine the ending address for this external + * bank of SDRAM. We write to a max address with a data value and then disable + * row address bits looking for "don't care" locations. Each "don't care" bit + * represents a dividing of the maximum density (128M) by 2. By dividing the + * maximum of 32 4M chunks in an external bank down by all the "don't care" bits + * determined during sizing, we set the proper density. + * + * WARNINGS. + * bp must be preserved because it is used for return linkage. + * + * EXIT + * nothing returned - but the memory subsystem is enabled + ******************************************************************************* + */ + +#include + +.section .text +.equ DRCCTL, 0x0fffef010 /* DRAM control register */ +.equ DRCTMCTL, 0x0fffef012 /* DRAM timing control register */ +.equ DRCCFG, 0x0fffef014 /* DRAM bank configuration register */ +.equ DRCBENDADR, 0x0fffef018 /* DRAM bank ending address register */ +.equ ECCCTL, 0x0fffef020 /* DRAM ECC control register */ +.equ ECCINT, 0x0fffefd18 /* DRAM ECC nmi-INT mapping */ +.equ DBCTL, 0x0fffef040 /* DRAM buffer control register */ + +.equ CACHELINESZ, 0x00000010 /* size of our cache line (read buffer) */ +.equ COL11_ADR, 0x0e001e00 /* 11 col addrs */ +.equ COL10_ADR, 0x0e000e00 /* 10 col addrs */ +.equ COL09_ADR, 0x0e000600 /* 9 col addrs */ +.equ COL08_ADR, 0x0e000200 /* 8 col addrs */ +.equ ROW14_ADR, 0x0f000000 /* 14 row addrs */ +.equ ROW13_ADR, 0x07000000 /* 13 row addrs */ +.equ ROW12_ADR, 0x03000000 /* 12 row addrs */ +.equ ROW11_ADR, 0x01000000 /* 11 row addrs/also bank switch */ +.equ ROW10_ADR, 0x00000000 /* 10 row addrs/also bank switch */ +.equ COL11_DATA, 0x0b0b0b0b /* 11 col addrs */ +.equ COL10_DATA, 0x0a0a0a0a /* 10 col data */ +.equ COL09_DATA, 0x09090909 /* 9 col data */ +.equ COL08_DATA, 0x08080808 /* 8 col data */ +.equ ROW14_DATA, 0x3f3f3f3f /* 14 row data (MASK) */ +.equ ROW13_DATA, 0x1f1f1f1f /* 13 row data (MASK) */ +.equ ROW12_DATA, 0x0f0f0f0f /* 12 row data (MASK) */ +.equ ROW11_DATA, 0x07070707 /* 11 row data/also bank switch (MASK) */ +.equ ROW10_DATA, 0xaaaaaaaa /* 10 row data/also bank switch (MASK) */ + + + /* + * initialize dram controller registers + */ +.globl mem_init +mem_init: + xorw %ax,%ax + movl $DBCTL, %edi + movb %al, (%edi) /* disable write buffer */ + + movl $ECCCTL, %edi + movb %al, (%edi) /* disable ECC */ + + movl $DRCTMCTL, %edi + movb $0x1E,%al /* Set SDRAM timing for slowest */ + movb %al, (%edi) + + /* + * setup loop to do 4 external banks starting with bank 3 + */ + movl $0xff000000,%eax /* enable last bank and setup */ + movl $DRCBENDADR, %edi /* ending address register */ + movl %eax, (%edi) + + movl $DRCCFG, %edi /* setup */ + movw $0xbbbb,%ax /* dram config register for */ + movw %ax, (%edi) + + /* + * issue a NOP to all DRAMs + */ + movl $DRCCTL, %edi /* setup DRAM control register with */ + movb $0x1,%al /* Disable refresh,disable write buffer */ + movb %al, (%edi) + movl $CACHELINESZ, %esi /* just a dummy address to write for */ + movw %ax, (%esi) + /* + * delay for 100 usec? 200? + * ******this is a cludge for now ************* + */ + movw $100,%cx +sizdelay: + loop sizdelay /* we need 100 usec here */ + /***********************************************/ + + /* + * issue all banks precharge + */ + movb $0x2,%al /* All banks precharge */ + movb %al, (%edi) + movw %ax, (%esi) + + /* + * issue 2 auto refreshes to all banks + */ + movb $0x4,%al /* Auto refresh cmd */ + movb %al, (%edi) + movw $2,%cx +refresh1: + movw %ax, (%esi) + loop refresh1 + + /* + * issue LOAD MODE REGISTER command + */ + movb $0x3,%al /* Load mode register cmd */ + movb %al, (%edi) + movw %ax, (%esi) + + /* + * issue 8 more auto refreshes to all banks + */ + movb $0x4,%al /* Auto refresh cmd */ + movb %al, (%edi) + movw $8,%cx +refresh2: + movw %ax, (%esi) + loop refresh2 + + /* + * set control register to NORMAL mode + */ + movb $0x0,%al /* Normal mode value */ + movb %al, (%edi) + + /* + * size dram starting with external bank 3 moving to external bank 0 + */ + movl $0x3,%ecx /* start with external bank 3 */ + +nextbank: + + /* + * write col 11 wrap adr + */ + movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */ + movl $COL11_DATA, %eax /* pattern for max supported columns(11) */ + movl %eax, (%esi) /* write max col pattern at max col adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write col 10 wrap adr + */ + + movl $COL10_ADR, %esi /* set address to 10 col wrap address */ + movl $COL10_DATA, %eax /* pattern for 10 col wrap */ + movl %eax, (%esi) /* write 10 col pattern @ 10 col wrap adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write col 9 wrap adr + */ + movl $COL09_ADR, %esi /* set address to 9 col wrap address */ + movl $COL09_DATA, %eax /* pattern for 9 col wrap */ + movl %eax, (%esi) /* write 9 col pattern @ 9 col wrap adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write col 8 wrap adr + */ + movl $COL08_ADR, %esi /* set address to min(8) col wrap address */ + movl $COL08_DATA, %eax /* pattern for min (8) col wrap */ + movl %eax, (%esi) /* write min col pattern @ min col adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write row 14 wrap adr + */ + movl $ROW14_ADR, %esi /* set address to max row (14) wrap addr */ + movl $ROW14_DATA, %eax /* pattern for max supported rows(14) */ + movl %eax, (%esi) /* write max row pattern at max row adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write row 13 wrap adr + */ + movl $ROW13_ADR, %esi /* set address to 13 row wrap address */ + movl $ROW13_DATA, %eax /* pattern for 13 row wrap */ + movl %eax, (%esi) /* write 13 row pattern @ 13 row wrap adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write row 12 wrap adr + */ + movl $ROW12_ADR, %esi /* set address to 12 row wrap address */ + movl $ROW12_DATA, %eax /* pattern for 12 row wrap */ + movl %eax, (%esi) /* write 12 row pattern @ 12 row wrap adr */ + movl (%esi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write row 11 wrap adr + */ + movl $ROW11_ADR, %edi /* set address to 11 row wrap address */ + movl $ROW11_DATA, %eax /* pattern for 11 row wrap */ + movl %eax, (%edi) /* write 11 row pattern @ 11 row wrap adr */ + movl (%edi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * write row 10 wrap adr --- this write is really to determine number of banks + */ + movl $ROW10_ADR, %edi /* set address to 10 row wrap address */ + movl $ROW10_DATA, %eax /* pattern for 10 row wrap (AA) */ + movl %eax, (%edi) /* write 10 row pattern @ 10 row wrap adr */ + movl (%edi), %ebx /* optional read */ + cmpl %ebx,%eax /* to verify write */ + jnz bad_ram /* this ram is bad */ + /* + * read data @ row 12 wrap adr to determine * banks, + * and read data @ row 14 wrap adr to determine * rows. + * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM. + * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4 + * if data @ row 12 wrap == 11 or 12, we have 4 banks, + */ + xorw %di,%di /* value for 2 banks in DI */ + movl (%esi), %ebx /* read from 12 row wrap to check banks + * (esi is setup from the write to row 12 wrap) */ + cmpl %ebx,%eax /* check for AA pattern (eax holds the aa pattern) */ + jz only2 /* if pattern == AA, we only have 2 banks */ + + /* 4 banks */ + + movw $8,%di /* value for 4 banks in DI (BNK_CNT bit) */ + cmpl $ROW11_DATA, %ebx /* only other legitimate values are 11 */ + jz only2 + cmpl $ROW12_DATA, %ebx /* and 12 */ + jnz bad_ram /* its bad if not 11 or 12! */ + + /* fall through */ +only2: + /* + * validate row mask + */ + movl $ROW14_ADR, %esi /* set address back to max row wrap addr */ + movl (%esi), %eax /* read actual number of rows @ row14 adr */ + + cmpl $ROW11_DATA, %eax /* row must be greater than 11 pattern */ + jb bad_ram + + cmpl $ROW14_DATA, %eax /* and row must be less than 14 pattern */ + ja bad_ram + + cmpb %ah,%al /* verify all 4 bytes of dword same */ + jnz bad_ram + movl %eax,%ebx + shrl $16,%ebx + cmpw %bx,%ax + jnz bad_ram + /* + * read col 11 wrap adr for real column data value + */ + movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */ + movl (%esi), %eax /* read real col number at max col adr */ + /* + * validate column data + */ + cmpl $COL08_DATA, %eax /* col must be greater than 8 pattern */ + jb bad_ram + + cmpl $COL11_DATA, %eax /* and row must be less than 11 pattern */ + ja bad_ram + + subl $COL08_DATA, %eax /* normalize column data to zero */ + jc bad_ram + cmpb %ah,%al /* verify all 4 bytes of dword equal */ + jnz bad_ram + movl %eax,%edx + shrl $16,%edx + cmpw %dx,%ax + jnz bad_ram + /* + * merge bank and col data together + */ + addw %di,%dx /* merge of bank and col info in dl */ + /* + * fix ending addr mask based upon col info + */ + movb $3,%al + subb %dh,%al /* dh contains the overflow from the bank/col merge */ + movb %bl,%dh /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */ + xchgw %cx,%ax /* cx = ax = 3 or 2 depending on 2 or 4 bank device */ + shrb %cl,%dh /* */ + incb %dh /* ending addr is 1 greater than real end */ + xchgw %cx,%ax /* cx is bank number again */ + /* + * issue all banks precharge + */ +bad_reint: + movl $DRCCTL, %esi /* setup DRAM control register with */ + movb $0x2,%al /* All banks precharge */ + movb %al, (%esi) + movl $CACHELINESZ, %esi /* address to init read buffer */ + movw %ax, (%esi) + + /* + * update ENDING ADDRESS REGISTER + */ + movl $DRCBENDADR, %edi /* DRAM ending address register */ + movl %ecx,%ebx + addl %ebx, %edi + movb %dh, (%edi) + /* + * update CONFIG REGISTER + */ + xorb %dh,%dh + movw $0x00f,%bx + movw %cx,%ax + shlw $2,%ax + xchgw %cx,%ax + shlw %cl,%dx + shlw %cl,%bx + notw %bx + xchgw %cx,%ax + movl $DRCCFG, %edi + mov (%edi), %ax + andw %bx,%ax + orw %dx,%ax + movw %ax, (%edi) + jcxz cleanup + + decw %cx + movl %ecx,%ebx + movl $DRCBENDADR, %edi /* DRAM ending address register */ + movb $0xff,%al + addl %ebx, %edi + movb %al, (%edi) + /* + * set control register to NORMAL mode + */ + movl $DRCCTL, %esi /* setup DRAM control register with */ + movb $0x0,%al /* Normal mode value */ + movb %al, (%esi) + movl $CACHELINESZ, %esi /* address to init read buffer */ + movw %ax, (%esi) + jmp nextbank + +cleanup: + movl $DRCBENDADR, %edi /* DRAM ending address register */ + movw $4,%cx + xorw %ax,%ax +cleanuplp: + movb (%edi), %al + orb %al,%al + jz emptybank + + addb %ah,%al + jns nottoomuch + + movb $0x7f,%al +nottoomuch: + movb %al,%ah + orb $0x80,%al + movb %al, (%edi) +emptybank: + incl %edi + loop cleanuplp + +#if defined CONFIG_SYS_SDRAM_DRCTMCTL + /* just have your hardware desinger _GIVE_ you what you need here! */ + movl $DRCTMCTL, %edi + movb $CONFIG_SYS_SDRAM_DRCTMCTL,%al + movb (%edi), %al +#else +#if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T) + /* set the CAS latency now since it is hard to do + * when we run from the RAM */ + movl $DRCTMCTL, %edi /* DRAM timing register */ + movb (%edi), %al +#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T + andb $0xef, %al +#endif +#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T + orb $0x10, %al +#endif + movb %al, (%edi) +#endif +#endif + movl $DRCCTL, %edi /* DRAM Control register */ + movb $0x3,%al /* Load mode register cmd */ + movb %al, (%edi) + movw %ax, (%esi) + + + movl $DRCCTL, %edi /* DRAM Control register */ + movb $0x18,%al /* Enable refresh and NORMAL mode */ + movb %al, (%edi) + + jmp dram_done + +bad_ram: + xorl %edx,%edx + xorl %edi,%edi + jmp bad_reint + +dram_done: + + /* readback DRCBENDADR and return the number + * of available ram bytes in %eax */ + + movl $DRCBENDADR, %edi /* DRAM ending address register */ + + movl (%edi), %eax + movl %eax, %ecx + andl $0x80000000, %ecx + jz bank2 + andl $0x7f000000, %eax + shrl $2, %eax + movl %eax, %ebx + +bank2: movl (%edi), %eax + movl %eax, %ecx + andl $0x00800000, %ecx + jz bank1 + andl $0x007f0000, %eax + shll $6, %eax + movl %eax, %ebx + +bank1: movl (%edi), %eax + movl %eax, %ecx + andl $0x00008000, %ecx + jz bank0 + andl $0x00007f00, %eax + shll $14, %eax + movl %eax, %ebx + +bank0: movl (%edi), %eax + movl %eax, %ecx + andl $0x00000080, %ecx + jz done + andl $0x0000007f, %eax + shll $22, %eax + movl %eax, %ebx + + +done: + movl %ebx, %eax + +#if CONFIG_SYS_SDRAM_ECC_ENABLE + /* A nominal memory test: just a byte at each address line */ + movl %eax, %ecx + shrl $0x1, %ecx + movl $0x1, %edi +memtest0: + movb $0xa5, (%edi) + cmpb $0xa5, (%edi) + jne out + shrl $1, %ecx + andl %ecx,%ecx + jz set_ecc + shll $1, %edi + jmp memtest0 + +set_ecc: + /* clear all ram with a memset */ + movl %eax, %ecx + xorl %esi, %esi + xorl %edi, %edi + xorl %eax, %eax + shrl $2, %ecx + cld + rep stosl + /* enable read, write buffers */ + movb $0x11, %al + movl $DBCTL, %edi + movb %al, (%edi) + /* enable NMI mapping for ECC */ + movl $ECCINT, %edi + mov $0x10, %al + movb %al, (%edi) + /* Turn on ECC */ + movl $ECCCTL, %edi + mov $0x05, %al + movb %al, (%edi) +#endif +out: + movl %ebx, %eax + jmp *%ebp diff --git a/arch/i386/cpu/sc520/sc520_pci.c b/arch/i386/cpu/sc520/sc520_pci.c new file mode 100644 index 0000000000..f446c6d592 --- /dev/null +++ b/arch/i386/cpu/sc520/sc520_pci.c @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* stuff specific for the sc520, but independent of implementation */ + +#include +#include +#include +#include + +static struct { + u8 priority; + u16 level_reg; + u8 level_bit; +} sc520_irq[] = { + { SC520_IRQ0, 0, 0x01 }, + { SC520_IRQ1, 0, 0x02 }, + { SC520_IRQ2, 1, 0x02 }, + { SC520_IRQ3, 0, 0x08 }, + { SC520_IRQ4, 0, 0x10 }, + { SC520_IRQ5, 0, 0x20 }, + { SC520_IRQ6, 0, 0x40 }, + { SC520_IRQ7, 0, 0x80 }, + + { SC520_IRQ8, 1, 0x01 }, + { SC520_IRQ9, 1, 0x02 }, + { SC520_IRQ10, 1, 0x04 }, + { SC520_IRQ11, 1, 0x08 }, + { SC520_IRQ12, 1, 0x10 }, + { SC520_IRQ13, 1, 0x20 }, + { SC520_IRQ14, 1, 0x40 }, + { SC520_IRQ15, 1, 0x80 } +}; + + +/* The interrupt used for PCI INTA-INTD */ +int sc520_pci_ints[15] = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1 +}; + +/* utility function to configure a pci interrupt */ +int pci_sc520_set_irq(int pci_pin, int irq) +{ + int i; + +# if 1 + printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq); +#endif + if (irq < 0 || irq > 15) { + return -1; /* illegal irq */ + } + + if (pci_pin < 0 || pci_pin > 15) { + return -1; /* illegal pci int pin */ + } + + /* first disable any non-pci interrupt source that use + * this level */ + + /* PCI interrupt mapping (A through D)*/ + for (i=0; i<=3 ;i++) { + if (sc520_mmcr->pci_int_map[i] == sc520_irq[irq].priority) + sc520_mmcr->pci_int_map[i] = SC520_IRQ_DISABLED; + } + + /* GP IRQ interrupt mapping */ + for (i=0; i<=10 ;i++) { + if (sc520_mmcr->gp_int_map[i] == sc520_irq[irq].priority) + sc520_mmcr->gp_int_map[i] = SC520_IRQ_DISABLED; + } + + /* Set the trigger to level */ + sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] = + sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] | sc520_irq[irq].level_bit; + + + if (pci_pin < 4) { + /* PCI INTA-INTD */ + /* route the interrupt */ + sc520_mmcr->pci_int_map[pci_pin] = sc520_irq[irq].priority; + } else { + /* GPIRQ0-GPIRQ10 used for additional PCI INTS */ + sc520_mmcr->gp_int_map[pci_pin - 4] = sc520_irq[irq].priority; + + /* also set the polarity in this case */ + sc520_mmcr->intpinpol = sc520_mmcr->intpinpol | (1 << (pci_pin-4)); + } + + /* register the pin */ + sc520_pci_ints[pci_pin] = irq; + + + return 0; /* OK */ +} + +void pci_sc520_init(struct pci_controller *hose) +{ + hose->first_busno = 0; + hose->last_busno = 0xff; + + /* System memory space */ + pci_set_region(hose->regions + 0, + SC520_PCI_MEMORY_BUS, + SC520_PCI_MEMORY_PHYS, + SC520_PCI_MEMORY_SIZE, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + /* PCI memory space */ + pci_set_region(hose->regions + 1, + SC520_PCI_MEM_BUS, + SC520_PCI_MEM_PHYS, + SC520_PCI_MEM_SIZE, + PCI_REGION_MEM); + + /* ISA/PCI memory space */ + pci_set_region(hose->regions + 2, + SC520_ISA_MEM_BUS, + SC520_ISA_MEM_PHYS, + SC520_ISA_MEM_SIZE, + PCI_REGION_MEM); + + /* PCI I/O space */ + pci_set_region(hose->regions + 3, + SC520_PCI_IO_BUS, + SC520_PCI_IO_PHYS, + SC520_PCI_IO_SIZE, + PCI_REGION_IO); + + /* ISA/PCI I/O space */ + pci_set_region(hose->regions + 4, + SC520_ISA_IO_BUS, + SC520_ISA_IO_PHYS, + SC520_ISA_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 5; + + pci_setup_type1(hose, + SC520_REG_ADDR, + SC520_REG_DATA); + + pci_register_hose(hose); + + hose->last_busno = pci_hose_scan(hose); + + /* enable target memory acceses on host brige */ + pci_write_config_word(0, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + +} diff --git a/arch/i386/cpu/sc520/sc520_ssi.c b/arch/i386/cpu/sc520/sc520_ssi.c new file mode 100644 index 0000000000..8dbe17aa60 --- /dev/null +++ b/arch/i386/cpu/sc520/sc520_ssi.c @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* stuff specific for the sc520, but independent of implementation */ + +#include +#include +#include + +int ssi_set_interface(int freq, int lsb_first, int inv_clock, int inv_phase) +{ + u8 temp=0; + + if (freq >= 8192) { + temp |= CTL_CLK_SEL_4; + } else if (freq >= 4096) { + temp |= CTL_CLK_SEL_8; + } else if (freq >= 2048) { + temp |= CTL_CLK_SEL_16; + } else if (freq >= 1024) { + temp |= CTL_CLK_SEL_32; + } else if (freq >= 512) { + temp |= CTL_CLK_SEL_64; + } else if (freq >= 256) { + temp |= CTL_CLK_SEL_128; + } else if (freq >= 128) { + temp |= CTL_CLK_SEL_256; + } else { + temp |= CTL_CLK_SEL_512; + } + + if (!lsb_first) { + temp |= MSBF_ENB; + } + + if (inv_clock) { + temp |= CLK_INV_ENB; + } + + if (inv_phase) { + temp |= PHS_INV_ENB; + } + + sc520_mmcr->ssictl = temp; + + return 0; +} + +u8 ssi_txrx_byte(u8 data) +{ + sc520_mmcr->ssixmit = data; + while (sc520_mmcr->ssista & SSISTA_BSY); + sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMITRCV; + while (sc520_mmcr->ssista & SSISTA_BSY); + + return sc520_mmcr->ssircv; +} + + +void ssi_tx_byte(u8 data) +{ + sc520_mmcr->ssixmit = data; + while (sc520_mmcr->ssista & SSISTA_BSY); + sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMIT; +} + +u8 ssi_rx_byte(void) +{ + while (sc520_mmcr->ssista & SSISTA_BSY); + sc520_mmcr->ssicmd = SSICMD_CMD_SEL_RCV; + while (sc520_mmcr->ssista & SSISTA_BSY); + + return sc520_mmcr->ssircv; +} diff --git a/arch/i386/cpu/sc520/sc520_timer.c b/arch/i386/cpu/sc520/sc520_timer.c new file mode 100644 index 0000000000..93b5b555c3 --- /dev/null +++ b/arch/i386/cpu/sc520/sc520_timer.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* stuff specific for the sc520, but independent of implementation */ + +#include +#include +#include + +void sc520_timer_isr(void) +{ + /* Ack the GP Timer Interrupt */ + sc520_mmcr->gptmrsta = 0x02; +} + +int timer_init(void) +{ + /* Register the SC520 specific timer interrupt handler */ + register_timer_isr (sc520_timer_isr); + + /* Install interrupt handler for GP Timer 1 */ + irq_install_handler (0, timer_isr, NULL); + + /* Map GP Timer 1 to Master PIC IR0 */ + sc520_mmcr->gp_tmr_int_map[1] = 0x01; + + /* Disable GP Timers 1 & 2 - Allow configuration writes */ + sc520_mmcr->gptmr1ctl = 0x4000; + sc520_mmcr->gptmr2ctl = 0x4000; + + /* Reset GP Timers 1 & 2 */ + sc520_mmcr->gptmr1cnt = 0x0000; + sc520_mmcr->gptmr2cnt = 0x0000; + + /* Setup GP Timer 2 as a 100kHz (10us) prescaler */ + sc520_mmcr->gptmr2maxcmpa = 83; + sc520_mmcr->gptmr2ctl = 0xc001; + + /* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */ + sc520_mmcr->gptmr1maxcmpa = 100; + sc520_mmcr->gptmr1ctl = 0xe009; + + unmask_irq (0); + + /* Clear the GP Timer 1 status register to get the show rolling*/ + sc520_mmcr->gptmrsta = 0x02; + + return 0; +} + +void __udelay(unsigned long usec) +{ + int m = 0; + long u; + long temp; + + temp = sc520_mmcr->swtmrmilli; + temp = sc520_mmcr->swtmrmicro; + + do { + m += sc520_mmcr->swtmrmilli; + u = sc520_mmcr->swtmrmicro + (m * 1000); + } while (u < usec); +} diff --git a/arch/i386/cpu/serial.c b/arch/i386/cpu/serial.c new file mode 100644 index 0000000000..e7025a3cdc --- /dev/null +++ b/arch/i386/cpu/serial.c @@ -0,0 +1,506 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +/*------------------------------------------------------------------------------+ */ + +/* + * This source code is dual-licensed. You may use it under the terms of the + * GNU General Public License version 2, or under the license below. + * + * This source code has been made available to you by IBM on an AS-IS + * basis. Anyone receiving this source is licensed under IBM + * copyrights to use it in any way he or she deems fit, including + * copying it, modifying it, compiling it, and redistributing it either + * with or without modifications. No license under IBM patents or + * patent applications is to be implied by the copyright license. + * + * Any user of this software should understand that IBM cannot provide + * technical support for this software and will not be responsible for + * any consequences resulting from the use of this software. + * + * Any person who transfers this source code or any derivative work + * must include the IBM copyright notice, this paragraph, and the + * preceding two paragraphs in the transferred software. + * + * COPYRIGHT I B M CORPORATION 1995 + * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + */ +/*------------------------------------------------------------------------------- */ + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_RBR 0x00 +#define UART_THR 0x00 +#define UART_IER 0x01 +#define UART_IIR 0x02 +#define UART_FCR 0x02 +#define UART_LCR 0x03 +#define UART_MCR 0x04 +#define UART_LSR 0x05 +#define UART_MSR 0x06 +#define UART_SCR 0x07 +#define UART_DLL 0x00 +#define UART_DLM 0x01 + +/*-----------------------------------------------------------------------------+ + | Line Status Register. + +-----------------------------------------------------------------------------*/ +#define asyncLSRDataReady1 0x01 +#define asyncLSROverrunError1 0x02 +#define asyncLSRParityError1 0x04 +#define asyncLSRFramingError1 0x08 +#define asyncLSRBreakInterrupt1 0x10 +#define asyncLSRTxHoldEmpty1 0x20 +#define asyncLSRTxShiftEmpty1 0x40 +#define asyncLSRRxFifoError1 0x80 + + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO +/*-----------------------------------------------------------------------------+ + | Fifo + +-----------------------------------------------------------------------------*/ +typedef struct { + char *rx_buffer; + ulong rx_put; + ulong rx_get; + int cts; +} serial_buffer_t; + +volatile serial_buffer_t buf_info; +static int serial_buffer_active=0; +#endif + + +static int serial_div(int baudrate) +{ + + switch (baudrate) { + case 1200: + return 96; + case 9600: + return 12; + case 19200: + return 6; + case 38400: + return 3; + case 57600: + return 2; + case 115200: + return 1; + } + + return 12; +} + + +/* + * Minimal serial functions needed to use one of the SMC ports + * as serial console interface. + */ + +int serial_init(void) +{ + volatile char val; + int bdiv = serial_div(gd->baudrate); + + outb(0x80, UART0_BASE + UART_LCR); /* set DLAB bit */ + outb(bdiv, UART0_BASE + UART_DLL); /* set baudrate divisor */ + outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */ + outb(0x03, UART0_BASE + UART_LCR); /* clear DLAB; set 8 bits, no parity */ + outb(0x01, UART0_BASE + UART_FCR); /* enable FIFO */ + outb(0x0b, UART0_BASE + UART_MCR); /* Set DTR and RTS active */ + val = inb(UART0_BASE + UART_LSR); /* clear line status */ + val = inb(UART0_BASE + UART_RBR); /* read receive buffer */ + outb(0x00, UART0_BASE + UART_SCR); /* set scratchpad */ + outb(0x00, UART0_BASE + UART_IER); /* set interrupt enable reg */ + + return 0; +} + + +void serial_setbrg(void) +{ + unsigned short bdiv; + + bdiv = serial_div(gd->baudrate); + + outb(0x80, UART0_BASE + UART_LCR); /* set DLAB bit */ + outb(bdiv&0xff, UART0_BASE + UART_DLL); /* set baudrate divisor */ + outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */ + outb(0x03, UART0_BASE + UART_LCR); /* clear DLAB; set 8 bits, no parity */ +} + + +void serial_putc(const char c) +{ + int i; + + if (c == '\n') + serial_putc ('\r'); + + /* check THRE bit, wait for transmiter available */ + for (i = 1; i < 3500; i++) { + if ((inb (UART0_BASE + UART_LSR) & 0x20) == 0x20) { + break; + } + udelay(100); + } + outb(c, UART0_BASE + UART_THR); /* put character out */ +} + + +void serial_puts(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + + +int serial_getc(void) +{ + unsigned char status = 0; + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO + if (serial_buffer_active) { + return serial_buffered_getc(); + } +#endif + + while (1) { +#if defined(CONFIG_HW_WATCHDOG) + WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */ +#endif /* CONFIG_HW_WATCHDOG */ + status = inb(UART0_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + break; + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + outb(asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR); + } + } + return (0x000000ff & (int) inb (UART0_BASE)); +} + + +int serial_tstc(void) +{ + unsigned char status; + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO + if (serial_buffer_active) { + return serial_buffered_tstc(); + } +#endif + + status = inb(UART0_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + return (1); + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + outb(asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR); + } + return 0; +} + + +#ifdef CONFIG_SERIAL_SOFTWARE_FIFO + +void serial_isr(void *arg) +{ + int space; + int c; + int rx_put = buf_info.rx_put; + + if (buf_info.rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - buf_info.rx_get); + } else { + space = buf_info.rx_get - rx_put; + } + + while (inb(UART0_BASE + UART_LSR) & 1) { + c = inb(UART0_BASE); + if (space) { + buf_info.rx_buffer[rx_put++] = c; + space--; + + if (rx_put == buf_info.rx_get) { + buf_info.rx_get++; + if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) { + buf_info.rx_get = 0; + } + } + + if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) { + rx_put = 0; + if (0 == buf_info.rx_get) { + buf_info.rx_get = 1; + } + + } + + } + if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) { + /* Stop flow by setting RTS inactive */ + outb(inb(UART0_BASE + UART_MCR) & (0xFF ^ 0x02), + UART0_BASE + UART_MCR); + } + } + buf_info.rx_put = rx_put; +} + +void serial_buffered_init(void) +{ + serial_puts ("Switching to interrupt driven serial input mode.\n"); + buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO); + buf_info.rx_put = 0; + buf_info.rx_get = 0; + + if (inb (UART0_BASE + UART_MSR) & 0x10) { + serial_puts ("Check CTS signal present on serial port: OK.\n"); + buf_info.cts = 1; + } else { + serial_puts ("WARNING: CTS signal not present on serial port.\n"); + buf_info.cts = 0; + } + + irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ , + serial_isr /*interrupt_handler_t *handler */ , + (void *) &buf_info /*void *arg */ ); + + /* Enable "RX Data Available" Interrupt on UART */ + /* outb(inb(UART0_BASE + UART_IER) |0x01, UART0_BASE + UART_IER); */ + outb(0x01, UART0_BASE + UART_IER); + + /* Set DTR and RTS active, enable interrupts */ + outb(inb (UART0_BASE + UART_MCR) | 0x0b, UART0_BASE + UART_MCR); + + /* Setup UART FIFO: RX trigger level: 1 byte, Enable FIFO */ + outb( /*(1 << 6) |*/ 1, UART0_BASE + UART_FCR); + + serial_buffer_active = 1; +} + +void serial_buffered_putc (const char c) +{ + int i; + /* Wait for CTS */ +#if defined(CONFIG_HW_WATCHDOG) + while (!(inb (UART0_BASE + UART_MSR) & 0x10)) + WATCHDOG_RESET (); +#else + if (buf_info.cts) { + for (i=0;i<1000;i++) { + if ((inb (UART0_BASE + UART_MSR) & 0x10)) { + break; + } + } + if (i!=1000) { + buf_info.cts = 0; + } + } else { + if ((inb (UART0_BASE + UART_MSR) & 0x10)) { + buf_info.cts = 1; + } + } + +#endif + serial_putc (c); +} + +void serial_buffered_puts(const char *s) +{ + serial_puts (s); +} + +int serial_buffered_getc(void) +{ + int space; + int c; + int rx_get = buf_info.rx_get; + int rx_put; + +#if defined(CONFIG_HW_WATCHDOG) + while (rx_get == buf_info.rx_put) + WATCHDOG_RESET (); +#else + while (rx_get == buf_info.rx_put); +#endif + c = buf_info.rx_buffer[rx_get++]; + if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO) { + rx_get = 0; + } + buf_info.rx_get = rx_get; + + rx_put = buf_info.rx_put; + if (rx_get <= rx_put) { + space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); + } else { + space = rx_get - rx_put; + } + if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) { + /* Start flow by setting RTS active */ + outb(inb (UART0_BASE + UART_MCR) | 0x02, UART0_BASE + UART_MCR); + } + + return c; +} + +int serial_buffered_tstc(void) +{ + return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0; +} + +#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */ + + +#if defined(CONFIG_CMD_KGDB) +/* + AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port + number 0 or number 1 + - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 : + configuration has been already done + - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 : + configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE +*/ +#if (CONFIG_KGDB_SER_INDEX & 2) +void kgdb_serial_init(void) +{ + volatile char val; + bdiv = serial_div (CONFIG_KGDB_BAUDRATE); + + /* + * Init onboard 16550 UART + */ + outb(0x80, UART1_BASE + UART_LCR); /* set DLAB bit */ + outb((bdiv & 0xff), UART1_BASE + UART_DLL); /* set divisor for 9600 baud */ + outb((bdiv >> 8 ), UART1_BASE + UART_DLM); /* set divisor for 9600 baud */ + outb(0x03, UART1_BASE + UART_LCR); /* line control 8 bits no parity */ + outb(0x00, UART1_BASE + UART_FCR); /* disable FIFO */ + outb(0x00, UART1_BASE + UART_MCR); /* no modem control DTR RTS */ + val = inb(UART1_BASE + UART_LSR); /* clear line status */ + val = inb(UART1_BASE + UART_RBR); /* read receive buffer */ + outb(0x00, UART1_BASE + UART_SCR); /* set scratchpad */ + outb(0x00, UART1_BASE + UART_IER); /* set interrupt enable reg */ +} + + +void putDebugChar(const char c) +{ + if (c == '\n') + serial_putc ('\r'); + + outb(c, UART1_BASE + UART_THR); /* put character out */ + + /* check THRE bit, wait for transfer done */ + while ((inb(UART1_BASE + UART_LSR) & 0x20) != 0x20); +} + + +void putDebugStr(const char *s) +{ + while (*s) { + serial_putc(*s++); + } +} + + +int getDebugChar(void) +{ + unsigned char status = 0; + + while (1) { + status = inb(UART1_BASE + UART_LSR); + if ((status & asyncLSRDataReady1) != 0x0) { + break; + } + if ((status & ( asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1 )) != 0) { + outb(asyncLSRFramingError1 | + asyncLSROverrunError1 | + asyncLSRParityError1 | + asyncLSRBreakInterrupt1, UART1_BASE + UART_LSR); + } + } + return (0x000000ff & (int) inb(UART1_BASE)); +} + + +void kgdb_interruptible(int yes) +{ + return; +} + +#else /* ! (CONFIG_KGDB_SER_INDEX & 2) */ + +void kgdb_serial_init(void) +{ + serial_printf ("[on serial] "); +} + +void putDebugChar(int c) +{ + serial_putc (c); +} + +void putDebugStr(const char *str) +{ + serial_puts (str); +} + +int getDebugChar(void) +{ + return serial_getc (); +} + +void kgdb_interruptible(int yes) +{ + return; +} +#endif /* (CONFIG_KGDB_SER_INDEX & 2) */ +#endif diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S new file mode 100644 index 0000000000..25d32e658e --- /dev/null +++ b/arch/i386/cpu/start.S @@ -0,0 +1,135 @@ +/* + * U-boot - i386 Startup Code + * + * Copyright (c) 2002 Omicron Ceti AB, Daniel Engström + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include +#include + + +.section .text +.code32 +.globl _start +.type _start, @function +.globl _i386boot_start +_i386boot_start: +_start: + movl $0x18,%eax /* Load our segement registes, the + * gdt have already been loaded by start16.S */ + movw %ax,%fs + movw %ax,%ds + movw %ax,%gs + movw %ax,%es + movw %ax,%ss + + /* We call a few functions in the board support package + * since we have no stack yet we'll have to use %ebp + * to store the return address */ + + /* Early platform init (setup gpio, etc ) */ + mov $early_board_init_ret, %ebp + jmp early_board_init +early_board_init_ret: + + /* The __port80 entry-point should be usabe by now */ + /* so we try to indicate progress */ + movw $0x01, %ax + movl $.progress0, %ebp + jmp show_boot_progress_asm +.progress0: + + /* size memory */ + mov $mem_init_ret, %ebp + jmp mem_init +mem_init_ret: + + /* Check we have enough memory for stack */ + movl $CONFIG_SYS_STACK_SIZE, %ecx + cmpl %ecx, %eax + jae mem_ok + + /* indicate (lack of) progress */ + movw $0x81, %ax + movl $.progress0a, %ebp + jmp show_boot_progress_asm +.progress0a: + jmp die +mem_ok: + /* Set stack pointer to upper memory limit*/ + movl %eax, %esp + + /* indicate progress */ + movw $0x02, %ax + movl $.progress1, %ebp + jmp show_boot_progress_asm +.progress1: + + /* Test the stack */ + pushl $0 + popl %eax + cmpl $0, %eax + jne no_stack + push $0x55aa55aa + popl %ebx + cmpl $0x55aa55aa, %ebx + je stack_ok + +no_stack: + /* indicate (lack of) progress */ + movw $0x82, %ax + movl $.progress1a, %ebp + jmp show_boot_progress_asm +.progress1a: + jmp die + + +stack_ok: + /* indicate progress */ + movw $0x03, %ax + movl $.progress2, %ebp + jmp show_boot_progress_asm +.progress2: + + wbinvd + + /* Get upper memory limit */ + movl %esp, %ecx + subl $CONFIG_SYS_STACK_SIZE, %ecx + + /* Create a Stack Frame */ + pushl %ebp + movl %esp, %ebp + + /* stack_limit parameter */ + pushl %ecx + call board_init_f /* Enter, U-boot! */ + + /* indicate (lack of) progress */ + movw $0x85, %ax + movl $.progress4a, %ebp + jmp show_boot_progress_asm +.progress4a: + +die: hlt + jmp die + hlt diff --git a/arch/i386/cpu/start16.S b/arch/i386/cpu/start16.S new file mode 100644 index 0000000000..1ebb6bc8b6 --- /dev/null +++ b/arch/i386/cpu/start16.S @@ -0,0 +1,112 @@ +/* + * U-boot - i386 Startup Code + * + * Copyright (c) 2002, 2003 Omicron Ceti AB, Daniel Engström + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#define BOOT_SEG 0xffff0000 /* linear segment of boot code */ +#define a32 .byte 0x67; +#define o32 .byte 0x66; + +.section .start16, "ax" +.code16 +.globl start16 +start16: + /* First we let the BSP do some early initialization + * this code have to map the flash to its final position + */ + mov $board_init16_ret, %bp + jmp board_init16 +board_init16_ret: + + /* Turn of cache (this might require a 486-class CPU) */ + movl %cr0, %eax + orl $0x60000000,%eax + movl %eax, %cr0 + wbinvd + + /* load the descriptor tables */ +o32 cs lidt idt_ptr +o32 cs lgdt gdt_ptr + + + /* Now, we enter protected mode */ + movl %cr0, %eax + orl $1,%eax + movl %eax, %cr0 + + /* Flush the prefetch queue */ + jmp ff +ff: + + /* Finally jump to the 32bit initialization code */ + movw $code32start, %ax + movw %ax,%bp +o32 cs ljmp *(%bp) + + /* 48-bit far pointer */ +code32start: + .long _start /* offset */ + .word 0x10 /* segment */ + +idt_ptr: + .word 0 /* limit */ + .long 0 /* base */ + +gdt_ptr: + .word 0x30 /* limit (48 bytes = 6 GDT entries) */ + .long BOOT_SEG + gdt /* base */ + + /* The GDT table ... + * + * Selector Type + * 0x00 NULL + * 0x08 Unused + * 0x10 32bit code + * 0x18 32bit data/stack + * 0x20 16bit code + * 0x28 16bit data/stack + */ + +gdt: + .word 0, 0, 0, 0 /* NULL */ + .word 0, 0, 0, 0 /* unused */ + + .word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */ + .word 0 /* base address = 0 */ + .word 0x9B00 /* code read/exec */ + .word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */ + + .word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */ + .word 0x0 /* base address = 0 */ + .word 0x9300 /* data read/write */ + .word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */ + + .word 0xFFFF /* 64kb */ + .word 0 /* base address = 0 */ + .word 0x9b00 /* data read/write */ + .word 0x0010 /* granularity = 1 (+5th nibble of limit) */ + + .word 0xFFFF /* 64kb */ + .word 0 /* base address = 0 */ + .word 0x9300 /* data read/write */ + .word 0x0010 /* granularity = 1 (+5th nibble of limit) */ diff --git a/arch/i386/include/asm/interrupt.h b/arch/i386/include/asm/interrupt.h index 8d324d9f37..07426fe6a7 100644 --- a/arch/i386/include/asm/interrupt.h +++ b/arch/i386/include/asm/interrupt.h @@ -27,7 +27,7 @@ #ifndef __ASM_INTERRUPT_H_ #define __ASM_INTERRUPT_H_ 1 -/* cpu/i386/interrupts.c */ +/* arch/i386/cpu/interrupts.c */ void set_vector(u8 intnum, void *routine); /* arch/i386/lib/interupts.c */ diff --git a/arch/i386/include/asm/u-boot-i386.h b/arch/i386/include/asm/u-boot-i386.h index a08632d2d3..521fd352bb 100644 --- a/arch/i386/include/asm/u-boot-i386.h +++ b/arch/i386/include/asm/u-boot-i386.h @@ -33,7 +33,7 @@ void timer_isr(void *); typedef void (timer_fnc_t) (void); int register_timer_isr (timer_fnc_t *isr_func); -/* Architecture specific - can be in cpu/i386/, arch/i386/lib/, or $(BOARD)/ */ +/* Architecture specific - can be in arch/i386/cpu/, arch/i386/lib/, or $(BOARD)/ */ int timer_init(void); /* cpu/.../interrupts.c */ diff --git a/cpu/i386/Makefile b/cpu/i386/Makefile deleted file mode 100644 index c658c6e459..0000000000 --- a/cpu/i386/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2002 -# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB = $(obj)lib$(CPU).a - -START = start.o start16.o resetvec.o -COBJS = serial.o interrupts.o cpu.o - -SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) -START := $(addprefix $(obj),$(START)) - -all: $(obj).depend $(START) $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### diff --git a/cpu/i386/config.mk b/cpu/i386/config.mk deleted file mode 100644 index 16a160d2f3..0000000000 --- a/cpu/i386/config.mk +++ /dev/null @@ -1,26 +0,0 @@ -# -# (C) Copyright 2002 -# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -PLATFORM_RELFLAGS += - -PLATFORM_CPPFLAGS += -march=i386 -Werror diff --git a/cpu/i386/cpu.c b/cpu/i386/cpu.c deleted file mode 100644 index 3010519e74..0000000000 --- a/cpu/i386/cpu.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * CPU specific code - */ - -#include -#include -#include - -int cpu_init_f(void) -{ - /* initialize FPU, reset EM, set MP and NE */ - asm ("fninit\n" \ - "movl %cr0, %eax\n" \ - "andl $~0x4, %eax\n" \ - "orl $0x22, %eax\n" \ - "movl %eax, %cr0\n" ); - - return 0; -} - -int cpu_init_r(void) -{ - /* Initialize core interrupt and exception functionality of CPU */ - cpu_init_interrupts (); - return 0; -} - -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) -{ - printf ("resetting ...\n"); - udelay(50000); /* wait 50 ms */ - disable_interrupts(); - reset_cpu(0); - - /*NOTREACHED*/ - return 0; -} - -void flush_cache (unsigned long dummy1, unsigned long dummy2) -{ - asm("wbinvd\n"); - return; -} - -void __attribute__ ((regparm(0))) generate_gpf(void); - -/* segment 0x70 is an arbitrary segment which does not exist */ -asm(".globl generate_gpf\n" - ".hidden generate_gpf\n" - ".type generate_gpf, @function\n" - "generate_gpf:\n" - "ljmp $0x70, $0x47114711\n"); - -void __reset_cpu(ulong addr) -{ - printf("Resetting using i386 Triple Fault\n"); - set_vector(13, generate_gpf); /* general protection fault handler */ - set_vector(8, generate_gpf); /* double fault handler */ - generate_gpf(); /* start the show */ -} -void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu"))); diff --git a/cpu/i386/interrupts.c b/cpu/i386/interrupts.c deleted file mode 100644 index 4b57437193..0000000000 --- a/cpu/i386/interrupts.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * (C) Copyright 2008 - * Graeme Russ, graeme.russ@gmail.com. - * - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#define DECLARE_INTERRUPT(x) \ - ".globl irq_"#x"\n" \ - ".hidden irq_"#x"\n" \ - ".type irq_"#x", @function\n" \ - "irq_"#x":\n" \ - "pushl %ebp\n" \ - "movl %esp,%ebp\n" \ - "pusha\n" \ - "pushl $"#x"\n" \ - "jmp irq_common_entry\n" - -struct idt_entry { - u16 base_low; - u16 selector; - u8 res; - u8 access; - u16 base_high; -} __attribute__ ((packed)); - -struct desc_ptr { - unsigned short size; - unsigned long address; - unsigned short segment; -} __attribute__((packed)); - -struct idt_entry idt[256]; - -struct desc_ptr idt_ptr; - -static inline void load_idt(const struct desc_ptr *dtr) -{ - asm volatile("cs lidt %0"::"m" (*dtr)); -} - -void set_vector(u8 intnum, void *routine) -{ - idt[intnum].base_high = (u16)((u32)(routine) >> 16); - idt[intnum].base_low = (u16)((u32)(routine) & 0xffff); -} - -void irq_0(void); -void irq_1(void); - -int cpu_init_interrupts(void) -{ - int i; - - int irq_entry_size = irq_1 - irq_0; - void *irq_entry = (void *)irq_0; - - /* Just in case... */ - disable_interrupts(); - - /* Setup the IDT */ - for (i=0;i<256;i++) { - idt[i].access = 0x8e; - idt[i].res = 0; - idt[i].selector = 0x10; - set_vector(i, irq_entry); - irq_entry += irq_entry_size; - } - - idt_ptr.size = 256 * 8; - idt_ptr.address = (unsigned long) idt; - idt_ptr.segment = 0x18; - - load_idt(&idt_ptr); - - /* It is now safe to enable interrupts */ - enable_interrupts(); - - return 0; -} - -void __do_irq(int irq) -{ - printf("Unhandled IRQ : %d\n", irq); -} -void do_irq(int irq) __attribute__((weak, alias("__do_irq"))); - -void enable_interrupts(void) -{ - asm("sti\n"); -} - -int disable_interrupts(void) -{ - long flags; - - asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); - - return (flags&0x200); /* IE flags is bit 9 */ -} - -/* IRQ Low-Level Service Routine */ -__isr__ irq_llsr(int ip, int seg, int irq) -{ - /* - * For detailed description of each exception, refer to: - * Intel® 64 and IA-32 Architectures Software Developer's Manual - * Volume 1: Basic Architecture - * Order Number: 253665-029US, November 2008 - * Table 6-1. Exceptions and Interrupts - */ - switch (irq) { - case 0x00: - printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x01: - printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip); - break; - case 0x02: - printf("NMI Interrupt at %04x:%08x\n", seg, ip); - break; - case 0x03: - printf("Breakpoint at %04x:%08x\n", seg, ip); - break; - case 0x04: - printf("Overflow at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x05: - printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x06: - printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x07: - printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x08: - printf("Double fault at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x09: - printf("Co-processor segment overrun at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x0a: - printf("Invalid TSS at %04x:%08x\n", seg, ip); - break; - case 0x0b: - printf("Segment Not Present at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x0c: - printf("Stack Segment Fault at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x0d: - printf("General Protection at %04x:%08x\n", seg, ip); - break; - case 0x0e: - printf("Page fault at %04x:%08x\n", seg, ip); - while(1); - break; - case 0x0f: - printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip); - break; - case 0x10: - printf("Alignment check at %04x:%08x\n", seg, ip); - break; - case 0x11: - printf("Machine Check at %04x:%08x\n", seg, ip); - break; - case 0x12: - printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip); - break; - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: - printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip); - break; - - default: - /* Hardware or User IRQ */ - do_irq(irq); - } -} - -/* - * OK - This looks really horrible, but it serves a purpose - It helps create - * fully relocatable code. - * - The call to irq_llsr will be a relative jump - * - The IRQ entries will be guaranteed to be in order - * It's a bit annoying that we need to waste 3 bytes per interrupt entry - * (total of 768 code bytes), but we MUST create a Stack Frame and this is - * the easiest way I could do it. Maybe it can be made better later. - */ -asm(".globl irq_common_entry\n" \ - ".hidden irq_common_entry\n" \ - ".type irq_common_entry, @function\n" \ - "irq_common_entry:\n" \ - "pushl $0\n" \ - "pushl $0\n" \ - "call irq_llsr\n" \ - "popl %eax\n" \ - "popl %eax\n" \ - "popl %eax\n" \ - "popa\n" \ - "leave\n"\ - "iret\n" \ - DECLARE_INTERRUPT(0) \ - DECLARE_INTERRUPT(1) \ - DECLARE_INTERRUPT(2) \ - DECLARE_INTERRUPT(3) \ - DECLARE_INTERRUPT(4) \ - DECLARE_INTERRUPT(5) \ - DECLARE_INTERRUPT(6) \ - DECLARE_INTERRUPT(7) \ - DECLARE_INTERRUPT(8) \ - DECLARE_INTERRUPT(9) \ - DECLARE_INTERRUPT(10) \ - DECLARE_INTERRUPT(11) \ - DECLARE_INTERRUPT(12) \ - DECLARE_INTERRUPT(13) \ - DECLARE_INTERRUPT(14) \ - DECLARE_INTERRUPT(15) \ - DECLARE_INTERRUPT(16) \ - DECLARE_INTERRUPT(17) \ - DECLARE_INTERRUPT(18) \ - DECLARE_INTERRUPT(19) \ - DECLARE_INTERRUPT(20) \ - DECLARE_INTERRUPT(21) \ - DECLARE_INTERRUPT(22) \ - DECLARE_INTERRUPT(23) \ - DECLARE_INTERRUPT(24) \ - DECLARE_INTERRUPT(25) \ - DECLARE_INTERRUPT(26) \ - DECLARE_INTERRUPT(27) \ - DECLARE_INTERRUPT(28) \ - DECLARE_INTERRUPT(29) \ - DECLARE_INTERRUPT(30) \ - DECLARE_INTERRUPT(31) \ - DECLARE_INTERRUPT(32) \ - DECLARE_INTERRUPT(33) \ - DECLARE_INTERRUPT(34) \ - DECLARE_INTERRUPT(35) \ - DECLARE_INTERRUPT(36) \ - DECLARE_INTERRUPT(37) \ - DECLARE_INTERRUPT(38) \ - DECLARE_INTERRUPT(39) \ - DECLARE_INTERRUPT(40) \ - DECLARE_INTERRUPT(41) \ - DECLARE_INTERRUPT(42) \ - DECLARE_INTERRUPT(43) \ - DECLARE_INTERRUPT(44) \ - DECLARE_INTERRUPT(45) \ - DECLARE_INTERRUPT(46) \ - DECLARE_INTERRUPT(47) \ - DECLARE_INTERRUPT(48) \ - DECLARE_INTERRUPT(49) \ - DECLARE_INTERRUPT(50) \ - DECLARE_INTERRUPT(51) \ - DECLARE_INTERRUPT(52) \ - DECLARE_INTERRUPT(53) \ - DECLARE_INTERRUPT(54) \ - DECLARE_INTERRUPT(55) \ - DECLARE_INTERRUPT(56) \ - DECLARE_INTERRUPT(57) \ - DECLARE_INTERRUPT(58) \ - DECLARE_INTERRUPT(59) \ - DECLARE_INTERRUPT(60) \ - DECLARE_INTERRUPT(61) \ - DECLARE_INTERRUPT(62) \ - DECLARE_INTERRUPT(63) \ - DECLARE_INTERRUPT(64) \ - DECLARE_INTERRUPT(65) \ - DECLARE_INTERRUPT(66) \ - DECLARE_INTERRUPT(67) \ - DECLARE_INTERRUPT(68) \ - DECLARE_INTERRUPT(69) \ - DECLARE_INTERRUPT(70) \ - DECLARE_INTERRUPT(71) \ - DECLARE_INTERRUPT(72) \ - DECLARE_INTERRUPT(73) \ - DECLARE_INTERRUPT(74) \ - DECLARE_INTERRUPT(75) \ - DECLARE_INTERRUPT(76) \ - DECLARE_INTERRUPT(77) \ - DECLARE_INTERRUPT(78) \ - DECLARE_INTERRUPT(79) \ - DECLARE_INTERRUPT(80) \ - DECLARE_INTERRUPT(81) \ - DECLARE_INTERRUPT(82) \ - DECLARE_INTERRUPT(83) \ - DECLARE_INTERRUPT(84) \ - DECLARE_INTERRUPT(85) \ - DECLARE_INTERRUPT(86) \ - DECLARE_INTERRUPT(87) \ - DECLARE_INTERRUPT(88) \ - DECLARE_INTERRUPT(89) \ - DECLARE_INTERRUPT(90) \ - DECLARE_INTERRUPT(91) \ - DECLARE_INTERRUPT(92) \ - DECLARE_INTERRUPT(93) \ - DECLARE_INTERRUPT(94) \ - DECLARE_INTERRUPT(95) \ - DECLARE_INTERRUPT(97) \ - DECLARE_INTERRUPT(96) \ - DECLARE_INTERRUPT(98) \ - DECLARE_INTERRUPT(99) \ - DECLARE_INTERRUPT(100) \ - DECLARE_INTERRUPT(101) \ - DECLARE_INTERRUPT(102) \ - DECLARE_INTERRUPT(103) \ - DECLARE_INTERRUPT(104) \ - DECLARE_INTERRUPT(105) \ - DECLARE_INTERRUPT(106) \ - DECLARE_INTERRUPT(107) \ - DECLARE_INTERRUPT(108) \ - DECLARE_INTERRUPT(109) \ - DECLARE_INTERRUPT(110) \ - DECLARE_INTERRUPT(111) \ - DECLARE_INTERRUPT(112) \ - DECLARE_INTERRUPT(113) \ - DECLARE_INTERRUPT(114) \ - DECLARE_INTERRUPT(115) \ - DECLARE_INTERRUPT(116) \ - DECLARE_INTERRUPT(117) \ - DECLARE_INTERRUPT(118) \ - DECLARE_INTERRUPT(119) \ - DECLARE_INTERRUPT(120) \ - DECLARE_INTERRUPT(121) \ - DECLARE_INTERRUPT(122) \ - DECLARE_INTERRUPT(123) \ - DECLARE_INTERRUPT(124) \ - DECLARE_INTERRUPT(125) \ - DECLARE_INTERRUPT(126) \ - DECLARE_INTERRUPT(127) \ - DECLARE_INTERRUPT(128) \ - DECLARE_INTERRUPT(129) \ - DECLARE_INTERRUPT(130) \ - DECLARE_INTERRUPT(131) \ - DECLARE_INTERRUPT(132) \ - DECLARE_INTERRUPT(133) \ - DECLARE_INTERRUPT(134) \ - DECLARE_INTERRUPT(135) \ - DECLARE_INTERRUPT(136) \ - DECLARE_INTERRUPT(137) \ - DECLARE_INTERRUPT(138) \ - DECLARE_INTERRUPT(139) \ - DECLARE_INTERRUPT(140) \ - DECLARE_INTERRUPT(141) \ - DECLARE_INTERRUPT(142) \ - DECLARE_INTERRUPT(143) \ - DECLARE_INTERRUPT(144) \ - DECLARE_INTERRUPT(145) \ - DECLARE_INTERRUPT(146) \ - DECLARE_INTERRUPT(147) \ - DECLARE_INTERRUPT(148) \ - DECLARE_INTERRUPT(149) \ - DECLARE_INTERRUPT(150) \ - DECLARE_INTERRUPT(151) \ - DECLARE_INTERRUPT(152) \ - DECLARE_INTERRUPT(153) \ - DECLARE_INTERRUPT(154) \ - DECLARE_INTERRUPT(155) \ - DECLARE_INTERRUPT(156) \ - DECLARE_INTERRUPT(157) \ - DECLARE_INTERRUPT(158) \ - DECLARE_INTERRUPT(159) \ - DECLARE_INTERRUPT(160) \ - DECLARE_INTERRUPT(161) \ - DECLARE_INTERRUPT(162) \ - DECLARE_INTERRUPT(163) \ - DECLARE_INTERRUPT(164) \ - DECLARE_INTERRUPT(165) \ - DECLARE_INTERRUPT(166) \ - DECLARE_INTERRUPT(167) \ - DECLARE_INTERRUPT(168) \ - DECLARE_INTERRUPT(169) \ - DECLARE_INTERRUPT(170) \ - DECLARE_INTERRUPT(171) \ - DECLARE_INTERRUPT(172) \ - DECLARE_INTERRUPT(173) \ - DECLARE_INTERRUPT(174) \ - DECLARE_INTERRUPT(175) \ - DECLARE_INTERRUPT(176) \ - DECLARE_INTERRUPT(177) \ - DECLARE_INTERRUPT(178) \ - DECLARE_INTERRUPT(179) \ - DECLARE_INTERRUPT(180) \ - DECLARE_INTERRUPT(181) \ - DECLARE_INTERRUPT(182) \ - DECLARE_INTERRUPT(183) \ - DECLARE_INTERRUPT(184) \ - DECLARE_INTERRUPT(185) \ - DECLARE_INTERRUPT(186) \ - DECLARE_INTERRUPT(187) \ - DECLARE_INTERRUPT(188) \ - DECLARE_INTERRUPT(189) \ - DECLARE_INTERRUPT(190) \ - DECLARE_INTERRUPT(191) \ - DECLARE_INTERRUPT(192) \ - DECLARE_INTERRUPT(193) \ - DECLARE_INTERRUPT(194) \ - DECLARE_INTERRUPT(195) \ - DECLARE_INTERRUPT(196) \ - DECLARE_INTERRUPT(197) \ - DECLARE_INTERRUPT(198) \ - DECLARE_INTERRUPT(199) \ - DECLARE_INTERRUPT(200) \ - DECLARE_INTERRUPT(201) \ - DECLARE_INTERRUPT(202) \ - DECLARE_INTERRUPT(203) \ - DECLARE_INTERRUPT(204) \ - DECLARE_INTERRUPT(205) \ - DECLARE_INTERRUPT(206) \ - DECLARE_INTERRUPT(207) \ - DECLARE_INTERRUPT(208) \ - DECLARE_INTERRUPT(209) \ - DECLARE_INTERRUPT(210) \ - DECLARE_INTERRUPT(211) \ - DECLARE_INTERRUPT(212) \ - DECLARE_INTERRUPT(213) \ - DECLARE_INTERRUPT(214) \ - DECLARE_INTERRUPT(215) \ - DECLARE_INTERRUPT(216) \ - DECLARE_INTERRUPT(217) \ - DECLARE_INTERRUPT(218) \ - DECLARE_INTERRUPT(219) \ - DECLARE_INTERRUPT(220) \ - DECLARE_INTERRUPT(221) \ - DECLARE_INTERRUPT(222) \ - DECLARE_INTERRUPT(223) \ - DECLARE_INTERRUPT(224) \ - DECLARE_INTERRUPT(225) \ - DECLARE_INTERRUPT(226) \ - DECLARE_INTERRUPT(227) \ - DECLARE_INTERRUPT(228) \ - DECLARE_INTERRUPT(229) \ - DECLARE_INTERRUPT(230) \ - DECLARE_INTERRUPT(231) \ - DECLARE_INTERRUPT(232) \ - DECLARE_INTERRUPT(233) \ - DECLARE_INTERRUPT(234) \ - DECLARE_INTERRUPT(235) \ - DECLARE_INTERRUPT(236) \ - DECLARE_INTERRUPT(237) \ - DECLARE_INTERRUPT(238) \ - DECLARE_INTERRUPT(239) \ - DECLARE_INTERRUPT(240) \ - DECLARE_INTERRUPT(241) \ - DECLARE_INTERRUPT(242) \ - DECLARE_INTERRUPT(243) \ - DECLARE_INTERRUPT(244) \ - DECLARE_INTERRUPT(245) \ - DECLARE_INTERRUPT(246) \ - DECLARE_INTERRUPT(247) \ - DECLARE_INTERRUPT(248) \ - DECLARE_INTERRUPT(249) \ - DECLARE_INTERRUPT(250) \ - DECLARE_INTERRUPT(251) \ - DECLARE_INTERRUPT(252) \ - DECLARE_INTERRUPT(253) \ - DECLARE_INTERRUPT(254) \ - DECLARE_INTERRUPT(255)); diff --git a/cpu/i386/resetvec.S b/cpu/i386/resetvec.S deleted file mode 100644 index d9222dd2fc..0000000000 --- a/cpu/i386/resetvec.S +++ /dev/null @@ -1,37 +0,0 @@ -/* - * U-boot - i386 Startup Code - * - * Copyright (c) 2002 Omicron Ceti AB, Daniel Engström - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* Reset vector, jumps to start16.S */ - -.extern start16 - -.section .resetvec, "ax" -.code16 -reset_vector: - cli - cld - jmp start16 - - .org 0xf - nop diff --git a/cpu/i386/sc520/Makefile b/cpu/i386/sc520/Makefile deleted file mode 100644 index 87835b2c20..0000000000 --- a/cpu/i386/sc520/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# (C) Copyright 2008 -# Graeme Russ, graeme.russ@gmail.com. -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2002 -# Daniel Engström, Omicron Ceti AB, daniel@omicron.se. -# -# See file CREDITS for list of people who contributed to this -# project. -# -# 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA -# - -include $(TOPDIR)/config.mk - -LIB := $(obj)lib$(SOC).a - -COBJS-$(CONFIG_SYS_SC520) += sc520.o -COBJS-$(CONFIG_SYS_SC520_SSI) += sc520_ssi.o -COBJS-$(CONFIG_SYS_SC520_TIMER) += sc520_timer.o -COBJS-$(CONFIG_PCI) += sc520_pci.o - -SOBJS-$(CONFIG_SYS_SC520) += sc520_asm.o - -SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) -OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) - -all: $(obj).depend $(LIB) - -$(LIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -######################################################################### - -# defines $(obj).depend target -include $(SRCTREE)/rules.mk - -sinclude $(obj).depend - -######################################################################### \ No newline at end of file diff --git a/cpu/i386/sc520/sc520.c b/cpu/i386/sc520/sc520.c deleted file mode 100644 index 4b566a75cc..0000000000 --- a/cpu/i386/sc520/sc520.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB . - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* stuff specific for the sc520, - * but idependent of implementation */ - -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* - * utility functions for boards based on the AMD sc520 - * - * void init_sc520(void) - * unsigned long init_sc520_dram(void) - */ - -volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000; - -void init_sc520(void) -{ - /* Set the UARTxCTL register at it's slower, - * baud clock giving us a 1.8432 MHz reference - */ - sc520_mmcr->uart1ctl = 0x07; - sc520_mmcr->uart2ctl = 0x07; - - /* first set the timer pin mapping */ - sc520_mmcr->clksel = 0x72; /* no clock frequency selected, use 1.1892MHz */ - - /* enable PCI bus arbitrer */ - sc520_mmcr->sysarbctl = 0x02; /* enable concurrent mode */ - - sc520_mmcr->sysarbmenb = 0x1f; /* enable external grants */ - sc520_mmcr->hbctl = 0x04; /* enable posted-writes */ - - if (CONFIG_SYS_SC520_HIGH_SPEED) { - sc520_mmcr->cpuctl = 0x02; /* set it to 133 MHz and write back */ - gd->cpu_clk = 133000000; - printf("## CPU Speed set to 133MHz\n"); - } else { - sc520_mmcr->cpuctl = 0x01; /* set it to 100 MHz and write back */ - printf("## CPU Speed set to 100MHz\n"); - gd->cpu_clk = 100000000; - } - - - /* wait at least one millisecond */ - asm("movl $0x2000,%%ecx\n" - "0: pushl %%ecx\n" - "popl %%ecx\n" - "loop 0b\n": : : "ecx"); - - /* turn on the SDRAM write buffer */ - sc520_mmcr->dbctl = 0x11; - - /* turn on the cache and disable write through */ - asm("movl %%cr0, %%eax\n" - "andl $0x9fffffff, %%eax\n" - "movl %%eax, %%cr0\n" : : : "eax"); -} - -unsigned long init_sc520_dram(void) -{ - bd_t *bd = gd->bd; - - u32 dram_present=0; - u32 dram_ctrl; -#ifdef CONFIG_SYS_SDRAM_DRCTMCTL - /* these memory control registers are set up in the assember part, - * in sc520_asm.S, during 'mem_init'. If we muck with them here, - * after we are running a stack in RAM, we have troubles. Besides, - * these refresh and delay values are better ? simply specified - * outright in the include/configs/{cfg} file since the HW designer - * simply dictates it. - */ -#else - int val; - - int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY; - int refresh_rate = CONFIG_SYS_SDRAM_REFRESH_RATE; - int ras_cas_delay = CONFIG_SYS_SDRAM_RAS_CAS_DELAY; - - /* set SDRAM speed here */ - - refresh_rate/=78; - if (refresh_rate<=1) { - val = 0; /* 7.8us */ - } else if (refresh_rate==2) { - val = 1; /* 15.6us */ - } else if (refresh_rate==3 || refresh_rate==4) { - val = 2; /* 31.2us */ - } else { - val = 3; /* 62.4us */ - } - - sc520_mmcr->drcctl = (sc520_mmcr->drcctl & 0xcf) | (val<<4); - - val = sc520_mmcr->drctmctl & 0xf0; - - if (cas_precharge_delay==3) { - val |= 0x04; /* 3T */ - } else if (cas_precharge_delay==4) { - val |= 0x08; /* 4T */ - } else if (cas_precharge_delay>4) { - val |= 0x0c; - } - - if (ras_cas_delay > 3) { - val |= 2; - } else { - val |= 1; - } - sc520_mmcr->drctmctl = val; -#endif - - /* We read-back the configuration of the dram - * controller that the assembly code wrote */ - dram_ctrl = sc520_mmcr->drcbendadr; - - bd->bi_dram[0].start = 0; - if (dram_ctrl & 0x80) { - /* bank 0 enabled */ - dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22; - bd->bi_dram[0].size = bd->bi_dram[1].start; - - } else { - bd->bi_dram[0].size = 0; - bd->bi_dram[1].start = bd->bi_dram[0].start; - } - - if (dram_ctrl & 0x8000) { - /* bank 1 enabled */ - dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14; - bd->bi_dram[1].size = bd->bi_dram[2].start - bd->bi_dram[1].start; - } else { - bd->bi_dram[1].size = 0; - bd->bi_dram[2].start = bd->bi_dram[1].start; - } - - if (dram_ctrl & 0x800000) { - /* bank 2 enabled */ - dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6; - bd->bi_dram[2].size = bd->bi_dram[3].start - bd->bi_dram[2].start; - } else { - bd->bi_dram[2].size = 0; - bd->bi_dram[3].start = bd->bi_dram[2].start; - } - - if (dram_ctrl & 0x80000000) { - /* bank 3 enabled */ - dram_present = (dram_ctrl & 0x7f000000) >> 2; - bd->bi_dram[3].size = dram_present - bd->bi_dram[3].start; - } else { - bd->bi_dram[3].size = 0; - } - - -#if 0 - printf("Configured %d bytes of dram\n", dram_present); -#endif - gd->ram_size = dram_present; - - return dram_present; -} - -#ifdef CONFIG_SYS_SC520_RESET -void reset_cpu(ulong addr) -{ - printf("Resetting using SC520 MMCR\n"); - /* Write a '1' to the SYS_RST of the RESCFG MMCR */ - sc520_mmcr->rescfg = 0x01; - - /* NOTREACHED */ -} -#endif diff --git a/cpu/i386/sc520/sc520_asm.S b/cpu/i386/sc520/sc520_asm.S deleted file mode 100644 index 2042d9bfcf..0000000000 --- a/cpu/i386/sc520/sc520_asm.S +++ /dev/null @@ -1,581 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB . - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This file is largely based on code obtned from AMD. AMD's original - * copyright is included below - */ - -/* - * ============================================================================= - * - * Copyright 1999 Advanced Micro Devices, Inc. - * - * This software is the property of Advanced Micro Devices, Inc (AMD) which - * specifically grants the user the right to modify, use and distribute this - * software provided this COPYRIGHT NOTICE is not removed or altered. All - * other rights are reserved by AMD. - * - * THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY - * OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF - * THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE. - * IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER - * (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS - * INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY - * TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES. BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR - * LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE - * LIMITATION MAY NOT APPLY TO YOU. - * - * AMD does not assume any responsibility for any errors that may appear in - * the Materials nor any responsibility to support or update the Materials. - * AMD retains the right to make changes to its test specifications at any - * time, without notice. - * - * So that all may benefit from your experience, please report any problems - * or suggestions about this software back to AMD. Please include your name, - * company, telephone number, AMD product requiring support and question or - * problem encountered. - * - * Advanced Micro Devices, Inc. Worldwide support and contact - * Embedded Processor Division information available at: - * Systems Engineering epd.support@amd.com - * 5204 E. Ben White Blvd. -or- - * Austin, TX 78741 http://www.amd.com/html/support/techsup.html - * ============================================================================ - */ - - -/******************************************************************************* - * AUTHOR : Buddy Fey - Original. - ******************************************************************************* - */ - - -/******************************************************************************* - * FUNCTIONAL DESCRIPTION: - * This routine is called to autodetect the geometry of the DRAM. - * - * This routine is called to determine the number of column bits for the DRAM - * devices in this external bank. This routine assumes that the external bank - * has been configured for an 11-bit column and for 4 internal banks. This gives - * us the maximum address reach in memory. By writing a test value to the max - * address and locating where it aliases to, we can determine the number of valid - * column bits. - * - * This routine is called to determine the number of internal banks each DRAM - * device has. The external bank (under test) is configured for maximum reach - * with 11-bit columns and 4 internal banks. This routine will write to a max - * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if - * that column is a "don't care". If BA1 does not affect write/read of data, - * then this device has only 2 internal banks. - * - * This routine is called to determine the ending address for this external - * bank of SDRAM. We write to a max address with a data value and then disable - * row address bits looking for "don't care" locations. Each "don't care" bit - * represents a dividing of the maximum density (128M) by 2. By dividing the - * maximum of 32 4M chunks in an external bank down by all the "don't care" bits - * determined during sizing, we set the proper density. - * - * WARNINGS. - * bp must be preserved because it is used for return linkage. - * - * EXIT - * nothing returned - but the memory subsystem is enabled - ******************************************************************************* - */ - -#include - -.section .text -.equ DRCCTL, 0x0fffef010 /* DRAM control register */ -.equ DRCTMCTL, 0x0fffef012 /* DRAM timing control register */ -.equ DRCCFG, 0x0fffef014 /* DRAM bank configuration register */ -.equ DRCBENDADR, 0x0fffef018 /* DRAM bank ending address register */ -.equ ECCCTL, 0x0fffef020 /* DRAM ECC control register */ -.equ ECCINT, 0x0fffefd18 /* DRAM ECC nmi-INT mapping */ -.equ DBCTL, 0x0fffef040 /* DRAM buffer control register */ - -.equ CACHELINESZ, 0x00000010 /* size of our cache line (read buffer) */ -.equ COL11_ADR, 0x0e001e00 /* 11 col addrs */ -.equ COL10_ADR, 0x0e000e00 /* 10 col addrs */ -.equ COL09_ADR, 0x0e000600 /* 9 col addrs */ -.equ COL08_ADR, 0x0e000200 /* 8 col addrs */ -.equ ROW14_ADR, 0x0f000000 /* 14 row addrs */ -.equ ROW13_ADR, 0x07000000 /* 13 row addrs */ -.equ ROW12_ADR, 0x03000000 /* 12 row addrs */ -.equ ROW11_ADR, 0x01000000 /* 11 row addrs/also bank switch */ -.equ ROW10_ADR, 0x00000000 /* 10 row addrs/also bank switch */ -.equ COL11_DATA, 0x0b0b0b0b /* 11 col addrs */ -.equ COL10_DATA, 0x0a0a0a0a /* 10 col data */ -.equ COL09_DATA, 0x09090909 /* 9 col data */ -.equ COL08_DATA, 0x08080808 /* 8 col data */ -.equ ROW14_DATA, 0x3f3f3f3f /* 14 row data (MASK) */ -.equ ROW13_DATA, 0x1f1f1f1f /* 13 row data (MASK) */ -.equ ROW12_DATA, 0x0f0f0f0f /* 12 row data (MASK) */ -.equ ROW11_DATA, 0x07070707 /* 11 row data/also bank switch (MASK) */ -.equ ROW10_DATA, 0xaaaaaaaa /* 10 row data/also bank switch (MASK) */ - - - /* - * initialize dram controller registers - */ -.globl mem_init -mem_init: - xorw %ax,%ax - movl $DBCTL, %edi - movb %al, (%edi) /* disable write buffer */ - - movl $ECCCTL, %edi - movb %al, (%edi) /* disable ECC */ - - movl $DRCTMCTL, %edi - movb $0x1E,%al /* Set SDRAM timing for slowest */ - movb %al, (%edi) - - /* - * setup loop to do 4 external banks starting with bank 3 - */ - movl $0xff000000,%eax /* enable last bank and setup */ - movl $DRCBENDADR, %edi /* ending address register */ - movl %eax, (%edi) - - movl $DRCCFG, %edi /* setup */ - movw $0xbbbb,%ax /* dram config register for */ - movw %ax, (%edi) - - /* - * issue a NOP to all DRAMs - */ - movl $DRCCTL, %edi /* setup DRAM control register with */ - movb $0x1,%al /* Disable refresh,disable write buffer */ - movb %al, (%edi) - movl $CACHELINESZ, %esi /* just a dummy address to write for */ - movw %ax, (%esi) - /* - * delay for 100 usec? 200? - * ******this is a cludge for now ************* - */ - movw $100,%cx -sizdelay: - loop sizdelay /* we need 100 usec here */ - /***********************************************/ - - /* - * issue all banks precharge - */ - movb $0x2,%al /* All banks precharge */ - movb %al, (%edi) - movw %ax, (%esi) - - /* - * issue 2 auto refreshes to all banks - */ - movb $0x4,%al /* Auto refresh cmd */ - movb %al, (%edi) - movw $2,%cx -refresh1: - movw %ax, (%esi) - loop refresh1 - - /* - * issue LOAD MODE REGISTER command - */ - movb $0x3,%al /* Load mode register cmd */ - movb %al, (%edi) - movw %ax, (%esi) - - /* - * issue 8 more auto refreshes to all banks - */ - movb $0x4,%al /* Auto refresh cmd */ - movb %al, (%edi) - movw $8,%cx -refresh2: - movw %ax, (%esi) - loop refresh2 - - /* - * set control register to NORMAL mode - */ - movb $0x0,%al /* Normal mode value */ - movb %al, (%edi) - - /* - * size dram starting with external bank 3 moving to external bank 0 - */ - movl $0x3,%ecx /* start with external bank 3 */ - -nextbank: - - /* - * write col 11 wrap adr - */ - movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */ - movl $COL11_DATA, %eax /* pattern for max supported columns(11) */ - movl %eax, (%esi) /* write max col pattern at max col adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write col 10 wrap adr - */ - - movl $COL10_ADR, %esi /* set address to 10 col wrap address */ - movl $COL10_DATA, %eax /* pattern for 10 col wrap */ - movl %eax, (%esi) /* write 10 col pattern @ 10 col wrap adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write col 9 wrap adr - */ - movl $COL09_ADR, %esi /* set address to 9 col wrap address */ - movl $COL09_DATA, %eax /* pattern for 9 col wrap */ - movl %eax, (%esi) /* write 9 col pattern @ 9 col wrap adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write col 8 wrap adr - */ - movl $COL08_ADR, %esi /* set address to min(8) col wrap address */ - movl $COL08_DATA, %eax /* pattern for min (8) col wrap */ - movl %eax, (%esi) /* write min col pattern @ min col adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write row 14 wrap adr - */ - movl $ROW14_ADR, %esi /* set address to max row (14) wrap addr */ - movl $ROW14_DATA, %eax /* pattern for max supported rows(14) */ - movl %eax, (%esi) /* write max row pattern at max row adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write row 13 wrap adr - */ - movl $ROW13_ADR, %esi /* set address to 13 row wrap address */ - movl $ROW13_DATA, %eax /* pattern for 13 row wrap */ - movl %eax, (%esi) /* write 13 row pattern @ 13 row wrap adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write row 12 wrap adr - */ - movl $ROW12_ADR, %esi /* set address to 12 row wrap address */ - movl $ROW12_DATA, %eax /* pattern for 12 row wrap */ - movl %eax, (%esi) /* write 12 row pattern @ 12 row wrap adr */ - movl (%esi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write row 11 wrap adr - */ - movl $ROW11_ADR, %edi /* set address to 11 row wrap address */ - movl $ROW11_DATA, %eax /* pattern for 11 row wrap */ - movl %eax, (%edi) /* write 11 row pattern @ 11 row wrap adr */ - movl (%edi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * write row 10 wrap adr --- this write is really to determine number of banks - */ - movl $ROW10_ADR, %edi /* set address to 10 row wrap address */ - movl $ROW10_DATA, %eax /* pattern for 10 row wrap (AA) */ - movl %eax, (%edi) /* write 10 row pattern @ 10 row wrap adr */ - movl (%edi), %ebx /* optional read */ - cmpl %ebx,%eax /* to verify write */ - jnz bad_ram /* this ram is bad */ - /* - * read data @ row 12 wrap adr to determine * banks, - * and read data @ row 14 wrap adr to determine * rows. - * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM. - * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4 - * if data @ row 12 wrap == 11 or 12, we have 4 banks, - */ - xorw %di,%di /* value for 2 banks in DI */ - movl (%esi), %ebx /* read from 12 row wrap to check banks - * (esi is setup from the write to row 12 wrap) */ - cmpl %ebx,%eax /* check for AA pattern (eax holds the aa pattern) */ - jz only2 /* if pattern == AA, we only have 2 banks */ - - /* 4 banks */ - - movw $8,%di /* value for 4 banks in DI (BNK_CNT bit) */ - cmpl $ROW11_DATA, %ebx /* only other legitimate values are 11 */ - jz only2 - cmpl $ROW12_DATA, %ebx /* and 12 */ - jnz bad_ram /* its bad if not 11 or 12! */ - - /* fall through */ -only2: - /* - * validate row mask - */ - movl $ROW14_ADR, %esi /* set address back to max row wrap addr */ - movl (%esi), %eax /* read actual number of rows @ row14 adr */ - - cmpl $ROW11_DATA, %eax /* row must be greater than 11 pattern */ - jb bad_ram - - cmpl $ROW14_DATA, %eax /* and row must be less than 14 pattern */ - ja bad_ram - - cmpb %ah,%al /* verify all 4 bytes of dword same */ - jnz bad_ram - movl %eax,%ebx - shrl $16,%ebx - cmpw %bx,%ax - jnz bad_ram - /* - * read col 11 wrap adr for real column data value - */ - movl $COL11_ADR, %esi /* set address to max col (11) wrap addr */ - movl (%esi), %eax /* read real col number at max col adr */ - /* - * validate column data - */ - cmpl $COL08_DATA, %eax /* col must be greater than 8 pattern */ - jb bad_ram - - cmpl $COL11_DATA, %eax /* and row must be less than 11 pattern */ - ja bad_ram - - subl $COL08_DATA, %eax /* normalize column data to zero */ - jc bad_ram - cmpb %ah,%al /* verify all 4 bytes of dword equal */ - jnz bad_ram - movl %eax,%edx - shrl $16,%edx - cmpw %dx,%ax - jnz bad_ram - /* - * merge bank and col data together - */ - addw %di,%dx /* merge of bank and col info in dl */ - /* - * fix ending addr mask based upon col info - */ - movb $3,%al - subb %dh,%al /* dh contains the overflow from the bank/col merge */ - movb %bl,%dh /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */ - xchgw %cx,%ax /* cx = ax = 3 or 2 depending on 2 or 4 bank device */ - shrb %cl,%dh /* */ - incb %dh /* ending addr is 1 greater than real end */ - xchgw %cx,%ax /* cx is bank number again */ - /* - * issue all banks precharge - */ -bad_reint: - movl $DRCCTL, %esi /* setup DRAM control register with */ - movb $0x2,%al /* All banks precharge */ - movb %al, (%esi) - movl $CACHELINESZ, %esi /* address to init read buffer */ - movw %ax, (%esi) - - /* - * update ENDING ADDRESS REGISTER - */ - movl $DRCBENDADR, %edi /* DRAM ending address register */ - movl %ecx,%ebx - addl %ebx, %edi - movb %dh, (%edi) - /* - * update CONFIG REGISTER - */ - xorb %dh,%dh - movw $0x00f,%bx - movw %cx,%ax - shlw $2,%ax - xchgw %cx,%ax - shlw %cl,%dx - shlw %cl,%bx - notw %bx - xchgw %cx,%ax - movl $DRCCFG, %edi - mov (%edi), %ax - andw %bx,%ax - orw %dx,%ax - movw %ax, (%edi) - jcxz cleanup - - decw %cx - movl %ecx,%ebx - movl $DRCBENDADR, %edi /* DRAM ending address register */ - movb $0xff,%al - addl %ebx, %edi - movb %al, (%edi) - /* - * set control register to NORMAL mode - */ - movl $DRCCTL, %esi /* setup DRAM control register with */ - movb $0x0,%al /* Normal mode value */ - movb %al, (%esi) - movl $CACHELINESZ, %esi /* address to init read buffer */ - movw %ax, (%esi) - jmp nextbank - -cleanup: - movl $DRCBENDADR, %edi /* DRAM ending address register */ - movw $4,%cx - xorw %ax,%ax -cleanuplp: - movb (%edi), %al - orb %al,%al - jz emptybank - - addb %ah,%al - jns nottoomuch - - movb $0x7f,%al -nottoomuch: - movb %al,%ah - orb $0x80,%al - movb %al, (%edi) -emptybank: - incl %edi - loop cleanuplp - -#if defined CONFIG_SYS_SDRAM_DRCTMCTL - /* just have your hardware desinger _GIVE_ you what you need here! */ - movl $DRCTMCTL, %edi - movb $CONFIG_SYS_SDRAM_DRCTMCTL,%al - movb (%edi), %al -#else -#if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T) - /* set the CAS latency now since it is hard to do - * when we run from the RAM */ - movl $DRCTMCTL, %edi /* DRAM timing register */ - movb (%edi), %al -#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T - andb $0xef, %al -#endif -#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T - orb $0x10, %al -#endif - movb %al, (%edi) -#endif -#endif - movl $DRCCTL, %edi /* DRAM Control register */ - movb $0x3,%al /* Load mode register cmd */ - movb %al, (%edi) - movw %ax, (%esi) - - - movl $DRCCTL, %edi /* DRAM Control register */ - movb $0x18,%al /* Enable refresh and NORMAL mode */ - movb %al, (%edi) - - jmp dram_done - -bad_ram: - xorl %edx,%edx - xorl %edi,%edi - jmp bad_reint - -dram_done: - - /* readback DRCBENDADR and return the number - * of available ram bytes in %eax */ - - movl $DRCBENDADR, %edi /* DRAM ending address register */ - - movl (%edi), %eax - movl %eax, %ecx - andl $0x80000000, %ecx - jz bank2 - andl $0x7f000000, %eax - shrl $2, %eax - movl %eax, %ebx - -bank2: movl (%edi), %eax - movl %eax, %ecx - andl $0x00800000, %ecx - jz bank1 - andl $0x007f0000, %eax - shll $6, %eax - movl %eax, %ebx - -bank1: movl (%edi), %eax - movl %eax, %ecx - andl $0x00008000, %ecx - jz bank0 - andl $0x00007f00, %eax - shll $14, %eax - movl %eax, %ebx - -bank0: movl (%edi), %eax - movl %eax, %ecx - andl $0x00000080, %ecx - jz done - andl $0x0000007f, %eax - shll $22, %eax - movl %eax, %ebx - - -done: - movl %ebx, %eax - -#if CONFIG_SYS_SDRAM_ECC_ENABLE - /* A nominal memory test: just a byte at each address line */ - movl %eax, %ecx - shrl $0x1, %ecx - movl $0x1, %edi -memtest0: - movb $0xa5, (%edi) - cmpb $0xa5, (%edi) - jne out - shrl $1, %ecx - andl %ecx,%ecx - jz set_ecc - shll $1, %edi - jmp memtest0 - -set_ecc: - /* clear all ram with a memset */ - movl %eax, %ecx - xorl %esi, %esi - xorl %edi, %edi - xorl %eax, %eax - shrl $2, %ecx - cld - rep stosl - /* enable read, write buffers */ - movb $0x11, %al - movl $DBCTL, %edi - movb %al, (%edi) - /* enable NMI mapping for ECC */ - movl $ECCINT, %edi - mov $0x10, %al - movb %al, (%edi) - /* Turn on ECC */ - movl $ECCCTL, %edi - mov $0x05, %al - movb %al, (%edi) -#endif -out: - movl %ebx, %eax - jmp *%ebp diff --git a/cpu/i386/sc520/sc520_pci.c b/cpu/i386/sc520/sc520_pci.c deleted file mode 100644 index f446c6d592..0000000000 --- a/cpu/i386/sc520/sc520_pci.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB . - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* stuff specific for the sc520, but independent of implementation */ - -#include -#include -#include -#include - -static struct { - u8 priority; - u16 level_reg; - u8 level_bit; -} sc520_irq[] = { - { SC520_IRQ0, 0, 0x01 }, - { SC520_IRQ1, 0, 0x02 }, - { SC520_IRQ2, 1, 0x02 }, - { SC520_IRQ3, 0, 0x08 }, - { SC520_IRQ4, 0, 0x10 }, - { SC520_IRQ5, 0, 0x20 }, - { SC520_IRQ6, 0, 0x40 }, - { SC520_IRQ7, 0, 0x80 }, - - { SC520_IRQ8, 1, 0x01 }, - { SC520_IRQ9, 1, 0x02 }, - { SC520_IRQ10, 1, 0x04 }, - { SC520_IRQ11, 1, 0x08 }, - { SC520_IRQ12, 1, 0x10 }, - { SC520_IRQ13, 1, 0x20 }, - { SC520_IRQ14, 1, 0x40 }, - { SC520_IRQ15, 1, 0x80 } -}; - - -/* The interrupt used for PCI INTA-INTD */ -int sc520_pci_ints[15] = { - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1 -}; - -/* utility function to configure a pci interrupt */ -int pci_sc520_set_irq(int pci_pin, int irq) -{ - int i; - -# if 1 - printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq); -#endif - if (irq < 0 || irq > 15) { - return -1; /* illegal irq */ - } - - if (pci_pin < 0 || pci_pin > 15) { - return -1; /* illegal pci int pin */ - } - - /* first disable any non-pci interrupt source that use - * this level */ - - /* PCI interrupt mapping (A through D)*/ - for (i=0; i<=3 ;i++) { - if (sc520_mmcr->pci_int_map[i] == sc520_irq[irq].priority) - sc520_mmcr->pci_int_map[i] = SC520_IRQ_DISABLED; - } - - /* GP IRQ interrupt mapping */ - for (i=0; i<=10 ;i++) { - if (sc520_mmcr->gp_int_map[i] == sc520_irq[irq].priority) - sc520_mmcr->gp_int_map[i] = SC520_IRQ_DISABLED; - } - - /* Set the trigger to level */ - sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] = - sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] | sc520_irq[irq].level_bit; - - - if (pci_pin < 4) { - /* PCI INTA-INTD */ - /* route the interrupt */ - sc520_mmcr->pci_int_map[pci_pin] = sc520_irq[irq].priority; - } else { - /* GPIRQ0-GPIRQ10 used for additional PCI INTS */ - sc520_mmcr->gp_int_map[pci_pin - 4] = sc520_irq[irq].priority; - - /* also set the polarity in this case */ - sc520_mmcr->intpinpol = sc520_mmcr->intpinpol | (1 << (pci_pin-4)); - } - - /* register the pin */ - sc520_pci_ints[pci_pin] = irq; - - - return 0; /* OK */ -} - -void pci_sc520_init(struct pci_controller *hose) -{ - hose->first_busno = 0; - hose->last_busno = 0xff; - - /* System memory space */ - pci_set_region(hose->regions + 0, - SC520_PCI_MEMORY_BUS, - SC520_PCI_MEMORY_PHYS, - SC520_PCI_MEMORY_SIZE, - PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); - - /* PCI memory space */ - pci_set_region(hose->regions + 1, - SC520_PCI_MEM_BUS, - SC520_PCI_MEM_PHYS, - SC520_PCI_MEM_SIZE, - PCI_REGION_MEM); - - /* ISA/PCI memory space */ - pci_set_region(hose->regions + 2, - SC520_ISA_MEM_BUS, - SC520_ISA_MEM_PHYS, - SC520_ISA_MEM_SIZE, - PCI_REGION_MEM); - - /* PCI I/O space */ - pci_set_region(hose->regions + 3, - SC520_PCI_IO_BUS, - SC520_PCI_IO_PHYS, - SC520_PCI_IO_SIZE, - PCI_REGION_IO); - - /* ISA/PCI I/O space */ - pci_set_region(hose->regions + 4, - SC520_ISA_IO_BUS, - SC520_ISA_IO_PHYS, - SC520_ISA_IO_SIZE, - PCI_REGION_IO); - - hose->region_count = 5; - - pci_setup_type1(hose, - SC520_REG_ADDR, - SC520_REG_DATA); - - pci_register_hose(hose); - - hose->last_busno = pci_hose_scan(hose); - - /* enable target memory acceses on host brige */ - pci_write_config_word(0, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - -} diff --git a/cpu/i386/sc520/sc520_ssi.c b/cpu/i386/sc520/sc520_ssi.c deleted file mode 100644 index 8dbe17aa60..0000000000 --- a/cpu/i386/sc520/sc520_ssi.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB . - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* stuff specific for the sc520, but independent of implementation */ - -#include -#include -#include - -int ssi_set_interface(int freq, int lsb_first, int inv_clock, int inv_phase) -{ - u8 temp=0; - - if (freq >= 8192) { - temp |= CTL_CLK_SEL_4; - } else if (freq >= 4096) { - temp |= CTL_CLK_SEL_8; - } else if (freq >= 2048) { - temp |= CTL_CLK_SEL_16; - } else if (freq >= 1024) { - temp |= CTL_CLK_SEL_32; - } else if (freq >= 512) { - temp |= CTL_CLK_SEL_64; - } else if (freq >= 256) { - temp |= CTL_CLK_SEL_128; - } else if (freq >= 128) { - temp |= CTL_CLK_SEL_256; - } else { - temp |= CTL_CLK_SEL_512; - } - - if (!lsb_first) { - temp |= MSBF_ENB; - } - - if (inv_clock) { - temp |= CLK_INV_ENB; - } - - if (inv_phase) { - temp |= PHS_INV_ENB; - } - - sc520_mmcr->ssictl = temp; - - return 0; -} - -u8 ssi_txrx_byte(u8 data) -{ - sc520_mmcr->ssixmit = data; - while (sc520_mmcr->ssista & SSISTA_BSY); - sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMITRCV; - while (sc520_mmcr->ssista & SSISTA_BSY); - - return sc520_mmcr->ssircv; -} - - -void ssi_tx_byte(u8 data) -{ - sc520_mmcr->ssixmit = data; - while (sc520_mmcr->ssista & SSISTA_BSY); - sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMIT; -} - -u8 ssi_rx_byte(void) -{ - while (sc520_mmcr->ssista & SSISTA_BSY); - sc520_mmcr->ssicmd = SSICMD_CMD_SEL_RCV; - while (sc520_mmcr->ssista & SSISTA_BSY); - - return sc520_mmcr->ssircv; -} diff --git a/cpu/i386/sc520/sc520_timer.c b/cpu/i386/sc520/sc520_timer.c deleted file mode 100644 index 93b5b555c3..0000000000 --- a/cpu/i386/sc520/sc520_timer.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB . - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* stuff specific for the sc520, but independent of implementation */ - -#include -#include -#include - -void sc520_timer_isr(void) -{ - /* Ack the GP Timer Interrupt */ - sc520_mmcr->gptmrsta = 0x02; -} - -int timer_init(void) -{ - /* Register the SC520 specific timer interrupt handler */ - register_timer_isr (sc520_timer_isr); - - /* Install interrupt handler for GP Timer 1 */ - irq_install_handler (0, timer_isr, NULL); - - /* Map GP Timer 1 to Master PIC IR0 */ - sc520_mmcr->gp_tmr_int_map[1] = 0x01; - - /* Disable GP Timers 1 & 2 - Allow configuration writes */ - sc520_mmcr->gptmr1ctl = 0x4000; - sc520_mmcr->gptmr2ctl = 0x4000; - - /* Reset GP Timers 1 & 2 */ - sc520_mmcr->gptmr1cnt = 0x0000; - sc520_mmcr->gptmr2cnt = 0x0000; - - /* Setup GP Timer 2 as a 100kHz (10us) prescaler */ - sc520_mmcr->gptmr2maxcmpa = 83; - sc520_mmcr->gptmr2ctl = 0xc001; - - /* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */ - sc520_mmcr->gptmr1maxcmpa = 100; - sc520_mmcr->gptmr1ctl = 0xe009; - - unmask_irq (0); - - /* Clear the GP Timer 1 status register to get the show rolling*/ - sc520_mmcr->gptmrsta = 0x02; - - return 0; -} - -void __udelay(unsigned long usec) -{ - int m = 0; - long u; - long temp; - - temp = sc520_mmcr->swtmrmilli; - temp = sc520_mmcr->swtmrmicro; - - do { - m += sc520_mmcr->swtmrmilli; - u = sc520_mmcr->swtmrmicro + (m * 1000); - } while (u < usec); -} diff --git a/cpu/i386/serial.c b/cpu/i386/serial.c deleted file mode 100644 index e7025a3cdc..0000000000 --- a/cpu/i386/serial.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * (C) Copyright 2002 - * Daniel Engström, Omicron Ceti AB, daniel@omicron.se - * - * (C) Copyright 2000 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -/*------------------------------------------------------------------------------+ */ - -/* - * This source code is dual-licensed. You may use it under the terms of the - * GNU General Public License version 2, or under the license below. - * - * This source code has been made available to you by IBM on an AS-IS - * basis. Anyone receiving this source is licensed under IBM - * copyrights to use it in any way he or she deems fit, including - * copying it, modifying it, compiling it, and redistributing it either - * with or without modifications. No license under IBM patents or - * patent applications is to be implied by the copyright license. - * - * Any user of this software should understand that IBM cannot provide - * technical support for this software and will not be responsible for - * any consequences resulting from the use of this software. - * - * Any person who transfers this source code or any derivative work - * must include the IBM copyright notice, this paragraph, and the - * preceding two paragraphs in the transferred software. - * - * COPYRIGHT I B M CORPORATION 1995 - * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M - */ -/*------------------------------------------------------------------------------- */ - -#include -#include -#include -#include - -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -#define UART_RBR 0x00 -#define UART_THR 0x00 -#define UART_IER 0x01 -#define UART_IIR 0x02 -#define UART_FCR 0x02 -#define UART_LCR 0x03 -#define UART_MCR 0x04 -#define UART_LSR 0x05 -#define UART_MSR 0x06 -#define UART_SCR 0x07 -#define UART_DLL 0x00 -#define UART_DLM 0x01 - -/*-----------------------------------------------------------------------------+ - | Line Status Register. - +-----------------------------------------------------------------------------*/ -#define asyncLSRDataReady1 0x01 -#define asyncLSROverrunError1 0x02 -#define asyncLSRParityError1 0x04 -#define asyncLSRFramingError1 0x08 -#define asyncLSRBreakInterrupt1 0x10 -#define asyncLSRTxHoldEmpty1 0x20 -#define asyncLSRTxShiftEmpty1 0x40 -#define asyncLSRRxFifoError1 0x80 - - -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO -/*-----------------------------------------------------------------------------+ - | Fifo - +-----------------------------------------------------------------------------*/ -typedef struct { - char *rx_buffer; - ulong rx_put; - ulong rx_get; - int cts; -} serial_buffer_t; - -volatile serial_buffer_t buf_info; -static int serial_buffer_active=0; -#endif - - -static int serial_div(int baudrate) -{ - - switch (baudrate) { - case 1200: - return 96; - case 9600: - return 12; - case 19200: - return 6; - case 38400: - return 3; - case 57600: - return 2; - case 115200: - return 1; - } - - return 12; -} - - -/* - * Minimal serial functions needed to use one of the SMC ports - * as serial console interface. - */ - -int serial_init(void) -{ - volatile char val; - int bdiv = serial_div(gd->baudrate); - - outb(0x80, UART0_BASE + UART_LCR); /* set DLAB bit */ - outb(bdiv, UART0_BASE + UART_DLL); /* set baudrate divisor */ - outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */ - outb(0x03, UART0_BASE + UART_LCR); /* clear DLAB; set 8 bits, no parity */ - outb(0x01, UART0_BASE + UART_FCR); /* enable FIFO */ - outb(0x0b, UART0_BASE + UART_MCR); /* Set DTR and RTS active */ - val = inb(UART0_BASE + UART_LSR); /* clear line status */ - val = inb(UART0_BASE + UART_RBR); /* read receive buffer */ - outb(0x00, UART0_BASE + UART_SCR); /* set scratchpad */ - outb(0x00, UART0_BASE + UART_IER); /* set interrupt enable reg */ - - return 0; -} - - -void serial_setbrg(void) -{ - unsigned short bdiv; - - bdiv = serial_div(gd->baudrate); - - outb(0x80, UART0_BASE + UART_LCR); /* set DLAB bit */ - outb(bdiv&0xff, UART0_BASE + UART_DLL); /* set baudrate divisor */ - outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */ - outb(0x03, UART0_BASE + UART_LCR); /* clear DLAB; set 8 bits, no parity */ -} - - -void serial_putc(const char c) -{ - int i; - - if (c == '\n') - serial_putc ('\r'); - - /* check THRE bit, wait for transmiter available */ - for (i = 1; i < 3500; i++) { - if ((inb (UART0_BASE + UART_LSR) & 0x20) == 0x20) { - break; - } - udelay(100); - } - outb(c, UART0_BASE + UART_THR); /* put character out */ -} - - -void serial_puts(const char *s) -{ - while (*s) { - serial_putc(*s++); - } -} - - -int serial_getc(void) -{ - unsigned char status = 0; - -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO - if (serial_buffer_active) { - return serial_buffered_getc(); - } -#endif - - while (1) { -#if defined(CONFIG_HW_WATCHDOG) - WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */ -#endif /* CONFIG_HW_WATCHDOG */ - status = inb(UART0_BASE + UART_LSR); - if ((status & asyncLSRDataReady1) != 0x0) { - break; - } - if ((status & ( asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1 )) != 0) { - outb(asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR); - } - } - return (0x000000ff & (int) inb (UART0_BASE)); -} - - -int serial_tstc(void) -{ - unsigned char status; - -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO - if (serial_buffer_active) { - return serial_buffered_tstc(); - } -#endif - - status = inb(UART0_BASE + UART_LSR); - if ((status & asyncLSRDataReady1) != 0x0) { - return (1); - } - if ((status & ( asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1 )) != 0) { - outb(asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR); - } - return 0; -} - - -#ifdef CONFIG_SERIAL_SOFTWARE_FIFO - -void serial_isr(void *arg) -{ - int space; - int c; - int rx_put = buf_info.rx_put; - - if (buf_info.rx_get <= rx_put) { - space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - buf_info.rx_get); - } else { - space = buf_info.rx_get - rx_put; - } - - while (inb(UART0_BASE + UART_LSR) & 1) { - c = inb(UART0_BASE); - if (space) { - buf_info.rx_buffer[rx_put++] = c; - space--; - - if (rx_put == buf_info.rx_get) { - buf_info.rx_get++; - if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) { - buf_info.rx_get = 0; - } - } - - if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) { - rx_put = 0; - if (0 == buf_info.rx_get) { - buf_info.rx_get = 1; - } - - } - - } - if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) { - /* Stop flow by setting RTS inactive */ - outb(inb(UART0_BASE + UART_MCR) & (0xFF ^ 0x02), - UART0_BASE + UART_MCR); - } - } - buf_info.rx_put = rx_put; -} - -void serial_buffered_init(void) -{ - serial_puts ("Switching to interrupt driven serial input mode.\n"); - buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO); - buf_info.rx_put = 0; - buf_info.rx_get = 0; - - if (inb (UART0_BASE + UART_MSR) & 0x10) { - serial_puts ("Check CTS signal present on serial port: OK.\n"); - buf_info.cts = 1; - } else { - serial_puts ("WARNING: CTS signal not present on serial port.\n"); - buf_info.cts = 0; - } - - irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ , - serial_isr /*interrupt_handler_t *handler */ , - (void *) &buf_info /*void *arg */ ); - - /* Enable "RX Data Available" Interrupt on UART */ - /* outb(inb(UART0_BASE + UART_IER) |0x01, UART0_BASE + UART_IER); */ - outb(0x01, UART0_BASE + UART_IER); - - /* Set DTR and RTS active, enable interrupts */ - outb(inb (UART0_BASE + UART_MCR) | 0x0b, UART0_BASE + UART_MCR); - - /* Setup UART FIFO: RX trigger level: 1 byte, Enable FIFO */ - outb( /*(1 << 6) |*/ 1, UART0_BASE + UART_FCR); - - serial_buffer_active = 1; -} - -void serial_buffered_putc (const char c) -{ - int i; - /* Wait for CTS */ -#if defined(CONFIG_HW_WATCHDOG) - while (!(inb (UART0_BASE + UART_MSR) & 0x10)) - WATCHDOG_RESET (); -#else - if (buf_info.cts) { - for (i=0;i<1000;i++) { - if ((inb (UART0_BASE + UART_MSR) & 0x10)) { - break; - } - } - if (i!=1000) { - buf_info.cts = 0; - } - } else { - if ((inb (UART0_BASE + UART_MSR) & 0x10)) { - buf_info.cts = 1; - } - } - -#endif - serial_putc (c); -} - -void serial_buffered_puts(const char *s) -{ - serial_puts (s); -} - -int serial_buffered_getc(void) -{ - int space; - int c; - int rx_get = buf_info.rx_get; - int rx_put; - -#if defined(CONFIG_HW_WATCHDOG) - while (rx_get == buf_info.rx_put) - WATCHDOG_RESET (); -#else - while (rx_get == buf_info.rx_put); -#endif - c = buf_info.rx_buffer[rx_get++]; - if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO) { - rx_get = 0; - } - buf_info.rx_get = rx_get; - - rx_put = buf_info.rx_put; - if (rx_get <= rx_put) { - space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get); - } else { - space = rx_get - rx_put; - } - if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) { - /* Start flow by setting RTS active */ - outb(inb (UART0_BASE + UART_MCR) | 0x02, UART0_BASE + UART_MCR); - } - - return c; -} - -int serial_buffered_tstc(void) -{ - return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0; -} - -#endif /* CONFIG_SERIAL_SOFTWARE_FIFO */ - - -#if defined(CONFIG_CMD_KGDB) -/* - AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port - number 0 or number 1 - - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 : - configuration has been already done - - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 : - configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE -*/ -#if (CONFIG_KGDB_SER_INDEX & 2) -void kgdb_serial_init(void) -{ - volatile char val; - bdiv = serial_div (CONFIG_KGDB_BAUDRATE); - - /* - * Init onboard 16550 UART - */ - outb(0x80, UART1_BASE + UART_LCR); /* set DLAB bit */ - outb((bdiv & 0xff), UART1_BASE + UART_DLL); /* set divisor for 9600 baud */ - outb((bdiv >> 8 ), UART1_BASE + UART_DLM); /* set divisor for 9600 baud */ - outb(0x03, UART1_BASE + UART_LCR); /* line control 8 bits no parity */ - outb(0x00, UART1_BASE + UART_FCR); /* disable FIFO */ - outb(0x00, UART1_BASE + UART_MCR); /* no modem control DTR RTS */ - val = inb(UART1_BASE + UART_LSR); /* clear line status */ - val = inb(UART1_BASE + UART_RBR); /* read receive buffer */ - outb(0x00, UART1_BASE + UART_SCR); /* set scratchpad */ - outb(0x00, UART1_BASE + UART_IER); /* set interrupt enable reg */ -} - - -void putDebugChar(const char c) -{ - if (c == '\n') - serial_putc ('\r'); - - outb(c, UART1_BASE + UART_THR); /* put character out */ - - /* check THRE bit, wait for transfer done */ - while ((inb(UART1_BASE + UART_LSR) & 0x20) != 0x20); -} - - -void putDebugStr(const char *s) -{ - while (*s) { - serial_putc(*s++); - } -} - - -int getDebugChar(void) -{ - unsigned char status = 0; - - while (1) { - status = inb(UART1_BASE + UART_LSR); - if ((status & asyncLSRDataReady1) != 0x0) { - break; - } - if ((status & ( asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1 )) != 0) { - outb(asyncLSRFramingError1 | - asyncLSROverrunError1 | - asyncLSRParityError1 | - asyncLSRBreakInterrupt1, UART1_BASE + UART_LSR); - } - } - return (0x000000ff & (int) inb(UART1_BASE)); -} - - -void kgdb_interruptible(int yes) -{ - return; -} - -#else /* ! (CONFIG_KGDB_SER_INDEX & 2) */ - -void kgdb_serial_init(void) -{ - serial_printf ("[on serial] "); -} - -void putDebugChar(int c) -{ - serial_putc (c); -} - -void putDebugStr(const char *str) -{ - serial_puts (str); -} - -int getDebugChar(void) -{ - return serial_getc (); -} - -void kgdb_interruptible(int yes) -{ - return; -} -#endif /* (CONFIG_KGDB_SER_INDEX & 2) */ -#endif diff --git a/cpu/i386/start.S b/cpu/i386/start.S deleted file mode 100644 index 25d32e658e..0000000000 --- a/cpu/i386/start.S +++ /dev/null @@ -1,135 +0,0 @@ -/* - * U-boot - i386 Startup Code - * - * Copyright (c) 2002 Omicron Ceti AB, Daniel Engström - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#include -#include - - -.section .text -.code32 -.globl _start -.type _start, @function -.globl _i386boot_start -_i386boot_start: -_start: - movl $0x18,%eax /* Load our segement registes, the - * gdt have already been loaded by start16.S */ - movw %ax,%fs - movw %ax,%ds - movw %ax,%gs - movw %ax,%es - movw %ax,%ss - - /* We call a few functions in the board support package - * since we have no stack yet we'll have to use %ebp - * to store the return address */ - - /* Early platform init (setup gpio, etc ) */ - mov $early_board_init_ret, %ebp - jmp early_board_init -early_board_init_ret: - - /* The __port80 entry-point should be usabe by now */ - /* so we try to indicate progress */ - movw $0x01, %ax - movl $.progress0, %ebp - jmp show_boot_progress_asm -.progress0: - - /* size memory */ - mov $mem_init_ret, %ebp - jmp mem_init -mem_init_ret: - - /* Check we have enough memory for stack */ - movl $CONFIG_SYS_STACK_SIZE, %ecx - cmpl %ecx, %eax - jae mem_ok - - /* indicate (lack of) progress */ - movw $0x81, %ax - movl $.progress0a, %ebp - jmp show_boot_progress_asm -.progress0a: - jmp die -mem_ok: - /* Set stack pointer to upper memory limit*/ - movl %eax, %esp - - /* indicate progress */ - movw $0x02, %ax - movl $.progress1, %ebp - jmp show_boot_progress_asm -.progress1: - - /* Test the stack */ - pushl $0 - popl %eax - cmpl $0, %eax - jne no_stack - push $0x55aa55aa - popl %ebx - cmpl $0x55aa55aa, %ebx - je stack_ok - -no_stack: - /* indicate (lack of) progress */ - movw $0x82, %ax - movl $.progress1a, %ebp - jmp show_boot_progress_asm -.progress1a: - jmp die - - -stack_ok: - /* indicate progress */ - movw $0x03, %ax - movl $.progress2, %ebp - jmp show_boot_progress_asm -.progress2: - - wbinvd - - /* Get upper memory limit */ - movl %esp, %ecx - subl $CONFIG_SYS_STACK_SIZE, %ecx - - /* Create a Stack Frame */ - pushl %ebp - movl %esp, %ebp - - /* stack_limit parameter */ - pushl %ecx - call board_init_f /* Enter, U-boot! */ - - /* indicate (lack of) progress */ - movw $0x85, %ax - movl $.progress4a, %ebp - jmp show_boot_progress_asm -.progress4a: - -die: hlt - jmp die - hlt diff --git a/cpu/i386/start16.S b/cpu/i386/start16.S deleted file mode 100644 index 1ebb6bc8b6..0000000000 --- a/cpu/i386/start16.S +++ /dev/null @@ -1,112 +0,0 @@ -/* - * U-boot - i386 Startup Code - * - * Copyright (c) 2002, 2003 Omicron Ceti AB, Daniel Engström - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#define BOOT_SEG 0xffff0000 /* linear segment of boot code */ -#define a32 .byte 0x67; -#define o32 .byte 0x66; - -.section .start16, "ax" -.code16 -.globl start16 -start16: - /* First we let the BSP do some early initialization - * this code have to map the flash to its final position - */ - mov $board_init16_ret, %bp - jmp board_init16 -board_init16_ret: - - /* Turn of cache (this might require a 486-class CPU) */ - movl %cr0, %eax - orl $0x60000000,%eax - movl %eax, %cr0 - wbinvd - - /* load the descriptor tables */ -o32 cs lidt idt_ptr -o32 cs lgdt gdt_ptr - - - /* Now, we enter protected mode */ - movl %cr0, %eax - orl $1,%eax - movl %eax, %cr0 - - /* Flush the prefetch queue */ - jmp ff -ff: - - /* Finally jump to the 32bit initialization code */ - movw $code32start, %ax - movw %ax,%bp -o32 cs ljmp *(%bp) - - /* 48-bit far pointer */ -code32start: - .long _start /* offset */ - .word 0x10 /* segment */ - -idt_ptr: - .word 0 /* limit */ - .long 0 /* base */ - -gdt_ptr: - .word 0x30 /* limit (48 bytes = 6 GDT entries) */ - .long BOOT_SEG + gdt /* base */ - - /* The GDT table ... - * - * Selector Type - * 0x00 NULL - * 0x08 Unused - * 0x10 32bit code - * 0x18 32bit data/stack - * 0x20 16bit code - * 0x28 16bit data/stack - */ - -gdt: - .word 0, 0, 0, 0 /* NULL */ - .word 0, 0, 0, 0 /* unused */ - - .word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */ - .word 0 /* base address = 0 */ - .word 0x9B00 /* code read/exec */ - .word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */ - - .word 0xFFFF /* 4Gb - (0x100000*0x1000 = 4Gb) */ - .word 0x0 /* base address = 0 */ - .word 0x9300 /* data read/write */ - .word 0x00CF /* granularity = 4096, 386 (+5th nibble of limit) */ - - .word 0xFFFF /* 64kb */ - .word 0 /* base address = 0 */ - .word 0x9b00 /* data read/write */ - .word 0x0010 /* granularity = 1 (+5th nibble of limit) */ - - .word 0xFFFF /* 64kb */ - .word 0 /* base address = 0 */ - .word 0x9300 /* data read/write */ - .word 0x0010 /* granularity = 1 (+5th nibble of limit) */ diff --git a/doc/TODO-i386 b/doc/TODO-i386 index 2261f4a1f3..9b6c5d41ab 100644 --- a/doc/TODO-i386 +++ b/doc/TODO-i386 @@ -4,11 +4,11 @@ i386 port missing features: * setup the BIOS data area and BIOS equipment word to reflect machine config. * Make reset work (from Linux and from the boot prompt) * DMA, FDC, RTC, KBC initialization -* split of part of cpu/i386/interrupt.c to cpu/i385/entry.c? +* split of part of arch/i386/cpu/interrupt.c to cpu/i385/entry.c? * re-entry of protected mode from real mode, should be added to realmode_switch.S (and used by INT 10h and INT 16h handlers for console I/O during early linux boot...) -* missing functions in arch/i386/lib and cpu/i386 +* missing functions in arch/i386/lib and arch/i386/cpu * speaker beep interface