Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0-only
vmlinux.lds
+25
View File
@@ -0,0 +1,25 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the linux kernel.
#
always-$(KBUILD_BUILTIN) += vmlinux.lds
obj-$(CONFIG_MMU_MOTOROLA) := head.o
obj-$(CONFIG_SUN3) := sun3-head.o
obj-y += entry.o irq.o module.o process.o ptrace.o
obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o
obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o
obj-$(CONFIG_MMU_SUN3) += ints.o vectors.o
obj-$(CONFIG_PCI) += pcibios.o
obj-$(CONFIG_M68K_NONCOHERENT_DMA) += dma.o
obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o
obj-$(CONFIG_UBOOT) += uboot.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+109
View File
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: GPL-2.0
/*
* This program is used to generate definitions needed by
* assembly language modules.
*
* We use the technique used in the OSF Mach kernel code:
* generate asm statements containing #defines,
* compile this file to assembler, and then extract the
* #defines from the assembly-language output.
*/
#define COMPILE_OFFSETS
#define ASM_OFFSETS_C
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/kbuild.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/amigahw.h>
#include <linux/font.h>
int main(void)
{
/* offsets into the task struct */
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
DEFINE(TASK_STACK, offsetof(struct task_struct, stack));
/* offsets into the thread struct */
DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
DEFINE(THREAD_FC, offsetof(struct thread_struct, fc));
DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
/* offsets into the thread_info struct */
DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
/* offsets into the pt_regs */
DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
/* bitfields are a bit difficult */
#ifdef CONFIG_COLDFIRE
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
#else
DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
#endif
/* offsets into the irq_cpustat_t struct */
DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
/* signal defines */
DEFINE(LSIGSEGV, SIGSEGV);
DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
DEFINE(LSIGTRAP, SIGTRAP);
DEFINE(LTRAP_TRACE, TRAP_TRACE);
#ifdef CONFIG_MMU
/* offsets into the bi_record struct */
DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
/* offsets into the font_desc struct */
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
/* offsets into the custom struct */
DEFINE(CUSTOMBASE, &amiga_custom);
DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
DEFINE(CIAABASE, &ciaa);
DEFINE(CIABBASE, &ciab);
DEFINE(C_PRA, offsetof(struct CIA, pra));
DEFINE(ZTWOBASE, zTwoBase);
/* enum m68k_fixup_type */
DEFINE(M68K_FIXUP_MEMOFFSET, m68k_fixup_memoffset);
#endif
return 0;
}
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Based on arch/arm/kernel/atags_proc.c
*/
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/printk.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
#include <asm/byteorder.h>
static char bootinfo_tmp[1536] __initdata;
static void *bootinfo_copy;
static size_t bootinfo_size;
static ssize_t bootinfo_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, bootinfo_copy,
bootinfo_size);
}
static const struct proc_ops bootinfo_proc_ops = {
.proc_read = bootinfo_read,
.proc_lseek = default_llseek,
};
void __init save_bootinfo(const struct bi_record *bi)
{
const void *start = bi;
size_t size = sizeof(bi->tag);
while (be16_to_cpu(bi->tag) != BI_LAST) {
uint16_t n = be16_to_cpu(bi->size);
size += n;
bi = (struct bi_record *)((unsigned long)bi + n);
}
if (size > sizeof(bootinfo_tmp)) {
pr_err("Cannot save %zu bytes of bootinfo\n", size);
return;
}
pr_info("Saving %zu bytes of bootinfo\n", size);
memcpy(bootinfo_tmp, start, size);
bootinfo_size = size;
}
static int __init init_bootinfo_procfs(void)
{
/*
* This cannot go into save_bootinfo() because kmalloc and proc don't
* work yet when it is called.
*/
struct proc_dir_entry *pde;
if (!bootinfo_size)
return -EINVAL;
bootinfo_copy = kmemdup(bootinfo_tmp, bootinfo_size, GFP_KERNEL);
if (!bootinfo_copy)
return -ENOMEM;
pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_proc_ops, NULL);
if (!pde) {
kfree(bootinfo_copy);
return -ENOMEM;
}
return 0;
}
arch_initcall(init_bootinfo_procfs);
+45
View File
@@ -0,0 +1,45 @@
/*
* 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.
*/
#include <linux/dma-map-ops.h>
#include <linux/kernel.h>
#include <asm/cacheflush.h>
#ifndef CONFIG_COLDFIRE
void arch_dma_prep_coherent(struct page *page, size_t size)
{
cache_push(page_to_phys(page), size);
}
pgprot_t pgprot_dmacoherent(pgprot_t prot)
{
if (CPU_IS_040_OR_060) {
pgprot_val(prot) &= ~_PAGE_CACHE040;
pgprot_val(prot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
} else {
pgprot_val(prot) |= _PAGE_NOCACHE030;
}
return prot;
}
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
void arch_sync_dma_for_device(phys_addr_t handle, size_t size,
enum dma_data_direction dir)
{
switch (dir) {
case DMA_BIDIRECTIONAL:
case DMA_TO_DEVICE:
cache_push(handle, size);
break;
case DMA_FROM_DEVICE:
cache_clear(handle, size);
break;
default:
pr_err_ratelimited("dma_sync_single_for_device: unsupported dir %u\n",
dir);
break;
}
}
@@ -0,0 +1,56 @@
/*
* 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.
*
* Copyright (c) 2014 Finn Thain
*/
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/string.h>
#include <asm/setup.h>
#include "../mvme147/mvme147.h"
#include "../mvme16x/mvme16x.h"
asmlinkage void __init debug_cons_nputs(struct console *c, const char *s, unsigned int n);
static struct console early_console_instance = {
.name = "debug",
.flags = CON_PRINTBUFFER | CON_BOOT,
.index = -1
};
static int __init setup_early_printk(char *buf)
{
if (early_console || buf)
return 0;
if (MACH_IS_MVME147)
early_console_instance.write = mvme147_scc_write;
else if (MACH_IS_MVME16x)
early_console_instance.write = mvme16x_cons_write;
else
early_console_instance.write = debug_cons_nputs;
early_console = &early_console_instance;
register_console(early_console);
return 0;
}
early_param("earlyprintk", setup_early_printk);
static int __init unregister_early_console(void)
{
/*
* debug_cons_nputs() defined in arch/m68k/kernel/head.S cannot be
* called after init sections are discarded (for platforms that use it).
*/
if (early_console && early_console->write == debug_cons_nputs)
return unregister_console(early_console);
return 0;
}
late_initcall(unregister_early_console);
+439
View File
@@ -0,0 +1,439 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* -*- mode: asm -*-
*
* linux/arch/m68k/kernel/entry.S
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Linux/m68k support by Hamish Macdonald
*
* 68060 fixes by Jesper Skov
*
*/
/*
* entry.S contains the system-call and fault low-level handling routines.
* This also contains the timer-interrupt handler, as well as all interrupts
* and faults that can result in a task-switch.
*
* NOTE: This code handles signal-recognition, which happens every time
* after a timer-interrupt and after each system call.
*
*/
/*
* 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
* all pointers that used to be 'current' are now entry
* number 0 in the 'current_set' list.
*
* 6/05/00 RZ: addedd writeback completion after return from sighandler
* for 68040
*/
#include <linux/linkage.h>
#include <asm/errno.h>
#include <asm/setup.h>
#include <asm/traps.h>
#include <asm/unistd.h>
#include <asm/asm-offsets.h>
#include <asm/entry.h>
.globl system_call, buserr, trap, resume
.globl sys_call_table
.globl __sys_fork, __sys_clone, __sys_vfork
.globl bad_interrupt
.globl auto_irqhandler_fixup
.globl user_irqvec_fixup
.text
ENTRY(__sys_fork)
SAVE_SWITCH_STACK
jbsr sys_fork
lea %sp@(24),%sp
rts
ENTRY(__sys_clone)
SAVE_SWITCH_STACK
pea %sp@(SWITCH_STACK_SIZE)
jbsr m68k_clone
lea %sp@(28),%sp
rts
ENTRY(__sys_vfork)
SAVE_SWITCH_STACK
jbsr sys_vfork
lea %sp@(24),%sp
rts
ENTRY(__sys_clone3)
SAVE_SWITCH_STACK
pea %sp@(SWITCH_STACK_SIZE)
jbsr m68k_clone3
lea %sp@(28),%sp
rts
ENTRY(sys_sigreturn)
SAVE_SWITCH_STACK
movel %sp,%a1 | switch_stack pointer
lea %sp@(SWITCH_STACK_SIZE),%a0 | pt_regs pointer
lea %sp@(-84),%sp | leave a gap
movel %a1,%sp@-
movel %a0,%sp@-
jbsr do_sigreturn
jra 1f | shared with rt_sigreturn()
ENTRY(sys_rt_sigreturn)
SAVE_SWITCH_STACK
movel %sp,%a1 | switch_stack pointer
lea %sp@(SWITCH_STACK_SIZE),%a0 | pt_regs pointer
lea %sp@(-84),%sp | leave a gap
movel %a1,%sp@-
movel %a0,%sp@-
| stack contents:
| [original pt_regs address] [original switch_stack address]
| [gap] [switch_stack] [pt_regs] [exception frame]
jbsr do_rt_sigreturn
1:
| stack contents now:
| [original pt_regs address] [original switch_stack address]
| [unused part of the gap] [moved switch_stack] [moved pt_regs]
| [replacement exception frame]
| return value of do_{rt_,}sigreturn() points to moved switch_stack.
movel %d0,%sp | discard the leftover junk
RESTORE_SWITCH_STACK
| stack contents now is just [syscall return address] [pt_regs] [frame]
| return pt_regs.d0
movel %sp@(PT_OFF_D0+4),%d0
rts
ENTRY(buserr)
SAVE_ALL_INT
GET_CURRENT(%d0)
movel %sp,%sp@- | stack frame pointer argument
jbsr buserr_c
addql #4,%sp
jra ret_from_exception
ENTRY(trap)
SAVE_ALL_INT
GET_CURRENT(%d0)
movel %sp,%sp@- | stack frame pointer argument
jbsr trap_c
addql #4,%sp
jra ret_from_exception
| After a fork we jump here directly from resume,
| so that %d1 contains the previous task
| schedule_tail now used regardless of CONFIG_SMP
ENTRY(ret_from_fork)
movel %d1,%sp@-
jsr schedule_tail
addql #4,%sp
jra ret_from_exception
ENTRY(ret_from_kernel_thread)
| a3 contains the kernel thread payload, d7 - its argument
movel %d1,%sp@-
jsr schedule_tail
movel %d7,(%sp)
jsr %a3@
addql #4,%sp
jra ret_from_exception
#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
#ifdef TRAP_DBG_INTERRUPT
.globl dbginterrupt
ENTRY(dbginterrupt)
SAVE_ALL_INT
GET_CURRENT(%d0)
movel %sp,%sp@- /* stack frame pointer argument */
jsr dbginterrupt_c
addql #4,%sp
jra ret_from_exception
#endif
ENTRY(reschedule)
/* save top of frame */
pea %sp@
jbsr set_esp0
addql #4,%sp
pea ret_from_exception
jmp schedule
ENTRY(ret_from_user_signal)
moveq #__NR_sigreturn,%d0
trap #0
ENTRY(ret_from_user_rt_signal)
movel #__NR_rt_sigreturn,%d0
trap #0
#else
do_trace_entry:
movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace_enter
RESTORE_SWITCH_STACK
addql #4,%sp
addql #1,%d0 | optimization for cmpil #-1,%d0
jeq ret_from_syscall
movel %sp@(PT_OFF_ORIG_D0),%d0
cmpl #NR_syscalls,%d0
jcs syscall
jra ret_from_syscall
badsys:
movel #-ENOSYS,%sp@(PT_OFF_D0)
jra ret_from_syscall
do_trace_exit:
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace_leave
RESTORE_SWITCH_STACK
addql #4,%sp
jra .Lret_from_exception
ENTRY(system_call)
SAVE_ALL_SYS
GET_CURRENT(%d1)
movel %d1,%a1
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
| syscall trace?
tstb %a1@(TINFO_FLAGS+2)
jmi do_trace_entry
| seccomp filter active?
btst #5,%a1@(TINFO_FLAGS+2)
bnes do_trace_entry
cmpl #NR_syscalls,%d0
jcc badsys
syscall:
jbsr @(sys_call_table,%d0:l:4)@(0)
movel %d0,%sp@(PT_OFF_D0) | save the return value
ret_from_syscall:
|oriw #0x0700,%sr
movel %curptr@(TASK_STACK),%a1
movew %a1@(TINFO_FLAGS+2),%d0
jne syscall_exit_work
1: RESTORE_ALL
syscall_exit_work:
btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
bnes 1b | if so, skip resched, signals
lslw #1,%d0
jcs do_trace_exit
jmi do_delayed_trace
lslw #8,%d0
jne do_signal_return
pea resume_userspace
jra schedule
ENTRY(ret_from_exception)
.Lret_from_exception:
btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
bnes 1f | if so, skip resched, signals
| only allow interrupts when we are really the last one on the
| kernel stack, otherwise stack overflow can occur during
| heavy interrupt load
andw #ALLOWINT,%sr
resume_userspace:
movel %curptr@(TASK_STACK),%a1
moveb %a1@(TINFO_FLAGS+3),%d0
jne exit_work
1: RESTORE_ALL
exit_work:
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
lslb #1,%d0
jne do_signal_return
pea resume_userspace
jra schedule
do_signal_return:
|andw #ALLOWINT,%sr
subql #4,%sp | dummy return address
SAVE_SWITCH_STACK
pea %sp@(SWITCH_STACK_SIZE)
bsrl do_notify_resume
addql #4,%sp
RESTORE_SWITCH_STACK
addql #4,%sp
jbra resume_userspace
do_delayed_trace:
bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
pea 1 | send SIGTRAP
movel %curptr,%sp@-
pea LSIGTRAP
jbsr send_sig
addql #8,%sp
addql #4,%sp
jbra resume_userspace
/* This is the main interrupt handler for autovector interrupts */
ENTRY(auto_inthandler)
SAVE_ALL_INT
GET_CURRENT(%d0)
| put exception # in d0
bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
subw #VEC_SPUR,%d0
movel %sp,%sp@-
movel %d0,%sp@- | put vector # on stack
auto_irqhandler_fixup = . + 2
jsr do_IRQ | process the IRQ
addql #8,%sp | pop parameters off stack
jra ret_from_exception
/* Handler for user defined interrupt vectors */
ENTRY(user_inthandler)
SAVE_ALL_INT
GET_CURRENT(%d0)
| put exception # in d0
bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
user_irqvec_fixup = . + 2
subw #VEC_USER,%d0
movel %sp,%sp@-
movel %d0,%sp@- | put vector # on stack
jsr do_IRQ | process the IRQ
addql #8,%sp | pop parameters off stack
jra ret_from_exception
/* Handler for uninitialized and spurious interrupts */
ENTRY(bad_inthandler)
SAVE_ALL_INT
GET_CURRENT(%d0)
movel %sp,%sp@-
jsr handle_badint
addql #4,%sp
jra ret_from_exception
resume:
/*
* Beware - when entering resume, prev (the current task) is
* in a0, next (the new task) is in a1,so don't change these
* registers until their contents are no longer needed.
*/
/* save sr */
movew %sr,%a0@(TASK_THREAD+THREAD_SR)
/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
movec %sfc,%d0
movew %d0,%a0@(TASK_THREAD+THREAD_FC)
/* save usp */
/* it is better to use a movel here instead of a movew 8*) */
movec %usp,%d0
movel %d0,%a0@(TASK_THREAD+THREAD_USP)
/* save non-scratch registers on stack */
SAVE_SWITCH_STACK
/* save current kernel stack pointer */
movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
/* save floating point context */
#ifndef CONFIG_M68KFPU_EMU_ONLY
#ifdef CONFIG_M68KFPU_EMU
tstl m68k_fputype
jeq 3f
#endif
fsave %a0@(TASK_THREAD+THREAD_FPSTATE)
#if defined(CONFIG_M68060)
#if !defined(CPU_M68060_ONLY)
btst #3,m68k_cputype+3
beqs 1f
#endif
/* The 060 FPU keeps status in bits 15-8 of the first longword */
tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2)
jeq 3f
#if !defined(CPU_M68060_ONLY)
jra 2f
#endif
#endif /* CONFIG_M68060 */
#if !defined(CPU_M68060_ONLY)
1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)
jeq 3f
#endif
2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)
fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)
3:
#endif /* CONFIG_M68KFPU_EMU_ONLY */
/* Return previous task in %d1 */
movel %curptr,%d1
/* switch to new task (a1 contains new task) */
movel %a1,%curptr
/* restore floating point context */
#ifndef CONFIG_M68KFPU_EMU_ONLY
#ifdef CONFIG_M68KFPU_EMU
tstl m68k_fputype
jeq 4f
#endif
#if defined(CONFIG_M68060)
#if !defined(CPU_M68060_ONLY)
btst #3,m68k_cputype+3
beqs 1f
#endif
/* The 060 FPU keeps status in bits 15-8 of the first longword */
tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2)
jeq 3f
#if !defined(CPU_M68060_ONLY)
jra 2f
#endif
#endif /* CONFIG_M68060 */
#if !defined(CPU_M68060_ONLY)
1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)
jeq 3f
#endif
2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7
fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar
3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)
4:
#endif /* CONFIG_M68KFPU_EMU_ONLY */
/* restore the kernel stack pointer */
movel %a1@(TASK_THREAD+THREAD_KSP),%sp
/* restore non-scratch registers */
RESTORE_SWITCH_STACK
/* restore user stack pointer */
movel %a1@(TASK_THREAD+THREAD_USP),%a0
movel %a0,%usp
/* restore fs (sfc,%dfc) */
movew %a1@(TASK_THREAD+THREAD_FC),%a0
movec %a0,%sfc
movec %a0,%dfc
/* restore status register */
movew %a1@(TASK_THREAD+THREAD_SR),%d0
oriw #0x0700,%d0
movew %d0,%sr
rts
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
File diff suppressed because it is too large Load Diff
+171
View File
@@ -0,0 +1,171 @@
/*
* linux/arch/m68k/kernel/ints.c -- Linux/m68k general interrupt handling code
*
* 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.
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/machdep.h>
#include <asm/cacheflush.h>
#include <asm/irq_regs.h>
#ifdef CONFIG_Q40
#include <asm/q40ints.h>
#endif
#include "ints.h"
extern u32 auto_irqhandler_fixup[];
extern u16 user_irqvec_fixup[];
static int m68k_first_user_vec;
static struct irq_chip auto_irq_chip = {
.name = "auto",
.irq_startup = m68k_irq_startup,
.irq_shutdown = m68k_irq_shutdown,
};
static struct irq_chip user_irq_chip = {
.name = "user",
.irq_startup = m68k_irq_startup,
.irq_shutdown = m68k_irq_shutdown,
};
/*
* void init_IRQ(void)
*
* Parameters: None
*
* Returns: Nothing
*
* This function should be called during kernel startup to initialize
* the IRQ handling routines.
*/
void __init init_IRQ(void)
{
int i;
for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
mach_init_IRQ();
}
/**
* m68k_setup_auto_interrupt
* @handler: called from auto vector interrupts
*
* setup the handler to be called from auto vector interrupts instead of the
* standard do_IRQ(), it will be called with irq numbers in the range
* from IRQ_AUTO_1 - IRQ_AUTO_7.
*/
void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *))
{
if (handler)
*auto_irqhandler_fixup = (u32)handler;
flush_icache();
}
/**
* m68k_setup_user_interrupt
* @vec: first user vector interrupt to handle
* @cnt: number of active user vector interrupts
*
* setup user vector interrupts, this includes activating the specified range
* of interrupts, only then these interrupts can be requested (note: this is
* different from auto vector interrupts).
*/
void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt)
{
int i;
BUG_ON(IRQ_USER + cnt > NR_IRQS);
m68k_first_user_vec = vec;
for (i = 0; i < cnt; i++)
irq_set_chip_and_handler(i, &user_irq_chip, handle_simple_irq);
*user_irqvec_fixup = vec - IRQ_USER;
flush_icache();
}
/**
* m68k_setup_irq_controller
* @chip: irq chip which controls specified irq
* @handle: flow handler which handles specified irq
* @irq: first irq to be managed by the controller
* @cnt: number of irqs to be managed by the controller
*
* Change the controller for the specified range of irq, which will be used to
* manage these irq. auto/user irq already have a default controller, which can
* be changed as well, but the controller probably should use m68k_irq_startup/
* m68k_irq_shutdown.
*/
void m68k_setup_irq_controller(struct irq_chip *chip,
irq_flow_handler_t handle, unsigned int irq,
unsigned int cnt)
{
int i;
for (i = 0; i < cnt; i++) {
irq_set_chip(irq + i, chip);
if (handle)
irq_set_handler(irq + i, handle);
}
}
unsigned int m68k_irq_startup_irq(unsigned int irq)
{
if (irq <= IRQ_AUTO_7)
vectors[VEC_SPUR + irq] = auto_inthandler;
else
vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler;
return 0;
}
unsigned int m68k_irq_startup(struct irq_data *data)
{
return m68k_irq_startup_irq(data->irq);
}
void m68k_irq_shutdown(struct irq_data *data)
{
unsigned int irq = data->irq;
if (irq <= IRQ_AUTO_7)
vectors[VEC_SPUR + irq] = bad_inthandler;
else
vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler;
}
unsigned int irq_canonicalize(unsigned int irq)
{
#ifdef CONFIG_Q40
if (MACH_IS_Q40 && irq == 11)
irq = 10;
#endif
return irq;
}
EXPORT_SYMBOL(irq_canonicalize);
asmlinkage void handle_badint(struct pt_regs *regs)
{
atomic_inc(&irq_err_count);
pr_warn("unexpected interrupt from %u\n", regs->vector);
}
+7
View File
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
struct pt_regs;
asmlinkage void handle_badint(struct pt_regs *regs);
+39
View File
@@ -0,0 +1,39 @@
/*
* irq.c
*
* (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
*
* 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.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <asm/traps.h>
asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
{
struct pt_regs *oldregs = set_irq_regs(regs);
irq_enter();
generic_handle_irq(irq);
irq_exit();
set_irq_regs(oldregs);
}
/* The number of spurious interrupts */
atomic_t irq_err_count;
int arch_show_interrupts(struct seq_file *p, int prec)
{
seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
return 0;
}
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: GPL-2.0
/*
* machine_kexec.c - handle transition of Linux booting another kernel
*/
#include <linux/compiler.h>
#include <linux/kexec.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <asm/cacheflush.h>
#include <asm/page.h>
#include <asm/setup.h>
extern const unsigned char relocate_new_kernel[];
extern const size_t relocate_new_kernel_size;
int machine_kexec_prepare(struct kimage *kimage)
{
return 0;
}
void machine_kexec_cleanup(struct kimage *kimage)
{
}
void machine_shutdown(void)
{
}
void machine_crash_shutdown(struct pt_regs *regs)
{
}
typedef void (*relocate_kernel_t)(unsigned long ptr,
unsigned long start,
unsigned long cpu_mmu_flags) __noreturn;
void machine_kexec(struct kimage *image)
{
void *reboot_code_buffer;
unsigned long cpu_mmu_flags;
reboot_code_buffer = page_address(image->control_code_page);
memcpy(reboot_code_buffer, relocate_new_kernel,
relocate_new_kernel_size);
/*
* we do not want to be bothered.
*/
local_irq_disable();
pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
__flush_cache_all();
cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
image->start,
cpu_mmu_flags);
}
+129
View File
@@ -0,0 +1,129 @@
/*
* 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.
*/
#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#if 0
#define DEBUGP(fmt, ...) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#else
#define DEBUGP(fmt, ...) no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif
#ifdef CONFIG_MODULES
int apply_relocate(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location += sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its position */
*location += sym->st_value - (uint32_t)location;
break;
default:
pr_err("module %s: Unknown relocation: %u\n", me->name,
ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int apply_relocate_add(Elf32_Shdr *sechdrs,
const char *strtab,
unsigned int symindex,
unsigned int relsec,
struct module *me)
{
unsigned int i;
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location;
DEBUGP("Applying relocate_add section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) {
case R_68K_32:
/* We add the value into the location given */
*location = rel[i].r_addend + sym->st_value;
break;
case R_68K_PC32:
/* Add the value, subtract its position */
*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
break;
default:
pr_err("module %s: Unknown relocation: %u\n", me->name,
ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
}
return 0;
}
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *mod)
{
module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end);
return 0;
}
#endif /* CONFIG_MODULES */
void module_fixup(struct module *mod, struct m68k_fixup_info *start,
struct m68k_fixup_info *end)
{
#ifdef CONFIG_MMU
struct m68k_fixup_info *fixup;
for (fixup = start; fixup < end; fixup++) {
switch (fixup->type) {
case m68k_fixup_memoffset:
*(u32 *)fixup->addr = m68k_memoffset;
break;
case m68k_fixup_vnode_shift:
*(u16 *)fixup->addr += m68k_virt_to_node_shift;
break;
}
}
#endif
}
+81
View File
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* pci.c -- basic PCI support code
*
* (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/pci.h>
/*
* From arch/i386/kernel/pci-i386.c:
*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
* addresses to be allocated in the 0x000-0x0ff region
* modulo 0x400.
*
* Why? Because some silly external IO cards only decode
* the low 10 bits of the IO address. The 0x00-0xff region
* is reserved for motherboard devices that decode all 16
* bits, so it's ok to allocate at, say, 0x2800-0x28ff,
* but we want to try to avoid allocating at 0x2900-0x2bff
* which might be mirrored at 0x0100-0x03ff..
*/
resource_size_t pcibios_align_resource(void *data, const struct resource *res,
const struct resource *empty_res,
resource_size_t size,
resource_size_t align)
{
struct pci_dev *dev = data;
resource_size_t start = res->start;
if ((res->flags & IORESOURCE_IO) && (start & 0x300))
start = (start + 0x3ff) & ~0x3ff;
if (res->flags & IORESOURCE_MEM)
return pci_align_resource(dev, res, empty_res, size, align);
return start;
}
/*
* This is taken from the ARM code for this.
*/
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
u16 cmd, newcmd;
int ret;
ret = pci_enable_resources(dev, mask);
if (ret < 0)
return ret;
/*
* Bridges (eg, cardbus bridges) need to be fully enabled
*/
if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
newcmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
if (newcmd != cmd) {
pr_info("PCI: enabling bridge %s (0x%04x -> 0x%04x)\n",
pci_name(dev), cmd, newcmd);
pci_write_config_word(dev, PCI_COMMAND, newcmd);
}
}
return 0;
}
void pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
}
}
+286
View File
@@ -0,0 +1,286 @@
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/m68k/kernel/process.c
*
* Copyright (C) 1995 Hamish Macdonald
*
* 68060 fixes by Jesper Skov
*/
/*
* This file handles the architecture-dependent parts of process handling..
*/
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <linux/rcupdate.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/elfcore.h>
#include <asm/traps.h>
#include <asm/machdep.h>
#include <asm/setup.h>
#include "process.h"
asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);
void arch_cpu_idle(void)
{
#if defined(MACH_ATARI_ONLY)
/* block out HSYNC on the atari (falcon) */
__asm__("stop #0x2200" : : : "cc");
#else
__asm__("stop #0x2000" : : : "cc");
#endif
}
void machine_restart(char * __unused)
{
if (mach_reset)
mach_reset();
for (;;);
}
void machine_halt(void)
{
if (mach_halt)
mach_halt();
for (;;);
}
void machine_power_off(void)
{
do_kernel_power_off();
for (;;);
}
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
void show_regs(struct pt_regs * regs)
{
pr_info("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
regs->format, regs->vector, regs->pc, regs->sr,
print_tainted());
pr_info("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
regs->orig_d0, regs->d0, regs->a2, regs->a1);
pr_info("A0: %08lx D5: %08lx D4: %08lx\n", regs->a0, regs->d5,
regs->d4);
pr_info("D3: %08lx D2: %08lx D1: %08lx\n", regs->d3, regs->d2,
regs->d1);
if (!(regs->sr & PS_S))
pr_info("USP: %08lx\n", rdusp());
}
void flush_thread(void)
{
current->thread.fc = USER_DATA;
#ifdef CONFIG_FPU
if (!FPU_IS_EMU) {
unsigned long zero = 0;
asm volatile("frestore %0": :"m" (zero));
}
#endif
}
/*
* Why not generic sys_clone, you ask? m68k passes all arguments on stack.
* And we need all registers saved, which means a bunch of stuff pushed
* on top of pt_regs, which means that sys_clone() arguments would be
* buried. We could, of course, copy them, but it's too costly for no
* good reason - generic clone() would have to copy them *again* for
* kernel_clone() anyway. So in this case it's actually better to pass pt_regs *
* and extract arguments for kernel_clone() from there. Eventually we might
* go for calling kernel_clone() directly from the wrapper, but only after we
* are finished with kernel_clone() prototype conversion.
*/
asmlinkage int m68k_clone(struct pt_regs *regs)
{
/* regs will be equal to current_pt_regs() */
struct kernel_clone_args args = {
.flags = (u32)(regs->d1) & ~CSIGNAL,
.pidfd = (int __user *)regs->d3,
.child_tid = (int __user *)regs->d4,
.parent_tid = (int __user *)regs->d3,
.exit_signal = regs->d1 & CSIGNAL,
.stack = regs->d2,
.tls = regs->d5,
};
return kernel_clone(&args);
}
/*
* Because extra registers are saved on the stack after the sys_clone3()
* arguments, this C wrapper extracts them from pt_regs * and then calls the
* generic sys_clone3() implementation.
*/
asmlinkage int m68k_clone3(struct pt_regs *regs)
{
return sys_clone3((struct clone_args __user *)regs->d1, regs->d2);
}
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
u64 clone_flags = args->flags;
unsigned long usp = args->stack;
unsigned long tls = args->tls;
struct fork_frame {
struct switch_stack sw;
struct pt_regs regs;
} *frame;
frame = (struct fork_frame *) (task_stack_page(p) + THREAD_SIZE) - 1;
p->thread.ksp = (unsigned long)frame;
p->thread.esp0 = (unsigned long)&frame->regs;
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
*/
p->thread.fc = USER_DATA;
if (unlikely(args->fn)) {
/* kernel thread */
memset(frame, 0, sizeof(struct fork_frame));
frame->regs.sr = PS_S;
frame->sw.a3 = (unsigned long)args->fn;
frame->sw.d7 = (unsigned long)args->fn_arg;
frame->sw.retpc = (unsigned long)ret_from_kernel_thread;
p->thread.usp = 0;
return 0;
}
memcpy(frame, container_of(current_pt_regs(), struct fork_frame, regs),
sizeof(struct fork_frame));
frame->regs.d0 = 0;
frame->sw.retpc = (unsigned long)ret_from_fork;
p->thread.usp = usp ?: rdusp();
if (clone_flags & CLONE_SETTLS)
task_thread_info(p)->tp_value = tls;
#ifdef CONFIG_FPU
if (!FPU_IS_EMU) {
/* Copy the current fpu state */
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
if (CPU_IS_COLDFIRE) {
asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
"fmovel %/fpiar,%1\n\t"
"fmovel %/fpcr,%2\n\t"
"fmovel %/fpsr,%3"
:
: "m" (p->thread.fp[0]),
"m" (p->thread.fpcntl[0]),
"m" (p->thread.fpcntl[1]),
"m" (p->thread.fpcntl[2])
: "memory");
} else {
asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
"fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
:
: "m" (p->thread.fp[0]),
"m" (p->thread.fpcntl[0])
: "memory");
}
}
/* Restore the state in case the fpu was busy */
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
}
#endif /* CONFIG_FPU */
return 0;
}
/* Fill in the fpu structure for a core dump. */
int elf_core_copy_task_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
{
if (FPU_IS_EMU) {
int i;
memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
memcpy(fpu->fpregs, current->thread.fp, 96);
/* Convert internal fpu reg representation
* into long double format
*/
for (i = 0; i < 24; i += 3)
fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
((fpu->fpregs[i] & 0x0000ffff) << 16);
return 1;
}
if (IS_ENABLED(CONFIG_FPU)) {
char fpustate[216];
/* First dump the fpu context to avoid protocol violation. */
asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
return 0;
if (CPU_IS_COLDFIRE) {
asm volatile ("fmovel %/fpiar,%0\n\t"
"fmovel %/fpcr,%1\n\t"
"fmovel %/fpsr,%2\n\t"
"fmovemd %/fp0-%/fp7,%3"
:
: "m" (fpu->fpcntl[0]),
"m" (fpu->fpcntl[1]),
"m" (fpu->fpcntl[2]),
"m" (fpu->fpregs[0])
: "memory");
} else {
asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
:
: "m" (fpu->fpcntl[0])
: "memory");
asm volatile ("fmovemx %/fp0-%/fp7,%0"
:
: "m" (fpu->fpregs[0])
: "memory");
}
}
return 1;
}
unsigned long __get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
stack_page = (unsigned long)task_stack_page(p);
fp = ((struct switch_stack *)p->thread.ksp)->a6;
do {
if (fp < stack_page+sizeof(struct thread_info) ||
fp >= 8184+stack_page)
return 0;
pc = ((unsigned long *)fp)[1];
if (!in_sched_functions(pc))
return pc;
fp = *(unsigned long *) fp;
} while (count++ < 16);
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
struct pt_regs;
asmlinkage int m68k_clone(struct pt_regs *regs);
asmlinkage int m68k_clone3(struct pt_regs *regs);
+350
View File
@@ -0,0 +1,350 @@
/*
* linux/arch/m68k/kernel/ptrace.c
*
* Copyright (C) 1994 by Hamish Macdonald
* Taken from linux/kernel/ptrace.c and modified for M680x0.
* linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
#include <linux/regset.h>
#include <linux/elf.h>
#include <linux/seccomp.h>
#include <linux/uaccess.h>
#include <asm/page.h>
#include <asm/processor.h>
#include "ptrace.h"
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
*/
/* determines which bits in the SR the user has access to. */
/* 1 = access 0 = no access */
#define SR_MASK 0x001f
/* sets the trace bits. */
#define TRACE_BITS 0xC000
#define T1_BIT 0x8000
#define T0_BIT 0x4000
/* Find the stack offset for a register, relative to thread.esp0. */
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- sizeof(struct switch_stack))
/* Mapping from PT_xxx to the stack offset at which the register is
saved. Notice that usp has no stack-slot and needs to be treated
specially (see get_reg/put_reg below). */
static const int regoff[] = {
[0] = PT_REG(d1),
[1] = PT_REG(d2),
[2] = PT_REG(d3),
[3] = PT_REG(d4),
[4] = PT_REG(d5),
[5] = SW_REG(d6),
[6] = SW_REG(d7),
[7] = PT_REG(a0),
[8] = PT_REG(a1),
[9] = PT_REG(a2),
[10] = SW_REG(a3),
[11] = SW_REG(a4),
[12] = SW_REG(a5),
[13] = SW_REG(a6),
[14] = PT_REG(d0),
[15] = -1,
[16] = PT_REG(orig_d0),
[17] = PT_REG(sr),
[18] = PT_REG(pc),
};
/*
* Get contents of register REGNO in task TASK.
*/
static inline long get_reg(struct task_struct *task, int regno)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < ARRAY_SIZE(regoff))
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return 0;
/* Need to take stkadj into account. */
if (regno == PT_SR || regno == PT_PC) {
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
addr = (unsigned long *) ((unsigned long)addr + stkadj);
/* The sr is actually a 16 bit register. */
if (regno == PT_SR)
return *(unsigned short *)addr;
}
return *addr;
}
/*
* Write contents of register REGNO in task TASK.
*/
static inline int put_reg(struct task_struct *task, int regno,
unsigned long data)
{
unsigned long *addr;
if (regno == PT_USP)
addr = &task->thread.usp;
else if (regno < ARRAY_SIZE(regoff))
addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
else
return -1;
/* Need to take stkadj into account. */
if (regno == PT_SR || regno == PT_PC) {
long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
addr = (unsigned long *) ((unsigned long)addr + stkadj);
/* The sr is actually a 16 bit register. */
if (regno == PT_SR) {
*(unsigned short *)addr = data;
return 0;
}
}
*addr = data;
return 0;
}
/*
* Make sure the single step bit is not set.
*/
static inline void singlestep_disable(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp);
clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
}
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
singlestep_disable(child);
}
void user_enable_single_step(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp | T1_BIT);
set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
}
#ifdef CONFIG_MMU
void user_enable_block_step(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
put_reg(child, PT_SR, tmp | T0_BIT);
}
#endif
void user_disable_single_step(struct task_struct *child)
{
singlestep_disable(child);
}
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
unsigned long tmp;
int i, ret = 0;
int regno = addr >> 2; /* temporary hack. */
unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR:
if (addr & 3)
goto out_eio;
if (regno >= 0 && regno < 19) {
tmp = get_reg(child, regno);
} else if (regno >= 21 && regno < 49) {
tmp = child->thread.fp[regno - 21];
/* Convert internal fpu reg representation
* into long double format
*/
if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
tmp = ((tmp & 0xffff0000) << 15) |
((tmp & 0x0000ffff) << 16);
#ifndef CONFIG_MMU
} else if (regno == 49) {
tmp = child->mm->start_code;
} else if (regno == 50) {
tmp = child->mm->start_data;
} else if (regno == 51) {
tmp = child->mm->end_code;
#endif
} else
goto out_eio;
ret = put_user(tmp, datap);
break;
case PTRACE_POKEUSR:
/* write the word at location addr in the USER area */
if (addr & 3)
goto out_eio;
if (regno == PT_SR) {
data &= SR_MASK;
data |= get_reg(child, PT_SR) & ~SR_MASK;
}
if (regno >= 0 && regno < 19) {
if (put_reg(child, regno, data))
goto out_eio;
} else if (regno >= 21 && regno < 48) {
/* Convert long double format
* into internal fpu reg representation
*/
if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
data <<= 15;
data = (data & 0xffff0000) |
((data & 0x0000ffff) >> 1);
}
child->thread.fp[regno - 21] = data;
} else
goto out_eio;
break;
case PTRACE_GETREGS: /* Get all gp regs from the child. */
for (i = 0; i < 19; i++) {
tmp = get_reg(child, i);
ret = put_user(tmp, datap);
if (ret)
break;
datap++;
}
break;
case PTRACE_SETREGS: /* Set all gp regs in the child. */
for (i = 0; i < 19; i++) {
ret = get_user(tmp, datap);
if (ret)
break;
if (i == PT_SR) {
tmp &= SR_MASK;
tmp |= get_reg(child, PT_SR) & ~SR_MASK;
}
put_reg(child, i, tmp);
datap++;
}
break;
case PTRACE_GETFPREGS: /* Get the child FPU state. */
if (copy_to_user(datap, &child->thread.fp,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_SETFPREGS: /* Set the child FPU state. */
if (copy_from_user(&child->thread.fp, datap,
sizeof(struct user_m68kfp_struct)))
ret = -EFAULT;
break;
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->tp_value, datap);
break;
default:
ret = ptrace_request(child, request, addr, data);
break;
}
return ret;
out_eio:
return -EIO;
}
asmlinkage int syscall_trace_enter(void)
{
int ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = ptrace_report_syscall_entry(task_pt_regs(current));
if (secure_computing() == -1)
return -1;
return ret;
}
asmlinkage void syscall_trace_leave(void)
{
if (test_thread_flag(TIF_SYSCALL_TRACE))
ptrace_report_syscall_exit(task_pt_regs(current), 0);
}
#if defined(CONFIG_BINFMT_ELF_FDPIC) && defined(CONFIG_ELF_CORE)
/*
* Currently the only thing that needs to use regsets for m68k is the
* coredump support of the elf_fdpic loader. Implement the minimum
* definitions required for that.
*/
static int m68k_regset_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
struct pt_regs *ptregs = task_pt_regs(target);
u32 uregs[ELF_NGREG];
ELF_CORE_COPY_REGS(uregs, ptregs);
return membuf_write(&to, uregs, sizeof(uregs));
}
enum m68k_regset {
REGSET_GPR,
#ifdef CONFIG_FPU
REGSET_FPU,
#endif
};
static const struct user_regset m68k_user_regsets[] = {
[REGSET_GPR] = {
USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = ELF_NGREG,
.size = sizeof(u32),
.align = sizeof(u16),
.regset_get = m68k_regset_get,
},
#ifdef CONFIG_FPU
[REGSET_FPU] = {
USER_REGSET_NOTE_TYPE(PRFPREG),
.n = sizeof(struct user_m68kfp_struct) / sizeof(u32),
.size = sizeof(u32),
.align = sizeof(u32),
}
#endif /* CONFIG_FPU */
};
static const struct user_regset_view user_m68k_view = {
.name = "m68k",
.e_machine = EM_68K,
.ei_osabi = ELF_OSABI,
.regsets = m68k_user_regsets,
.n = ARRAY_SIZE(m68k_user_regsets)
};
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
return &user_m68k_view;
}
#endif /* CONFIG_BINFMT_ELF_FDPIC && CONFIG_ELF_CORE */
+6
View File
@@ -0,0 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
asmlinkage int syscall_trace_enter(void);
asmlinkage void syscall_trace_leave(void);
@@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/setup.h>
#define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */
.text
ENTRY(relocate_new_kernel)
movel %sp@(4),%a0 /* a0 = ptr */
movel %sp@(8),%a1 /* a1 = start */
movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */
movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */
/* Disable MMU */
btst #MMU_BASE + MMUB_68851,%d1
jeq 3f
1: /* 68851 or 68030 */
lea %pc@(.Lcopy),%a4
2: addl #0x00000000,%a4 /* virt_to_phys() */
.section .m68k_fixup,"aw"
.long M68K_FIXUP_MEMOFFSET, 2b+2
.previous
.chip 68030
pmove %tc,%d0 /* Disable MMU */
bclr #7,%d0
pmove %d0,%tc
jmp %a4@ /* Jump to physical .Lcopy */
.chip 68k
3:
btst #MMU_BASE + MMUB_68030,%d1
jne 1b
btst #MMU_BASE + MMUB_68040,%d1
jeq 6f
4: /* 68040 or 68060 */
lea %pc@(.Lcont040),%a4
5: addl #0x00000000,%a4 /* virt_to_phys() */
.section .m68k_fixup,"aw"
.long M68K_FIXUP_MEMOFFSET, 5b+2
.previous
movel %a4,%d0
andl #0xff000000,%d0
orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */
.chip 68040
movec %d0,%itt0
movec %d0,%dtt0
.chip 68k
jmp %a4@ /* Jump to physical .Lcont040 */
.Lcont040:
moveq #0,%d0
.chip 68040
movec %d0,%tc /* Disable MMU */
movec %d0,%itt0
movec %d0,%itt1
movec %d0,%dtt0
movec %d0,%dtt1
.chip 68k
jra .Lcopy
6:
btst #MMU_BASE + MMUB_68060,%d1
jne 4b
.Lcopy:
movel %a0@+,%d0 /* d0 = entry = *ptr */
jeq .Lflush
btst #2,%d0 /* entry & IND_DONE? */
jne .Lflush
btst #1,%d0 /* entry & IND_INDIRECTION? */
jeq 1f
andw %d2,%d0
movel %d0,%a0 /* ptr = entry & PAGE_MASK */
jra .Lcopy
1:
btst #0,%d0 /* entry & IND_DESTINATION? */
jeq 2f
andw %d2,%d0
movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */
jra .Lcopy
2:
btst #3,%d0 /* entry & IND_SOURCE? */
jeq .Lcopy
andw %d2,%d0
movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */
movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */
3:
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
movel %a3@+,%a2@+ /* *dst++ = *src++ */
dbf %d0, 3b
jra .Lcopy
.Lflush:
/* Flush all caches */
btst #CPUB_68020,%d1
jeq 2f
1: /* 68020 or 68030 */
.chip 68030
movec %cacr,%d0
orw #0x808,%d0
movec %d0,%cacr
.chip 68k
jra .Lreincarnate
2:
btst #CPUB_68030,%d1
jne 1b
btst #CPUB_68040,%d1
jeq 4f
3: /* 68040 or 68060 */
.chip 68040
nop
cpusha %bc
nop
cinva %bc
nop
.chip 68k
jra .Lreincarnate
4:
btst #CPUB_68060,%d1
jne 3b
.Lreincarnate:
jmp %a1@
relocate_new_kernel_end:
ENTRY(relocate_new_kernel_size)
.long relocate_new_kernel_end - relocate_new_kernel
+11
View File
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
#ifdef CONFIG_MMU
#include "setup_mm.c"
#else
#include "setup_no.c"
#endif
#if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
void (*mach_beep)(unsigned int, unsigned int);
EXPORT_SYMBOL(mach_beep);
#endif
+607
View File
@@ -0,0 +1,607 @@
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/m68k/kernel/setup.c
*
* Copyright (C) 1995 Hamish Macdonald
*/
/*
* This file handles the architecture-dependent parts of system setup
*/
#include <linux/kernel.h>
#include <linux/cpu.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/module.h>
#include <linux/nvram.h>
#include <linux/initrd.h>
#include <linux/random.h>
#include <asm/bootinfo.h>
#include <asm/byteorder.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/machdep.h>
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
#endif
#include <asm/atarihw.h>
#ifdef CONFIG_ATARI
#include <asm/atari_stram.h>
#endif
#ifdef CONFIG_SUN3X
#include <asm/dvma.h>
#endif
#include <asm/macintosh.h>
#include <asm/natfeat.h>
#include <asm/config.h>
#if !FPSTATESIZE || !NR_IRQS
#warning No CPU/platform type selected, your kernel will not work!
#warning Are you building an allnoconfig kernel?
#endif
unsigned long m68k_machtype;
EXPORT_SYMBOL(m68k_machtype);
unsigned long m68k_cputype;
EXPORT_SYMBOL(m68k_cputype);
unsigned long m68k_fputype;
unsigned long m68k_mmutype;
EXPORT_SYMBOL(m68k_mmutype);
#ifdef CONFIG_VME
unsigned long vme_brdtype;
EXPORT_SYMBOL(vme_brdtype);
#endif
int m68k_is040or060;
EXPORT_SYMBOL(m68k_is040or060);
extern unsigned long availmem;
int m68k_num_memory;
EXPORT_SYMBOL(m68k_num_memory);
int m68k_realnum_memory;
EXPORT_SYMBOL(m68k_realnum_memory);
unsigned long m68k_memoffset;
struct m68k_mem_info m68k_memory[NUM_MEMINFO];
EXPORT_SYMBOL(m68k_memory);
static struct m68k_mem_info m68k_ramdisk __initdata;
static char m68k_command_line[CL_SIZE] __initdata;
void (*mach_sched_init) (void) __initdata = NULL;
/* machine dependent irq functions */
void (*mach_init_IRQ) (void) __initdata = NULL;
void (*mach_get_model) (char *model);
void (*mach_get_hardware_list) (struct seq_file *m);
void (*mach_reset)( void );
void (*mach_halt)( void );
#ifdef CONFIG_HEARTBEAT
void (*mach_heartbeat) (int);
EXPORT_SYMBOL(mach_heartbeat);
#endif
#ifdef CONFIG_M68K_L2_CACHE
void (*mach_l2_flush) (int);
#endif
#if defined(CONFIG_ISA) && defined(MULTI_ISA)
int isa_type;
int isa_sex;
EXPORT_SYMBOL(isa_type);
EXPORT_SYMBOL(isa_sex);
#endif
#define MASK_256K 0xfffc0000
static void __init m68k_parse_bootinfo(const struct bi_record *record)
{
const struct bi_record *first_record = record;
uint16_t tag;
while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
int unknown = 0;
const void *data = record->data;
uint16_t size = be16_to_cpu(record->size);
switch (tag) {
case BI_MACHTYPE:
case BI_CPUTYPE:
case BI_FPUTYPE:
case BI_MMUTYPE:
/* Already set up by head.S */
break;
case BI_MEMCHUNK:
if (m68k_num_memory < NUM_MEMINFO) {
const struct mem_info *m = data;
m68k_memory[m68k_num_memory].addr =
be32_to_cpu(m->addr);
m68k_memory[m68k_num_memory].size =
be32_to_cpu(m->size);
m68k_num_memory++;
} else
pr_warn("%s: too many memory chunks\n",
__func__);
break;
case BI_RAMDISK:
{
const struct mem_info *m = data;
m68k_ramdisk.addr = be32_to_cpu(m->addr);
m68k_ramdisk.size = be32_to_cpu(m->size);
}
break;
case BI_COMMAND_LINE:
strscpy(m68k_command_line, data);
break;
case BI_RNG_SEED: {
u16 len = be16_to_cpup(data);
add_bootloader_randomness(data + 2, len);
/*
* Zero the data to preserve forward secrecy, and zero the
* length to prevent kexec from using it.
*/
memzero_explicit((void *)data, len + 2);
break;
}
default:
if (MACH_IS_AMIGA)
unknown = amiga_parse_bootinfo(record);
else if (MACH_IS_ATARI)
unknown = atari_parse_bootinfo(record);
else if (MACH_IS_MAC)
unknown = mac_parse_bootinfo(record);
else if (MACH_IS_Q40)
unknown = q40_parse_bootinfo(record);
else if (MACH_IS_BVME6000)
unknown = bvme6000_parse_bootinfo(record);
else if (MACH_IS_MVME16x)
unknown = mvme16x_parse_bootinfo(record);
else if (MACH_IS_MVME147)
unknown = mvme147_parse_bootinfo(record);
else if (MACH_IS_HP300)
unknown = hp300_parse_bootinfo(record);
else if (MACH_IS_APOLLO)
unknown = apollo_parse_bootinfo(record);
else if (MACH_IS_VIRT)
unknown = virt_parse_bootinfo(record);
else
unknown = 1;
}
if (unknown)
pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
tag);
record = (struct bi_record *)((unsigned long)record + size);
}
save_bootinfo(first_record);
m68k_realnum_memory = m68k_num_memory;
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
if (m68k_num_memory > 1) {
pr_warn("%s: ignoring last %i chunks of physical memory\n",
__func__, (m68k_num_memory - 1));
m68k_num_memory = 1;
}
#endif
}
void __init setup_arch(char **cmdline_p)
{
/* The bootinfo is located right after the kernel */
if (!CPU_IS_COLDFIRE)
m68k_parse_bootinfo((const struct bi_record *)_end);
if (CPU_IS_040)
m68k_is040or060 = 4;
else if (CPU_IS_060)
m68k_is040or060 = 6;
/* FIXME: m68k_fputype is passed in by Penguin booter, which can
* be confused by software FPU emulation. BEWARE.
* We should really do our own FPU check at startup.
* [what do we do with buggy 68LC040s? if we have problems
* with them, we should add a test to check_bugs() below] */
#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY)
/* clear the fpu if we have one */
if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
volatile int zero = 0;
asm volatile ("frestore %0" : : "m" (zero));
}
#endif
if (CPU_IS_060) {
u32 pcr;
asm (".chip 68060; movec %%pcr,%0; .chip 68k"
: "=d" (pcr));
if (((pcr >> 8) & 0xff) <= 5) {
pr_warn("Enabling workaround for errata I14\n");
asm (".chip 68060; movec %0,%%pcr; .chip 68k"
: : "d" (pcr | 0x20));
}
}
setup_initial_init_mm((void *)PAGE_OFFSET, _etext, _edata, _end);
#if defined(CONFIG_BOOTPARAM)
strscpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
#endif /* CONFIG_BOOTPARAM */
process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
*cmdline_p = m68k_command_line;
memcpy(boot_command_line, *cmdline_p, CL_SIZE);
/*
* Initialise the static keys early as they may be enabled by the
* cpufeature code and early parameters.
*/
jump_label_init();
parse_early_param();
switch (m68k_machtype) {
#ifdef CONFIG_AMIGA
case MACH_AMIGA:
config_amiga();
break;
#endif
#ifdef CONFIG_ATARI
case MACH_ATARI:
config_atari();
break;
#endif
#ifdef CONFIG_MAC
case MACH_MAC:
config_mac();
break;
#endif
#ifdef CONFIG_SUN3
case MACH_SUN3:
config_sun3();
break;
#endif
#ifdef CONFIG_APOLLO
case MACH_APOLLO:
config_apollo();
break;
#endif
#ifdef CONFIG_MVME147
case MACH_MVME147:
config_mvme147();
break;
#endif
#ifdef CONFIG_MVME16x
case MACH_MVME16x:
config_mvme16x();
break;
#endif
#ifdef CONFIG_BVME6000
case MACH_BVME6000:
config_bvme6000();
break;
#endif
#ifdef CONFIG_HP300
case MACH_HP300:
config_hp300();
break;
#endif
#ifdef CONFIG_Q40
case MACH_Q40:
config_q40();
break;
#endif
#ifdef CONFIG_SUN3X
case MACH_SUN3X:
config_sun3x();
break;
#endif
#ifdef CONFIG_COLDFIRE
case MACH_M54XX:
case MACH_M5441X:
cf_bootmem_alloc();
cf_mmu_context_init();
config_BSP(NULL, 0);
break;
#endif
#ifdef CONFIG_VIRT
case MACH_VIRT:
config_virt();
break;
#endif
default:
panic("No configuration setup");
}
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size)
memblock_reserve(m68k_ramdisk.addr, m68k_ramdisk.size);
paging_init();
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size) {
initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
initrd_end = initrd_start + m68k_ramdisk.size;
pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
}
#ifdef CONFIG_NATFEAT
nf_init();
#endif
#ifdef CONFIG_ATARI
if (MACH_IS_ATARI)
atari_stram_reserve_pages((void *)availmem);
#endif
#ifdef CONFIG_SUN3X
if (MACH_IS_SUN3X) {
dvma_init();
}
#endif
/* set ISA defs early as possible */
#if defined(CONFIG_ISA) && defined(MULTI_ISA)
if (MACH_IS_Q40) {
isa_type = ISA_TYPE_Q40;
isa_sex = 0;
}
#ifdef CONFIG_AMIGA_PCMCIA
if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
isa_type = ISA_TYPE_AG;
isa_sex = 1;
}
#endif
#ifdef CONFIG_ATARI_ROM_ISA
if (MACH_IS_ATARI) {
isa_type = ISA_TYPE_ENEC;
isa_sex = 0;
}
#endif
#endif
}
static int show_cpuinfo(struct seq_file *m, void *v)
{
const char *cpu, *mmu, *fpu;
unsigned long clockfreq, clockfactor;
#define LOOP_CYCLES_68020 (8)
#define LOOP_CYCLES_68030 (8)
#define LOOP_CYCLES_68040 (3)
#define LOOP_CYCLES_68060 (1)
#define LOOP_CYCLES_COLDFIRE (2)
if (CPU_IS_020) {
cpu = "68020";
clockfactor = LOOP_CYCLES_68020;
} else if (CPU_IS_030) {
cpu = "68030";
clockfactor = LOOP_CYCLES_68030;
} else if (CPU_IS_040) {
cpu = "68040";
clockfactor = LOOP_CYCLES_68040;
} else if (CPU_IS_060) {
cpu = "68060";
clockfactor = LOOP_CYCLES_68060;
} else if (CPU_IS_COLDFIRE) {
cpu = "ColdFire";
clockfactor = LOOP_CYCLES_COLDFIRE;
} else {
cpu = "680x0";
clockfactor = 0;
}
#ifdef CONFIG_M68KFPU_EMU_ONLY
fpu = "none(soft float)";
#else
if (m68k_fputype & FPU_68881)
fpu = "68881";
else if (m68k_fputype & FPU_68882)
fpu = "68882";
else if (m68k_fputype & FPU_68040)
fpu = "68040";
else if (m68k_fputype & FPU_68060)
fpu = "68060";
else if (m68k_fputype & FPU_SUNFPA)
fpu = "Sun FPA";
else if (m68k_fputype & FPU_COLDFIRE)
fpu = "ColdFire";
else
fpu = "none";
#endif
if (m68k_mmutype & MMU_68851)
mmu = "68851";
else if (m68k_mmutype & MMU_68030)
mmu = "68030";
else if (m68k_mmutype & MMU_68040)
mmu = "68040";
else if (m68k_mmutype & MMU_68060)
mmu = "68060";
else if (m68k_mmutype & MMU_SUN3)
mmu = "Sun-3";
else if (m68k_mmutype & MMU_APOLLO)
mmu = "Apollo";
else if (m68k_mmutype & MMU_COLDFIRE)
mmu = "ColdFire";
else
mmu = "unknown";
clockfreq = loops_per_jiffy * HZ * clockfactor;
seq_printf(m, "CPU:\t\t%s\n"
"MMU:\t\t%s\n"
"FPU:\t\t%s\n"
"Clocking:\t%lu.%1luMHz\n"
"BogoMips:\t%lu.%02lu\n"
"Calibration:\t%lu loops\n",
cpu, mmu, fpu,
clockfreq/1000000,(clockfreq/100000)%10,
loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
loops_per_jiffy);
return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
{
return *pos < 1 ? (void *)1 : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
++*pos;
return NULL;
}
static void c_stop(struct seq_file *m, void *v)
{
}
const struct seq_operations cpuinfo_op = {
.start = c_start,
.next = c_next,
.stop = c_stop,
.show = show_cpuinfo,
};
#ifdef CONFIG_PROC_HARDWARE
static int hardware_proc_show(struct seq_file *m, void *v)
{
char model[80];
unsigned long mem;
int i;
if (mach_get_model)
mach_get_model(model);
else
strscpy(model, "Unknown m68k");
seq_printf(m, "Model:\t\t%s\n", model);
for (mem = 0, i = 0; i < m68k_num_memory; i++)
mem += m68k_memory[i].size;
seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
if (mach_get_hardware_list)
mach_get_hardware_list(m);
return 0;
}
static int __init proc_hardware_init(void)
{
proc_create_single("hardware", 0, NULL, hardware_proc_show);
return 0;
}
module_init(proc_hardware_init);
#endif
void __init arch_cpu_finalize_init(void)
{
#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
if (m68k_fputype == 0) {
pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
"WHICH IS REQUIRED BY LINUX/M68K ***\n");
pr_emerg("Upgrade your hardware or join the FPU "
"emulation project\n");
panic("no FPU");
}
#endif /* !CONFIG_M68KFPU_EMU */
}
#ifdef CONFIG_ADB
static int __init adb_probe_sync_enable (char *str) {
extern int __adb_probe_sync;
__adb_probe_sync = 1;
return 1;
}
__setup("adb_sync", adb_probe_sync_enable);
#endif /* CONFIG_ADB */
#if IS_ENABLED(CONFIG_NVRAM)
#ifdef CONFIG_MAC
static unsigned char m68k_nvram_read_byte(int addr)
{
if (MACH_IS_MAC)
return mac_pram_read_byte(addr);
return 0xff;
}
static void m68k_nvram_write_byte(unsigned char val, int addr)
{
if (MACH_IS_MAC)
mac_pram_write_byte(val, addr);
}
#endif /* CONFIG_MAC */
#ifdef CONFIG_ATARI
static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
{
if (MACH_IS_ATARI)
return atari_nvram_read(buf, count, ppos);
else if (MACH_IS_MAC)
return nvram_read_bytes(buf, count, ppos);
return -EINVAL;
}
static ssize_t m68k_nvram_write(char *buf, size_t count, loff_t *ppos)
{
if (MACH_IS_ATARI)
return atari_nvram_write(buf, count, ppos);
else if (MACH_IS_MAC)
return nvram_write_bytes(buf, count, ppos);
return -EINVAL;
}
static long m68k_nvram_set_checksum(void)
{
if (MACH_IS_ATARI)
return atari_nvram_set_checksum();
return -EINVAL;
}
static long m68k_nvram_initialize(void)
{
if (MACH_IS_ATARI)
return atari_nvram_initialize();
return -EINVAL;
}
#endif /* CONFIG_ATARI */
static ssize_t m68k_nvram_get_size(void)
{
if (MACH_IS_ATARI)
return atari_nvram_get_size();
else if (MACH_IS_MAC)
return mac_pram_get_size();
return -ENODEV;
}
/* Atari device drivers call .read (to get checksum validation) whereas
* Mac and PowerMac device drivers just use .read_byte.
*/
const struct nvram_ops arch_nvram_ops = {
#ifdef CONFIG_MAC
.read_byte = m68k_nvram_read_byte,
.write_byte = m68k_nvram_write_byte,
#endif
#ifdef CONFIG_ATARI
.read = m68k_nvram_read,
.write = m68k_nvram_write,
.set_checksum = m68k_nvram_set_checksum,
.initialize = m68k_nvram_initialize,
#endif
.get_size = m68k_nvram_get_size,
};
EXPORT_SYMBOL(arch_nvram_ops);
#endif /* CONFIG_NVRAM */
+219
View File
@@ -0,0 +1,219 @@
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/m68knommu/kernel/setup.c
*
* Copyright (C) 1999-2007 Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 1998,1999 D. Jeff Dionne <jeff@uClinux.org>
* Copyleft ()) 2000 James D. Schettine {james@telos-systems.com}
* Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
* Copyright (C) 1995 Hamish Macdonald
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
* Copyright (C) 2001 Lineo, Inc. <www.lineo.com>
*
* 68VZ328 Fixes/support Evan Stawnyczy <e@lineo.ca>
*/
/*
* This file handles the architecture-dependent parts of system setup
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/memblock.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
#include <linux/rtc.h>
#include <asm/setup.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/sections.h>
unsigned long memory_start;
unsigned long memory_end;
EXPORT_SYMBOL(memory_start);
EXPORT_SYMBOL(memory_end);
char __initdata command_line[COMMAND_LINE_SIZE];
/* machine dependent timer functions */
void (*mach_sched_init)(void) __initdata = NULL;
/* machine dependent reboot functions */
void (*mach_reset)(void);
void (*mach_halt)(void);
#ifdef CONFIG_M68000
#if defined(CONFIG_M68328)
#define CPU_NAME "MC68328"
#elif defined(CONFIG_M68EZ328)
#define CPU_NAME "MC68EZ328"
#elif defined(CONFIG_M68VZ328)
#define CPU_NAME "MC68VZ328"
#else
#define CPU_NAME "MC68000"
#endif
#endif /* CONFIG_M68000 */
#ifndef CPU_NAME
#define CPU_NAME "UNKNOWN"
#endif
/*
* Different cores have different instruction execution timings.
* The old/traditional 68000 cores are basically all the same, at 16.
* The ColdFire cores vary a little, their values are defined in their
* headers. We default to the standard 68000 value here.
*/
#ifndef CPU_INSTR_PER_JIFFY
#define CPU_INSTR_PER_JIFFY 16
#endif
void __init setup_arch(char **cmdline_p)
{
memory_start = PAGE_ALIGN(_ramstart);
memory_end = _ramend;
setup_initial_init_mm(_stext, _etext, _edata, NULL);
config_BSP(&command_line[0], sizeof(command_line));
#if defined(CONFIG_BOOTPARAM)
strscpy(&command_line[0], CONFIG_BOOTPARAM_STRING, sizeof(command_line));
#endif /* CONFIG_BOOTPARAM */
process_uboot_commandline(&command_line[0], sizeof(command_line));
pr_info("uClinux with CPU " CPU_NAME "\n");
#ifdef CONFIG_UCDIMM
pr_info("uCdimm by Lineo, Inc. <www.lineo.com>\n");
#endif
#ifdef CONFIG_M68328
pr_info("68328 support D. Jeff Dionne <jeff@uclinux.org>\n");
pr_info("68328 support Kenneth Albanowski <kjahds@kjshds.com>\n");
#endif
#ifdef CONFIG_M68EZ328
pr_info("68EZ328 DragonBallEZ support (C) 1999 Rt-Control, Inc\n");
#endif
#ifdef CONFIG_M68VZ328
pr_info("M68VZ328 support by Evan Stawnyczy <e@lineo.ca>\n");
pr_info("68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n");
#endif
#ifdef CONFIG_COLDFIRE
pr_info("COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n");
#ifdef CONFIG_M5307
pr_info("Modified for M5307 by Dave Miller, dmiller@intellistor.com\n");
#endif
#ifdef CONFIG_ELITE
pr_info("Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
#endif
#endif
pr_info("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
pr_info("68328/Pilot support Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>\n");
pr_info("TRG SuperPilot FLASH card support <info@trgnet.com>\n");
#endif
#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
pr_info("PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
#endif
#ifdef CONFIG_DRAGEN2
pr_info("DragonEngine II board support by Georges Menie\n");
#endif
#ifdef CONFIG_M5235EVB
pr_info("Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
#endif
pr_debug("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n",
_stext, _etext, _sdata, _edata, __bss_start, __bss_stop);
pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n",
__bss_stop, memory_start, memory_start, memory_end);
memblock_add(_rambase, memory_end - _rambase);
memblock_reserve(_rambase, memory_start - _rambase);
/* Keep a copy of command line */
*cmdline_p = &command_line[0];
strscpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
/*
* Give all the memory to the bootmap allocator, tell it to put the
* boot mem_map at the start of memory.
*/
min_low_pfn = PFN_DOWN(memory_start);
max_pfn = max_low_pfn = PFN_DOWN(memory_end);
#if defined(CONFIG_UBOOT) && defined(CONFIG_BLK_DEV_INITRD)
if ((initrd_start > 0) && (initrd_start < initrd_end) &&
(initrd_end < memory_end))
memblock_reserve(initrd_start, initrd_end - initrd_start);
#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
/*
* Get kmalloc into gear.
*/
paging_init();
}
/*
* Get CPU information for use by the procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
char *cpu, *mmu, *fpu;
u_long clockfreq;
cpu = CPU_NAME;
mmu = "none";
fpu = "none";
clockfreq = (loops_per_jiffy * HZ) * CPU_INSTR_PER_JIFFY;
seq_printf(m, "CPU:\t\t%s\n"
"MMU:\t\t%s\n"
"FPU:\t\t%s\n"
"Clocking:\t%lu.%1luMHz\n"
"BogoMips:\t%lu.%02lu\n"
"Calibration:\t%lu loops\n",
cpu, mmu, fpu,
clockfreq / 1000000,
(clockfreq / 100000) % 10,
(loops_per_jiffy * HZ) / 500000,
((loops_per_jiffy * HZ) / 5000) % 100,
(loops_per_jiffy * HZ));
return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
{
return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
++*pos;
return c_start(m, pos);
}
static void c_stop(struct seq_file *m, void *v)
{
}
const struct seq_operations cpuinfo_op = {
.start = c_start,
.next = c_next,
.stop = c_stop,
.show = show_cpuinfo,
};
File diff suppressed because it is too large Load Diff
+7
View File
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
asmlinkage void do_notify_resume(struct pt_regs *regs);
asmlinkage void *do_sigreturn(struct pt_regs *regs, struct switch_stack *sw);
asmlinkage void *do_rt_sigreturn(struct pt_regs *regs, struct switch_stack *sw);
+90
View File
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/entry.h>
#include <asm/page.h>
#include <asm/contregs.h>
#include <asm/sun3-head.h>
PSL_HIGHIPL = 0x2700
NBSG = 0x20000
ICACHE_ONLY = 0x00000009
CACHES_OFF = 0x00000008 | actually a clear and disable --m
#define MAS_STACK INT_STACK
ROOT_TABLE_SIZE = 128
PAGESIZE = 8192
SUN3_INVALID_PMEG = 255
.globl bootup_user_stack
.globl bootup_kernel_stack
.globl pg0
.globl swapper_pg_dir
.globl kernel_pmd_table
.globl availmem
.global m68k_pgtable_cachemode
.global kpt
| todo: all these should be in bss!
swapper_pg_dir: .skip 0x2000
pg0: .skip 0x2000
kernel_pmd_table: .skip 0x2000
.globl kernel_pg_dir
.equ kernel_pg_dir,kernel_pmd_table
__HEAD
ENTRY(_stext)
ENTRY(_start)
/* Firstly, disable interrupts and set up function codes. */
movew #PSL_HIGHIPL, %sr
moveq #FC_CONTROL, %d0
movec %d0, %sfc
movec %d0, %dfc
/* Make sure we're in context zero. */
moveq #0, %d0
movsb %d0, AC_CONTEXT
/* map everything the bootloader left us into high memory, clean up the
excess later */
lea (AC_SEGMAP+0),%a0
lea (AC_SEGMAP+KERNBASE),%a1
1:
movsb %a0@, %d1
movsb %d1, %a1@
cmpib #SUN3_INVALID_PMEG, %d1
beq 2f
addl #NBSG,%a0
addl #NBSG,%a1
jmp 1b
2:
/* Disable caches and jump to high code. */
moveq #ICACHE_ONLY,%d0 | Cache disabled until we're ready to enable it
movc %d0, %cacr | is this the right value? (yes --m)
jmp 1f:l
/* Following code executes at high addresses (0xE000xxx). */
1: lea init_task,%curptr | get initial thread...
lea init_thread_union+THREAD_SIZE,%sp | ...and its stack.
/* Point MSP at an invalid page to trap if it's used. --m */
movl #(PAGESIZE),%d0
movc %d0,%msp
moveq #-1,%d0
movsb %d0,(AC_SEGMAP+0x0)
jbsr sun3_init
jbsr base_trap_init
jbsr start_kernel
trap #15
.data
.even
kpt:
.long 0
availmem:
.long 0
+584
View File
@@ -0,0 +1,584 @@
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/m68k/kernel/sys_m68k.c
*
* This file contains various random system calls that
* have a non-standard calling sequence on the Linux/m68k
* platform.
*/
#include <linux/capability.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/smp.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/syscalls.h>
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/ipc.h>
#include <asm/setup.h>
#include <linux/uaccess.h>
#include <asm/cachectl.h>
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/syscalls.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#ifdef CONFIG_MMU
#include <asm/tlb.h>
#include "../mm/fault.h"
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
/*
* This is wrong for sun3 - there PAGE_SIZE is 8Kb,
* so we need to shift the argument down by 1; m68k mmap64(3)
* (in libc) expects the last argument of mmap2 in 4Kb units.
*/
return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
}
/* Convert virtual (user) address VADDR to physical address PADDR */
#define virt_to_phys_040(vaddr) \
({ \
unsigned long _mmusr, _paddr; \
\
__asm__ __volatile__ (".chip 68040\n\t" \
"ptestr (%1)\n\t" \
"movec %%mmusr,%0\n\t" \
".chip 68k" \
: "=r" (_mmusr) \
: "a" (vaddr)); \
_paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0; \
_paddr; \
})
static inline int
cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
{
unsigned long paddr, i;
switch (scope)
{
case FLUSH_SCOPE_ALL:
switch (cache)
{
case FLUSH_CACHE_DATA:
/* This nop is needed for some broken versions of the 68040. */
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpusha %dc\n\t"
".chip 68k");
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpusha %ic\n\t"
".chip 68k");
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpusha %bc\n\t"
".chip 68k");
break;
}
break;
case FLUSH_SCOPE_LINE:
/* Find the physical address of the first mapped page in the
address range. */
if ((paddr = virt_to_phys_040(addr))) {
paddr += addr & ~(PAGE_MASK | 15);
len = (len + (addr & 15) + 15) >> 4;
} else {
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
if (len <= tmp)
return 0;
addr += tmp;
len -= tmp;
tmp = PAGE_SIZE;
for (;;)
{
if ((paddr = virt_to_phys_040(addr)))
break;
if (len <= tmp)
return 0;
addr += tmp;
len -= tmp;
}
len = (len + 15) >> 4;
}
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
while (len--)
{
switch (cache)
{
case FLUSH_CACHE_DATA:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushl %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushl %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushl %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
}
if (!--i && len)
{
/*
* No need to page align here since it is done by
* virt_to_phys_040().
*/
addr += PAGE_SIZE;
i = PAGE_SIZE / 16;
/* Recompute physical address when crossing a page
boundary. */
for (;;)
{
if ((paddr = virt_to_phys_040(addr)))
break;
if (len <= i)
return 0;
len -= i;
addr += PAGE_SIZE;
}
}
else
paddr += 16;
}
break;
default:
case FLUSH_SCOPE_PAGE:
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
{
if (!(paddr = virt_to_phys_040(addr)))
continue;
switch (cache)
{
case FLUSH_CACHE_DATA:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushp %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushp %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ ("nop\n\t"
".chip 68040\n\t"
"cpushp %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
}
}
break;
}
return 0;
}
#define virt_to_phys_060(vaddr) \
({ \
unsigned long paddr; \
__asm__ __volatile__ (".chip 68060\n\t" \
"plpar (%0)\n\t" \
".chip 68k" \
: "=a" (paddr) \
: "0" (vaddr)); \
(paddr); /* XXX */ \
})
static inline int
cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
{
unsigned long paddr, i;
/*
* 68060 manual says:
* cpush %dc : flush DC, remains valid (with our %cacr setup)
* cpush %ic : invalidate IC
* cpush %bc : flush DC + invalidate IC
*/
switch (scope)
{
case FLUSH_SCOPE_ALL:
switch (cache)
{
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %dc\n\t"
".chip 68k");
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %ic\n\t"
".chip 68k");
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpusha %bc\n\t"
".chip 68k");
break;
}
break;
case FLUSH_SCOPE_LINE:
/* Find the physical address of the first mapped page in the
address range. */
len += addr & 15;
addr &= -16;
if (!(paddr = virt_to_phys_060(addr))) {
unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
if (len <= tmp)
return 0;
addr += tmp;
len -= tmp;
tmp = PAGE_SIZE;
for (;;)
{
if ((paddr = virt_to_phys_060(addr)))
break;
if (len <= tmp)
return 0;
addr += tmp;
len -= tmp;
}
}
len = (len + 15) >> 4;
i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
while (len--)
{
switch (cache)
{
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushl %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
}
if (!--i && len)
{
/*
* We just want to jump to the first cache line
* in the next page.
*/
addr += PAGE_SIZE;
addr &= PAGE_MASK;
i = PAGE_SIZE / 16;
/* Recompute physical address when crossing a page
boundary. */
for (;;)
{
if ((paddr = virt_to_phys_060(addr)))
break;
if (len <= i)
return 0;
len -= i;
addr += PAGE_SIZE;
}
}
else
paddr += 16;
}
break;
default:
case FLUSH_SCOPE_PAGE:
len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
addr &= PAGE_MASK; /* Workaround for bug in some
revisions of the 68060 */
for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
{
if (!(paddr = virt_to_phys_060(addr)))
continue;
switch (cache)
{
case FLUSH_CACHE_DATA:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%dc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
case FLUSH_CACHE_INSN:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%ic,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
default:
case FLUSH_CACHE_BOTH:
__asm__ __volatile__ (".chip 68060\n\t"
"cpushp %%bc,(%0)\n\t"
".chip 68k"
: : "a" (paddr));
break;
}
}
break;
}
return 0;
}
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage int
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
{
int ret = -EINVAL;
if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
cache & ~FLUSH_CACHE_BOTH)
goto out;
if (scope == FLUSH_SCOPE_ALL) {
/* Only the superuser may explicitly flush the whole cache. */
ret = -EPERM;
if (!capable(CAP_SYS_ADMIN))
goto out;
mmap_read_lock(current->mm);
} else {
struct vm_area_struct *vma;
/* Check for overflow. */
if (addr + len < addr)
goto out;
/*
* Verify that the specified address region actually belongs
* to this process.
*/
mmap_read_lock(current->mm);
vma = vma_lookup(current->mm, addr);
if (!vma || addr + len > vma->vm_end)
goto out_unlock;
}
if (CPU_IS_020_OR_030) {
if (scope == FLUSH_SCOPE_LINE && len < 256) {
unsigned long cacr;
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
if (cache & FLUSH_CACHE_INSN)
cacr |= 4;
if (cache & FLUSH_CACHE_DATA)
cacr |= 0x400;
len >>= 2;
while (len--) {
__asm__ __volatile__ ("movec %1, %%caar\n\t"
"movec %0, %%cacr"
: /* no outputs */
: "r" (cacr), "r" (addr));
addr += 4;
}
} else {
/* Flush the whole cache, even if page granularity requested. */
unsigned long cacr;
__asm__ ("movec %%cacr, %0" : "=r" (cacr));
if (cache & FLUSH_CACHE_INSN)
cacr |= 8;
if (cache & FLUSH_CACHE_DATA)
cacr |= 0x800;
__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
}
ret = 0;
goto out_unlock;
} else {
/*
* 040 or 060: don't blindly trust 'scope', someone could
* try to flush a few megs of memory.
*/
if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
scope=FLUSH_SCOPE_PAGE;
if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
scope=FLUSH_SCOPE_ALL;
if (CPU_IS_040) {
ret = cache_flush_040 (addr, scope, cache, len);
} else if (CPU_IS_060) {
ret = cache_flush_060 (addr, scope, cache, len);
}
}
out_unlock:
mmap_read_unlock(current->mm);
out:
return ret;
}
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
D1 (newval). */
asmlinkage int
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
unsigned long __user * mem)
{
/* This was borrowed from ARM's implementation. */
for (;;) {
struct mm_struct *mm = current->mm;
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
spinlock_t *ptl;
unsigned long mem_value;
mmap_read_lock(mm);
pgd = pgd_offset(mm, (unsigned long)mem);
if (!pgd_present(*pgd))
goto bad_access;
p4d = p4d_offset(pgd, (unsigned long)mem);
if (!p4d_present(*p4d))
goto bad_access;
pud = pud_offset(p4d, (unsigned long)mem);
if (!pud_present(*pud))
goto bad_access;
pmd = pmd_offset(pud, (unsigned long)mem);
if (!pmd_present(*pmd))
goto bad_access;
pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
if (!pte)
goto bad_access;
if (!pte_present(*pte) || !pte_dirty(*pte)
|| !pte_write(*pte)) {
pte_unmap_unlock(pte, ptl);
goto bad_access;
}
/*
* No need to check for EFAULT; we know that the page is
* present and writable.
*/
__get_user(mem_value, mem);
if (mem_value == oldval)
__put_user(newval, mem);
pte_unmap_unlock(pte, ptl);
mmap_read_unlock(mm);
return mem_value;
bad_access:
mmap_read_unlock(mm);
/* This is not necessarily a bad access, we can get here if
a memory we're trying to write to should be copied-on-write.
Make the kernel do the necessary page stuff, then re-iterate.
Simulate a write access fault to do that. */
{
/* The first argument of the function corresponds to
D1, which is the first field of struct pt_regs. */
struct pt_regs *fp = (struct pt_regs *)&newval;
/* '3' is an RMW flag. */
if (do_page_fault(fp, (unsigned long)mem, 3))
/* If the do_page_fault() failed, we don't
have anything meaningful to return.
There should be a SIGSEGV pending for
the process. */
return 0xdeadbeef;
}
}
}
#else
/* sys_cacheflush -- flush (part of) the processor cache. */
asmlinkage int
sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
{
flush_cache_all();
return 0;
}
/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
D1 (newval). */
asmlinkage int
sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
unsigned long __user * mem)
{
struct mm_struct *mm = current->mm;
unsigned long mem_value;
mmap_read_lock(mm);
mem_value = *mem;
if (mem_value == oldval)
*mem = newval;
mmap_read_unlock(mm);
return mem_value;
}
#endif /* CONFIG_MMU */
asmlinkage int sys_getpagesize(void)
{
return PAGE_SIZE;
}
asmlinkage unsigned long sys_get_thread_area(void)
{
return current_thread_info()->tp_value;
}
asmlinkage int sys_set_thread_area(unsigned long tp)
{
current_thread_info()->tp_value = tp;
return 0;
}
asmlinkage int sys_atomic_barrier(void)
{
/* no code needed for uniprocs */
return 0;
}
@@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0
kapi := arch/$(SRCARCH)/include/generated/asm
uapi := arch/$(SRCARCH)/include/generated/uapi/asm
$(shell mkdir -p $(uapi) $(kapi))
syscall := $(src)/syscall.tbl
syshdr := $(srctree)/scripts/syscallhdr.sh
systbl := $(srctree)/scripts/syscalltbl.sh
quiet_cmd_syshdr = SYSHDR $@
cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --emit-nr $< $@
quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) $(systbl) $< $@
$(uapi)/unistd_32.h: $(syscall) $(syshdr) FORCE
$(call if_changed,syshdr)
$(kapi)/syscall_table.h: $(syscall) $(systbl) FORCE
$(call if_changed,systbl)
uapisyshdr-y += unistd_32.h
kapisyshdr-y += syscall_table.h
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
kapisyshdr-y := $(addprefix $(kapi)/, $(kapisyshdr-y))
targets += $(addprefix ../../../../, $(uapisyshdr-y) $(kapisyshdr-y))
PHONY += all
all: $(uapisyshdr-y) $(kapisyshdr-y)
@:
@@ -0,0 +1,473 @@
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# system call numbers and entry vectors for m68k
#
# The format is:
# <number> <abi> <name> <entry point>
#
# The <abi> is always "common" for this file
#
0 common restart_syscall sys_restart_syscall
1 common exit sys_exit
2 common fork __sys_fork
3 common read sys_read
4 common write sys_write
5 common open sys_open
6 common close sys_close
7 common waitpid sys_waitpid
8 common creat sys_creat
9 common link sys_link
10 common unlink sys_unlink
11 common execve sys_execve
12 common chdir sys_chdir
13 common time sys_time32
14 common mknod sys_mknod
15 common chmod sys_chmod
16 common chown sys_chown16
# 17 was break
18 common oldstat sys_stat
19 common lseek sys_lseek
20 common getpid sys_getpid
21 common mount sys_mount
22 common umount sys_oldumount
23 common setuid sys_setuid16
24 common getuid sys_getuid16
25 common stime sys_stime32
26 common ptrace sys_ptrace
27 common alarm sys_alarm
28 common oldfstat sys_fstat
29 common pause sys_pause
30 common utime sys_utime32
# 31 was stty
# 32 was gtty
33 common access sys_access
34 common nice sys_nice
# 35 was ftime
36 common sync sys_sync
37 common kill sys_kill
38 common rename sys_rename
39 common mkdir sys_mkdir
40 common rmdir sys_rmdir
41 common dup sys_dup
42 common pipe sys_pipe
43 common times sys_times
# 44 was prof
45 common brk sys_brk
46 common setgid sys_setgid16
47 common getgid sys_getgid16
48 common signal sys_signal
49 common geteuid sys_geteuid16
50 common getegid sys_getegid16
51 common acct sys_acct
52 common umount2 sys_umount
# 53 was lock
54 common ioctl sys_ioctl
55 common fcntl sys_fcntl
# 56 was mpx
57 common setpgid sys_setpgid
# 58 was ulimit
# 59 was oldolduname
60 common umask sys_umask
61 common chroot sys_chroot
62 common ustat sys_ustat
63 common dup2 sys_dup2
64 common getppid sys_getppid
65 common getpgrp sys_getpgrp
66 common setsid sys_setsid
67 common sigaction sys_sigaction
68 common sgetmask sys_sgetmask
69 common ssetmask sys_ssetmask
70 common setreuid sys_setreuid16
71 common setregid sys_setregid16
72 common sigsuspend sys_sigsuspend
73 common sigpending sys_sigpending
74 common sethostname sys_sethostname
75 common setrlimit sys_setrlimit
76 common getrlimit sys_old_getrlimit
77 common getrusage sys_getrusage
78 common gettimeofday sys_gettimeofday
79 common settimeofday sys_settimeofday
80 common getgroups sys_getgroups16
81 common setgroups sys_setgroups16
82 common select sys_old_select
83 common symlink sys_symlink
84 common oldlstat sys_lstat
85 common readlink sys_readlink
86 common uselib sys_uselib
87 common swapon sys_swapon
88 common reboot sys_reboot
89 common readdir sys_old_readdir
90 common mmap sys_old_mmap
91 common munmap sys_munmap
92 common truncate sys_truncate
93 common ftruncate sys_ftruncate
94 common fchmod sys_fchmod
95 common fchown sys_fchown16
96 common getpriority sys_getpriority
97 common setpriority sys_setpriority
# 98 was profil
99 common statfs sys_statfs
100 common fstatfs sys_fstatfs
# 101 was ioperm
102 common socketcall sys_socketcall
103 common syslog sys_syslog
104 common setitimer sys_setitimer
105 common getitimer sys_getitimer
106 common stat sys_newstat
107 common lstat sys_newlstat
108 common fstat sys_newfstat
# 109 was olduname
# 110 was iopl
111 common vhangup sys_vhangup
# 112 was idle
# 113 was vm86
114 common wait4 sys_wait4
115 common swapoff sys_swapoff
116 common sysinfo sys_sysinfo
117 common ipc sys_ipc
118 common fsync sys_fsync
119 common sigreturn sys_sigreturn
120 common clone __sys_clone
121 common setdomainname sys_setdomainname
122 common uname sys_newuname
123 common cacheflush sys_cacheflush
124 common adjtimex sys_adjtimex_time32
125 common mprotect sys_mprotect
126 common sigprocmask sys_sigprocmask
127 common create_module sys_ni_syscall
128 common init_module sys_init_module
129 common delete_module sys_delete_module
130 common get_kernel_syms sys_ni_syscall
131 common quotactl sys_quotactl
132 common getpgid sys_getpgid
133 common fchdir sys_fchdir
134 common bdflush sys_ni_syscall
135 common sysfs sys_sysfs
136 common personality sys_personality
# 137 was afs_syscall
138 common setfsuid sys_setfsuid16
139 common setfsgid sys_setfsgid16
140 common _llseek sys_llseek
141 common getdents sys_getdents
142 common _newselect sys_select
143 common flock sys_flock
144 common msync sys_msync
145 common readv sys_readv
146 common writev sys_writev
147 common getsid sys_getsid
148 common fdatasync sys_fdatasync
149 common _sysctl sys_ni_syscall
150 common mlock sys_mlock
151 common munlock sys_munlock
152 common mlockall sys_mlockall
153 common munlockall sys_munlockall
154 common sched_setparam sys_sched_setparam
155 common sched_getparam sys_sched_getparam
156 common sched_setscheduler sys_sched_setscheduler
157 common sched_getscheduler sys_sched_getscheduler
158 common sched_yield sys_sched_yield
159 common sched_get_priority_max sys_sched_get_priority_max
160 common sched_get_priority_min sys_sched_get_priority_min
161 common sched_rr_get_interval sys_sched_rr_get_interval_time32
162 common nanosleep sys_nanosleep_time32
163 common mremap sys_mremap
164 common setresuid sys_setresuid16
165 common getresuid sys_getresuid16
166 common getpagesize sys_getpagesize
167 common query_module sys_ni_syscall
168 common poll sys_poll
169 common nfsservctl sys_ni_syscall
170 common setresgid sys_setresgid16
171 common getresgid sys_getresgid16
172 common prctl sys_prctl
173 common rt_sigreturn sys_rt_sigreturn
174 common rt_sigaction sys_rt_sigaction
175 common rt_sigprocmask sys_rt_sigprocmask
176 common rt_sigpending sys_rt_sigpending
177 common rt_sigtimedwait sys_rt_sigtimedwait_time32
178 common rt_sigqueueinfo sys_rt_sigqueueinfo
179 common rt_sigsuspend sys_rt_sigsuspend
180 common pread64 sys_pread64
181 common pwrite64 sys_pwrite64
182 common lchown sys_lchown16
183 common getcwd sys_getcwd
184 common capget sys_capget
185 common capset sys_capset
186 common sigaltstack sys_sigaltstack
187 common sendfile sys_sendfile
188 common getpmsg sys_ni_syscall
189 common putpmsg sys_ni_syscall
190 common vfork __sys_vfork
191 common ugetrlimit sys_getrlimit
192 common mmap2 sys_mmap2
193 common truncate64 sys_truncate64
194 common ftruncate64 sys_ftruncate64
195 common stat64 sys_stat64
196 common lstat64 sys_lstat64
197 common fstat64 sys_fstat64
198 common chown32 sys_chown
199 common getuid32 sys_getuid
200 common getgid32 sys_getgid
201 common geteuid32 sys_geteuid
202 common getegid32 sys_getegid
203 common setreuid32 sys_setreuid
204 common setregid32 sys_setregid
205 common getgroups32 sys_getgroups
206 common setgroups32 sys_setgroups
207 common fchown32 sys_fchown
208 common setresuid32 sys_setresuid
209 common getresuid32 sys_getresuid
210 common setresgid32 sys_setresgid
211 common getresgid32 sys_getresgid
212 common lchown32 sys_lchown
213 common setuid32 sys_setuid
214 common setgid32 sys_setgid
215 common setfsuid32 sys_setfsuid
216 common setfsgid32 sys_setfsgid
217 common pivot_root sys_pivot_root
# 218 is reserved
# 219 is reserved
220 common getdents64 sys_getdents64
221 common gettid sys_gettid
222 common tkill sys_tkill
223 common setxattr sys_setxattr
224 common lsetxattr sys_lsetxattr
225 common fsetxattr sys_fsetxattr
226 common getxattr sys_getxattr
227 common lgetxattr sys_lgetxattr
228 common fgetxattr sys_fgetxattr
229 common listxattr sys_listxattr
230 common llistxattr sys_llistxattr
231 common flistxattr sys_flistxattr
232 common removexattr sys_removexattr
233 common lremovexattr sys_lremovexattr
234 common fremovexattr sys_fremovexattr
235 common futex sys_futex_time32
236 common sendfile64 sys_sendfile64
237 common mincore sys_mincore
238 common madvise sys_madvise
239 common fcntl64 sys_fcntl64
240 common readahead sys_readahead
241 common io_setup sys_io_setup
242 common io_destroy sys_io_destroy
243 common io_getevents sys_io_getevents_time32
244 common io_submit sys_io_submit
245 common io_cancel sys_io_cancel
246 common fadvise64 sys_fadvise64
247 common exit_group sys_exit_group
248 common lookup_dcookie sys_ni_syscall
249 common epoll_create sys_epoll_create
250 common epoll_ctl sys_epoll_ctl
251 common epoll_wait sys_epoll_wait
252 common remap_file_pages sys_remap_file_pages
253 common set_tid_address sys_set_tid_address
254 common timer_create sys_timer_create
255 common timer_settime sys_timer_settime32
256 common timer_gettime sys_timer_gettime32
257 common timer_getoverrun sys_timer_getoverrun
258 common timer_delete sys_timer_delete
259 common clock_settime sys_clock_settime32
260 common clock_gettime sys_clock_gettime32
261 common clock_getres sys_clock_getres_time32
262 common clock_nanosleep sys_clock_nanosleep_time32
263 common statfs64 sys_statfs64
264 common fstatfs64 sys_fstatfs64
265 common tgkill sys_tgkill
266 common utimes sys_utimes_time32
267 common fadvise64_64 sys_fadvise64_64
268 common mbind sys_mbind
269 common get_mempolicy sys_get_mempolicy
270 common set_mempolicy sys_set_mempolicy
271 common mq_open sys_mq_open
272 common mq_unlink sys_mq_unlink
273 common mq_timedsend sys_mq_timedsend_time32
274 common mq_timedreceive sys_mq_timedreceive_time32
275 common mq_notify sys_mq_notify
276 common mq_getsetattr sys_mq_getsetattr
277 common waitid sys_waitid
# 278 was vserver
279 common add_key sys_add_key
280 common request_key sys_request_key
281 common keyctl sys_keyctl
282 common ioprio_set sys_ioprio_set
283 common ioprio_get sys_ioprio_get
284 common inotify_init sys_inotify_init
285 common inotify_add_watch sys_inotify_add_watch
286 common inotify_rm_watch sys_inotify_rm_watch
287 common migrate_pages sys_migrate_pages
288 common openat sys_openat
289 common mkdirat sys_mkdirat
290 common mknodat sys_mknodat
291 common fchownat sys_fchownat
292 common futimesat sys_futimesat_time32
293 common fstatat64 sys_fstatat64
294 common unlinkat sys_unlinkat
295 common renameat sys_renameat
296 common linkat sys_linkat
297 common symlinkat sys_symlinkat
298 common readlinkat sys_readlinkat
299 common fchmodat sys_fchmodat
300 common faccessat sys_faccessat
301 common pselect6 sys_pselect6_time32
302 common ppoll sys_ppoll_time32
303 common unshare sys_unshare
304 common set_robust_list sys_set_robust_list
305 common get_robust_list sys_get_robust_list
306 common splice sys_splice
307 common sync_file_range sys_sync_file_range
308 common tee sys_tee
309 common vmsplice sys_vmsplice
310 common move_pages sys_move_pages
311 common sched_setaffinity sys_sched_setaffinity
312 common sched_getaffinity sys_sched_getaffinity
313 common kexec_load sys_kexec_load
314 common getcpu sys_getcpu
315 common epoll_pwait sys_epoll_pwait
316 common utimensat sys_utimensat_time32
317 common signalfd sys_signalfd
318 common timerfd_create sys_timerfd_create
319 common eventfd sys_eventfd
320 common fallocate sys_fallocate
321 common timerfd_settime sys_timerfd_settime32
322 common timerfd_gettime sys_timerfd_gettime32
323 common signalfd4 sys_signalfd4
324 common eventfd2 sys_eventfd2
325 common epoll_create1 sys_epoll_create1
326 common dup3 sys_dup3
327 common pipe2 sys_pipe2
328 common inotify_init1 sys_inotify_init1
329 common preadv sys_preadv
330 common pwritev sys_pwritev
331 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
332 common perf_event_open sys_perf_event_open
333 common get_thread_area sys_get_thread_area
334 common set_thread_area sys_set_thread_area
335 common atomic_cmpxchg_32 sys_atomic_cmpxchg_32
336 common atomic_barrier sys_atomic_barrier
337 common fanotify_init sys_fanotify_init
338 common fanotify_mark sys_fanotify_mark
339 common prlimit64 sys_prlimit64
340 common name_to_handle_at sys_name_to_handle_at
341 common open_by_handle_at sys_open_by_handle_at
342 common clock_adjtime sys_clock_adjtime32
343 common syncfs sys_syncfs
344 common setns sys_setns
345 common process_vm_readv sys_process_vm_readv
346 common process_vm_writev sys_process_vm_writev
347 common kcmp sys_kcmp
348 common finit_module sys_finit_module
349 common sched_setattr sys_sched_setattr
350 common sched_getattr sys_sched_getattr
351 common renameat2 sys_renameat2
352 common getrandom sys_getrandom
353 common memfd_create sys_memfd_create
354 common bpf sys_bpf
355 common execveat sys_execveat
356 common socket sys_socket
357 common socketpair sys_socketpair
358 common bind sys_bind
359 common connect sys_connect
360 common listen sys_listen
361 common accept4 sys_accept4
362 common getsockopt sys_getsockopt
363 common setsockopt sys_setsockopt
364 common getsockname sys_getsockname
365 common getpeername sys_getpeername
366 common sendto sys_sendto
367 common sendmsg sys_sendmsg
368 common recvfrom sys_recvfrom
369 common recvmsg sys_recvmsg
370 common shutdown sys_shutdown
371 common recvmmsg sys_recvmmsg_time32
372 common sendmmsg sys_sendmmsg
373 common userfaultfd sys_userfaultfd
374 common membarrier sys_membarrier
375 common mlock2 sys_mlock2
376 common copy_file_range sys_copy_file_range
377 common preadv2 sys_preadv2
378 common pwritev2 sys_pwritev2
379 common statx sys_statx
380 common seccomp sys_seccomp
381 common pkey_mprotect sys_pkey_mprotect
382 common pkey_alloc sys_pkey_alloc
383 common pkey_free sys_pkey_free
384 common rseq sys_rseq
# room for arch specific calls
393 common semget sys_semget
394 common semctl sys_semctl
395 common shmget sys_shmget
396 common shmctl sys_shmctl
397 common shmat sys_shmat
398 common shmdt sys_shmdt
399 common msgget sys_msgget
400 common msgsnd sys_msgsnd
401 common msgrcv sys_msgrcv
402 common msgctl sys_msgctl
403 common clock_gettime64 sys_clock_gettime
404 common clock_settime64 sys_clock_settime
405 common clock_adjtime64 sys_clock_adjtime
406 common clock_getres_time64 sys_clock_getres
407 common clock_nanosleep_time64 sys_clock_nanosleep
408 common timer_gettime64 sys_timer_gettime
409 common timer_settime64 sys_timer_settime
410 common timerfd_gettime64 sys_timerfd_gettime
411 common timerfd_settime64 sys_timerfd_settime
412 common utimensat_time64 sys_utimensat
413 common pselect6_time64 sys_pselect6
414 common ppoll_time64 sys_ppoll
416 common io_pgetevents_time64 sys_io_pgetevents
417 common recvmmsg_time64 sys_recvmmsg
418 common mq_timedsend_time64 sys_mq_timedsend
419 common mq_timedreceive_time64 sys_mq_timedreceive
420 common semtimedop_time64 sys_semtimedop
421 common rt_sigtimedwait_time64 sys_rt_sigtimedwait
422 common futex_time64 sys_futex
423 common sched_rr_get_interval_time64 sys_sched_rr_get_interval
424 common pidfd_send_signal sys_pidfd_send_signal
425 common io_uring_setup sys_io_uring_setup
426 common io_uring_enter sys_io_uring_enter
427 common io_uring_register sys_io_uring_register
428 common open_tree sys_open_tree
429 common move_mount sys_move_mount
430 common fsopen sys_fsopen
431 common fsconfig sys_fsconfig
432 common fsmount sys_fsmount
433 common fspick sys_fspick
434 common pidfd_open sys_pidfd_open
435 common clone3 __sys_clone3
436 common close_range sys_close_range
437 common openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
443 common quotactl_fd sys_quotactl_fd
444 common landlock_create_ruleset sys_landlock_create_ruleset
445 common landlock_add_rule sys_landlock_add_rule
446 common landlock_restrict_self sys_landlock_restrict_self
# 447 reserved for memfd_secret
448 common process_mrelease sys_process_mrelease
449 common futex_waitv sys_futex_waitv
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
457 common statmount sys_statmount
458 common listmount sys_listmount
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common setxattrat sys_setxattrat
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common listns sys_listns
471 common rseq_slice_yield sys_rseq_slice_yield
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
*
* Based on older entry.S files, the following copyrights apply:
*
* Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
* Kenneth Albanowski <kjahds@kjahds.com>,
* Copyright (C) 2000 Lineo Inc. (www.lineo.com)
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Linux/m68k support by Hamish Macdonald
*/
#include <linux/linkage.h>
#ifndef CONFIG_MMU
#define sys_mmap2 sys_mmap_pgoff
#endif
#define __SYSCALL(nr, entry) .long entry
.section .rodata
ALIGN
ENTRY(sys_call_table)
#include <asm/syscall_table.h>
+157
View File
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* linux/arch/m68k/kernel/time.c
*
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*
* This file contains the m68k-specific time handling details.
* Most of the stuff is located in the machine specific files.
*
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
* "A Kernel Model for Precision Timekeeping" by Dave Mills
*/
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sched/loadavg.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/irq_regs.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/profile.h>
unsigned long (*mach_random_get_entropy)(void);
EXPORT_SYMBOL_GPL(mach_random_get_entropy);
#ifdef CONFIG_HEARTBEAT
void timer_heartbeat(void)
{
/* use power LED as a heartbeat instead -- much more useful
for debugging -- based on the version for PReP by Cort */
/* acts like an actual heart beat -- ie thump-thump-pause... */
if (mach_heartbeat) {
static unsigned cnt = 0, period = 0, dist = 0;
if (cnt == 0 || cnt == dist)
mach_heartbeat( 1 );
else if (cnt == 7 || cnt == dist+7)
mach_heartbeat( 0 );
if (++cnt > period) {
cnt = 0;
/* The hyperbolic function below modifies the heartbeat period
* length in dependency of the current (5min) load. It goes
* through the points f(0)=126, f(1)=86, f(5)=51,
* f(inf)->30. */
period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
dist = period / 4;
}
}
}
#endif /* CONFIG_HEARTBEAT */
#if defined(CONFIG_M68KCLASSIC) || defined(CONFIG_SUN3)
/* machine dependent timer functions */
int (*mach_hwclk) (int, struct rtc_time*);
EXPORT_SYMBOL(mach_hwclk);
int (*mach_get_rtc_pll)(struct rtc_pll_info *);
int (*mach_set_rtc_pll)(struct rtc_pll_info *);
EXPORT_SYMBOL(mach_get_rtc_pll);
EXPORT_SYMBOL(mach_set_rtc_pll);
#if !IS_BUILTIN(CONFIG_RTC_DRV_GENERIC)
void read_persistent_clock64(struct timespec64 *ts)
{
struct rtc_time time;
ts->tv_sec = 0;
ts->tv_nsec = 0;
if (!mach_hwclk)
return;
mach_hwclk(0, &time);
ts->tv_sec = mktime64(time.tm_year + 1900, time.tm_mon + 1, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
}
#endif
#if IS_ENABLED(CONFIG_RTC_DRV_GENERIC)
static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm)
{
mach_hwclk(0, tm);
return 0;
}
static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm)
{
if (mach_hwclk(1, tm) < 0)
return -EOPNOTSUPP;
return 0;
}
static int rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rtc_pll_info pll;
struct rtc_pll_info __user *argp = (void __user *)arg;
switch (cmd) {
case RTC_PLL_GET:
if (!mach_get_rtc_pll || mach_get_rtc_pll(&pll))
return -EINVAL;
return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0;
case RTC_PLL_SET:
if (!mach_set_rtc_pll)
return -EINVAL;
if (!capable(CAP_SYS_TIME))
return -EACCES;
if (copy_from_user(&pll, argp, sizeof(pll)))
return -EFAULT;
return mach_set_rtc_pll(&pll);
}
return -ENOIOCTLCMD;
}
static const struct rtc_class_ops generic_rtc_ops = {
.ioctl = rtc_ioctl,
.read_time = rtc_generic_get_time,
.set_time = rtc_generic_set_time,
};
static int __init rtc_init(void)
{
struct platform_device *pdev;
if (!mach_hwclk)
return -ENODEV;
pdev = platform_device_register_data(NULL, "rtc-generic", -1,
&generic_rtc_ops,
sizeof(generic_rtc_ops));
return PTR_ERR_OR_ZERO(pdev);
}
module_init(rtc_init);
#endif /* CONFIG_RTC_DRV_GENERIC */
#endif /* CONFIG_M68KCLASSIC || SUN3 */
void __init time_init(void)
{
mach_sched_init();
}
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <linux/linkage.h>
struct frame;
asmlinkage void buserr_c(struct frame *fp);
asmlinkage void fpemu_signal(int signal, int code, void *addr);
asmlinkage void fpsp040_die(void);
asmlinkage void set_esp0(unsigned long ssp);
+107
View File
@@ -0,0 +1,107 @@
/*
* uboot.c -- uboot arguments support
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/memblock.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
#include <linux/rtc.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/sections.h>
#include <asm/bootinfo.h>
/*
* parse_uboot_commandline
*
* Copies u-boot commandline arguments and store them in the proper linux
* variables.
*
* Assumes:
* _init_sp global contains the address in the stack pointer when the
* kernel starts (see head.S::_start)
*
* U-Boot calling convention:
* (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
*
* _init_sp can be parsed as such
*
* _init_sp+00 = u-boot cmd after jsr into kernel (skip)
* _init_sp+04 = &kernel board_info (residual data)
* _init_sp+08 = &initrd_start
* _init_sp+12 = &initrd_end
* _init_sp+16 = &cmd_start
* _init_sp+20 = &cmd_end
*
* This also assumes that the memory locations pointed to are still
* unmodified. U-boot places them near the end of external SDRAM.
*
* Argument(s):
* commandp = the linux commandline arg container to fill.
* size = the sizeof commandp.
*
* Returns:
*/
static void __init parse_uboot_commandline(char *commandp, int size)
{
extern unsigned long _init_sp;
unsigned long *sp;
unsigned long uboot_cmd_start, uboot_cmd_end;
#if defined(CONFIG_BLK_DEV_INITRD)
unsigned long uboot_initrd_start, uboot_initrd_end;
#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
sp = (unsigned long *)_init_sp;
uboot_cmd_start = sp[4];
uboot_cmd_end = sp[5];
if (uboot_cmd_start && uboot_cmd_end)
strscpy(commandp, (const char *)uboot_cmd_start, size);
#if defined(CONFIG_BLK_DEV_INITRD)
uboot_initrd_start = sp[2];
uboot_initrd_end = sp[3];
if (uboot_initrd_start && uboot_initrd_end &&
(uboot_initrd_end > uboot_initrd_start)) {
initrd_start = uboot_initrd_start;
initrd_end = uboot_initrd_end;
ROOT_DEV = Root_RAM0;
pr_info("initrd at 0x%lx:0x%lx\n", initrd_start, initrd_end);
}
#endif /* if defined(CONFIG_BLK_DEV_INITRD) */
}
__init void process_uboot_commandline(char *commandp, int size)
{
int len, n;
n = strnlen(commandp, size);
commandp += n;
len = size - n;
if (len) {
/* Add the whitespace separator */
*commandp++ = ' ';
len--;
}
parse_uboot_commandline(commandp, len);
commandp[len - 1] = 0;
}
+147
View File
@@ -0,0 +1,147 @@
/*
* vectors.c
*
* Copyright (C) 1993, 1994 by Hamish Macdonald
*
* 68040 fixes by Michael Rausch
* 68040 fixes by Martin Apel
* 68040 fixes and writeback by Richard Zidlicky
* 68060 fixes by Roman Hodek
* 68060 fixes by Jesper Skov
*
* 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.
*/
/*
* Sets up all exception vectors
*/
#include <linux/cpu.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/kallsyms.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/traps.h>
#include "vectors.h"
/* assembler routines */
asmlinkage void system_call(void);
asmlinkage void buserr(void);
asmlinkage void trap(void);
asmlinkage void nmihandler(void);
#ifdef CONFIG_M68KFPU_EMU
asmlinkage void fpu_emu(void);
#endif
e_vector vectors[256];
/* nmi handler for the Amiga */
asm(".text\n"
__ALIGN_STR "\n"
"nmihandler: rte");
/*
* this must be called very early as the kernel might
* use some instruction that are emulated on the 060
* and so we're prepared for early probe attempts (e.g. nf_init).
*/
void __init base_trap_init(void)
{
if (MACH_IS_SUN3X) {
extern e_vector *sun3x_prom_vbr;
__asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
}
/* setup the exception vector table */
__asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
if (CPU_IS_060) {
/* set up ISP entry points */
asmlinkage void unimp_vec(void) asm ("_060_isp_unimp");
vectors[VEC_UNIMPII] = unimp_vec;
}
vectors[VEC_BUSERR] = buserr;
vectors[VEC_ILLEGAL] = trap;
vectors[VEC_SYS] = system_call;
}
void __init trap_init (void)
{
int i;
for (i = VEC_SPUR; i <= VEC_INT7; i++)
vectors[i] = bad_inthandler;
for (i = 0; i < VEC_USER; i++)
if (!vectors[i])
vectors[i] = trap;
for (i = VEC_USER; i < 256; i++)
vectors[i] = bad_inthandler;
#ifdef CONFIG_M68KFPU_EMU
if (FPU_IS_EMU)
vectors[VEC_LINE11] = fpu_emu;
#endif
if (CPU_IS_040 && !FPU_IS_EMU) {
/* set up FPSP entry points */
asmlinkage void dz_vec(void) asm ("dz");
asmlinkage void inex_vec(void) asm ("inex");
asmlinkage void ovfl_vec(void) asm ("ovfl");
asmlinkage void unfl_vec(void) asm ("unfl");
asmlinkage void snan_vec(void) asm ("snan");
asmlinkage void operr_vec(void) asm ("operr");
asmlinkage void bsun_vec(void) asm ("bsun");
asmlinkage void fline_vec(void) asm ("fline");
asmlinkage void unsupp_vec(void) asm ("unsupp");
vectors[VEC_FPDIVZ] = dz_vec;
vectors[VEC_FPIR] = inex_vec;
vectors[VEC_FPOVER] = ovfl_vec;
vectors[VEC_FPUNDER] = unfl_vec;
vectors[VEC_FPNAN] = snan_vec;
vectors[VEC_FPOE] = operr_vec;
vectors[VEC_FPBRUC] = bsun_vec;
vectors[VEC_LINE11] = fline_vec;
vectors[VEC_FPUNSUP] = unsupp_vec;
}
if (CPU_IS_060 && !FPU_IS_EMU) {
/* set up IFPSP entry points */
asmlinkage void snan_vec6(void) asm ("_060_fpsp_snan");
asmlinkage void operr_vec6(void) asm ("_060_fpsp_operr");
asmlinkage void ovfl_vec6(void) asm ("_060_fpsp_ovfl");
asmlinkage void unfl_vec6(void) asm ("_060_fpsp_unfl");
asmlinkage void dz_vec6(void) asm ("_060_fpsp_dz");
asmlinkage void inex_vec6(void) asm ("_060_fpsp_inex");
asmlinkage void fline_vec6(void) asm ("_060_fpsp_fline");
asmlinkage void unsupp_vec6(void) asm ("_060_fpsp_unsupp");
asmlinkage void effadd_vec6(void) asm ("_060_fpsp_effadd");
vectors[VEC_FPNAN] = snan_vec6;
vectors[VEC_FPOE] = operr_vec6;
vectors[VEC_FPOVER] = ovfl_vec6;
vectors[VEC_FPUNDER] = unfl_vec6;
vectors[VEC_FPDIVZ] = dz_vec6;
vectors[VEC_FPIR] = inex_vec6;
vectors[VEC_LINE11] = fline_vec6;
vectors[VEC_FPUNSUP] = unsupp_vec6;
vectors[VEC_UNIMPEA] = effadd_vec6;
}
/* if running on an amiga, make the NMI interrupt do nothing */
if (MACH_IS_AMIGA) {
vectors[VEC_INT7] = nmihandler;
}
}
+3
View File
@@ -0,0 +1,3 @@
/* SPDX-License-Identifier: GPL-2.0-only */
void base_trap_init(void);
@@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* vmlinux.lds.S -- master linker script for m68knommu arch
*
* (C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com>
*
* This linker script is equipped to build either ROM loaded or RAM
* run kernels.
*/
#if defined(CONFIG_RAMKERNEL)
#define KTEXT_ADDR CONFIG_KERNELBASE
#endif
#if defined(CONFIG_ROMKERNEL)
#define KTEXT_ADDR CONFIG_ROMSTART
#define KDATA_ADDR CONFIG_KERNELBASE
#define LOAD_OFFSET KDATA_ADDR + (ADDR(.text) + SIZEOF(.text))
#endif
#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm-generic/vmlinux.lds.h>
OUTPUT_ARCH(m68k)
ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS {
#ifdef CONFIG_ROMVEC
. = CONFIG_ROMVEC;
.romvec : {
__rom_start = .;
_romvec = .;
*(.romvec)
*(.data..initvect)
}
#endif
. = KTEXT_ADDR;
_text = .;
_stext = .;
.text : {
HEAD_TEXT
TEXT_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
SCHED_TEXT
LOCK_TEXT
*(.fixup)
. = ALIGN(16);
}
_etext = .;
#ifdef KDATA_ADDR
. = KDATA_ADDR;
#endif
_sdata = .;
RO_DATA(PAGE_SIZE)
RW_DATA(16, PAGE_SIZE, THREAD_SIZE)
_edata = .;
EXCEPTION_TABLE(16)
. = ALIGN(PAGE_SIZE);
__init_begin = .;
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
PERCPU_SECTION(16)
.m68k_fixup : {
__start_fixup = .;
*(.m68k_fixup)
__stop_fixup = .;
}
.init.data : {
. = ALIGN(PAGE_SIZE);
__init_end = .;
}
BSS_SECTION(4, 0, 4)
_end = .;
STABS_DEBUG
MODINFO
ELF_DETAILS
/* Sections to be discarded */
DISCARDS
}
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* ld script to make m68k Linux kernel */
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
#include <asm/thread_info.h>
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS
{
. = 0x1000;
_text = .; /* Text and read-only data */
.text : {
HEAD_TEXT
TEXT_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
SCHED_TEXT
LOCK_TEXT
*(.fixup)
*(.gnu.warning)
} :text = 0x4e75
_etext = .; /* End of text section */
EXCEPTION_TABLE(16)
_sdata = .; /* Start of data section */
RO_DATA(4096)
RW_DATA(16, PAGE_SIZE, THREAD_SIZE)
BSS_SECTION(0, 0, 0)
_edata = .; /* End of data section */
/* will be freed after init */
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
INIT_TEXT_SECTION(PAGE_SIZE) :data
INIT_DATA_SECTION(16)
.m68k_fixup : {
__start_fixup = .;
*(.m68k_fixup)
__stop_fixup = .;
}
.init_end : {
/* This ALIGN be in a section so that _end is at the end of the
load segment. */
. = ALIGN(PAGE_SIZE);
__init_end = .;
}
_end = . ;
STABS_DEBUG
MODINFO
ELF_DETAILS
/* Sections to be discarded */
DISCARDS
}
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* ld script to make m68k Linux kernel */
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
#include <asm/thread_info.h>
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS
{
. = 0xE002000;
_text = .; /* Text and read-only data */
.text : {
HEAD_TEXT
TEXT_TEXT
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
SCHED_TEXT
LOCK_TEXT
*(.fixup)
*(.gnu.warning)
} :text = 0x4e75
RO_DATA(4096)
_etext = .; /* End of text section */
EXCEPTION_TABLE(16) :data
_sdata = .; /* Start of rw data section */
RW_DATA(16, PAGE_SIZE, THREAD_SIZE) :data
/* End of data goes *here* so that freeing init code works properly. */
_edata = .;
/* will be freed after init */
. = ALIGN(PAGE_SIZE); /* Init code and data */
__init_begin = .;
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
.m68k_fixup : {
__start_fixup = .;
*(.m68k_fixup)
__stop_fixup = .;
}
. = ALIGN(PAGE_SIZE);
__init_end = .;
BSS_SECTION(0, 0, 0)
_end = . ;
STABS_DEBUG
MODINFO
ELF_DETAILS
/* Sections to be discarded */
DISCARDS
}
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
PHDRS
{
text PT_LOAD FILEHDR PHDRS FLAGS (7);
data PT_LOAD FLAGS (7);
}
#ifdef CONFIG_SUN3
#include "vmlinux-sun3.lds"
#else
#include "vmlinux-std.lds"
#endif
#else
#include "vmlinux-nommu.lds"
#endif