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

pcit.c (6373B)


      1/*
      2 * PCI Tower specific code
      3 *
      4 * This file is subject to the terms and conditions of the GNU General Public
      5 * License.  See the file "COPYING" in the main directory of this archive
      6 * for more details.
      7 *
      8 * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
      9 */
     10
     11#include <linux/init.h>
     12#include <linux/interrupt.h>
     13#include <linux/irq.h>
     14#include <linux/pci.h>
     15#include <linux/serial_8250.h>
     16
     17#include <asm/sni.h>
     18#include <asm/time.h>
     19#include <asm/irq_cpu.h>
     20
     21
     22#define PORT(_base,_irq)				\
     23	{						\
     24		.iobase		= _base,		\
     25		.irq		= _irq,			\
     26		.uartclk	= 1843200,		\
     27		.iotype		= UPIO_PORT,		\
     28		.flags		= UPF_BOOT_AUTOCONF,	\
     29	}
     30
     31static struct plat_serial8250_port pcit_data[] = {
     32	PORT(0x3f8, 0),
     33	PORT(0x2f8, 3),
     34	{ },
     35};
     36
     37static struct platform_device pcit_serial8250_device = {
     38	.name			= "serial8250",
     39	.id			= PLAT8250_DEV_PLATFORM,
     40	.dev			= {
     41		.platform_data	= pcit_data,
     42	},
     43};
     44
     45static struct plat_serial8250_port pcit_cplus_data[] = {
     46	PORT(0x3f8, 0),
     47	PORT(0x2f8, 3),
     48	PORT(0x3e8, 4),
     49	PORT(0x2e8, 3),
     50	{ },
     51};
     52
     53static struct platform_device pcit_cplus_serial8250_device = {
     54	.name			= "serial8250",
     55	.id			= PLAT8250_DEV_PLATFORM,
     56	.dev			= {
     57		.platform_data	= pcit_cplus_data,
     58	},
     59};
     60
     61static struct resource pcit_cmos_rsrc[] = {
     62	{
     63		.start = 0x70,
     64		.end   = 0x71,
     65		.flags = IORESOURCE_IO
     66	},
     67	{
     68		.start = 8,
     69		.end   = 8,
     70		.flags = IORESOURCE_IRQ
     71	}
     72};
     73
     74static struct platform_device pcit_cmos_device = {
     75	.name		= "rtc_cmos",
     76	.num_resources	= ARRAY_SIZE(pcit_cmos_rsrc),
     77	.resource	= pcit_cmos_rsrc
     78};
     79
     80static struct platform_device pcit_pcspeaker_pdev = {
     81	.name		= "pcspkr",
     82	.id		= -1,
     83};
     84
     85static struct resource sni_io_resource = {
     86	.start	= 0x00000000UL,
     87	.end	= 0x03bfffffUL,
     88	.name	= "PCIT IO",
     89	.flags	= IORESOURCE_IO,
     90};
     91
     92static struct resource pcit_io_resources[] = {
     93	{
     94		.start	= 0x00,
     95		.end	= 0x1f,
     96		.name	= "dma1",
     97		.flags	= IORESOURCE_BUSY
     98	}, {
     99		.start	=  0x40,
    100		.end	= 0x5f,
    101		.name	= "timer",
    102		.flags	= IORESOURCE_BUSY
    103	}, {
    104		.start	=  0x60,
    105		.end	= 0x6f,
    106		.name	= "keyboard",
    107		.flags	= IORESOURCE_BUSY
    108	}, {
    109		.start	=  0x80,
    110		.end	= 0x8f,
    111		.name	= "dma page reg",
    112		.flags	= IORESOURCE_BUSY
    113	}, {
    114		.start	=  0xc0,
    115		.end	= 0xdf,
    116		.name	= "dma2",
    117		.flags	= IORESOURCE_BUSY
    118	}, {
    119		.start	=  0xcf8,
    120		.end	= 0xcfb,
    121		.name	= "PCI config addr",
    122		.flags	= IORESOURCE_BUSY
    123	}, {
    124		.start	=  0xcfc,
    125		.end	= 0xcff,
    126		.name	= "PCI config data",
    127		.flags	= IORESOURCE_BUSY
    128	}
    129};
    130
    131static void __init sni_pcit_resource_init(void)
    132{
    133	int i;
    134
    135	/* request I/O space for devices used on all i[345]86 PCs */
    136	for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
    137		request_resource(&sni_io_resource, pcit_io_resources + i);
    138}
    139
    140
    141extern struct pci_ops sni_pcit_ops;
    142
    143#ifdef CONFIG_PCI
    144static struct resource sni_mem_resource = {
    145	.start	= 0x18000000UL,
    146	.end	= 0x1fbfffffUL,
    147	.name	= "PCIT PCI MEM",
    148	.flags	= IORESOURCE_MEM
    149};
    150
    151static struct pci_controller sni_pcit_controller = {
    152	.pci_ops	= &sni_pcit_ops,
    153	.mem_resource	= &sni_mem_resource,
    154	.mem_offset	= 0x00000000UL,
    155	.io_resource	= &sni_io_resource,
    156	.io_offset	= 0x00000000UL,
    157	.io_map_base	= SNI_PORT_BASE
    158};
    159#endif /* CONFIG_PCI */
    160
    161static void enable_pcit_irq(struct irq_data *d)
    162{
    163	u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
    164
    165	*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
    166}
    167
    168void disable_pcit_irq(struct irq_data *d)
    169{
    170	u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
    171
    172	*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
    173}
    174
    175static struct irq_chip pcit_irq_type = {
    176	.name = "PCIT",
    177	.irq_mask = disable_pcit_irq,
    178	.irq_unmask = enable_pcit_irq,
    179};
    180
    181static void pcit_hwint1(void)
    182{
    183	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
    184	int irq;
    185
    186	clear_c0_status(IE_IRQ1);
    187	irq = ffs((pending >> 16) & 0x7f);
    188
    189	if (likely(irq > 0))
    190		do_IRQ(irq + SNI_PCIT_INT_START - 1);
    191	set_c0_status(IE_IRQ1);
    192}
    193
    194static void pcit_hwint0(void)
    195{
    196	u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
    197	int irq;
    198
    199	clear_c0_status(IE_IRQ0);
    200	irq = ffs((pending >> 16) & 0x3f);
    201
    202	if (likely(irq > 0))
    203		do_IRQ(irq + SNI_PCIT_INT_START - 1);
    204	set_c0_status(IE_IRQ0);
    205}
    206
    207static void sni_pcit_hwint(void)
    208{
    209	u32 pending = read_c0_cause() & read_c0_status();
    210
    211	if (pending & C_IRQ1)
    212		pcit_hwint1();
    213	else if (pending & C_IRQ2)
    214		do_IRQ(MIPS_CPU_IRQ_BASE + 4);
    215	else if (pending & C_IRQ3)
    216		do_IRQ(MIPS_CPU_IRQ_BASE + 5);
    217	else if (pending & C_IRQ5)
    218		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
    219}
    220
    221static void sni_pcit_hwint_cplus(void)
    222{
    223	u32 pending = read_c0_cause() & read_c0_status();
    224
    225	if (pending & C_IRQ0)
    226		pcit_hwint0();
    227	else if (pending & C_IRQ1)
    228		do_IRQ(MIPS_CPU_IRQ_BASE + 3);
    229	else if (pending & C_IRQ2)
    230		do_IRQ(MIPS_CPU_IRQ_BASE + 4);
    231	else if (pending & C_IRQ3)
    232		do_IRQ(MIPS_CPU_IRQ_BASE + 5);
    233	else if (pending & C_IRQ5)
    234		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
    235}
    236
    237void __init sni_pcit_irq_init(void)
    238{
    239	int i;
    240
    241	mips_cpu_irq_init();
    242	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
    243		irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
    244	*(volatile u32 *)SNI_PCIT_INT_REG = 0;
    245	sni_hwint = sni_pcit_hwint;
    246	change_c0_status(ST0_IM, IE_IRQ1);
    247	if (request_irq(SNI_PCIT_INT_START + 6, sni_isa_irq_handler, 0, "ISA",
    248			NULL))
    249		pr_err("Failed to register ISA interrupt\n");
    250}
    251
    252void __init sni_pcit_cplus_irq_init(void)
    253{
    254	int i;
    255
    256	mips_cpu_irq_init();
    257	for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
    258		irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
    259	*(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
    260	sni_hwint = sni_pcit_hwint_cplus;
    261	change_c0_status(ST0_IM, IE_IRQ0);
    262	if (request_irq(MIPS_CPU_IRQ_BASE + 3, sni_isa_irq_handler, 0, "ISA",
    263			NULL))
    264		pr_err("Failed to register ISA interrupt\n");
    265}
    266
    267void __init sni_pcit_init(void)
    268{
    269	ioport_resource.end = sni_io_resource.end;
    270#ifdef CONFIG_PCI
    271	PCIBIOS_MIN_IO = 0x9000;
    272	register_pci_controller(&sni_pcit_controller);
    273#endif
    274	sni_pcit_resource_init();
    275}
    276
    277static int __init snirm_pcit_setup_devinit(void)
    278{
    279	switch (sni_brd_type) {
    280	case SNI_BRD_PCI_TOWER:
    281		platform_device_register(&pcit_serial8250_device);
    282		platform_device_register(&pcit_cmos_device);
    283		platform_device_register(&pcit_pcspeaker_pdev);
    284		break;
    285
    286	case SNI_BRD_PCI_TOWER_CPLUS:
    287		platform_device_register(&pcit_cplus_serial8250_device);
    288		platform_device_register(&pcit_cmos_device);
    289		platform_device_register(&pcit_pcspeaker_pdev);
    290		break;
    291	}
    292	return 0;
    293}
    294
    295device_initcall(snirm_pcit_setup_devinit);