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

config.c (20776B)


      1/*
      2 *  linux/arch/m68k/amiga/config.c
      3 *
      4 *  Copyright (C) 1993 Hamish Macdonald
      5 *
      6 * This file is subject to the terms and conditions of the GNU General Public
      7 * License.  See the file COPYING in the main directory of this archive
      8 * for more details.
      9 */
     10
     11/*
     12 * Miscellaneous Amiga stuff
     13 */
     14
     15#include <linux/types.h>
     16#include <linux/kernel.h>
     17#include <linux/mm.h>
     18#include <linux/seq_file.h>
     19#include <linux/tty.h>
     20#include <linux/clocksource.h>
     21#include <linux/console.h>
     22#include <linux/rtc.h>
     23#include <linux/init.h>
     24#include <linux/vt_kern.h>
     25#include <linux/delay.h>
     26#include <linux/interrupt.h>
     27#include <linux/zorro.h>
     28#include <linux/module.h>
     29#include <linux/keyboard.h>
     30
     31#include <asm/bootinfo.h>
     32#include <asm/bootinfo-amiga.h>
     33#include <asm/byteorder.h>
     34#include <asm/setup.h>
     35#include <asm/amigahw.h>
     36#include <asm/amigaints.h>
     37#include <asm/irq.h>
     38#include <asm/machdep.h>
     39#include <asm/io.h>
     40#include <asm/config.h>
     41
     42static unsigned long amiga_model;
     43
     44unsigned long amiga_eclock;
     45EXPORT_SYMBOL(amiga_eclock);
     46
     47unsigned long amiga_colorclock;
     48EXPORT_SYMBOL(amiga_colorclock);
     49
     50unsigned long amiga_chipset;
     51EXPORT_SYMBOL(amiga_chipset);
     52
     53unsigned char amiga_vblank;
     54EXPORT_SYMBOL(amiga_vblank);
     55
     56static unsigned char amiga_psfreq;
     57
     58struct amiga_hw_present amiga_hw_present;
     59EXPORT_SYMBOL(amiga_hw_present);
     60
     61static char s_a500[] __initdata = "A500";
     62static char s_a500p[] __initdata = "A500+";
     63static char s_a600[] __initdata = "A600";
     64static char s_a1000[] __initdata = "A1000";
     65static char s_a1200[] __initdata = "A1200";
     66static char s_a2000[] __initdata = "A2000";
     67static char s_a2500[] __initdata = "A2500";
     68static char s_a3000[] __initdata = "A3000";
     69static char s_a3000t[] __initdata = "A3000T";
     70static char s_a3000p[] __initdata = "A3000+";
     71static char s_a4000[] __initdata = "A4000";
     72static char s_a4000t[] __initdata = "A4000T";
     73static char s_cdtv[] __initdata = "CDTV";
     74static char s_cd32[] __initdata = "CD32";
     75static char s_draco[] __initdata = "Draco";
     76static char *amiga_models[] __initdata = {
     77	[AMI_500-AMI_500]	= s_a500,
     78	[AMI_500PLUS-AMI_500]	= s_a500p,
     79	[AMI_600-AMI_500]	= s_a600,
     80	[AMI_1000-AMI_500]	= s_a1000,
     81	[AMI_1200-AMI_500]	= s_a1200,
     82	[AMI_2000-AMI_500]	= s_a2000,
     83	[AMI_2500-AMI_500]	= s_a2500,
     84	[AMI_3000-AMI_500]	= s_a3000,
     85	[AMI_3000T-AMI_500]	= s_a3000t,
     86	[AMI_3000PLUS-AMI_500]	= s_a3000p,
     87	[AMI_4000-AMI_500]	= s_a4000,
     88	[AMI_4000T-AMI_500]	= s_a4000t,
     89	[AMI_CDTV-AMI_500]	= s_cdtv,
     90	[AMI_CD32-AMI_500]	= s_cd32,
     91	[AMI_DRACO-AMI_500]	= s_draco,
     92};
     93
     94static char amiga_model_name[13] = "Amiga ";
     95
     96static void amiga_sched_init(void);
     97static void amiga_get_model(char *model);
     98static void amiga_get_hardware_list(struct seq_file *m);
     99extern void amiga_mksound(unsigned int count, unsigned int ticks);
    100static void amiga_reset(void);
    101extern void amiga_init_sound(void);
    102static void amiga_mem_console_write(struct console *co, const char *b,
    103				    unsigned int count);
    104#ifdef CONFIG_HEARTBEAT
    105static void amiga_heartbeat(int on);
    106#endif
    107
    108static struct console amiga_console_driver = {
    109	.name	= "debug",
    110	.flags	= CON_PRINTBUFFER,
    111	.index	= -1,
    112};
    113
    114
    115    /*
    116     *  Motherboard Resources present in all Amiga models
    117     */
    118
    119static struct {
    120	struct resource _ciab, _ciaa, _custom, _kickstart;
    121} mb_resources = {
    122	._ciab = {
    123		.name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff
    124	},
    125	._ciaa = {
    126		.name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff
    127	},
    128	._custom = {
    129		.name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff
    130	},
    131	._kickstart = {
    132		.name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff
    133	}
    134};
    135
    136static struct resource ram_resource[NUM_MEMINFO];
    137
    138
    139    /*
    140     *  Parse an Amiga-specific record in the bootinfo
    141     */
    142
    143int __init amiga_parse_bootinfo(const struct bi_record *record)
    144{
    145	int unknown = 0;
    146	const void *data = record->data;
    147
    148	switch (be16_to_cpu(record->tag)) {
    149	case BI_AMIGA_MODEL:
    150		amiga_model = be32_to_cpup(data);
    151		break;
    152
    153	case BI_AMIGA_ECLOCK:
    154		amiga_eclock = be32_to_cpup(data);
    155		break;
    156
    157	case BI_AMIGA_CHIPSET:
    158		amiga_chipset = be32_to_cpup(data);
    159		break;
    160
    161	case BI_AMIGA_CHIP_SIZE:
    162		amiga_chip_size = be32_to_cpup(data);
    163		break;
    164
    165	case BI_AMIGA_VBLANK:
    166		amiga_vblank = *(const __u8 *)data;
    167		break;
    168
    169	case BI_AMIGA_PSFREQ:
    170		amiga_psfreq = *(const __u8 *)data;
    171		break;
    172
    173	case BI_AMIGA_AUTOCON:
    174#ifdef CONFIG_ZORRO
    175		if (zorro_num_autocon < ZORRO_NUM_AUTO) {
    176			const struct ConfigDev *cd = data;
    177			struct zorro_dev_init *dev = &zorro_autocon_init[zorro_num_autocon++];
    178			dev->rom = cd->cd_Rom;
    179			dev->slotaddr = be16_to_cpu(cd->cd_SlotAddr);
    180			dev->slotsize = be16_to_cpu(cd->cd_SlotSize);
    181			dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr);
    182			dev->boardsize = be32_to_cpu(cd->cd_BoardSize);
    183		} else
    184			pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n");
    185#endif /* CONFIG_ZORRO */
    186		break;
    187
    188	case BI_AMIGA_SERPER:
    189		/* serial port period: ignored here */
    190		break;
    191
    192	default:
    193		unknown = 1;
    194	}
    195	return unknown;
    196}
    197
    198    /*
    199     *  Identify builtin hardware
    200     */
    201
    202static void __init amiga_identify(void)
    203{
    204	/* Fill in some default values, if necessary */
    205	if (amiga_eclock == 0)
    206		amiga_eclock = 709379;
    207
    208	memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
    209
    210	pr_info("Amiga hardware found: ");
    211	if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) {
    212		pr_cont("[%s] ", amiga_models[amiga_model-AMI_500]);
    213		strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]);
    214	}
    215
    216	switch (amiga_model) {
    217	case AMI_UNKNOWN:
    218		break;
    219
    220	case AMI_600:
    221	case AMI_1200:
    222		AMIGAHW_SET(A1200_IDE);
    223		AMIGAHW_SET(PCMCIA);
    224		fallthrough;
    225	case AMI_500:
    226	case AMI_500PLUS:
    227	case AMI_1000:
    228	case AMI_2000:
    229	case AMI_2500:
    230		AMIGAHW_SET(A2000_CLK);	/* Is this correct for all models? */
    231		break;
    232
    233	case AMI_3000:
    234	case AMI_3000T:
    235		AMIGAHW_SET(AMBER_FF);
    236		AMIGAHW_SET(MAGIC_REKICK);
    237		fallthrough;
    238	case AMI_3000PLUS:
    239		AMIGAHW_SET(A3000_SCSI);
    240		AMIGAHW_SET(A3000_CLK);
    241		AMIGAHW_SET(ZORRO3);
    242		break;
    243
    244	case AMI_4000T:
    245		AMIGAHW_SET(A4000_SCSI);
    246		fallthrough;
    247	case AMI_4000:
    248		AMIGAHW_SET(A4000_IDE);
    249		AMIGAHW_SET(A3000_CLK);
    250		AMIGAHW_SET(ZORRO3);
    251		break;
    252
    253	case AMI_CDTV:
    254	case AMI_CD32:
    255		AMIGAHW_SET(CD_ROM);
    256		AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
    257		break;
    258
    259	case AMI_DRACO:
    260		panic("No support for Draco yet");
    261
    262	default:
    263		panic("Unknown Amiga Model");
    264	}
    265
    266	AMIGAHW_SET(AMI_VIDEO);
    267	AMIGAHW_SET(AMI_BLITTER);
    268	AMIGAHW_SET(AMI_AUDIO);
    269	AMIGAHW_SET(AMI_FLOPPY);
    270	AMIGAHW_SET(AMI_KEYBOARD);
    271	AMIGAHW_SET(AMI_MOUSE);
    272	AMIGAHW_SET(AMI_SERIAL);
    273	AMIGAHW_SET(AMI_PARALLEL);
    274	AMIGAHW_SET(CHIP_RAM);
    275	AMIGAHW_SET(PAULA);
    276
    277	switch (amiga_chipset) {
    278	case CS_OCS:
    279	case CS_ECS:
    280	case CS_AGA:
    281		switch (amiga_custom.deniseid & 0xf) {
    282		case 0x0c:
    283			AMIGAHW_SET(DENISE_HR);
    284			break;
    285		case 0x08:
    286			AMIGAHW_SET(LISA);
    287			break;
    288		default:
    289			AMIGAHW_SET(DENISE);
    290			break;
    291		}
    292		break;
    293	}
    294	switch ((amiga_custom.vposr>>8) & 0x7f) {
    295	case 0x00:
    296		AMIGAHW_SET(AGNUS_PAL);
    297		break;
    298	case 0x10:
    299		AMIGAHW_SET(AGNUS_NTSC);
    300		break;
    301	case 0x20:
    302	case 0x21:
    303		AMIGAHW_SET(AGNUS_HR_PAL);
    304		break;
    305	case 0x30:
    306	case 0x31:
    307		AMIGAHW_SET(AGNUS_HR_NTSC);
    308		break;
    309	case 0x22:
    310	case 0x23:
    311		AMIGAHW_SET(ALICE_PAL);
    312		break;
    313	case 0x32:
    314	case 0x33:
    315		AMIGAHW_SET(ALICE_NTSC);
    316		break;
    317	}
    318	AMIGAHW_SET(ZORRO);
    319
    320#define AMIGAHW_ANNOUNCE(name, str)		\
    321	if (AMIGAHW_PRESENT(name))		\
    322		pr_cont(str)
    323
    324	AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO ");
    325	AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER ");
    326	AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF ");
    327	AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO ");
    328	AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY ");
    329	AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI ");
    330	AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI ");
    331	AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE ");
    332	AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE ");
    333	AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM ");
    334	AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD ");
    335	AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE ");
    336	AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL ");
    337	AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL ");
    338	AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK ");
    339	AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK ");
    340	AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM ");
    341	AMIGAHW_ANNOUNCE(PAULA, "PAULA ");
    342	AMIGAHW_ANNOUNCE(DENISE, "DENISE ");
    343	AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR ");
    344	AMIGAHW_ANNOUNCE(LISA, "LISA ");
    345	AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL ");
    346	AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC ");
    347	AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL ");
    348	AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC ");
    349	AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL ");
    350	AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC ");
    351	AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK ");
    352	AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA ");
    353	if (AMIGAHW_PRESENT(ZORRO))
    354		pr_cont("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : "");
    355	pr_cont("\n");
    356
    357#undef AMIGAHW_ANNOUNCE
    358}
    359
    360
    361static unsigned long amiga_random_get_entropy(void)
    362{
    363	/* VPOSR/VHPOSR provide at least 17 bits of data changing at 1.79 MHz */
    364	return *(unsigned long *)&amiga_custom.vposr;
    365}
    366
    367
    368    /*
    369     *  Setup the Amiga configuration info
    370     */
    371
    372void __init config_amiga(void)
    373{
    374	int i;
    375
    376	amiga_identify();
    377
    378	/* Yuk, we don't have PCI memory */
    379	iomem_resource.name = "Memory";
    380	for (i = 0; i < 4; i++)
    381		request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
    382
    383	mach_sched_init      = amiga_sched_init;
    384	mach_init_IRQ        = amiga_init_IRQ;
    385	mach_get_model       = amiga_get_model;
    386	mach_get_hardware_list = amiga_get_hardware_list;
    387	mach_reset           = amiga_reset;
    388#if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
    389	mach_beep            = amiga_mksound;
    390#endif
    391
    392#ifdef CONFIG_HEARTBEAT
    393	mach_heartbeat = amiga_heartbeat;
    394#endif
    395
    396	mach_random_get_entropy = amiga_random_get_entropy;
    397
    398	/* Fill in the clock value (based on the 700 kHz E-Clock) */
    399	amiga_colorclock = 5*amiga_eclock;	/* 3.5 MHz */
    400
    401	/* clear all DMA bits */
    402	amiga_custom.dmacon = DMAF_ALL;
    403	/* ensure that the DMA master bit is set */
    404	amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
    405
    406	/* don't use Z2 RAM as system memory on Z3 capable machines */
    407	if (AMIGAHW_PRESENT(ZORRO3)) {
    408		int i, j;
    409		u32 disabled_z2mem = 0;
    410
    411		for (i = 0; i < m68k_num_memory; i++) {
    412			if (m68k_memory[i].addr < 16*1024*1024) {
    413				if (i == 0) {
    414					/* don't cut off the branch we're sitting on */
    415					pr_warn("Warning: kernel runs in Zorro II memory\n");
    416					continue;
    417				}
    418				disabled_z2mem += m68k_memory[i].size;
    419				m68k_num_memory--;
    420				for (j = i; j < m68k_num_memory; j++)
    421					m68k_memory[j] = m68k_memory[j+1];
    422				i--;
    423			}
    424		}
    425		if (disabled_z2mem)
    426			pr_info("%dK of Zorro II memory will not be used as system memory\n",
    427				disabled_z2mem>>10);
    428	}
    429
    430	/* request all RAM */
    431	for (i = 0; i < m68k_num_memory; i++) {
    432		ram_resource[i].name =
    433			(m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" :
    434			(m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" :
    435			"16-bit Slow RAM";
    436		ram_resource[i].start = m68k_memory[i].addr;
    437		ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1;
    438		request_resource(&iomem_resource, &ram_resource[i]);
    439	}
    440
    441	/* initialize chipram allocator */
    442	amiga_chip_init();
    443
    444	/* our beloved beeper */
    445	if (AMIGAHW_PRESENT(AMI_AUDIO))
    446		amiga_init_sound();
    447
    448	/*
    449	 * if it is an A3000, set the magic bit that forces
    450	 * a hard rekick
    451	 */
    452	if (AMIGAHW_PRESENT(MAGIC_REKICK))
    453		*(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80;
    454}
    455
    456static u64 amiga_read_clk(struct clocksource *cs);
    457
    458static struct clocksource amiga_clk = {
    459	.name   = "ciab",
    460	.rating = 250,
    461	.read   = amiga_read_clk,
    462	.mask   = CLOCKSOURCE_MASK(32),
    463	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
    464};
    465
    466static unsigned short jiffy_ticks;
    467static u32 clk_total, clk_offset;
    468
    469static irqreturn_t ciab_timer_handler(int irq, void *dev_id)
    470{
    471	clk_total += jiffy_ticks;
    472	clk_offset = 0;
    473	legacy_timer_tick(1);
    474	timer_heartbeat();
    475
    476	return IRQ_HANDLED;
    477}
    478
    479static void __init amiga_sched_init(void)
    480{
    481	static struct resource sched_res = {
    482		.name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
    483	};
    484	jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ);
    485
    486	if (request_resource(&mb_resources._ciab, &sched_res))
    487		pr_warn("Cannot allocate ciab.ta{lo,hi}\n");
    488	ciab.cra &= 0xC0;   /* turn off timer A, continuous mode, from Eclk */
    489	ciab.talo = jiffy_ticks % 256;
    490	ciab.tahi = jiffy_ticks / 256;
    491
    492	/* install interrupt service routine for CIAB Timer A
    493	 *
    494	 * Please don't change this to use ciaa, as it interferes with the
    495	 * SCSI code. We'll have to take a look at this later
    496	 */
    497	if (request_irq(IRQ_AMIGA_CIAB_TA, ciab_timer_handler, IRQF_TIMER,
    498			"timer", NULL))
    499		pr_err("Couldn't register timer interrupt\n");
    500	/* start timer */
    501	ciab.cra |= 0x11;
    502
    503	clocksource_register_hz(&amiga_clk, amiga_eclock);
    504}
    505
    506static u64 amiga_read_clk(struct clocksource *cs)
    507{
    508	unsigned short hi, lo, hi2;
    509	unsigned long flags;
    510	u32 ticks;
    511
    512	local_irq_save(flags);
    513
    514	/* read CIA B timer A current value */
    515	hi  = ciab.tahi;
    516	lo  = ciab.talo;
    517	hi2 = ciab.tahi;
    518
    519	if (hi != hi2) {
    520		lo = ciab.talo;
    521		hi = hi2;
    522	}
    523
    524	ticks = hi << 8 | lo;
    525
    526	if (ticks > jiffy_ticks / 2)
    527		/* check for pending interrupt */
    528		if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
    529			clk_offset = jiffy_ticks;
    530
    531	ticks = jiffy_ticks - ticks;
    532	ticks += clk_offset + clk_total;
    533
    534	local_irq_restore(flags);
    535
    536	return ticks;
    537}
    538
    539static void amiga_reset(void)  __noreturn;
    540
    541static void amiga_reset(void)
    542{
    543	unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
    544	unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label);
    545
    546	local_irq_disable();
    547	if (CPU_IS_040_OR_060)
    548		/* Setup transparent translation registers for mapping
    549		 * of 16 MB kernel segment before disabling translation
    550		 */
    551		asm volatile ("\n"
    552			"	move.l	%0,%%d0\n"
    553			"	and.l	#0xff000000,%%d0\n"
    554			"	or.w	#0xe020,%%d0\n"   /* map 16 MB, enable, cacheable */
    555			"	.chip	68040\n"
    556			"	movec	%%d0,%%itt0\n"
    557			"	movec	%%d0,%%dtt0\n"
    558			"	.chip	68k\n"
    559			"	jmp	%0@\n"
    560			: /* no outputs */
    561			: "a" (jmp_addr040)
    562			: "d0");
    563	else
    564		/* for 680[23]0, just disable translation and jump to the physical
    565		 * address of the label
    566		 */
    567		asm volatile ("\n"
    568			"	pmove	%%tc,%@\n"
    569			"	bclr	#7,%@\n"
    570			"	pmove	%@,%%tc\n"
    571			"	jmp	%0@\n"
    572			: /* no outputs */
    573			: "a" (jmp_addr));
    574jmp_addr_label040:
    575	/* disable translation on '040 now */
    576	asm volatile ("\n"
    577		"	moveq	#0,%%d0\n"
    578		"	.chip	68040\n"
    579		"	movec	%%d0,%%tc\n"	/* disable MMU */
    580		"	.chip	68k\n"
    581		: /* no outputs */
    582		: /* no inputs */
    583		: "d0");
    584
    585	jmp_addr_label:
    586	/* pickup reset address from AmigaOS ROM, reset devices and jump
    587	 * to reset address
    588	 */
    589	asm volatile ("\n"
    590		"	move.w	#0x2700,%sr\n"
    591		"	lea	0x01000000,%a0\n"
    592		"	sub.l	%a0@(-0x14),%a0\n"
    593		"	move.l	%a0@(4),%a0\n"
    594		"	subq.l	#2,%a0\n"
    595		"	jra	1f\n"
    596		/* align on a longword boundary */
    597		"	" __ALIGN_STR "\n"
    598		"1:\n"
    599		"	reset\n"
    600		"	jmp   %a0@");
    601
    602	for (;;)
    603		;
    604}
    605
    606
    607    /*
    608     *  Debugging
    609     */
    610
    611#define SAVEKMSG_MAXMEM		128*1024
    612
    613#define SAVEKMSG_MAGIC1		0x53415645	/* 'SAVE' */
    614#define SAVEKMSG_MAGIC2		0x4B4D5347	/* 'KMSG' */
    615
    616struct savekmsg {
    617	unsigned long magic1;		/* SAVEKMSG_MAGIC1 */
    618	unsigned long magic2;		/* SAVEKMSG_MAGIC2 */
    619	unsigned long magicptr;		/* address of magic1 */
    620	unsigned long size;
    621	char data[];
    622};
    623
    624static struct savekmsg *savekmsg;
    625
    626static void amiga_mem_console_write(struct console *co, const char *s,
    627				    unsigned int count)
    628{
    629	if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {
    630		memcpy(savekmsg->data + savekmsg->size, s, count);
    631		savekmsg->size += count;
    632	}
    633}
    634
    635static int __init amiga_savekmsg_setup(char *arg)
    636{
    637	bool registered;
    638
    639	if (!MACH_IS_AMIGA || strcmp(arg, "mem"))
    640		return 0;
    641
    642	if (amiga_chip_size < SAVEKMSG_MAXMEM) {
    643		pr_err("Not enough chipram for debugging\n");
    644		return -ENOMEM;
    645	}
    646
    647	/* Just steal the block, the chipram allocator isn't functional yet */
    648	amiga_chip_size -= SAVEKMSG_MAXMEM;
    649	savekmsg = ZTWO_VADDR(CHIP_PHYSADDR + amiga_chip_size);
    650	savekmsg->magic1 = SAVEKMSG_MAGIC1;
    651	savekmsg->magic2 = SAVEKMSG_MAGIC2;
    652	savekmsg->magicptr = ZTWO_PADDR(savekmsg);
    653	savekmsg->size = 0;
    654
    655	registered = !!amiga_console_driver.write;
    656	amiga_console_driver.write = amiga_mem_console_write;
    657	if (!registered)
    658		register_console(&amiga_console_driver);
    659	return 0;
    660}
    661
    662early_param("debug", amiga_savekmsg_setup);
    663
    664static void amiga_serial_putc(char c)
    665{
    666	amiga_custom.serdat = (unsigned char)c | 0x100;
    667	while (!(amiga_custom.serdatr & 0x2000))
    668		;
    669}
    670
    671static void amiga_serial_console_write(struct console *co, const char *s,
    672				       unsigned int count)
    673{
    674	while (count--) {
    675		if (*s == '\n')
    676			amiga_serial_putc('\r');
    677		amiga_serial_putc(*s++);
    678	}
    679}
    680
    681#if 0
    682void amiga_serial_puts(const char *s)
    683{
    684	amiga_serial_console_write(NULL, s, strlen(s));
    685}
    686
    687int amiga_serial_console_wait_key(struct console *co)
    688{
    689	int ch;
    690
    691	while (!(amiga_custom.intreqr & IF_RBF))
    692		barrier();
    693	ch = amiga_custom.serdatr & 0xff;
    694	/* clear the interrupt, so that another character can be read */
    695	amiga_custom.intreq = IF_RBF;
    696	return ch;
    697}
    698
    699void amiga_serial_gets(struct console *co, char *s, int len)
    700{
    701	int ch, cnt = 0;
    702
    703	while (1) {
    704		ch = amiga_serial_console_wait_key(co);
    705
    706		/* Check for backspace. */
    707		if (ch == 8 || ch == 127) {
    708			if (cnt == 0) {
    709				amiga_serial_putc('\007');
    710				continue;
    711			}
    712			cnt--;
    713			amiga_serial_puts("\010 \010");
    714			continue;
    715		}
    716
    717		/* Check for enter. */
    718		if (ch == 10 || ch == 13)
    719			break;
    720
    721		/* See if line is too long. */
    722		if (cnt >= len + 1) {
    723			amiga_serial_putc(7);
    724			cnt--;
    725			continue;
    726		}
    727
    728		/* Store and echo character. */
    729		s[cnt++] = ch;
    730		amiga_serial_putc(ch);
    731	}
    732	/* Print enter. */
    733	amiga_serial_puts("\r\n");
    734	s[cnt] = 0;
    735}
    736#endif
    737
    738static int __init amiga_debug_setup(char *arg)
    739{
    740	bool registered;
    741
    742	if (!MACH_IS_AMIGA || strcmp(arg, "ser"))
    743		return 0;
    744
    745	/* no initialization required (?) */
    746	registered = !!amiga_console_driver.write;
    747	amiga_console_driver.write = amiga_serial_console_write;
    748	if (!registered)
    749		register_console(&amiga_console_driver);
    750	return 0;
    751}
    752
    753early_param("debug", amiga_debug_setup);
    754
    755#ifdef CONFIG_HEARTBEAT
    756static void amiga_heartbeat(int on)
    757{
    758	if (on)
    759		ciaa.pra &= ~2;
    760	else
    761		ciaa.pra |= 2;
    762}
    763#endif
    764
    765    /*
    766     *  Amiga specific parts of /proc
    767     */
    768
    769static void amiga_get_model(char *model)
    770{
    771	strcpy(model, amiga_model_name);
    772}
    773
    774
    775static void amiga_get_hardware_list(struct seq_file *m)
    776{
    777	if (AMIGAHW_PRESENT(CHIP_RAM))
    778		seq_printf(m, "Chip RAM:\t%ldK\n", amiga_chip_size>>10);
    779	seq_printf(m, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
    780			amiga_psfreq, amiga_eclock);
    781	if (AMIGAHW_PRESENT(AMI_VIDEO)) {
    782		char *type;
    783		switch (amiga_chipset) {
    784		case CS_OCS:
    785			type = "OCS";
    786			break;
    787		case CS_ECS:
    788			type = "ECS";
    789			break;
    790		case CS_AGA:
    791			type = "AGA";
    792			break;
    793		default:
    794			type = "Old or Unknown";
    795			break;
    796		}
    797		seq_printf(m, "Graphics:\t%s\n", type);
    798	}
    799
    800#define AMIGAHW_ANNOUNCE(name, str)			\
    801	if (AMIGAHW_PRESENT(name))			\
    802		seq_printf (m, "\t%s\n", str)
    803
    804	seq_puts(m, "Detected hardware:\n");
    805	AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
    806	AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
    807	AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
    808	AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
    809	AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
    810	AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
    811	AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
    812	AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
    813	AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
    814	AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
    815	AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
    816	AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
    817	AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
    818	AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
    819	AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
    820	AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
    821	AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
    822	AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
    823	AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
    824	AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
    825	AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
    826	AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
    827	AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
    828	AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
    829	AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
    830	AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
    831	AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
    832	AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
    833	AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot");
    834#ifdef CONFIG_ZORRO
    835	if (AMIGAHW_PRESENT(ZORRO))
    836		seq_printf(m, "\tZorro II%s AutoConfig: %d Expansion "
    837				"Device%s\n",
    838				AMIGAHW_PRESENT(ZORRO3) ? "I" : "",
    839				zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
    840#endif /* CONFIG_ZORRO */
    841
    842#undef AMIGAHW_ANNOUNCE
    843}
    844
    845/*
    846 * The Amiga keyboard driver needs key_maps, but we cannot export it in
    847 * drivers/char/defkeymap.c, as it is autogenerated
    848 */
    849#ifdef CONFIG_HW_CONSOLE
    850EXPORT_SYMBOL_GPL(key_maps);
    851#endif