aboutsummaryrefslogtreecommitdiffstats
path: root/arch/h8300/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/h8300/kernel
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/h8300/kernel')
-rw-r--r--arch/h8300/kernel/Makefile11
-rw-r--r--arch/h8300/kernel/asm-offsets.c65
-rw-r--r--arch/h8300/kernel/gpio.c174
-rw-r--r--arch/h8300/kernel/h8300_ksyms.c112
-rw-r--r--arch/h8300/kernel/init_task.c43
-rw-r--r--arch/h8300/kernel/ints.c255
-rw-r--r--arch/h8300/kernel/module.c122
-rw-r--r--arch/h8300/kernel/process.c288
-rw-r--r--arch/h8300/kernel/ptrace.c277
-rw-r--r--arch/h8300/kernel/semaphore.c133
-rw-r--r--arch/h8300/kernel/setup.c248
-rw-r--r--arch/h8300/kernel/signal.c552
-rw-r--r--arch/h8300/kernel/sys_h8300.c282
-rw-r--r--arch/h8300/kernel/syscalls.S340
-rw-r--r--arch/h8300/kernel/time.c134
-rw-r--r--arch/h8300/kernel/traps.c169
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S172
17 files changed, 3377 insertions, 0 deletions
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
new file mode 100644
index 000000000000..71b6131e98b8
--- /dev/null
+++ b/arch/h8300/kernel/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the linux kernel.
3#
4
5extra-y := vmlinux.lds
6
7obj-y := process.o traps.o ptrace.o ints.o \
8 sys_h8300.o time.o semaphore.o signal.o \
9 setup.o gpio.o init_task.o syscalls.o
10
11obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c
new file mode 100644
index 000000000000..b78b82ad28a3
--- /dev/null
+++ b/arch/h8300/kernel/asm-offsets.c
@@ -0,0 +1,65 @@
1/*
2 * This program is used to generate definitions needed by
3 * assembly language modules.
4 *
5 * We use the technique used in the OSF Mach kernel code:
6 * generate asm statements containing #defines,
7 * compile this file to assembler, and then extract the
8 * #defines from the assembly-language output.
9 */
10
11#include <linux/stddef.h>
12#include <linux/sched.h>
13#include <linux/kernel_stat.h>
14#include <linux/ptrace.h>
15#include <linux/hardirq.h>
16#include <asm/bootinfo.h>
17#include <asm/irq.h>
18#include <asm/ptrace.h>
19
20#define DEFINE(sym, val) \
21 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
22
23#define BLANK() asm volatile("\n->" : : )
24
25int main(void)
26{
27 /* offsets into the task struct */
28 DEFINE(TASK_STATE, offsetof(struct task_struct, state));
29 DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
30 DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
31 DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
32 DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
33 DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
34 DEFINE(TASK_MM, offsetof(struct task_struct, mm));
35 DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
36
37 /* offsets into the irq_cpustat_t struct */
38 DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
39
40 /* offsets into the thread struct */
41 DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
42 DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
43 DEFINE(THREAD_CCR, offsetof(struct thread_struct, ccr));
44
45 /* offsets into the pt_regs struct */
46 DEFINE(LER0, offsetof(struct pt_regs, er0) - sizeof(long));
47 DEFINE(LER1, offsetof(struct pt_regs, er1) - sizeof(long));
48 DEFINE(LER2, offsetof(struct pt_regs, er2) - sizeof(long));
49 DEFINE(LER3, offsetof(struct pt_regs, er3) - sizeof(long));
50 DEFINE(LER4, offsetof(struct pt_regs, er4) - sizeof(long));
51 DEFINE(LER5, offsetof(struct pt_regs, er5) - sizeof(long));
52 DEFINE(LER6, offsetof(struct pt_regs, er6) - sizeof(long));
53 DEFINE(LORIG, offsetof(struct pt_regs, orig_er0) - sizeof(long));
54 DEFINE(LCCR, offsetof(struct pt_regs, ccr) - sizeof(long));
55 DEFINE(LVEC, offsetof(struct pt_regs, vector) - sizeof(long));
56#if defined(__H8300S__)
57 DEFINE(LEXR, offsetof(struct pt_regs, exr) - sizeof(long));
58#endif
59 DEFINE(LRET, offsetof(struct pt_regs, pc) - sizeof(long));
60
61 DEFINE(PT_PTRACED, PT_PTRACED);
62 DEFINE(PT_DTRACE, PT_DTRACE);
63
64 return 0;
65}
diff --git a/arch/h8300/kernel/gpio.c b/arch/h8300/kernel/gpio.c
new file mode 100644
index 000000000000..795682b873e2
--- /dev/null
+++ b/arch/h8300/kernel/gpio.c
@@ -0,0 +1,174 @@
1/*
2 * linux/arch/h8300/kernel/gpio.c
3 *
4 * Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 */
7
8/*
9 * Internal I/O Port Management
10 */
11
12#include <linux/config.h>
13#include <linux/stddef.h>
14#include <linux/proc_fs.h>
15#include <linux/kernel.h>
16#include <linux/string.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19
20#define _(addr) (volatile unsigned char *)(addr)
21#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
22#include <asm/regs306x.h>
23static volatile unsigned char *ddrs[] = {
24 _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
25 NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
26};
27#define MAX_PORT 11
28#endif
29
30 #if defined(CONFIG_H83002) || defined(CONFIG_H8048)
31/* Fix me!! */
32#include <asm/regs306x.h>
33static volatile unsigned char *ddrs[] = {
34 _(P1DDR),_(P2DDR),_(P3DDR),_(P4DDR),_(P5DDR),_(P6DDR),
35 NULL, _(P8DDR),_(P9DDR),_(PADDR),_(PBDDR),
36};
37#define MAX_PORT 11
38#endif
39
40#if defined(CONFIG_H8S2678)
41#include <asm/regs267x.h>
42static volatile unsigned char *ddrs[] = {
43 _(P1DDR),_(P2DDR),_(P3DDR),NULL ,_(P5DDR),_(P6DDR),
44 _(P7DDR),_(P8DDR),NULL, _(PADDR),_(PBDDR),_(PCDDR),
45 _(PDDDR),_(PEDDR),_(PFDDR),_(PGDDR),_(PHDDR),
46 _(PADDR),_(PBDDR),_(PCDDR),_(PDDDR),_(PEDDR),_(PFDDR),
47 _(PGDDR),_(PHDDR)
48};
49#define MAX_PORT 17
50#endif
51#undef _
52
53#if !defined(P1DDR)
54#error Unsuppoted CPU Selection
55#endif
56
57static struct {
58 unsigned char used;
59 unsigned char ddr;
60} gpio_regs[MAX_PORT];
61
62extern char *_platform_gpio_table(int length);
63
64int h8300_reserved_gpio(int port, unsigned int bits)
65{
66 unsigned char *used;
67
68 if (port < 0 || port >= MAX_PORT)
69 return -1;
70 used = &(gpio_regs[port].used);
71 if ((*used & bits) != 0)
72 return 0;
73 *used |= bits;
74 return 1;
75}
76
77int h8300_free_gpio(int port, unsigned int bits)
78{
79 unsigned char *used;
80
81 if (port < 0 || port >= MAX_PORT)
82 return -1;
83 used = &(gpio_regs[port].used);
84 if ((*used & bits) != bits)
85 return 0;
86 *used &= (~bits);
87 return 1;
88}
89
90int h8300_set_gpio_dir(int port_bit,int dir)
91{
92 int port = (port_bit >> 8) & 0xff;
93 int bit = port_bit & 0xff;
94
95 if (ddrs[port] == NULL)
96 return 0;
97 if (gpio_regs[port].used & bit) {
98 if (dir)
99 gpio_regs[port].ddr |= bit;
100 else
101 gpio_regs[port].ddr &= ~bit;
102 *ddrs[port] = gpio_regs[port].ddr;
103 return 1;
104 } else
105 return 0;
106}
107
108int h8300_get_gpio_dir(int port_bit)
109{
110 int port = (port_bit >> 8) & 0xff;
111 int bit = port_bit & 0xff;
112
113 if (ddrs[port] == NULL)
114 return 0;
115 if (gpio_regs[port].used & bit) {
116 return (gpio_regs[port].ddr & bit) != 0;
117 } else
118 return -1;
119}
120
121#if defined(CONFIG_PROC_FS)
122static char *port_status(int portno)
123{
124 static char result[10];
125 const static char io[2]={'I','O'};
126 char *rp;
127 int c;
128 unsigned char used,ddr;
129
130 used = gpio_regs[portno].used;
131 ddr = gpio_regs[portno].ddr;
132 result[8]='\0';
133 rp = result + 7;
134 for (c = 8; c > 0; c--,rp--,used >>= 1, ddr >>= 1)
135 if (used & 0x01)
136 *rp = io[ ddr & 0x01];
137 else
138 *rp = '-';
139 return result;
140}
141
142static int gpio_proc_read(char *buf, char **start, off_t offset,
143 int len, int *unused_i, void *unused_v)
144{
145 int c,outlen;
146 const static char port_name[]="123456789ABCDEFGH";
147 outlen = 0;
148 for (c = 0; c < MAX_PORT; c++) {
149 if (ddrs[c] == NULL)
150 continue ;
151 len = sprintf(buf,"P%c: %s\n",port_name[c],port_status(c));
152 buf += len;
153 outlen += len;
154 }
155 return outlen;
156}
157
158static __init int register_proc(void)
159{
160 struct proc_dir_entry *proc_gpio;
161
162 proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
163 if (proc_gpio)
164 proc_gpio->read_proc = gpio_proc_read;
165 return proc_gpio != NULL;
166}
167
168__initcall(register_proc);
169#endif
170
171void __init h8300_gpio_init(void)
172{
173 memcpy(gpio_regs,_platform_gpio_table(sizeof(gpio_regs)),sizeof(gpio_regs));
174}
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
new file mode 100644
index 000000000000..5a630233112f
--- /dev/null
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -0,0 +1,112 @@
1#include <linux/module.h>
2#include <linux/linkage.h>
3#include <linux/sched.h>
4#include <linux/string.h>
5#include <linux/mm.h>
6#include <linux/user.h>
7#include <linux/elfcore.h>
8#include <linux/in6.h>
9#include <linux/interrupt.h>
10#include <linux/config.h>
11
12#include <asm/setup.h>
13#include <asm/pgalloc.h>
14#include <asm/irq.h>
15#include <asm/io.h>
16#include <asm/semaphore.h>
17#include <asm/checksum.h>
18#include <asm/current.h>
19#include <asm/gpio.h>
20
21//asmlinkage long long __ashrdi3 (long long, int);
22//asmlinkage long long __lshrdi3 (long long, int);
23extern char h8300_debug_device[];
24
25extern void dump_thread(struct pt_regs *, struct user *);
26
27/* platform dependent support */
28
29EXPORT_SYMBOL(dump_thread);
30EXPORT_SYMBOL(strnlen);
31EXPORT_SYMBOL(strrchr);
32EXPORT_SYMBOL(strstr);
33EXPORT_SYMBOL(strchr);
34EXPORT_SYMBOL(strcat);
35EXPORT_SYMBOL(strlen);
36EXPORT_SYMBOL(strcmp);
37EXPORT_SYMBOL(strncmp);
38
39EXPORT_SYMBOL(ip_fast_csum);
40
41EXPORT_SYMBOL(kernel_thread);
42EXPORT_SYMBOL(enable_irq);
43EXPORT_SYMBOL(disable_irq);
44
45/* Networking helper routines. */
46EXPORT_SYMBOL(csum_partial_copy);
47
48/* The following are special because they're not called
49 explicitly (the C compiler generates them). Fortunately,
50 their interface isn't gonna change any time soon now, so
51 it's OK to leave it out of version control. */
52//EXPORT_SYMBOL(__ashrdi3);
53//EXPORT_SYMBOL(__lshrdi3);
54EXPORT_SYMBOL(memcpy);
55EXPORT_SYMBOL(memset);
56EXPORT_SYMBOL(memcmp);
57EXPORT_SYMBOL(memscan);
58EXPORT_SYMBOL(memmove);
59
60EXPORT_SYMBOL(get_wchan);
61
62/*
63 * libgcc functions - functions that are used internally by the
64 * compiler... (prototypes are not correct though, but that
65 * doesn't really matter since they're not versioned).
66 */
67extern void __gcc_bcmp(void);
68extern void __ashldi3(void);
69extern void __ashrdi3(void);
70extern void __cmpdi2(void);
71extern void __divdi3(void);
72extern void __divsi3(void);
73extern void __lshrdi3(void);
74extern void __moddi3(void);
75extern void __modsi3(void);
76extern void __muldi3(void);
77extern void __mulsi3(void);
78extern void __negdi2(void);
79extern void __ucmpdi2(void);
80extern void __udivdi3(void);
81extern void __udivmoddi4(void);
82extern void __udivsi3(void);
83extern void __umoddi3(void);
84extern void __umodsi3(void);
85
86 /* gcc lib functions */
87EXPORT_SYMBOL(__gcc_bcmp);
88EXPORT_SYMBOL(__ashldi3);
89EXPORT_SYMBOL(__ashrdi3);
90EXPORT_SYMBOL(__cmpdi2);
91EXPORT_SYMBOL(__divdi3);
92EXPORT_SYMBOL(__divsi3);
93EXPORT_SYMBOL(__lshrdi3);
94EXPORT_SYMBOL(__moddi3);
95EXPORT_SYMBOL(__modsi3);
96EXPORT_SYMBOL(__muldi3);
97EXPORT_SYMBOL(__mulsi3);
98EXPORT_SYMBOL(__negdi2);
99EXPORT_SYMBOL(__ucmpdi2);
100EXPORT_SYMBOL(__udivdi3);
101EXPORT_SYMBOL(__udivmoddi4);
102EXPORT_SYMBOL(__udivsi3);
103EXPORT_SYMBOL(__umoddi3);
104EXPORT_SYMBOL(__umodsi3);
105
106#ifdef MAGIC_ROM_PTR
107EXPORT_SYMBOL(is_in_rom);
108#endif
109
110EXPORT_SYMBOL(h8300_reserved_gpio);
111EXPORT_SYMBOL(h8300_free_gpio);
112EXPORT_SYMBOL(h8300_set_gpio_dir);
diff --git a/arch/h8300/kernel/init_task.c b/arch/h8300/kernel/init_task.c
new file mode 100644
index 000000000000..19272c2ac56a
--- /dev/null
+++ b/arch/h8300/kernel/init_task.c
@@ -0,0 +1,43 @@
1/*
2 * linux/arch/h8300/kernel/init_task.c
3 */
4#include <linux/mm.h>
5#include <linux/module.h>
6#include <linux/sched.h>
7#include <linux/init.h>
8#include <linux/init_task.h>
9#include <linux/fs.h>
10#include <linux/mqueue.h>
11
12#include <asm/uaccess.h>
13#include <asm/pgtable.h>
14
15static struct fs_struct init_fs = INIT_FS;
16static struct files_struct init_files = INIT_FILES;
17static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
18static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
19struct mm_struct init_mm = INIT_MM(init_mm);
20
21EXPORT_SYMBOL(init_mm);
22
23/*
24 * Initial task structure.
25 *
26 * All other task structs will be allocated on slabs in fork.c
27 */
28__asm__(".align 4");
29struct task_struct init_task = INIT_TASK(init_task);
30
31EXPORT_SYMBOL(init_task);
32
33/*
34 * Initial thread structure.
35 *
36 * We need to make sure that this is 8192-byte aligned due to the
37 * way process stacks are handled. This is done by having a special
38 * "init_task" linker map entry..
39 */
40union thread_union init_thread_union
41 __attribute__((__section__(".data.init_task"))) =
42 { INIT_THREAD_INFO(init_task) };
43
diff --git a/arch/h8300/kernel/ints.c b/arch/h8300/kernel/ints.c
new file mode 100644
index 000000000000..edb3c4170013
--- /dev/null
+++ b/arch/h8300/kernel/ints.c
@@ -0,0 +1,255 @@
1/*
2 * linux/arch/h8300/platform/h8300h/ints.c
3 *
4 * Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 * Based on linux/arch/$(ARCH)/platform/$(PLATFORM)/ints.c
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
11 *
12 * Copyright 1996 Roman Zippel
13 * Copyright 1999 D. Jeff Dionne <jeff@rt-control.com>
14 */
15
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/kernel_stat.h>
21#include <linux/seq_file.h>
22#include <linux/init.h>
23#include <linux/random.h>
24#include <linux/bootmem.h>
25#include <linux/hardirq.h>
26
27#include <asm/system.h>
28#include <asm/irq.h>
29#include <asm/traps.h>
30#include <asm/io.h>
31#include <asm/setup.h>
32#include <asm/errno.h>
33
34/*
35 * This structure has only 4 elements for speed reasons
36 */
37typedef struct irq_handler {
38 irqreturn_t (*handler)(int, void *, struct pt_regs *);
39 int flags;
40 int count;
41 void *dev_id;
42 const char *devname;
43} irq_handler_t;
44
45static irq_handler_t *irq_list[NR_IRQS];
46static int use_kmalloc;
47
48extern unsigned long *interrupt_redirect_table;
49extern const int h8300_saved_vectors[];
50extern const unsigned long h8300_trap_table[];
51int h8300_enable_irq_pin(unsigned int irq);
52void h8300_disable_irq_pin(unsigned int irq);
53
54#define CPU_VECTOR ((unsigned long *)0x000000)
55#define ADDR_MASK (0xffffff)
56
57#if defined(CONFIG_RAMKERNEL)
58static unsigned long __init *get_vector_address(void)
59{
60 unsigned long *rom_vector = CPU_VECTOR;
61 unsigned long base,tmp;
62 int vec_no;
63
64 base = rom_vector[EXT_IRQ0] & ADDR_MASK;
65
66 /* check romvector format */
67 for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) {
68 if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK))
69 return NULL;
70 }
71
72 /* ramvector base address */
73 base -= EXT_IRQ0*4;
74
75 /* writerble check */
76 tmp = ~(*(volatile unsigned long *)base);
77 (*(volatile unsigned long *)base) = tmp;
78 if ((*(volatile unsigned long *)base) != tmp)
79 return NULL;
80 return (unsigned long *)base;
81}
82#endif
83
84void __init init_IRQ(void)
85{
86#if defined(CONFIG_RAMKERNEL)
87 int i;
88 unsigned long *ramvec,*ramvec_p;
89 const unsigned long *trap_entry;
90 const int *saved_vector;
91
92 ramvec = get_vector_address();
93 if (ramvec == NULL)
94 panic("interrupt vector serup failed.");
95 else
96 printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec);
97
98 /* create redirect table */
99 ramvec_p = ramvec;
100 trap_entry = h8300_trap_table;
101 saved_vector = h8300_saved_vectors;
102 for ( i = 0; i < NR_IRQS; i++) {
103 if (i == *saved_vector) {
104 ramvec_p++;
105 saved_vector++;
106 } else {
107 if ( i < NR_TRAPS ) {
108 if (*trap_entry)
109 *ramvec_p = VECTOR(*trap_entry);
110 ramvec_p++;
111 trap_entry++;
112 } else
113 *ramvec_p++ = REDIRECT(interrupt_entry);
114 }
115 }
116 interrupt_redirect_table = ramvec;
117#ifdef DUMP_VECTOR
118 ramvec_p = ramvec;
119 for (i = 0; i < NR_IRQS; i++) {
120 if ((i % 8) == 0)
121 printk(KERN_DEBUG "\n%p: ",ramvec_p);
122 printk(KERN_DEBUG "%p ",*ramvec_p);
123 ramvec_p++;
124 }
125 printk(KERN_DEBUG "\n");
126#endif
127#endif
128}
129
130int request_irq(unsigned int irq,
131 irqreturn_t (*handler)(int, void *, struct pt_regs *),
132 unsigned long flags, const char *devname, void *dev_id)
133{
134 irq_handler_t *irq_handle;
135 if (irq < 0 || irq >= NR_IRQS) {
136 printk(KERN_ERR "Incorrect IRQ %d from %s\n", irq, devname);
137 return -EINVAL;
138 }
139
140 if (irq_list[irq] || (h8300_enable_irq_pin(irq) == -EBUSY))
141 return -EBUSY;
142
143 if (use_kmalloc)
144 irq_handle = (irq_handler_t *)kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
145 else {
146 /* use bootmem allocater */
147 irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
148 irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
149 }
150
151 if (irq_handle == NULL)
152 return -ENOMEM;
153
154 irq_handle->handler = handler;
155 irq_handle->flags = flags;
156 irq_handle->count = 0;
157 irq_handle->dev_id = dev_id;
158 irq_handle->devname = devname;
159 irq_list[irq] = irq_handle;
160
161 if (irq_handle->flags & SA_SAMPLE_RANDOM)
162 rand_initialize_irq(irq);
163
164 enable_irq(irq);
165 return 0;
166}
167
168EXPORT_SYMBOL(request_irq);
169
170void free_irq(unsigned int irq, void *dev_id)
171{
172 if (irq >= NR_IRQS)
173 return;
174
175 if (!irq_list[irq] || irq_list[irq]->dev_id != dev_id)
176 printk(KERN_WARNING "Removing probably wrong IRQ %d from %s\n",
177 irq, irq_list[irq]->devname);
178 disable_irq(irq);
179 h8300_disable_irq_pin(irq);
180 if (((unsigned long)irq_list[irq] & 0x80000000) == 0) {
181 kfree(irq_list[irq]);
182 irq_list[irq] = NULL;
183 }
184}
185
186EXPORT_SYMBOL(free_irq);
187
188/*
189 * Do we need these probe functions on the m68k?
190 */
191unsigned long probe_irq_on (void)
192{
193 return 0;
194}
195
196EXPORT_SYMBOL(probe_irq_on);
197
198int probe_irq_off (unsigned long irqs)
199{
200 return 0;
201}
202
203EXPORT_SYMBOL(probe_irq_off);
204
205void enable_irq(unsigned int irq)
206{
207 if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
208 IER_REGS |= 1 << (irq - EXT_IRQ0);
209}
210
211void disable_irq(unsigned int irq)
212{
213 if (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS))
214 IER_REGS &= ~(1 << (irq - EXT_IRQ0));
215}
216
217asmlinkage void process_int(int irq, struct pt_regs *fp)
218{
219 irq_enter();
220 h8300_clear_isr(irq);
221 if (irq >= NR_TRAPS && irq < NR_IRQS) {
222 if (irq_list[irq]) {
223 irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp);
224 irq_list[irq]->count++;
225 if (irq_list[irq]->flags & SA_SAMPLE_RANDOM)
226 add_interrupt_randomness(irq);
227 }
228 } else {
229 BUG();
230 }
231 irq_exit();
232}
233
234int show_interrupts(struct seq_file *p, void *v)
235{
236 int i = *(loff_t *) v;
237
238 if ((i < NR_IRQS) && (irq_list[i]!=NULL)) {
239 seq_printf(p, "%3d: %10u ",i,irq_list[i]->count);
240 seq_printf(p, "%s\n", irq_list[i]->devname);
241 }
242
243 return 0;
244}
245
246void init_irq_proc(void)
247{
248}
249
250static int __init enable_kmalloc(void)
251{
252 use_kmalloc = 1;
253 return 0;
254}
255core_initcall(enable_kmalloc);
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
new file mode 100644
index 000000000000..4fd7138a6e03
--- /dev/null
+++ b/arch/h8300/kernel/module.c
@@ -0,0 +1,122 @@
1#include <linux/moduleloader.h>
2#include <linux/elf.h>
3#include <linux/vmalloc.h>
4#include <linux/fs.h>
5#include <linux/string.h>
6#include <linux/kernel.h>
7
8#if 0
9#define DEBUGP printk
10#else
11#define DEBUGP(fmt...)
12#endif
13
14void *module_alloc(unsigned long size)
15{
16 if (size == 0)
17 return NULL;
18 return vmalloc(size);
19}
20
21
22/* Free memory returned from module_alloc */
23void module_free(struct module *mod, void *module_region)
24{
25 vfree(module_region);
26 /* FIXME: If module_region == mod->init_region, trim exception
27 table entries. */
28}
29
30/* We don't need anything special. */
31int module_frob_arch_sections(Elf_Ehdr *hdr,
32 Elf_Shdr *sechdrs,
33 char *secstrings,
34 struct module *mod)
35{
36 return 0;
37}
38
39int apply_relocate(Elf32_Shdr *sechdrs,
40 const char *strtab,
41 unsigned int symindex,
42 unsigned int relsec,
43 struct module *me)
44{
45 printk(KERN_ERR "module %s: RELOCATION unsupported\n",
46 me->name);
47 return -ENOEXEC;
48}
49
50int apply_relocate_add(Elf32_Shdr *sechdrs,
51 const char *strtab,
52 unsigned int symindex,
53 unsigned int relsec,
54 struct module *me)
55{
56 unsigned int i;
57 Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
58
59 DEBUGP("Applying relocate section %u to %u\n", relsec,
60 sechdrs[relsec].sh_info);
61 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
62 /* This is where to make the change */
63 uint32_t *loc = (uint32_t *)(sechdrs[sechdrs[relsec].sh_info].sh_addr
64 + rela[i].r_offset);
65 /* This is the symbol it is referring to. Note that all
66 undefined symbols have been resolved. */
67 Elf32_Sym *sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
68 + ELF32_R_SYM(rela[i].r_info);
69 uint32_t v = sym->st_value + rela[i].r_addend;
70
71 switch (ELF32_R_TYPE(rela[i].r_info)) {
72 case R_H8_DIR24R8:
73 loc = (uint32_t *)((uint32_t)loc - 1);
74 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v);
75 break;
76 case R_H8_DIR24A8:
77 if (ELF32_R_SYM(rela[i].r_info))
78 *loc += v;
79 break;
80 case R_H8_DIR32:
81 case R_H8_DIR32A16:
82 *loc += v;
83 break;
84 case R_H8_PCREL16:
85 v -= (unsigned long)loc + 2;
86 if ((Elf32_Sword)v > 0x7fff ||
87 (Elf32_Sword)v < -(Elf32_Sword)0x8000)
88 goto overflow;
89 else
90 *(unsigned short *)loc = v;
91 break;
92 case R_H8_PCREL8:
93 v -= (unsigned long)loc + 1;
94 if ((Elf32_Sword)v > 0x7f ||
95 (Elf32_Sword)v < -(Elf32_Sword)0x80)
96 goto overflow;
97 else
98 *(unsigned char *)loc = v;
99 break;
100 default:
101 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
102 me->name, ELF32_R_TYPE(rela[i].r_info));
103 return -ENOEXEC;
104 }
105 }
106 return 0;
107 overflow:
108 printk(KERN_ERR "module %s: relocation offset overflow: %08x\n",
109 me->name, rela[i].r_offset);
110 return -ENOEXEC;
111}
112
113int module_finalize(const Elf_Ehdr *hdr,
114 const Elf_Shdr *sechdrs,
115 struct module *me)
116{
117 return 0;
118}
119
120void module_arch_cleanup(struct module *mod)
121{
122}
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
new file mode 100644
index 000000000000..134aec1c6d19
--- /dev/null
+++ b/arch/h8300/kernel/process.c
@@ -0,0 +1,288 @@
1/*
2 * linux/arch/h8300/kernel/process.c
3 *
4 * Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 * Based on:
7 *
8 * linux/arch/m68knommu/kernel/process.c
9 *
10 * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
11 * Kenneth Albanowski <kjahds@kjahds.com>,
12 * The Silver Hammer Group, Ltd.
13 *
14 * linux/arch/m68k/kernel/process.c
15 *
16 * Copyright (C) 1995 Hamish Macdonald
17 *
18 * 68060 fixes by Jesper Skov
19 */
20
21/*
22 * This file handles the architecture-dependent parts of process handling..
23 */
24
25#include <linux/config.h>
26#include <linux/errno.h>
27#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/kernel.h>
30#include <linux/mm.h>
31#include <linux/smp.h>
32#include <linux/smp_lock.h>
33#include <linux/stddef.h>
34#include <linux/unistd.h>
35#include <linux/ptrace.h>
36#include <linux/slab.h>
37#include <linux/user.h>
38#include <linux/a.out.h>
39#include <linux/interrupt.h>
40#include <linux/reboot.h>
41
42#include <asm/uaccess.h>
43#include <asm/system.h>
44#include <asm/traps.h>
45#include <asm/setup.h>
46#include <asm/pgtable.h>
47
48asmlinkage void ret_from_fork(void);
49
50/*
51 * The idle loop on an H8/300..
52 */
53#if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
54void default_idle(void)
55{
56 while(1) {
57 if (need_resched()) {
58 local_irq_enable();
59 __asm__("sleep");
60 local_irq_disable();
61 }
62 schedule();
63 }
64}
65#else
66void default_idle(void)
67{
68 while(1) {
69 if (need_resched())
70 schedule();
71 }
72}
73#endif
74void (*idle)(void) = default_idle;
75
76/*
77 * The idle thread. There's no useful work to be
78 * done, so just try to conserve power and have a
79 * low exit latency (ie sit in a loop waiting for
80 * somebody to say that they'd like to reschedule)
81 */
82void cpu_idle(void)
83{
84 idle();
85}
86
87void machine_restart(char * __unused)
88{
89 local_irq_disable();
90 __asm__("jmp @@0");
91}
92
93EXPORT_SYMBOL(machine_restart);
94
95void machine_halt(void)
96{
97 local_irq_disable();
98 __asm__("sleep");
99 for (;;);
100}
101
102EXPORT_SYMBOL(machine_halt);
103
104void machine_power_off(void)
105{
106 local_irq_disable();
107 __asm__("sleep");
108 for (;;);
109}
110
111EXPORT_SYMBOL(machine_power_off);
112
113void show_regs(struct pt_regs * regs)
114{
115 printk("\nPC: %08lx Status: %02x",
116 regs->pc, regs->ccr);
117 printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx",
118 regs->orig_er0, regs->er0, regs->er1);
119 printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx",
120 regs->er2, regs->er3, regs->er4, regs->er5);
121 printk("\nER6' %08lx ",regs->er6);
122 if (user_mode(regs))
123 printk("USP: %08lx\n", rdusp());
124 else
125 printk("\n");
126}
127
128/*
129 * Create a kernel thread
130 */
131int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
132{
133 long retval;
134 long clone_arg;
135 mm_segment_t fs;
136
137 fs = get_fs();
138 set_fs (KERNEL_DS);
139 clone_arg = flags | CLONE_VM;
140 __asm__("mov.l sp,er3\n\t"
141 "sub.l er2,er2\n\t"
142 "mov.l %2,er1\n\t"
143 "mov.l %1,er0\n\t"
144 "trapa #0\n\t"
145 "cmp.l sp,er3\n\t"
146 "beq 1f\n\t"
147 "mov.l %4,er0\n\t"
148 "mov.l %3,er1\n\t"
149 "jsr @er1\n\t"
150 "mov.l %5,er0\n\t"
151 "trapa #0\n"
152 "1:\n\t"
153 "mov.l er0,%0"
154 :"=r"(retval)
155 :"i"(__NR_clone),"g"(clone_arg),"g"(fn),"g"(arg),"i"(__NR_exit)
156 :"er0","er1","er2","er3");
157 set_fs (fs);
158 return retval;
159}
160
161void flush_thread(void)
162{
163}
164
165/*
166 * "h8300_fork()".. By the time we get here, the
167 * non-volatile registers have also been saved on the
168 * stack. We do some ugly pointer stuff here.. (see
169 * also copy_thread)
170 */
171
172asmlinkage int h8300_fork(struct pt_regs *regs)
173{
174 return -EINVAL;
175}
176
177asmlinkage int h8300_vfork(struct pt_regs *regs)
178{
179 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
180}
181
182asmlinkage int h8300_clone(struct pt_regs *regs)
183{
184 unsigned long clone_flags;
185 unsigned long newsp;
186
187 /* syscall2 puts clone_flags in er1 and usp in er2 */
188 clone_flags = regs->er1;
189 newsp = regs->er2;
190 if (!newsp)
191 newsp = rdusp();
192 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
193
194}
195
196int copy_thread(int nr, unsigned long clone_flags,
197 unsigned long usp, unsigned long topstk,
198 struct task_struct * p, struct pt_regs * regs)
199{
200 struct pt_regs * childregs;
201
202 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
203
204 *childregs = *regs;
205 childregs->retpc = (unsigned long) ret_from_fork;
206 childregs->er0 = 0;
207
208 p->thread.usp = usp;
209 p->thread.ksp = (unsigned long)childregs;
210
211 return 0;
212}
213
214/*
215 * fill in the user structure for a core dump..
216 */
217void dump_thread(struct pt_regs * regs, struct user * dump)
218{
219/* changed the size calculations - should hopefully work better. lbt */
220 dump->magic = CMAGIC;
221 dump->start_code = 0;
222 dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
223 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
224 dump->u_dsize = ((unsigned long) (current->mm->brk +
225 (PAGE_SIZE-1))) >> PAGE_SHIFT;
226 dump->u_dsize -= dump->u_tsize;
227 dump->u_ssize = 0;
228
229 dump->u_ar0 = (struct user_regs_struct *)(((int)(&dump->regs)) -((int)(dump)));
230 dump->regs.er0 = regs->er0;
231 dump->regs.er1 = regs->er1;
232 dump->regs.er2 = regs->er2;
233 dump->regs.er3 = regs->er3;
234 dump->regs.er4 = regs->er4;
235 dump->regs.er5 = regs->er5;
236 dump->regs.er6 = regs->er6;
237 dump->regs.orig_er0 = regs->orig_er0;
238 dump->regs.ccr = regs->ccr;
239 dump->regs.pc = regs->pc;
240}
241
242/*
243 * sys_execve() executes a new program.
244 */
245asmlinkage int sys_execve(char *name, char **argv, char **envp,int dummy,...)
246{
247 int error;
248 char * filename;
249 struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
250
251 lock_kernel();
252 filename = getname(name);
253 error = PTR_ERR(filename);
254 if (IS_ERR(filename))
255 goto out;
256 error = do_execve(filename, argv, envp, regs);
257 putname(filename);
258out:
259 unlock_kernel();
260 return error;
261}
262
263unsigned long thread_saved_pc(struct task_struct *tsk)
264{
265 return ((struct pt_regs *)tsk->thread.esp0)->pc;
266}
267
268unsigned long get_wchan(struct task_struct *p)
269{
270 unsigned long fp, pc;
271 unsigned long stack_page;
272 int count = 0;
273 if (!p || p == current || p->state == TASK_RUNNING)
274 return 0;
275
276 stack_page = (unsigned long)p;
277 fp = ((struct pt_regs *)p->thread.ksp)->er6;
278 do {
279 if (fp < stack_page+sizeof(struct thread_info) ||
280 fp >= 8184+stack_page)
281 return 0;
282 pc = ((unsigned long *)fp)[1];
283 if (!in_sched_functions(pc))
284 return pc;
285 fp = *(unsigned long *) fp;
286 } while (count++ < 16);
287 return 0;
288}
diff --git a/arch/h8300/kernel/ptrace.c b/arch/h8300/kernel/ptrace.c
new file mode 100644
index 000000000000..5f19d774a288
--- /dev/null
+++ b/arch/h8300/kernel/ptrace.c
@@ -0,0 +1,277 @@
1/*
2 * linux/arch/h8300/kernel/ptrace.c
3 *
4 * Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 * Based on:
7 * linux/arch/m68k/kernel/ptrace.c
8 *
9 * Copyright (C) 1994 by Hamish Macdonald
10 * Taken from linux/kernel/ptrace.c and modified for M680x0.
11 * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
12 *
13 * This file is subject to the terms and conditions of the GNU General
14 * Public License. See the file COPYING in the main directory of
15 * this archive for more details.
16 */
17
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/mm.h>
21#include <linux/smp.h>
22#include <linux/smp_lock.h>
23#include <linux/errno.h>
24#include <linux/ptrace.h>
25#include <linux/user.h>
26#include <linux/config.h>
27
28#include <asm/uaccess.h>
29#include <asm/page.h>
30#include <asm/pgtable.h>
31#include <asm/system.h>
32#include <asm/processor.h>
33#include <asm/signal.h>
34
35/* cpu depend functions */
36extern long h8300_get_reg(struct task_struct *task, int regno);
37extern int h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
38extern void h8300_disable_trace(struct task_struct *child);
39extern void h8300_enable_trace(struct task_struct *child);
40
41/*
42 * does not yet catch signals sent when the child dies.
43 * in exit.c or in signal.c.
44 */
45
46inline
47static int read_long(struct task_struct * tsk, unsigned long addr,
48 unsigned long * result)
49{
50 *result = *(unsigned long *)addr;
51 return 0;
52}
53
54void ptrace_disable(struct task_struct *child)
55{
56 h8300_disable_trace(child);
57}
58
59asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
60{
61 struct task_struct *child;
62 int ret;
63
64 lock_kernel();
65 ret = -EPERM;
66 if (request == PTRACE_TRACEME) {
67 /* are we already being traced? */
68 if (current->ptrace & PT_PTRACED)
69 goto out;
70 /* set the ptrace bit in the process flags. */
71 current->ptrace |= PT_PTRACED;
72 ret = 0;
73 goto out;
74 }
75 ret = -ESRCH;
76 read_lock(&tasklist_lock);
77 child = find_task_by_pid(pid);
78 if (child)
79 get_task_struct(child);
80 read_unlock(&tasklist_lock);
81 if (!child)
82 goto out;
83
84 ret = -EPERM;
85 if (pid == 1) /* you may not mess with init */
86 goto out_tsk;
87
88 if (request == PTRACE_ATTACH) {
89 ret = ptrace_attach(child);
90 goto out_tsk;
91 }
92 ret = ptrace_check_attach(child, request == PTRACE_KILL);
93 if (ret < 0)
94 goto out_tsk;
95
96 switch (request) {
97 case PTRACE_PEEKTEXT: /* read word at location addr. */
98 case PTRACE_PEEKDATA: {
99 unsigned long tmp;
100
101 ret = read_long(child, addr, &tmp);
102 if (ret < 0)
103 break ;
104 ret = put_user(tmp, (unsigned long *) data);
105 break ;
106 }
107
108 /* read the word at location addr in the USER area. */
109 case PTRACE_PEEKUSR: {
110 unsigned long tmp = 0;
111
112 if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
113 ret = -EIO;
114 break ;
115 }
116
117 ret = 0; /* Default return condition */
118 addr = addr >> 2; /* temporary hack. */
119
120 if (addr < H8300_REGS_NO)
121 tmp = h8300_get_reg(child, addr);
122 else {
123 switch(addr) {
124 case 49:
125 tmp = child->mm->start_code;
126 break ;
127 case 50:
128 tmp = child->mm->start_data;
129 break ;
130 case 51:
131 tmp = child->mm->end_code;
132 break ;
133 case 52:
134 tmp = child->mm->end_data;
135 break ;
136 default:
137 ret = -EIO;
138 }
139 }
140 if (!ret)
141 ret = put_user(tmp,(unsigned long *) data);
142 break ;
143 }
144
145 /* when I and D space are separate, this will have to be fixed. */
146 case PTRACE_POKETEXT: /* write the word at location addr. */
147 case PTRACE_POKEDATA:
148 ret = 0;
149 if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
150 break;
151 ret = -EIO;
152 break;
153
154 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
155 if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) {
156 ret = -EIO;
157 break ;
158 }
159 addr = addr >> 2; /* temporary hack. */
160
161 if (addr == PT_ORIG_ER0) {
162 ret = -EIO;
163 break ;
164 }
165 if (addr < H8300_REGS_NO) {
166 ret = h8300_put_reg(child, addr, data);
167 break ;
168 }
169 ret = -EIO;
170 break ;
171 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
172 case PTRACE_CONT: { /* restart after signal. */
173 ret = -EIO;
174 if ((unsigned long) data >= _NSIG)
175 break ;
176 if (request == PTRACE_SYSCALL)
177 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
178 else
179 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
180 child->exit_code = data;
181 wake_up_process(child);
182 /* make sure the single step bit is not set. */
183 h8300_disable_trace(child);
184 ret = 0;
185 }
186
187/*
188 * make the child exit. Best I can do is send it a sigkill.
189 * perhaps it should be put in the status that it wants to
190 * exit.
191 */
192 case PTRACE_KILL: {
193
194 ret = 0;
195 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
196 break;
197 child->exit_code = SIGKILL;
198 h8300_disable_trace(child);
199 wake_up_process(child);
200 break;
201 }
202
203 case PTRACE_SINGLESTEP: { /* set the trap flag. */
204 ret = -EIO;
205 if ((unsigned long) data > _NSIG)
206 break;
207 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
208 child->exit_code = data;
209 h8300_enable_trace(child);
210 wake_up_process(child);
211 ret = 0;
212 break;
213 }
214
215 case PTRACE_DETACH: /* detach a process that was attached. */
216 ret = ptrace_detach(child, data);
217 break;
218
219 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
220 int i;
221 unsigned long tmp;
222 for (i = 0; i < H8300_REGS_NO; i++) {
223 tmp = h8300_get_reg(child, i);
224 if (put_user(tmp, (unsigned long *) data)) {
225 ret = -EFAULT;
226 break;
227 }
228 data += sizeof(long);
229 }
230 ret = 0;
231 break;
232 }
233
234 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
235 int i;
236 unsigned long tmp;
237 for (i = 0; i < H8300_REGS_NO; i++) {
238 if (get_user(tmp, (unsigned long *) data)) {
239 ret = -EFAULT;
240 break;
241 }
242 h8300_put_reg(child, i, tmp);
243 data += sizeof(long);
244 }
245 ret = 0;
246 break;
247 }
248
249 default:
250 ret = -EIO;
251 break;
252 }
253out_tsk:
254 put_task_struct(child);
255out:
256 unlock_kernel();
257 return ret;
258}
259
260asmlinkage void syscall_trace(void)
261{
262 if (!test_thread_flag(TIF_SYSCALL_TRACE))
263 return;
264 if (!(current->ptrace & PT_PTRACED))
265 return;
266 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
267 ? 0x80 : 0));
268 /*
269 * this isn't the same as continuing with a signal, but it will do
270 * for normal use. strace only continues with a signal if the
271 * stopping signal is not SIGTRAP. -brl
272 */
273 if (current->exit_code) {
274 send_sig(current->exit_code, current, 1);
275 current->exit_code = 0;
276 }
277}
diff --git a/arch/h8300/kernel/semaphore.c b/arch/h8300/kernel/semaphore.c
new file mode 100644
index 000000000000..1ebb79baaa8c
--- /dev/null
+++ b/arch/h8300/kernel/semaphore.c
@@ -0,0 +1,133 @@
1/*
2 * Generic semaphore code. Buyer beware. Do your own
3 * specific changes in <asm/semaphore-helper.h>
4 */
5
6#include <linux/config.h>
7#include <linux/sched.h>
8#include <linux/init.h>
9#include <asm/semaphore-helper.h>
10
11#ifndef CONFIG_RMW_INSNS
12spinlock_t semaphore_wake_lock;
13#endif
14
15/*
16 * Semaphores are implemented using a two-way counter:
17 * The "count" variable is decremented for each process
18 * that tries to sleep, while the "waking" variable is
19 * incremented when the "up()" code goes to wake up waiting
20 * processes.
21 *
22 * Notably, the inline "up()" and "down()" functions can
23 * efficiently test if they need to do any extra work (up
24 * needs to do something only if count was negative before
25 * the increment operation.
26 *
27 * waking_non_zero() (from asm/semaphore.h) must execute
28 * atomically.
29 *
30 * When __up() is called, the count was negative before
31 * incrementing it, and we need to wake up somebody.
32 *
33 * This routine adds one to the count of processes that need to
34 * wake up and exit. ALL waiting processes actually wake up but
35 * only the one that gets to the "waking" field first will gate
36 * through and acquire the semaphore. The others will go back
37 * to sleep.
38 *
39 * Note that these functions are only called when there is
40 * contention on the lock, and as such all this is the
41 * "non-critical" part of the whole semaphore business. The
42 * critical part is the inline stuff in <asm/semaphore.h>
43 * where we want to avoid any extra jumps and calls.
44 */
45void __up(struct semaphore *sem)
46{
47 wake_one_more(sem);
48 wake_up(&sem->wait);
49}
50
51/*
52 * Perform the "down" function. Return zero for semaphore acquired,
53 * return negative for signalled out of the function.
54 *
55 * If called from __down, the return is ignored and the wait loop is
56 * not interruptible. This means that a task waiting on a semaphore
57 * using "down()" cannot be killed until someone does an "up()" on
58 * the semaphore.
59 *
60 * If called from __down_interruptible, the return value gets checked
61 * upon return. If the return value is negative then the task continues
62 * with the negative value in the return register (it can be tested by
63 * the caller).
64 *
65 * Either form may be used in conjunction with "up()".
66 *
67 */
68
69
70#define DOWN_HEAD(task_state) \
71 \
72 \
73 current->state = (task_state); \
74 add_wait_queue(&sem->wait, &wait); \
75 \
76 /* \
77 * Ok, we're set up. sem->count is known to be less than zero \
78 * so we must wait. \
79 * \
80 * We can let go the lock for purposes of waiting. \
81 * We re-acquire it after awaking so as to protect \
82 * all semaphore operations. \
83 * \
84 * If "up()" is called before we call waking_non_zero() then \
85 * we will catch it right away. If it is called later then \
86 * we will have to go through a wakeup cycle to catch it. \
87 * \
88 * Multiple waiters contend for the semaphore lock to see \
89 * who gets to gate through and who has to wait some more. \
90 */ \
91 for (;;) {
92
93#define DOWN_TAIL(task_state) \
94 current->state = (task_state); \
95 } \
96 current->state = TASK_RUNNING; \
97 remove_wait_queue(&sem->wait, &wait);
98
99void __sched __down(struct semaphore * sem)
100{
101 DECLARE_WAITQUEUE(wait, current);
102
103 DOWN_HEAD(TASK_UNINTERRUPTIBLE)
104 if (waking_non_zero(sem))
105 break;
106 schedule();
107 DOWN_TAIL(TASK_UNINTERRUPTIBLE)
108}
109
110int __sched __down_interruptible(struct semaphore * sem)
111{
112 DECLARE_WAITQUEUE(wait, current);
113 int ret = 0;
114
115 DOWN_HEAD(TASK_INTERRUPTIBLE)
116
117 ret = waking_non_zero_interruptible(sem, current);
118 if (ret)
119 {
120 if (ret == 1)
121 /* ret != 0 only if we get interrupted -arca */
122 ret = 0;
123 break;
124 }
125 schedule();
126 DOWN_TAIL(TASK_INTERRUPTIBLE)
127 return ret;
128}
129
130int __down_trylock(struct semaphore * sem)
131{
132 return waking_non_zero_trylock(sem);
133}
diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c
new file mode 100644
index 000000000000..f469d9160730
--- /dev/null
+++ b/arch/h8300/kernel/setup.c
@@ -0,0 +1,248 @@
1/*
2 * linux/arch/h8300/kernel/setup.c
3 *
4 * Copyleft ()) 2000 James D. Schettine {james@telos-systems.com}
5 * Copyright (C) 1999,2000 Greg Ungerer (gerg@snapgear.com)
6 * Copyright (C) 1998,1999 D. Jeff Dionne <jeff@lineo.ca>
7 * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>
8 * Copyright (C) 1995 Hamish Macdonald
9 * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
10 * Copyright (C) 2001 Lineo, Inc. <www.lineo.com>
11 *
12 * H8/300 porting Yoshinori Sato <ysato@users.sourceforge.jp>
13 */
14
15/*
16 * This file handles the architecture-dependent parts of system setup
17 */
18
19#include <linux/config.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/delay.h>
23#include <linux/interrupt.h>
24#include <linux/fs.h>
25#include <linux/fb.h>
26#include <linux/console.h>
27#include <linux/genhd.h>
28#include <linux/errno.h>
29#include <linux/string.h>
30#include <linux/major.h>
31#include <linux/bootmem.h>
32#include <linux/seq_file.h>
33#include <linux/init.h>
34
35#include <asm/setup.h>
36#include <asm/irq.h>
37
38#ifdef CONFIG_BLK_DEV_INITRD
39#include <asm/pgtable.h>
40#endif
41
42#if defined(__H8300H__)
43#define CPU "H8/300H"
44#include <asm/regs306x.h>
45#endif
46
47#if defined(__H8300S__)
48#define CPU "H8S"
49#include <asm/regs267x.h>
50#endif
51
52#define STUBSIZE 0xc000;
53
54unsigned long rom_length;
55unsigned long memory_start;
56unsigned long memory_end;
57
58char command_line[COMMAND_LINE_SIZE];
59
60extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
61extern int _ramstart, _ramend;
62extern char _target_name[];
63extern void h8300_gpio_init(void);
64
65#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) \
66 && defined(CONFIG_GDB_MAGICPRINT)
67/* printk with gdb service */
68static void gdb_console_output(struct console *c, const char *msg, unsigned len)
69{
70 for (; len > 0; len--) {
71 asm("mov.w %0,r2\n\t"
72 "jsr @0xc4"::"r"(*msg++):"er2");
73 }
74}
75
76/*
77 * Setup initial baud/bits/parity. We do two things here:
78 * - construct a cflag setting for the first rs_open()
79 * - initialize the serial port
80 * Return non-zero if we didn't find a serial port.
81 */
82static int __init gdb_console_setup(struct console *co, char *options)
83{
84 return 0;
85}
86
87static const struct console gdb_console = {
88 .name = "gdb_con",
89 .write = gdb_console_output,
90 .device = NULL,
91 .setup = gdb_console_setup,
92 .flags = CON_PRINTBUFFER,
93 .index = -1,
94};
95#endif
96
97void __init setup_arch(char **cmdline_p)
98{
99 int bootmap_size;
100
101 memory_start = (unsigned long) &_ramstart;
102
103 /* allow for ROMFS on the end of the kernel */
104 if (memcmp((void *)memory_start, "-rom1fs-", 8) == 0) {
105#if defined(CONFIG_BLK_DEV_INITRD)
106 initrd_start = memory_start;
107 initrd_end = memory_start += be32_to_cpu(((unsigned long *) (memory_start))[2]);
108#else
109 memory_start += be32_to_cpu(((unsigned long *) memory_start)[2]);
110#endif
111 }
112 memory_start = PAGE_ALIGN(memory_start);
113#if !defined(CONFIG_BLKDEV_RESERVE)
114 memory_end = (unsigned long) &_ramend; /* by now the stack is part of the init task */
115#if defined(CONFIG_GDB_DEBUG)
116 memory_end -= STUBSIZE;
117#endif
118#else
119 if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) &&
120 (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)
121 /* overlap userarea */
122 memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS;
123#endif
124
125 init_mm.start_code = (unsigned long) &_stext;
126 init_mm.end_code = (unsigned long) &_etext;
127 init_mm.end_data = (unsigned long) &_edata;
128 init_mm.brk = (unsigned long) 0;
129
130#if (defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)) && defined(CONFIG_GDB_MAGICPRINT)
131 register_console((struct console *)&gdb_console);
132#endif
133
134 printk(KERN_INFO "\r\n\nuClinux " CPU "\n");
135 printk(KERN_INFO "Target Hardware: %s\n",_target_name);
136 printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
137 printk(KERN_INFO "H8/300 series support by Yoshinori Sato <ysato@users.sourceforge.jp>\n");
138
139#ifdef DEBUG
140 printk(KERN_DEBUG "KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
141 "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
142 (int) &_sdata, (int) &_edata,
143 (int) &_sbss, (int) &_ebss);
144 printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
145 "STACK=0x%06x-0x%06x\n",
146 (int) &_ebss, (int) memory_start,
147 (int) memory_start, (int) memory_end,
148 (int) memory_end, (int) &_ramend);
149#endif
150
151#ifdef CONFIG_DEFAULT_CMDLINE
152 /* set from default command line */
153 if (*command_line == '\0')
154 strcpy(command_line,CONFIG_KERNEL_COMMAND);
155#endif
156 /* Keep a copy of command line */
157 *cmdline_p = &command_line[0];
158 memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
159 saved_command_line[COMMAND_LINE_SIZE-1] = 0;
160
161#ifdef DEBUG
162 if (strlen(*cmdline_p))
163 printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
164#endif
165
166 /*
167 * give all the memory to the bootmap allocator, tell it to put the
168 * boot mem_map at the start of memory
169 */
170 bootmap_size = init_bootmem_node(
171 NODE_DATA(0),
172 memory_start >> PAGE_SHIFT, /* map goes here */
173 PAGE_OFFSET >> PAGE_SHIFT, /* 0 on coldfire */
174 memory_end >> PAGE_SHIFT);
175 /*
176 * free the usable memory, we have to make sure we do not free
177 * the bootmem bitmap so we then reserve it after freeing it :-)
178 */
179 free_bootmem(memory_start, memory_end - memory_start);
180 reserve_bootmem(memory_start, bootmap_size);
181 /*
182 * get kmalloc into gear
183 */
184 paging_init();
185 h8300_gpio_init();
186#if defined(CONFIG_H8300_AKI3068NET) && defined(CONFIG_IDE)
187 {
188#define AREABIT(addr) (1 << (((addr) >> 21) & 7))
189 /* setup BSC */
190 volatile unsigned char *abwcr = (volatile unsigned char *)ABWCR;
191 volatile unsigned char *cscr = (volatile unsigned char *)CSCR;
192 *abwcr &= ~(AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT));
193 *cscr |= (AREABIT(CONFIG_H8300_IDE_BASE) | AREABIT(CONFIG_H8300_IDE_ALT)) | 0x0f;
194 }
195#endif
196#ifdef DEBUG
197 printk(KERN_DEBUG "Done setup_arch\n");
198#endif
199}
200
201/*
202 * Get CPU information for use by the procfs.
203 */
204
205static int show_cpuinfo(struct seq_file *m, void *v)
206{
207 char *cpu;
208 int mode;
209 u_long clockfreq;
210
211 cpu = CPU;
212 mode = *(volatile unsigned char *)MDCR & 0x07;
213
214 clockfreq = CONFIG_CPU_CLOCK;
215
216 seq_printf(m, "CPU:\t\t%s (mode:%d)\n"
217 "Clock:\t\t%lu.%1luMHz\n"
218 "BogoMips:\t%lu.%02lu\n"
219 "Calibration:\t%lu loops\n",
220 cpu,mode,
221 clockfreq/1000,clockfreq%1000,
222 (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
223 (loops_per_jiffy*HZ));
224
225 return 0;
226}
227
228static void *c_start(struct seq_file *m, loff_t *pos)
229{
230 return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
231}
232
233static void *c_next(struct seq_file *m, void *v, loff_t *pos)
234{
235 ++*pos;
236 return c_start(m, pos);
237}
238
239static void c_stop(struct seq_file *m, void *v)
240{
241}
242
243struct seq_operations cpuinfo_op = {
244 .start = c_start,
245 .next = c_next,
246 .stop = c_stop,
247 .show = show_cpuinfo,
248};
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
new file mode 100644
index 000000000000..a4799d633ef4
--- /dev/null
+++ b/arch/h8300/kernel/signal.c
@@ -0,0 +1,552 @@
1/*
2 * linux/arch/h8300/kernel/signal.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11/*
12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
13 * and David McCullough <davidm@snapgear.com>
14 *
15 * Based on
16 * Linux/m68k by Hamish Macdonald
17 */
18
19/*
20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
21 * Atari :-) Current limitation: Only one sigstack can be active at one time.
22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
24 * signal handlers!
25 */
26
27#include <linux/sched.h>
28#include <linux/mm.h>
29#include <linux/kernel.h>
30#include <linux/signal.h>
31#include <linux/syscalls.h>
32#include <linux/errno.h>
33#include <linux/wait.h>
34#include <linux/ptrace.h>
35#include <linux/unistd.h>
36#include <linux/stddef.h>
37#include <linux/highuid.h>
38#include <linux/personality.h>
39#include <linux/tty.h>
40#include <linux/binfmts.h>
41#include <linux/suspend.h>
42
43#include <asm/setup.h>
44#include <asm/uaccess.h>
45#include <asm/pgtable.h>
46#include <asm/traps.h>
47#include <asm/ucontext.h>
48
49#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
50
51asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
52
53/*
54 * Atomically swap in the new signal mask, and wait for a signal.
55 */
56asmlinkage int do_sigsuspend(struct pt_regs *regs)
57{
58 old_sigset_t mask = regs->er3;
59 sigset_t saveset;
60
61 mask &= _BLOCKABLE;
62 spin_lock_irq(&current->sighand->siglock);
63 saveset = current->blocked;
64 siginitset(&current->blocked, mask);
65 recalc_sigpending();
66 spin_unlock_irq(&current->sighand->siglock);
67
68 regs->er0 = -EINTR;
69 while (1) {
70 current->state = TASK_INTERRUPTIBLE;
71 schedule();
72 if (do_signal(regs, &saveset))
73 return -EINTR;
74 }
75}
76
77asmlinkage int
78do_rt_sigsuspend(struct pt_regs *regs)
79{
80 sigset_t *unewset = (sigset_t *)regs->er1;
81 size_t sigsetsize = (size_t)regs->er2;
82 sigset_t saveset, newset;
83
84 /* XXX: Don't preclude handling different sized sigset_t's. */
85 if (sigsetsize != sizeof(sigset_t))
86 return -EINVAL;
87
88 if (copy_from_user(&newset, unewset, sizeof(newset)))
89 return -EFAULT;
90 sigdelsetmask(&newset, ~_BLOCKABLE);
91
92 spin_lock_irq(&current->sighand->siglock);
93 saveset = current->blocked;
94 current->blocked = newset;
95 recalc_sigpending();
96 spin_unlock_irq(&current->sighand->siglock);
97
98 regs->er0 = -EINTR;
99 while (1) {
100 current->state = TASK_INTERRUPTIBLE;
101 schedule();
102 if (do_signal(regs, &saveset))
103 return -EINTR;
104 }
105}
106
107asmlinkage int
108sys_sigaction(int sig, const struct old_sigaction *act,
109 struct old_sigaction *oact)
110{
111 struct k_sigaction new_ka, old_ka;
112 int ret;
113
114 if (act) {
115 old_sigset_t mask;
116 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
117 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
118 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
119 return -EFAULT;
120 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
121 __get_user(mask, &act->sa_mask);
122 siginitset(&new_ka.sa.sa_mask, mask);
123 }
124
125 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
126
127 if (!ret && oact) {
128 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
129 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
130 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
131 return -EFAULT;
132 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
133 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
134 }
135
136 return ret;
137}
138
139asmlinkage int
140sys_sigaltstack(const stack_t *uss, stack_t *uoss)
141{
142 return do_sigaltstack(uss, uoss, rdusp());
143}
144
145
146/*
147 * Do a signal return; undo the signal stack.
148 *
149 * Keep the return code on the stack quadword aligned!
150 * That makes the cache flush below easier.
151 */
152
153struct sigframe
154{
155 long dummy_er0;
156 long dummy_vector;
157#if defined(CONFIG_CPU_H8S)
158 short dummy_exr;
159#endif
160 long dummy_pc;
161 char *pretcode;
162 unsigned char retcode[8];
163 unsigned long extramask[_NSIG_WORDS-1];
164 struct sigcontext sc;
165 int sig;
166} __attribute__((aligned(2),packed));
167
168struct rt_sigframe
169{
170 long dummy_er0;
171 long dummy_vector;
172#if defined(CONFIG_CPU_H8S)
173 short dummy_exr;
174#endif
175 long dummy_pc;
176 char *pretcode;
177 struct siginfo *pinfo;
178 void *puc;
179 unsigned char retcode[8];
180 struct siginfo info;
181 struct ucontext uc;
182 int sig;
183} __attribute__((aligned(2),packed));
184
185static inline int
186restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc,
187 int *pd0)
188{
189 int err = 0;
190 unsigned int ccr;
191 unsigned int usp;
192 unsigned int er0;
193
194 /* Always make any pending restarted system calls return -EINTR */
195 current_thread_info()->restart_block.fn = do_no_restart_syscall;
196
197#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r) /* restore passed registers */
198 COPY(er1);
199 COPY(er2);
200 COPY(er3);
201 COPY(er5);
202 COPY(pc);
203 ccr = regs->ccr & 0x10;
204 COPY(ccr);
205#undef COPY
206 regs->ccr &= 0xef;
207 regs->ccr |= ccr;
208 regs->orig_er0 = -1; /* disable syscall checks */
209 err |= __get_user(usp, &usc->sc_usp);
210 wrusp(usp);
211
212 err |= __get_user(er0, &usc->sc_er0);
213 *pd0 = er0;
214 return err;
215}
216
217asmlinkage int do_sigreturn(unsigned long __unused,...)
218{
219 struct pt_regs *regs = (struct pt_regs *) (&__unused - 1);
220 unsigned long usp = rdusp();
221 struct sigframe *frame = (struct sigframe *)(usp - 4);
222 sigset_t set;
223 int er0;
224
225 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
226 goto badframe;
227 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
228 (_NSIG_WORDS > 1 &&
229 __copy_from_user(&set.sig[1], &frame->extramask,
230 sizeof(frame->extramask))))
231 goto badframe;
232
233 sigdelsetmask(&set, ~_BLOCKABLE);
234 spin_lock_irq(&current->sighand->siglock);
235 current->blocked = set;
236 recalc_sigpending();
237 spin_unlock_irq(&current->sighand->siglock);
238
239 if (restore_sigcontext(regs, &frame->sc, &er0))
240 goto badframe;
241 return er0;
242
243badframe:
244 force_sig(SIGSEGV, current);
245 return 0;
246}
247
248asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
249{
250 struct pt_regs *regs = (struct pt_regs *) &__unused;
251 unsigned long usp = rdusp();
252 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
253 sigset_t set;
254 int er0;
255
256 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
257 goto badframe;
258 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
259 goto badframe;
260
261 sigdelsetmask(&set, ~_BLOCKABLE);
262 spin_unlock_irq(&current->sighand->siglock);
263 current->blocked = set;
264 recalc_sigpending();
265 spin_lock_irq(&current->sighand->siglock);
266
267 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
268 goto badframe;
269
270 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
271 goto badframe;
272
273 return er0;
274
275badframe:
276 force_sig(SIGSEGV, current);
277 return 0;
278}
279
280static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
281 unsigned long mask)
282{
283 int err = 0;
284
285 err |= __put_user(regs->er0, &sc->sc_er0);
286 err |= __put_user(regs->er1, &sc->sc_er1);
287 err |= __put_user(regs->er2, &sc->sc_er2);
288 err |= __put_user(regs->er3, &sc->sc_er3);
289 err |= __put_user(regs->er4, &sc->sc_er4);
290 err |= __put_user(regs->er5, &sc->sc_er5);
291 err |= __put_user(regs->er6, &sc->sc_er6);
292 err |= __put_user(rdusp(), &sc->sc_usp);
293 err |= __put_user(regs->pc, &sc->sc_pc);
294 err |= __put_user(regs->ccr, &sc->sc_ccr);
295 err |= __put_user(mask, &sc->sc_mask);
296
297 return err;
298}
299
300static inline void *
301get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
302{
303 unsigned long usp;
304
305 /* Default to using normal stack. */
306 usp = rdusp();
307
308 /* This is the X/Open sanctioned signal stack switching. */
309 if (ka->sa.sa_flags & SA_ONSTACK) {
310 if (!on_sig_stack(usp))
311 usp = current->sas_ss_sp + current->sas_ss_size;
312 }
313 return (void *)((usp - frame_size) & -8UL);
314}
315
316static void setup_frame (int sig, struct k_sigaction *ka,
317 sigset_t *set, struct pt_regs *regs)
318{
319 struct sigframe *frame;
320 int err = 0;
321 int usig;
322 unsigned char *ret;
323
324 frame = get_sigframe(ka, regs, sizeof(*frame));
325
326 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
327 goto give_sigsegv;
328
329 usig = current_thread_info()->exec_domain
330 && current_thread_info()->exec_domain->signal_invmap
331 && sig < 32
332 ? current_thread_info()->exec_domain->signal_invmap[sig]
333 : sig;
334
335 err |= __put_user(usig, &frame->sig);
336 if (err)
337 goto give_sigsegv;
338
339 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
340 if (err)
341 goto give_sigsegv;
342
343 if (_NSIG_WORDS > 1) {
344 err |= copy_to_user(frame->extramask, &set->sig[1],
345 sizeof(frame->extramask));
346 if (err)
347 goto give_sigsegv;
348 }
349
350 ret = frame->retcode;
351 if (ka->sa.sa_flags & SA_RESTORER)
352 ret = (unsigned char *)(ka->sa.sa_restorer);
353 else {
354 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
355 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
356 (unsigned long *)(frame->retcode + 0));
357 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
358 }
359
360 /* Set up to return from userspace. */
361 err |= __put_user(ret, &frame->pretcode);
362
363 if (err)
364 goto give_sigsegv;
365
366 /* Set up registers for signal handler */
367 wrusp ((unsigned long) frame);
368 regs->pc = (unsigned long) ka->sa.sa_handler;
369 regs->er0 = (current_thread_info()->exec_domain
370 && current_thread_info()->exec_domain->signal_invmap
371 && sig < 32
372 ? current_thread_info()->exec_domain->signal_invmap[sig]
373 : sig);
374 regs->er1 = (unsigned long)&(frame->sc);
375 regs->er5 = current->mm->start_data; /* GOT base */
376
377 return;
378
379give_sigsegv:
380 force_sigsegv(sig, current);
381}
382
383static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
384 sigset_t *set, struct pt_regs *regs)
385{
386 struct rt_sigframe *frame;
387 int err = 0;
388 int usig;
389 unsigned char *ret;
390
391 frame = get_sigframe(ka, regs, sizeof(*frame));
392
393 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
394 goto give_sigsegv;
395
396 usig = current_thread_info()->exec_domain
397 && current_thread_info()->exec_domain->signal_invmap
398 && sig < 32
399 ? current_thread_info()->exec_domain->signal_invmap[sig]
400 : sig;
401
402 err |= __put_user(usig, &frame->sig);
403 if (err)
404 goto give_sigsegv;
405
406 err |= __put_user(&frame->info, &frame->pinfo);
407 err |= __put_user(&frame->uc, &frame->puc);
408 err |= copy_siginfo_to_user(&frame->info, info);
409 if (err)
410 goto give_sigsegv;
411
412 /* Create the ucontext. */
413 err |= __put_user(0, &frame->uc.uc_flags);
414 err |= __put_user(0, &frame->uc.uc_link);
415 err |= __put_user((void *)current->sas_ss_sp,
416 &frame->uc.uc_stack.ss_sp);
417 err |= __put_user(sas_ss_flags(rdusp()),
418 &frame->uc.uc_stack.ss_flags);
419 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
420 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
421 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
422 if (err)
423 goto give_sigsegv;
424
425 /* Set up to return from userspace. */
426 ret = frame->retcode;
427 if (ka->sa.sa_flags & SA_RESTORER)
428 ret = (unsigned char *)(ka->sa.sa_restorer);
429 else {
430 /* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
431 err != __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
432 (unsigned long *)(frame->retcode + 0));
433 err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
434 }
435 err |= __put_user(ret, &frame->pretcode);
436
437 if (err)
438 goto give_sigsegv;
439
440 /* Set up registers for signal handler */
441 wrusp ((unsigned long) frame);
442 regs->pc = (unsigned long) ka->sa.sa_handler;
443 regs->er0 = (current_thread_info()->exec_domain
444 && current_thread_info()->exec_domain->signal_invmap
445 && sig < 32
446 ? current_thread_info()->exec_domain->signal_invmap[sig]
447 : sig);
448 regs->er1 = (unsigned long)&(frame->info);
449 regs->er2 = (unsigned long)&frame->uc;
450 regs->er5 = current->mm->start_data; /* GOT base */
451
452 return;
453
454give_sigsegv:
455 force_sigsegv(sig, current);
456}
457
458/*
459 * OK, we're invoking a handler
460 */
461static void
462handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
463 sigset_t *oldset, struct pt_regs * regs)
464{
465 /* are we from a system call? */
466 if (regs->orig_er0 >= 0) {
467 switch (regs->er0) {
468 case -ERESTART_RESTARTBLOCK:
469 case -ERESTARTNOHAND:
470 regs->er0 = -EINTR;
471 break;
472
473 case -ERESTARTSYS:
474 if (!(ka->sa.sa_flags & SA_RESTART)) {
475 regs->er0 = -EINTR;
476 break;
477 }
478 /* fallthrough */
479 case -ERESTARTNOINTR:
480 regs->er0 = regs->orig_er0;
481 regs->pc -= 2;
482 }
483 }
484
485 /* set up the stack frame */
486 if (ka->sa.sa_flags & SA_SIGINFO)
487 setup_rt_frame(sig, ka, info, oldset, regs);
488 else
489 setup_frame(sig, ka, oldset, regs);
490
491 if (!(ka->sa.sa_flags & SA_NODEFER)) {
492 spin_lock_irq(&current->sighand->siglock);
493 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
494 sigaddset(&current->blocked,sig);
495 recalc_sigpending();
496 spin_unlock_irq(&current->sighand->siglock);
497 }
498}
499
500/*
501 * Note that 'init' is a special process: it doesn't get signals it doesn't
502 * want to handle. Thus you cannot kill init even with a SIGKILL even by
503 * mistake.
504 */
505asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
506{
507 siginfo_t info;
508 int signr;
509 struct k_sigaction ka;
510
511 /*
512 * We want the common case to go fast, which
513 * is why we may in certain cases get here from
514 * kernel mode. Just return without doing anything
515 * if so.
516 */
517 if ((regs->ccr & 0x10))
518 return 1;
519
520 if (current->flags & PF_FREEZE) {
521 refrigerator(0);
522 goto no_signal;
523 }
524
525 current->thread.esp0 = (unsigned long) regs;
526
527 if (!oldset)
528 oldset = &current->blocked;
529
530 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
531 if (signr > 0) {
532 /* Whee! Actually deliver the signal. */
533 handle_signal(signr, &info, &ka, oldset, regs);
534 return 1;
535 }
536 no_signal:
537 /* Did we come from a system call? */
538 if (regs->orig_er0 >= 0) {
539 /* Restart the system call - no handlers present */
540 if (regs->er0 == -ERESTARTNOHAND ||
541 regs->er0 == -ERESTARTSYS ||
542 regs->er0 == -ERESTARTNOINTR) {
543 regs->er0 = regs->orig_er0;
544 regs->pc -= 2;
545 }
546 if (regs->er0 == -ERESTART_RESTARTBLOCK){
547 regs->er0 = __NR_restart_syscall;
548 regs->pc -= 2;
549 }
550 }
551 return 0;
552}
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
new file mode 100644
index 000000000000..0f61b7ad69ab
--- /dev/null
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -0,0 +1,282 @@
1/*
2 * linux/arch/h8300/kernel/sys_h8300.c
3 *
4 * This file contains various random system calls that
5 * have a non-standard calling sequence on the H8/300
6 * platform.
7 */
8
9#include <linux/errno.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/smp_lock.h>
14#include <linux/sem.h>
15#include <linux/msg.h>
16#include <linux/shm.h>
17#include <linux/stat.h>
18#include <linux/syscalls.h>
19#include <linux/mman.h>
20#include <linux/file.h>
21#include <linux/utsname.h>
22
23#include <asm/setup.h>
24#include <asm/uaccess.h>
25#include <asm/cachectl.h>
26#include <asm/traps.h>
27#include <asm/ipc.h>
28
29/*
30 * sys_pipe() is the normal C calling standard for creating
31 * a pipe. It's not the way unix traditionally does this, though.
32 */
33asmlinkage int sys_pipe(unsigned long * fildes)
34{
35 int fd[2];
36 int error;
37
38 error = do_pipe(fd);
39 if (!error) {
40 if (copy_to_user(fildes, fd, 2*sizeof(int)))
41 error = -EFAULT;
42 }
43 return error;
44}
45
46/* common code for old and new mmaps */
47static inline long do_mmap2(
48 unsigned long addr, unsigned long len,
49 unsigned long prot, unsigned long flags,
50 unsigned long fd, unsigned long pgoff)
51{
52 int error = -EBADF;
53 struct file * file = NULL;
54
55 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
56 if (!(flags & MAP_ANONYMOUS)) {
57 file = fget(fd);
58 if (!file)
59 goto out;
60 }
61
62 down_write(&current->mm->mmap_sem);
63 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
64 up_write(&current->mm->mmap_sem);
65
66 if (file)
67 fput(file);
68out:
69 return error;
70}
71
72asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
73 unsigned long prot, unsigned long flags,
74 unsigned long fd, unsigned long pgoff)
75{
76 return do_mmap2(addr, len, prot, flags, fd, pgoff);
77}
78
79/*
80 * Perform the select(nd, in, out, ex, tv) and mmap() system
81 * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
82 * handle more than 4 system call parameters, so these system calls
83 * used a memory block for parameter passing..
84 */
85
86struct mmap_arg_struct {
87 unsigned long addr;
88 unsigned long len;
89 unsigned long prot;
90 unsigned long flags;
91 unsigned long fd;
92 unsigned long offset;
93};
94
95asmlinkage int old_mmap(struct mmap_arg_struct *arg)
96{
97 struct mmap_arg_struct a;
98 int error = -EFAULT;
99
100 if (copy_from_user(&a, arg, sizeof(a)))
101 goto out;
102
103 error = -EINVAL;
104 if (a.offset & ~PAGE_MASK)
105 goto out;
106
107 a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
108
109 error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
110out:
111 return error;
112}
113
114#if 0 /* DAVIDM - do we want this */
115struct mmap_arg_struct64 {
116 __u32 addr;
117 __u32 len;
118 __u32 prot;
119 __u32 flags;
120 __u64 offset; /* 64 bits */
121 __u32 fd;
122};
123
124asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
125{
126 int error = -EFAULT;
127 struct file * file = NULL;
128 struct mmap_arg_struct64 a;
129 unsigned long pgoff;
130
131 if (copy_from_user(&a, arg, sizeof(a)))
132 return -EFAULT;
133
134 if ((long)a.offset & ~PAGE_MASK)
135 return -EINVAL;
136
137 pgoff = a.offset >> PAGE_SHIFT;
138 if ((a.offset >> PAGE_SHIFT) != pgoff)
139 return -EINVAL;
140
141 if (!(a.flags & MAP_ANONYMOUS)) {
142 error = -EBADF;
143 file = fget(a.fd);
144 if (!file)
145 goto out;
146 }
147 a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
148
149 down_write(&current->mm->mmap_sem);
150 error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
151 up_write(&current->mm->mmap_sem);
152 if (file)
153 fput(file);
154out:
155 return error;
156}
157#endif
158
159struct sel_arg_struct {
160 unsigned long n;
161 fd_set *inp, *outp, *exp;
162 struct timeval *tvp;
163};
164
165asmlinkage int old_select(struct sel_arg_struct *arg)
166{
167 struct sel_arg_struct a;
168
169 if (copy_from_user(&a, arg, sizeof(a)))
170 return -EFAULT;
171 /* sys_select() does the appropriate kernel locking */
172 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
173}
174
175/*
176 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
177 *
178 * This is really horribly ugly.
179 */
180asmlinkage int sys_ipc (uint call, int first, int second,
181 int third, void *ptr, long fifth)
182{
183 int version, ret;
184
185 version = call >> 16; /* hack for backward compatibility */
186 call &= 0xffff;
187
188 if (call <= SEMCTL)
189 switch (call) {
190 case SEMOP:
191 return sys_semop (first, (struct sembuf *)ptr, second);
192 case SEMGET:
193 return sys_semget (first, second, third);
194 case SEMCTL: {
195 union semun fourth;
196 if (!ptr)
197 return -EINVAL;
198 if (get_user(fourth.__pad, (void **) ptr))
199 return -EFAULT;
200 return sys_semctl (first, second, third, fourth);
201 }
202 default:
203 return -EINVAL;
204 }
205 if (call <= MSGCTL)
206 switch (call) {
207 case MSGSND:
208 return sys_msgsnd (first, (struct msgbuf *) ptr,
209 second, third);
210 case MSGRCV:
211 switch (version) {
212 case 0: {
213 struct ipc_kludge tmp;
214 if (!ptr)
215 return -EINVAL;
216 if (copy_from_user (&tmp,
217 (struct ipc_kludge *)ptr,
218 sizeof (tmp)))
219 return -EFAULT;
220 return sys_msgrcv (first, tmp.msgp, second,
221 tmp.msgtyp, third);
222 }
223 default:
224 return sys_msgrcv (first,
225 (struct msgbuf *) ptr,
226 second, fifth, third);
227 }
228 case MSGGET:
229 return sys_msgget ((key_t) first, second);
230 case MSGCTL:
231 return sys_msgctl (first, second,
232 (struct msqid_ds *) ptr);
233 default:
234 return -EINVAL;
235 }
236 if (call <= SHMCTL)
237 switch (call) {
238 case SHMAT:
239 switch (version) {
240 default: {
241 ulong raddr;
242 ret = do_shmat (first, (char *) ptr,
243 second, &raddr);
244 if (ret)
245 return ret;
246 return put_user (raddr, (ulong *) third);
247 }
248 }
249 case SHMDT:
250 return sys_shmdt ((char *)ptr);
251 case SHMGET:
252 return sys_shmget (first, second, third);
253 case SHMCTL:
254 return sys_shmctl (first, second,
255 (struct shmid_ds *) ptr);
256 default:
257 return -EINVAL;
258 }
259
260 return -EINVAL;
261}
262
263/* sys_cacheflush -- no support. */
264asmlinkage int
265sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
266{
267 return -EINVAL;
268}
269
270asmlinkage int sys_getpagesize(void)
271{
272 return PAGE_SIZE;
273}
274
275#if defined(CONFIG_SYSCALL_PRINT)
276asmlinkage void syscall_print(void *dummy,...)
277{
278 struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
279 printk("call %06lx:%ld 1:%08lx,2:%08lx,3:%08lx,ret:%08lx\n",
280 ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0);
281}
282#endif
diff --git a/arch/h8300/kernel/syscalls.S b/arch/h8300/kernel/syscalls.S
new file mode 100644
index 000000000000..79b3bda5c6e3
--- /dev/null
+++ b/arch/h8300/kernel/syscalls.S
@@ -0,0 +1,340 @@
1/* Systemcall Entry Table */
2#include <linux/config.h>
3#include <linux/sys.h>
4#include <asm/linkage.h>
5#include <asm/unistd.h>
6
7.globl SYMBOL_NAME(sys_call_table)
8
9#if defined(CONFIG_CPU_H8300H)
10 .h8300h
11#endif
12#if defined(CONFIG_CPU_H8S)
13 .h8300s
14#endif
15 .section .text
16 .align 2
17SYMBOL_NAME_LABEL(sys_call_table)
18 .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
19 .long SYMBOL_NAME(sys_exit)
20 .long SYMBOL_NAME(sys_fork)
21 .long SYMBOL_NAME(sys_read)
22 .long SYMBOL_NAME(sys_write)
23 .long SYMBOL_NAME(sys_open) /* 5 */
24 .long SYMBOL_NAME(sys_close)
25 .long SYMBOL_NAME(sys_waitpid)
26 .long SYMBOL_NAME(sys_creat)
27 .long SYMBOL_NAME(sys_link)
28 .long SYMBOL_NAME(sys_unlink) /* 10 */
29 .long SYMBOL_NAME(sys_execve)
30 .long SYMBOL_NAME(sys_chdir)
31 .long SYMBOL_NAME(sys_time)
32 .long SYMBOL_NAME(sys_mknod)
33 .long SYMBOL_NAME(sys_chmod) /* 15 */
34 .long SYMBOL_NAME(sys_chown16)
35 .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
36 .long SYMBOL_NAME(sys_stat)
37 .long SYMBOL_NAME(sys_lseek)
38 .long SYMBOL_NAME(sys_getpid) /* 20 */
39 .long SYMBOL_NAME(sys_mount)
40 .long SYMBOL_NAME(sys_oldumount)
41 .long SYMBOL_NAME(sys_setuid16)
42 .long SYMBOL_NAME(sys_getuid16)
43 .long SYMBOL_NAME(sys_stime) /* 25 */
44 .long SYMBOL_NAME(sys_ptrace)
45 .long SYMBOL_NAME(sys_alarm)
46 .long SYMBOL_NAME(sys_fstat)
47 .long SYMBOL_NAME(sys_pause)
48 .long SYMBOL_NAME(sys_utime) /* 30 */
49 .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
50 .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
51 .long SYMBOL_NAME(sys_access)
52 .long SYMBOL_NAME(sys_nice)
53 .long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
54 .long SYMBOL_NAME(sys_sync)
55 .long SYMBOL_NAME(sys_kill)
56 .long SYMBOL_NAME(sys_rename)
57 .long SYMBOL_NAME(sys_mkdir)
58 .long SYMBOL_NAME(sys_rmdir) /* 40 */
59 .long SYMBOL_NAME(sys_dup)
60 .long SYMBOL_NAME(sys_pipe)
61 .long SYMBOL_NAME(sys_times)
62 .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
63 .long SYMBOL_NAME(sys_brk) /* 45 */
64 .long SYMBOL_NAME(sys_setgid16)
65 .long SYMBOL_NAME(sys_getgid16)
66 .long SYMBOL_NAME(sys_signal)
67 .long SYMBOL_NAME(sys_geteuid16)
68 .long SYMBOL_NAME(sys_getegid16) /* 50 */
69 .long SYMBOL_NAME(sys_acct)
70 .long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
71 .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
72 .long SYMBOL_NAME(sys_ioctl)
73 .long SYMBOL_NAME(sys_fcntl) /* 55 */
74 .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
75 .long SYMBOL_NAME(sys_setpgid)
76 .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
77 .long SYMBOL_NAME(sys_ni_syscall)
78 .long SYMBOL_NAME(sys_umask) /* 60 */
79 .long SYMBOL_NAME(sys_chroot)
80 .long SYMBOL_NAME(sys_ustat)
81 .long SYMBOL_NAME(sys_dup2)
82 .long SYMBOL_NAME(sys_getppid)
83 .long SYMBOL_NAME(sys_getpgrp) /* 65 */
84 .long SYMBOL_NAME(sys_setsid)
85 .long SYMBOL_NAME(sys_sigaction)
86 .long SYMBOL_NAME(sys_sgetmask)
87 .long SYMBOL_NAME(sys_ssetmask)
88 .long SYMBOL_NAME(sys_setreuid16) /* 70 */
89 .long SYMBOL_NAME(sys_setregid16)
90 .long SYMBOL_NAME(sys_sigsuspend)
91 .long SYMBOL_NAME(sys_sigpending)
92 .long SYMBOL_NAME(sys_sethostname)
93 .long SYMBOL_NAME(sys_setrlimit) /* 75 */
94 .long SYMBOL_NAME(sys_old_getrlimit)
95 .long SYMBOL_NAME(sys_getrusage)
96 .long SYMBOL_NAME(sys_gettimeofday)
97 .long SYMBOL_NAME(sys_settimeofday)
98 .long SYMBOL_NAME(sys_getgroups16) /* 80 */
99 .long SYMBOL_NAME(sys_setgroups16)
100 .long SYMBOL_NAME(old_select)
101 .long SYMBOL_NAME(sys_symlink)
102 .long SYMBOL_NAME(sys_lstat)
103 .long SYMBOL_NAME(sys_readlink) /* 85 */
104 .long SYMBOL_NAME(sys_uselib)
105 .long SYMBOL_NAME(sys_swapon)
106 .long SYMBOL_NAME(sys_reboot)
107 .long SYMBOL_NAME(old_readdir)
108 .long SYMBOL_NAME(old_mmap) /* 90 */
109 .long SYMBOL_NAME(sys_munmap)
110 .long SYMBOL_NAME(sys_truncate)
111 .long SYMBOL_NAME(sys_ftruncate)
112 .long SYMBOL_NAME(sys_fchmod)
113 .long SYMBOL_NAME(sys_fchown16) /* 95 */
114 .long SYMBOL_NAME(sys_getpriority)
115 .long SYMBOL_NAME(sys_setpriority)
116 .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
117 .long SYMBOL_NAME(sys_statfs)
118 .long SYMBOL_NAME(sys_fstatfs) /* 100 */
119 .long SYMBOL_NAME(sys_ni_syscall) /* ioperm for i386 */
120 .long SYMBOL_NAME(sys_socketcall)
121 .long SYMBOL_NAME(sys_syslog)
122 .long SYMBOL_NAME(sys_setitimer)
123 .long SYMBOL_NAME(sys_getitimer) /* 105 */
124 .long SYMBOL_NAME(sys_newstat)
125 .long SYMBOL_NAME(sys_newlstat)
126 .long SYMBOL_NAME(sys_newfstat)
127 .long SYMBOL_NAME(sys_ni_syscall)
128 .long SYMBOL_NAME(sys_ni_syscall) /* iopl for i386 */ /* 110 */
129 .long SYMBOL_NAME(sys_vhangup)
130 .long SYMBOL_NAME(sys_ni_syscall) /* obsolete idle() syscall */
131 .long SYMBOL_NAME(sys_ni_syscall) /* vm86old for i386 */
132 .long SYMBOL_NAME(sys_wait4)
133 .long SYMBOL_NAME(sys_swapoff) /* 115 */
134 .long SYMBOL_NAME(sys_sysinfo)
135 .long SYMBOL_NAME(sys_ipc)
136 .long SYMBOL_NAME(sys_fsync)
137 .long SYMBOL_NAME(sys_sigreturn)
138 .long SYMBOL_NAME(sys_clone) /* 120 */
139 .long SYMBOL_NAME(sys_setdomainname)
140 .long SYMBOL_NAME(sys_newuname)
141 .long SYMBOL_NAME(sys_cacheflush) /* modify_ldt for i386 */
142 .long SYMBOL_NAME(sys_adjtimex)
143 .long SYMBOL_NAME(sys_ni_syscall) /* 125 sys_mprotect */
144 .long SYMBOL_NAME(sys_sigprocmask)
145 .long SYMBOL_NAME(sys_ni_syscall) /* sys_create_module */
146 .long SYMBOL_NAME(sys_init_module)
147 .long SYMBOL_NAME(sys_delete_module)
148 .long SYMBOL_NAME(sys_ni_syscall) /* 130 sys_get_kernel_syms */
149 .long SYMBOL_NAME(sys_quotactl)
150 .long SYMBOL_NAME(sys_getpgid)
151 .long SYMBOL_NAME(sys_fchdir)
152 .long SYMBOL_NAME(sys_bdflush)
153 .long SYMBOL_NAME(sys_sysfs) /* 135 */
154 .long SYMBOL_NAME(sys_personality)
155 .long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
156 .long SYMBOL_NAME(sys_setfsuid16)
157 .long SYMBOL_NAME(sys_setfsgid16)
158 .long SYMBOL_NAME(sys_llseek) /* 140 */
159 .long SYMBOL_NAME(sys_getdents)
160 .long SYMBOL_NAME(sys_select)
161 .long SYMBOL_NAME(sys_flock)
162 .long SYMBOL_NAME(sys_ni_syscall) /* sys_msync */
163 .long SYMBOL_NAME(sys_readv) /* 145 */
164 .long SYMBOL_NAME(sys_writev)
165 .long SYMBOL_NAME(sys_getsid)
166 .long SYMBOL_NAME(sys_fdatasync)
167 .long SYMBOL_NAME(sys_sysctl)
168 .long SYMBOL_NAME(sys_ni_syscall) /* 150 sys_mlock */
169 .long SYMBOL_NAME(sys_ni_syscall) /* sys_munlock */
170 .long SYMBOL_NAME(sys_ni_syscall) /* sys_mlockall */
171 .long SYMBOL_NAME(sys_ni_syscall) /* sys_munlockall */
172 .long SYMBOL_NAME(sys_sched_setparam)
173 .long SYMBOL_NAME(sys_sched_getparam) /* 155 */
174 .long SYMBOL_NAME(sys_sched_setscheduler)
175 .long SYMBOL_NAME(sys_sched_getscheduler)
176 .long SYMBOL_NAME(sys_sched_yield)
177 .long SYMBOL_NAME(sys_sched_get_priority_max)
178 .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
179 .long SYMBOL_NAME(sys_sched_rr_get_interval)
180 .long SYMBOL_NAME(sys_nanosleep)
181 .long SYMBOL_NAME(sys_ni_syscall) /* sys_mremap */
182 .long SYMBOL_NAME(sys_setresuid16)
183 .long SYMBOL_NAME(sys_getresuid16) /* 165 */
184 .long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */
185 .long SYMBOL_NAME(sys_ni_syscall) /* sys_query_module */
186 .long SYMBOL_NAME(sys_poll)
187 .long SYMBOL_NAME(sys_nfsservctl)
188 .long SYMBOL_NAME(sys_setresgid16) /* 170 */
189 .long SYMBOL_NAME(sys_getresgid16)
190 .long SYMBOL_NAME(sys_prctl)
191 .long SYMBOL_NAME(sys_rt_sigreturn)
192 .long SYMBOL_NAME(sys_rt_sigaction)
193 .long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
194 .long SYMBOL_NAME(sys_rt_sigpending)
195 .long SYMBOL_NAME(sys_rt_sigtimedwait)
196 .long SYMBOL_NAME(sys_rt_sigqueueinfo)
197 .long SYMBOL_NAME(sys_rt_sigsuspend)
198 .long SYMBOL_NAME(sys_pread64) /* 180 */
199 .long SYMBOL_NAME(sys_pwrite64)
200 .long SYMBOL_NAME(sys_lchown16);
201 .long SYMBOL_NAME(sys_getcwd)
202 .long SYMBOL_NAME(sys_capget)
203 .long SYMBOL_NAME(sys_capset) /* 185 */
204 .long SYMBOL_NAME(sys_sigaltstack)
205 .long SYMBOL_NAME(sys_sendfile)
206 .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
207 .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
208 .long SYMBOL_NAME(sys_vfork) /* 190 */
209 .long SYMBOL_NAME(sys_getrlimit)
210 .long SYMBOL_NAME(sys_mmap2)
211 .long SYMBOL_NAME(sys_truncate64)
212 .long SYMBOL_NAME(sys_ftruncate64)
213 .long SYMBOL_NAME(sys_stat64) /* 195 */
214 .long SYMBOL_NAME(sys_lstat64)
215 .long SYMBOL_NAME(sys_fstat64)
216 .long SYMBOL_NAME(sys_chown)
217 .long SYMBOL_NAME(sys_getuid)
218 .long SYMBOL_NAME(sys_getgid) /* 200 */
219 .long SYMBOL_NAME(sys_geteuid)
220 .long SYMBOL_NAME(sys_getegid)
221 .long SYMBOL_NAME(sys_setreuid)
222 .long SYMBOL_NAME(sys_setregid)
223 .long SYMBOL_NAME(sys_getgroups) /* 205 */
224 .long SYMBOL_NAME(sys_setgroups)
225 .long SYMBOL_NAME(sys_fchown)
226 .long SYMBOL_NAME(sys_setresuid)
227 .long SYMBOL_NAME(sys_getresuid)
228 .long SYMBOL_NAME(sys_setresgid) /* 210 */
229 .long SYMBOL_NAME(sys_getresgid)
230 .long SYMBOL_NAME(sys_lchown)
231 .long SYMBOL_NAME(sys_setuid)
232 .long SYMBOL_NAME(sys_setgid)
233 .long SYMBOL_NAME(sys_setfsuid) /* 215 */
234 .long SYMBOL_NAME(sys_setfsgid)
235 .long SYMBOL_NAME(sys_pivot_root)
236 .long SYMBOL_NAME(sys_ni_syscall)
237 .long SYMBOL_NAME(sys_ni_syscall)
238 .long SYMBOL_NAME(sys_getdents64) /* 220 */
239 .long SYMBOL_NAME(sys_fcntl64)
240 .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
241 .long SYMBOL_NAME(sys_ni_syscall)
242 .long SYMBOL_NAME(sys_gettid)
243 .long SYMBOL_NAME(sys_ni_syscall) /* 225 */ /* sys_readahead */
244 .long SYMBOL_NAME(sys_setxattr)
245 .long SYMBOL_NAME(sys_lsetxattr)
246 .long SYMBOL_NAME(sys_fsetxattr)
247 .long SYMBOL_NAME(sys_getxattr)
248 .long SYMBOL_NAME(sys_lgetxattr) /* 230 */
249 .long SYMBOL_NAME(sys_fgetxattr)
250 .long SYMBOL_NAME(sys_listxattr)
251 .long SYMBOL_NAME(sys_llistxattr)
252 .long SYMBOL_NAME(sys_flistxattr)
253 .long SYMBOL_NAME(sys_removexattr) /* 235 */
254 .long SYMBOL_NAME(sys_lremovexattr)
255 .long SYMBOL_NAME(sys_fremovexattr)
256 .long SYMBOL_NAME(sys_tkill)
257 .long SYMBOL_NAME(sys_sendfile64)
258 .long SYMBOL_NAME(sys_futex) /* 240 */
259 .long SYMBOL_NAME(sys_sched_setaffinity)
260 .long SYMBOL_NAME(sys_sched_getaffinity)
261 .long SYMBOL_NAME(sys_ni_syscall) /* sys_set_thread_area */
262 .long SYMBOL_NAME(sys_ni_syscall) /* sys_get_thread_area */
263 .long SYMBOL_NAME(sys_io_setup) /* 245 */
264 .long SYMBOL_NAME(sys_io_destroy)
265 .long SYMBOL_NAME(sys_io_getevents)
266 .long SYMBOL_NAME(sys_io_submit)
267 .long SYMBOL_NAME(sys_io_cancel)
268 .long SYMBOL_NAME(sys_fadvise64) /* 250 */
269 .long SYMBOL_NAME(sys_ni_syscall)
270 .long SYMBOL_NAME(sys_exit_group)
271 .long SYMBOL_NAME(sys_lookup_dcookie)
272 .long SYMBOL_NAME(sys_epoll_create)
273 .long SYMBOL_NAME(sys_epoll_ctl) /* 255 */
274 .long SYMBOL_NAME(sys_epoll_wait)
275 .long SYMBOL_NAME(sys_ni_syscall) /* sys_remap_file_pages */
276 .long SYMBOL_NAME(sys_set_tid_address)
277 .long SYMBOL_NAME(sys_timer_create)
278 .long SYMBOL_NAME(sys_timer_settime) /* 260 */
279 .long SYMBOL_NAME(sys_timer_gettime)
280 .long SYMBOL_NAME(sys_timer_getoverrun)
281 .long SYMBOL_NAME(sys_timer_delete)
282 .long SYMBOL_NAME(sys_clock_settime)
283 .long SYMBOL_NAME(sys_clock_gettime) /* 265 */
284 .long SYMBOL_NAME(sys_clock_getres)
285 .long SYMBOL_NAME(sys_clock_nanosleep)
286 .long SYMBOL_NAME(sys_statfs64)
287 .long SYMBOL_NAME(sys_fstatfs64)
288 .long SYMBOL_NAME(sys_tgkill) /* 270 */
289 .long SYMBOL_NAME(sys_utimes)
290 .long SYMBOL_NAME(sys_fadvise64_64)
291 .long SYMBOL_NAME(sys_ni_syscall) /* sys_vserver */
292 .long SYMBOL_NAME(sys_mbind)
293 .long SYMBOL_NAME(sys_get_mempolicy)
294 .long SYMBOL_NAME(sys_set_mempolicy)
295 .long SYMBOL_NAME(sys_mq_open)
296 .long SYMBOL_NAME(sys_mq_unlink)
297 .long SYMBOL_NAME(sys_mq_timedsend)
298 .long SYMBOL_NAME(sys_mq_timedreceive) /* 280 */
299 .long SYMBOL_NAME(sys_mq_notify)
300 .long SYMBOL_NAME(sys_mq_getsetattr)
301 .long SYMBOL_NAME(sys_ni_syscall) /* reserved for kexec */
302 .long SYMBOL_NAME(sys_waitid)
303 .long SYMBOL_NAME(sys_ni_syscall) /* 285 */ /* available */
304 .long SYMBOL_NAME(sys_add_key)
305 .long SYMBOL_NAME(sys_request_key)
306 .long SYMBOL_NAME(sys_keyctl)
307
308 .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
309 .long SYMBOL_NAME(sys_ni_syscall)
310 .endr
311
312 .macro call_sp addr
313 mov.l #SYMBOL_NAME(\addr),er6
314 bra SYMBOL_NAME(syscall_trampoline):8
315 .endm
316
317SYMBOL_NAME_LABEL(sys_clone)
318 call_sp h8300_clone
319
320SYMBOL_NAME_LABEL(sys_sigsuspend)
321 call_sp do_sigsuspend
322
323SYMBOL_NAME_LABEL(sys_rt_sigsuspend)
324 call_sp do_rt_sigsuspend
325
326SYMBOL_NAME_LABEL(sys_sigreturn)
327 call_sp do_sigreturn
328
329SYMBOL_NAME_LABEL(sys_rt_sigreturn)
330 call_sp do_rt_sigreturn
331
332SYMBOL_NAME_LABEL(sys_fork)
333 call_sp h8300_fork
334
335SYMBOL_NAME_LABEL(sys_vfork)
336 call_sp h8300_vfork
337
338SYMBOL_NAME_LABEL(syscall_trampoline)
339 mov.l sp,er0
340 jmp @er6
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
new file mode 100644
index 000000000000..8a600218334d
--- /dev/null
+++ b/arch/h8300/kernel/time.c
@@ -0,0 +1,134 @@
1/*
2 * linux/arch/h8300/kernel/time.c
3 *
4 * Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 * Copied/hacked from:
7 *
8 * linux/arch/m68k/kernel/time.c
9 *
10 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
11 *
12 * This file contains the m68k-specific time handling details.
13 * Most of the stuff is located in the machine specific files.
14 *
15 * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
16 * "A Kernel Model for Precision Timekeeping" by Dave Mills
17 */
18
19#include <linux/config.h> /* CONFIG_HEARTBEAT */
20#include <linux/errno.h>
21#include <linux/module.h>
22#include <linux/sched.h>
23#include <linux/kernel.h>
24#include <linux/param.h>
25#include <linux/string.h>
26#include <linux/mm.h>
27#include <linux/timex.h>
28#include <linux/profile.h>
29
30#include <asm/io.h>
31#include <asm/target_time.h>
32
33#define TICK_SIZE (tick_nsec / 1000)
34
35u64 jiffies_64;
36
37EXPORT_SYMBOL(jiffies_64);
38
39/*
40 * timer_interrupt() needs to keep up the real-time clock,
41 * as well as call the "do_timer()" routine every clocktick
42 */
43static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
44{
45 /* may need to kick the hardware timer */
46 platform_timer_eoi();
47
48 do_timer(regs);
49#ifndef CONFIG_SMP
50 update_process_times(user_mode(regs));
51#endif
52 profile_tick(CPU_PROFILING, regs);
53}
54
55void time_init(void)
56{
57 unsigned int year, mon, day, hour, min, sec;
58
59 /* FIX by dqg : Set to zero for platforms that don't have tod */
60 /* without this time is undefined and can overflow time_t, causing */
61 /* very stange errors */
62 year = 1980;
63 mon = day = 1;
64 hour = min = sec = 0;
65 platform_gettod (&year, &mon, &day, &hour, &min, &sec);
66
67 if ((year += 1900) < 1970)
68 year += 100;
69 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
70 xtime.tv_nsec = 0;
71
72 platform_timer_setup(timer_interrupt);
73}
74
75/*
76 * This version of gettimeofday has near microsecond resolution.
77 */
78void do_gettimeofday(struct timeval *tv)
79{
80 unsigned long flags;
81 unsigned long usec, sec;
82
83 read_lock_irqsave(&xtime_lock, flags);
84 usec = 0;
85 sec = xtime.tv_sec;
86 usec += (xtime.tv_nsec / 1000);
87 read_unlock_irqrestore(&xtime_lock, flags);
88
89 while (usec >= 1000000) {
90 usec -= 1000000;
91 sec++;
92 }
93
94 tv->tv_sec = sec;
95 tv->tv_usec = usec;
96}
97
98EXPORT_SYMBOL(do_gettimeofday);
99
100int do_settimeofday(struct timespec *tv)
101{
102 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
103 return -EINVAL;
104
105 write_lock_irq(&xtime_lock);
106 /* This is revolting. We need to set the xtime.tv_usec
107 * correctly. However, the value in this location is
108 * is value at the last tick.
109 * Discover what correction gettimeofday
110 * would have done, and then undo it!
111 */
112 while (tv->tv_nsec < 0) {
113 tv->tv_nsec += NSEC_PER_SEC;
114 tv->tv_sec--;
115 }
116
117 xtime.tv_sec = tv->tv_sec;
118 xtime.tv_nsec = tv->tv_nsec;
119 time_adjust = 0; /* stop active adjtime() */
120 time_status |= STA_UNSYNC;
121 time_maxerror = NTP_PHASE_LIMIT;
122 time_esterror = NTP_PHASE_LIMIT;
123 write_sequnlock_irq(&xtime_lock);
124 clock_was_set();
125 return 0;
126}
127
128EXPORT_SYMBOL(do_settimeofday);
129
130unsigned long long sched_clock(void)
131{
132 return (unsigned long long)jiffies * (1000000000 / HZ);
133
134}
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
new file mode 100644
index 000000000000..300e3279ca5a
--- /dev/null
+++ b/arch/h8300/kernel/traps.c
@@ -0,0 +1,169 @@
1/*
2 * linux/arch/h8300/boot/traps.c -- general exception handling code
3 * H8/300 support Yoshinori Sato <ysato@users.sourceforge.jp>
4 *
5 * Cloned from Linux/m68k.
6 *
7 * No original Copyright holder listed,
8 * Probabily original (C) Roman Zippel (assigned DJD, 1999)
9 *
10 * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file COPYING in the main directory of this archive
14 * for more details.
15 */
16
17#include <linux/types.h>
18#include <linux/sched.h>
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/module.h>
23
24#include <asm/system.h>
25#include <asm/irq.h>
26#include <asm/traps.h>
27#include <asm/page.h>
28#include <asm/gpio.h>
29
30/*
31 * this must be called very early as the kernel might
32 * use some instruction that are emulated on the 060
33 */
34
35void __init base_trap_init(void)
36{
37}
38
39void __init trap_init (void)
40{
41}
42
43asmlinkage void set_esp0 (unsigned long ssp)
44{
45 current->thread.esp0 = ssp;
46}
47
48/*
49 * Generic dumping code. Used for panic and debug.
50 */
51
52static void dump(struct pt_regs *fp)
53{
54 unsigned long *sp;
55 unsigned char *tp;
56 int i;
57
58 printk("\nCURRENT PROCESS:\n\n");
59 printk("COMM=%s PID=%d\n", current->comm, current->pid);
60 if (current->mm) {
61 printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
62 (int) current->mm->start_code,
63 (int) current->mm->end_code,
64 (int) current->mm->start_data,
65 (int) current->mm->end_data,
66 (int) current->mm->end_data,
67 (int) current->mm->brk);
68 printk("USER-STACK=%08x KERNEL-STACK=%08lx\n\n",
69 (int) current->mm->start_stack,
70 (int) PAGE_SIZE+(unsigned long)current);
71 }
72
73 show_regs(fp);
74 printk("\nCODE:");
75 tp = ((unsigned char *) fp->pc) - 0x20;
76 for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
77 if ((i % 0x10) == 0)
78 printk("\n%08x: ", (int) (tp + i));
79 printk("%08x ", (int) *sp++);
80 }
81 printk("\n");
82
83 printk("\nKERNEL STACK:");
84 tp = ((unsigned char *) fp) - 0x40;
85 for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
86 if ((i % 0x10) == 0)
87 printk("\n%08x: ", (int) (tp + i));
88 printk("%08x ", (int) *sp++);
89 }
90 printk("\n");
91 if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE))
92 printk("(Possibly corrupted stack page??)\n");
93
94 printk("\n\n");
95}
96
97void die_if_kernel (char *str, struct pt_regs *fp, int nr)
98{
99 extern int console_loglevel;
100
101 if (!(fp->ccr & PS_S))
102 return;
103
104 console_loglevel = 15;
105 dump(fp);
106
107 do_exit(SIGSEGV);
108}
109
110extern char _start, _etext;
111#define check_kernel_text(addr) \
112 ((addr >= (unsigned long)(&_start)) && \
113 (addr < (unsigned long)(&_etext)))
114
115static int kstack_depth_to_print = 24;
116
117void show_stack(struct task_struct *task, unsigned long *esp)
118{
119 unsigned long *stack, addr;
120 int i;
121
122 if (esp == NULL)
123 esp = (unsigned long *) &esp;
124
125 stack = esp;
126
127 printk("Stack from %08lx:", (unsigned long)stack);
128 for (i = 0; i < kstack_depth_to_print; i++) {
129 if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0)
130 break;
131 if (i % 8 == 0)
132 printk("\n ");
133 printk(" %08lx", *stack++);
134 }
135
136 printk("\nCall Trace:");
137 i = 0;
138 stack = esp;
139 while (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) {
140 addr = *stack++;
141 /*
142 * If the address is either in the text segment of the
143 * kernel, or in the region which contains vmalloc'ed
144 * memory, it *may* be the address of a calling
145 * routine; if so, print it so that someone tracing
146 * down the cause of the crash will be able to figure
147 * out the call path that was taken.
148 */
149 if (check_kernel_text(addr)) {
150 if (i % 4 == 0)
151 printk("\n ");
152 printk(" [<%08lx>]", addr);
153 i++;
154 }
155 }
156 printk("\n");
157}
158
159void show_trace_task(struct task_struct *tsk)
160{
161 show_stack(tsk,(unsigned long *)tsk->thread.esp0);
162}
163
164void dump_stack(void)
165{
166 show_stack(NULL,NULL);
167}
168
169EXPORT_SYMBOL(dump_stack);
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..17fa11da1e4a
--- /dev/null
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -0,0 +1,172 @@
1#define VMLINUX_SYMBOL(_sym_) _##_sym_
2#include <asm-generic/vmlinux.lds.h>
3#include <linux/config.h>
4
5/* target memory map */
6#ifdef CONFIG_H8300H_GENERIC
7#define ROMTOP 0x000000
8#define ROMSIZE 0x400000
9#define RAMTOP 0x400000
10#define RAMSIZE 0x400000
11#endif
12
13#ifdef CONFIG_H8300H_AKI3068NET
14#define ROMTOP 0x000000
15#define ROMSIZE 0x080000
16#define RAMTOP 0x400000
17#define RAMSIZE 0x200000
18#endif
19
20#ifdef CONFIG_H8300H_H8MAX
21#define ROMTOP 0x000000
22#define ROMSIZE 0x080000
23#define RAMTOP 0x400000
24#define RAMSIZE 0x200000
25#endif
26
27#ifdef CONFIG_H8300H_SIM
28#define ROMTOP 0x000000
29#define ROMSIZE 0x400000
30#define RAMTOP 0x400000
31#define RAMSIZE 0x400000
32#endif
33
34#ifdef CONFIG_H8S_SIM
35#define ROMTOP 0x000000
36#define ROMSIZE 0x400000
37#define RAMTOP 0x400000
38#define RAMSIZE 0x800000
39#endif
40
41#ifdef CONFIG_H8S_EDOSK2674
42#define ROMTOP 0x000000
43#define ROMSIZE 0x400000
44#define RAMTOP 0x400000
45#define RAMSIZE 0x800000
46#endif
47
48#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
49INPUT(romfs.o)
50#endif
51
52_jiffies = _jiffies_64 + 4;
53
54ENTRY(__start)
55
56SECTIONS
57{
58#if defined(CONFIG_ROMKERNEL)
59 . = ROMTOP;
60 .vectors :
61 {
62 __vector = . ;
63 *(.vectors*)
64 }
65#else
66 . = RAMTOP;
67 .bootvec :
68 {
69 *(.bootvec)
70 }
71#endif
72 .text :
73 {
74#if defined(CONFIG_ROMKERNEL)
75 *(.int_redirect)
76#endif
77 __stext = . ;
78 *(.text)
79 SCHED_TEXT
80 LOCK_TEXT
81 __etext = . ;
82 . = ALIGN(16); /* Exception table */
83 ___start___ex_table = .;
84 *(__ex_table)
85 ___stop___ex_table = .;
86 }
87
88 RODATA
89#if defined(CONFIG_ROMKERNEL)
90 SECURITY_INIT
91#endif
92 ROEND = .;
93#if defined(CONFIG_ROMKERNEL)
94 . = RAMTOP;
95 .data : AT(ROEND)
96#else
97 .data :
98#endif
99 {
100 __sdata = . ;
101 ___data_start = . ;
102
103 . = ALIGN(0x2000) ;
104 *(.data.init_task)
105 . = ALIGN(0x4) ;
106 *(.data)
107 . = ALIGN(0x4) ;
108 *(.data.*)
109
110 . = ALIGN(0x4) ;
111 ___init_begin = .;
112 __sinittext = .;
113 *(.init.text)
114 __einittext = .;
115 *(.init.data)
116 . = ALIGN(0x4) ;
117 ___setup_start = .;
118 *(.init.setup)
119 . = ALIGN(0x4) ;
120 ___setup_end = .;
121 ___initcall_start = .;
122 *(.initcall1.init)
123 *(.initcall2.init)
124 *(.initcall3.init)
125 *(.initcall4.init)
126 *(.initcall5.init)
127 *(.initcall6.init)
128 *(.initcall7.init)
129 ___initcall_end = .;
130 ___con_initcall_start = .;
131 *(.con_initcall.init)
132 ___con_initcall_end = .;
133 *(.exit.text)
134 *(.exit.data)
135 . = ALIGN(4);
136 ___initramfs_start = .;
137 *(.init.ramfs)
138 ___initramfs_end = .;
139 . = ALIGN(0x4) ;
140 ___init_end = .;
141 __edata = . ;
142 }
143#if defined(CONFIG_RAMKERNEL)
144 SECURITY_INIT
145#endif
146 __begin_data = LOADADDR(.data);
147 .bss :
148 {
149 . = ALIGN(0x4) ;
150 __sbss = . ;
151 *(.bss*)
152 . = ALIGN(0x4) ;
153 *(COMMON)
154 . = ALIGN(0x4) ;
155 __ebss = . ;
156 __end = . ;
157 __ramstart = .;
158 }
159 /DISCARD/ : {
160 *(.exitcall.exit)
161 }
162 .romfs :
163 {
164 *(.romfs*)
165 }
166 . = RAMTOP+RAMSIZE;
167 .dummy :
168 {
169 COMMAND_START = . - 0x200 ;
170 __ramend = . ;
171 }
172}