123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * arch/v850/kernel/fpga85e2c.h -- Machine-dependent defs for
- * FPGA implementation of V850E2/NA85E2C
- *
- * Copyright (C) 2002,03 NEC Electronics Corporation
- * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of this
- * archive for more details.
- *
- * Written by Miles Bader <miles@gnu.org>
- */
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/mm.h>
- #include <linux/swap.h>
- #include <linux/bootmem.h>
- #include <linux/irq.h>
- #include <linux/bitops.h>
- #include <asm/atomic.h>
- #include <asm/page.h>
- #include <asm/machdep.h>
- #include "mach.h"
- extern void memcons_setup (void);
- #define REG_DUMP_ADDR 0x220000
- extern struct irqaction reg_snap_action; /* fwd decl */
- void __init mach_early_init (void)
- {
- int i;
- const u32 *src;
- register u32 *dst asm ("ep");
- extern u32 _intv_end, _intv_load_start;
- /* Set bus sizes: CS0 32-bit, CS1 16-bit, CS7 8-bit,
- everything else 32-bit. */
- V850E2_BSC = 0x2AA6;
- for (i = 2; i <= 6; i++)
- CSDEV(i) = 0; /* 32 bit */
- /* Ensure that the simulator halts on a panic, instead of going
- into an infinite loop inside the panic function. */
- panic_timeout = -1;
- /* Move the interrupt vectors into their real location. Note that
- any relocations there are relative to the real location, so we
- don't have to fix anything up. We use a loop instead of calling
- memcpy to keep this a leaf function (to avoid a function
- prologue being generated). */
- dst = 0x10; /* &_intv_start + 0x10. */
- src = &_intv_load_start;
- do {
- u32 t0 = src[0], t1 = src[1], t2 = src[2], t3 = src[3];
- u32 t4 = src[4], t5 = src[5], t6 = src[6], t7 = src[7];
- dst[0] = t0; dst[1] = t1; dst[2] = t2; dst[3] = t3;
- dst[4] = t4; dst[5] = t5; dst[6] = t6; dst[7] = t7;
- dst += 8;
- src += 8;
- } while (dst < &_intv_end);
- }
- void __init mach_setup (char **cmdline)
- {
- memcons_setup ();
- /* Setup up NMI0 to copy the registers to a known memory location.
- The FGPA board has a button that produces NMI0 when pressed, so
- this allows us to push the button, and then look at memory to see
- what's in the registers (there's no other way to easily do so).
- We have to use `setup_irq' instead of `request_irq' because it's
- still too early to do memory allocation. */
- setup_irq (IRQ_NMI (0), ®_snap_action);
- }
- void mach_get_physical_ram (unsigned long *ram_start, unsigned long *ram_len)
- {
- *ram_start = ERAM_ADDR;
- *ram_len = ERAM_SIZE;
- }
- void __init mach_sched_init (struct irqaction *timer_action)
- {
- /* Setup up the timer interrupt. The FPGA peripheral control
- registers _only_ work with single-bit writes (set1/clr1)! */
- __clear_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
- __clear_bit (RPU_GTMC_CLK_BIT, &RPU_GTMC);
- __set_bit (RPU_GTMC_CE_BIT, &RPU_GTMC);
- /* We use the first RPU interrupt, which occurs every 8.192ms. */
- setup_irq (IRQ_RPU (0), timer_action);
- }
- void mach_gettimeofday (struct timespec *tv)
- {
- tv->tv_sec = 0;
- tv->tv_nsec = 0;
- }
- void machine_halt (void) __attribute__ ((noreturn));
- void machine_halt (void)
- {
- for (;;) {
- DWC(0) = 0x7777;
- DWC(1) = 0x7777;
- ASC = 0xffff;
- FLGREG(0) = 1; /* Halt immediately. */
- asm ("di; halt; nop; nop; nop; nop; nop");
- }
- }
- void machine_restart (char *__unused)
- {
- machine_halt ();
- }
- void machine_power_off (void)
- {
- machine_halt ();
- }
- /* Interrupts */
- struct v850e_intc_irq_init irq_inits[] = {
- { "IRQ", 0, NUM_MACH_IRQS, 1, 7 },
- { "RPU", IRQ_RPU(0), IRQ_RPU_NUM, 1, 6 },
- { 0 }
- };
- #define NUM_IRQ_INITS ((sizeof irq_inits / sizeof irq_inits[0]) - 1)
- struct hw_interrupt_type hw_itypes[NUM_IRQ_INITS];
- /* Initialize interrupts. */
- void __init mach_init_irqs (void)
- {
- v850e_intc_init_irq_types (irq_inits, hw_itypes);
- }
- /* An interrupt handler that copies the registers to a known memory location,
- for debugging purposes. */
- static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
- {
- (*(unsigned *)REG_DUMP_ADDR)++;
- (*(struct pt_regs *)(REG_DUMP_ADDR + sizeof (unsigned))) = *regs;
- }
- static int reg_snap_dev_id;
- static struct irqaction reg_snap_action = {
- make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", ®_snap_dev_id, 0
- };
|