cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

common.c (7775B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  linux/arch/arm/mach-footbridge/common.c
      4 *
      5 *  Copyright (C) 1998-2000 Russell King, Dave Gilbert.
      6 */
      7#include <linux/module.h>
      8#include <linux/types.h>
      9#include <linux/mm.h>
     10#include <linux/ioport.h>
     11#include <linux/list.h>
     12#include <linux/init.h>
     13#include <linux/io.h>
     14#include <linux/spinlock.h>
     15#include <video/vga.h>
     16
     17#include <asm/page.h>
     18#include <asm/irq.h>
     19#include <asm/mach-types.h>
     20#include <asm/setup.h>
     21#include <asm/system_misc.h>
     22#include <asm/hardware/dec21285.h>
     23
     24#include <asm/mach/irq.h>
     25#include <asm/mach/map.h>
     26#include <asm/mach/pci.h>
     27
     28#include "common.h"
     29
     30#include <mach/hardware.h>
     31#include <mach/irqs.h>
     32#include <asm/hardware/dec21285.h>
     33
     34static int dc21285_get_irq(void)
     35{
     36	void __iomem *irqstatus = (void __iomem *)CSR_IRQ_STATUS;
     37	u32 mask = readl(irqstatus);
     38
     39	if (mask & IRQ_MASK_SDRAMPARITY)
     40		return IRQ_SDRAMPARITY;
     41
     42	if (mask & IRQ_MASK_UART_RX)
     43		return IRQ_CONRX;
     44
     45	if (mask & IRQ_MASK_DMA1)
     46		return IRQ_DMA1;
     47
     48	if (mask & IRQ_MASK_DMA2)
     49		return IRQ_DMA2;
     50
     51	if (mask & IRQ_MASK_IN0)
     52		return IRQ_IN0;
     53
     54	if (mask & IRQ_MASK_IN1)
     55		return IRQ_IN1;
     56
     57	if (mask & IRQ_MASK_IN2)
     58		return IRQ_IN2;
     59
     60	if (mask & IRQ_MASK_IN3)
     61		return IRQ_IN3;
     62
     63	if (mask & IRQ_MASK_PCI)
     64		return IRQ_PCI;
     65
     66	if (mask & IRQ_MASK_DOORBELLHOST)
     67		return IRQ_DOORBELLHOST;
     68
     69	if (mask & IRQ_MASK_I2OINPOST)
     70		return IRQ_I2OINPOST;
     71
     72	if (mask & IRQ_MASK_TIMER1)
     73		return IRQ_TIMER1;
     74
     75	if (mask & IRQ_MASK_TIMER2)
     76		return IRQ_TIMER2;
     77
     78	if (mask & IRQ_MASK_TIMER3)
     79		return IRQ_TIMER3;
     80
     81	if (mask & IRQ_MASK_UART_TX)
     82		return IRQ_CONTX;
     83
     84	if (mask & IRQ_MASK_PCI_ABORT)
     85		return IRQ_PCI_ABORT;
     86
     87	if (mask & IRQ_MASK_PCI_SERR)
     88		return IRQ_PCI_SERR;
     89
     90	if (mask & IRQ_MASK_DISCARD_TIMER)
     91		return IRQ_DISCARD_TIMER;
     92
     93	if (mask & IRQ_MASK_PCI_DPERR)
     94		return IRQ_PCI_DPERR;
     95
     96	if (mask & IRQ_MASK_PCI_PERR)
     97		return IRQ_PCI_PERR;
     98
     99	return 0;
    100}
    101
    102static void dc21285_handle_irq(struct pt_regs *regs)
    103{
    104	int irq;
    105	do {
    106		irq = dc21285_get_irq();
    107		if (!irq)
    108			break;
    109
    110		generic_handle_irq(irq);
    111	} while (1);
    112}
    113
    114
    115unsigned int mem_fclk_21285 = 50000000;
    116
    117EXPORT_SYMBOL(mem_fclk_21285);
    118
    119static int __init early_fclk(char *arg)
    120{
    121	mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
    122	return 0;
    123}
    124
    125early_param("mem_fclk_21285", early_fclk);
    126
    127static int __init parse_tag_memclk(const struct tag *tag)
    128{
    129	mem_fclk_21285 = tag->u.memclk.fmemclk;
    130	return 0;
    131}
    132
    133__tagtable(ATAG_MEMCLK, parse_tag_memclk);
    134
    135/*
    136 * Footbridge IRQ translation table
    137 *  Converts from our IRQ numbers into FootBridge masks
    138 */
    139static const int fb_irq_mask[] = {
    140	IRQ_MASK_UART_RX,	/*  0 */
    141	IRQ_MASK_UART_TX,	/*  1 */
    142	IRQ_MASK_TIMER1,	/*  2 */
    143	IRQ_MASK_TIMER2,	/*  3 */
    144	IRQ_MASK_TIMER3,	/*  4 */
    145	IRQ_MASK_IN0,		/*  5 */
    146	IRQ_MASK_IN1,		/*  6 */
    147	IRQ_MASK_IN2,		/*  7 */
    148	IRQ_MASK_IN3,		/*  8 */
    149	IRQ_MASK_DOORBELLHOST,	/*  9 */
    150	IRQ_MASK_DMA1,		/* 10 */
    151	IRQ_MASK_DMA2,		/* 11 */
    152	IRQ_MASK_PCI,		/* 12 */
    153	IRQ_MASK_SDRAMPARITY,	/* 13 */
    154	IRQ_MASK_I2OINPOST,	/* 14 */
    155	IRQ_MASK_PCI_ABORT,	/* 15 */
    156	IRQ_MASK_PCI_SERR,	/* 16 */
    157	IRQ_MASK_DISCARD_TIMER,	/* 17 */
    158	IRQ_MASK_PCI_DPERR,	/* 18 */
    159	IRQ_MASK_PCI_PERR,	/* 19 */
    160};
    161
    162static void fb_mask_irq(struct irq_data *d)
    163{
    164	*CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(d->irq)];
    165}
    166
    167static void fb_unmask_irq(struct irq_data *d)
    168{
    169	*CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(d->irq)];
    170}
    171
    172static struct irq_chip fb_chip = {
    173	.irq_ack	= fb_mask_irq,
    174	.irq_mask	= fb_mask_irq,
    175	.irq_unmask	= fb_unmask_irq,
    176};
    177
    178static void __init __fb_init_irq(void)
    179{
    180	unsigned int irq;
    181
    182	/*
    183	 * setup DC21285 IRQs
    184	 */
    185	*CSR_IRQ_DISABLE = -1;
    186	*CSR_FIQ_DISABLE = -1;
    187
    188	for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
    189		irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq);
    190		irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
    191	}
    192}
    193
    194void __init footbridge_init_irq(void)
    195{
    196	set_handle_irq(dc21285_handle_irq);
    197
    198	__fb_init_irq();
    199
    200	if (!footbridge_cfn_mode())
    201		return;
    202
    203	if (machine_is_ebsa285())
    204		/* The following is dependent on which slot
    205		 * you plug the Southbridge card into.  We
    206		 * currently assume that you plug it into
    207		 * the right-hand most slot.
    208		 */
    209		isa_init_irq(IRQ_PCI);
    210
    211	if (machine_is_cats())
    212		isa_init_irq(IRQ_IN2);
    213
    214	if (machine_is_netwinder())
    215		isa_init_irq(IRQ_IN3);
    216}
    217
    218/*
    219 * Common mapping for all systems.  Note that the outbound write flush is
    220 * commented out since there is a "No Fix" problem with it.  Not mapping
    221 * it means that we have extra bullet protection on our feet.
    222 */
    223static struct map_desc fb_common_io_desc[] __initdata = {
    224	{
    225		.virtual	= ARMCSR_BASE,
    226		.pfn		= __phys_to_pfn(DC21285_ARMCSR_BASE),
    227		.length		= ARMCSR_SIZE,
    228		.type		= MT_DEVICE,
    229	}
    230};
    231
    232/*
    233 * The mapping when the footbridge is in host mode.  We don't map any of
    234 * this when we are in add-in mode.
    235 */
    236static struct map_desc ebsa285_host_io_desc[] __initdata = {
    237#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
    238	{
    239		.virtual	= PCIMEM_BASE,
    240		.pfn		= __phys_to_pfn(DC21285_PCI_MEM),
    241		.length		= PCIMEM_SIZE,
    242		.type		= MT_DEVICE,
    243	}, {
    244		.virtual	= PCICFG0_BASE,
    245		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
    246		.length		= PCICFG0_SIZE,
    247		.type		= MT_DEVICE,
    248	}, {
    249		.virtual	= PCICFG1_BASE,
    250		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
    251		.length		= PCICFG1_SIZE,
    252		.type		= MT_DEVICE,
    253	}, {
    254		.virtual	= PCIIACK_BASE,
    255		.pfn		= __phys_to_pfn(DC21285_PCI_IACK),
    256		.length		= PCIIACK_SIZE,
    257		.type		= MT_DEVICE,
    258	},
    259#endif
    260};
    261
    262void __init footbridge_map_io(void)
    263{
    264	/*
    265	 * Set up the common mapping first; we need this to
    266	 * determine whether we're in host mode or not.
    267	 */
    268	iotable_init(fb_common_io_desc, ARRAY_SIZE(fb_common_io_desc));
    269
    270	/*
    271	 * Now, work out what we've got to map in addition on this
    272	 * platform.
    273	 */
    274	if (footbridge_cfn_mode()) {
    275		iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
    276		pci_map_io_early(__phys_to_pfn(DC21285_PCI_IO));
    277	}
    278
    279	vga_base = PCIMEM_BASE;
    280}
    281
    282void footbridge_restart(enum reboot_mode mode, const char *cmd)
    283{
    284	if (mode == REBOOT_SOFT) {
    285		/* Jump into the ROM */
    286		soft_restart(0x41000000);
    287	} else {
    288		/*
    289		 * Force the watchdog to do a CPU reset.
    290		 *
    291		 * After making sure that the watchdog is disabled
    292		 * (so we can change the timer registers) we first
    293		 * enable the timer to autoreload itself.  Next, the
    294		 * timer interval is set really short and any
    295		 * current interrupt request is cleared (so we can
    296		 * see an edge transition).  Finally, TIMER4 is
    297		 * enabled as the watchdog.
    298		 */
    299		*CSR_SA110_CNTL &= ~(1 << 13);
    300		*CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
    301				   TIMER_CNTL_AUTORELOAD |
    302				   TIMER_CNTL_DIV16;
    303		*CSR_TIMER4_LOAD = 0x2;
    304		*CSR_TIMER4_CLR  = 0;
    305		*CSR_SA110_CNTL |= (1 << 13);
    306	}
    307}
    308
    309#ifdef CONFIG_FOOTBRIDGE_ADDIN
    310
    311static inline unsigned long fb_bus_sdram_offset(void)
    312{
    313	return *CSR_PCISDRAMBASE & 0xfffffff0;
    314}
    315
    316/*
    317 * These two functions convert virtual addresses to PCI addresses and PCI
    318 * addresses to virtual addresses.  Note that it is only legal to use these
    319 * on memory obtained via get_zeroed_page or kmalloc.
    320 */
    321unsigned long __virt_to_bus(unsigned long res)
    322{
    323	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
    324
    325	return res + (fb_bus_sdram_offset() - PAGE_OFFSET);
    326}
    327EXPORT_SYMBOL(__virt_to_bus);
    328
    329unsigned long __bus_to_virt(unsigned long res)
    330{
    331	res = res - (fb_bus_sdram_offset() - PAGE_OFFSET);
    332
    333	WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
    334
    335	return res;
    336}
    337EXPORT_SYMBOL(__bus_to_virt);
    338
    339unsigned long __pfn_to_bus(unsigned long pfn)
    340{
    341	return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET);
    342}
    343EXPORT_SYMBOL(__pfn_to_bus);
    344
    345unsigned long __bus_to_pfn(unsigned long bus)
    346{
    347	return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET));
    348}
    349EXPORT_SYMBOL(__bus_to_pfn);
    350
    351#endif